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-devel

[Xen-devel] RFC: Nested VMX patch series 12: shadow vmcs control

To: "Dong, Eddie" <eddie.dong@xxxxxxxxx>, Tim Deegan <Tim.Deegan@xxxxxxxxxx>, Keir Fraser <keir@xxxxxxx>
Subject: [Xen-devel] RFC: Nested VMX patch series 12: shadow vmcs control
From: "Dong, Eddie" <eddie.dong@xxxxxxxxx>
Date: Wed, 1 Jun 2011 12:03:42 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, "Dong, Eddie" <eddie.dong@xxxxxxxxx>, "He, Qing" <qing.he@xxxxxxxxx>
Delivery-date: Tue, 31 May 2011 21:11:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <osstest-7468-mainreport@xxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcwgAhjDwUdZ/2BOTBqtK+IA8ti/WgAC9edgAAAdViAAAA3MIAAAF9kwAAAdbWAAABYxcAAAC+egAAALN5AAAAWccAAABoAAAAAHMIAAAArpgAAABgbg
Thread-topic: [Xen-devel] RFC: Nested VMX patch series 12: shadow vmcs control

Thx, Eddie

        Signed-off-by: Qing He <qing.he@xxxxxxxxx>
        Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>


diff -r 607ce7be0b5c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon May 30 17:15:56 2011 +0800
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon May 30 17:38:21 2011 +0800
@@ -54,6 +54,7 @@
 #include <asm/xenoprof.h>
 #include <asm/debugger.h>
 #include <asm/apic.h>
+#include <asm/hvm/nestedhvm.h>
 
 enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised };
 
@@ -361,18 +362,28 @@
 
 void vmx_update_cpu_exec_control(struct vcpu *v)
 {
-    __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control);
+    if ( nestedhvm_vcpu_in_guestmode(v) )
+        nvmx_update_exec_control(v, v->arch.hvm_vmx.exec_control);
+    else
+        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control);
 }
 
 static void vmx_update_secondary_exec_control(struct vcpu *v)
 {
-    __vmwrite(SECONDARY_VM_EXEC_CONTROL,
-              v->arch.hvm_vmx.secondary_exec_control);
+    if ( nestedhvm_vcpu_in_guestmode(v) )
+        nvmx_update_secondary_exec_control(v,
+            v->arch.hvm_vmx.secondary_exec_control);
+    else
+        __vmwrite(SECONDARY_VM_EXEC_CONTROL,
+                  v->arch.hvm_vmx.secondary_exec_control);
 }
 
 void vmx_update_exception_bitmap(struct vcpu *v)
 {
-    __vmwrite(EXCEPTION_BITMAP, v->arch.hvm_vmx.exception_bitmap);
+    if ( nestedhvm_vcpu_in_guestmode(v) )
+        nvmx_update_exception_bitmap(v, v->arch.hvm_vmx.exception_bitmap);
+    else
+        __vmwrite(EXCEPTION_BITMAP, v->arch.hvm_vmx.exception_bitmap);
 }
 
 static int vmx_guest_x86_mode(struct vcpu *v)
diff -r 607ce7be0b5c xen/arch/x86/hvm/vmx/vvmx.c
--- a/xen/arch/x86/hvm/vmx/vvmx.c       Mon May 30 17:15:56 2011 +0800
+++ b/xen/arch/x86/hvm/vmx/vvmx.c       Mon May 30 17:38:21 2011 +0800
@@ -25,6 +25,7 @@
 #include <asm/p2m.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vvmx.h>
+#include <asm/hvm/nestedhvm.h>
 
 int nvmx_vcpu_initialise(struct vcpu *v)
 {
@@ -443,6 +444,93 @@
     regs->eflags = eflags;
 }
 
+/*
+ * Nested VMX uses "strict" condition to exit from 
+ * L2 guest if either L1 VMM or L0 VMM expect to exit.
+ */
+static inline u32 __shadow_control(struct vcpu *v,
+                                 unsigned int field,
+                                 u32 host_value)
+{
+    struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+
+    return (u32) __get_vvmcs(nvcpu->nv_vvmcx, field) | host_value;
+}
+
+static void set_shadow_control(struct vcpu *v,
+                               unsigned int field,
+                               u32 host_value)
+{
+    __vmwrite(field, __shadow_control(v, field, host_value));
+}
+
+unsigned long *_shadow_io_bitmap(struct vcpu *v)
+{
+    struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+    int port80, portED;
+    u8 *bitmap;
+
+    bitmap = nvmx->iobitmap[0];
+    port80 = bitmap[0x80 >> 3] & (1 << (0x80 & 0x7)) ? 1 : 0;
+    portED = bitmap[0xed >> 3] & (1 << (0xed & 0x7)) ? 1 : 0;
+
+    return nestedhvm_vcpu_iomap_get(port80, portED);
+}
+
+void nvmx_update_exec_control(struct vcpu *v, unsigned long host_cntrl)
+{
+#define PIO_CNTRL_BITS    ( CPU_BASED_ACTIVATE_IO_BITMAP         \
+             | CPU_BASED_UNCOND_IO_EXITING)
+    u32 pio_cntrl = PIO_CNTRL_BITS;
+    unsigned long *bitmap; 
+    u32 shadow_cntrl;
+ 
+    shadow_cntrl = __n2_exec_control(v);
+    pio_cntrl &= shadow_cntrl;
+    /* Enforce the removed features */
+#define REMOVED_EXEC_CONTROL_BITS (CPU_BASED_TPR_SHADOW          \
+             | CPU_BASED_ACTIVATE_MSR_BITMAP                     \
+             | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS             \
+             | CPU_BASED_ACTIVATE_IO_BITMAP                      \
+             | CPU_BASED_UNCOND_IO_EXITING)
+    shadow_cntrl &= ~REMOVED_EXEC_CONTROL_BITS;
+    shadow_cntrl |= host_cntrl;
+    if ( pio_cntrl == CPU_BASED_UNCOND_IO_EXITING ) {
+        /* L1 VMM intercepts all I/O instructions */
+        shadow_cntrl |= CPU_BASED_UNCOND_IO_EXITING;
+        shadow_cntrl &= ~CPU_BASED_ACTIVATE_IO_BITMAP;
+    }
+    else {
+        /* Use IO_BITMAP in shadow */
+        if ( pio_cntrl == 0 ) {
+            /* 
+             * L1 VMM doesn't intercept IO instruction.
+             * Use host configuration and reset IO_BITMAP
+             */
+            bitmap = hvm_io_bitmap;
+        }
+        else {
+            /* use IO bitmap */
+            bitmap = _shadow_io_bitmap(v);
+        }
+        __vmwrite(IO_BITMAP_A, virt_to_maddr(bitmap));
+        __vmwrite(IO_BITMAP_B, virt_to_maddr(bitmap) + PAGE_SIZE);
+    }
+
+    __vmwrite(CPU_BASED_VM_EXEC_CONTROL, shadow_cntrl);
+}
+
+void nvmx_update_secondary_exec_control(struct vcpu *v,
+                                            unsigned long value)
+{
+    set_shadow_control(v, SECONDARY_VM_EXEC_CONTROL, value);
+}
+
+void nvmx_update_exception_bitmap(struct vcpu *v, unsigned long value)
+{
+    set_shadow_control(v, EXCEPTION_BITMAP, value);
+}
+
 static void __clear_current_vvmcs(struct vcpu *v)
 {
     struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
diff -r 607ce7be0b5c xen/include/asm-x86/hvm/vmx/vvmx.h
--- a/xen/include/asm-x86/hvm/vmx/vvmx.h        Mon May 30 17:15:56 2011 +0800
+++ b/xen/include/asm-x86/hvm/vmx/vvmx.h        Mon May 30 17:38:21 2011 +0800
@@ -117,5 +117,10 @@
 int nvmx_handle_vmresume(struct cpu_user_regs *regs);
 int nvmx_handle_vmlaunch(struct cpu_user_regs *regs);
 
+void nvmx_update_exec_control(struct vcpu *v, unsigned long value);
+void nvmx_update_secondary_exec_control(struct vcpu *v,
+                                        unsigned long value);
+void nvmx_update_exception_bitmap(struct vcpu *v, unsigned long value);
+
 #endif /* __ASM_X86_HVM_VVMX_H__ */


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