/[pkg-src]/trunk/kernel26-xen/patches-2.6.25-r1/1048-2.6.25-xen-x86_64-Make-hypercall-assembly-code-work.patch |
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 | 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)
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 |