[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active.
> -----Original Message----- > From: Wei Liu [mailto:wei.liu2@xxxxxxxxxx] > Sent: 23 January 2012 03:51 > To: xen-devel@xxxxxxxxxxxxxxxxxxx > Cc: Paul Durrant; Wei Liu (Intern) > Subject: [PATCH] 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> > --- > xen/arch/x86/hvm/hvm.c | 1 + > xen/common/grant_table.c | 86 > ++++++++++++++++++++++++++++++++++++++ > xen/include/public/grant_table.h | 18 +++++++- > xen/include/xlat.lst | 1 + > 4 files changed, 104 insertions(+), 2 deletions(-) > > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index > b3d9ac0..c46bd3e 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -2857,6 +2857,7 @@ static int grant_table_op_is_allowed(unsigned int > cmd) > 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 --git > a/xen/common/grant_table.c b/xen/common/grant_table.c index > 34a49db..1147a3b 100644 > --- a/xen/common/grant_table.c > +++ b/xen/common/grant_table.c > @@ -2282,6 +2282,78 @@ > gnttab_get_version(XEN_GUEST_HANDLE(gnttab_get_version_t uop)) > return 0; > } > > +static s16 > +__gnttab_swap_grant_ref(unsigned long ref_a, unsigned long 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 %ld busy\n", ref_a); > + > + act = &active_entry(d->grant_table, ref_b); > + if ( act->pin ) > + PIN_FAIL(out, GNTST_eagain, "ref %ld busy\n", 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) > @@ -2400,6 +2472,20 @@ do_grant_table_op( > 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 --git a/xen/include/public/grant_table.h > b/xen/include/public/grant_table.h > index 0bf20bc..54d9551 100644 > --- a/xen/include/public/grant_table.h > +++ b/xen/include/public/grant_table.h > @@ -511,6 +511,20 @@ struct gnttab_get_version { 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_XEN_GUEST_HANDLE(gnttab_get_version_t); > #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 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t); > "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 --git > a/xen/include/xlat.lst b/xen/include/xlat.lst index 3d92175..f602155 100644 > --- a/xen/include/xlat.lst > +++ b/xen/include/xlat.lst > @@ -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 > -- > 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |