svn commit: r261088 - in stable/10: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/amd64/vmm/intel sys/amd64/vmm/io sys/modules/vmm usr.sbin/bhyve

John Baldwin jhb at FreeBSD.org
Thu Jan 23 20:21:41 UTC 2014


Author: jhb
Date: Thu Jan 23 20:21:39 2014
New Revision: 261088
URL: http://svnweb.freebsd.org/changeset/base/261088

Log:
  MFC 257422,257661,258075,258476,258494,258579,258609,258699:
  Several enhancements to the I/O APIC support in bhyve including:
  - Move the I/O APIC device model from userspace into vmm.ko and add
    ioctls to assert and deassert I/O APIC pins.
  - Add HPET device emulation including a single timer block with 8 timers.
  - Remove the 'vdev' abstraction.
  
  Approved by:	neel

Added:
  stable/10/sys/amd64/vmm/io/vhpet.c
     - copied, changed from r258579, head/sys/amd64/vmm/io/vhpet.c
  stable/10/sys/amd64/vmm/io/vhpet.h
     - copied unchanged from r258579, head/sys/amd64/vmm/io/vhpet.h
  stable/10/sys/amd64/vmm/io/vioapic.c
     - copied, changed from r258075, head/sys/amd64/vmm/io/vioapic.c
  stable/10/sys/amd64/vmm/io/vioapic.h
     - copied, changed from r258075, head/sys/amd64/vmm/io/vioapic.h
Deleted:
  stable/10/sys/amd64/vmm/io/vdev.c
  stable/10/sys/amd64/vmm/io/vdev.h
  stable/10/usr.sbin/bhyve/ioapic.c
  stable/10/usr.sbin/bhyve/ioapic.h
Modified:
  stable/10/lib/libvmmapi/vmmapi.c
  stable/10/lib/libvmmapi/vmmapi.h
  stable/10/sys/amd64/include/vmm.h
  stable/10/sys/amd64/include/vmm_dev.h
  stable/10/sys/amd64/vmm/intel/vmx.c
  stable/10/sys/amd64/vmm/io/ppt.c
  stable/10/sys/amd64/vmm/io/vlapic.c
  stable/10/sys/amd64/vmm/io/vlapic.h
  stable/10/sys/amd64/vmm/vmm.c
  stable/10/sys/amd64/vmm/vmm_dev.c
  stable/10/sys/amd64/vmm/vmm_ktr.h
  stable/10/sys/amd64/vmm/vmm_lapic.c
  stable/10/sys/amd64/vmm/vmm_lapic.h
  stable/10/sys/modules/vmm/Makefile
  stable/10/usr.sbin/bhyve/Makefile
  stable/10/usr.sbin/bhyve/acpi.c
  stable/10/usr.sbin/bhyve/bhyverun.c
  stable/10/usr.sbin/bhyve/mptbl.c
  stable/10/usr.sbin/bhyve/pci_emul.c
  stable/10/usr.sbin/bhyve/pci_emul.h
  stable/10/usr.sbin/bhyve/pci_lpc.c
  stable/10/usr.sbin/bhyve/pit_8254.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libvmmapi/vmmapi.c
==============================================================================
--- stable/10/lib/libvmmapi/vmmapi.c	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/lib/libvmmapi/vmmapi.c	Thu Jan 23 20:21:39 2014	(r261088)
@@ -397,6 +397,39 @@ vm_lapic_irq(struct vmctx *ctx, int vcpu
 }
 
 int
+vm_ioapic_assert_irq(struct vmctx *ctx, int irq)
+{
+	struct vm_ioapic_irq ioapic_irq;
+
+	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
+	ioapic_irq.irq = irq;
+
+	return (ioctl(ctx->fd, VM_IOAPIC_ASSERT_IRQ, &ioapic_irq));
+}
+
+int
+vm_ioapic_deassert_irq(struct vmctx *ctx, int irq)
+{
+	struct vm_ioapic_irq ioapic_irq;
+
+	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
+	ioapic_irq.irq = irq;
+
+	return (ioctl(ctx->fd, VM_IOAPIC_DEASSERT_IRQ, &ioapic_irq));
+}
+
+int
+vm_ioapic_pulse_irq(struct vmctx *ctx, int irq)
+{
+	struct vm_ioapic_irq ioapic_irq;
+
+	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
+	ioapic_irq.irq = irq;
+
+	return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq));
+}
+
+int
 vm_inject_nmi(struct vmctx *ctx, int vcpu)
 {
 	struct vm_nmi vmnmi;
@@ -792,3 +825,16 @@ vm_get_gpa_pmap(struct vmctx *ctx, uint6
 
 	return (error);
 }
+
+int
+vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities)
+{
+	int error;
+	struct vm_hpet_cap cap;
+
+	bzero(&cap, sizeof(struct vm_hpet_cap));
+	error = ioctl(ctx->fd, VM_GET_HPET_CAPABILITIES, &cap);
+	if (capabilities != NULL)
+		*capabilities = cap.capabilities;
+	return (error);
+}

Modified: stable/10/lib/libvmmapi/vmmapi.h
==============================================================================
--- stable/10/lib/libvmmapi/vmmapi.h	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/lib/libvmmapi/vmmapi.h	Thu Jan 23 20:21:39 2014	(r261088)
@@ -67,6 +67,9 @@ int	vm_inject_event(struct vmctx *ctx, i
 int	vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type,
 			 int vector, int error_code);
 int	vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector);
+int	vm_ioapic_assert_irq(struct vmctx *ctx, int irq);
+int	vm_ioapic_deassert_irq(struct vmctx *ctx, int irq);
+int	vm_ioapic_pulse_irq(struct vmctx *ctx, int irq);
 int	vm_inject_nmi(struct vmctx *ctx, int vcpu);
 int	vm_capability_name2type(const char *capname);
 const char *vm_capability_type2name(int type);
@@ -93,6 +96,8 @@ const char *vm_get_stat_desc(struct vmct
 int	vm_get_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state *s);
 int	vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state s);
 
+int	vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities);
+
 /* Reset vcpu register state */
 int	vcpu_reset(struct vmctx *ctx, int vcpu);
 

Modified: stable/10/sys/amd64/include/vmm.h
==============================================================================
--- stable/10/sys/amd64/include/vmm.h	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/sys/amd64/include/vmm.h	Thu Jan 23 20:21:39 2014	(r261088)
@@ -38,6 +38,8 @@ struct vm_memory_segment;
 struct seg_desc;
 struct vm_exit;
 struct vm_run;
+struct vhpet;
+struct vioapic;
 struct vlapic;
 struct vmspace;
 struct vm_object;
@@ -116,10 +118,13 @@ int vm_nmi_pending(struct vm *vm, int vc
 void vm_nmi_clear(struct vm *vm, int vcpuid);
 uint64_t *vm_guest_msrs(struct vm *vm, int cpu);
 struct vlapic *vm_lapic(struct vm *vm, int cpu);
+struct vioapic *vm_ioapic(struct vm *vm);
+struct vhpet *vm_hpet(struct vm *vm);
 int vm_get_capability(struct vm *vm, int vcpu, int type, int *val);
 int vm_set_capability(struct vm *vm, int vcpu, int type, int val);
 int vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state);
 int vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state);
+int vm_apicid2vcpuid(struct vm *vm, int apicid);
 void vm_activate_cpu(struct vm *vm, int vcpu);
 cpuset_t vm_active_cpus(struct vm *vm);
 struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);

Modified: stable/10/sys/amd64/include/vmm_dev.h
==============================================================================
--- stable/10/sys/amd64/include/vmm_dev.h	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/sys/amd64/include/vmm_dev.h	Thu Jan 23 20:21:39 2014	(r261088)
@@ -71,6 +71,10 @@ struct vm_lapic_irq {
 	int		vector;
 };
 
+struct vm_ioapic_irq {
+	int		irq;
+};
+
 struct vm_capability {
 	int		cpuid;
 	enum vm_cap_type captype;
@@ -142,6 +146,10 @@ struct vm_gpa_pte {
 	int		ptenum;
 };
 
+struct vm_hpet_cap {
+	uint32_t	capabilities;	/* lower 32 bits of HPET capabilities */
+};
+
 enum {
 	/* general routines */
 	IOCNUM_ABIVERS = 0,
@@ -164,6 +172,9 @@ enum {
 	IOCNUM_INJECT_EVENT = 30,
 	IOCNUM_LAPIC_IRQ = 31,
 	IOCNUM_INJECT_NMI = 32,
+	IOCNUM_IOAPIC_ASSERT_IRQ = 33,
+	IOCNUM_IOAPIC_DEASSERT_IRQ = 34,
+	IOCNUM_IOAPIC_PULSE_IRQ = 35,
 
 	/* PCI pass-thru */
 	IOCNUM_BIND_PPTDEV = 40,
@@ -179,6 +190,7 @@ enum {
 	/* kernel device state */
 	IOCNUM_SET_X2APIC_STATE = 60,
 	IOCNUM_GET_X2APIC_STATE = 61,
+	IOCNUM_GET_HPET_CAPABILITIES = 62,
 };
 
 #define	VM_RUN		\
@@ -199,6 +211,12 @@ enum {
 	_IOW('v', IOCNUM_INJECT_EVENT, struct vm_event)
 #define	VM_LAPIC_IRQ 		\
 	_IOW('v', IOCNUM_LAPIC_IRQ, struct vm_lapic_irq)
+#define	VM_IOAPIC_ASSERT_IRQ	\
+	_IOW('v', IOCNUM_IOAPIC_ASSERT_IRQ, struct vm_ioapic_irq)
+#define	VM_IOAPIC_DEASSERT_IRQ	\
+	_IOW('v', IOCNUM_IOAPIC_DEASSERT_IRQ, struct vm_ioapic_irq)
+#define	VM_IOAPIC_PULSE_IRQ	\
+	_IOW('v', IOCNUM_IOAPIC_PULSE_IRQ, struct vm_ioapic_irq)
 #define	VM_SET_CAPABILITY \
 	_IOW('v', IOCNUM_SET_CAPABILITY, struct vm_capability)
 #define	VM_GET_CAPABILITY \
@@ -223,6 +241,8 @@ enum {
 	_IOW('v', IOCNUM_SET_X2APIC_STATE, struct vm_x2apic)
 #define	VM_GET_X2APIC_STATE \
 	_IOWR('v', IOCNUM_GET_X2APIC_STATE, struct vm_x2apic)
+#define	VM_GET_HPET_CAPABILITIES \
+	_IOR('v', IOCNUM_GET_HPET_CAPABILITIES, struct vm_hpet_cap)
 #define	VM_GET_GPA_PMAP \
 	_IOWR('v', IOCNUM_GET_GPA_PMAP, struct vm_gpa_pte)
 #endif

Modified: stable/10/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- stable/10/sys/amd64/vmm/intel/vmx.c	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/sys/amd64/vmm/intel/vmx.c	Thu Jan 23 20:21:39 2014	(r261088)
@@ -308,8 +308,8 @@ vmx_setjmp_rc2str(int rc)
 	}
 }
 
-#define	SETJMP_TRACE(vmx, vcpu, vmxctx, regname)			  \
-	VMM_CTR1((vmx)->vm, (vcpu), "setjmp trace " #regname " 0x%016lx", \
+#define	SETJMP_TRACE(vmx, vcpu, vmxctx, regname)			    \
+	VCPU_CTR1((vmx)->vm, (vcpu), "setjmp trace " #regname " 0x%016lx",  \
 		 (vmxctx)->regname)
 
 static void
@@ -321,14 +321,14 @@ vmx_setjmp_trace(struct vmx *vmx, int vc
 		panic("vmx_setjmp_trace: invalid vmxctx %p; should be %p",
 			vmxctx, &vmx->ctx[vcpu]);
 
-	VMM_CTR1((vmx)->vm, (vcpu), "vmxctx = %p", vmxctx);
-	VMM_CTR2((vmx)->vm, (vcpu), "setjmp return code %s(%d)",
+	VCPU_CTR1((vmx)->vm, (vcpu), "vmxctx = %p", vmxctx);
+	VCPU_CTR2((vmx)->vm, (vcpu), "setjmp return code %s(%d)",
 		 vmx_setjmp_rc2str(rc), rc);
 
 	host_rsp = host_rip = ~0;
 	vmread(VMCS_HOST_RIP, &host_rip);
 	vmread(VMCS_HOST_RSP, &host_rsp);
-	VMM_CTR2((vmx)->vm, (vcpu), "vmcs host_rip 0x%016lx, host_rsp 0x%016lx",
+	VCPU_CTR2((vmx)->vm, (vcpu), "vmcs host_rip 0x%016lx, host_rsp %#lx",
 		 host_rip, host_rsp);
 
 	SETJMP_TRACE(vmx, vcpu, vmxctx, host_r15);
@@ -887,7 +887,7 @@ static __inline void
 vmx_run_trace(struct vmx *vmx, int vcpu)
 {
 #ifdef KTR
-	VMM_CTR1(vmx->vm, vcpu, "Resume execution at 0x%0lx", vmcs_guest_rip());
+	VCPU_CTR1(vmx->vm, vcpu, "Resume execution at %#lx", vmcs_guest_rip());
 #endif
 }
 
@@ -896,7 +896,7 @@ vmx_exit_trace(struct vmx *vmx, int vcpu
 	       int handled)
 {
 #ifdef KTR
-	VMM_CTR3(vmx->vm, vcpu, "%s %s vmexit at 0x%0lx",
+	VCPU_CTR3(vmx->vm, vcpu, "%s %s vmexit at 0x%0lx",
 		 handled ? "handled" : "unhandled",
 		 exit_reason_to_str(exit_reason), rip);
 #endif
@@ -906,7 +906,7 @@ static __inline void
 vmx_astpending_trace(struct vmx *vmx, int vcpu, uint64_t rip)
 {
 #ifdef KTR
-	VMM_CTR1(vmx->vm, vcpu, "astpending vmexit at 0x%0lx", rip);
+	VCPU_CTR1(vmx->vm, vcpu, "astpending vmexit at 0x%0lx", rip);
 #endif
 }
 
@@ -1055,7 +1055,7 @@ vmx_inject_nmi(struct vmx *vmx, int vcpu
 	if (error)
 		panic("vmx_inject_nmi: vmwrite(intrinfo) %d", error);
 
-	VMM_CTR0(vmx->vm, vcpu, "Injecting vNMI");
+	VCPU_CTR0(vmx->vm, vcpu, "Injecting vNMI");
 
 	/* Clear the request */
 	vm_nmi_clear(vmx->vm, vcpu);
@@ -1068,7 +1068,7 @@ nmiblocked:
 	 */
 	vmx_set_nmi_window_exiting(vmx, vcpu);
 
-	VMM_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting");
+	VCPU_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting");
 	return (1);
 }
 
@@ -1134,7 +1134,7 @@ vmx_inject_interrupts(struct vmx *vmx, i
 	/* Update the Local APIC ISR */
 	lapic_intr_accepted(vmx->vm, vcpu, vector);
 
-	VMM_CTR1(vmx->vm, vcpu, "Injecting hwintr at vector %d", vector);
+	VCPU_CTR1(vmx->vm, vcpu, "Injecting hwintr at vector %d", vector);
 
 	return;
 
@@ -1145,7 +1145,7 @@ cantinject:
 	 */
 	vmx_set_int_window_exiting(vmx, vcpu);
 
-	VMM_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting");
+	VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting");
 }
 
 static int
@@ -1435,7 +1435,7 @@ vmx_exit_process(struct vmx *vmx, int vc
 	case EXIT_REASON_INTR_WINDOW:
 		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INTR_WINDOW, 1);
 		vmx_clear_int_window_exiting(vmx, vcpu);
-		VMM_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting");
+		VCPU_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting");
 		return (1);
 	case EXIT_REASON_EXT_INTR:
 		/*
@@ -1458,7 +1458,7 @@ vmx_exit_process(struct vmx *vmx, int vc
 		/* Exit to allow the pending virtual NMI to be injected */
 		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_NMI_WINDOW, 1);
 		vmx_clear_nmi_window_exiting(vmx, vcpu);
-		VMM_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting");
+		VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting");
 		return (1);
 	case EXIT_REASON_INOUT:
 		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INOUT, 1);
@@ -1659,7 +1659,7 @@ vmx_run(void *arg, int vcpu, register_t 
 	if (!handled)
 		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_USERSPACE, 1);
 
-	VMM_CTR1(vmx->vm, vcpu, "goto userland: exitcode %d",vmexit->exitcode);
+	VCPU_CTR1(vmx->vm, vcpu, "goto userland: exitcode %d",vmexit->exitcode);
 
 	/*
 	 * XXX

Modified: stable/10/sys/amd64/vmm/io/ppt.c
==============================================================================
--- stable/10/sys/amd64/vmm/io/ppt.c	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/sys/amd64/vmm/io/ppt.c	Thu Jan 23 20:21:39 2014	(r261088)
@@ -421,7 +421,7 @@ pptintr(void *arg)
 	vec = pptarg->vec;
 
 	if (ppt->vm != NULL)
-		(void) lapic_set_intr(ppt->vm, pptarg->vcpu, vec);
+		lapic_intr_edge(ppt->vm, pptarg->vcpu, vec);
 	else {
 		/*
 		 * XXX

Copied and modified: stable/10/sys/amd64/vmm/io/vhpet.c (from r258579, head/sys/amd64/vmm/io/vhpet.c)
==============================================================================
--- head/sys/amd64/vmm/io/vhpet.c	Mon Nov 25 19:04:51 2013	(r258579, copy source)
+++ stable/10/sys/amd64/vmm/io/vhpet.c	Thu Jan 23 20:21:39 2014	(r261088)
@@ -266,14 +266,14 @@ vhpet_timer_interrupt(struct vhpet *vhpe
 		if (apicid != 0xff) {
 			/* unicast */
 			vcpuid = vm_apicid2vcpuid(vhpet->vm, apicid);
-			lapic_set_intr(vhpet->vm, vcpuid, vector);
+			lapic_intr_edge(vhpet->vm, vcpuid, vector);
 		} else {
 			/* broadcast */
 			dmask = vm_active_cpus(vhpet->vm);
 			while ((vcpuid = CPU_FFS(&dmask)) != 0) {
 				vcpuid--;
 				CPU_CLR(vcpuid, &dmask);
-				lapic_set_intr(vhpet->vm, vcpuid, vector);
+				lapic_intr_edge(vhpet->vm, vcpuid, vector);
 			}
 		}
 		return;
@@ -725,8 +725,9 @@ done:
 struct vhpet *
 vhpet_init(struct vm *vm)
 {
-	int i;
+	int i, pincount;
 	struct vhpet *vhpet;
+	uint64_t allowed_irqs;
 	struct vhpet_callout_arg *arg;
 	struct bintime bt;
 
@@ -737,12 +738,20 @@ vhpet_init(struct vm *vm)
 	FREQ2BT(HPET_FREQ, &bt);
 	vhpet->freq_sbt = bttosbt(bt);
 
+	pincount = vioapic_pincount(vm);
+	if (pincount >= 24)
+		allowed_irqs = 0x00f00000;	/* irqs 20, 21, 22 and 23 */
+	else
+		allowed_irqs = 0;
+
 	/*
 	 * Initialize HPET timer hardware state.
 	 */
 	for (i = 0; i < VHPET_NUM_TIMERS; i++) {
-		vhpet->timer[i].cap_config = 0UL << 32 |
-		    HPET_TCAP_FSB_INT_DEL | HPET_TCAP_PER_INT;
+		vhpet->timer[i].cap_config = allowed_irqs << 32;
+		vhpet->timer[i].cap_config |= HPET_TCAP_PER_INT;
+		vhpet->timer[i].cap_config |= HPET_TCAP_FSB_INT_DEL;
+
 		vhpet->timer[i].compval = 0xffffffff;
 		callout_init(&vhpet->timer[i].callout, 1);
 

Copied: stable/10/sys/amd64/vmm/io/vhpet.h (from r258579, head/sys/amd64/vmm/io/vhpet.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/sys/amd64/vmm/io/vhpet.h	Thu Jan 23 20:21:39 2014	(r261088, copy of r258579, head/sys/amd64/vmm/io/vhpet.h)
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2013 Tycho Nightingale <tycho.nightingale at pluribusnetworks.com>
+ * Copyright (c) 2013 Neel Natu <neel at freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _VHPET_H_
+#define	_VHPET_H_
+
+#define	VHPET_BASE	0xfed00000
+#define	VHPET_SIZE	1024
+
+struct vhpet *vhpet_init(struct vm *vm);
+void 	vhpet_cleanup(struct vhpet *vhpet);
+int	vhpet_mmio_write(void *vm, int vcpuid, uint64_t gpa, uint64_t val,
+	    int size, void *arg);
+int	vhpet_mmio_read(void *vm, int vcpuid, uint64_t gpa, uint64_t *val,
+	    int size, void *arg);
+int	vhpet_getcap(struct vm_hpet_cap *cap);
+
+#endif	/* _VHPET_H_ */

Copied and modified: stable/10/sys/amd64/vmm/io/vioapic.c (from r258075, head/sys/amd64/vmm/io/vioapic.c)
==============================================================================
--- head/sys/amd64/vmm/io/vioapic.c	Tue Nov 12 22:51:03 2013	(r258075, copy source)
+++ stable/10/sys/amd64/vmm/io/vioapic.c	Thu Jan 23 20:21:39 2014	(r261088)
@@ -49,8 +49,8 @@ __FBSDID("$FreeBSD$");
 #define	IOREGSEL	0x00
 #define	IOWIN		0x10
 
-#define	REDIR_ENTRIES	16
-#define	INTR_ASSERTED(vioapic, pin) ((vioapic)->rtbl[(pin)].pinstate == true)
+#define	REDIR_ENTRIES	24
+#define	RTBL_RO_BITS	((uint64_t)(IOART_REM_IRR | IOART_DELIVS))
 
 struct vioapic {
 	struct vm	*vm;
@@ -59,8 +59,7 @@ struct vioapic {
 	uint32_t	ioregsel;
 	struct {
 		uint64_t reg;
-		bool     pinstate;
-		bool     pending;
+		int	 acnt;	/* sum of pin asserts (+1) and deasserts (-1) */
 	} rtbl[REDIR_ENTRIES];
 };
 
@@ -79,6 +78,9 @@ static MALLOC_DEFINE(M_VIOAPIC, "vioapic
 #define	VIOAPIC_CTR3(vioapic, fmt, a1, a2, a3)				\
 	VM_CTR3((vioapic)->vm, fmt, a1, a2, a3)
 
+#define	VIOAPIC_CTR4(vioapic, fmt, a1, a2, a3, a4)			\
+	VM_CTR4((vioapic)->vm, fmt, a1, a2, a3, a4)
+
 #ifdef KTR
 static const char *
 pinstate_str(bool asserted)
@@ -89,14 +91,25 @@ pinstate_str(bool asserted)
 	else
 		return ("deasserted");
 }
+
+static const char *
+trigger_str(bool level)
+{
+
+	if (level)
+		return ("level");
+	else
+		return ("edge");
+}
 #endif
 
 static void
-vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
+vioapic_send_intr(struct vioapic *vioapic, int pin)
 {
 	int vector, apicid, vcpuid;
 	uint32_t low, high;
 	cpuset_t dmask;
+	bool level;
 
 	KASSERT(pin >= 0 && pin < REDIR_ENTRIES,
 	    ("vioapic_set_pinstate: invalid pin number %d", pin));
@@ -104,64 +117,104 @@ vioapic_set_pinstate(struct vioapic *vio
 	KASSERT(VIOAPIC_LOCKED(vioapic),
 	    ("vioapic_set_pinstate: vioapic is not locked"));
 
-	VIOAPIC_CTR2(vioapic, "ioapic pin%d %s", pin, pinstate_str(newstate));
+	low = vioapic->rtbl[pin].reg;
+	high = vioapic->rtbl[pin].reg >> 32;
 
-	/* Nothing to do if interrupt pin has not changed state */
-	if (vioapic->rtbl[pin].pinstate == newstate)
+	/*
+	 * XXX We only deal with:
+	 * - physical destination
+	 * - fixed delivery mode
+	 */
+	if ((low & IOART_DESTMOD) != IOART_DESTPHY) {
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: unsupported dest mode "
+		    "0x%08x", pin, low);
 		return;
+	}
 
-	vioapic->rtbl[pin].pinstate = newstate;	/* record it */
+	if ((low & IOART_DELMOD) != IOART_DELFIXED) {
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: unsupported delivery mode "
+		    "0x%08x", pin, low);
+		return;
+	}
 
-	/* Nothing to do if interrupt pin is deasserted */
-	if (!INTR_ASSERTED(vioapic, pin))
+	if ((low & IOART_INTMASK) == IOART_INTMSET) {
+		VIOAPIC_CTR1(vioapic, "ioapic pin%d: masked", pin);
 		return;
+	}
 
-	/*
-	 * XXX
-	 * We only deal with:
-	 * - edge triggered interrupts
-	 * - fixed delivery mode
-	 *  Level-triggered sources will work so long as there is no sharing.
-	 */
-	low = vioapic->rtbl[pin].reg;
-	high = vioapic->rtbl[pin].reg >> 32;
-	if ((low & IOART_INTMASK) == IOART_INTMCLR &&
-	    (low & IOART_DESTMOD) == IOART_DESTPHY &&
-	    (low & IOART_DELMOD) == IOART_DELFIXED) {
-		vector = low & IOART_INTVEC;
-		apicid = high >> APIC_ID_SHIFT;
-		if (apicid != 0xff) {
-			/* unicast */
-			vcpuid = vm_apicid2vcpuid(vioapic->vm, apicid);
-			VIOAPIC_CTR3(vioapic, "ioapic pin%d triggering "
-			    "intr vector %d on vcpuid %d", pin, vector, vcpuid);
-			lapic_set_intr(vioapic->vm, vcpuid, vector);
-		} else {
-			/* broadcast */
-			VIOAPIC_CTR2(vioapic, "ioapic pin%d triggering intr "
-			    "vector %d on all vcpus", pin, vector);
-			dmask = vm_active_cpus(vioapic->vm);
-			while ((vcpuid = CPU_FFS(&dmask)) != 0) {
-				vcpuid--;
-				CPU_CLR(vcpuid, &dmask);
-				lapic_set_intr(vioapic->vm, vcpuid, vector);
-			}
+	level = low & IOART_TRGRLVL ? true : false;
+	if (level)
+		vioapic->rtbl[pin].reg |= IOART_REM_IRR;
+
+	vector = low & IOART_INTVEC;
+	apicid = high >> APIC_ID_SHIFT;
+	if (apicid != 0xff) {
+		/* unicast */
+		vcpuid = vm_apicid2vcpuid(vioapic->vm, apicid);
+		VIOAPIC_CTR4(vioapic, "ioapic pin%d: %s triggered intr "
+		    "vector %d on vcpuid %d", pin, trigger_str(level),
+		    vector, vcpuid);
+		lapic_set_intr(vioapic->vm, vcpuid, vector, level);
+	} else {
+		/* broadcast */
+		VIOAPIC_CTR3(vioapic, "ioapic pin%d: %s triggered intr "
+		    "vector %d on all vcpus", pin, trigger_str(level), vector);
+		dmask = vm_active_cpus(vioapic->vm);
+		while ((vcpuid = CPU_FFS(&dmask)) != 0) {
+			vcpuid--;
+			CPU_CLR(vcpuid, &dmask);
+			lapic_set_intr(vioapic->vm, vcpuid, vector, level);
 		}
-	} else if ((low & IOART_INTMASK) != IOART_INTMCLR &&
-		   (low & IOART_TRGRLVL) != 0) {
-		/*
-		 * For level-triggered interrupts that have been
-		 * masked, set the pending bit so that an interrupt
-		 * will be generated on unmask and if the level is
-		 * still asserted
-		 */
-		VIOAPIC_CTR1(vioapic, "ioapic pin%d interrupt pending", pin);
-		vioapic->rtbl[pin].pending = true;
 	}
 }
 
+static void
+vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
+{
+	int oldcnt, newcnt;
+	bool needintr;
+
+	KASSERT(pin >= 0 && pin < REDIR_ENTRIES,
+	    ("vioapic_set_pinstate: invalid pin number %d", pin));
+
+	KASSERT(VIOAPIC_LOCKED(vioapic),
+	    ("vioapic_set_pinstate: vioapic is not locked"));
+
+	oldcnt = vioapic->rtbl[pin].acnt;
+	if (newstate)
+		vioapic->rtbl[pin].acnt++;
+	else
+		vioapic->rtbl[pin].acnt--;
+	newcnt = vioapic->rtbl[pin].acnt;
+
+	if (newcnt < 0) {
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: bad acnt %d",
+		    pin, newcnt);
+	}
+
+	needintr = false;
+	if (oldcnt == 0 && newcnt == 1) {
+		needintr = true;
+		VIOAPIC_CTR1(vioapic, "ioapic pin%d: asserted", pin);
+	} else if (oldcnt == 1 && newcnt == 0) {
+		VIOAPIC_CTR1(vioapic, "ioapic pin%d: deasserted", pin);
+	} else {
+		VIOAPIC_CTR3(vioapic, "ioapic pin%d: %s, ignored, acnt %d",
+		    pin, pinstate_str(newstate), newcnt);
+	}
+
+	if (needintr)
+		vioapic_send_intr(vioapic, pin);
+}
+
+enum irqstate {
+	IRQSTATE_ASSERT,
+	IRQSTATE_DEASSERT,
+	IRQSTATE_PULSE
+};
+
 static int
-vioapic_set_irqstate(struct vm *vm, int irq, bool state)
+vioapic_set_irqstate(struct vm *vm, int irq, enum irqstate irqstate)
 {
 	struct vioapic *vioapic;
 
@@ -171,7 +224,20 @@ vioapic_set_irqstate(struct vm *vm, int 
 	vioapic = vm_ioapic(vm);
 
 	VIOAPIC_LOCK(vioapic);
-	vioapic_set_pinstate(vioapic, irq, state);
+	switch (irqstate) {
+	case IRQSTATE_ASSERT:
+		vioapic_set_pinstate(vioapic, irq, true);
+		break;
+	case IRQSTATE_DEASSERT:
+		vioapic_set_pinstate(vioapic, irq, false);
+		break;
+	case IRQSTATE_PULSE:
+		vioapic_set_pinstate(vioapic, irq, true);
+		vioapic_set_pinstate(vioapic, irq, false);
+		break;
+	default:
+		panic("vioapic_set_irqstate: invalid irqstate %d", irqstate);
+	}
 	VIOAPIC_UNLOCK(vioapic);
 
 	return (0);
@@ -181,14 +247,21 @@ int
 vioapic_assert_irq(struct vm *vm, int irq)
 {
 
-	return (vioapic_set_irqstate(vm, irq, true));
+	return (vioapic_set_irqstate(vm, irq, IRQSTATE_ASSERT));
 }
 
 int
 vioapic_deassert_irq(struct vm *vm, int irq)
 {
 
-	return (vioapic_set_irqstate(vm, irq, false));
+	return (vioapic_set_irqstate(vm, irq, IRQSTATE_DEASSERT));
+}
+
+int
+vioapic_pulse_irq(struct vm *vm, int irq)
+{
+
+	return (vioapic_set_irqstate(vm, irq, IRQSTATE_PULSE));
 }
 
 static uint32_t
@@ -202,7 +275,7 @@ vioapic_read(struct vioapic *vioapic, ui
 		return (vioapic->id);
 		break;
 	case IOAPIC_VER:
-		return ((REDIR_ENTRIES << MAXREDIRSHIFT) | 0x11);
+		return (((REDIR_ENTRIES - 1) << MAXREDIRSHIFT) | 0x11);
 		break;
 	case IOAPIC_ARB:
 		return (vioapic->id);
@@ -229,6 +302,7 @@ vioapic_read(struct vioapic *vioapic, ui
 static void
 vioapic_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
 {
+	uint64_t data64, mask64;
 	int regnum, pin, lshift;
 
 	regnum = addr & 0xff;
@@ -253,30 +327,26 @@ vioapic_write(struct vioapic *vioapic, u
 		else
 			lshift = 0;
 
-		vioapic->rtbl[pin].reg &= ~((uint64_t)0xffffffff << lshift);
-		vioapic->rtbl[pin].reg |= ((uint64_t)data << lshift);
+		data64 = (uint64_t)data << lshift;
+		mask64 = (uint64_t)0xffffffff << lshift;
+		vioapic->rtbl[pin].reg &= ~mask64 | RTBL_RO_BITS;
+		vioapic->rtbl[pin].reg |= data64 & ~RTBL_RO_BITS;
 
-		VIOAPIC_CTR2(vioapic, "ioapic pin%d redir table entry %#lx",
+		VIOAPIC_CTR2(vioapic, "ioapic pin%d: redir table entry %#lx",
 		    pin, vioapic->rtbl[pin].reg);
 
-		if (vioapic->rtbl[pin].pending &&
-		    ((vioapic->rtbl[pin].reg & IOART_INTMASK) ==
-		    IOART_INTMCLR)) {
-			vioapic->rtbl[pin].pending = false;
-			/*
-			 * Inject the deferred level-triggered int if it is
-			 * still asserted. Simulate by toggling the pin
-			 * off and then on.
-			 */
-			if (vioapic->rtbl[pin].pinstate == true) {
-				VIOAPIC_CTR1(vioapic, "ioapic pin%d pending "
-				    "interrupt delivered", pin);
-				vioapic_set_pinstate(vioapic, pin, false);
-				vioapic_set_pinstate(vioapic, pin, true);
-			} else {
-				VIOAPIC_CTR1(vioapic, "ioapic pin%d pending "
-				    "interrupt dismissed", pin);
-			}
+		/*
+		 * Generate an interrupt if the following conditions are met:
+		 * - pin is not masked
+		 * - previous interrupt has been EOIed
+		 * - pin level is asserted
+		 */
+		if ((vioapic->rtbl[pin].reg & IOART_INTMASK) == IOART_INTMCLR &&
+		    (vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0 &&
+		    (vioapic->rtbl[pin].acnt > 0)) {
+			VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at rtbl "
+			    "write, acnt %d", pin, vioapic->rtbl[pin].acnt);
+			vioapic_send_intr(vioapic, pin);
 		}
 	}
 }
@@ -340,6 +410,38 @@ vioapic_mmio_write(void *vm, int vcpuid,
 	return (error);
 }
 
+void
+vioapic_process_eoi(struct vm *vm, int vcpuid, int vector)
+{
+	struct vioapic *vioapic;
+	int pin;
+
+	KASSERT(vector >= 0 && vector < 256,
+	    ("vioapic_process_eoi: invalid vector %d", vector));
+
+	vioapic = vm_ioapic(vm);
+	VIOAPIC_CTR1(vioapic, "ioapic processing eoi for vector %d", vector);
+
+	/*
+	 * XXX keep track of the pins associated with this vector instead
+	 * of iterating on every single pin each time.
+	 */
+	VIOAPIC_LOCK(vioapic);
+	for (pin = 0; pin < REDIR_ENTRIES; pin++) {
+		if ((vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0)
+			continue;
+		if ((vioapic->rtbl[pin].reg & IOART_INTVEC) != vector)
+			continue;
+		vioapic->rtbl[pin].reg &= ~IOART_REM_IRR;
+		if (vioapic->rtbl[pin].acnt > 0) {
+			VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at eoi, "
+			    "acnt %d", pin, vioapic->rtbl[pin].acnt);
+			vioapic_send_intr(vioapic, pin);
+		}
+	}
+	VIOAPIC_UNLOCK(vioapic);
+}
+
 struct vioapic *
 vioapic_init(struct vm *vm)
 {
@@ -364,3 +466,10 @@ vioapic_cleanup(struct vioapic *vioapic)
 
 	free(vioapic, M_VIOAPIC);
 }
+
+int
+vioapic_pincount(struct vm *vm)
+{
+
+	return (REDIR_ENTRIES);
+}

Copied and modified: stable/10/sys/amd64/vmm/io/vioapic.h (from r258075, head/sys/amd64/vmm/io/vioapic.h)
==============================================================================
--- head/sys/amd64/vmm/io/vioapic.h	Tue Nov 12 22:51:03 2013	(r258075, copy source)
+++ stable/10/sys/amd64/vmm/io/vioapic.h	Thu Jan 23 20:21:39 2014	(r261088)
@@ -30,9 +30,6 @@
 #ifndef _VIOAPIC_H_
 #define	_VIOAPIC_H_
 
-struct vm;
-struct vioapic;
-
 #define	VIOAPIC_BASE	0xFEC00000
 #define	VIOAPIC_SIZE	4096
 
@@ -41,9 +38,13 @@ void	vioapic_cleanup(struct vioapic *vio
 
 int	vioapic_assert_irq(struct vm *vm, int irq);
 int	vioapic_deassert_irq(struct vm *vm, int irq);
+int	vioapic_pulse_irq(struct vm *vm, int irq);
 
 int	vioapic_mmio_write(void *vm, int vcpuid, uint64_t gpa,
 	    uint64_t wval, int size, void *arg);
 int	vioapic_mmio_read(void *vm, int vcpuid, uint64_t gpa,
 	    uint64_t *rval, int size, void *arg);
+
+int	vioapic_pincount(struct vm *vm);
+void	vioapic_process_eoi(struct vm *vm, int vcpuid, int vector);
 #endif

Modified: stable/10/sys/amd64/vmm/io/vlapic.c
==============================================================================
--- stable/10/sys/amd64/vmm/io/vlapic.c	Thu Jan 23 20:10:22 2014	(r261087)
+++ stable/10/sys/amd64/vmm/io/vlapic.c	Thu Jan 23 20:21:39 2014	(r261088)
@@ -44,14 +44,14 @@ __FBSDID("$FreeBSD$");
 #include "vmm_stat.h"
 #include "vmm_lapic.h"
 #include "vmm_ktr.h"
-#include "vdev.h"
 #include "vlapic.h"
+#include "vioapic.h"
 
 #define	VLAPIC_CTR0(vlapic, format)					\
-	VMM_CTR0((vlapic)->vm, (vlapic)->vcpuid, format)
+	VCPU_CTR0((vlapic)->vm, (vlapic)->vcpuid, format)
 
 #define	VLAPIC_CTR1(vlapic, format, p1)					\
-	VMM_CTR1((vlapic)->vm, (vlapic)->vcpuid, format, p1)
+	VCPU_CTR1((vlapic)->vm, (vlapic)->vcpuid, format, p1)
 
 #define	VLAPIC_CTR_IRR(vlapic, msg)					\
 do {									\
@@ -100,8 +100,6 @@ struct vlapic {
 	struct vm		*vm;
 	int			vcpuid;
 
-	struct io_region	*mmio;
-	struct vdev_ops		*ops;
 	struct LAPIC		 apic;
 
 	int			 esr_update;
@@ -195,9 +193,8 @@ vlapic_init_ipi(struct vlapic *vlapic)
 }
 
 static int
-vlapic_op_reset(void* dev)
+vlapic_reset(struct vlapic *vlapic)
 {
-	struct vlapic 	*vlapic = (struct vlapic*)dev;
 	struct LAPIC	*lapic = &vlapic->apic;
 
 	memset(lapic, 0, sizeof(*lapic));
@@ -214,36 +211,33 @@ vlapic_op_reset(void* dev)
 
 }
 
-static int
-vlapic_op_init(void* dev)
-{
-	struct vlapic *vlapic = (struct vlapic*)dev;
-	vdev_register_region(vlapic->ops, vlapic, vlapic->mmio);
-	return vlapic_op_reset(dev);
-}
-
-static int
-vlapic_op_halt(void* dev)
-{
-	struct vlapic *vlapic = (struct vlapic*)dev;
-	vdev_unregister_region(vlapic, vlapic->mmio);
-	return 0;
-
-}
-
 void
-vlapic_set_intr_ready(struct vlapic *vlapic, int vector)
+vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level)
 {
 	struct LAPIC	*lapic = &vlapic->apic;
-	uint32_t	*irrptr;
+	uint32_t	*irrptr, *tmrptr, mask;
 	int		idx;
 
 	if (vector < 0 || vector >= 256)
 		panic("vlapic_set_intr_ready: invalid vector %d\n", vector);
 
 	idx = (vector / 32) * 4;
+	mask = 1 << (vector % 32);
+
 	irrptr = &lapic->irr0;
-	atomic_set_int(&irrptr[idx], 1 << (vector % 32));
+	atomic_set_int(&irrptr[idx], mask);
+
+	/*
+	 * Upon acceptance of an interrupt into the IRR the corresponding
+	 * TMR bit is cleared for edge-triggered interrupts and set for
+	 * level-triggered interrupts.
+	 */
+	tmrptr = &lapic->tmr0;
+	if (level)
+		atomic_set_int(&tmrptr[idx], mask);
+	else
+		atomic_clear_int(&tmrptr[idx], mask);
+
 	VLAPIC_CTR_IRR(vlapic, "vlapic_set_intr_ready");
 }
 
@@ -371,10 +365,11 @@ static void
 vlapic_process_eoi(struct vlapic *vlapic)
 {
 	struct LAPIC	*lapic = &vlapic->apic;
-	uint32_t	*isrptr;
-	int		i, idx, bitpos;
+	uint32_t	*isrptr, *tmrptr;
+	int		i, idx, bitpos, vector;
 
 	isrptr = &lapic->isr0;
+	tmrptr = &lapic->tmr0;
 
 	/*
 	 * The x86 architecture reserves the the first 32 vectors for use
@@ -383,15 +378,20 @@ vlapic_process_eoi(struct vlapic *vlapic
 	for (i = 7; i > 0; i--) {
 		idx = i * 4;
 		bitpos = fls(isrptr[idx]);
-		if (bitpos != 0) {
+		if (bitpos-- != 0) {
 			if (vlapic->isrvec_stk_top <= 0) {
 				panic("invalid vlapic isrvec_stk_top %d",
 				      vlapic->isrvec_stk_top);
 			}
-			isrptr[idx] &= ~(1 << (bitpos - 1));
+			isrptr[idx] &= ~(1 << bitpos);
 			VLAPIC_CTR_ISR(vlapic, "vlapic_process_eoi");
 			vlapic->isrvec_stk_top--;
 			vlapic_update_ppr(vlapic);
+			if ((tmrptr[idx] & (1 << bitpos)) != 0) {
+				vector = i * 32 + bitpos;
+				vioapic_process_eoi(vlapic->vm, vlapic->vcpuid,
+				    vector);
+			}
 			return;
 		}
 	}
@@ -426,7 +426,7 @@ vlapic_fire_timer(struct vlapic *vlapic)
 	if (!vlapic_get_lvt_field(lvt, APIC_LVTT_M)) {
 		vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_INTR_TIMER, 1);
 		vector = vlapic_get_lvt_field(lvt,APIC_LVTT_VECTOR);
-		vlapic_set_intr_ready(vlapic, vector);
+		vlapic_set_intr_ready(vlapic, vector, false);
 	}
 }
 
@@ -472,7 +472,7 @@ lapic_process_icr(struct vlapic *vlapic,
 			i--;
 			CPU_CLR(i, &dmask);
 			if (mode == APIC_DELMODE_FIXED) {
-				lapic_set_intr(vlapic->vm, i, vec);
+				lapic_intr_edge(vlapic->vm, i, vec);
 				vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid,
 						    IPIS_SENT, i, 1);
 			} else
@@ -594,11 +594,9 @@ vlapic_intr_accepted(struct vlapic *vlap
 }
 
 int
-vlapic_op_mem_read(void* dev, uint64_t gpa, opsize_t size, uint64_t *data)
+vlapic_read(struct vlapic *vlapic, uint64_t offset, uint64_t *data)
 {
-	struct vlapic 	*vlapic = (struct vlapic*)dev;
 	struct LAPIC	*lapic = &vlapic->apic;
-	uint64_t	 offset = gpa & ~(PAGE_SIZE);
 	uint32_t	*reg;
 	int		 i;
 
@@ -686,11 +684,9 @@ vlapic_op_mem_read(void* dev, uint64_t g
 }
 
 int
-vlapic_op_mem_write(void* dev, uint64_t gpa, opsize_t size, uint64_t data)
+vlapic_write(struct vlapic *vlapic, uint64_t offset, uint64_t data)
 {
-	struct vlapic 	*vlapic = (struct vlapic*)dev;
 	struct LAPIC	*lapic = &vlapic->apic;
-	uint64_t	 offset = gpa & ~(PAGE_SIZE);
 	uint32_t	*reg;
 	int		retval;
 
@@ -832,16 +828,6 @@ restart:
 		return (0);
 }
 
-struct vdev_ops vlapic_dev_ops = {
-	.name = "vlapic",
-	.init = vlapic_op_init,
-	.reset = vlapic_op_reset,
-	.halt = vlapic_op_halt,
-	.memread = vlapic_op_mem_read,
-	.memwrite = vlapic_op_mem_write,
-};
-static struct io_region vlapic_mmio[VM_MAXCPU];
-
 struct vlapic *
 vlapic_init(struct vm *vm, int vcpuid)
 {
@@ -856,17 +842,7 @@ vlapic_init(struct vm *vm, int vcpuid)
 	if (vcpuid == 0)
 		vlapic->msr_apicbase |= APICBASE_BSP;
 
-	vlapic->ops = &vlapic_dev_ops;
-
-	vlapic->mmio = vlapic_mmio + vcpuid;
-	vlapic->mmio->base = DEFAULT_APIC_BASE;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list