Support for save and restore of compatibility guests
authorEmmanuel Ackaouy <ack@xensource.com>
Fri, 5 Jan 2007 17:34:43 +0000 (17:34 +0000)
committerEmmanuel Ackaouy <ack@xensource.com>
Fri, 5 Jan 2007 17:34:43 +0000 (17:34 +0000)
Signed-off-by: Emmanuel Ackaouy <ack@xensource.com>
tools/libxc/xc_linux_save.c
tools/libxc/xg_save_restore.h
xen/arch/x86/domctl.c
xen/include/asm-x86/x86_64/page.h

index 44dba99cd5b8137f7a682ce16471f0471235bc84..7ca8453848323363754c65b12a404bd24e48f974 100644 (file)
@@ -44,6 +44,7 @@ static xen_pfn_t *live_p2m = NULL;
 
 /* Live mapping of system MFN to PFN table. */
 static xen_pfn_t *live_m2p = NULL;
+static unsigned long m2p_mfn0;
 
 /* grep fodder: machine_to_phys */
 
@@ -440,13 +441,23 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn,
     ** that this check will fail for other L2s.
     */
     if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L2TAB) {
-
-/* XXX index of the L2 entry in PAE mode which holds the guest LPT */
-#define PAE_GLPT_L2ENTRY (495)
-        pte = ((const uint64_t*)spage)[PAE_GLPT_L2ENTRY];
-
-        if(((pte >> PAGE_SHIFT) & 0x0fffffff) == live_p2m[pfn])
-            xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
+        int hstart;
+        unsigned long he;
+
+        hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
+        he = ((const uint64_t *) spage)[hstart];
+
+        if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) {
+            /* hvirt starts with xen stuff... */
+            xen_start = hstart;
+        } else if ( hvirt_start != 0xf5800000 ) {
+            /* old L2s from before hole was shrunk... */
+            hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
+            he = ((const uint64_t *) spage)[hstart];
+
+            if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 )
+                xen_start = hstart;
+        }
     }
 
     if (pt_levels == 4 && type == XEN_DOMCTL_PFINFO_L4TAB) {
@@ -550,6 +561,8 @@ static xen_pfn_t *xc_map_m2p(int xc_handle,
         return NULL;
     }
 
+    m2p_mfn0 = entries[0].mfn;
+
     free(extent_start);
     free(entries);
 
index 00d0753defd18a5363b267afe7506bf504fa11ea..6275b37ef03deeb8c03f08097410e59302ab17f1 100644 (file)
@@ -53,8 +53,17 @@ static int get_platform_info(int xc_handle, uint32_t dom,
 
     *hvirt_start = xen_params.virt_start;
 
+    /*
+     * XXX For now, 32bit dom0's can only save/restore 32bit domUs
+     * on 64bit hypervisors, so no need to check which type of domain
+     * we're dealing with.
+     */
     if (strstr(xen_caps, "xen-3.0-x86_64"))
+#if defined(__i386__)
+        *pt_levels = 3;
+#else
         *pt_levels = 4;
+#endif
     else if (strstr(xen_caps, "xen-3.0-x86_32p"))
         *pt_levels = 3;
     else if (strstr(xen_caps, "xen-3.0-x86_32"))
index f1b63ffb66ae260c9d16bc50dee1deb28545c7f3..fdc102c1a54b61d7e395aa0d4dfb3fb9013962ce 100644 (file)
@@ -356,7 +356,10 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
         c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
 #ifdef CONFIG_COMPAT
     else
-        c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
+    {
+        l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table));
+        c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
+    }
 #endif
 
     c(vm_assist = v->domain->vm_assist);
index b1f59b8f13d5ea18d243a9993af58b277461f94c..ecda3a7bf5c5e35ad4d94325050f732fa99ead86 100644 (file)
@@ -96,7 +96,7 @@ typedef l4_pgentry_t root_pgentry_t;
 #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
 #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
 
-#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */
+#define COMPAT_L3_DISALLOW_MASK L3_DISALLOW_MASK
 
 #define PAGE_HYPERVISOR         (__PAGE_HYPERVISOR         | _PAGE_GLOBAL)
 #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL)