aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/compat
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-07-13 12:18:04 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-07-13 12:18:04 +0100
commit1c4e651d3f00df7e81f8dbbd123b07835d6c9ebc (patch)
tree92e7e8da65f873f46351c21fa1a9562c68bda836 /xen/common/compat
parentd785a52854430743a8e51b814f75462ac73c9291 (diff)
downloadxen-1c4e651d3f00df7e81f8dbbd123b07835d6c9ebc.tar.gz
xen-1c4e651d3f00df7e81f8dbbd123b07835d6c9ebc.tar.bz2
xen-1c4e651d3f00df7e81f8dbbd123b07835d6c9ebc.zip
Eliminate grant_table_op restriction
Eliminate the hard-coded, arbitrarily chosen limit of 512 grant table ops a domain may submit at a time, and instead check for necessary preemption after each individual element got processed, invoking the hypercall continuation logic when necessary. Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/common/compat')
-rw-r--r--xen/common/compat/grant_table.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/xen/common/compat/grant_table.c b/xen/common/compat/grant_table.c
index 5f0dc2db57..06e75de3f0 100644
--- a/xen/common/compat/grant_table.c
+++ b/xen/common/compat/grant_table.c
@@ -35,7 +35,9 @@ int compat_grant_table_op(unsigned int cmd,
{
int rc = 0;
unsigned int i;
+ XEN_GUEST_HANDLE(void) cnt_uop;
+ set_xen_guest_handle(cnt_uop, NULL);
switch ( cmd )
{
#define CASE(name) \
@@ -79,7 +81,7 @@ int compat_grant_table_op(unsigned int cmd,
return do_grant_table_op(cmd, cmp_uop, count);
}
- if ( count > 512 )
+ if ( (int)count < 0 )
rc = -EINVAL;
for ( i = 0; i < count && rc == 0; )
@@ -128,6 +130,7 @@ int compat_grant_table_op(unsigned int cmd,
rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
}
}
+ ASSERT(rc <= 0);
if ( rc == 0 )
{
#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
@@ -163,12 +166,19 @@ int compat_grant_table_op(unsigned int cmd,
}
if ( rc == 0 )
rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n);
- if ( rc == 0 )
+ if ( rc > 0 )
+ {
+ ASSERT(rc < n);
+ i -= n - rc;
+ n = rc;
+ }
+ if ( rc >= 0 )
{
XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer;
xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t);
guest_handle_add_offset(xfer, i);
+ cnt_uop = guest_handle_cast(xfer, void);
while ( n-- )
{
guest_handle_add_offset(xfer, -1);
@@ -201,12 +211,19 @@ int compat_grant_table_op(unsigned int cmd,
}
if ( rc == 0 )
rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n);
- if ( rc == 0 )
+ if ( rc > 0 )
+ {
+ ASSERT(rc < n);
+ i -= n - rc;
+ n = rc;
+ }
+ if ( rc >= 0 )
{
XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy;
copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t);
guest_handle_add_offset(copy, i);
+ cnt_uop = guest_handle_cast(copy, void);
while ( n-- )
{
guest_handle_add_offset(copy, -1);
@@ -222,6 +239,14 @@ int compat_grant_table_op(unsigned int cmd,
}
}
+ if ( rc > 0 )
+ {
+ ASSERT(i < count);
+ ASSERT(!guest_handle_is_null(cnt_uop));
+ rc = hypercall_create_continuation(__HYPERVISOR_grant_table_op,
+ "ihi", cmd, cnt_uop, count - i);
+ }
+
return rc;
}