xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2] Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active.
@ 2012-01-23 13:56 Wei Liu
  2012-01-25 15:52 ` Wei Liu
  0 siblings, 1 reply; 3+ messages in thread
From: Wei Liu @ 2012-01-23 13:56 UTC (permalink / raw)
  To: xen-devel; +Cc: Paul Durrant, wei.liu2, Jan Beulich

Fix issues commented by Jan - coding style, stubs and variable types.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/hvm/hvm.c           |    1 +
 xen/common/compat/grant_table.c  |    8 +++
 xen/common/grant_table.c         |   89 ++++++++++++++++++++++++++++++++++++++
 xen/include/public/grant_table.h |   18 +++++++-
 xen/include/xlat.lst             |    1 +
 5 files changed, 115 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/compat/grant_table.c b/xen/common/compat/grant_table.c
index ca60395..edd20c6 100644
--- a/xen/common/compat/grant_table.c
+++ b/xen/common/compat/grant_table.c
@@ -47,6 +47,10 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_compat_t);
 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 @@ int compat_grant_table_op(unsigned int cmd,
     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 --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 34a49db..2683324 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -2282,6 +2282,81 @@ gnttab_get_version(XEN_GUEST_HANDLE(gnttab_get_version_t uop))
     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)
@@ -2400,6 +2475,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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH V2] Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active.
  2012-01-23 13:56 [PATCH V2] Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active Wei Liu
@ 2012-01-25 15:52 ` Wei Liu
  2012-01-25 15:56   ` Keir Fraser
  0 siblings, 1 reply; 3+ messages in thread
From: Wei Liu @ 2012-01-25 15:52 UTC (permalink / raw)
  To: xen-devel; +Cc: Keir Fraser, wei.liu2

Keir, ping?

And got a SOB from Paul:

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

On Mon, 2012-01-23 at 13:56 +0000, Wei Liu (Intern) wrote:
> Fix issues commented by Jan - coding style, stubs and variable types.
> 
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
>  xen/arch/x86/hvm/hvm.c           |    1 +
>  xen/common/compat/grant_table.c  |    8 +++
>  xen/common/grant_table.c         |   89 ++++++++++++++++++++++++++++++++++++++
>  xen/include/public/grant_table.h |   18 +++++++-
>  xen/include/xlat.lst             |    1 +
>  5 files changed, 115 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/compat/grant_table.c b/xen/common/compat/grant_table.c
> index ca60395..edd20c6 100644
> --- a/xen/common/compat/grant_table.c
> +++ b/xen/common/compat/grant_table.c
> @@ -47,6 +47,10 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_compat_t);
>  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 @@ int compat_grant_table_op(unsigned int cmd,
>      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 --git a/xen/common/grant_table.c b/xen/common/grant_table.c
> index 34a49db..2683324 100644
> --- a/xen/common/grant_table.c
> +++ b/xen/common/grant_table.c
> @@ -2282,6 +2282,81 @@ gnttab_get_version(XEN_GUEST_HANDLE(gnttab_get_version_t uop))
>      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)
> @@ -2400,6 +2475,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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH V2] Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active.
  2012-01-25 15:52 ` Wei Liu
@ 2012-01-25 15:56   ` Keir Fraser
  0 siblings, 0 replies; 3+ messages in thread
From: Keir Fraser @ 2012-01-25 15:56 UTC (permalink / raw)
  To: Wei Liu, xen-devel

On 25/01/2012 15:52, "Wei Liu" <wei.liu2@citrix.com> wrote:

> Keir, ping?

It is already checked in.

 -- Keir

> And got a SOB from Paul:
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> On Mon, 2012-01-23 at 13:56 +0000, Wei Liu (Intern) wrote:
>> Fix issues commented by Jan - coding style, stubs and variable types.
>> 
>> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
>> ---
>>  xen/arch/x86/hvm/hvm.c           |    1 +
>>  xen/common/compat/grant_table.c  |    8 +++
>>  xen/common/grant_table.c         |   89
>> ++++++++++++++++++++++++++++++++++++++
>>  xen/include/public/grant_table.h |   18 +++++++-
>>  xen/include/xlat.lst             |    1 +
>>  5 files changed, 115 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/compat/grant_table.c
>> b/xen/common/compat/grant_table.c
>> index ca60395..edd20c6 100644
>> --- a/xen/common/compat/grant_table.c
>> +++ b/xen/common/compat/grant_table.c
>> @@ -47,6 +47,10 @@
>> DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_compat_t);
>>  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 @@ int compat_grant_table_op(unsigned int cmd,
>>      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 --git a/xen/common/grant_table.c b/xen/common/grant_table.c
>> index 34a49db..2683324 100644
>> --- a/xen/common/grant_table.c
>> +++ b/xen/common/grant_table.c
>> @@ -2282,6 +2282,81 @@
>> gnttab_get_version(XEN_GUEST_HANDLE(gnttab_get_version_t uop))
>>      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)
>> @@ -2400,6 +2475,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
> 
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-01-25 15:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-23 13:56 [PATCH V2] Add a GNTTABOP to swap the content of two grant references under lock provided that they are not currently active Wei Liu
2012-01-25 15:52 ` Wei Liu
2012-01-25 15:56   ` Keir Fraser

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).