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

[Xen-changelog] [xen-unstable] memory hotadd 5/7: Sync changes to mapping changes caused by memory



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1260521810 0
# Node ID 611f49efe955fc5222942e51e474f1d6028d6d1e
# Parent  283a5357d1968b85278d926ec6082dad70954b17
memory hotadd 5/7: Sync changes to mapping changes caused by memory
hotplug in page fault handler.

In compact guest situation, the compat m2p table is copied, not
directly mapped in L3, so we have to sync it.  Direct mapping range
may changes, and we need sync it with guest's table.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>
---
 xen/arch/x86/traps.c     |    4 ++
 xen/arch/x86/x86_64/mm.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/mm.h |   15 ++++++++
 3 files changed, 100 insertions(+)

diff -r 283a5357d196 -r 611f49efe955 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Fri Dec 11 08:56:04 2009 +0000
+++ b/xen/arch/x86/traps.c      Fri Dec 11 08:56:50 2009 +0000
@@ -1229,6 +1229,10 @@ static int fixup_page_fault(unsigned lon
             trace_trap_two_addr(TRC_PV_PAGING_FIXUP, regs->eip, addr);
         return ret;
     }
+
+    if ( !(regs->error_code & PFEC_page_present) &&
+          (pagefault_by_memadd(addr, regs)) )
+        return handle_memadd_fault(addr, regs);
 
     if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
     {
diff -r 283a5357d196 -r 611f49efe955 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Fri Dec 11 08:56:04 2009 +0000
+++ b/xen/arch/x86/x86_64/mm.c  Fri Dec 11 08:56:50 2009 +0000
@@ -1182,6 +1182,87 @@ int check_descriptor(const struct domain
     return 0;
 }
 
+int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs)
+{
+    struct domain *d = current->domain;
+
+    if (guest_mode(regs) &&
+        is_pv_32bit_domain(d) &&
+        ((addr >= HYPERVISOR_COMPAT_VIRT_START(d)) &&
+             (addr < MACH2PHYS_COMPAT_VIRT_END)) )
+            return 1;
+    return 0;
+}
+
+int handle_memadd_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+    struct domain *d = current->domain;
+    l4_pgentry_t *pl4e = NULL;
+    l4_pgentry_t l4e;
+    l3_pgentry_t  *pl3e = NULL;
+    l3_pgentry_t l3e;
+    l2_pgentry_t *pl2e = NULL;
+    l2_pgentry_t l2e, idle_l2e;
+    unsigned long mfn, idle_index;
+    int ret = 0;
+
+    if (!is_pv_32on64_domain(d))
+        return 0;
+
+    if ((addr < HYPERVISOR_COMPAT_VIRT_START(d)) ||
+             (addr > MACH2PHYS_COMPAT_VIRT_END) )
+        return 0;
+
+    mfn = (read_cr3()) >> PAGE_SHIFT;
+
+    pl4e = map_domain_page(mfn);
+
+    l4e = pl4e[addr];
+
+    if (!(l4e_get_flags(l4e) & _PAGE_PRESENT))
+        goto unmap;
+
+    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) )
+        goto unmap;
+
+    mfn = l3e_get_pfn(l3e);
+    pl2e = map_domain_page(mfn);
+
+    l2e = pl2e[l2_table_offset(addr)];
+
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT))
+        goto unmap;
+
+    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))
+        goto unmap;
+
+    memcpy(&pl2e[l2_table_offset(addr)],
+            &compat_idle_pg_table_l2[idle_index],
+            sizeof(l2_pgentry_t));
+
+    ret = EXCRET_fault_fixed;
+
+unmap:
+    if ( pl4e )
+        unmap_domain_page(pl4e);
+    if ( pl3e )
+        unmap_domain_page(pl3e);
+    if ( pl2e )
+        unmap_domain_page(pl2e);
+
+    return ret;
+}
+
 void domain_set_alloc_bitsize(struct domain *d)
 {
     if ( !is_pv_32on64_domain(d) ||
diff -r 283a5357d196 -r 611f49efe955 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Fri Dec 11 08:56:04 2009 +0000
+++ b/xen/include/asm-x86/mm.h  Fri Dec 11 08:56:50 2009 +0000
@@ -476,6 +476,21 @@ int  ptwr_do_page_fault(struct vcpu *, u
 
 int audit_adjust_pgtables(struct domain *d, int dir, int noisy);
 
+#ifdef CONFIG_X86_64
+extern int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs);
+extern int handle_memadd_fault(unsigned long addr, struct cpu_user_regs *regs);
+#else
+int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs)
+{
+    return 0;
+}
+
+int handle_memadd_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+    return 0;
+}
+#endif
+
 #ifndef NDEBUG
 
 #define AUDIT_SHADOW_ALREADY_LOCKED ( 1u << 0 )

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.