[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Add a GNTTABOP to swap the content of two grant references under lock
# HG changeset patch # User Wei Liu <wei.liu2@xxxxxxxxxx> # Date 1327414564 0 # Node ID d115844ebfbb02bd785a4bd1b50fa31072f36bff # Parent 370924e204dc29e12cd807dd730974d6b2bc53d3 Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Committed-by: Keir Fraser <keir@xxxxxxx> --- diff -r 370924e204dc -r d115844ebfbb xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Jan 23 15:10:43 2012 +0000 +++ b/xen/arch/x86/hvm/hvm.c Tue Jan 24 14:16:04 2012 +0000 @@ -2959,6 +2959,7 @@ case GNTTABOP_copy: case GNTTABOP_map_grant_ref: case GNTTABOP_unmap_grant_ref: + case GNTTABOP_swap_grant_ref: return 1; default: /* all other commands need auditing */ diff -r 370924e204dc -r d115844ebfbb xen/common/compat/grant_table.c --- a/xen/common/compat/grant_table.c Mon Jan 23 15:10:43 2012 +0000 +++ b/xen/common/compat/grant_table.c Tue Jan 24 14:16:04 2012 +0000 @@ -47,6 +47,10 @@ CHECK_gnttab_get_version; #undef xen_gnttab_get_version +#define xen_gnttab_swap_grant_ref gnttab_swap_grant_ref +CHECK_gnttab_swap_grant_ref; +#undef xen_gnttab_swap_grant_ref + int compat_grant_table_op(unsigned int cmd, XEN_GUEST_HANDLE(void) cmp_uop, unsigned int count) @@ -98,6 +102,10 @@ CASE(get_status_frames); #endif +#ifndef CHECK_gnttab_swap_grant_ref + CASE(swap_grant_ref); +#endif + #undef CASE default: return do_grant_table_op(cmd, cmp_uop, count); diff -r 370924e204dc -r d115844ebfbb xen/common/grant_table.c --- a/xen/common/grant_table.c Mon Jan 23 15:10:43 2012 +0000 +++ b/xen/common/grant_table.c Tue Jan 24 14:16:04 2012 +0000 @@ -2283,6 +2283,81 @@ return 0; } +static s16 +__gnttab_swap_grant_ref(grant_ref_t ref_a, grant_ref_t ref_b) +{ + struct domain *d; + struct active_grant_entry *act; + s16 rc = GNTST_okay; + + d = rcu_lock_current_domain(); + + spin_lock(&d->grant_table->lock); + + act = &active_entry(d->grant_table, ref_a); + if ( act->pin ) + PIN_FAIL(out, GNTST_eagain, "ref a %ld busy\n", (long)ref_a); + + act = &active_entry(d->grant_table, ref_b); + if ( act->pin ) + PIN_FAIL(out, GNTST_eagain, "ref b %ld busy\n", (long)ref_b); + + if ( d->grant_table->gt_version == 1 ) + { + grant_entry_v1_t shared; + + shared = shared_entry_v1(d->grant_table, ref_a); + + shared_entry_v1(d->grant_table, ref_a) = + shared_entry_v1(d->grant_table, ref_b); + + shared_entry_v1(d->grant_table, ref_b) = shared; + } + else + { + grant_entry_v2_t shared; + grant_status_t status; + + shared = shared_entry_v2(d->grant_table, ref_a); + status = status_entry(d->grant_table, ref_a); + + shared_entry_v2(d->grant_table, ref_a) = + shared_entry_v2(d->grant_table, ref_b); + status_entry(d->grant_table, ref_a) = + status_entry(d->grant_table, ref_b); + + shared_entry_v2(d->grant_table, ref_b) = shared; + status_entry(d->grant_table, ref_b) = status; + } + +out: + spin_unlock(&d->grant_table->lock); + + rcu_unlock_domain(d); + + return rc; +} + +static long +gnttab_swap_grant_ref(XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t uop), + unsigned int count) +{ + int i; + gnttab_swap_grant_ref_t op; + + for ( i = 0; i < count; i++ ) + { + if ( i && hypercall_preempt_check() ) + return i; + if ( unlikely(__copy_from_guest_offset(&op, uop, i, 1)) ) + return -EFAULT; + op.status = __gnttab_swap_grant_ref(op.ref_a, op.ref_b); + if ( unlikely(__copy_to_guest_offset(uop, i, &op, 1)) ) + return -EFAULT; + } + return 0; +} + long do_grant_table_op( unsigned int cmd, XEN_GUEST_HANDLE(void) uop, unsigned int count) @@ -2401,6 +2476,20 @@ rc = gnttab_get_version(guest_handle_cast(uop, gnttab_get_version_t)); break; } + case GNTTABOP_swap_grant_ref: + { + XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t) swap = + guest_handle_cast(uop, gnttab_swap_grant_ref_t); + if ( unlikely(!guest_handle_okay(swap, count)) ) + goto out; + rc = gnttab_swap_grant_ref(swap, count); + if ( rc > 0 ) + { + guest_handle_add_offset(swap, rc); + uop = guest_handle_cast(swap, void); + } + break; + } default: rc = -ENOSYS; break; diff -r 370924e204dc -r d115844ebfbb xen/include/public/grant_table.h --- a/xen/include/public/grant_table.h Mon Jan 23 15:10:43 2012 +0000 +++ b/xen/include/public/grant_table.h Tue Jan 24 14:16:04 2012 +0000 @@ -511,6 +511,20 @@ typedef struct gnttab_get_version gnttab_get_version_t; DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t); +/* + * GNTTABOP_swap_grant_ref: Swap the contents of two grant entries. + */ +#define GNTTABOP_swap_grant_ref 11 +struct gnttab_swap_grant_ref { + /* IN parameters */ + grant_ref_t ref_a; + grant_ref_t ref_b; + /* OUT parameters */ + int16_t status; /* GNTST_* */ +}; +typedef struct gnttab_swap_grant_ref gnttab_swap_grant_ref_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t); + #endif /* __XEN_INTERFACE_VERSION__ */ /* @@ -566,7 +580,7 @@ #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */ #define GNTST_address_too_big (-11) /* transfer page address too large. */ -#define GNTST_eagain (-12) /* Could not map at the moment. Retry. */ +#define GNTST_eagain (-12) /* Operation not done; try again. */ #define GNTTABOP_error_msgs { \ "okay", \ @@ -581,7 +595,7 @@ "bad page", \ "copy arguments cross page boundary", \ "page address size too large", \ - "could not map at the moment, retry" \ + "operation not done; try again" \ } #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ diff -r 370924e204dc -r d115844ebfbb xen/include/xlat.lst --- a/xen/include/xlat.lst Mon Jan 23 15:10:43 2012 +0000 +++ b/xen/include/xlat.lst Tue Jan 24 14:16:04 2012 +0000 @@ -50,6 +50,7 @@ ? grant_entry_v1 grant_table.h ? grant_entry_header grant_table.h ? grant_entry_v2 grant_table.h +? gnttab_swap_grant_ref grant_table.h ? kexec_exec kexec.h ! kexec_image kexec.h ! kexec_range kexec.h _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |