WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEN] Simplify VMCS allocation (never big

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Simplify VMCS allocation (never bigger than a page).
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 25 Sep 2006 18:40:17 +0000
Delivery-date: Mon, 25 Sep 2006 11:41:27 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 0f9908c2c5c75d787d70a13b01506d1dca49290a
# Parent  f5fd563bcc84f5bb67ceb1031c127ce44515507a
[XEN] Simplify VMCS allocation (never bigger than a page).
Dynamically determine reserved bits in execution-control
fields.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/vmcs.c        |  135 +++++++++++++++++++++++++++++--------
 xen/arch/x86/hvm/vmx/vmx.c         |   47 +-----------
 xen/include/asm-x86/hvm/vmx/vmcs.h |   15 ++--
 xen/include/asm-x86/hvm/vmx/vmx.h  |   67 ------------------
 4 files changed, 124 insertions(+), 140 deletions(-)

diff -r f5fd563bcc84 -r 0f9908c2c5c7 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Mon Sep 25 17:45:28 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Mon Sep 25 17:46:08 2006 +0100
@@ -37,36 +37,119 @@
 #include <xen/keyhandler.h>
 #include <asm/shadow.h>
 
-static int vmcs_size;
-static int vmcs_order;
+/* Basic flags for Pin-based VM-execution controls. */
+#define MONITOR_PIN_BASED_EXEC_CONTROLS                 \
+    ( PIN_BASED_EXT_INTR_MASK |                         \
+      PIN_BASED_NMI_EXITING )
+
+/* Basic flags for CPU-based VM-execution controls. */
+#ifdef __x86_64__
+#define MONITOR_CPU_BASED_EXEC_CONTROLS_SUBARCH         \
+    ( CPU_BASED_CR8_LOAD_EXITING |                      \
+      CPU_BASED_CR8_STORE_EXITING )
+#else
+#define MONITOR_CPU_BASED_EXEC_CONTROLS_SUBARCH 0
+#endif
+#define MONITOR_CPU_BASED_EXEC_CONTROLS                 \
+    ( MONITOR_CPU_BASED_EXEC_CONTROLS_SUBARCH |         \
+      CPU_BASED_HLT_EXITING |                           \
+      CPU_BASED_INVDPG_EXITING |                        \
+      CPU_BASED_MWAIT_EXITING |                         \
+      CPU_BASED_MOV_DR_EXITING |                        \
+      CPU_BASED_ACTIVATE_IO_BITMAP |                    \
+      CPU_BASED_USE_TSC_OFFSETING )
+
+/* Basic flags for VM-Exit controls. */
+#ifdef __x86_64__
+#define MONITOR_VM_EXIT_CONTROLS_SUBARCH VM_EXIT_IA32E_MODE
+#else
+#define MONITOR_VM_EXIT_CONTROLS_SUBARCH 0
+#endif
+#define MONITOR_VM_EXIT_CONTROLS                        \
+    ( MONITOR_VM_EXIT_CONTROLS_SUBARCH |                \
+      VM_EXIT_ACK_INTR_ON_EXIT )
+
+/* Basic flags for VM-Entry controls. */
+#define MONITOR_VM_ENTRY_CONTROLS                       0x00000000
+
+/* Dynamic (run-time adjusted) execution control flags. */
+static u32 vmx_pin_based_exec_control;
+static u32 vmx_cpu_based_exec_control;
+static u32 vmx_vmexit_control;
+static u32 vmx_vmentry_control;
+
 static u32 vmcs_revision_id;
 
+static u32 adjust_vmx_controls(u32 ctrls, u32 msr)
+{
+    u32 vmx_msr_low, vmx_msr_high;
+
+    rdmsr(msr, vmx_msr_low, vmx_msr_high);
+
+    /* Bit == 0 means must be zero. */
+    BUG_ON(ctrls & ~vmx_msr_high);
+
+    /* Bit == 1 means must be one. */
+    ctrls |= vmx_msr_low;
+
+    return ctrls;
+}
+
 void vmx_init_vmcs_config(void)
 {
     u32 vmx_msr_low, vmx_msr_high;
-
-    if ( vmcs_size )
-        return;
+    u32 _vmx_pin_based_exec_control;
+    u32 _vmx_cpu_based_exec_control;
+    u32 _vmx_vmexit_control;
+    u32 _vmx_vmentry_control;
+
+    _vmx_pin_based_exec_control =
+        adjust_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
+                            MSR_IA32_VMX_PINBASED_CTLS_MSR);
+    _vmx_cpu_based_exec_control =
+        adjust_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
+                            MSR_IA32_VMX_PROCBASED_CTLS_MSR);
+    _vmx_vmexit_control =
+        adjust_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
+                            MSR_IA32_VMX_EXIT_CTLS_MSR);
+    _vmx_vmentry_control =
+        adjust_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
+                            MSR_IA32_VMX_ENTRY_CTLS_MSR);
 
     rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
 
-    vmcs_revision_id = vmx_msr_low;
-
-    vmcs_size  = vmx_msr_high & 0x1fff;
-    vmcs_order = get_order_from_bytes(vmcs_size);
+    if ( smp_processor_id() == 0 )
+    {
+        vmcs_revision_id = vmx_msr_low;
+        vmx_pin_based_exec_control = _vmx_pin_based_exec_control;
+        vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
+        vmx_vmexit_control         = _vmx_vmexit_control;
+        vmx_vmentry_control        = _vmx_vmentry_control;
+    }
+    else
+    {
+        BUG_ON(vmcs_revision_id != vmx_msr_low);
+        BUG_ON(vmx_pin_based_exec_control != _vmx_pin_based_exec_control);
+        BUG_ON(vmx_cpu_based_exec_control != _vmx_cpu_based_exec_control);
+        BUG_ON(vmx_vmexit_control != _vmx_vmexit_control);
+        BUG_ON(vmx_vmentry_control != _vmx_vmentry_control);
+    }
+
+    /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
+    BUG_ON((vmx_msr_high & 0x1fff) > PAGE_SIZE);
 }
 
 static struct vmcs_struct *vmx_alloc_vmcs(void)
 {
     struct vmcs_struct *vmcs;
 
-    if ( (vmcs = alloc_xenheap_pages(vmcs_order)) == NULL )
+    if ( (vmcs = alloc_xenheap_page()) == NULL )
     {
         DPRINTK("Failed to allocate VMCS.\n");
         return NULL;
     }
 
-    memset(vmcs, 0, vmcs_size); /* don't remove this */
+    memset(vmcs, 0, PAGE_SIZE);
     vmcs->vmcs_revision_id = vmcs_revision_id;
 
     return vmcs;
@@ -74,7 +157,7 @@ static struct vmcs_struct *vmx_alloc_vmc
 
 static void vmx_free_vmcs(struct vmcs_struct *vmcs)
 {
-    free_xenheap_pages(vmcs, vmcs_order);
+    free_xenheap_page(vmcs);
 }
 
 static void __vmx_clear_vmcs(void *info)
@@ -156,12 +239,11 @@ static inline int construct_vmcs_control
 {
     int error = 0;
 
-    error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
-                       MONITOR_PIN_BASED_EXEC_CONTROLS);
-
-    error |= __vmwrite(VM_EXIT_CONTROLS, MONITOR_VM_EXIT_CONTROLS);
-
-    error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS);
+    error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
+
+    error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
+
+    error |= __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
 
     error |= __vmwrite(IO_BITMAP_A, virt_to_maddr(arch_vmx->io_bitmap_a));
     error |= __vmwrite(IO_BITMAP_B, virt_to_maddr(arch_vmx->io_bitmap_b));
@@ -246,9 +328,8 @@ static void vmx_do_launch(struct vcpu *v
     error |= __vmwrite(GUEST_CR0, cr0);
     cr0 &= ~X86_CR0_PG;
     error |= __vmwrite(CR0_READ_SHADOW, cr0);
-    error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                       MONITOR_CPU_BASED_EXEC_CONTROLS);
-    v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
+    error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
+    v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control;
 
     __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (cr4) : );
 
@@ -297,21 +378,21 @@ static inline int construct_init_vmcs_gu
     /* MSR */
     error |= __vmwrite(VM_EXIT_MSR_LOAD_ADDR, 0);
     error |= __vmwrite(VM_EXIT_MSR_STORE_ADDR, 0);
-
     error |= __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
     error |= __vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
     error |= __vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
-    /* interrupt */
+
     error |= __vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
-    /* mask */
-    error |= __vmwrite(CR0_GUEST_HOST_MASK, -1UL);
-    error |= __vmwrite(CR4_GUEST_HOST_MASK, -1UL);
+
+    error |= __vmwrite(CR0_GUEST_HOST_MASK, ~0UL);
+    error |= __vmwrite(CR4_GUEST_HOST_MASK, ~0UL);
 
     error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
     error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
 
-    /* TSC */
     error |= __vmwrite(CR3_TARGET_COUNT, 0);
+
+    error |= __vmwrite(GUEST_ACTIVITY_STATE, 0);
 
     /* Guest Selectors */
     error |= __vmwrite(GUEST_ES_SELECTOR, GUEST_LAUNCH_DS);
diff -r f5fd563bcc84 -r 0f9908c2c5c7 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Sep 25 17:45:28 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Sep 25 17:46:08 2006 +0100
@@ -684,21 +684,6 @@ static void vmx_init_ap_context(struct v
 
 void do_nmi(struct cpu_user_regs *);
 
-static int check_vmx_controls(u32 ctrls, u32 msr)
-{
-    u32 vmx_msr_low, vmx_msr_high;
-
-    rdmsr(msr, vmx_msr_low, vmx_msr_high);
-    if ( (ctrls < vmx_msr_low) || (ctrls > vmx_msr_high) )
-    {
-        printk("Insufficient VMX capability 0x%x, "
-               "msr=0x%x,low=0x%8x,high=0x%x\n",
-               ctrls, msr, vmx_msr_low, vmx_msr_high);
-        return 0;
-    }
-    return 1;
-}
-
 static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page)
 {
     char *p;
@@ -791,7 +776,7 @@ int start_vmx(void)
      */
     boot_cpu_data.x86_capability[4] = cpuid_ecx(1);
 
-    if (!(test_bit(X86_FEATURE_VMXE, &boot_cpu_data.x86_capability)))
+    if ( !test_bit(X86_FEATURE_VMXE, &boot_cpu_data.x86_capability) )
         return 0;
 
     rdmsr(IA32_FEATURE_CONTROL_MSR, eax, edx);
@@ -811,24 +796,11 @@ int start_vmx(void)
               IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON, 0);
     }
 
-    if ( !check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
-                             MSR_IA32_VMX_PINBASED_CTLS_MSR) )
-        return 0;
-    if ( !check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
-                             MSR_IA32_VMX_PROCBASED_CTLS_MSR) )
-        return 0;
-    if ( !check_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
-                             MSR_IA32_VMX_EXIT_CTLS_MSR) )
-        return 0;
-    if ( !check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
-                             MSR_IA32_VMX_ENTRY_CTLS_MSR) )
-        return 0;
-
     set_in_cr4(X86_CR4_VMXE);
 
     vmx_init_vmcs_config();
-    
-    if(!smp_processor_id())
+
+    if ( smp_processor_id() == 0 )
         setup_vmcs_dump();
 
     if ( (vmcs = vmx_alloc_host_vmcs()) == NULL )
@@ -1519,7 +1491,7 @@ static int vmx_set_cr0(unsigned long val
                     &v->arch.hvm_vmx.cpu_state);
 
             __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
-            vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
+            vm_entry_value |= VM_ENTRY_IA32E_MODE;
             __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
         }
 #endif
@@ -1573,7 +1545,7 @@ static int vmx_set_cr0(unsigned long val
                 clear_bit(VMX_CPU_STATE_LMA_ENABLED,
                           &v->arch.hvm_vmx.cpu_state);
                 __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
-                vm_entry_value &= ~VM_ENTRY_CONTROLS_IA32E_MODE;
+                vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
                 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
             }
         }
@@ -2296,15 +2268,8 @@ asmlinkage void vmx_vmexit_handler(struc
         domain_crash_synchronous();
         break;
     case EXIT_REASON_PENDING_INTERRUPT:
-        /*
-         * Not sure exactly what the purpose of this is.  The only bits set
-         * and cleared at this point are CPU_BASED_VIRTUAL_INTR_PENDING.
-         * (in io.c:{enable,disable}_irq_window().  So presumably we want to
-         * set it to the original value...
-         */
+        /* Disable the interrupt window. */
         v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
-        v->arch.hvm_vcpu.u.vmx.exec_control |=
-            (MONITOR_CPU_BASED_EXEC_CONTROLS & CPU_BASED_VIRTUAL_INTR_PENDING);
         __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
                   v->arch.hvm_vcpu.u.vmx.exec_control);
         break;
diff -r f5fd563bcc84 -r 0f9908c2c5c7 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Mon Sep 25 17:45:28 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Mon Sep 25 17:46:08 2006 +0100
@@ -132,12 +132,16 @@ extern int vmcs_version;
 #define CPU_BASED_ACTIVATE_IO_BITMAP    0x02000000
 #define CPU_BASED_MONITOR_EXITING       0x20000000
 #define CPU_BASED_PAUSE_EXITING         0x40000000
-#define PIN_BASED_EXT_INTR_MASK 0x1
-#define PIN_BASED_NMI_EXITING   0x8
-
+
+#define PIN_BASED_EXT_INTR_MASK         0x00000001
+#define PIN_BASED_NMI_EXITING           0x00000008
+
+#define VM_EXIT_IA32E_MODE              0x00000200
 #define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000
-#define VM_EXIT_HOST_ADD_SPACE_SIZE     0x00000200
-
+
+#define VM_ENTRY_IA32E_MODE             0x00000200
+#define VM_ENTRY_SMM                    0x00000400
+#define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800
 
 /* VMCS Encordings */
 enum vmcs_field {
@@ -217,6 +221,7 @@ enum vmcs_field {
     GUEST_LDTR_AR_BYTES             = 0x00004820,
     GUEST_TR_AR_BYTES               = 0x00004822,
     GUEST_INTERRUPTIBILITY_INFO     = 0x00004824,
+    GUEST_ACTIVITY_STATE            = 0x00004826,
     GUEST_SYSENTER_CS               = 0x0000482A,
     HOST_IA32_SYSENTER_CS           = 0x00004c00,
     CR0_GUEST_HOST_MASK             = 0x00006000,
diff -r f5fd563bcc84 -r 0f9908c2c5c7 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Mon Sep 25 17:45:28 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Mon Sep 25 17:46:08 2006 +0100
@@ -35,73 +35,6 @@ extern void set_guest_time(struct vcpu *
 extern void set_guest_time(struct vcpu *v, u64 gtime);
 
 extern unsigned int cpu_rev;
-
-/*
- * Need fill bits for SENTER
- */
-
-#define MONITOR_PIN_BASED_EXEC_CONTROLS_RESERVED_VALUE  0x00000016
-
-#define MONITOR_PIN_BASED_EXEC_CONTROLS                 \
-    (                                                   \
-    MONITOR_PIN_BASED_EXEC_CONTROLS_RESERVED_VALUE |    \
-    PIN_BASED_EXT_INTR_MASK |                           \
-    PIN_BASED_NMI_EXITING                               \
-    )
-
-#define MONITOR_CPU_BASED_EXEC_CONTROLS_RESERVED_VALUE  0x0401e172
-
-#define _MONITOR_CPU_BASED_EXEC_CONTROLS                \
-    (                                                   \
-    MONITOR_CPU_BASED_EXEC_CONTROLS_RESERVED_VALUE |    \
-    CPU_BASED_HLT_EXITING |                             \
-    CPU_BASED_INVDPG_EXITING |                          \
-    CPU_BASED_MWAIT_EXITING |                           \
-    CPU_BASED_MOV_DR_EXITING |                          \
-    CPU_BASED_ACTIVATE_IO_BITMAP |                      \
-    CPU_BASED_USE_TSC_OFFSETING                         \
-    )
-
-#define MONITOR_CPU_BASED_EXEC_CONTROLS_IA32E_MODE      \
-    (                                                   \
-    CPU_BASED_CR8_LOAD_EXITING |                        \
-    CPU_BASED_CR8_STORE_EXITING                         \
-    )
-
-#define MONITOR_VM_EXIT_CONTROLS_RESERVED_VALUE         0x0003edff
-
-#define MONITOR_VM_EXIT_CONTROLS_IA32E_MODE             0x00000200
-
-#define _MONITOR_VM_EXIT_CONTROLS                       \
-    (                                                   \
-    MONITOR_VM_EXIT_CONTROLS_RESERVED_VALUE |           \
-    VM_EXIT_ACK_INTR_ON_EXIT                            \
-    )
-
-#if defined (__x86_64__)
-#define MONITOR_CPU_BASED_EXEC_CONTROLS                 \
-    (                                                   \
-    _MONITOR_CPU_BASED_EXEC_CONTROLS |                  \
-    MONITOR_CPU_BASED_EXEC_CONTROLS_IA32E_MODE          \
-    )
-#define MONITOR_VM_EXIT_CONTROLS                        \
-    (                                                   \
-    _MONITOR_VM_EXIT_CONTROLS |                         \
-    MONITOR_VM_EXIT_CONTROLS_IA32E_MODE                 \
-    )
-#else
-#define MONITOR_CPU_BASED_EXEC_CONTROLS                 \
-    _MONITOR_CPU_BASED_EXEC_CONTROLS
-
-#define MONITOR_VM_EXIT_CONTROLS                        \
-    _MONITOR_VM_EXIT_CONTROLS
-#endif
-
-#define VM_ENTRY_CONTROLS_RESERVED_VALUE                0x000011ff
-#define VM_ENTRY_CONTROLS_IA32E_MODE                    0x00000200
-
-#define MONITOR_VM_ENTRY_CONTROLS                       \
-    VM_ENTRY_CONTROLS_RESERVED_VALUE
 
 /*
  * Exit Reasons

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Simplify VMCS allocation (never bigger than a page)., Xen patchbot-unstable <=