[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.