diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-07-13 12:18:04 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-07-13 12:18:04 +0100 |
commit | 1c4e651d3f00df7e81f8dbbd123b07835d6c9ebc (patch) | |
tree | 92e7e8da65f873f46351c21fa1a9562c68bda836 /xen/common/compat | |
parent | d785a52854430743a8e51b814f75462ac73c9291 (diff) | |
download | xen-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.c | 31 |
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; } |