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

[Xen-changelog] Change the location of the shared_info page for auto_translated_physmap guests.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID fbeb0a5b7219630839986cf4cdb1b813618cbdce
# Parent  df0ad1c46f10a1075478b434956fbdb1aad6ebd5
Change the location of the shared_info page for auto_translated_physmap guests.
Instead of putting the page outside of the guests pseudo-physical address
space, we put it next to the other pages filled by the domain builder,
such that the page is already mapped in the initial pagetables and/or a
lowmem-type memory mapping.

Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r df0ad1c46f10 -r fbeb0a5b7219 
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c      Thu Mar  9 15:03:23 2006
+++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c      Thu Mar  9 16:24:57 2006
@@ -556,10 +556,15 @@
 
        kmap_init();
 
-       /* Switch to the real shared_info page, and clear the dummy page. */
-       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-       memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       if (!xen_feature(XENFEAT_auto_translated_physmap) ||
+           xen_start_info->shared_info >= xen_start_info->nr_pages) {
+               /* Switch to the real shared_info page, and clear the
+                * dummy page. */
+               set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+               HYPERVISOR_shared_info =
+                       (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+               memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       }
 
        /* Setup mapping of lower 1st MB */
        for (i = 0; i < NR_FIX_ISAMAPS; i++)
diff -r df0ad1c46f10 -r fbeb0a5b7219 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Thu Mar  9 
15:03:23 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Thu Mar  9 
16:24:57 2006
@@ -664,6 +664,13 @@
 
        setup_xen_features();
 
+       if (xen_feature(XENFEAT_auto_translated_physmap) &&
+           xen_start_info->shared_info < xen_start_info->nr_pages) {
+               HYPERVISOR_shared_info =
+                       (shared_info_t *)__va(xen_start_info->shared_info);
+               memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       }
+
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_writable_pagetables);
 
diff -r df0ad1c46f10 -r fbeb0a5b7219 
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Thu Mar  9 15:03:23 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Thu Mar  9 16:24:57 2006
@@ -757,10 +757,16 @@
        free_area_init_node(0, NODE_DATA(0), zones,
                            __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
 
-       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-
-       memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       if (!xen_feature(XENFEAT_auto_translated_physmap) ||
+           xen_start_info->shared_info >= xen_start_info->nr_pages) {
+               /* Switch to the real shared_info page, and clear the
+                * dummy page. */
+               set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+               HYPERVISOR_shared_info =
+                       (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+               memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       }
+
        init_mm.context.pinned = 1;
 
        /* Setup mapping of lower 1st MB */
diff -r df0ad1c46f10 -r fbeb0a5b7219 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Thu Mar 
 9 15:03:23 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Thu Mar 
 9 16:24:57 2006
@@ -37,6 +37,13 @@
        struct xen_platform_parameters pp;
        struct xennmi_callback cb;
 
+       if (xen_feature(XENFEAT_auto_translated_physmap) &&
+           xen_start_info->shared_info < xen_start_info->nr_pages) {
+               HYPERVISOR_shared_info =
+                       (shared_info_t *)__va(xen_start_info->shared_info);
+               memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       }
+
        HYPERVISOR_set_callbacks(
            __KERNEL_CS, (unsigned long)hypervisor_callback,
            __KERNEL_CS, (unsigned long)failsafe_callback);
diff -r df0ad1c46f10 -r fbeb0a5b7219 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Thu Mar  9 15:03:23 2006
+++ b/tools/libxc/xc_linux_build.c      Thu Mar  9 16:24:57 2006
@@ -606,15 +606,11 @@
     struct load_funcs load_funcs;
     struct domain_setup_info dsi;
     unsigned long vinitrd_start;
-    unsigned long vinitrd_end;
     unsigned long vphysmap_start;
-    unsigned long vphysmap_end;
     unsigned long vstartinfo_start;
-    unsigned long vstartinfo_end;
     unsigned long vstoreinfo_start;
-    unsigned long vstoreinfo_end;
     unsigned long vconsole_start;
-    unsigned long vconsole_end;
+    unsigned long vsharedinfo_start = 0; /* XXX gcc */
     unsigned long vstack_start;
     unsigned long vstack_end;
     unsigned long vpt_start;
@@ -640,6 +636,34 @@
         goto error_out;
     }
 
+    /* Parse and validate kernel features. */
+    p = strstr(dsi.xen_guest_string, "FEATURES=");
+    if ( p != NULL )
+    {
+        if ( !parse_features(p + strlen("FEATURES="),
+                             supported_features,
+                             required_features) )
+        {
+            ERROR("Failed to parse guest kernel features.\n");
+            goto error_out;
+        }
+
+        printf("Supported features  = { %08x }.\n", supported_features[0]);
+        printf("Required features   = { %08x }.\n", required_features[0]);
+    }
+
+    for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
+    {
+        if ( (supported_features[i]&required_features[i]) != 
required_features[i] )
+        {
+            ERROR("Guest kernel does not support a required feature.\n");
+            goto error_out;
+        }
+    }
+
+    shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
+                                           required_features);
+
     /*
      * Why do we need this? The number of page-table frames depends on the 
      * size of the bootstrap address space. But the size of the address space 
@@ -647,17 +671,22 @@
      * read-only). We have a pair of simultaneous equations in two unknowns, 
      * which we solve by exhaustive search.
      */
-    vinitrd_start    = round_pgup(dsi.v_end);
-    vinitrd_end      = vinitrd_start + initrd->len;
-    vphysmap_start   = round_pgup(vinitrd_end);
-    vphysmap_end     = vphysmap_start + (nr_pages * sizeof(unsigned long));
-    vstartinfo_start = round_pgup(vphysmap_end);
-    vstartinfo_end   = vstartinfo_start + PAGE_SIZE;
-    vstoreinfo_start = vstartinfo_end;
-    vstoreinfo_end   = vstoreinfo_start + PAGE_SIZE;
-    vconsole_start   = vstoreinfo_end;
-    vconsole_end     = vconsole_start + PAGE_SIZE;
-    vpt_start        = vconsole_end; 
+    v_end = round_pgup(dsi.v_end);
+    vinitrd_start = v_end;
+    v_end += round_pgup(initrd->len);
+    vphysmap_start = v_end;
+    v_end += round_pgup(nr_pages * sizeof(unsigned long));
+    vstartinfo_start = v_end;
+    v_end += PAGE_SIZE;
+    vstoreinfo_start = v_end;
+    v_end += PAGE_SIZE;
+    vconsole_start = v_end;
+    v_end += PAGE_SIZE;
+    if ( shadow_mode_enabled ) {
+        vsharedinfo_start = v_end;
+        v_end += PAGE_SIZE;
+    }
+    vpt_start = v_end;
 
     for ( nr_pt_pages = 2; ; nr_pt_pages++ )
     {
@@ -697,26 +726,22 @@
 
 #define _p(a) ((void *) (a))
 
-    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
-           " Loaded kernel: %p->%p\n"
-           " Init. ramdisk: %p->%p\n"
-           " Phys-Mach map: %p->%p\n"
-           " Start info:    %p->%p\n"
-           " Store page:    %p->%p\n"
-           " Console page:  %p->%p\n"
-           " Page tables:   %p->%p\n"
-           " Boot stack:    %p->%p\n"
-           " TOTAL:         %p->%p\n",
-           _p(dsi.v_kernstart), _p(dsi.v_kernend), 
-           _p(vinitrd_start), _p(vinitrd_end),
-           _p(vphysmap_start), _p(vphysmap_end),
-           _p(vstartinfo_start), _p(vstartinfo_end),
-           _p(vstoreinfo_start), _p(vstoreinfo_end),
-           _p(vconsole_start), _p(vconsole_end),
-           _p(vpt_start), _p(vpt_end),
-           _p(vstack_start), _p(vstack_end),
-           _p(dsi.v_start), _p(v_end));
-    printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
+    printf("VIRTUAL MEMORY ARRANGEMENT:\n");
+    printf(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
+           _p(dsi.v_kernend));
+    if ( initrd->len )
+        printf(" Initial ramdisk:  %p->%p\n", _p(vinitrd_start),
+               _p(vinitrd_start + initrd->len));
+    printf(" Phys-Mach map:    %p\n", _p(vphysmap_start));
+    printf(" Start info:       %p\n", _p(vstartinfo_start));
+    printf(" Store page:       %p\n", _p(vstoreinfo_start));
+    printf(" Console page:     %p\n", _p(vconsole_start));
+    if ( shadow_mode_enabled )
+        printf(" Shared Info page: %p\n", _p(vsharedinfo_start));
+    printf(" Page tables:      %p\n", _p(vpt_start));
+    printf(" Boot stack:       %p\n", _p(vstack_start));
+    printf(" TOTAL:            %p->%p\n", _p(dsi.v_start), _p(v_end));
+    printf(" ENTRY ADDRESS:    %p\n", _p(dsi.v_kernentry));
 
     if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
     {
@@ -741,36 +766,6 @@
     (load_funcs.loadimage)(image, image_size,
                            xc_handle, dom, page_array,
                            &dsi);
-
-    /* Parse and validate kernel features. */
-    p = strstr(dsi.xen_guest_string, "FEATURES=");
-    if ( p != NULL )
-    {
-        if ( !parse_features(p + strlen("FEATURES="),
-                             supported_features,
-                             required_features) )
-        {
-            ERROR("Failed to parse guest kernel features.\n");
-            goto error_out;
-        }
-
-        fprintf(stderr, "Supported features  = { %08x }.\n",
-                supported_features[0]);
-        fprintf(stderr, "Required features   = { %08x }.\n",
-                required_features[0]);
-    }
-
-    for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
-    {
-        if ( (supported_features[i]&required_features[i]) != 
required_features[i] )
-        {
-            ERROR("Guest kernel does not support a required feature.\n");
-            goto error_out;
-        }
-    }
-
-    shadow_mode_enabled = test_feature_bit(
-        XENFEAT_auto_translated_physmap, required_features);
 
     if ( load_initrd(xc_handle, dom, initrd,
                      vinitrd_start - dsi.v_start, page_array) )
@@ -869,6 +864,7 @@
     if ( shadow_mode_enabled )
     {
         struct xen_reserved_phys_area xrpa;
+        struct xen_map_shared_info xmsi;
 
         /* Enable shadow translate mode */
         if ( xc_shadow_control(xc_handle, dom,
@@ -889,7 +885,16 @@
             PERROR("Cannot find shared info pfn");
             goto error_out;
         }
-        guest_shared_info_mfn = xrpa.first_gpfn;
+
+        guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT;
+        xmsi.domid = dom;
+        xmsi.pfn = guest_shared_info_mfn;
+        rc = xc_memory_op(xc_handle, XENMEM_map_shared_info, &xmsi);
+        if ( rc != 0 )
+        {
+            PERROR("Cannot map shared info pfn");
+            goto error_out;
+        }
     }
     else
     {
diff -r df0ad1c46f10 -r fbeb0a5b7219 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Mar  9 15:03:23 2006
+++ b/xen/arch/x86/mm.c Thu Mar  9 16:24:57 2006
@@ -2817,14 +2817,15 @@
 
 long arch_memory_op(int op, GUEST_HANDLE(void) arg)
 {
-    struct xen_reserved_phys_area xrpa;
     unsigned long pfn;
     struct domain *d;
     unsigned int i;
 
     switch ( op )
     {
-    case XENMEM_reserved_phys_area:
+    case XENMEM_reserved_phys_area: {
+        struct xen_reserved_phys_area xrpa;
+
         if ( copy_from_guest(&xrpa, arg, 1) )
             return -EFAULT;
 
@@ -2846,16 +2847,14 @@
         if ( d->arch.first_reserved_pfn == 0 )
         {
             d->arch.first_reserved_pfn = pfn = d->max_pages;
-            guest_physmap_add_page(
-                d, pfn + 0, virt_to_maddr(d->shared_info) >> PAGE_SHIFT);
             for ( i = 0; i < NR_GRANT_FRAMES; i++ )
                 guest_physmap_add_page(
-                    d, pfn + 1 + i, gnttab_shared_mfn(d, d->grant_table, i));
+                    d, pfn + i, gnttab_shared_mfn(d, d->grant_table, i));
         }
         UNLOCK_BIGLOCK(d);
 
         xrpa.first_gpfn = d->arch.first_reserved_pfn;
-        xrpa.nr_gpfns   = 32;
+        xrpa.nr_gpfns   = NR_GRANT_FRAMES;
 
         put_domain(d);
 
@@ -2863,6 +2862,42 @@
             return -EFAULT;
 
         break;
+    }
+
+    case XENMEM_map_shared_info: {
+        struct xen_map_shared_info xmsi;
+
+        if ( copy_from_guest(&xmsi, arg, 1) )
+            return -EFAULT;
+
+        if ( (d = find_domain_by_id(xmsi.domid)) == NULL )
+            return -ESRCH;
+
+        /* Only initialised translated guests can set the shared_info
+         * mapping. */
+        if ( !shadow_mode_translate(d) || (d->max_pages == 0) )
+        {
+            put_domain(d);
+            return -ESRCH;
+        }
+
+        if ( xmsi.pfn > d->max_pages ) {
+            put_domain(d);
+            return -EINVAL;
+        }
+
+        LOCK_BIGLOCK(d);
+        /* Remove previously mapped page if it was present. */
+        if ( mfn_valid(gmfn_to_mfn(d, xmsi.pfn)) )
+            guest_remove_page(d, xmsi.pfn);
+        guest_physmap_add_page(d, xmsi.pfn,
+                               virt_to_maddr(d->shared_info) >> PAGE_SHIFT);
+        UNLOCK_BIGLOCK(d);
+
+        put_domain(d);
+
+        break;
+    }
 
     default:
         return subarch_memory_op(op, arg);
diff -r df0ad1c46f10 -r fbeb0a5b7219 xen/common/memory.c
--- a/xen/common/memory.c       Thu Mar  9 15:03:23 2006
+++ b/xen/common/memory.c       Thu Mar  9 16:24:57 2006
@@ -137,7 +137,43 @@
  out:
     return i;
 }
-    
+
+int
+guest_remove_page(
+    struct domain *d,
+    unsigned long gmfn)
+{
+    struct page_info *page;
+    unsigned long mfn;
+
+    mfn = gmfn_to_mfn(d, gmfn);
+    if ( unlikely(!mfn_valid(mfn)) )
+    {
+        DPRINTK("Domain %u page number %lx invalid\n",
+                d->domain_id, mfn);
+        return 0;
+    }
+            
+    page = mfn_to_page(mfn);
+    if ( unlikely(!get_page(page, d)) )
+    {
+        DPRINTK("Bad page free for domain %u\n", d->domain_id);
+        return 0;
+    }
+
+    if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
+        put_page_and_type(page);
+            
+    if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
+        put_page(page);
+
+    guest_physmap_remove_page(d, gmfn, mfn);
+
+    put_page(page);
+
+    return 1;
+}
+
 static long
 decrease_reservation(
     struct domain *d,
@@ -147,8 +183,7 @@
     unsigned int   flags,
     int           *preempted)
 {
-    struct page_info *page;
-    unsigned long    i, j, gmfn, mfn;
+    unsigned long    i, j, gmfn;
 
     if ( !guest_handle_okay(extent_list, nr_extents) )
         return 0;
@@ -166,30 +201,8 @@
 
         for ( j = 0; j < (1 << extent_order); j++ )
         {
-            mfn = gmfn_to_mfn(d, gmfn + j);
-            if ( unlikely(!mfn_valid(mfn)) )
-            {
-                DPRINTK("Domain %u page number %lx invalid\n",
-                        d->domain_id, mfn);
+            if ( !guest_remove_page(d, gmfn + j) )
                 return i;
-            }
-            
-            page = mfn_to_page(mfn);
-            if ( unlikely(!get_page(page, d)) )
-            {
-                DPRINTK("Bad page free for domain %u\n", d->domain_id);
-                return i;
-            }
-
-            if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
-                put_page_and_type(page);
-            
-            if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-                put_page(page);
-
-            guest_physmap_remove_page(d, gmfn + j, mfn);
-
-            put_page(page);
         }
     }
 
diff -r df0ad1c46f10 -r fbeb0a5b7219 xen/include/public/memory.h
--- a/xen/include/public/memory.h       Thu Mar  9 15:03:23 2006
+++ b/xen/include/public/memory.h       Thu Mar  9 16:24:57 2006
@@ -140,6 +140,21 @@
 } xen_translate_gpfn_list_t;
 DEFINE_GUEST_HANDLE(xen_translate_gpfn_list_t);
 
+/*
+ * Sets the GPFN at which the shared_info_page appears in the specified
+ * guest's pseudophysical address space.
+ * arg == addr of xen_map_shared_info_t.
+ */
+#define XENMEM_map_shared_info      9
+typedef struct xen_map_shared_info {
+    /* Which domain to change the mapping for. */
+    domid_t domid;
+
+    /* GPFN where the shared_info_page should appear. */
+    unsigned long pfn;
+} xen_map_shared_info_t;
+DEFINE_GUEST_HANDLE(xen_map_shared_info_t);
+
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
 
 /*
diff -r df0ad1c46f10 -r fbeb0a5b7219 xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Thu Mar  9 15:03:23 2006
+++ b/xen/include/xen/mm.h      Thu Mar  9 16:24:57 2006
@@ -82,4 +82,6 @@
 #define sync_pagetable_state(d) ((void)0)
 #endif
 
+int guest_remove_page(struct domain *d, unsigned long gmfn);
+
 #endif /* __XEN_MM_H__ */

_______________________________________________
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®.