[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/hypercall: Move hypercall continuation logic



The newly-repurposed arch/x86/hypercall.c is a more appropriate place for the
hypercall continuation logic to live.

This is purely code motion.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
---
 xen/arch/x86/domain.c    | 177 -----------------------------------------------
 xen/arch/x86/hypercall.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 177 insertions(+), 177 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 3209eb3..8d7cae3 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -2184,183 +2184,6 @@ void sync_vcpu_execstate(struct vcpu *v)
     flush_tlb_mask(v->vcpu_dirty_cpumask);
 }
 
-#define next_arg(fmt, args) ({                                              \
-    unsigned long __arg;                                                    \
-    switch ( *(fmt)++ )                                                     \
-    {                                                                       \
-    case 'i': __arg = (unsigned long)va_arg(args, unsigned int);  break;    \
-    case 'l': __arg = (unsigned long)va_arg(args, unsigned long); break;    \
-    case 'h': __arg = (unsigned long)va_arg(args, void *);        break;    \
-    default:  __arg = 0; BUG();                                             \
-    }                                                                       \
-    __arg;                                                                  \
-})
-
-void hypercall_cancel_continuation(void)
-{
-    current->hcall_preempted = false;
-}
-
-unsigned long hypercall_create_continuation(
-    unsigned int op, const char *format, ...)
-{
-    struct vcpu *curr = current;
-    struct mc_state *mcs = &curr->mc_state;
-    const char *p = format;
-    unsigned long arg;
-    unsigned int i;
-    va_list args;
-
-    curr->hcall_preempted = true;
-
-    va_start(args, format);
-
-    if ( mcs->flags & MCSF_in_multicall )
-    {
-        for ( i = 0; *p != '\0'; i++ )
-            mcs->call.args[i] = next_arg(p, args);
-    }
-    else
-    {
-        struct cpu_user_regs *regs = guest_cpu_user_regs();
-
-        regs->rax = op;
-
-        if ( !curr->hcall_compat )
-        {
-            for ( i = 0; *p != '\0'; i++ )
-            {
-                arg = next_arg(p, args);
-                switch ( i )
-                {
-                case 0: regs->rdi = arg; break;
-                case 1: regs->rsi = arg; break;
-                case 2: regs->rdx = arg; break;
-                case 3: regs->r10 = arg; break;
-                case 4: regs->r8  = arg; break;
-                case 5: regs->r9  = arg; break;
-                }
-            }
-        }
-        else
-        {
-            for ( i = 0; *p != '\0'; i++ )
-            {
-                arg = next_arg(p, args);
-                switch ( i )
-                {
-                case 0: regs->rbx = arg; break;
-                case 1: regs->rcx = arg; break;
-                case 2: regs->rdx = arg; break;
-                case 3: regs->rsi = arg; break;
-                case 4: regs->rdi = arg; break;
-                case 5: regs->rbp = arg; break;
-                }
-            }
-        }
-    }
-
-    va_end(args);
-
-    return op;
-}
-
-int hypercall_xlat_continuation(unsigned int *id, unsigned int nr,
-                                unsigned int mask, ...)
-{
-    int rc = 0;
-    struct mc_state *mcs = &current->mc_state;
-    struct cpu_user_regs *regs;
-    unsigned int i, cval = 0;
-    unsigned long nval = 0;
-    va_list args;
-
-    ASSERT(nr <= ARRAY_SIZE(mcs->call.args));
-    ASSERT(!(mask >> nr));
-    ASSERT(!id || *id < nr);
-    ASSERT(!id || !(mask & (1U << *id)));
-
-    va_start(args, mask);
-
-    if ( mcs->flags & MCSF_in_multicall )
-    {
-        if ( !current->hcall_preempted )
-        {
-            va_end(args);
-            return 0;
-        }
-
-        for ( i = 0; i < nr; ++i, mask >>= 1 )
-        {
-            if ( mask & 1 )
-            {
-                nval = va_arg(args, unsigned long);
-                cval = va_arg(args, unsigned int);
-                if ( cval == nval )
-                    mask &= ~1U;
-                else
-                    BUG_ON(nval == (unsigned int)nval);
-            }
-            else if ( id && *id == i )
-            {
-                *id = mcs->call.args[i];
-                id = NULL;
-            }
-            if ( (mask & 1) && mcs->call.args[i] == nval )
-            {
-                mcs->call.args[i] = cval;
-                ++rc;
-            }
-            else
-                BUG_ON(mcs->call.args[i] != (unsigned int)mcs->call.args[i]);
-        }
-    }
-    else
-    {
-        regs = guest_cpu_user_regs();
-        for ( i = 0; i < nr; ++i, mask >>= 1 )
-        {
-            unsigned long *reg;
-
-            switch ( i )
-            {
-            case 0: reg = &regs->rbx; break;
-            case 1: reg = &regs->rcx; break;
-            case 2: reg = &regs->rdx; break;
-            case 3: reg = &regs->rsi; break;
-            case 4: reg = &regs->rdi; break;
-            case 5: reg = &regs->rbp; break;
-            default: BUG(); reg = NULL; break;
-            }
-            if ( (mask & 1) )
-            {
-                nval = va_arg(args, unsigned long);
-                cval = va_arg(args, unsigned int);
-                if ( cval == nval )
-                    mask &= ~1U;
-                else
-                    BUG_ON(nval == (unsigned int)nval);
-            }
-            else if ( id && *id == i )
-            {
-                *id = *reg;
-                id = NULL;
-            }
-            if ( (mask & 1) && *reg == nval )
-            {
-                *reg = cval;
-                ++rc;
-            }
-            else
-                BUG_ON(*reg != (unsigned int)*reg);
-        }
-    }
-
-    va_end(args);
-
-    return rc;
-}
-
 static int relinquish_memory(
     struct domain *d, struct page_list_head *list, unsigned long type)
 {
diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c
index f807332..e301818 100644
--- a/xen/arch/x86/hypercall.c
+++ b/xen/arch/x86/hypercall.c
@@ -74,6 +74,183 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] =
 #undef COMP
 #undef ARGS
 
+#define next_arg(fmt, args) ({                                              \
+    unsigned long __arg;                                                    \
+    switch ( *(fmt)++ )                                                     \
+    {                                                                       \
+    case 'i': __arg = (unsigned long)va_arg(args, unsigned int);  break;    \
+    case 'l': __arg = (unsigned long)va_arg(args, unsigned long); break;    \
+    case 'h': __arg = (unsigned long)va_arg(args, void *);        break;    \
+    default:  __arg = 0; BUG();                                             \
+    }                                                                       \
+    __arg;                                                                  \
+})
+
+void hypercall_cancel_continuation(void)
+{
+    current->hcall_preempted = false;
+}
+
+unsigned long hypercall_create_continuation(
+    unsigned int op, const char *format, ...)
+{
+    struct vcpu *curr = current;
+    struct mc_state *mcs = &curr->mc_state;
+    const char *p = format;
+    unsigned long arg;
+    unsigned int i;
+    va_list args;
+
+    curr->hcall_preempted = true;
+
+    va_start(args, format);
+
+    if ( mcs->flags & MCSF_in_multicall )
+    {
+        for ( i = 0; *p != '\0'; i++ )
+            mcs->call.args[i] = next_arg(p, args);
+    }
+    else
+    {
+        struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+        regs->rax = op;
+
+        if ( !curr->hcall_compat )
+        {
+            for ( i = 0; *p != '\0'; i++ )
+            {
+                arg = next_arg(p, args);
+                switch ( i )
+                {
+                case 0: regs->rdi = arg; break;
+                case 1: regs->rsi = arg; break;
+                case 2: regs->rdx = arg; break;
+                case 3: regs->r10 = arg; break;
+                case 4: regs->r8  = arg; break;
+                case 5: regs->r9  = arg; break;
+                }
+            }
+        }
+        else
+        {
+            for ( i = 0; *p != '\0'; i++ )
+            {
+                arg = next_arg(p, args);
+                switch ( i )
+                {
+                case 0: regs->rbx = arg; break;
+                case 1: regs->rcx = arg; break;
+                case 2: regs->rdx = arg; break;
+                case 3: regs->rsi = arg; break;
+                case 4: regs->rdi = arg; break;
+                case 5: regs->rbp = arg; break;
+                }
+            }
+        }
+    }
+
+    va_end(args);
+
+    return op;
+}
+
+int hypercall_xlat_continuation(unsigned int *id, unsigned int nr,
+                                unsigned int mask, ...)
+{
+    int rc = 0;
+    struct mc_state *mcs = &current->mc_state;
+    struct cpu_user_regs *regs;
+    unsigned int i, cval = 0;
+    unsigned long nval = 0;
+    va_list args;
+
+    ASSERT(nr <= ARRAY_SIZE(mcs->call.args));
+    ASSERT(!(mask >> nr));
+    ASSERT(!id || *id < nr);
+    ASSERT(!id || !(mask & (1U << *id)));
+
+    va_start(args, mask);
+
+    if ( mcs->flags & MCSF_in_multicall )
+    {
+        if ( !current->hcall_preempted )
+        {
+            va_end(args);
+            return 0;
+        }
+
+        for ( i = 0; i < nr; ++i, mask >>= 1 )
+        {
+            if ( mask & 1 )
+            {
+                nval = va_arg(args, unsigned long);
+                cval = va_arg(args, unsigned int);
+                if ( cval == nval )
+                    mask &= ~1U;
+                else
+                    BUG_ON(nval == (unsigned int)nval);
+            }
+            else if ( id && *id == i )
+            {
+                *id = mcs->call.args[i];
+                id = NULL;
+            }
+            if ( (mask & 1) && mcs->call.args[i] == nval )
+            {
+                mcs->call.args[i] = cval;
+                ++rc;
+            }
+            else
+                BUG_ON(mcs->call.args[i] != (unsigned int)mcs->call.args[i]);
+        }
+    }
+    else
+    {
+        regs = guest_cpu_user_regs();
+        for ( i = 0; i < nr; ++i, mask >>= 1 )
+        {
+            unsigned long *reg;
+
+            switch ( i )
+            {
+            case 0: reg = &regs->rbx; break;
+            case 1: reg = &regs->rcx; break;
+            case 2: reg = &regs->rdx; break;
+            case 3: reg = &regs->rsi; break;
+            case 4: reg = &regs->rdi; break;
+            case 5: reg = &regs->rbp; break;
+            default: BUG(); reg = NULL; break;
+            }
+            if ( (mask & 1) )
+            {
+                nval = va_arg(args, unsigned long);
+                cval = va_arg(args, unsigned int);
+                if ( cval == nval )
+                    mask &= ~1U;
+                else
+                    BUG_ON(nval == (unsigned int)nval);
+            }
+            else if ( id && *id == i )
+            {
+                *id = *reg;
+                id = NULL;
+            }
+            if ( (mask & 1) && *reg == nval )
+            {
+                *reg = cval;
+                ++rc;
+            }
+            else
+                BUG_ON(*reg != (unsigned int)*reg);
+        }
+    }
+
+    va_end(args);
+
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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