|
[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.
>>> On 23.01.12 at 12:51, Wei Liu <wei.liu2@xxxxxxxxxx> wrote:
> --- 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)
unsigned long?
> +{
> + 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);
As these two messages are (I think) intended to help developers, you
will want to make them distinct (so one knows which one it was that
failed).
> +
> + if ( d->grant_table->gt_version == 1 ) {
Formatting ({ on the next line).
> + 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 {
}
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)
> --- 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
Adding this here isn't enough - you also need to invoke
CHECK_gnttab_swap_grant_ref in xen/common/compat/grant_table.c,
and you should add a stub CASE() at the top of
compat_grant_table_op() (to keep the set complete there).
Jan
> ? kexec_exec kexec.h
> ! kexec_image kexec.h
> ! kexec_range kexec.h
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |