Xen Test Framework
main.c
Go to the documentation of this file.
1
47#include <xtf.h>
48
49#include "lowlevel.h"
50
51const char test_title[] = "Software interrupt emulation";
52
53#ifdef __i386__
54# define COND(_32, _64) _32
55#else
56# define COND(_32, _64) _64
57#endif
58
59#define EXINFO_TRAP EXINFO_AVAIL0
60
61enum mode { KERN, USER };
62
63bool ex_record_trap_eax(struct cpu_regs *regs, const struct extable_entry *ex)
64{
65 regs->ax = EXINFO(regs->entry_vector, regs->error_code) | EXINFO_TRAP;
66 regs->ip = ex->fixup;
67
68 return true;
69}
70
71struct insn
72{
73 const char *name;
74 unsigned long (*fn[4])(void);
75 unsigned long (*user_fn[4])(void);
76};
77
78const struct insn int3 = {
79 "int3",
80 {
85 },
86 {
91 },
92};
93
94const struct insn int_0x3 = {
95 "int $3",
96 {
101 },
102 {
107 },
108};
109
110const struct insn icebp = {
111 "icebp",
112 {
117 },
118 {
123 },
124};
125
126const struct insn int_0x1 = {
127 "int $1",
128 {
133 },
134 {
139 },
140};
141
142const struct insn into = {
143 "into",
144 {
145 stub_into,
149 },
150 {
155 },
156};
157
158void test_insn(enum mode user, const struct insn *insn, exinfo_t exp)
159{
160 printk(" Testing %s\n", insn->name);
161
162 for ( unsigned int i = 0; i < ARRAY_SIZE(insn->fn); ++i )
163 {
164 exinfo_t got;
165
166 got = user ? exec_user(insn->user_fn[i]) : insn->fn[i]();
167
168 if ( exp != got )
169 xtf_failure(" Fail (Force%c, Addr%c): expected %pe %s, got %pe %s\n",
170 i & 1 ? '+' : '-',
171 i & 2 ? '+' : '-',
172 _p(exp), exp & EXINFO_TRAP ? "trap" : "fault",
173 _p(got), got & EXINFO_TRAP ? "trap" : "fault");
174
175 /* Avoid FEP stubs if FEP isn't available. */
176 if ( i == 1 && !xtf_has_fep )
177 break;
178 }
179}
180
182static void set_idt_entries_present(bool present)
183{
184 idt[X86_EXC_DB].p = present;
185 idt[X86_EXC_BP].p = present;
186 idt[X86_EXC_OF].p = present;
187}
188
190static void set_idt_entries_dpl(unsigned int dpl)
191{
192 idt[X86_EXC_DB].dpl = dpl;
193 idt[X86_EXC_BP].dpl = dpl;
194 idt[X86_EXC_OF].dpl = dpl;
195}
196
197#define TRAP(V) EXINFO_SYM(V, 0) | EXINFO_TRAP
198#define FAULT(V) EXINFO_SYM(V, 0)
199#define FAULT_EC(V, ...) EXINFO_SYM(V, EXC_EC_SYM(__VA_ARGS__))
200
202void cpl3_tests(void)
203{
204 printk("Test cpl3: all perms ok\n");
205 {
206 test_insn(USER, &int3, TRAP(BP));
207 test_insn(USER, &int_0x3, TRAP(BP));
208 test_insn(USER, &icebp, TRAP(DB));
209 test_insn(USER, &int_0x1, TRAP(DB));
210 test_insn(USER, &into, COND(TRAP(OF), FAULT(UD)));
211 }
212
213 printk("Test cpl3: p=0\n");
214 {
216
217 test_insn(USER, &int3, FAULT_EC(NP, BP));
218 test_insn(USER, &int_0x3, FAULT_EC(NP, BP));
219 test_insn(USER, &icebp, FAULT_EC(NP, DB, EXT));
220 test_insn(USER, &int_0x1, FAULT_EC(NP, DB));
221 test_insn(USER, &into, COND(FAULT_EC(NP, OF), FAULT(UD)));
222
224 }
225
226 printk("Test cpl3: dpl=0\n");
227 {
229
230 test_insn(USER, &int3, FAULT_EC(GP, BP));
232 test_insn(USER, &icebp, TRAP(DB)); /* ICEBP doesn't check DPL. */
234 test_insn(USER, &into, COND(FAULT_EC(GP, OF), FAULT(UD)));
235
237 }
238}
239
241void cpl0_tests(void)
242{
243 printk("Test cpl0: all perms ok\n");
244 {
245 test_insn(KERN, &int3, TRAP(BP));
246 test_insn(KERN, &int_0x3, TRAP(BP));
247 test_insn(KERN, &icebp, TRAP(DB));
248 test_insn(KERN, &int_0x1, TRAP(DB));
249 test_insn(KERN, &into, COND(TRAP(OF), FAULT(UD)));
250 }
251
252 printk("Test cpl0: p=0\n");
253 {
255
256 test_insn(KERN, &int3, FAULT_EC(NP, BP));
257 test_insn(KERN, &int_0x3, FAULT_EC(NP, BP));
258 test_insn(KERN, &icebp, FAULT_EC(NP, DB, EXT));
259 test_insn(KERN, &int_0x1, FAULT_EC(NP, DB));
260 test_insn(KERN, &into, COND(FAULT_EC(NP, OF), FAULT(UD)));
261
263 }
264}
265
266void test_main(void)
267{
268 /*
269 * Even if FEP is unavailable, run the tests against real hardware to
270 * check the algorithm, but don't claim overall success.
271 */
272 if ( !xtf_has_fep )
273 xtf_skip("FEP support not detected - some tests will be skipped\n");
274
277
278 cpl0_tests();
279 cpl3_tests();
280
282}
283
284/*
285 * Local variables:
286 * mode: C
287 * c-file-style: "BSD"
288 * c-basic-offset: 4
289 * tab-width: 4
290 * indent-tabs-mode: nil
291 * End:
292 */
bool xtf_has_fep
Boolean indicating whether generic Force Emulation Prefix support is available for the test to use.
Definition: setup.c:276
void printk(const char *fmt,...)
Definition: console.c:134
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
#define EXINFO(vec, ec)
Definition: exinfo.h:26
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
#define ARRAY_SIZE(a)
Definition: lib.h:8
static unsigned long exec_user(unsigned long(*fn)(void))
Definition: lib.h:62
static void user(void)
Definition: main.c:43
Declarations of stubs and labels in generated in lowlevel.S.
unsigned long stub_user_into_FA(void)
unsigned long stub_into_F(void)
unsigned long stub_int_0x3_A(void)
unsigned long stub_into_A(void)
unsigned long stub_user_icebp(void)
unsigned long stub_int_0x1(void)
unsigned long stub_user_int_0x3_F(void)
unsigned long stub_user_int_0x1_F(void)
unsigned long stub_int3(void)
unsigned long stub_int_0x1_F(void)
unsigned long stub_user_int3_A(void)
unsigned long stub_int_0x3_FA(void)
unsigned long stub_user_int_0x3_A(void)
unsigned long stub_int_0x1_A(void)
unsigned long stub_icebp_A(void)
unsigned long stub_into(void)
unsigned long stub_user_int_0x1_A(void)
unsigned long stub_user_icebp_A(void)
unsigned long stub_user_int3_FA(void)
unsigned long stub_user_int_0x1_FA(void)
unsigned long stub_icebp(void)
unsigned long stub_int3_FA(void)
unsigned long stub_into_FA(void)
unsigned long stub_user_int3(void)
unsigned long stub_user_icebp_FA(void)
unsigned long stub_int_0x1_FA(void)
unsigned long stub_user_into_F(void)
unsigned long stub_icebp_F(void)
unsigned long stub_user_into(void)
unsigned long stub_int3_A(void)
unsigned long stub_user_int_0x3_FA(void)
unsigned long stub_int_0x3(void)
unsigned long stub_user_icebp_F(void)
unsigned long stub_icebp_FA(void)
unsigned long stub_int3_F(void)
unsigned long stub_user_int_0x1(void)
unsigned long stub_user_into_A(void)
unsigned long stub_int_0x3_F(void)
unsigned long stub_user_int_0x3(void)
unsigned long stub_user_int3_F(void)
#define GP
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define X86_EXC_OF
Definition: processor.h:106
#define X86_EXC_DB
Definition: processor.h:103
#define X86_EXC_BP
Definition: processor.h:105
mode
Definition: main.c:102
@ KERN
Definition: main.c:102
@ USER
Definition: main.c:102
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
void xtf_skip(const char *fmt,...)
Report a test skip.
Definition: report.c:66
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
#define NULL
Definition: stddef.h:12
Exception table entry.
Definition: extable.h:65
unsigned long fixup
Fixup address.
Definition: extable.h:67
Definition: main.c:93
unsigned long(* user_fn)(void)
Definition: main.c:96
unsigned long(* fn)(void)
Definition: main.c:95
const char * name
Definition: main.c:94
const struct insn int_0x3
Definition: main.c:94
static void set_idt_entries_dpl(unsigned int dpl)
Modify the descriptor privilege level on the IDT entries under test.
Definition: main.c:190
bool ex_record_trap_eax(struct cpu_regs *regs, const struct extable_entry *ex)
Definition: main.c:63
const struct insn icebp
Definition: main.c:110
#define EXINFO_TRAP
Definition: main.c:59
const struct insn into
Definition: main.c:142
const struct insn int3
Definition: main.c:78
#define FAULT_EC(V,...)
Definition: main.c:199
#define FAULT(V)
Definition: main.c:198
#define TRAP(V)
Definition: main.c:197
void cpl0_tests(void)
Tests run in supervisor mode.
Definition: main.c:241
static void set_idt_entries_present(bool present)
Modify the present flag on the IDT entries under test.
Definition: main.c:182
const struct insn int_0x1
Definition: main.c:126
void cpl3_tests(void)
Tests run in user mode.
Definition: main.c:202
#define COND(_32, _64)
Definition: main.c:56
void test_insn(enum mode user, const struct insn *insn, exinfo_t exp)
Definition: main.c:158