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 5/6] Handler m2p table and frametable fault in page f

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxxxx>, Tim Deegan <Tim.Deegan@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 5/6] Handler m2p table and frametable fault in page fault handler
From: "Jiang, Yunhong" <yunhong.jiang@xxxxxxxxx>
Date: Sun, 28 Jun 2009 17:27:44 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc:
Delivery-date: Sun, 28 Jun 2009 02:31:18 -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>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acn30rE3Fo6Vnm6ASkiYPsBaFiu16Q==
Thread-topic: [PATCH 5/6] Handler m2p table and frametable fault in page fault handler
After memory added, the m2p table and frametable maybe increased, and the 
idle_page_table is updated for it.
These new mapping are propgated to other guest, when access to the new 
m2p/frame table. The access can happen either in HV or in guest for read-only 
mapping.
The propagation is needed for 32 bit Xen environment, or compatibility guest in 
64 bit Xen environment.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>

diff -r fbba70d76aec xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Sun Jun 28 02:34:55 2009 +0800
+++ b/xen/arch/x86/traps.c      Sun Jun 28 02:34:57 2009 +0800
@@ -1213,6 +1213,9 @@ static int fixup_page_fault(unsigned lon
              (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
             return handle_gdt_ldt_mapping_fault(
                 addr - GDT_LDT_VIRT_START, regs);
+        if ( !(regs->error_code & PFEC_page_present) &&
+             (pagefault_by_memadd(addr, regs)) )
+             return handle_memadd_fault(addr, regs);
         return 0;
     }
 
diff -r fbba70d76aec xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Sun Jun 28 02:34:55 2009 +0800
+++ b/xen/arch/x86/x86_32/mm.c  Sun Jun 28 02:41:09 2009 +0800
@@ -383,6 +383,63 @@ int check_descriptor(const struct domain
     return 0;
 }
 
+
+int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs)
+{
+    if ( guest_mode(regs) )
+    {
+        if ( ((addr >= RO_MPT_VIRT_START) && (addr < RO_MPT_VIRT_END)) )
+            return 1;
+    }
+    else
+    {
+        if ( (addr >= RO_MPT_VIRT_START) && (addr < RDWR_MPT_VIRT_END) )
+            return 1;
+    }
+
+    return 0;
+}
+
+int handle_memadd_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+    l3_pgentry_t  *pl3e;
+    l3_pgentry_t l3e;
+    l2_pgentry_t *pl2e;
+    l2_pgentry_t l2e, idle_l2e;
+    unsigned long mfn, cr3;
+
+    idle_l2e = idle_pg_table_l2[l2_linear_offset(addr)];
+    if (!(l2e_get_flags(idle_l2e) & _PAGE_PRESENT))
+        return 0;
+
+    cr3 = read_cr3();
+    mfn = cr3 >> PAGE_SHIFT;
+
+    /*
+     * No need get page type here and validate checking for xen mapping
+     */
+    pl3e = map_domain_page(mfn);
+    pl3e += (cr3 & 0xFE0UL) >> 3;
+    l3e = pl3e[3];
+
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return 0;
+
+    mfn = l3e_get_pfn(l3e);
+    pl2e = map_domain_page(mfn);
+
+    l2e = pl2e[l2_table_offset(addr)];
+
+    if (l2e_get_flags(l2e) & _PAGE_PRESENT)
+        return 0;
+
+    memcpy(&pl2e[l2_table_offset(addr)],
+            &idle_pg_table_l2[l2_linear_offset(addr)],
+            sizeof(l2_pgentry_t));
+
+    return EXCRET_fault_fixed;
+}
+
 /*
  * Local variables:
  * mode: C
diff -r fbba70d76aec xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Sun Jun 28 02:34:55 2009 +0800
+++ b/xen/arch/x86/x86_64/mm.c  Sun Jun 28 02:42:08 2009 +0800
@@ -643,6 +643,76 @@ unsigned int domain_clamp_alloc_bitsize(
     return min(d->arch.physaddr_bitsize, bits);
 }
 
+int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs)
+{
+    struct domain *d = current->domain;
+#ifdef CONFIG_COMPAT
+    if (guest_mode(regs) &&
+        ((addr >= HYPERVISOR_COMPAT_VIRT_START(d)) &&
+             (addr < MACH2PHYS_COMPAT_VIRT_END)) )
+            return 1;
+#endif
+    return 0;
+}
+
+int handle_memadd_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+#ifdef CONFIG_COMPAT
+    struct domain *d = current->domain;
+    l4_pgentry_t *pl4e;
+    l4_pgentry_t l4e;
+    l3_pgentry_t  *pl3e;
+    l3_pgentry_t l3e;
+    l2_pgentry_t *pl2e;
+    l2_pgentry_t l2e, idle_l2e;
+    unsigned long mfn, idle_index;
+
+    if (!is_pv_32on64_domain(d))
+        return 0;
+
+    mfn = (read_cr3()) >> PAGE_SHIFT;
+
+    pl4e = map_domain_page(mfn);
+
+    l4e = pl4e[0];
+
+    if (!(l4e_get_flags(l4e) & _PAGE_PRESENT))
+        return 0;
+
+    mfn = l4e_get_pfn(l4e);
+    /* We don't need get page type here since it is current CR3 */
+    pl3e = map_domain_page(mfn);
+
+    l3e = pl3e[3];
+
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return 0;
+
+    mfn = l3e_get_pfn(l3e);
+    pl2e = map_domain_page(mfn);
+
+    l2e = pl2e[l2_table_offset(addr)];
+
+    if (l2e_get_flags(l2e) & _PAGE_PRESENT)
+        return 0;
+
+    idle_index = (l2_table_offset(addr) -
+                        COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d))/
+                  sizeof(l2_pgentry_t);
+    idle_l2e = compat_idle_pg_table_l2[idle_index];
+    if (!(l2e_get_flags(idle_l2e) & _PAGE_PRESENT))
+        return 0;
+    memcpy(&pl2e[l2_table_offset(addr)], 
&compat_idle_pg_table_l2[l2_table_offset(addr)],
+                sizeof(l2_pgentry_t));
+
+    memcpy(&pl2e[l2_table_offset(addr)],
+            &compat_idle_pg_table_l2[idle_index],
+            sizeof(l2_pgentry_t));
+    return EXCRET_fault_fixed;
+#endif
+    return 0;
+}
+
 #include "compat/mm.c"
 
 /*
diff -r fbba70d76aec xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Sun Jun 28 02:34:55 2009 +0800
+++ b/xen/include/asm-x86/mm.h  Sun Jun 28 02:34:57 2009 +0800
@@ -518,6 +518,8 @@ int setup_m2p_table(unsigned long spfn, 
 int setup_m2p_table(unsigned long spfn, unsigned long epfn, int hotplug);
 unsigned long domain_get_maximum_gpfn(struct domain *d);
 
+int handle_memadd_fault(unsigned long addr, struct cpu_user_regs *regs);
+int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs);
 extern struct domain *dom_xen, *dom_io;        /* for vmcoreinfo */
 
 #endif /* __ASM_X86_MM_H__ */

Attachment: page_fault.patch
Description: page_fault.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>