diff options
author | iap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk> | 2005-09-08 17:36:23 +0000 |
---|---|---|
committer | iap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk> | 2005-09-08 17:36:23 +0000 |
commit | cab0ef71c3013bdb8d8cae2ab3529724adbd3291 (patch) | |
tree | 7513a423883806ede4b0a87c49f46fd94a650bcd /tools/libxc | |
parent | 8ecda208694048a6926ec1f05ffc1a13e6c66a5d (diff) | |
download | xen-cab0ef71c3013bdb8d8cae2ab3529724adbd3291.tar.gz xen-cab0ef71c3013bdb8d8cae2ab3529724adbd3291.tar.bz2 xen-cab0ef71c3013bdb8d8cae2ab3529724adbd3291.zip |
Improved "PGDs must be under 4GB" handling for PAE.
Signed-off-by: ian@xensource.com
Diffstat (limited to 'tools/libxc')
-rw-r--r-- | tools/libxc/xc_domain.c | 54 | ||||
-rw-r--r-- | tools/libxc/xc_linux_build.c | 15 | ||||
-rw-r--r-- | tools/libxc/xc_linux_restore.c | 2 | ||||
-rw-r--r-- | tools/libxc/xc_private.c | 18 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 14 |
5 files changed, 91 insertions, 12 deletions
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 2c3a3a998c..7181518380 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -262,28 +262,66 @@ int xc_domain_setmaxmem(int xc_handle, int xc_domain_memory_increase_reservation(int xc_handle, u32 domid, - unsigned long mem_kb, + unsigned long nr_extents, unsigned int extent_order, - unsigned int address_bits) + unsigned int address_bits, + unsigned long *extent_start) { int err; - unsigned int npages = mem_kb / (PAGE_SIZE/1024); struct xen_memory_reservation reservation = { - .nr_extents = npages, - .extent_order = extent_order, + .extent_start = extent_start, /* may be NULL */ + .nr_extents = nr_extents, + .extent_order = extent_order, .address_bits = address_bits, .domid = domid }; err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation); - if (err == npages) + if (err == nr_extents) return 0; if (err > 0) { - fprintf(stderr,"Failed alocation for dom %d : %d pages order %d addr_bits %d\n", - domid, npages, extent_order, address_bits); + fprintf(stderr,"Failed alocation for dom %d : %ld pages order %d addr_bits %d\n", + domid, nr_extents, extent_order, address_bits); errno = ENOMEM; err = -1; } return err; } + +int xc_domain_memory_decrease_reservation(int xc_handle, + u32 domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned long *extent_start) +{ + int err; + struct xen_memory_reservation reservation = { + .extent_start = extent_start, + .nr_extents = nr_extents, + .extent_order = extent_order, + .address_bits = 0, + .domid = domid + }; + + if (extent_start == NULL) + { + fprintf(stderr,"decrease_reservation extent_start is NULL!\n"); + errno = EINVAL; + err = -1; + goto out; + } + + err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation); + if (err == nr_extents) + return 0; + + if (err > 0) { + fprintf(stderr,"Failed de-alocation for dom %d : %ld pages order %d\n", + domid, nr_extents, extent_order); + errno = EBUSY; + err = -1; + } +out: + return err; +} diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 89a71a4695..d8bd76d26f 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -136,11 +136,24 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom, /* First allocate page for page dir. */ ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT; + + if ( page_array[ppt_alloc] > 0xfffff ) + { + unsigned long nmfn; + nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] ); + if ( nmfn == 0 ) + { + fprintf(stderr, "Couldn't get a page below 4GB :-(\n"); + goto error_out; + } + page_array[ppt_alloc] = nmfn; + } + alloc_pt(l3tab, vl3tab); vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)]; ctxt->ctrlreg[3] = l3tab; - if(l3tab>0xfffff000) + if(l3tab>0xfffff000ULL) { fprintf(stderr,"L3TAB = %llx above 4GB!\n",l3tab); goto error_out; diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index d953ad2a48..f1fb60db8d 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -149,7 +149,7 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, } err = xc_domain_memory_increase_reservation(xc_handle, dom, - nr_pfns * PAGE_SIZE / 1024, 0, 0); //FIX ME + nr_pfns, 0, 0, NULL); if (err != 0) { ERR("Failed to increase reservation by %lx\n", nr_pfns * PAGE_SIZE / 1024); diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 58392cc07e..5a1d78f9d5 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -427,3 +427,21 @@ int xc_version(int xc_handle, int cmd, void *arg) { return do_xen_version(xc_handle, cmd, arg); } + +unsigned long xc_make_page_below_4G(int xc_handle, u32 domid, + unsigned long mfn) +{ + unsigned long new_mfn; + if ( xc_domain_memory_decrease_reservation( + xc_handle, domid, 1, 0, &mfn ) != 1 ) + { + fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn); + return 0; + } + if ( xc_domain_memory_increase_reservation( xc_handle, domid, 1, 0, 32, &new_mfn ) != 1 ) + { + fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn); + return 0; + } + return new_mfn; +} diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 006e647825..41174c1feb 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -387,9 +387,19 @@ int xc_domain_setmaxmem(int xc_handle, int xc_domain_memory_increase_reservation(int xc_handle, u32 domid, - unsigned long mem_kb, + unsigned long nr_extents, unsigned int extent_order, - unsigned int address_bits); + unsigned int address_bits, + unsigned long *extent_start); + +int xc_domain_memory_decrease_reservation(int xc_handle, + u32 domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned long *extent_start); + +unsigned long xc_make_page_below_4G(int xc_handle, u32 domid, + unsigned long mfn); typedef dom0_perfc_desc_t xc_perfc_desc_t; /* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ |