Author: jhb
Date: Wed Jul 30 00:00:12 2014
New Revision: 269281
URL: http://svnweb.freebsd.org/changeset/base/269281

Log:
  - Output a summary of optional VT-x features in dmesg similar to CPU
    features.  If bootverbose is enabled, a detailed list is provided;
    otherwise, a single-line summary is displayed.
  - Add read-only sysctls for optional VT-x capabilities used by bhyve
    under a new hw.vmm.vmx.cap node. Move a few exiting sysctls that
    indicate the presence of optional capabilities under this node.
  
  CR:           https://phabric.freebsd.org/D498
  Reviewed by:  grehan, neel
  MFC after:    1 week

Modified:
  head/sys/amd64/amd64/identcpu.c
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/intel/vmx_msr.c
  head/sys/amd64/vmm/intel/vmx_msr.h
  head/sys/x86/include/specialreg.h

Modified: head/sys/amd64/amd64/identcpu.c
==============================================================================
--- head/sys/amd64/amd64/identcpu.c     Tue Jul 29 23:42:51 2014        
(r269280)
+++ head/sys/amd64/amd64/identcpu.c     Wed Jul 30 00:00:12 2014        
(r269281)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/specialreg.h>
 #include <machine/md_var.h>
 
+#include <amd64/vmm/intel/vmx_controls.h>
 #include <x86/isa/icu.h>
 
 /* XXX - should be in header file: */
@@ -73,6 +74,7 @@ static u_int find_cpu_vendor_id(void);
 static void print_AMD_info(void);
 static void print_AMD_assoc(int i);
 static void print_via_padlock_info(void);
+static void print_vmx_info(void);
 
 int    cpu_class;
 char machine[] = "amd64";
@@ -428,6 +430,9 @@ printcpuinfo(void)
                        if (via_feature_rng != 0 || via_feature_xcrypt != 0)
                                print_via_padlock_info();
 
+                       if (cpu_feature2 & CPUID2_VMX)
+                               print_vmx_info();
+
                        if ((cpu_feature & CPUID_HTT) &&
                            cpu_vendor_id == CPU_VENDOR_AMD)
                                cpu_feature &= ~CPUID_HTT;
@@ -722,3 +727,197 @@ print_via_padlock_info(void)
        "\015RSA"               /* PMM */
        );
 }
+
+static uint32_t
+vmx_settable(uint64_t basic, int msr, int true_msr)
+{
+       uint64_t val;
+
+       if (basic & (1UL << 55))
+               val = rdmsr(true_msr);
+       else
+               val = rdmsr(msr);
+
+       /* Just report the controls that can be set to 1. */
+       return (val >> 32);
+}
+
+static void
+print_vmx_info(void)
+{
+       uint64_t basic, msr;
+       uint32_t entry, exit, mask, pin, proc, proc2;
+       int comma;
+
+       printf("\n  VT-x: ");
+       msr = rdmsr(MSR_IA32_FEATURE_CONTROL);
+       if (!(msr & IA32_FEATURE_CONTROL_VMX_EN))
+               printf("(disabled in BIOS) ");
+       basic = rdmsr(MSR_VMX_BASIC);
+       pin = vmx_settable(basic, MSR_VMX_PINBASED_CTLS,
+           MSR_VMX_TRUE_PINBASED_CTLS);
+       proc = vmx_settable(basic, MSR_VMX_PROCBASED_CTLS,
+           MSR_VMX_TRUE_PROCBASED_CTLS);
+       if (proc & PROCBASED_SECONDARY_CONTROLS)
+               proc2 = vmx_settable(basic, MSR_VMX_PROCBASED_CTLS2,
+                   MSR_VMX_PROCBASED_CTLS2);
+       else
+               proc2 = 0;
+       exit = vmx_settable(basic, MSR_VMX_EXIT_CTLS, MSR_VMX_TRUE_EXIT_CTLS);
+       entry = vmx_settable(basic, MSR_VMX_ENTRY_CTLS, 
MSR_VMX_TRUE_ENTRY_CTLS);
+
+       if (!bootverbose) {
+               comma = 0;
+               if (exit & VM_EXIT_SAVE_PAT && exit & VM_EXIT_LOAD_PAT &&
+                   entry & VM_ENTRY_LOAD_PAT) {
+                       printf("%sPAT", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc & PROCBASED_HLT_EXITING) {
+                       printf("%sHLT", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc & PROCBASED_MTF) {
+                       printf("%sMTF", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc & PROCBASED_PAUSE_EXITING) {
+                       printf("%sPAUSE", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc2 & PROCBASED2_ENABLE_EPT) {
+                       printf("%sEPT", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc2 & PROCBASED2_UNRESTRICTED_GUEST) {
+                       printf("%sUG", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc2 & PROCBASED2_ENABLE_VPID) {
+                       printf("%sVPID", comma ? "," : "");
+                       comma = 1;
+               }
+               if (proc & PROCBASED_USE_TPR_SHADOW &&
+                   proc2 & PROCBASED2_VIRTUALIZE_APIC_ACCESSES &&
+                   proc2 & PROCBASED2_VIRTUALIZE_X2APIC_MODE &&
+                   proc2 & PROCBASED2_APIC_REGISTER_VIRTUALIZATION &&
+                   proc2 & PROCBASED2_VIRTUAL_INTERRUPT_DELIVERY) {
+                       printf("%sVID", comma ? "," : "");
+                       comma = 1;
+                       if (pin & PINBASED_POSTED_INTERRUPT)
+                               printf(",PostIntr");
+               }
+               return;
+       }
+
+       mask = basic >> 32;
+       printf("Basic Features=0x%b", mask,
+       "\020"
+       "\02132PA"              /* 32-bit physical addresses */
+       "\022SMM"               /* SMM dual-monitor */
+       "\027INS/OUTS"          /* VM-exit info for INS and OUTS */
+       "\030TRUE"              /* TRUE_CTLS MSRs */
+       );
+       printf("\n        Pin-Based Controls=0x%b", pin,
+       "\020"
+       "\001ExtINT"            /* External-interrupt exiting */
+       "\004NMI"               /* NMI exiting */
+       "\006VNMI"              /* Virtual NMIs */
+       "\007PreTmr"            /* Activate VMX-preemption timer */
+       "\010PostIntr"          /* Process posted interrupts */
+       );
+       printf("\n        Primary Processor Controls=0x%b", proc,
+       "\020"
+       "\003INTWIN"            /* Interrupt-window exiting */
+       "\004TSCOff"            /* Use TSC offsetting */
+       "\010HLT"               /* HLT exiting */
+       "\012INVLPG"            /* INVLPG exiting */
+       "\013MWAIT"             /* MWAIT exiting */
+       "\014RDPMC"             /* RDPMC exiting */
+       "\015RDTSC"             /* RDTSC exiting */
+       "\020CR3-LD"            /* CR3-load exiting */
+       "\021CR3-ST"            /* CR3-store exiting */
+       "\024CR8-LD"            /* CR8-load exiting */
+       "\025CR8-ST"            /* CR8-store exiting */
+       "\026TPR"               /* Use TPR shadow */
+       "\027NMIWIN"            /* NMI-window exiting */
+       "\030MOV-DR"            /* MOV-DR exiting */
+       "\031IO"                /* Unconditional I/O exiting */
+       "\032IOmap"             /* Use I/O bitmaps */
+       "\034MTF"               /* Monitor trap flag */
+       "\035MSRmap"            /* Use MSR bitmaps */
+       "\036MONITOR"           /* MONITOR exiting */
+       "\037PAUSE"             /* PAUSE exiting */
+       );
+       if (proc & PROCBASED_SECONDARY_CONTROLS)
+               printf("\n        Secondary Processor Controls=0x%b", proc2,
+               "\020"
+               "\001APIC"              /* Virtualize APIC accesses */
+               "\002EPT"               /* Enable EPT */
+               "\003DT"                /* Descriptor-table exiting */
+               "\004RDTSCP"            /* Enable RDTSCP */
+               "\005x2APIC"            /* Virtualize x2APIC mode */
+               "\006VPID"              /* Enable VPID */
+               "\007WBINVD"            /* WBINVD exiting */
+               "\010UG"                /* Unrestricted guest */
+               "\011APIC-reg"          /* APIC-register virtualization */
+               "\012VID"               /* Virtual-interrupt delivery */
+               "\013PAUSE-loop"        /* PAUSE-loop exiting */
+               "\014RDRAND"            /* RDRAND exiting */
+               "\015INVPCID"           /* Enable INVPCID */
+               "\016VMFUNC"            /* Enable VM functions */
+               "\017VMCS"              /* VMCS shadowing */
+               "\020EPT#VE"            /* EPT-violation #VE */
+               "\021XSAVES"            /* Enable XSAVES/XRSTORS */
+               );
+       printf("\n        Exit Controls=0x%b", mask,
+       "\020"
+       "\003DR"                /* Save debug controls */
+                               /* Ignore Host address-space size */
+       "\015PERF"              /* Load MSR_PERF_GLOBAL_CTRL */
+       "\020AckInt"            /* Acknowledge interrupt on exit */
+       "\023PAT-SV"            /* Save MSR_PAT */
+       "\024PAT-LD"            /* Load MSR_PAT */
+       "\025EFER-SV"           /* Save MSR_EFER */
+       "\026EFER-LD"           /* Load MSR_EFER */
+       "\027PTMR-SV"           /* Save VMX-preemption timer value */
+       );
+       printf("\n        Entry Controls=0x%b", mask,
+       "\020"
+       "\003DR"                /* Save debug controls */
+                               /* Ignore IA-32e mode guest */
+                               /* Ignore Entry to SMM */
+                               /* Ignore Deactivate dual-monitor treatment */
+       "\016PERF"              /* Load MSR_PERF_GLOBAL_CTRL */
+       "\017PAT"               /* Load MSR_PAT */
+       "\020EFER"              /* Load MSR_EFER */
+       );
+       if (proc & PROCBASED_SECONDARY_CONTROLS &&
+           (proc2 & (PROCBASED2_ENABLE_EPT | PROCBASED2_ENABLE_VPID)) != 0) {
+               msr = rdmsr(MSR_VMX_EPT_VPID_CAP);
+               mask = msr;
+               printf("\n        EPT Features=0x%b", mask,
+               "\020"
+               "\001XO"                /* Execute-only translations */
+               "\007PW4"               /* Page-walk length of 4 */
+               "\011UC"                /* EPT paging-structure mem can be UC */
+               "\017WB"                /* EPT paging-structure mem can be WB */
+               "\0212M"                /* EPT PDE can map a 2-Mbyte page */
+               "\0221G"                /* EPT PDPTE can map a 1-Gbyte page */
+               "\025INVEPT"            /* INVEPT is supported */
+               "\026AD"                /* Accessed and dirty flags for EPT */
+               "\032single"            /* INVEPT single-context type */
+               "\033all"               /* INVEPT all-context type */
+               );
+               mask = msr >> 32;
+               printf("\n        VPID Features=0x%b", mask,
+               "\020"
+               "\001INVVPID"           /* INVVPID is supported */
+               "\011individual"        /* INVVPID individual-address type */
+               "\012single"            /* INVVPID single-context type */
+               "\013all"               /* INVVPID all-context type */
+                /* INVVPID single-context-retaining-globals type */
+               "\014single-globals"    
+               );
+       }
+}

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c      Tue Jul 29 23:42:51 2014        
(r269280)
+++ head/sys/amd64/vmm/intel/vmx.c      Wed Jul 30 00:00:12 2014        
(r269281)
@@ -149,8 +149,6 @@ SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_
 SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_zeros_mask, CTLFLAG_RD,
             &cr4_zeros_mask, 0, NULL);
 
-static int vmx_no_patmsr;
-
 static int vmx_initialized;
 SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, initialized, CTLFLAG_RD,
           &vmx_initialized, 0, "Intel VMX initialized");
@@ -158,18 +156,38 @@ SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, initia
 /*
  * Optional capabilities
  */
+static SYSCTL_NODE(_hw_vmm_vmx, OID_AUTO, cap, CTLFLAG_RW, NULL, NULL);
+
+static int vmx_patmsr;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, patmsr, CTLFLAG_RD, &vmx_patmsr, 0,
+    "PAT MSR saved and restored in VCMS");
+
 static int cap_halt_exit;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, halt_exit, CTLFLAG_RD, &cap_halt_exit, 0,
+    "HLT triggers a VM-exit");
+
 static int cap_pause_exit;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, pause_exit, CTLFLAG_RD, &cap_pause_exit,
+    0, "PAUSE triggers a VM-exit");
+
 static int cap_unrestricted_guest;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, unrestricted_guest, CTLFLAG_RD,
+    &cap_unrestricted_guest, 0, "Unrestricted guests");
+
 static int cap_monitor_trap;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, monitor_trap, CTLFLAG_RD,
+    &cap_monitor_trap, 0, "Monitor trap flag");
+
 static int cap_invpcid;
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, invpcid, CTLFLAG_RD, &cap_invpcid,
+    0, "Guests are allowed to use INVPCID");
 
 static int virtual_interrupt_delivery;
-SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, virtual_interrupt_delivery, CTLFLAG_RD,
+SYSCTL_INT(_hw_vmm_vmx_cap, 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,
+SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, posted_interrupts, CTLFLAG_RD,
     &posted_interrupts, 0, "APICv posted interrupt support");
 
 static int pirvec;
@@ -618,6 +636,7 @@ vmx_init(int ipinum)
        }
 
        /* Check support for VM-exit controls */
+       vmx_patmsr = 1;
        error = vmx_set_ctlreg(MSR_VMX_EXIT_CTLS, MSR_VMX_TRUE_EXIT_CTLS,
                               VM_EXIT_CTLS_ONE_SETTING,
                               VM_EXIT_CTLS_ZERO_SETTING,
@@ -637,12 +656,12 @@ vmx_init(int ipinum)
                        if (bootverbose)
                                printf("vmm: PAT MSR access not supported\n");
                        guest_msr_valid(MSR_PAT);
-                       vmx_no_patmsr = 1;
+                       vmx_patmsr = 0;
                }
        }
 
        /* Check support for VM-entry controls */
-       if (!vmx_no_patmsr) {
+       if (vmx_patmsr) {
                error = vmx_set_ctlreg(MSR_VMX_ENTRY_CTLS,
                                       MSR_VMX_TRUE_ENTRY_CTLS,
                                       VM_ENTRY_CTLS_ONE_SETTING,
@@ -918,7 +937,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
         * MSR_PAT save/restore support, leave access disabled so accesses
         * will be trapped.
         */
-       if (!vmx_no_patmsr && guest_msr_rw(vmx, MSR_PAT))
+       if (vmx_patmsr && guest_msr_rw(vmx, MSR_PAT))
                panic("vmx_vminit: error setting guest pat msr access");
 
        vpid_alloc(vpid, VM_MAXCPU);

Modified: head/sys/amd64/vmm/intel/vmx_msr.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx_msr.c  Tue Jul 29 23:42:51 2014        
(r269280)
+++ head/sys/amd64/vmm/intel/vmx_msr.c  Wed Jul 30 00:00:12 2014        
(r269281)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 
 #include <machine/cpufunc.h>
+#include <machine/specialreg.h>
 
 #include "vmx_msr.h"
 

Modified: head/sys/amd64/vmm/intel/vmx_msr.h
==============================================================================
--- head/sys/amd64/vmm/intel/vmx_msr.h  Tue Jul 29 23:42:51 2014        
(r269280)
+++ head/sys/amd64/vmm/intel/vmx_msr.h  Wed Jul 30 00:00:12 2014        
(r269281)
@@ -29,29 +29,6 @@
 #ifndef _VMX_MSR_H_
 #define        _VMX_MSR_H_
 
-#define        MSR_VMX_BASIC                   0x480
-#define        MSR_VMX_EPT_VPID_CAP            0x48C
-
-#define        MSR_VMX_PROCBASED_CTLS          0x482
-#define        MSR_VMX_TRUE_PROCBASED_CTLS     0x48E
-
-#define        MSR_VMX_PINBASED_CTLS           0x481
-#define        MSR_VMX_TRUE_PINBASED_CTLS      0x48D
-
-#define        MSR_VMX_PROCBASED_CTLS2         0x48B
-
-#define        MSR_VMX_EXIT_CTLS               0x483
-#define        MSR_VMX_TRUE_EXIT_CTLS          0x48f
-
-#define        MSR_VMX_ENTRY_CTLS              0x484
-#define        MSR_VMX_TRUE_ENTRY_CTLS         0x490
-
-#define        MSR_VMX_CR0_FIXED0              0x486
-#define        MSR_VMX_CR0_FIXED1              0x487
-
-#define        MSR_VMX_CR4_FIXED0              0x488
-#define        MSR_VMX_CR4_FIXED1              0x489
-
 uint32_t vmx_revision(void);
 
 int vmx_set_ctlreg(int ctl_reg, int true_ctl_reg, uint32_t ones_mask,

Modified: head/sys/x86/include/specialreg.h
==============================================================================
--- head/sys/x86/include/specialreg.h   Tue Jul 29 23:42:51 2014        
(r269280)
+++ head/sys/x86/include/specialreg.h   Wed Jul 30 00:00:12 2014        
(r269281)
@@ -436,6 +436,25 @@
 #define        MSR_MC4_MISC            0x413
 
 /*
+ * VMX MSRs
+ */
+#define        MSR_VMX_BASIC           0x480
+#define        MSR_VMX_PINBASED_CTLS   0x481
+#define        MSR_VMX_PROCBASED_CTLS  0x482
+#define        MSR_VMX_EXIT_CTLS       0x483
+#define        MSR_VMX_ENTRY_CTLS      0x484
+#define        MSR_VMX_CR0_FIXED0      0x486
+#define        MSR_VMX_CR0_FIXED1      0x487
+#define        MSR_VMX_CR4_FIXED0      0x488
+#define        MSR_VMX_CR4_FIXED1      0x489
+#define        MSR_VMX_PROCBASED_CTLS2 0x48b
+#define        MSR_VMX_EPT_VPID_CAP    0x48c
+#define        MSR_VMX_TRUE_PINBASED_CTLS      0x48d
+#define        MSR_VMX_TRUE_PROCBASED_CTLS     0x48e
+#define        MSR_VMX_TRUE_EXIT_CTLS  0x48f
+#define        MSR_VMX_TRUE_ENTRY_CTLS 0x490
+
+/*
  * X2APIC MSRs
  */
 #define        MSR_APIC_ID             0x802
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to