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-3.4-testing] hvm: Clean up EPT/NPT 'nested page fau

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.4-testing] hvm: Clean up EPT/NPT 'nested page fault' handling.
From: "Xen patchbot-3.4-testing" <patchbot-3.4-testing@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 27 Oct 2009 06:05:27 -0700
Delivery-date: Tue, 27 Oct 2009 06:08:54 -0700
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 1256648540 0
# Node ID 6f8d8b88edd61e1f1d6264471f6a5996028bb9c8
# Parent  48ccb3d1ebd040f990d948975e3956184f389dc4
hvm: Clean up EPT/NPT 'nested page fault' handling.

Share most of the code.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   20368:b27f85b54ecc
xen-unstable date:        Mon Oct 26 13:19:33 2009 +0000
---
 xen/arch/x86/hvm/hvm.c            |   29 ++++++++++++++
 xen/arch/x86/hvm/svm/svm.c        |   33 ++++++----------
 xen/arch/x86/hvm/vmx/vmx.c        |   75 ++++++++------------------------------
 xen/include/asm-x86/hvm/hvm.h     |    2 +
 xen/include/asm-x86/hvm/vmx/vmx.h |   29 ++------------
 5 files changed, 64 insertions(+), 104 deletions(-)

diff -r 48ccb3d1ebd0 -r 6f8d8b88edd6 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Oct 27 12:57:40 2009 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Tue Oct 27 13:02:20 2009 +0000
@@ -826,6 +826,35 @@ void hvm_triple_fault(void)
     domain_shutdown(v->domain, SHUTDOWN_reboot);
 }
 
+bool_t hvm_hap_nested_page_fault(unsigned long gfn)
+{
+    p2m_type_t p2mt;
+    mfn_t mfn;
+
+    mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest);
+
+    /*
+     * If this GFN is emulated MMIO or marked as read-only, pass the fault
+     * to the mmio handler.
+     */
+    if ( p2m_is_mmio(p2mt) || (p2mt == p2m_ram_ro) )
+    {
+        if ( !handle_mmio() )
+            hvm_inject_exception(TRAP_gp_fault, 0, 0);
+        return 1;
+    }
+
+    /* Log-dirty: mark the page dirty and let the guest write it again */
+    if ( p2mt == p2m_ram_logdirty )
+    {
+        paging_mark_dirty(current->domain, mfn_x(mfn));
+        p2m_change_type(current->domain, gfn, p2m_ram_logdirty, p2m_ram_rw);
+        return 1;
+    }
+
+    return 0;
+}
+
 int hvm_set_efer(uint64_t value)
 {
     struct vcpu *v = current;
diff -r 48ccb3d1ebd0 -r 6f8d8b88edd6 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Oct 27 12:57:40 2009 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Oct 27 13:02:20 2009 +0000
@@ -909,27 +909,20 @@ void start_svm(struct cpuinfo_x86 *c)
     hvm_enable(&svm_function_table);
 }
 
-static void svm_do_nested_pgfault(paddr_t gpa, struct cpu_user_regs *regs)
-{
+static void svm_do_nested_pgfault(paddr_t gpa)
+{
+    unsigned long gfn = gpa >> PAGE_SHIFT;
+    mfn_t mfn;
     p2m_type_t p2mt;
-    mfn_t mfn;
-    unsigned long gfn = gpa >> PAGE_SHIFT;
-
-    /*
-     * If this GFN is emulated MMIO or marked as read-only, pass the fault
-     * to the mmio handler.
-     */
+
+    if ( hvm_hap_nested_page_fault(gfn) )
+        return;
+
+    /* Everything else is an error. */
     mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest);
-    if ( (p2mt == p2m_mmio_dm) || (p2mt == p2m_ram_ro) )
-    {
-        if ( !handle_mmio() )
-            hvm_inject_exception(TRAP_gp_fault, 0, 0);
-        return;
-    }
-
-    /* Log-dirty: mark the page dirty and let the guest write it again */
-    paging_mark_dirty(current->domain, mfn_x(mfn));
-    p2m_change_type(current->domain, gfn, p2m_ram_logdirty, p2m_ram_rw);
+    gdprintk(XENLOG_ERR, "SVM violation gpa %#"PRIpaddr", mfn %#lx, type %i\n",
+             gpa, mfn_x(mfn), p2mt);
+    domain_crash(current->domain);
 }
 
 static void svm_fpu_dirty_intercept(void)
@@ -1428,7 +1421,7 @@ asmlinkage void svm_vmexit_handler(struc
     case VMEXIT_NPF:
         perfc_incra(svmexits, VMEXIT_NPF_PERFC);
         regs->error_code = vmcb->exitinfo1;
-        svm_do_nested_pgfault(vmcb->exitinfo2, regs);
+        svm_do_nested_pgfault(vmcb->exitinfo2);
         break;
 
     case VMEXIT_IRET:
diff -r 48ccb3d1ebd0 -r 6f8d8b88edd6 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Oct 27 12:57:40 2009 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Oct 27 13:02:20 2009 +0000
@@ -2123,50 +2123,16 @@ static void vmx_wbinvd_intercept(void)
 
 static void ept_handle_violation(unsigned long qualification, paddr_t gpa)
 {
-    unsigned long gla_validity = qualification & EPT_GLA_VALIDITY_MASK;
-    struct domain *d = current->domain;
     unsigned long gla, gfn = gpa >> PAGE_SHIFT;
     mfn_t mfn;
-    p2m_type_t t;
-
-    mfn = gfn_to_mfn_guest(d, gfn, &t);
-
-    /* There are three legitimate reasons for taking an EPT violation. 
-     * One is a guest access to MMIO space. */
-    if ( gla_validity == EPT_GLA_VALIDITY_MATCH && p2m_is_mmio(t) )
-    {
-        handle_mmio();
+    p2m_type_t p2mt;
+
+    if ( (qualification & EPT_GLA_VALID) &&
+         hvm_hap_nested_page_fault(gfn) )
         return;
-    }
-
-    /* The second is log-dirty mode, writing to a read-only page;
-     * The third is populating a populate-on-demand page. */
-    if ( (gla_validity == EPT_GLA_VALIDITY_MATCH
-          || gla_validity == EPT_GLA_VALIDITY_GPT_WALK)
-         && p2m_is_ram(t) && (t != p2m_ram_ro) )
-    {
-        if ( paging_mode_log_dirty(d) )
-        {
-            paging_mark_dirty(d, mfn_x(mfn));
-            p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw);
-            flush_tlb_mask(d->domain_dirty_cpumask);
-        }
-        return;
-    }
-
-    /* Ignore writes to:
-     *     1. read only memory regions;
-     *     2. memory holes. */
-    if ( (qualification & EPT_WRITE_VIOLATION)
-         && (((gla_validity == EPT_GLA_VALIDITY_MATCH) && (t == p2m_ram_ro))
-             || (mfn_x(mfn) == INVALID_MFN)) ) {
-        int inst_len = __get_instruction_length();
-        __update_guest_eip(inst_len);
-        return;
-    }
 
     /* Everything else is an error. */
-    gla = __vmread(GUEST_LINEAR_ADDRESS);
+    mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest);
     gdprintk(XENLOG_ERR, "EPT violation %#lx (%c%c%c/%c%c%c), "
              "gpa %#"PRIpaddr", mfn %#lx, type %i.\n", 
              qualification, 
@@ -2176,29 +2142,20 @@ static void ept_handle_violation(unsigne
              (qualification & EPT_EFFECTIVE_READ) ? 'r' : '-',
              (qualification & EPT_EFFECTIVE_WRITE) ? 'w' : '-',
              (qualification & EPT_EFFECTIVE_EXEC) ? 'x' : '-',
-             gpa, mfn_x(mfn), t);
+             gpa, mfn_x(mfn), p2mt);
+
+    if ( qualification & EPT_GLA_VALID )
+    {
+        gla = __vmread(GUEST_LINEAR_ADDRESS);
+        gdprintk(XENLOG_ERR, " --- GLA %#lx\n", gla);
+    }
 
     if ( qualification & EPT_GAW_VIOLATION )
         gdprintk(XENLOG_ERR, " --- GPA too wide (max %u bits)\n", 
-                 9 * (unsigned) d->arch.hvm_domain.vmx.ept_control.gaw + 21);
-
-    switch ( gla_validity )
-    {
-    case EPT_GLA_VALIDITY_PDPTR_LOAD:
-        gdprintk(XENLOG_ERR, " --- PDPTR load failed\n"); 
-        break;
-    case EPT_GLA_VALIDITY_GPT_WALK:
-        gdprintk(XENLOG_ERR, " --- guest PT walk to %#lx failed\n", gla);
-        break;
-    case EPT_GLA_VALIDITY_RSVD:
-        gdprintk(XENLOG_ERR, " --- GLA_validity 2 (reserved)\n");
-        break;
-    case EPT_GLA_VALIDITY_MATCH:
-        gdprintk(XENLOG_ERR, " --- guest access to %#lx failed\n", gla);
-        break;
-    }
-
-    domain_crash(d);
+                 9 * (unsigned int)current->domain->arch.hvm_domain.
+                 vmx.ept_control.gaw + 21);
+
+    domain_crash(current->domain);
 }
 
 static void vmx_failed_vmentry(unsigned int exit_reason,
diff -r 48ccb3d1ebd0 -r 6f8d8b88edd6 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Tue Oct 27 12:57:40 2009 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Tue Oct 27 13:02:20 2009 +0000
@@ -323,4 +323,6 @@ static inline void hvm_set_info_guest(st
 
 int hvm_debug_op(struct vcpu *v, int32_t op);
 
+bool_t hvm_hap_nested_page_fault(unsigned long gfn);
+
 #endif /* __ASM_X86_HVM_HVM_H__ */
diff -r 48ccb3d1ebd0 -r 6f8d8b88edd6 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Tue Oct 27 12:57:40 2009 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Tue Oct 27 13:02:20 2009 +0000
@@ -365,45 +365,24 @@ void ept_p2m_init(struct domain *d);
 void ept_p2m_init(struct domain *d);
 
 /* EPT violation qualifications definitions */
-/* bit offset 0 in exit qualification */
 #define _EPT_READ_VIOLATION         0
 #define EPT_READ_VIOLATION          (1UL<<_EPT_READ_VIOLATION)
-/* bit offset 1 in exit qualification */
 #define _EPT_WRITE_VIOLATION        1
 #define EPT_WRITE_VIOLATION         (1UL<<_EPT_WRITE_VIOLATION)
-/* bit offset 2 in exit qualification */
 #define _EPT_EXEC_VIOLATION         2
 #define EPT_EXEC_VIOLATION          (1UL<<_EPT_EXEC_VIOLATION)
-
-/* bit offset 3 in exit qualification */
 #define _EPT_EFFECTIVE_READ         3
 #define EPT_EFFECTIVE_READ          (1UL<<_EPT_EFFECTIVE_READ)
-/* bit offset 4 in exit qualification */
 #define _EPT_EFFECTIVE_WRITE        4
 #define EPT_EFFECTIVE_WRITE         (1UL<<_EPT_EFFECTIVE_WRITE)
-/* bit offset 5 in exit qualification */
 #define _EPT_EFFECTIVE_EXEC         5
 #define EPT_EFFECTIVE_EXEC          (1UL<<_EPT_EFFECTIVE_EXEC)
-
-/* bit offset 6 in exit qualification */
 #define _EPT_GAW_VIOLATION          6
 #define EPT_GAW_VIOLATION           (1UL<<_EPT_GAW_VIOLATION)
-
-/* bits offset 7 & 8 in exit qualification */
-#define _EPT_GLA_VALIDITY           7
-#define EPT_GLA_VALIDITY_MASK       (3UL<<_EPT_GLA_VALIDITY)
-/* gla != gpa, when load PDPTR */
-#define EPT_GLA_VALIDITY_PDPTR_LOAD (0UL<<_EPT_GLA_VALIDITY)
-/* gla != gpa, during guest page table walking */
-#define EPT_GLA_VALIDITY_GPT_WALK   (1UL<<_EPT_GLA_VALIDITY)
-/* reserved */
-#define EPT_GLA_VALIDITY_RSVD       (2UL<<_EPT_GLA_VALIDITY)
-/* gla == gpa, normal case */
-#define EPT_GLA_VALIDITY_MATCH      (3UL<<_EPT_GLA_VALIDITY)
-
-#define EPT_EFFECTIVE_MASK          (EPT_EFFECTIVE_READ  |  \
-                                     EPT_EFFECTIVE_WRITE |  \
-                                     EPT_EFFECTIVE_EXEC)
+#define _EPT_GLA_VALID              7
+#define EPT_GLA_VALID               (1UL<<_EPT_GLA_VALID)
+#define _EPT_GLA_FAULT              8
+#define EPT_GLA_FAULT               (1UL<<_EPT_GLA_FAULT)
 
 #define EPT_PAGETABLE_ENTRIES       512
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.4-testing] hvm: Clean up EPT/NPT 'nested page fault' handling., Xen patchbot-3.4-testing <=