Xen Test Framework
traps.c
Go to the documentation of this file.
1#include <xtf/traps.h>
2#include <xtf/lib.h>
3#include <xtf/hypercall.h>
4#include <xtf/test.h>
5
6#include <arch/idt.h>
7#include <arch/lib.h>
8#include <arch/processor.h>
9#include <arch/segment.h>
10#include <arch/pagetable.h>
11#include <arch/symbolic-const.h>
12
13/* Filled in by pv/head.S */
15
16/* Real entry points */
17void entry_DE(void);
18void entry_DB(void);
19void entry_NMI(void);
20void entry_BP(void);
21void entry_OF(void);
22void entry_BR(void);
23void entry_UD(void);
24void entry_NM(void);
25void entry_DF(void);
26void entry_TS(void);
27void entry_NP(void);
28void entry_SS(void);
29void entry_GP(void);
30void entry_PF(void);
31void entry_MF(void);
32void entry_AC(void);
33void entry_MC(void);
34void entry_XM(void);
35void entry_VE(void);
37
38void entry_SYSCALL(void);
39void entry_SYSENTER(void);
40void entry_EVTCHN(void);
41
43{
44 { X86_EXC_DE, 0|4, __KERN_CS, _u(entry_DE) },
45 { X86_EXC_DB, 0|4, __KERN_CS, _u(entry_DB) },
46 { X86_EXC_NMI, 0|4, __KERN_CS, _u(entry_NMI) },
47 { X86_EXC_BP, 3|4, __KERN_CS, _u(entry_BP) },
48 { X86_EXC_OF, 3|4, __KERN_CS, _u(entry_OF) },
49 { X86_EXC_BR, 0|4, __KERN_CS, _u(entry_BR) },
50 { X86_EXC_UD, 0|4, __KERN_CS, _u(entry_UD) },
51 { X86_EXC_NM, 0|4, __KERN_CS, _u(entry_NM) },
52 { X86_EXC_DF, 0|4, __KERN_CS, _u(entry_DF) },
53 { X86_EXC_TS, 0|4, __KERN_CS, _u(entry_TS) },
54 { X86_EXC_NP, 0|4, __KERN_CS, _u(entry_NP) },
55 { X86_EXC_SS, 0|4, __KERN_CS, _u(entry_SS) },
56 { X86_EXC_GP, 0|4, __KERN_CS, _u(entry_GP) },
57 { X86_EXC_PF, 0|4, __KERN_CS, _u(entry_PF) },
58 { X86_EXC_MF, 0|4, __KERN_CS, _u(entry_MF) },
59 { X86_EXC_AC, 0|4, __KERN_CS, _u(entry_AC) },
60 { X86_EXC_MC, 0|4, __KERN_CS, _u(entry_MC) },
61 { X86_EXC_XM, 0|4, __KERN_CS, _u(entry_XM) },
62 { X86_EXC_VE, 0|4, __KERN_CS, _u(entry_VE) },
63
64 { X86_VEC_RET2KERN, 3|4, __KERN_CS, _u(entry_ret_to_kernel) },
65
66 { 0, 0, 0, 0 }, /* Sentinel. */
67};
68
69int xtf_set_idte(unsigned int vector, const struct xtf_idte *idte)
70{
71 struct xen_trap_info ti[2] =
72 {
73 { vector, idte->dpl | 4, idte->cs, idte->addr },
74 { 0, 0, 0, 0 }, /* Sentinel. */
75 };
76
77 return hypercall_set_trap_table(ti);
78}
79
80static int remap_linear(const void *linear, uint64_t flags)
81{
82 intpte_t nl1e = pte_from_virt(linear, flags);
83
84 return hypercall_update_va_mapping(_u(linear), nl1e, UVMF_INVLPG);
85}
86
87static int __maybe_unused remap_linear_range(const void *start, const void *end,
89{
90 int ret = 0;
91
92 while ( !ret && start < end )
93 {
94 ret = remap_linear(start, flags);
95 start += PAGE_SIZE;
96 }
97
98 return ret;
99}
100
101static void init_callbacks(void)
102{
103 /* PV equivalent of `lidt`. */
105
106 if ( rc )
107 panic("Failed to set trap table: %d\n", rc);
108
110 {
112 .address = INIT_XEN_CALLBACK(__KERN_CS, _u(entry_EVTCHN)),
113 },
114#ifdef __x86_64__
115 {
116 .type = CALLBACKTYPE_syscall,
117 .flags = CALLBACKF_mask_events,
118 .address = INIT_XEN_CALLBACK(__KERN_CS, _u(entry_SYSCALL)),
119 },
120#endif
121 {
123 .flags = CALLBACKF_mask_events,
124 .address = INIT_XEN_CALLBACK(__KERN_CS, _u(entry_SYSCALL)),
125 },
126 {
127 .type = CALLBACKTYPE_sysenter,
128 .flags = CALLBACKF_mask_events,
129 .address = INIT_XEN_CALLBACK(__KERN_CS, _u(entry_SYSENTER)),
130 },
131 };
132
133 for ( unsigned int i = 0; i < ARRAY_SIZE(cb); ++i )
134 {
135 rc = hypercall_register_callback(&cb[i]);
136 if ( rc )
137 panic("Failed to register callback[%u]: %d\n", i, rc);
138 }
139}
140
142{
143 int rc;
144
146
147 /* Register gdt[] with Xen. Need to map it read-only first. */
148 if ( remap_linear(gdt, PF_SYM(AD, P)) )
149 panic("Unable to remap gdt[] as read-only\n");
150
151 unsigned long gdt_frames[] = {
153 };
154 BUILD_BUG_ON(NR_GDT_ENTRIES > (PAGE_SIZE / sizeof(user_desc)));
155
156 rc = hypercall_set_gdt(gdt_frames, NR_GDT_ENTRIES);
157 if ( rc )
158 panic("Failed to set gdt: %d\n", rc);
159
160 /* PV equivalent of setting tss.{esp0,ss0}. */
161 rc = hypercall_stack_switch(__KERN_DS, &boot_stack[2 * PAGE_SIZE]);
162 if ( rc )
163 panic("Failed to set kernel stack: %d\n", rc);
164
165 write_ds(__USER_DS);
166 write_es(__USER_DS);
167 write_fs(__USER_DS);
168 write_gs(__USER_DS);
169
170#ifdef __x86_64__
171 /*
172 * Set the user pagetables (only applicable to 64bit PV).
173 *
174 * XTF uses a shared user/kernel address space, so register the kernel
175 * %cr3 as the user %cr3.
176 */
177 mmuext_op_t ext =
178 {
180 .arg1.mfn = read_cr3() >> PAGE_SHIFT,
181 };
182
183 rc = hypercall_mmuext_op(&ext, 1, NULL, DOMID_SELF);
184 if ( rc )
185 panic("Failed to set user %%cr3: %d\n", rc);
186
187#elif defined(__i386__)
188 /* Remap the structures which specifically want to be user. */
189 extern const char __start_user_text[], __end_user_text[];
190 extern const char __start_user_data[], __end_user_data[];
191 extern const char __start_user_bss[], __end_user_bss[];
192
193 remap_linear_range(__start_user_text, __end_user_text,
194 PF_SYM(AD, U, RW, P));
195
196 remap_linear_range(__start_user_data, __end_user_data,
197 PF_SYM(AD, U, RW, P));
198
199 remap_linear_range(__start_user_bss, __end_user_bss,
200 PF_SYM(AD, U, RW, P));
201#endif
202
203 /* Unmap page at 0 to catch errors with NULL pointers. */
205 if ( rc )
206 panic("Failed to unmap page at NULL: %d\n", rc);
207}
208
210{
211 /*
212 * For both architectures, put the stack pointer into an invalid place and
213 * attempt to use it. Xen should fail to create a bounce frame and crash
214 * the domain.
215 */
216 asm volatile(
217 "mov %0, %%" _ASM_SP ";"
218 "pushf"
219 ::
220#ifdef __i386__
221 "i" (0xfbadc0deUL) /* 32bit: In the read-only M2P mapping. */
222#else
223 "i" (0x800000000badc0deUL) /* 64bit: Non-canonical region. */
224#endif
225 : "memory" );
226
227 /*
228 * Attempt to crash failed. Give up and sit in a loop.
229 */
230 asm volatile("1: hlt;"
231 "pause;"
232 "jmp 1b"
233 ::: "memory");
234 unreachable();
235}
236
237/*
238 * Local variables:
239 * mode: C
240 * c-file-style: "BSD"
241 * c-basic-offset: 4
242 * tab-width: 4
243 * indent-tabs-mode: nil
244 * End:
245 */
#define _ASM_SP
Definition: asm_macros.h:37
static void write_ds(unsigned int ds)
Definition: lib.h:186
static unsigned long read_cr3(void)
Definition: lib.h:243
static void write_fs(unsigned int fs)
Definition: lib.h:196
static void write_es(unsigned int es)
Definition: lib.h:191
static void write_gs(unsigned int gs)
Definition: lib.h:201
uint8_t boot_stack[3 *PAGE_SIZE]
Definition: setup.c:21
#define CALLBACKTYPE_syscall32
Definition: callback.h:49
#define CALLBACKF_mask_events
Definition: callback.h:56
#define CALLBACKTYPE_sysenter
Definition: callback.h:43
#define CALLBACKTYPE_event
Definition: callback.h:18
#define CALLBACKTYPE_syscall
Definition: callback.h:24
#define __noreturn
Definition: compiler.h:10
#define unreachable()
Definition: compiler.h:29
#define __maybe_unused
Definition: compiler.h:13
user_desc gdt[NR_GDT_ENTRIES]
void entry_MF(void)
void entry_DE(void)
void entry_DB(void)
void entry_MC(void)
void entry_ret_to_kernel(void)
void entry_GP(void)
void entry_UD(void)
void arch_init_traps(void)
Definition: traps.c:86
void entry_AC(void)
void arch_crash_hard(void)
Definition: traps.c:142
void entry_DF(void)
void entry_BR(void)
void entry_SS(void)
void entry_NMI(void)
int xtf_set_idte(unsigned int vector, const struct xtf_idte *idte)
Set up an IDT Entry, in a guest agnostic way.
Definition: traps.c:73
void entry_BP(void)
void entry_PF(void)
void entry_OF(void)
void entry_TS(void)
void entry_NP(void)
void entry_XM(void)
void entry_NM(void)
void entry_VE(void)
static long hypercall_mmuext_op(const mmuext_op_t ops[], unsigned int count, unsigned int *done, unsigned int foreigndom)
Definition: hypercall.h:148
static long hypercall_stack_switch(const unsigned int ss, const void *sp)
Definition: hypercall.h:75
static long hypercall_set_gdt(const unsigned long *mfns, unsigned int entries)
Definition: hypercall.h:69
static int hypercall_register_callback(const xen_callback_register_t *arg)
Definition: hypercall.h:218
static long hypercall_update_va_mapping(unsigned long linear, uint64_t npte, enum XEN_UVMF flags)
Definition: hypercall.h:115
static long hypercall_set_trap_table(const struct xen_trap_info *ti)
Definition: hypercall.h:55
x86 IDT vector infrastructure.
#define X86_VEC_RET2KERN
Return to kernel mode.
Definition: idt.h:15
#define ARRAY_SIZE(a)
Definition: lib.h:8
#define BUILD_BUG_ON(cond)
Definition: lib.h:24
API for tests.
void panic(const char *fmt,...)
Definition: lib.c:15
unsigned long virt_to_mfn(const void *va)
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define PAGE_SIZE
Definition: page.h:11
#define PAGE_SHIFT
Definition: page.h:10
unsigned long intpte_t
Definition: page.h:152
intpte_t pte_from_virt(const void *va, uint64_t flags)
#define X86_EXC_NP
Definition: processor.h:113
#define X86_EXC_PF
Definition: processor.h:116
#define X86_EXC_VE
Definition: processor.h:122
#define X86_EXC_AC
Definition: processor.h:119
#define X86_EXC_OF
Definition: processor.h:106
#define X86_EXC_MC
Definition: processor.h:120
#define X86_EXC_XM
Definition: processor.h:121
#define X86_EXC_DE
Definition: processor.h:102
#define X86_EXC_NMI
Definition: processor.h:104
#define X86_EXC_NM
Definition: processor.h:109
#define X86_EXC_MF
Definition: processor.h:118
#define X86_EXC_DF
Definition: processor.h:110
#define X86_EXC_DB
Definition: processor.h:103
#define X86_EXC_BR
Definition: processor.h:107
#define X86_EXC_GP
Definition: processor.h:115
#define X86_EXC_UD
Definition: processor.h:108
#define X86_EXC_BP
Definition: processor.h:105
#define X86_EXC_SS
Definition: processor.h:114
#define X86_EXC_TS
Definition: processor.h:112
struct xen_trap_info pv_default_trap_info[]
Definition: traps.c:42
static int remap_linear_range(const void *start, const void *end, uint64_t flags)
Definition: traps.c:87
static int remap_linear(const void *linear, uint64_t flags)
Definition: traps.c:80
void entry_SYSCALL(void)
void entry_EVTCHN(void)
void entry_SYSENTER(void)
static void init_callbacks(void)
Definition: traps.c:101
xen_pv_start_info_t * pv_start_info
Definition: traps.c:14
#define NR_GDT_ENTRIES
Definition: segment.h:44
static const struct xtf_idte idte
Definition: main.c:170
#define NULL
Definition: stddef.h:12
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
Definition: xen.h:355
unsigned int cmd
Definition: xen.h:356
uint8_t flags
Definition: xen.h:34
uint8_t vector
Definition: xen.h:33
A guest agnostic represention of IDT information.
Definition: idt.h:27
unsigned int dpl
Definition: idt.h:29
unsigned int cs
Definition: idt.h:29
unsigned long addr
Definition: idt.h:28
Macros for creating constants using mnemonics.
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
#define INIT_XEN_CALLBACK(_cs, _ip)
Definition: xen-x86_32.h:88
#define DOMID_SELF
Definition: xen.h:70
@ UVMF_INVLPG
Definition: xen.h:383
#define MMUEXT_NEW_USER_BASEPTR
Definition: xen.h:347