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] hvm: Share ASID logic between VMX and SVM

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvm: Share ASID logic between VMX and SVM.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 08 Dec 2009 06:20:24 -0800
Delivery-date: Tue, 08 Dec 2009 06:21:18 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1260281667 0
# Node ID 7f611de6b93cc4cbec0530548a85953afa845315
# Parent  2d92ad3ef517208240aa3d00e22516cf885ef351
hvm: Share ASID logic between VMX and SVM.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/asid.c            |    6 +-
 xen/arch/x86/hvm/hvm.c             |    2 
 xen/arch/x86/hvm/svm/svm.c         |   13 ----
 xen/arch/x86/hvm/svm/vmcb.c        |    3 -
 xen/arch/x86/hvm/vmx/entry.S       |    2 
 xen/arch/x86/hvm/vmx/vmcs.c        |   12 +++-
 xen/arch/x86/hvm/vmx/vmx.c         |  111 +++++++++++++------------------------
 xen/include/asm-x86/hvm/asid.h     |    6 +-
 xen/include/asm-x86/hvm/hvm.h      |   18 ++----
 xen/include/asm-x86/hvm/svm/asid.h |    2 
 xen/include/asm-x86/hvm/vmx/vmcs.h |    2 
 xen/include/asm-x86/hvm/vmx/vmx.h  |   12 ----
 12 files changed, 73 insertions(+), 116 deletions(-)

diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/asid.c
--- a/xen/arch/x86/hvm/asid.c   Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/asid.c   Tue Dec 08 14:14:27 2009 +0000
@@ -20,7 +20,9 @@
 #include <xen/config.h>
 #include <xen/init.h>
 #include <xen/lib.h>
-#include <xen/perfc.h>
+#include <xen/sched.h>
+#include <xen/smp.h>
+#include <xen/percpu.h>
 #include <asm/hvm/asid.h>
 
 /*
@@ -80,7 +82,7 @@ void hvm_asid_init(int nasids)
     data->next_asid = 1;
 }
 
-void hvm_asid_invalidate_asid(struct vcpu *v)
+void hvm_asid_flush_vcpu(struct vcpu *v)
 {
     v->arch.hvm_vcpu.asid_generation = 0;
 }
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Tue Dec 08 14:14:27 2009 +0000
@@ -756,6 +756,8 @@ int hvm_vcpu_initialise(struct vcpu *v)
 {
     int rc;
 
+    hvm_asid_flush_vcpu(v);
+
     if ( cpu_has_xsave )
     {
         /* XSAVE/XRSTOR requires the save area be 64-byte-boundary aligned. */
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Dec 08 14:14:27 2009 +0000
@@ -424,7 +424,7 @@ static void svm_update_guest_cr(struct v
         break;
     case 3:
         vmcb->cr3 = v->arch.hvm_vcpu.hw_cr[3];
-        hvm_asid_invalidate_asid(v);
+        hvm_asid_flush_vcpu(v);
         break;
     case 4:
         vmcb->cr4 = HVM_CR4_HOST_MASK;
@@ -453,14 +453,6 @@ static void svm_update_guest_efer(struct
     svm_intercept_msr(v, MSR_IA32_SYSENTER_CS, lma);
     svm_intercept_msr(v, MSR_IA32_SYSENTER_ESP, lma);
     svm_intercept_msr(v, MSR_IA32_SYSENTER_EIP, lma);
-}
-
-static void svm_flush_guest_tlbs(void)
-{
-    /* Roll over the CPU's ASID generation, so it gets a clean TLB when we
-     * next VMRUN.  (If ASIDs are disabled, the whole TLB is flushed on
-     * VMRUN anyway). */
-    hvm_asid_flush_core();
 }
 
 static void svm_sync_vmcb(struct vcpu *v)
@@ -704,7 +696,7 @@ static void svm_do_resume(struct vcpu *v
         hvm_migrate_timers(v);
 
         /* Migrating to another ASID domain.  Request a new ASID. */
-        hvm_asid_invalidate_asid(v);
+        hvm_asid_flush_vcpu(v);
     }
 
     /* Reflect the vlapic's TPR in the hardware vtpr */
@@ -1250,7 +1242,6 @@ static struct hvm_function_table __read_
     .update_host_cr3      = svm_update_host_cr3,
     .update_guest_cr      = svm_update_guest_cr,
     .update_guest_efer    = svm_update_guest_efer,
-    .flush_guest_tlbs     = svm_flush_guest_tlbs,
     .set_tsc_offset       = svm_set_tsc_offset,
     .inject_exception     = svm_inject_exception,
     .init_hypercall_page  = svm_init_hypercall_page,
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Tue Dec 08 14:14:27 2009 +0000
@@ -113,9 +113,6 @@ static int construct_vmcb(struct vcpu *v
 {
     struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
-
-    /* TLB control, and ASID assigment. */
-    hvm_asid_invalidate_asid(v);
 
     vmcb->general1_intercepts = 
         GENERAL1_INTERCEPT_INTR        | GENERAL1_INTERCEPT_NMI         |
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/vmx/entry.S
--- a/xen/arch/x86/hvm/vmx/entry.S      Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/vmx/entry.S      Tue Dec 08 14:14:27 2009 +0000
@@ -142,9 +142,9 @@ vmx_asm_do_vmentry:
         call_with_regs(vmx_enter_realmode) 
 
 .Lvmx_not_realmode:
+        call vmx_vmenter_helper
         mov  VCPU_hvm_guest_cr2(r(bx)),r(ax)
         mov  r(ax),%cr2
-        call vmx_trace_vmentry
 
         lea  UREGS_rip(r(sp)),r(di)
         mov  $GUEST_RIP,%eax
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Tue Dec 08 14:14:27 2009 +0000
@@ -400,9 +400,12 @@ int vmx_cpu_up(void)
         BUG();
     }
 
+    hvm_asid_init(cpu_has_vmx_vpid ? (1u << VMCS_VPID_WIDTH) : 0);
+
     ept_sync_all();
 
-    vpid_sync_all();
+    if ( cpu_has_vmx_vpid )
+        vpid_sync_all();
 
     return 1;
 }
@@ -558,6 +561,9 @@ static int construct_vmcs(struct vcpu *v
         v->arch.hvm_vmx.exec_control |= CPU_BASED_RDTSC_EXITING;
 
     v->arch.hvm_vmx.secondary_exec_control = vmx_secondary_exec_control;
+
+    /* Disable VPID for now: we decide when to enable it on VMENTER. */
+    v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
 
     if ( paging_mode_hap(d) )
     {
@@ -736,7 +742,7 @@ static int construct_vmcs(struct vcpu *v
     }
 
     if ( cpu_has_vmx_vpid )
-        __vmwrite(VIRTUAL_PROCESSOR_ID, v->arch.hvm_vmx.vpid);
+        __vmwrite(VIRTUAL_PROCESSOR_ID, v->arch.hvm_vcpu.asid);
 
     if ( cpu_has_vmx_pat && paging_mode_hap(d) )
     {
@@ -946,7 +952,7 @@ void vmx_do_resume(struct vcpu *v)
         hvm_migrate_timers(v);
         hvm_migrate_pirqs(v);
         vmx_set_host_env(v);
-        vpid_sync_vcpu_all(v);
+        hvm_asid_flush_vcpu(v);
     }
 
     debug_state = v->domain->debugger_attached;
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Dec 08 14:14:27 2009 +0000
@@ -60,8 +60,6 @@ static void vmx_ctxt_switch_to(struct vc
 
 static int  vmx_alloc_vlapic_mapping(struct domain *d);
 static void vmx_free_vlapic_mapping(struct domain *d);
-static int  vmx_alloc_vpid(struct vcpu *v);
-static void vmx_free_vpid(struct vcpu *v);
 static void vmx_install_vlapic_mapping(struct vcpu *v);
 static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr);
 static void vmx_update_guest_efer(struct vcpu *v);
@@ -104,9 +102,6 @@ static int vmx_vcpu_initialise(struct vc
 
     spin_lock_init(&v->arch.hvm_vmx.vmcs_lock);
 
-    if ( (rc = vmx_alloc_vpid(v)) != 0 )
-        return rc;
-
     v->arch.schedule_tail    = vmx_do_resume;
     v->arch.ctxt_switch_from = vmx_ctxt_switch_from;
     v->arch.ctxt_switch_to   = vmx_ctxt_switch_to;
@@ -116,7 +111,6 @@ static int vmx_vcpu_initialise(struct vc
         dprintk(XENLOG_WARNING,
                 "Failed to create VMCS for vcpu %d: err=%d.\n",
                 v->vcpu_id, rc);
-        vmx_free_vpid(v);
         return rc;
     }
 
@@ -136,7 +130,6 @@ static void vmx_vcpu_destroy(struct vcpu
     vmx_destroy_vmcs(v);
     vpmu_destroy(v);
     passive_domain_destroy(v);
-    vmx_free_vpid(v);
 }
 
 #ifdef __x86_64__
@@ -1168,7 +1161,7 @@ static void vmx_update_guest_cr(struct v
         }
  
         __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr[3]);
-        vpid_sync_vcpu_all(v);
+        hvm_asid_flush_vcpu(v);
         break;
     case 4:
         v->arch.hvm_vcpu.hw_cr[4] = HVM_CR4_HOST_MASK;
@@ -1212,19 +1205,6 @@ static void vmx_update_guest_efer(struct
     if ( v == current )
         write_efer((read_efer() & ~EFER_SCE) |
                    (v->arch.hvm_vcpu.guest_efer & EFER_SCE));
-}
-
-static void vmx_flush_guest_tlbs(void)
-{
-    /*
-     * If VPID (i.e. tagged TLB support) is not enabled, the fact that
-     * we're in Xen at all means any guest will have a clean TLB when
-     * it's next run, because VMRESUME will flush it for us.
-     *
-     * If enabled, we invalidate all translations associated with all
-     * VPID values.
-     */
-    vpid_sync_all();
 }
 
 static void __ept_sync_domain(void *info)
@@ -1358,7 +1338,7 @@ static void vmx_set_uc_mode(struct vcpu 
     if ( paging_mode_hap(v->domain) )
         ept_change_entry_emt_with_range(
             v->domain, 0, v->domain->arch.p2m->max_mapped_pfn);
-    vpid_sync_all();
+    hvm_asid_flush_vcpu(v);
 }
 
 static void vmx_set_info_guest(struct vcpu *v)
@@ -1405,7 +1385,6 @@ static struct hvm_function_table __read_
     .update_host_cr3      = vmx_update_host_cr3,
     .update_guest_cr      = vmx_update_guest_cr,
     .update_guest_efer    = vmx_update_guest_efer,
-    .flush_guest_tlbs     = vmx_flush_guest_tlbs,
     .set_tsc_offset       = vmx_set_tsc_offset,
     .inject_exception     = vmx_inject_exception,
     .init_hypercall_page  = vmx_init_hypercall_page,
@@ -1424,9 +1403,6 @@ static struct hvm_function_table __read_
     .set_rdtsc_exiting    = vmx_set_rdtsc_exiting
 };
 
-static unsigned long *vpid_bitmap;
-#define VPID_BITMAP_SIZE (1u << VMCS_VPID_WIDTH)
-
 void start_vmx(void)
 {
     static bool_t bootstrapped;
@@ -1460,17 +1436,6 @@ void start_vmx(void)
 
     if ( cpu_has_vmx_ept )
         vmx_function_table.hap_supported = 1;
-
-    if ( cpu_has_vmx_vpid )
-    {
-        vpid_bitmap = xmalloc_array(
-            unsigned long, BITS_TO_LONGS(VPID_BITMAP_SIZE));
-        BUG_ON(vpid_bitmap == NULL);
-        memset(vpid_bitmap, 0, BITS_TO_LONGS(VPID_BITMAP_SIZE) * sizeof(long));
-
-        /* VPID 0 is used by VMX root mode (the hypervisor). */
-        __set_bit(0, vpid_bitmap);
-    }
 
     setup_vmcs_dump();
 
@@ -1584,7 +1549,7 @@ static void vmx_invlpg_intercept(unsigne
 {
     struct vcpu *curr = current;
     HVMTRACE_LONG_2D(INVLPG, /*invlpga=*/ 0, TRC_PAR_LONG(vaddr));
-    if ( paging_invlpg(curr, vaddr) )
+    if ( paging_invlpg(curr, vaddr) && cpu_has_vmx_vpid )
         vpid_sync_vcpu_gva(curr, vaddr);
 }
 
@@ -1929,36 +1894,6 @@ static void vmx_free_vlapic_mapping(stru
     unsigned long mfn = d->arch.hvm_domain.vmx.apic_access_mfn;
     if ( mfn != 0 )
         free_xenheap_page(mfn_to_virt(mfn));
-}
-
-static int vmx_alloc_vpid(struct vcpu *v)
-{
-    int idx;
-
-    if ( !cpu_has_vmx_vpid )
-        return 0;
-
-    do {
-        idx = find_first_zero_bit(vpid_bitmap, VPID_BITMAP_SIZE);
-        if ( idx >= VPID_BITMAP_SIZE )
-        {
-            dprintk(XENLOG_WARNING, "VMX VPID space exhausted.\n");
-            return -EBUSY;
-        }
-    }
-    while ( test_and_set_bit(idx, vpid_bitmap) );
-
-    v->arch.hvm_vmx.vpid = idx;
-    return 0;
-}
-
-static void vmx_free_vpid(struct vcpu *v)
-{
-    if ( !cpu_has_vmx_vpid )
-        return;
-
-    if ( v->arch.hvm_vmx.vpid )
-        clear_bit(v->arch.hvm_vmx.vpid, vpid_bitmap);
 }
 
 static void vmx_install_vlapic_mapping(struct vcpu *v)
@@ -2675,8 +2610,44 @@ asmlinkage void vmx_vmexit_handler(struc
     }
 }
 
-asmlinkage void vmx_trace_vmentry(void)
-{
+asmlinkage void vmx_vmenter_helper(void)
+{
+    struct vcpu *curr = current;
+    u32 new_asid, old_asid;
+    bool_t need_flush;
+
+    if ( !cpu_has_vmx_vpid )
+        goto out;
+
+    old_asid = curr->arch.hvm_vcpu.asid;
+    need_flush = hvm_asid_handle_vmenter();
+    new_asid = curr->arch.hvm_vcpu.asid;
+
+    if ( unlikely(new_asid != old_asid) )
+    {
+        __vmwrite(VIRTUAL_PROCESSOR_ID, new_asid);
+        if ( !old_asid && new_asid )
+        {
+            /* VPID was disabled: now enabled. */
+            curr->arch.hvm_vmx.secondary_exec_control |=
+                SECONDARY_EXEC_ENABLE_VPID;
+            __vmwrite(SECONDARY_VM_EXEC_CONTROL,
+                      curr->arch.hvm_vmx.secondary_exec_control);
+        }
+        else if ( old_asid && !new_asid )
+        {
+            /* VPID was enabled: now disabled. */
+            curr->arch.hvm_vmx.secondary_exec_control &=
+                ~SECONDARY_EXEC_ENABLE_VPID;
+            __vmwrite(SECONDARY_VM_EXEC_CONTROL,
+                      curr->arch.hvm_vmx.secondary_exec_control);
+        }
+    }
+
+    if ( unlikely(need_flush) )
+        vpid_sync_all();
+
+ out:
     HVMTRACE_ND (VMENTRY, 1/*cycles*/, 0, 0, 0, 0, 0, 0, 0);
 }
 
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/include/asm-x86/hvm/asid.h
--- a/xen/include/asm-x86/hvm/asid.h    Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/include/asm-x86/hvm/asid.h    Tue Dec 08 14:14:27 2009 +0000
@@ -21,14 +21,14 @@
 #define __ASM_X86_HVM_ASID_H__
 
 #include <xen/config.h>
-#include <xen/sched.h>
-#include <asm/processor.h>
+
+struct vcpu;
 
 /* Initialise ASID management for the current physical CPU. */
 void hvm_asid_init(int nasids);
 
 /* Invalidate a VCPU's current ASID allocation: forces re-allocation. */
-void hvm_asid_invalidate_asid(struct vcpu *v);
+void hvm_asid_flush_vcpu(struct vcpu *v);
 
 /* Flush all ASIDs on this processor core. */
 void hvm_asid_flush_core(void);
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Tue Dec 08 14:14:27 2009 +0000
@@ -23,6 +23,7 @@
 
 #include <asm/current.h>
 #include <asm/x86_emulate.h>
+#include <asm/hvm/asid.h>
 #include <public/domctl.h>
 #include <public/hvm/save.h>
 
@@ -99,13 +100,6 @@ struct hvm_function_table {
      */
     void (*update_guest_cr)(struct vcpu *v, unsigned int cr);
     void (*update_guest_efer)(struct vcpu *v);
-
-    /*
-     * Called to ensure than all guest-specific mappings in a tagged TLB
-     * are flushed; does *not* flush Xen's TLB entries, and on
-     * processors without a tagged TLB it will be a noop.
-     */
-    void (*flush_guest_tlbs)(void);
 
     void (*set_tsc_offset)(struct vcpu *v, u64 offset);
 
@@ -201,11 +195,15 @@ static inline void hvm_update_guest_efer
     hvm_funcs.update_guest_efer(v);
 }
 
-static inline void 
-hvm_flush_guest_tlbs(void)
+/*
+ * Called to ensure than all guest-specific mappings in a tagged TLB are 
+ * flushed; does *not* flush Xen's TLB entries, and on processors without a 
+ * tagged TLB it will be a noop.
+ */
+static inline void hvm_flush_guest_tlbs(void)
 {
     if ( hvm_enabled )
-        hvm_funcs.flush_guest_tlbs();
+        hvm_asid_flush_core();
 }
 
 void hvm_hypercall_page_initialise(struct domain *d,
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/include/asm-x86/hvm/svm/asid.h
--- a/xen/include/asm-x86/hvm/svm/asid.h        Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/include/asm-x86/hvm/svm/asid.h        Tue Dec 08 14:14:27 2009 +0000
@@ -41,7 +41,7 @@ static inline void svm_asid_g_invlpg(str
 #endif
 
     /* Safe fallback. Take a new ASID. */
-    hvm_asid_invalidate_asid(v);
+    hvm_asid_flush_vcpu(v);
 }
 
 #endif /* __ASM_X86_HVM_SVM_ASID_H__ */
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue Dec 08 14:14:27 2009 +0000
@@ -89,8 +89,6 @@ struct arch_vmx_struct {
     /* Cache of cpu execution control. */
     u32                  exec_control;
     u32                  secondary_exec_control;
-
-    u16                  vpid;
 
     /* PMU */
     struct vpmu_struct   vpmu;
diff -r 2d92ad3ef517 -r 7f611de6b93c xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Tue Dec 08 10:33:08 2009 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Tue Dec 08 14:14:27 2009 +0000
@@ -314,20 +314,12 @@ void ept_sync_domain(struct domain *d);
 
 static inline void vpid_sync_vcpu_gva(struct vcpu *v, unsigned long gva)
 {
-    if ( cpu_has_vmx_vpid )
-        __invvpid(0, v->arch.hvm_vmx.vpid, (u64)gva);
-}
-
-static inline void vpid_sync_vcpu_all(struct vcpu *v)
-{
-    if ( cpu_has_vmx_vpid )
-        __invvpid(1, v->arch.hvm_vmx.vpid, 0);
+    __invvpid(0, v->arch.hvm_vcpu.asid, (u64)gva);
 }
 
 static inline void vpid_sync_all(void)
 {
-    if ( cpu_has_vmx_vpid )
-        __invvpid(2, 0, 0);
+    __invvpid(2, 0, 0);
 }
 
 static inline void __vmxoff(void)

_______________________________________________
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] hvm: Share ASID logic between VMX and SVM., Xen patchbot-unstable <=