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] [PATCH 14 of 20] Extend VMCS control fields for n2 guest

To: Tim.Deegan@xxxxxxxxxx
Subject: [Xen-devel] [PATCH 14 of 20] Extend VMCS control fields for n2 guest
From: Eddie Dong <eddie.dong@xxxxxxxxx>
Date: Thu, 09 Jun 2011 16:25:19 +0800
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Thu, 09 Jun 2011 01:45:03 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1307607905@xxxxxxxxxxxxxxxxxxxx>
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: <patchbomb.1307607905@xxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Eddie Dong <eddie.dong@xxxxxxxxx>
# Date 1307607849 -28800
# Node ID fc6a432d6c6367acaee71526556e1feeece4d34c
# Parent  a6f9b015835e503474c4a258e5c03178358c68e8
Extend VMCS control fields for n2 guest

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

diff -r a6f9b015835e -r fc6a432d6c63 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 09 16:24:09 2011 +0800
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 09 16:24:09 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 @@ long_mode_do_msr_write(unsigned int msr,
 
 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 a6f9b015835e -r fc6a432d6c63 xen/arch/x86/hvm/vmx/vvmx.c
--- a/xen/arch/x86/hvm/vmx/vvmx.c       Thu Jun 09 16:24:09 2011 +0800
+++ b/xen/arch/x86/hvm/vmx/vvmx.c       Thu Jun 09 16:24:09 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>
 
 static void nvmx_purge_vvmcs(struct vcpu *v);
 
@@ -390,6 +391,93 @@ static void vmreturn(struct cpu_user_reg
     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, u32 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 a6f9b015835e -r fc6a432d6c63 xen/include/asm-x86/hvm/vmx/vvmx.h
--- a/xen/include/asm-x86/hvm/vmx/vvmx.h        Thu Jun 09 16:24:09 2011 +0800
+++ b/xen/include/asm-x86/hvm/vmx/vvmx.h        Thu Jun 09 16:24:09 2011 +0800
@@ -161,5 +161,10 @@ int nvmx_handle_vmwrite(struct cpu_user_
 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, u32 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

<Prev in Thread] Current Thread [Next in Thread>