[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] nested vmx: nested TPR shadow/threshold emulation


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Wed, 19 Dec 2012 16:55:19 +0000
  • Delivery-date: Wed, 19 Dec 2012 16:55:29 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
# Date 1355854485 0
# Node ID 9333aa732be79962738eba5368b9af3695d8e8b1
# Parent  aba2d72aae6cb9dcb78edbdbb45102ff0738f6b5
nested vmx: nested TPR shadow/threshold emulation

TPR shadow/threshold feature is important to speedup the boot time
for Windows guest. Besides, it is a must feature for certain VMM.

We map virtual APIC page address and TPR threshold from L1 VMCS,
and synch it into shadow VMCS in virtual vmentry.
If TPR_BELOW_THRESHOLD VM exit is triggered by L2 guest, we
inject it into L1 VMM for handling.

Besides, this commit fixes an issue for apic access page, if L1
VMM didn't enable this feature, we need to fill zero into the
shadow VMCS.

Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r aba2d72aae6c -r 9333aa732be7 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Tue Dec 18 18:12:00 2012 +0000
+++ b/xen/arch/x86/hvm/vmx/intr.c       Tue Dec 18 18:14:45 2012 +0000
@@ -324,7 +324,9 @@ void vmx_intr_assist(void)
     }
 
  out:
-    if ( !cpu_has_vmx_virtual_intr_delivery && cpu_has_vmx_tpr_shadow )
+    if ( !nestedhvm_vcpu_in_guestmode(v) &&
+         !cpu_has_vmx_virtual_intr_delivery &&
+         cpu_has_vmx_tpr_shadow )
         __vmwrite(TPR_THRESHOLD, tpr_threshold);
 }
 
diff -r aba2d72aae6c -r 9333aa732be7 xen/arch/x86/hvm/vmx/vvmx.c
--- a/xen/arch/x86/hvm/vmx/vvmx.c       Tue Dec 18 18:12:00 2012 +0000
+++ b/xen/arch/x86/hvm/vmx/vvmx.c       Tue Dec 18 18:14:45 2012 +0000
@@ -471,8 +471,7 @@ void nvmx_update_exec_control(struct vcp
     shadow_cntrl = __n2_exec_control(v);
     pio_cntrl &= shadow_cntrl;
     /* Enforce the removed features */
-    shadow_cntrl &= ~(CPU_BASED_TPR_SHADOW
-                      | CPU_BASED_ACTIVATE_MSR_BITMAP
+    shadow_cntrl &= ~(CPU_BASED_ACTIVATE_MSR_BITMAP
                       | CPU_BASED_ACTIVATE_IO_BITMAP
                       | CPU_BASED_UNCOND_IO_EXITING);
     shadow_cntrl |= host_cntrl;
@@ -570,6 +569,38 @@ static void nvmx_update_apic_access_addr
         __vmwrite(APIC_ACCESS_ADDR, (apic_mfn << PAGE_SHIFT));
         hvm_unmap_guest_frame(apic_va); 
     }
+    else
+        __vmwrite(APIC_ACCESS_ADDR, 0);
+}
+
+static void nvmx_update_virtual_apic_address(struct vcpu *v)
+{
+    struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+    u64 vapic_gpfn, vapic_mfn;
+    u32 ctrl;
+    void *vapic_va;
+
+    ctrl = __n2_exec_control(v);
+    if ( ctrl & CPU_BASED_TPR_SHADOW )
+    {
+        vapic_gpfn = __get_vvmcs(nvcpu->nv_vvmcx, VIRTUAL_APIC_PAGE_ADDR) >> 
PAGE_SHIFT;
+        vapic_va = hvm_map_guest_frame_ro(vapic_gpfn);
+        vapic_mfn = virt_to_mfn(vapic_va);
+        __vmwrite(VIRTUAL_APIC_PAGE_ADDR, (vapic_mfn << PAGE_SHIFT));
+        hvm_unmap_guest_frame(vapic_va); 
+    }
+    else
+        __vmwrite(VIRTUAL_APIC_PAGE_ADDR, 0);
+}
+
+static void nvmx_update_tpr_threshold(struct vcpu *v)
+{
+    struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+    u32 ctrl = __n2_exec_control(v);
+    if ( ctrl & CPU_BASED_TPR_SHADOW )
+        __vmwrite(TPR_THRESHOLD, __get_vvmcs(nvcpu->nv_vvmcx, TPR_THRESHOLD));
+    else
+        __vmwrite(TPR_THRESHOLD, 0);
 }
 
 static void __clear_current_vvmcs(struct vcpu *v)
@@ -780,6 +811,8 @@ static void load_shadow_control(struct v
     nvmx_update_entry_control(v);
     vmx_update_exception_bitmap(v);
     nvmx_update_apic_access_address(v);
+    nvmx_update_virtual_apic_address(v);
+    nvmx_update_tpr_threshold(v);
 }
 
 static void load_shadow_guest_state(struct vcpu *v)
@@ -1371,6 +1404,7 @@ int nvmx_msr_read_intercept(unsigned int
                CPU_BASED_ACTIVATE_MSR_BITMAP |
                CPU_BASED_PAUSE_EXITING |
                CPU_BASED_RDPMC_EXITING |
+               CPU_BASED_TPR_SHADOW |
                CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
         data = gen_vmx_msr(data, VMX_PROCBASED_CTLS_DEFAULT1, host_data);
         break;
@@ -1707,6 +1741,11 @@ int nvmx_n2_vmexit_handler(struct cpu_us
         if ( ctrl & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES )
             nvcpu->nv_vmexit_pending = 1;
         break;
+    case EXIT_REASON_TPR_BELOW_THRESHOLD:
+        ctrl = __n2_exec_control(v);
+        if ( ctrl & CPU_BASED_TPR_SHADOW )
+            nvcpu->nv_vmexit_pending = 1;
+        break;
     default:
         gdprintk(XENLOG_WARNING, "Unknown nested vmexit reason %x.\n",
                  exit_reason);

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.