Xen Test Framework
main.c
Go to the documentation of this file.
1 
32 #include <xtf.h>
33 
34 #include "test.h"
35 
36 const char test_title[] = "Memory operand and segment emulation tests";
37 
38 static 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
252 };
253 
254 void 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 
274  for ( i = 0; i < ARRAY_SIZE(tests); ++i )
275  {
276  const struct test *t = &tests[i];
277  exinfo_t res;
278 
279  res = exec_user_param(t->fn, addr);
280  if ( res != t->exp )
281  xtf_failure("Fail: Testing '%s'\n"
282  " expected %pe, got %pe\n",
283  t->name, _p(t->exp), _p(res));
284 
285  if ( !xtf_has_fep )
286  continue;
287 
288  res = exec_user_param(t->fn, addr | 1);
289  if ( res != t->exp )
290  xtf_failure("Fail: Testing emulated '%s'\n"
291  " expected %pe, got %pe\n",
292  t->name, _p(t->exp), _p(res));
293  }
294 
295  xtf_success(NULL);
296 }
297 
298 /*
299  * Local variables:
300  * mode: C
301  * c-file-style: "BSD"
302  * c-basic-offset: 4
303  * tab-width: 4
304  * indent-tabs-mode: nil
305  * End:
306  */
unsigned long stub_ss_r9(unsigned long)
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
unsigned long stub_es_rsi(unsigned long)
unsigned long stub_gs_rbx(unsigned long)
unsigned long exec_user_param(unsigned long(*fn)(unsigned long), unsigned long p1)
Execute fn(p1) at user privilege, passing its return value back.
unsigned long stub_gs_r10(unsigned long)
unsigned long stub_ss_rcx(unsigned long)
unsigned long stub_none_rbx(unsigned long)
unsigned long stub_ss_r14(unsigned long)
unsigned long stub_ss_rsi(unsigned long)
unsigned long stub_gs_r14(unsigned long)
unsigned long stub_gs_abs(unsigned long)
unsigned long stub_es_rcx(unsigned long)
unsigned long stub_gs_r11(unsigned long)
#define IS_DEFINED(x)
Evalute whether the CONFIG_ token x is defined.
Definition: macro_magic.h:67
unsigned long stub_none_r13(unsigned long)
unsigned long stub_ds_rax(unsigned long)
unsigned long stub_cs_r12(unsigned long)
unsigned long stub_cs_rsp(unsigned long)
unsigned long stub_cs_r15(unsigned long)
unsigned long stub_gs_r15(unsigned long)
unsigned long stub_cs_r9(unsigned long)
#define ARRAY_SIZE(a)
Definition: lib.h:8
unsigned long stub_fs_rbp(unsigned long)
unsigned long stub_es_r9(unsigned long)
unsigned long stub_fs_r13(unsigned long)
exinfo_t exp
Definition: main.c:42
unsigned long stub_cs_rdi(unsigned long)
unsigned long stub_none_rax(unsigned long)
unsigned long stub_gs_r8(unsigned long)
unsigned long stub_ds_rdi(unsigned long)
unsigned long exec_user_ss
Definition: traps.c:13
unsigned long stub_gs_r12(unsigned long)
unsigned long stub_cs_abs(unsigned long)
unsigned long stub_cs_r10(unsigned long)
unsigned long stub_ds_rdx(unsigned long)
unsigned long stub_fs_rcx(unsigned long)
unsigned long stub_ds_abs(unsigned long)
unsigned long stub_ss_rax(unsigned long)
unsigned long stub_es_rax(unsigned long)
unsigned long stub_cs_r14(unsigned long)
unsigned long stub_ds_rbp(unsigned long)
unsigned long stub_ds_r9(unsigned long)
unsigned long stub_ss_rdi(unsigned long)
unsigned long stub_es_rbx(unsigned long)
unsigned long stub_gs_rax(unsigned long)
unsigned long stub_ss_r11(unsigned long)
unsigned long stub_es_r11(unsigned long)
unsigned long stub_gs_r9(unsigned long)
unsigned long stub_es_r10(unsigned long)
unsigned long stub_cs_rsi(unsigned long)
unsigned long stub_none_rsp(unsigned long)
unsigned long stub_ss_r15(unsigned long)
unsigned long stub_ss_r13(unsigned long)
bool xtf_has_fep
Boolean indicating whether generic Force Emulation Prefix support is available for the test to use...
Definition: setup.c:276
unsigned long stub_fs_r15(unsigned long)
unsigned long stub_none_rdi(unsigned long)
unsigned long stub_es_r15(unsigned long)
unsigned long stub_ds_r12(unsigned long)
unsigned long stub_es_rbp(unsigned long)
unsigned long stub_gs_rdi(unsigned long)
unsigned long stub_none_r10(unsigned long)
unsigned long stub_none_rdx(unsigned long)
unsigned long stub_cs_rbx(unsigned long)
unsigned long stub_fs_r9(unsigned long)
unsigned long stub_fs_r11(unsigned long)
unsigned long stub_fs_r8(unsigned long)
#define NULL
Definition: stddef.h:12
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
unsigned long stub_none_rbp(unsigned long)
unsigned long stub_cs_rbp(unsigned long)
unsigned long stub_es_rdi(unsigned long)
unsigned long stub_ds_r8(unsigned long)
unsigned long stub_cs_rax(unsigned long)
unsigned long stub_fs_rsp(unsigned long)
user_desc gdt[NR_GDT_ENTRIES]
#define SS
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:137
unsigned long stub_es_r12(unsigned long)
unsigned long stub_fs_abs(unsigned long)
#define GDTE_AVAIL1
Definition: segment.h:38
unsigned long stub_none_r14(unsigned long)
#define GP
unsigned long stub_fs_r10(unsigned long)
unsigned long stub_ds_rsp(unsigned long)
unsigned long stub_none_rsi(unsigned long)
unsigned long stub_ss_r8(unsigned long)
unsigned long stub_fs_rsi(unsigned long)
unsigned long stub_fs_rdx(unsigned long)
unsigned long stub_ss_rsp(unsigned long)
unsigned long stub_none_rcx(unsigned long)
unsigned long stub_ss_r10(unsigned long)
static void update_desc(user_desc *ptr, const user_desc new)
Helper to update a live LDT/GDT entry.
Definition: xtf.h:26
unsigned long stub_ds_r14(unsigned long)
unsigned long stub_cs_r13(unsigned long)
unsigned long stub_es_r8(unsigned long)
unsigned long stub_none_r15(unsigned long)
const char test_title[]
The title of the test.
Definition: main.c:14
unsigned long stub_none_r11(unsigned long)
unsigned long stub_es_rdx(unsigned long)
unsigned long stub_gs_rdx(unsigned long)
unsigned long stub_es_r14(unsigned long)
unsigned long stub_cs_r11(unsigned long)
unsigned long stub_ds_rbx(unsigned long)
#define GDTE_AVAIL0
Definition: segment.h:37
const char * name
Definition: main.c:41
Definition: main.c:38
unsigned long stub_fs_r12(unsigned long)
unsigned long stub_none_r9(unsigned long)
unsigned long stub_fs_rdi(unsigned long)
unsigned long stub_es_rsp(unsigned long)
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
unsigned long stub_es_abs(unsigned long)
unsigned long stub_ds_rsi(unsigned long)
unsigned long stub_fs_rbx(unsigned long)
unsigned long stub_ds_r11(unsigned long)
#define GB(num)
Express num in Gigabytes.
Definition: numbers.h:29
unsigned long stub_ds_rcx(unsigned long)
unsigned long stub_ds_r13(unsigned long)
unsigned long stub_ss_rdx(unsigned long)
unsigned long stub_ss_rbx(unsigned long)
unsigned long stub_es_r13(unsigned long)
unsigned long stub_ds_r10(unsigned long)
unsigned long(* fn)(unsigned long)
Definition: main.c:40
unsigned long stub_ss_rbp(unsigned long)
unsigned long stub_ss_r12(unsigned long)
unsigned long stub_gs_r13(unsigned long)
unsigned long stub_gs_rsp(unsigned long)
static const struct test tests[]
unsigned long stub_gs_rcx(unsigned long)
unsigned long stub_fs_r14(unsigned long)
unsigned long stub_cs_r8(unsigned long)
#define GDTE_SYM(base, limit,...)
As INIT_GDTE_SYM(), but creates a user_desc object.
unsigned long stub_none_abs(unsigned long)
unsigned long exec_user_cs
Definition: traps.c:12
unsigned long stub_none_r8(unsigned long)
unsigned long stub_cs_rdx(unsigned long)
unsigned long stub_gs_rbp(unsigned long)
unsigned long stub_fs_rax(unsigned long)
unsigned long stub_ss_abs(unsigned long)
unsigned long stub_gs_rsi(unsigned long)
unsigned long stub_cs_rcx(unsigned long)
unsigned long stub_none_r12(unsigned long)
unsigned long stub_ds_r15(unsigned long)