WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] Re: [PATCH] Linux: 6 arguments hypercall v2

To: Jean Guyader <jean.guyader@xxxxxxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH] Linux: 6 arguments hypercall v2
From: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>
Date: Fri, 24 Jun 2011 15:46:58 +0100
Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>, Konrad
Delivery-date: Fri, 24 Jun 2011 07:51:11 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20110624140044.GA22264@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Organization: Citrix Systems, Inc.
References: <20110624140044.GA22264@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
On Fri, 2011-06-24 at 15:00 +0100, Jean Guyader wrote:
> Hi,
> 
> This patch implements the 6 arguments hypercalls.
> The sixth argument is passed using ebp or r9.

Looks pretty good.

I was able to get rid of more of the ifdefery etc with the following. It
appears to do the right thing (by inspection of compiled code, not
actual testing).

Defining both __res and __arg6 as register("eax") seems slightly
dubious, as is including them both in  __HYPERCALL_6PARAM, but gcc
doesn't seem to mind and it makes  __HYPERCALL_6PARAM the same in both
cases and gets rid of __HYPERCALL_DECLS6.

Your version is probably less likely to tickle ggc bugs/behaviour
changes in the future, so it's likely safer I think.

diff --git a/arch/x86/include/asm/xen/hypercall.h 
b/arch/x86/include/asm/xen/hypercall.h
index d240ea9..cacd1b9 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -74,8 +74,7 @@
  *     - clobber the rest
  *
  * The result certainly isn't pretty, and it really shows up cpp's
- * weakness as as macro language.  Sorry.  (But let's just give thanks
- * there aren't more than 5 arguments...)
+ * weakness as as macro language.  Sorry.
  */
 
 extern struct { char _entry[32]; } hypercall_page[];
@@ -91,6 +90,18 @@ extern struct { char _entry[32]; } hypercall_page[];
 #define __HYPERCALL_ARG3REG    "edx"
 #define __HYPERCALL_ARG4REG    "esi"
 #define __HYPERCALL_ARG5REG    "edi"
+
+/*
+ * On 32b we are out of free registers to pass in
+ * the 6th argument of the hypercall, the last one
+ * available is ebp.
+ * %ebp is already being used by linux so we save it
+ * then we move %eax which is the 6th argument in %ebp.
+ * On the way back of the hypercall we restore %ebp.
+ */
+#define __HYPERCALL_ARG6REG    "eax"
+#define __HYPERCALL6_PRE        "push %%ebp ; mov %%eax, %%ebp ; "
+#define __HYPERCALL6_POST       ";" "pop %%ebp"
 #else
 #define __HYPERCALL_RETREG     "rax"
 #define __HYPERCALL_ARG1REG    "rdi"
@@ -98,6 +109,9 @@ extern struct { char _entry[32]; } hypercall_page[];
 #define __HYPERCALL_ARG3REG    "rdx"
 #define __HYPERCALL_ARG4REG    "r10"
 #define __HYPERCALL_ARG5REG    "r8"
+#define __HYPERCALL_ARG6REG    "r9"
+#define __HYPERCALL6_PRE        ""
+#define __HYPERCALL6_POST       ""
 #endif
 
 #define __HYPERCALL_DECLS                                              \
@@ -106,7 +120,8 @@ extern struct { char _entry[32]; } hypercall_page[];
        register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \
        register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \
        register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \
-       register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5;
+       register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \
+       register unsigned long __arg6 asm(__HYPERCALL_ARG6REG) = __arg6;
 
 #define __HYPERCALL_0PARAM     "=r" (__res)
 #define __HYPERCALL_1PARAM     __HYPERCALL_0PARAM, "+r" (__arg1)
@@ -114,6 +129,7 @@ extern struct { char _entry[32]; } hypercall_page[];
 #define __HYPERCALL_3PARAM     __HYPERCALL_2PARAM, "+r" (__arg3)
 #define __HYPERCALL_4PARAM     __HYPERCALL_3PARAM, "+r" (__arg4)
 #define __HYPERCALL_5PARAM     __HYPERCALL_4PARAM, "+r" (__arg5)
+#define __HYPERCALL_6PARAM     __HYPERCALL_5PARAM, "+r" (__arg6)
 
 #define __HYPERCALL_0ARG()
 #define __HYPERCALL_1ARG(a1)                                           \
@@ -126,7 +142,10 @@ extern struct { char _entry[32]; } hypercall_page[];
        __HYPERCALL_3ARG(a1,a2,a3)      __arg4 = (unsigned long)(a4);
 #define __HYPERCALL_5ARG(a1,a2,a3,a4,a5)                               \
        __HYPERCALL_4ARG(a1,a2,a3,a4)   __arg5 = (unsigned long)(a5);
+#define __HYPERCALL_6ARG(a1,a2,a3,a4,a5,a6)                            \
+       __HYPERCALL_5ARG(a1,a2,a3,a4,a5) __arg6 = (unsigned long)(a6);
 
+#define __HYPERCALL_CLOBBER6   "memory"
 #define __HYPERCALL_CLOBBER5   "memory"
 #define __HYPERCALL_CLOBBER4   __HYPERCALL_CLOBBER5, __HYPERCALL_ARG5REG
 #define __HYPERCALL_CLOBBER3   __HYPERCALL_CLOBBER4, __HYPERCALL_ARG4REG
@@ -200,6 +219,17 @@ extern struct { char _entry[32]; } hypercall_page[];
        (type)__res;                                                    \
 })
 
+#define _hypercall6(type, name, a1, a2, a3, a4, a5, a6)                        
\
+({                                                                     \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_6ARG(a1, a2, a3, a4, a5, a6);                       \
+       asm volatile (__HYPERCALL6_PRE __HYPERCALL __HYPERCALL6_POST    \
+                     : __HYPERCALL_6PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER6);                          \
+       (type)__res;                                                    \
+})
+
 static inline long
 privcmd_call(unsigned call,
             unsigned long a1, unsigned long a2,
@@ -220,6 +250,7 @@ privcmd_call(unsigned call,
 static inline int
 HYPERVISOR_set_trap_table(struct trap_info *table)
 {
+       return _hypercall6(int, set_trap_table, 1, 2, 3, 4, 5, 6);
        return _hypercall1(int, set_trap_table, table);
 }
 

> 
> Signed-off-by: Jean Guyader <jean.guyader@xxxxxxxxxx>
> 
> http://lists.xensource.com/archives/html/xen-devel/2010-12/msg00945.html
> 
> Jean



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>