aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc
diff options
context:
space:
mode:
authoriap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk>2005-09-08 17:36:23 +0000
committeriap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk>2005-09-08 17:36:23 +0000
commitcab0ef71c3013bdb8d8cae2ab3529724adbd3291 (patch)
tree7513a423883806ede4b0a87c49f46fd94a650bcd /tools/libxc
parent8ecda208694048a6926ec1f05ffc1a13e6c66a5d (diff)
downloadxen-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.c54
-rw-r--r--tools/libxc/xc_linux_build.c15
-rw-r--r--tools/libxc/xc_linux_restore.c2
-rw-r--r--tools/libxc/xc_private.c18
-rw-r--r--tools/libxc/xenctrl.h14
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. */