# 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
|