Magellan Linux

Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1048-2.6.25-xen-x86_64-Make-hypercall-assembly-code-work.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 606 - (show annotations) (download)
Thu May 22 23:13:13 2008 UTC (15 years, 11 months ago) by niro
File size: 5690 byte(s)
-ver bump to 2.6.25-magellan-r1:
- linux-2.6.25.4
- fbcondecor-0.9.4
- squashfs-3.3
- unionfs-2.3.3
- tuxonice-3.0-rc7
- linux-phc-0.3.0
- acpi-dstd-0.9a
- reiser4
- xen-3.2.0
. ipw3945-1.2.2

1 From c83e0eda9e665d2f1607a46e778d8c907814a36e Mon Sep 17 00:00:00 2001
2 From: Eduardo Habkost <ehabkost@redhat.com>
3 Date: Tue, 4 Dec 2007 16:25:41 -0200
4 Subject: [PATCH] xen x86_64: Make hypercall assembly code work
5
6 Se comment for explanation.
7
8 Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
9 ---
10 include/asm-x86/xen/hypercall.h | 113 ++++++++++++++++++++++++++++++--------
11 1 files changed, 89 insertions(+), 24 deletions(-)
12
13 diff --git a/include/asm-x86/xen/hypercall.h b/include/asm-x86/xen/hypercall.h
14 index cbf3d52..605775e 100644
15 --- a/include/asm-x86/xen/hypercall.h
16 +++ b/include/asm-x86/xen/hypercall.h
17 @@ -42,13 +42,42 @@
18
19 extern struct { char _entry[32]; } hypercall_page[];
20
21 +#define __STR(x) #x
22 +#define STR(x) __STR(x)
23 +
24 +/* We could let gcc handle the asm operand generation for us, and
25 + * use hypercall_page[__HYPERVISOR_##name] as a asm "m" or "i" operand.
26 + *
27 + * On i386, a "m" operand works for a direct call, but on x86_64,
28 + * gcc generates a %rip-relative operand and the assembler generates
29 + * an indirect call (and emits a warning).
30 + *
31 + *
32 + * A "i" operand could work, but at least on x86_64, gcc generates
33 + * the following:
34 + *
35 + * call $hypercall_page+555
36 + *
37 + * That is rejected by the assembler with the error "suffix or operands
38 + * invalid for `call'"
39 + */
40 +#define HYPERCALL_STR(name) \
41 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
42 +
43 +#ifdef CONFIG_X86_64
44 +#define IGN1 "=D"
45 +#define IGN2 "=S"
46 +#else
47 +#define IGN1 "=b"
48 +#define IGN2 "=c"
49 +#endif
50 +
51 #define _hypercall0(type, name) \
52 ({ \
53 long __res; \
54 asm volatile ( \
55 - "call %[call]" \
56 + HYPERCALL_STR(name) \
57 : "=a" (__res) \
58 - : [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
59 : "memory" ); \
60 (type)__res; \
61 })
62 @@ -57,10 +86,9 @@ extern struct { char _entry[32]; } hypercall_page[];
63 ({ \
64 long __res, __ign1; \
65 asm volatile ( \
66 - "call %[call]" \
67 - : "=a" (__res), "=b" (__ign1) \
68 - : "1" ((long)(a1)), \
69 - [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
70 + HYPERCALL_STR(name) \
71 + : "=a" (__res), IGN1(__ign1) \
72 + : "1" ((long)(a1)) \
73 : "memory" ); \
74 (type)__res; \
75 })
76 @@ -69,10 +97,9 @@ extern struct { char _entry[32]; } hypercall_page[];
77 ({ \
78 long __res, __ign1, __ign2; \
79 asm volatile ( \
80 - "call %[call]" \
81 - : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
82 - : "1" ((long)(a1)), "2" ((long)(a2)), \
83 - [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
84 + HYPERCALL_STR(name) \
85 + : "=a" (__res), IGN1(__ign1), IGN2(__ign2) \
86 + : "1" ((long)(a1)), "2" ((long)(a2)) \
87 : "memory" ); \
88 (type)__res; \
89 })
90 @@ -81,27 +108,64 @@ extern struct { char _entry[32]; } hypercall_page[];
91 ({ \
92 long __res, __ign1, __ign2, __ign3; \
93 asm volatile ( \
94 - "call %[call]" \
95 - : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
96 + HYPERCALL_STR(name) \
97 + : "=a" (__res), IGN1(__ign1), IGN2(__ign2), \
98 "=d" (__ign3) \
99 : "1" ((long)(a1)), "2" ((long)(a2)), \
100 - "3" ((long)(a3)), \
101 - [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
102 + "3" ((long)(a3)) \
103 : "memory" ); \
104 (type)__res; \
105 })
106
107 +/* The hypercalls below are handled differently on x86_64 because
108 + * of the way the 4th and following parameters are passed to the asm
109 + * block.
110 + */
111 +
112 +#ifdef CONFIG_X86_64
113 +
114 +#define _hypercall4(type, name, a1, a2, a3, a4) \
115 +({ \
116 + long __res, __ign1, __ign2, __ign3; \
117 + asm volatile ( \
118 + "movq %7,%%r10; " \
119 + HYPERCALL_STR(name) \
120 + : "=a" (__res), IGN1(__ign1), IGN2(__ign2), \
121 + "=d" (__ign3) \
122 + : "1" ((long)(a1)), "2" ((long)(a2)), \
123 + "3" ((long)(a3)), "g" ((long)(a4)) \
124 + : "memory", "r10"); \
125 + (type)__res; \
126 +})
127 +
128 +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
129 +({ \
130 + long __res, __ign1, __ign2, __ign3; \
131 + asm volatile ( \
132 + "movq %7,%%r10; movq %8,%%r8; " \
133 + HYPERCALL_STR(name) \
134 + : "=a" (__res), IGN1(__ign1), IGN2(__ign2), \
135 + "=d" (__ign3) \
136 + : "1" ((long)(a1)), "2" ((long)(a2)), \
137 + "3" ((long)(a3)), "g" ((long)(a4)), \
138 + "g" ((long)(a5)) \
139 + : "memory", "r10", "r8"); \
140 + (type)__res; \
141 +})
142 +
143 +
144 +#else
145 +
146 #define _hypercall4(type, name, a1, a2, a3, a4) \
147 ({ \
148 long __res, __ign1, __ign2, __ign3, __ign4; \
149 asm volatile ( \
150 - "call %[call]" \
151 - : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
152 + HYPERCALL_STR(name) \
153 + : "=a" (__res), IGN1(__ign1), IGN2(__ign2), \
154 "=d" (__ign3), "=S" (__ign4) \
155 : "1" ((long)(a1)), "2" ((long)(a2)), \
156 - "3" ((long)(a3)), "4" ((long)(a4)), \
157 - [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
158 - : "memory" ); \
159 + "3" ((long)(a3)), "4" ((long)(a4)) \
160 + : "memory"); \
161 (type)__res; \
162 })
163
164 @@ -109,17 +173,18 @@ extern struct { char _entry[32]; } hypercall_page[];
165 ({ \
166 long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
167 asm volatile ( \
168 - "call %[call]" \
169 - : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
170 + HYPERCALL_STR(name) \
171 + : "=a" (__res), IGN1(__ign1), IGN2(__ign2), \
172 "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
173 : "1" ((long)(a1)), "2" ((long)(a2)), \
174 "3" ((long)(a3)), "4" ((long)(a4)), \
175 - "5" ((long)(a5)), \
176 - [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
177 - : "memory" ); \
178 + "5" ((long)(a5)) \
179 + : "memory"); \
180 (type)__res; \
181 })
182
183 +#endif
184 +
185 #if defined(CONFIG_X86_64)
186 #define MULTI_UVMFLAGS_INDEX 2
187 #define MULTI_UVMDOMID_INDEX 3
188 --
189 1.5.4.1
190