Xen Test Framework
main.c
Go to the documentation of this file.
1
32#include <xtf.h>
33
34#include "test.h"
35
36const char test_title[] = "Memory operand and segment emulation tests";
37
38static const struct test
39{
40 unsigned long (*fn)(unsigned long);
41 const char *name;
43} tests[] =
44{
45#define GP EXINFO_SYM(GP, 0)
46#define SS EXINFO_SYM(SS, 0)
47
48#ifdef __i386__
49
50 { stub_none_abs, "abs", GP },
51 { stub_none_eax, "(%eax)", GP },
52 { stub_none_ecx, "(%ecx)", GP },
53 { stub_none_edx, "(%edx)", GP },
54 { stub_none_ebx, "(%ebx)", GP },
55 { stub_none_esp, "(%esp)", SS },
56 { stub_none_ebp, "(%ebp)", SS },
57 { stub_none_esi, "(%esi)", GP },
58 { stub_none_edi, "(%edi)", GP },
59
60 { stub_es_abs, "%es:abs", GP },
61 { stub_es_eax, "%es:(%eax)", GP },
62 { stub_es_ecx, "%es:(%ecx)", GP },
63 { stub_es_edx, "%es:(%edx)", GP },
64 { stub_es_ebx, "%es:(%ebx)", GP },
65 { stub_es_esp, "%es:(%esp)", GP },
66 { stub_es_ebp, "%es:(%ebp)", GP },
67 { stub_es_esi, "%es:(%esi)", GP },
68 { stub_es_edi, "%es:(%edi)", GP },
69
70 { stub_cs_abs, "%cs:abs", GP },
71 { stub_cs_eax, "%cs:(%eax)", GP },
72 { stub_cs_ecx, "%cs:(%ecx)", GP },
73 { stub_cs_edx, "%cs:(%edx)", GP },
74 { stub_cs_ebx, "%cs:(%ebx)", GP },
75 { stub_cs_esp, "%cs:(%esp)", GP },
76 { stub_cs_ebp, "%cs:(%ebp)", GP },
77 { stub_cs_esi, "%cs:(%esi)", GP },
78 { stub_cs_edi, "%cs:(%edi)", GP },
79
80 { stub_ss_abs, "%ss:abs", SS },
81 { stub_ss_eax, "%ss:(%eax)", SS },
82 { stub_ss_ecx, "%ss:(%ecx)", SS },
83 { stub_ss_edx, "%ss:(%edx)", SS },
84 { stub_ss_ebx, "%ss:(%ebx)", SS },
85 { stub_ss_esp, "%ss:(%esp)", SS },
86 { stub_ss_ebp, "%ss:(%ebp)", SS },
87 { stub_ss_esi, "%ss:(%esi)", SS },
88 { stub_ss_edi, "%ss:(%edi)", SS },
89
90 { stub_ds_abs, "%ds:abs", GP },
91 { stub_ds_eax, "%ds:(%eax)", GP },
92 { stub_ds_ecx, "%ds:(%ecx)", GP },
93 { stub_ds_edx, "%ds:(%edx)", GP },
94 { stub_ds_ebx, "%ds:(%ebx)", GP },
95 { stub_ds_esp, "%ds:(%esp)", GP },
96 { stub_ds_ebp, "%ds:(%ebp)", GP },
97 { stub_ds_esi, "%ds:(%esi)", GP },
98 { stub_ds_edi, "%ds:(%edi)", GP },
99
100 { stub_fs_abs, "%fs:abs", GP },
101 { stub_fs_eax, "%fs:(%eax)", GP },
102 { stub_fs_ecx, "%fs:(%ecx)", GP },
103 { stub_fs_edx, "%fs:(%edx)", GP },
104 { stub_fs_ebx, "%fs:(%ebx)", GP },
105 { stub_fs_esp, "%fs:(%esp)", GP },
106 { stub_fs_ebp, "%fs:(%ebp)", GP },
107 { stub_fs_esi, "%fs:(%esi)", GP },
108 { stub_fs_edi, "%fs:(%edi)", GP },
109
110 { stub_gs_abs, "%gs:abs", GP },
111 { stub_gs_eax, "%gs:(%eax)", GP },
112 { stub_gs_ecx, "%gs:(%ecx)", GP },
113 { stub_gs_edx, "%gs:(%edx)", GP },
114 { stub_gs_ebx, "%gs:(%ebx)", GP },
115 { stub_gs_esp, "%gs:(%esp)", GP },
116 { stub_gs_ebp, "%gs:(%ebp)", GP },
117 { stub_gs_esi, "%gs:(%esi)", GP },
118 { stub_gs_edi, "%gs:(%edi)", GP },
119
120#else
121
122 { stub_none_abs, "abs", GP },
123 { stub_none_rax, "(%rax)", GP },
124 { stub_none_rcx, "(%rcx)", GP },
125 { stub_none_rdx, "(%rdx)", GP },
126 { stub_none_rbx, "(%rbx)", GP },
127 { stub_none_rsp, "(%rsp)", SS },
128 { stub_none_rbp, "(%rbp)", SS },
129 { stub_none_rsi, "(%rsi)", GP },
130 { stub_none_rdi, "(%rdi)", GP },
131 { stub_none_r8, "(%r8)", GP },
132 { stub_none_r9, "(%r9)", GP },
133 { stub_none_r10, "(%r10)", GP },
134 { stub_none_r11, "(%r11)", GP },
135 { stub_none_r12, "(%r12)", GP },
136 { stub_none_r13, "(%r13)", GP },
137 { stub_none_r14, "(%r14)", GP },
138 { stub_none_r15, "(%r15)", GP },
139
140 { stub_es_abs, "%es:abs", GP },
141 { stub_es_rax, "%es:(%rax)", GP },
142 { stub_es_rcx, "%es:(%rcx)", GP },
143 { stub_es_rdx, "%es:(%rdx)", GP },
144 { stub_es_rbx, "%es:(%rbx)", GP },
145 { stub_es_rsp, "%es:(%rsp)", SS },
146 { stub_es_rbp, "%es:(%rbp)", SS },
147 { stub_es_rsi, "%es:(%rsi)", GP },
148 { stub_es_rdi, "%es:(%rdi)", GP },
149 { stub_es_r8, "%es:(%r8)", GP },
150 { stub_es_r9, "%es:(%r9)", GP },
151 { stub_es_r10, "%es:(%r10)", GP },
152 { stub_es_r11, "%es:(%r11)", GP },
153 { stub_es_r12, "%es:(%r12)", GP },
154 { stub_es_r13, "%es:(%r13)", GP },
155 { stub_es_r14, "%es:(%r14)", GP },
156 { stub_es_r15, "%es:(%r15)", GP },
157
158 { stub_cs_abs, "%cs:abs", GP },
159 { stub_cs_rax, "%cs:(%rax)", GP },
160 { stub_cs_rcx, "%cs:(%rcx)", GP },
161 { stub_cs_rdx, "%cs:(%rdx)", GP },
162 { stub_cs_rbx, "%cs:(%rbx)", GP },
163 { stub_cs_rsp, "%cs:(%rsp)", SS },
164 { stub_cs_rbp, "%cs:(%rbp)", SS },
165 { stub_cs_rsi, "%cs:(%rsi)", GP },
166 { stub_cs_rdi, "%cs:(%rdi)", GP },
167 { stub_cs_r8, "%cs:(%r8)", GP },
168 { stub_cs_r9, "%cs:(%r9)", GP },
169 { stub_cs_r10, "%cs:(%r10)", GP },
170 { stub_cs_r11, "%cs:(%r11)", GP },
171 { stub_cs_r12, "%cs:(%r12)", GP },
172 { stub_cs_r13, "%cs:(%r13)", GP },
173 { stub_cs_r14, "%cs:(%r14)", GP },
174 { stub_cs_r15, "%cs:(%r15)", GP },
175
176 { stub_ss_abs, "%ss:abs", GP },
177 { stub_ss_rax, "%ss:(%rax)", GP },
178 { stub_ss_rcx, "%ss:(%rcx)", GP },
179 { stub_ss_rdx, "%ss:(%rdx)", GP },
180 { stub_ss_rbx, "%ss:(%rbx)", GP },
181 { stub_ss_rsp, "%ss:(%rsp)", SS },
182 { stub_ss_rbp, "%ss:(%rbp)", SS },
183 { stub_ss_rsi, "%ss:(%rsi)", GP },
184 { stub_ss_rdi, "%ss:(%rdi)", GP },
185 { stub_ss_r8, "%ss:(%r8)", GP },
186 { stub_ss_r9, "%ss:(%r9)", GP },
187 { stub_ss_r10, "%ss:(%r10)", GP },
188 { stub_ss_r11, "%ss:(%r11)", GP },
189 { stub_ss_r12, "%ss:(%r12)", GP },
190 { stub_ss_r13, "%ss:(%r13)", GP },
191 { stub_ss_r14, "%ss:(%r14)", GP },
192 { stub_ss_r15, "%ss:(%r15)", GP },
193
194 { stub_ds_abs, "%ds:abs", GP },
195 { stub_ds_rax, "%ds:(%rax)", GP },
196 { stub_ds_rcx, "%ds:(%rcx)", GP },
197 { stub_ds_rdx, "%ds:(%rdx)", GP },
198 { stub_ds_rbx, "%ds:(%rbx)", GP },
199 { stub_ds_rsp, "%ds:(%rsp)", SS },
200 { stub_ds_rbp, "%ds:(%rbp)", SS },
201 { stub_ds_rsi, "%ds:(%rsi)", GP },
202 { stub_ds_rdi, "%ds:(%rdi)", GP },
203 { stub_ds_r8, "%ds:(%r8)", GP },
204 { stub_ds_r9, "%ds:(%r9)", GP },
205 { stub_ds_r10, "%ds:(%r10)", GP },
206 { stub_ds_r11, "%ds:(%r11)", GP },
207 { stub_ds_r12, "%ds:(%r12)", GP },
208 { stub_ds_r13, "%ds:(%r13)", GP },
209 { stub_ds_r14, "%ds:(%r14)", GP },
210 { stub_ds_r15, "%ds:(%r15)", GP },
211
212 { stub_fs_abs, "%fs:abs", GP },
213 { stub_fs_rax, "%fs:(%rax)", GP },
214 { stub_fs_rcx, "%fs:(%rcx)", GP },
215 { stub_fs_rdx, "%fs:(%rdx)", GP },
216 { stub_fs_rbx, "%fs:(%rbx)", GP },
217 { stub_fs_rsp, "%fs:(%rsp)", GP },
218 { stub_fs_rbp, "%fs:(%rbp)", GP },
219 { stub_fs_rsi, "%fs:(%rsi)", GP },
220 { stub_fs_rdi, "%fs:(%rdi)", GP },
221 { stub_fs_r8, "%fs:(%r8)", GP },
222 { stub_fs_r9, "%fs:(%r9)", GP },
223 { stub_fs_r10, "%fs:(%r10)", GP },
224 { stub_fs_r11, "%fs:(%r11)", GP },
225 { stub_fs_r12, "%fs:(%r12)", GP },
226 { stub_fs_r13, "%fs:(%r13)", GP },
227 { stub_fs_r14, "%fs:(%r14)", GP },
228 { stub_fs_r15, "%fs:(%r15)", GP },
229
230 { stub_gs_abs, "%gs:abs", GP },
231 { stub_gs_rax, "%gs:(%rax)", GP },
232 { stub_gs_rcx, "%gs:(%rcx)", GP },
233 { stub_gs_rdx, "%gs:(%rdx)", GP },
234 { stub_gs_rbx, "%gs:(%rbx)", GP },
235 { stub_gs_rsp, "%gs:(%rsp)", GP },
236 { stub_gs_rbp, "%gs:(%rbp)", GP },
237 { stub_gs_rsi, "%gs:(%rsi)", GP },
238 { stub_gs_rdi, "%gs:(%rdi)", GP },
239 { stub_gs_r8, "%gs:(%r8)", GP },
240 { stub_gs_r9, "%gs:(%r9)", GP },
241 { stub_gs_r10, "%gs:(%r10)", GP },
242 { stub_gs_r11, "%gs:(%r11)", GP },
243 { stub_gs_r12, "%gs:(%r12)", GP },
244 { stub_gs_r13, "%gs:(%r13)", GP },
245 { stub_gs_r14, "%gs:(%r14)", GP },
246 { stub_gs_r15, "%gs:(%r15)", GP },
247
248#endif
249
250#undef SS
251#undef GP
253
254void test_main(void)
255{
256 /* Top bit set + 1GB. Yields a non canonical address in 64bit. */
257 unsigned long addr = (~0ul & ~(~0ul >> 1)) + GB(1);
258 unsigned int i;
259
260 /* For 32bit, use segments with a limit of 2GB. */
261 if ( IS_DEFINED(CONFIG_32BIT) )
262 {
263 /* Code selector in AVAIL0 */
265 GDTE_SYM(0, 0x7ffff, COMMON, CODE, DPL3, R, D));
266 exec_user_cs = GDTE_AVAIL0 << 3 | 3;
267
268 /* Data selector in AVAIL1 */
270 GDTE_SYM(0, 0x7ffff, COMMON, DATA, DPL3, B, W));
271 exec_user_ss = GDTE_AVAIL1 << 3 | 3;
272
273 /* Load %fs/%gs unconditionally. */
276 }
277
278 for ( i = 0; i < ARRAY_SIZE(tests); ++i )
279 {
280 const struct test *t = &tests[i];
281 exinfo_t res;
282
283 res = exec_user_param(t->fn, addr);
284 if ( res != t->exp )
285 xtf_failure("Fail: Testing '%s'\n"
286 " expected %pe, got %pe\n",
287 t->name, _p(t->exp), _p(res));
288
289 if ( !xtf_has_fep )
290 continue;
291
292 res = exec_user_param(t->fn, addr | 1);
293 if ( res != t->exp )
294 xtf_failure("Fail: Testing emulated '%s'\n"
295 " expected %pe, got %pe\n",
296 t->name, _p(t->exp), _p(res));
297 }
298
300}
301
302/*
303 * Local variables:
304 * mode: C
305 * c-file-style: "BSD"
306 * c-basic-offset: 4
307 * tab-width: 4
308 * indent-tabs-mode: nil
309 * End:
310 */
static void write_fs(unsigned int fs)
Definition: lib.h:196
static void write_gs(unsigned int gs)
Definition: lib.h:201
unsigned long exec_user_ss
Definition: traps.h:58
unsigned long exec_user_cs
Definition: traps.c:12
static void update_desc(user_desc *ptr, const user_desc new)
Helper to update a live LDT/GDT entry.
Definition: xtf.h:26
bool xtf_has_fep
Boolean indicating whether generic Force Emulation Prefix support is available for the test to use.
Definition: setup.c:276
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:110
const char test_title[]
The title of the test.
Definition: main.c:24
user_desc gdt[NR_GDT_ENTRIES]
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
#define ARRAY_SIZE(a)
Definition: lib.h:8
unsigned long exec_user_param(unsigned long(*fn)(unsigned long), unsigned long p1)
Execute fn(p1) at user privilege, passing its return value back.
#define IS_DEFINED(x)
Evalute whether the CONFIG_ token x is defined.
Definition: macro_magic.h:67
#define GP
#define SS
static const struct test tests[]
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define GB(num)
Express num in Gigabytes.
Definition: numbers.h:29
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
#define GDTE_AVAIL0
Definition: segment.h:37
#define GDTE_AVAIL1
Definition: segment.h:38
#define NULL
Definition: stddef.h:12
Definition: main.c:39
exinfo_t exp
Definition: main.c:42
unsigned long(* fn)(unsigned long)
Definition: main.c:40
const char * name
Definition: main.c:41
#define GDTE_SYM(base, limit,...)
As INIT_GDTE_SYM(), but creates a user_desc object.
unsigned long stub_cs_r11(unsigned long)
unsigned long stub_none_rdx(unsigned long)
unsigned long stub_fs_rax(unsigned long)
unsigned long stub_cs_rcx(unsigned long)
unsigned long stub_none_rbx(unsigned long)
unsigned long stub_fs_r15(unsigned long)
unsigned long stub_ss_rdx(unsigned long)
unsigned long stub_gs_rsp(unsigned long)
unsigned long stub_gs_r10(unsigned long)
unsigned long stub_ds_r11(unsigned long)
unsigned long stub_cs_rbp(unsigned long)
unsigned long stub_fs_abs(unsigned long)
unsigned long stub_gs_rdx(unsigned long)
unsigned long stub_none_rdi(unsigned long)
unsigned long stub_gs_rax(unsigned long)
unsigned long stub_none_r9(unsigned long)
unsigned long stub_fs_r14(unsigned long)
unsigned long stub_gs_abs(unsigned long)
unsigned long stub_es_r9(unsigned long)
unsigned long stub_none_rsp(unsigned long)
unsigned long stub_es_rcx(unsigned long)
unsigned long stub_cs_r14(unsigned long)
unsigned long stub_cs_rsi(unsigned long)
unsigned long stub_none_abs(unsigned long)
unsigned long stub_ss_rbp(unsigned long)
unsigned long stub_none_rax(unsigned long)
unsigned long stub_gs_rsi(unsigned long)
unsigned long stub_gs_r8(unsigned long)
unsigned long stub_fs_r10(unsigned long)
unsigned long stub_cs_abs(unsigned long)
unsigned long stub_ss_rcx(unsigned long)
unsigned long stub_fs_r13(unsigned long)
unsigned long stub_ds_rsi(unsigned long)
unsigned long stub_fs_rdx(unsigned long)
unsigned long stub_gs_r12(unsigned long)
unsigned long stub_cs_rsp(unsigned long)
unsigned long stub_gs_rbp(unsigned long)
unsigned long stub_none_r15(unsigned long)
unsigned long stub_ss_rsp(unsigned long)
unsigned long stub_ds_rsp(unsigned long)
unsigned long stub_ds_r15(unsigned long)
unsigned long stub_cs_r10(unsigned long)
unsigned long stub_cs_r13(unsigned long)
unsigned long stub_es_r13(unsigned long)
unsigned long stub_gs_r9(unsigned long)
unsigned long stub_fs_r11(unsigned long)
unsigned long stub_es_rdx(unsigned long)
unsigned long stub_cs_r8(unsigned long)
unsigned long stub_ss_rax(unsigned long)
unsigned long stub_cs_r12(unsigned long)
unsigned long stub_cs_r9(unsigned long)
unsigned long stub_fs_r12(unsigned long)
unsigned long stub_es_rdi(unsigned long)
unsigned long stub_es_r15(unsigned long)
unsigned long stub_fs_rsp(unsigned long)
unsigned long stub_cs_rdx(unsigned long)
unsigned long stub_gs_r15(unsigned long)
unsigned long stub_cs_rbx(unsigned long)
unsigned long stub_fs_rbp(unsigned long)
unsigned long stub_es_abs(unsigned long)
unsigned long stub_ds_r12(unsigned long)
unsigned long stub_gs_rbx(unsigned long)
unsigned long stub_ss_r12(unsigned long)
unsigned long stub_ss_r10(unsigned long)
unsigned long stub_es_r8(unsigned long)
unsigned long stub_ds_abs(unsigned long)
unsigned long stub_ds_rbp(unsigned long)
unsigned long stub_gs_rcx(unsigned long)
unsigned long stub_ds_rcx(unsigned long)
unsigned long stub_none_r8(unsigned long)
unsigned long stub_fs_rsi(unsigned long)
unsigned long stub_ss_rdi(unsigned long)
unsigned long stub_ds_r14(unsigned long)
unsigned long stub_none_r11(unsigned long)
unsigned long stub_fs_r9(unsigned long)
unsigned long stub_none_rsi(unsigned long)
unsigned long stub_gs_r11(unsigned long)
unsigned long stub_none_rcx(unsigned long)
unsigned long stub_es_r11(unsigned long)
unsigned long stub_ds_r13(unsigned long)
unsigned long stub_none_r10(unsigned long)
unsigned long stub_fs_r8(unsigned long)
unsigned long stub_ds_rdi(unsigned long)
unsigned long stub_none_r14(unsigned long)
unsigned long stub_ds_r9(unsigned long)
unsigned long stub_es_rsp(unsigned long)
unsigned long stub_ss_rsi(unsigned long)
unsigned long stub_none_r13(unsigned long)
unsigned long stub_ds_r8(unsigned long)
unsigned long stub_cs_rax(unsigned long)
unsigned long stub_ds_rdx(unsigned long)
unsigned long stub_cs_r15(unsigned long)
unsigned long stub_none_r12(unsigned long)
unsigned long stub_es_rbp(unsigned long)
unsigned long stub_es_rax(unsigned long)
unsigned long stub_ss_r13(unsigned long)
unsigned long stub_ss_abs(unsigned long)
unsigned long stub_ss_r9(unsigned long)
unsigned long stub_cs_rdi(unsigned long)
unsigned long stub_fs_rbx(unsigned long)
unsigned long stub_ds_rbx(unsigned long)
unsigned long stub_ds_r10(unsigned long)
unsigned long stub_ss_r8(unsigned long)
unsigned long stub_gs_r13(unsigned long)
unsigned long stub_fs_rdi(unsigned long)
unsigned long stub_ss_r15(unsigned long)
unsigned long stub_es_r14(unsigned long)
unsigned long stub_ss_r11(unsigned long)
unsigned long stub_es_rbx(unsigned long)
unsigned long stub_fs_rcx(unsigned long)
unsigned long stub_ds_rax(unsigned long)
unsigned long stub_ss_r14(unsigned long)
unsigned long stub_none_rbp(unsigned long)
unsigned long stub_es_r12(unsigned long)
unsigned long stub_es_r10(unsigned long)
unsigned long stub_gs_r14(unsigned long)
unsigned long stub_gs_rdi(unsigned long)
unsigned long stub_ss_rbx(unsigned long)
unsigned long stub_es_rsi(unsigned long)