Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Jan 2014 21:23:11 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 1190142 for review
Message-ID:  <201401182123.s0ILNBX2016953@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@1190142?ac=10

Change 1190142 by jhb@jhb_pippin on 2014/01/18 21:22:36

	IFC @1190140

Affected files ...

.. //depot/projects/pci/sys/amd64/amd64/identcpu.c#9 integrate
.. //depot/projects/pci/sys/amd64/conf/NOTES#12 integrate
.. //depot/projects/pci/sys/amd64/include/vmm.h#8 integrate
.. //depot/projects/pci/sys/amd64/vmm/amd/amdv.c#5 integrate
.. //depot/projects/pci/sys/amd64/vmm/intel/vmcs.c#7 integrate
.. //depot/projects/pci/sys/amd64/vmm/intel/vmcs.h#7 integrate
.. //depot/projects/pci/sys/amd64/vmm/intel/vmx.c#9 integrate
.. //depot/projects/pci/sys/amd64/vmm/intel/vmx.h#6 integrate
.. //depot/projects/pci/sys/amd64/vmm/intel/vmx_genassym.c#6 integrate
.. //depot/projects/pci/sys/amd64/vmm/intel/vmx_support.S#4 integrate
.. //depot/projects/pci/sys/amd64/vmm/io/vioapic.c#3 integrate
.. //depot/projects/pci/sys/amd64/vmm/io/vlapic.c#6 integrate
.. //depot/projects/pci/sys/amd64/vmm/io/vlapic.h#5 integrate
.. //depot/projects/pci/sys/amd64/vmm/vmm.c#8 integrate
.. //depot/projects/pci/sys/amd64/vmm/vmm_stat.c#3 integrate
.. //depot/projects/pci/sys/amd64/vmm/vmm_stat.h#3 integrate
.. //depot/projects/pci/sys/arm/at91/at91_gpio.h#1 branch
.. //depot/projects/pci/sys/arm/at91/at91rm9200.c#4 integrate
.. //depot/projects/pci/sys/arm/at91/at91sam9260.c#3 integrate
.. //depot/projects/pci/sys/arm/at91/at91sam9g20.c#3 integrate
.. //depot/projects/pci/sys/arm/at91/at91sam9g45.c#2 integrate
.. //depot/projects/pci/sys/arm/at91/at91sam9x5.c#2 integrate
.. //depot/projects/pci/sys/arm/at91/at91var.h#3 integrate
.. //depot/projects/pci/sys/arm/freescale/imx/imx51_ipuv3_fbd.c#2 integrate
.. //depot/projects/pci/sys/cam/cam_periph.c#13 integrate
.. //depot/projects/pci/sys/cam/cam_periph.h#8 integrate
.. //depot/projects/pci/sys/cam/cam_xpt.c#15 integrate
.. //depot/projects/pci/sys/cam/scsi/scsi_xpt.c#10 integrate
.. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c#9 integrate
.. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c#6 integrate
.. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c#6 integrate
.. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c#7 integrate
.. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#12 integrate
.. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c#9 integrate
.. //depot/projects/pci/sys/compat/freebsd32/freebsd32_misc.c#14 integrate
.. //depot/projects/pci/sys/conf/files.amd64#13 integrate
.. //depot/projects/pci/sys/conf/files.i386#15 integrate
.. //depot/projects/pci/sys/contrib/dev/iwn/iwlwifi-105-6-18.168.6.1.fw.uu#1 branch
.. //depot/projects/pci/sys/contrib/ipfilter/netinet/ip_compat.h#6 integrate
.. //depot/projects/pci/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c#4 integrate
.. //depot/projects/pci/sys/dev/ahci/ahci.c#16 integrate
.. //depot/projects/pci/sys/dev/altera/atse/if_atse.c#2 integrate
.. //depot/projects/pci/sys/dev/bxe/bxe.c#6 integrate
.. //depot/projects/pci/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c#4 integrate
.. //depot/projects/pci/sys/dev/netmap/netmap.c#7 integrate
.. //depot/projects/pci/sys/dev/netmap/netmap_generic.c#3 integrate
.. //depot/projects/pci/sys/dev/netmap/netmap_vale.c#3 integrate
.. //depot/projects/pci/sys/dev/qlxge/qls_os.c#2 integrate
.. //depot/projects/pci/sys/dev/usb/controller/ehci.c#9 integrate
.. //depot/projects/pci/sys/dev/usb/controller/uhci.c#6 integrate
.. //depot/projects/pci/sys/dev/usb/controller/xhci.c#11 integrate
.. //depot/projects/pci/sys/dev/usb/input/ukbd.c#11 integrate
.. //depot/projects/pci/sys/dev/usb/net/uhso.c#9 integrate
.. //depot/projects/pci/sys/dev/usb/serial/u3g.c#9 integrate
.. //depot/projects/pci/sys/dev/usb/serial/umcs.c#5 integrate
.. //depot/projects/pci/sys/dev/usb/usb_dev.c#6 integrate
.. //depot/projects/pci/sys/dev/usb/usb_device.c#8 integrate
.. //depot/projects/pci/sys/dev/usb/usb_device.h#8 integrate
.. //depot/projects/pci/sys/dev/usb/usb_hub.c#11 integrate
.. //depot/projects/pci/sys/dev/usb/usb_hub.h#4 integrate
.. //depot/projects/pci/sys/dev/usb/usb_request.c#8 integrate
.. //depot/projects/pci/sys/dev/usb/usb_transfer.c#8 integrate
.. //depot/projects/pci/sys/dev/usb/wlan/if_run.c#12 integrate
.. //depot/projects/pci/sys/dev/virtio/block/virtio_blk.c#5 integrate
.. //depot/projects/pci/sys/dev/virtio/random/virtio_random.c#1 branch
.. //depot/projects/pci/sys/dev/virtio/scsi/virtio_scsi.c#4 integrate
.. //depot/projects/pci/sys/dev/vt/hw/xboxfb/xboxfb.c#3 integrate
.. //depot/projects/pci/sys/fs/ext2fs/ext2_inode_cnv.c#7 integrate
.. //depot/projects/pci/sys/fs/nfs/nfs_var.h#12 integrate
.. //depot/projects/pci/sys/fs/nfsserver/nfs_nfsdcache.c#9 integrate
.. //depot/projects/pci/sys/fs/nfsserver/nfs_nfsdkrpc.c#8 integrate
.. //depot/projects/pci/sys/geom/uncompress/g_uncompress.c#3 integrate
.. //depot/projects/pci/sys/i386/conf/NOTES#11 integrate
.. //depot/projects/pci/sys/i386/i386/identcpu.c#8 integrate
.. //depot/projects/pci/sys/ia64/ia64/exception.S#7 integrate
.. //depot/projects/pci/sys/kern/kern_event.c#11 integrate
.. //depot/projects/pci/sys/kern/subr_sglist.c#3 integrate
.. //depot/projects/pci/sys/kern/uipc_mbuf.c#9 integrate
.. //depot/projects/pci/sys/kern/uipc_sockbuf.c#7 integrate
.. //depot/projects/pci/sys/kern/uipc_socket.c#9 integrate
.. //depot/projects/pci/sys/kern/uipc_syscalls.c#14 integrate
.. //depot/projects/pci/sys/mips/cavium/ciu.c#4 integrate
.. //depot/projects/pci/sys/modules/geom/Makefile#4 integrate
.. //depot/projects/pci/sys/modules/geom/geom_uncompress/Makefile#3 integrate
.. //depot/projects/pci/sys/modules/iwnfw/Makefile#7 integrate
.. //depot/projects/pci/sys/modules/iwnfw/iwn105/Makefile#1 branch
.. //depot/projects/pci/sys/modules/sound/driver/ai2s/Makefile#3 integrate
.. //depot/projects/pci/sys/modules/virtio/Makefile#3 integrate
.. //depot/projects/pci/sys/modules/virtio/random/Makefile#1 branch
.. //depot/projects/pci/sys/net/netmap_user.h#6 integrate
.. //depot/projects/pci/sys/net80211/ieee80211_mesh.c#11 integrate
.. //depot/projects/pci/sys/netinet/in.c#12 integrate
.. //depot/projects/pci/sys/netinet/in_mcast.c#8 integrate
.. //depot/projects/pci/sys/netinet/ip_output.c#13 integrate
.. //depot/projects/pci/sys/netinet6/in6.c#14 integrate
.. //depot/projects/pci/sys/netinet6/in6_ifattach.c#10 integrate
.. //depot/projects/pci/sys/netinet6/in6_var.h#8 integrate
.. //depot/projects/pci/sys/netinet6/nd6_rtr.c#9 integrate
.. //depot/projects/pci/sys/netpfil/ipfw/ip_fw_nat.c#4 integrate
.. //depot/projects/pci/sys/powerpc/include/atomic.h#4 integrate
.. //depot/projects/pci/sys/powerpc/powermac/macgpio.c#3 integrate
.. //depot/projects/pci/sys/powerpc/powermac/macgpiovar.h#3 integrate
.. //depot/projects/pci/sys/sys/mbuf.h#10 integrate
.. //depot/projects/pci/sys/sys/random.h#6 integrate
.. //depot/projects/pci/sys/sys/sf_base.h#2 integrate
.. //depot/projects/pci/sys/sys/sf_sync.h#2 integrate
.. //depot/projects/pci/sys/sys/sglist.h#3 integrate
.. //depot/projects/pci/sys/sys/socket.h#8 integrate
.. //depot/projects/pci/sys/vm/vm_pageout.c#11 integrate

Differences ...

==== //depot/projects/pci/sys/amd64/amd64/identcpu.c#9 (text+ko) ====

@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/amd64/identcpu.c 257856 2013-11-08 16:32:30Z kib $");
+__FBSDID("$FreeBSD: head/sys/amd64/amd64/identcpu.c 260557 2014-01-11 22:41:10Z gavin $");
 
 #include "opt_cpu.h"
 
@@ -206,16 +206,16 @@
 	}
 	printf("-class CPU)\n");
 	if (*cpu_vendor)
-		printf("  Origin = \"%s\"", cpu_vendor);
+		printf("  Origin=\"%s\"", cpu_vendor);
 	if (cpu_id)
-		printf("  Id = 0x%x", cpu_id);
+		printf("  Id=0x%x", cpu_id);
 
 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
 	    cpu_vendor_id == CPU_VENDOR_AMD ||
 	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {
-		printf("  Family = 0x%x", CPUID_TO_FAMILY(cpu_id));
-		printf("  Model = 0x%x", CPUID_TO_MODEL(cpu_id));
-		printf("  Stepping = %u", cpu_id & CPUID_STEPPING);
+		printf("  Family=0x%x", CPUID_TO_FAMILY(cpu_id));
+		printf("  Model=0x%x", CPUID_TO_MODEL(cpu_id));
+		printf("  Stepping=%u", cpu_id & CPUID_STEPPING);
 
 		/*
 		 * AMD CPUID Specification

==== //depot/projects/pci/sys/amd64/conf/NOTES#12 (text+ko) ====

@@ -4,7 +4,7 @@
 # This file contains machine dependent kernel configuration notes.  For
 # machine independent notes, look in /sys/conf/NOTES.
 #
-# $FreeBSD: head/sys/amd64/conf/NOTES 260376 2014-01-06 17:23:22Z schweikh $
+# $FreeBSD: head/sys/amd64/conf/NOTES 260847 2014-01-18 06:14:38Z bryanv $
 #
 
 #
@@ -472,6 +472,7 @@
 device		virtio_blk	# VirtIO Block device
 device		virtio_scsi	# VirtIO SCSI device
 device		virtio_balloon	# VirtIO Memory Balloon device
+device		virtio_random	# VirtIO Entropy device
 
 device 		hyperv		# HyperV drivers
 

==== //depot/projects/pci/sys/amd64/include/vmm.h#8 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/include/vmm.h 260466 2014-01-09 03:25:54Z neel $
+ * $FreeBSD: head/sys/amd64/include/vmm.h 260619 2014-01-14 01:55:58Z neel $
  */
 
 #ifndef _VMM_H_
@@ -52,7 +52,7 @@
 typedef void	(*vmm_resume_func_t)(void);
 typedef void *	(*vmi_init_func_t)(struct vm *vm, struct pmap *pmap);
 typedef int	(*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
-				  struct pmap *pmap);
+				  struct pmap *pmap, void *rendezvous_cookie);
 typedef void	(*vmi_cleanup_func_t)(void *vmi);
 typedef int	(*vmi_get_register_t)(void *vmi, int vcpu, int num,
 				      uint64_t *retval);
@@ -136,6 +136,31 @@
 struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
 
 /*
+ * Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'.
+ * The rendezvous 'func(arg)' is not allowed to do anything that will
+ * cause the thread to be put to sleep.
+ *
+ * If the rendezvous is being initiated from a vcpu context then the
+ * 'vcpuid' must refer to that vcpu, otherwise it should be set to -1.
+ *
+ * The caller cannot hold any locks when initiating the rendezvous.
+ *
+ * The implementation of this API may cause vcpus other than those specified
+ * by 'dest' to be stalled. The caller should not rely on any vcpus making
+ * forward progress when the rendezvous is in progress.
+ */
+typedef void (*vm_rendezvous_func_t)(struct vm *vm, int vcpuid, void *arg);
+void vm_smp_rendezvous(struct vm *vm, int vcpuid, cpuset_t dest,
+    vm_rendezvous_func_t func, void *arg);
+
+static __inline int
+vcpu_rendezvous_pending(void *rendezvous_cookie)
+{
+
+	return (*(uintptr_t *)rendezvous_cookie != 0);
+}
+
+/*
  * Return 1 if device indicated by bus/slot/func is supposed to be a
  * pci passthrough device.
  *
@@ -272,6 +297,7 @@
 	VM_EXITCODE_INST_EMUL,
 	VM_EXITCODE_SPINUP_AP,
 	VM_EXITCODE_SPINDOWN_CPU,
+	VM_EXITCODE_RENDEZVOUS,
 	VM_EXITCODE_MAX
 };
 

==== //depot/projects/pci/sys/amd64/vmm/amd/amdv.c#5 (text+ko) ====

@@ -23,11 +23,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260466 2014-01-09 03:25:54Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260619 2014-01-14 01:55:58Z neel $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260466 2014-01-09 03:25:54Z neel $");
+__FBSDID("$FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260619 2014-01-14 01:55:58Z neel $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -67,7 +67,7 @@
 }
 
 static int
-amdv_vmrun(void *arg, int vcpu, register_t rip, struct pmap *pmap)
+amdv_vmrun(void *arg, int vcpu, register_t rip, struct pmap *pmap, void *cookie)
 {
 
 	printf("amdv_vmrun: not implemented\n");

==== //depot/projects/pci/sys/amd64/vmm/intel/vmcs.c#7 (text+ko) ====

@@ -23,13 +23,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260380 2014-01-06 23:16:39Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260531 2014-01-11 03:14:05Z neel $
  */
 
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260380 2014-01-06 23:16:39Z neel $");
+__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260531 2014-01-11 03:14:05Z neel $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -473,7 +473,7 @@
 	switch (exit & 0x8000ffff) {
 	case EXIT_REASON_EXCEPTION:
 	case EXIT_REASON_EXT_INTR:
-		val = vmcs_read(VMCS_EXIT_INTERRUPTION_INFO);
+		val = vmcs_read(VMCS_EXIT_INTR_INFO);
 		db_printf("Interrupt Type: ");
 		switch (val >> 8 & 0x7) {
 		case 0:
@@ -495,7 +495,7 @@
 		db_printf("  Vector: %lu", val & 0xff);
 		if (val & 0x800)
 			db_printf("  Error Code: %lx",
-			    vmcs_read(VMCS_EXIT_INTERRUPTION_ERROR));
+			    vmcs_read(VMCS_EXIT_INTR_ERRCODE));
 		db_printf("\n");
 		break;
 	case EXIT_REASON_EPT_FAULT:

==== //depot/projects/pci/sys/amd64/vmm/intel/vmcs.h#7 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.h 260410 2014-01-07 21:04:49Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.h 260836 2014-01-18 02:20:10Z neel $
  */
 
 #ifndef _VMCS_H_
@@ -97,6 +97,7 @@
 
 /* 16-bit control fields */
 #define	VMCS_VPID			0x00000000
+#define	VMCS_PIR_VECTOR			0x00000002
 
 /* 16-bit guest-state fields */
 #define	VMCS_GUEST_ES_SELECTOR		0x00000800
@@ -129,6 +130,7 @@
 #define	VMCS_TSC_OFFSET			0x00002010
 #define	VMCS_VIRTUAL_APIC		0x00002012
 #define	VMCS_APIC_ACCESS		0x00002014
+#define	VMCS_PIR_DESC			0x00002016
 #define	VMCS_EPTP			0x0000201A
 #define	VMCS_EOI_EXIT0			0x0000201C
 #define	VMCS_EOI_EXIT1			0x0000201E
@@ -177,8 +179,8 @@
 /* 32-bit read-only data fields */
 #define	VMCS_INSTRUCTION_ERROR		0x00004400
 #define	VMCS_EXIT_REASON		0x00004402
-#define	VMCS_EXIT_INTERRUPTION_INFO	0x00004404
-#define	VMCS_EXIT_INTERRUPTION_ERROR	0x00004406
+#define	VMCS_EXIT_INTR_INFO		0x00004404
+#define	VMCS_EXIT_INTR_ERRCODE		0x00004406
 #define	VMCS_IDT_VECTORING_INFO		0x00004408
 #define	VMCS_IDT_VECTORING_ERROR	0x0000440A
 #define	VMCS_EXIT_INSTRUCTION_LENGTH	0x0000440C
@@ -329,11 +331,18 @@
 #define	EXIT_REASON_APIC_WRITE		56
 
 /*
+ * NMI unblocking due to IRET.
+ *
+ * Applies to VM-exits due to hardware exception or EPT fault.
+ */
+#define	EXIT_QUAL_NMIUDTI	(1 << 12)
+/*
  * VMCS interrupt information fields
  */
-#define	VMCS_INTERRUPTION_INFO_VALID	(1U << 31)
-#define	VMCS_INTERRUPTION_INFO_HW_INTR	(0 << 8)
-#define	VMCS_INTERRUPTION_INFO_NMI	(2 << 8)
+#define	VMCS_INTR_VALID		(1U << 31)
+#define	VMCS_INTR_T_MASK	0x700		/* Interruption-info type */
+#define	VMCS_INTR_T_HWINTR	(0 << 8)
+#define	VMCS_INTR_T_NMI		(2 << 8)
 
 /*
  * VMCS IDT-Vectoring information fields

==== //depot/projects/pci/sys/amd64/vmm/intel/vmx.c#9 (text+ko) ====

@@ -23,11 +23,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260466 2014-01-09 03:25:54Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260836 2014-01-18 02:20:10Z neel $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260466 2014-01-09 03:25:54Z neel $");
+__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260836 2014-01-18 02:20:10Z neel $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -45,11 +45,13 @@
 #include <machine/cpufunc.h>
 #include <machine/md_var.h>
 #include <machine/segments.h>
+#include <machine/smp.h>
 #include <machine/specialreg.h>
 #include <machine/vmparam.h>
 
 #include <machine/vmm.h>
 #include "vmm_host.h"
+#include "vmm_ipi.h"
 #include "vmm_msr.h"
 #include "vmm_ktr.h"
 #include "vmm_stat.h"
@@ -93,6 +95,7 @@
 
 #define	VM_EXIT_CTLS_ONE_SETTING					\
 	(VM_EXIT_CTLS_ONE_SETTING_NO_PAT       	|			\
+	VM_EXIT_ACKNOWLEDGE_INTERRUPT		|			\
 	VM_EXIT_SAVE_PAT			|			\
 	VM_EXIT_LOAD_PAT)
 #define	VM_EXIT_CTLS_ZERO_SETTING	VM_EXIT_SAVE_DEBUG_CONTROLS
@@ -171,6 +174,14 @@
 SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, virtual_interrupt_delivery, CTLFLAG_RD,
     &virtual_interrupt_delivery, 0, "APICv virtual interrupt delivery support");
 
+static int posted_interrupts;
+SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupts, CTLFLAG_RD,
+    &posted_interrupts, 0, "APICv posted interrupt support");
+
+static int pirvec;
+SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupt_vector, CTLFLAG_RD,
+    &pirvec, 0, "APICv posted interrupt vector");
+
 static struct unrhdr *vpid_unr;
 static u_int vpid_alloc_failed;
 SYSCTL_UINT(_hw_vmm_vmx, OID_AUTO, vpid_alloc_failed, CTLFLAG_RD,
@@ -441,6 +452,9 @@
 static int
 vmx_cleanup(void)
 {
+	
+	if (pirvec != 0)
+		vmm_ipi_free(pirvec);
 
 	if (vpid_unr != NULL) {
 		delete_unrhdr(vpid_unr);
@@ -636,8 +650,32 @@
 		procbased_ctls |= PROCBASED_USE_TPR_SHADOW;
 		procbased_ctls2 |= procbased2_vid_bits;
 		procbased_ctls2 &= ~PROCBASED2_VIRTUALIZE_X2APIC_MODE;
+
+		/*
+		 * Check for Posted Interrupts only if Virtual Interrupt
+		 * Delivery is enabled.
+		 */
+		error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS,
+		    MSR_VMX_TRUE_PINBASED_CTLS, PINBASED_POSTED_INTERRUPT, 0,
+		    &tmp);
+		if (error == 0) {
+			pirvec = vmm_ipi_alloc();
+			if (pirvec == 0) {
+				if (bootverbose) {
+					printf("vmx_init: unable to allocate "
+					    "posted interrupt vector\n");
+				}
+			} else {
+				posted_interrupts = 1;
+				TUNABLE_INT_FETCH("hw.vmm.vmx.use_apic_pir",
+				    &posted_interrupts);
+			}
+		}
 	}
 
+	if (posted_interrupts)
+		    pinbased_ctls |= PINBASED_POSTED_INTERRUPT;
+
 	/* Initialize EPT */
 	error = ept_init(ipinum);
 	if (error) {
@@ -680,6 +718,31 @@
 	return (0);
 }
 
+static void
+vmx_trigger_hostintr(int vector)
+{
+	uintptr_t func;
+	struct gate_descriptor *gd;
+
+	gd = &idt[vector];
+
+	KASSERT(vector >= 32 && vector <= 255, ("vmx_trigger_hostintr: "
+	    "invalid vector %d", vector));
+	KASSERT(gd->gd_p == 1, ("gate descriptor for vector %d not present",
+	    vector));
+	KASSERT(gd->gd_type == SDT_SYSIGT, ("gate descriptor for vector %d "
+	    "has invalid type %d", vector, gd->gd_type));
+	KASSERT(gd->gd_dpl == SEL_KPL, ("gate descriptor for vector %d "
+	    "has invalid dpl %d", vector, gd->gd_dpl));
+	KASSERT(gd->gd_selector == GSEL(GCODE_SEL, SEL_KPL), ("gate descriptor "
+	    "for vector %d has invalid selector %d", vector, gd->gd_selector));
+	KASSERT(gd->gd_ist == 0, ("gate descriptor for vector %d has invalid "
+	    "IST %d", vector, gd->gd_ist));
+
+	func = ((long)gd->gd_hioffset << 16 | gd->gd_looffset);
+	vmx_call_isr(func);
+}
+
 static int
 vmx_setup_cr_shadow(int which, struct vmcs *vmcs, uint32_t initial)
 {
@@ -822,6 +885,11 @@
 			error += vmwrite(VMCS_EOI_EXIT2, 0);
 			error += vmwrite(VMCS_EOI_EXIT3, 0);
 		}
+		if (posted_interrupts) {
+			error += vmwrite(VMCS_PIR_VECTOR, pirvec);
+			error += vmwrite(VMCS_PIR_DESC,
+			    vtophys(&vmx->pir_desc[i]));
+		}
 		VMCLEAR(vmcs);
 		KASSERT(error == 0, ("vmx_vminit: error customizing the vmcs"));
 
@@ -997,7 +1065,7 @@
 	 * Inject the virtual NMI. The vector must be the NMI IDT entry
 	 * or the VMCS entry check will fail.
 	 */
-	info = VMCS_INTERRUPTION_INFO_NMI | VMCS_INTERRUPTION_INFO_VALID;
+	info = VMCS_INTR_T_NMI | VMCS_INTR_VALID;
 	info |= IDT_NMI;
 	vmcs_write(VMCS_ENTRY_INTR_INFO, info);
 
@@ -1035,7 +1103,7 @@
 	 * because of a pending AST.
 	 */
 	info = vmcs_read(VMCS_ENTRY_INTR_INFO);
-	if (info & VMCS_INTERRUPTION_INFO_VALID)
+	if (info & VMCS_INTR_VALID)
 		return;
 
 	/*
@@ -1066,7 +1134,7 @@
 		goto cantinject;
 
 	/* Inject the interrupt */
-	info = VMCS_INTERRUPTION_INFO_HW_INTR | VMCS_INTERRUPTION_INFO_VALID;
+	info = VMCS_INTR_T_HWINTR | VMCS_INTR_VALID;
 	info |= vector;
 	vmcs_write(VMCS_ENTRY_INTR_INFO, info);
 
@@ -1087,6 +1155,37 @@
 	VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting");
 }
 
+/*
+ * If the Virtual NMIs execution control is '1' then the logical processor
+ * tracks virtual-NMI blocking in the Guest Interruptibility-state field of
+ * the VMCS. An IRET instruction in VMX non-root operation will remove any
+ * virtual-NMI blocking.
+ *
+ * This unblocking occurs even if the IRET causes a fault. In this case the
+ * hypervisor needs to restore virtual-NMI blocking before resuming the guest.
+ */
+static void
+vmx_restore_nmi_blocking(struct vmx *vmx, int vcpuid)
+{
+	uint32_t gi;
+
+	VCPU_CTR0(vmx->vm, vcpuid, "Restore Virtual-NMI blocking");
+	gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
+	gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
+	vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi);
+}
+
+static void
+vmx_clear_nmi_blocking(struct vmx *vmx, int vcpuid)
+{
+	uint32_t gi;
+
+	VCPU_CTR0(vmx->vm, vcpuid, "Clear Virtual-NMI blocking");
+	gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
+	gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
+	vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi);
+}
+
 static int
 vmx_emulate_cr_access(struct vmx *vmx, int vcpu, uint64_t exitqual)
 {
@@ -1376,10 +1475,12 @@
 	int error, handled;
 	struct vmxctx *vmxctx;
 	struct vlapic *vlapic;
-	uint32_t eax, ecx, edx, idtvec_info, idtvec_err, reason;
+	uint32_t eax, ecx, edx, idtvec_info, idtvec_err, intr_info, reason;
 	uint64_t qual, gpa;
 	bool retu;
 
+	CTASSERT((PINBASED_CTLS_ONE_SETTING & PINBASED_VIRTUAL_NMI) != 0);
+
 	handled = 0;
 	vmxctx = &vmx->ctx[vcpu];
 
@@ -1412,9 +1513,20 @@
 				vmcs_write(VMCS_ENTRY_EXCEPTION_ERROR,
 				    idtvec_err);
 			}
+			/*
+			 * If 'virtual NMIs' are being used and the VM-exit
+			 * happened while injecting an NMI during the previous
+			 * VM-entry, then clear "blocking by NMI" in the Guest
+			 * Interruptibility-state.
+			 */
+			if ((idtvec_info & VMCS_INTR_T_MASK) ==
+			    VMCS_INTR_T_NMI) {
+				 vmx_clear_nmi_blocking(vmx, vcpu);
+			}
 			vmcs_write(VMCS_ENTRY_INST_LENGTH, vmexit->inst_length);
 		}
 	default:
+		idtvec_info = 0;
 		break;
 	}
 
@@ -1487,6 +1599,11 @@
 		 * host interrupt handler in the VM's softc. We will inject
 		 * this virtual interrupt during the subsequent VM enter.
 		 */
+		intr_info = vmcs_read(VMCS_EXIT_INTR_INFO);
+		KASSERT((intr_info & VMCS_INTR_VALID) != 0 &&
+		    (intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_HWINTR,
+		    ("VM exit interruption info invalid: %#x", intr_info));
+		vmx_trigger_hostintr(intr_info & 0xff);
 
 		/*
 		 * This is special. We want to treat this as an 'handled'
@@ -1514,6 +1631,23 @@
 		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_CPUID, 1);
 		handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx);
 		break;
+	case EXIT_REASON_EXCEPTION:
+		intr_info = vmcs_read(VMCS_EXIT_INTR_INFO);
+		KASSERT((intr_info & VMCS_INTR_VALID) != 0,
+		    ("VM exit interruption info invalid: %#x", intr_info));
+		/*
+		 * If Virtual NMIs control is 1 and the VM-exit is due to a
+		 * fault encountered during the execution of IRET then we must
+		 * restore the state of "virtual-NMI blocking" before resuming
+		 * the guest.
+		 *
+		 * See "Resuming Guest Software after Handling an Exception".
+		 */
+		if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 &&
+		    (intr_info & 0xff) != IDT_DF &&
+		    (intr_info & EXIT_QUAL_NMIUDTI) != 0)
+			vmx_restore_nmi_blocking(vmx, vcpu);
+		break;
 	case EXIT_REASON_EPT_FAULT:
 		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EPT_FAULT, 1);
 		/*
@@ -1532,6 +1666,17 @@
 			vmexit->u.inst_emul.gla = vmcs_gla();
 			vmexit->u.inst_emul.cr3 = vmcs_guest_cr3();
 		}
+		/*
+		 * If Virtual NMIs control is 1 and the VM-exit is due to an
+		 * EPT fault during the execution of IRET then we must restore
+		 * the state of "virtual-NMI blocking" before resuming.
+		 *
+		 * See description of "NMI unblocking due to IRET" in
+		 * "Exit Qualification for EPT Violations".
+		 */
+		if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 &&
+		    (qual & EXIT_QUAL_NMIUDTI) != 0)
+			vmx_restore_nmi_blocking(vmx, vcpu);
 		break;
 	case EXIT_REASON_APIC_ACCESS:
 		handled = vmx_handle_apic_access(vmx, vcpu, vmexit);
@@ -1596,6 +1741,18 @@
 }
 
 static __inline int
+vmx_exit_rendezvous(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
+{
+
+	vmexit->rip = vmcs_guest_rip();
+	vmexit->inst_length = 0;
+	vmexit->exitcode = VM_EXITCODE_RENDEZVOUS;
+	vmm_stat_incr(vmx->vm, vcpu, VMEXIT_RENDEZVOUS, 1);
+
+	return (UNHANDLED);
+}
+
+static __inline int
 vmx_exit_inst_error(struct vmxctx *vmxctx, int rc, struct vm_exit *vmexit)
 {
 
@@ -1624,10 +1781,12 @@
 }
 
 static int
-vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap)
+vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
+    void *rendezvous_cookie)
 {
 	int rc, handled, launched;
 	struct vmx *vmx;
+	struct vm *vm;
 	struct vmxctx *vmxctx;
 	struct vmcs *vmcs;
 	struct vm_exit *vmexit;
@@ -1636,10 +1795,11 @@
 	uint32_t exit_reason;
 
 	vmx = arg;
+	vm = vmx->vm;
 	vmcs = &vmx->vmcs[vcpu];
 	vmxctx = &vmx->ctx[vcpu];
-	vlapic = vm_lapic(vmx->vm, vcpu);
-	vmexit = vm_exitinfo(vmx->vm, vcpu);
+	vlapic = vm_lapic(vm, vcpu);
+	vmexit = vm_exitinfo(vm, vcpu);
 	launched = 0;
 
 	KASSERT(vmxctx->pmap == pmap,
@@ -1687,6 +1847,12 @@
 			break;
 		}
 
+		if (vcpu_rendezvous_pending(rendezvous_cookie)) {
+			enable_intr();
+			handled = vmx_exit_rendezvous(vmx, vcpu, vmexit);
+			break;
+		}
+
 		vmx_inject_interrupts(vmx, vcpu, vlapic);
 		vmx_run_trace(vmx, vcpu);
 		rc = vmx_enter_guest(vmxctx, launched);
@@ -1720,9 +1886,9 @@
 	}
 
 	if (!handled)
-		vmm_stat_incr(vmx->vm, vcpu, VMEXIT_USERSPACE, 1);
+		vmm_stat_incr(vm, vcpu, VMEXIT_USERSPACE, 1);
 
-	VCPU_CTR1(vmx->vm, vcpu, "returning from vmx_run: exitcode %d",
+	VCPU_CTR1(vm, vcpu, "returning from vmx_run: exitcode %d",
 	    vmexit->exitcode);
 
 	VMCLEAR(vmcs);
@@ -1945,11 +2111,11 @@
 	if (error)
 		return (error);
 
-	if (info & VMCS_INTERRUPTION_INFO_VALID)
+	if (info & VMCS_INTR_VALID)
 		return (EAGAIN);
 
 	info = vector | (type_map[type] << 8) | (code_valid ? 1 << 11 : 0);
-	info |= VMCS_INTERRUPTION_INFO_VALID;
+	info |= VMCS_INTR_VALID;
 	error = vmcs_setreg(vmcs, 0, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), info);
 	if (error != 0)
 		return (error);
@@ -2101,19 +2267,9 @@
         return (retval);
 }
 
-/*
- * Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM).
- */
-struct pir_desc {
-	uint64_t	pir[4];
-	uint64_t	pending;
-	uint64_t	unused[3];
-} __aligned(64);
-CTASSERT(sizeof(struct pir_desc) == 64);
-
 struct vlapic_vtx {
 	struct vlapic	vlapic;
-	struct pir_desc	pir_desc;
+	struct pir_desc	*pir_desc;
 };
 
 #define	VMX_CTR_PIR(vm, vcpuid, pir_desc, notify, vector, level, msg)	\
@@ -2143,7 +2299,7 @@
 	 * XXX need to deal with level triggered interrupts
 	 */
 	vlapic_vtx = (struct vlapic_vtx *)vlapic;
-	pir_desc = &vlapic_vtx->pir_desc;
+	pir_desc = vlapic_vtx->pir_desc;
 
 	/*
 	 * Keep track of interrupt requests in the PIR descriptor. This is
@@ -2177,7 +2333,7 @@
 	KASSERT(vecptr == NULL, ("vmx_pending_intr: vecptr must be NULL"));
 
 	vlapic_vtx = (struct vlapic_vtx *)vlapic;
-	pir_desc = &vlapic_vtx->pir_desc;
+	pir_desc = vlapic_vtx->pir_desc;
 
 	pending = atomic_load_acq_long(&pir_desc->pending);
 	if (!pending)
@@ -2215,6 +2371,13 @@
 	panic("vmx_intr_accepted: not expected to be called");
 }
 
+static void
+vmx_post_intr(struct vlapic *vlapic, int hostcpu)
+{
+
+	ipi_cpu(hostcpu, pirvec);
+}
+
 /*
  * Transfer the pending interrupts in the PIR descriptor to the IRR
  * in the virtual APIC page.
@@ -2230,7 +2393,7 @@
 	uint16_t intr_status_old, intr_status_new;
 
 	vlapic_vtx = (struct vlapic_vtx *)vlapic;
-	pir_desc = &vlapic_vtx->pir_desc;
+	pir_desc = vlapic_vtx->pir_desc;
 	if (atomic_cmpset_long(&pir_desc->pending, 1, 0) == 0) {
 		VCPU_CTR0(vlapic->vm, vlapic->vcpuid, "vmx_inject_pir: "
 		    "no posted interrupt pending");
@@ -2295,6 +2458,7 @@
 {
 	struct vmx *vmx;
 	struct vlapic *vlapic;
+	struct vlapic_vtx *vlapic_vtx;
 	
 	vmx = arg;
 
@@ -2303,12 +2467,18 @@
 	vlapic->vcpuid = vcpuid;
 	vlapic->apic_page = (struct LAPIC *)&vmx->apic_page[vcpuid];
 
+	vlapic_vtx = (struct vlapic_vtx *)vlapic;
+	vlapic_vtx->pir_desc = &vmx->pir_desc[vcpuid];
+
 	if (virtual_interrupt_delivery) {
 		vlapic->ops.set_intr_ready = vmx_set_intr_ready;
 		vlapic->ops.pending_intr = vmx_pending_intr;
 		vlapic->ops.intr_accepted = vmx_intr_accepted;
 	}
 
+	if (posted_interrupts)
+		vlapic->ops.post_intr = vmx_post_intr;
+
 	vlapic_init(vlapic);
 
 	return (vlapic);

==== //depot/projects/pci/sys/amd64/vmm/intel/vmx.h#6 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/intel/vmx.h 260167 2014-01-01 21:17:08Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/intel/vmx.h 260532 2014-01-11 04:22:00Z neel $
  */
 
 #ifndef _VMX_H_
@@ -93,11 +93,20 @@
 };
 CTASSERT(sizeof(struct apic_page) == PAGE_SIZE);
 
+/* Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM) */
+struct pir_desc {
+	uint64_t	pir[4];
+	uint64_t	pending;
+	uint64_t	unused[3];
+} __aligned(64);
+CTASSERT(sizeof(struct pir_desc) == 64);
+
 /* virtual machine softc */
 struct vmx {
 	struct vmcs	vmcs[VM_MAXCPU];	/* one vmcs per virtual cpu */
 	struct apic_page apic_page[VM_MAXCPU];	/* one apic page per vcpu */
 	char		msr_bitmap[PAGE_SIZE];
+	struct pir_desc	pir_desc[VM_MAXCPU];
 	struct msr_entry guest_msrs[VM_MAXCPU][GUEST_MSR_MAX_ENTRIES];
 	struct vmxctx	ctx[VM_MAXCPU];
 	struct vmxcap	cap[VM_MAXCPU];
@@ -108,6 +117,7 @@
 CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0);
 CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0);
 CTASSERT((offsetof(struct vmx, guest_msrs) & 15) == 0);
+CTASSERT((offsetof(struct vmx, pir_desc[0]) & 63) == 0);
 
 #define	VMX_GUEST_VMEXIT	0
 #define	VMX_VMRESUME_ERROR	1
@@ -115,6 +125,7 @@
 #define	VMX_INVEPT_ERROR	3
 int	vmx_enter_guest(struct vmxctx *ctx, int launched);
 void	vmx_exit_guest(void);
+void	vmx_call_isr(uintptr_t entry);
 
 u_long	vmx_fix_cr0(u_long cr0);
 u_long	vmx_fix_cr4(u_long cr4);

==== //depot/projects/pci/sys/amd64/vmm/intel/vmx_genassym.c#6 (text+ko) ====

@@ -23,11 +23,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260167 2014-01-01 21:17:08Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260531 2014-01-11 03:14:05Z neel $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260167 2014-01-01 21:17:08Z neel $");
+__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260531 2014-01-11 03:14:05Z neel $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -84,3 +84,6 @@
 
 ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active));
 ASSYM(PM_EPTGEN, offsetof(struct pmap, pm_eptgen));
+
+ASSYM(KERNEL_SS, GSEL(GDATA_SEL, SEL_KPL));
+ASSYM(KERNEL_CS, GSEL(GCODE_SEL, SEL_KPL));

==== //depot/projects/pci/sys/amd64/vmm/intel/vmx_support.S#4 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/intel/vmx_support.S 260238 2014-01-03 19:29:33Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/intel/vmx_support.S 260531 2014-01-11 03:14:05Z neel $
  */
 
 #include <machine/asmacros.h>
@@ -234,3 +234,21 @@
 	movl	$VMX_GUEST_VMEXIT, %eax
 	ret
 END(vmx_exit_guest)
+
+/*
+ * %rdi = interrupt handler entry point
+ *
+ * Calling sequence described in the "Instruction Set Reference" for the "INT"
+ * instruction in Intel SDM, Vol 2.
+ */
+ENTRY(vmx_call_isr)
+	mov	%rsp, %r11			/* save %rsp */
+	and	$~0xf, %rsp			/* align on 16-byte boundary */
+	pushq	$KERNEL_SS			/* %ss */
+	pushq	%r11				/* %rsp */
+	pushfq					/* %rflags */
+	pushq	$KERNEL_CS			/* %cs */
+	cli					/* disable interrupts */
+	callq	*%rdi				/* push %rip and call isr */
+	ret
+END(vmx_call_isr)

==== //depot/projects/pci/sys/amd64/vmm/io/vioapic.c#3 (text+ko) ====

@@ -24,11 +24,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/vmm/io/vioapic.c 259482 2013-12-16 19:59:31Z neel $
+ * $FreeBSD: head/sys/amd64/vmm/io/vioapic.c 260619 2014-01-14 01:55:58Z neel $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vioapic.c 259482 2013-12-16 19:59:31Z neel $");
+__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vioapic.c 260619 2014-01-14 01:55:58Z neel $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -222,8 +222,52 @@
 	return (vioapic_set_irqstate(vm, irq, IRQSTATE_PULSE));
 }
 
+/*
+ * Reset the vlapic's trigger-mode register to reflect the ioapic pin
+ * configuration.
+ */
+static void
+vioapic_update_tmr(struct vm *vm, int vcpuid, void *arg)
+{
+	struct vioapic *vioapic;
+	struct vlapic *vlapic;
+	uint32_t low, high, dest;
+	int delmode, pin, vector;
+	bool level, phys;
+
+	vlapic = vm_lapic(vm, vcpuid);
+	vioapic = vm_ioapic(vm);
+
+	VIOAPIC_LOCK(vioapic);
+	/*
+	 * Reset all vectors to be edge-triggered.
+	 */
+	vlapic_reset_tmr(vlapic);
+	for (pin = 0; pin < REDIR_ENTRIES; pin++) {
+		low = vioapic->rtbl[pin].reg;
+		high = vioapic->rtbl[pin].reg >> 32;
+
+		level = low & IOART_TRGRLVL ? true : false;
+		if (!level)
+			continue;
+
+		/*
+		 * For a level-triggered 'pin' let the vlapic figure out if
+		 * an assertion on this 'pin' would result in an interrupt
+		 * being delivered to it. If yes, then it will modify the
+		 * TMR bit associated with this vector to level-triggered.
+		 */
+		phys = ((low & IOART_DESTMOD) == IOART_DESTPHY);
+		delmode = low & IOART_DELMOD;
+		vector = low & IOART_INTVEC;
+		dest = high >> APIC_ID_SHIFT;
+		vlapic_set_tmr_level(vlapic, dest, phys, delmode, vector);
+	}
+	VIOAPIC_UNLOCK(vioapic);
+}
+
 static uint32_t
-vioapic_read(struct vioapic *vioapic, uint32_t addr)

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401182123.s0ILNBX2016953>