Xen Test Framework
main.c
Go to the documentation of this file.
1 
18 #include <xtf.h>
19 
20 const char test_title[] = "Test Long Mode #TS";
21 
22 #ifdef __i386__
23 # define COND(_32, _64) _32
24 #else
25 # define COND(_32, _64) _64
26 #endif
27 
28 static bool check_ts(struct cpu_regs *regs, const struct extable_entry *ex)
29 {
30  exinfo_t got = EXINFO(regs->entry_vector, regs->error_code);
31  exinfo_t exp = EXINFO_SYM(TS, SEL_EC_SYM(TSS_SEL, GDT));
32 
33  if ( got == exp )
34  {
35  printk(" Got %pe as expected\n", _p(got));
36  regs->ip = ex->fixup;
37  return true;
38  }
39 
40  return false;
41 }
42 
43 static void __user_text user(void)
44 {
45  asm volatile ("1: int $"STR(X86_VEC_AVAIL)";"
46  "2:"
47  _ASM_EXTABLE_HANDLER(1b, 2b, %P[check])
48  :
49  : [check] "p" (check_ts)
50  : "memory");
51 }
52 
53 void test_main(void)
54 {
55  /*
56  * Edit the TSS descriptor in place. Reset Busy to Available, and reduce
57  * limit to exclude the Ring1 stack.
58  */
59  gdt[GDTE_TSS].type = 0x9;
60  gdt[GDTE_TSS].limit0 = offsetof(env_tss, COND(esp1, rsp1)) - 1;
61 
62  /* Reload %tr */
63  ltr(TSS_SEL);
64 
65 #ifdef __i386__
66  tss.ss1 = __KERN_CS;
67 #endif
68 
69  /* Ring1 code segment. */
70  gdt[GDTE_AVAIL0] = GDTE_SYM(0, 0xfffff, COMMON, DPL1, CODE, COND(D, L));
71 
72  /*
73  * DPL3 RPL1 gate to allow userspace to invoke Ring 1. It will fault as
74  * %tr->{e,r}sp1 can't be accessed.
75  */
76  pack_intr_gate(&idt[X86_VEC_AVAIL], (GDTE_AVAIL0 * 8) | 1, 0, 3, 0);
77 
79 
81 }
82 
83 /*
84  * Local variables:
85  * mode: C
86  * c-file-style: "BSD"
87  * c-basic-offset: 4
88  * tab-width: 4
89  * indent-tabs-mode: nil
90  * End:
91  */
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
static void pack_intr_gate(env_gate *g, unsigned int sel, unsigned long offset, unsigned int dpl, unsigned int other)
Definition: x86-gate.h:117
unsigned long fixup
Fixup address.
Definition: extable.h:67
#define EXINFO(vec, ec)
Definition: exinfo.h:26
void printk(const char *fmt,...)
Definition: console.c:134
#define STR(x)
Stringise an expression, expanding preprocessor tokens.
Definition: macro_magic.h:17
#define SEL_EC_SYM(sel,...)
Create a selector based error code using X86_EC_ mnemonics.
static void user(void)
Definition: main.c:43
#define __user_text
Definition: compiler.h:33
#define offsetof(t, m)
Definition: stddef.h:14
#define NULL
Definition: stddef.h:12
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
static void exec_user_void(void(*fn)(void))
Definition: lib.h:70
static void ltr(unsigned int sel)
Definition: lib.h:342
user_desc gdt[NR_GDT_ENTRIES]
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:137
Exception table entry.
Definition: extable.h:64
env_tss tss
Definition: traps.c:35
const char test_title[]
The title of the test.
Definition: main.c:14
#define GDTE_AVAIL0
Definition: segment.h:37
#define X86_VEC_AVAIL
Available for test use.
Definition: idt.h:20
#define COND(_32, _64)
Definition: main.c:25
void check(const char *func, exinfo_t got, exinfo_t exp)
Compare an expectation against what really happenend, printing human-readable information in case of ...
Definition: util.c:37
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define EXINFO_SYM(exc, ec)
Definition: exinfo.h:29
static bool check_ts(struct cpu_regs *regs, const struct extable_entry *ex)
Definition: main.c:28
#define GDTE_TSS
Definition: segment.h:34
#define GDTE_SYM(base, limit,...)
As INIT_GDTE_SYM(), but creates a user_desc object.
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38