Xen Test Framework
traps.c
Go to the documentation of this file.
1#include <xtf/traps.h>
2#include <xtf/lib.h>
3
4#include <arch/idt.h>
5#include <arch/lib.h>
6#include <arch/mm.h>
7#include <arch/processor.h>
8#include <arch/desc.h>
9
10/* Filled in by hvm/head.S if started via the PVH entrypoint. */
12
13/* Real entry points */
14void entry_DE(void);
15void entry_DB(void);
16void entry_NMI(void);
17void entry_BP(void);
18void entry_OF(void);
19void entry_BR(void);
20void entry_UD(void);
21void entry_NM(void);
22void entry_DF(void);
23void entry_TS(void);
24void entry_NP(void);
25void entry_SS(void);
26void entry_GP(void);
27void entry_PF(void);
28void entry_MF(void);
29void entry_AC(void);
30void entry_MC(void);
31void entry_XM(void);
32void entry_VE(void);
34
35env_tss tss __aligned(16) = /* lgtm [cpp/short-global-name] */
36{
37#if defined(__i386__)
38
39 .esp0 = _u(&boot_stack[2 * PAGE_SIZE]),
40 .ss0 = __KERN_DS,
41
42 .cr3 = _u(cr3_target),
43
44#elif defined(__x86_64__)
45
46 .rsp0 = _u(&boot_stack[2 * PAGE_SIZE]),
47 .ist[0] = _u(&boot_stack[3 * PAGE_SIZE]),
48
49#endif
50
52};
53
54static env_tss tss_DF __aligned(16) =
55{
56#if defined(__i386__)
57 .esp = _u(&boot_stack[3 * PAGE_SIZE]),
58 .ss = __KERN_DS,
59 .ds = __KERN_DS,
60 .es = __KERN_DS,
61 .fs = __KERN_DS,
62 .gs = __KERN_DS,
63
64 .eip = _u(entry_DF),
65 .cs = __KERN_CS,
66
67 .cr3 = _u(cr3_target),
68#endif
69
71};
72
73int xtf_set_idte(unsigned int vector, const struct xtf_idte *idte)
74{
75 pack_intr_gate(&idt[vector], idte->cs, idte->addr, idte->dpl, 0);
76
77 return 0;
78}
79
80static void remap_user(unsigned int start_gfn, unsigned int end_gfn)
81{
82 while ( start_gfn < end_gfn )
83 l1_identmap[start_gfn++] |= _PAGE_USER;
84}
85
87{
88 pack_intr_gate(&idt[X86_EXC_DE], __KERN_CS, _u(&entry_DE), 0, 0);
89 pack_intr_gate(&idt[X86_EXC_DB], __KERN_CS, _u(&entry_DB), 0, 0);
90 pack_intr_gate(&idt[X86_EXC_NMI], __KERN_CS, _u(&entry_NMI), 0, 0);
91 pack_intr_gate(&idt[X86_EXC_BP], __KERN_CS, _u(&entry_BP), 3, 0);
92 pack_intr_gate(&idt[X86_EXC_OF], __KERN_CS, _u(&entry_OF), 3, 0);
93 pack_intr_gate(&idt[X86_EXC_BR], __KERN_CS, _u(&entry_BR), 0, 0);
94 pack_intr_gate(&idt[X86_EXC_UD], __KERN_CS, _u(&entry_UD), 0, 0);
95 pack_intr_gate(&idt[X86_EXC_NM], __KERN_CS, _u(&entry_NM), 0, 0);
96 pack_intr_gate(&idt[X86_EXC_TS], __KERN_CS, _u(&entry_TS), 0, 0);
97 pack_intr_gate(&idt[X86_EXC_NP], __KERN_CS, _u(&entry_NP), 0, 0);
98 pack_intr_gate(&idt[X86_EXC_SS], __KERN_CS, _u(&entry_SS), 0, 0);
99 pack_intr_gate(&idt[X86_EXC_GP], __KERN_CS, _u(&entry_GP), 0, 0);
100 pack_intr_gate(&idt[X86_EXC_PF], __KERN_CS, _u(&entry_PF), 0, 0);
101 pack_intr_gate(&idt[X86_EXC_MF], __KERN_CS, _u(&entry_MF), 0, 0);
102 pack_intr_gate(&idt[X86_EXC_AC], __KERN_CS, _u(&entry_AC), 0, 0);
103 pack_intr_gate(&idt[X86_EXC_MC], __KERN_CS, _u(&entry_MC), 0, 0);
104 pack_intr_gate(&idt[X86_EXC_XM], __KERN_CS, _u(&entry_XM), 0, 0);
105 pack_intr_gate(&idt[X86_EXC_VE], __KERN_CS, _u(&entry_VE), 0, 0);
106
107 /* Handle #DF with a task gate in 32bit, and IST 1 in 64bit. */
108 if ( IS_DEFINED(CONFIG_32BIT) )
109 {
112 }
113 else
114 pack_intr_gate(&idt[X86_EXC_DF], __KERN_CS, _u(&entry_DF), 0, 1);
115
117 __KERN_CS, _u(&entry_ret_to_kernel), 3, 0);
118
119 lidt(&idt_ptr);
120
122 ltr(GDTE_TSS * 8);
123
124 /*
125 * Remap the structures which specifically want to be user. No need for a
126 * TLB flush as this is a strict relaxing of permissions.
127 */
128 extern const char __start_user_text[], __end_user_text[];
129 extern const char __start_user_data[], __end_user_data[];
130 extern const char __start_user_bss[], __end_user_bss[];
131
132 remap_user(virt_to_gfn(__start_user_text),
133 virt_to_gfn(__end_user_text));
134
135 remap_user(virt_to_gfn(__start_user_data),
136 virt_to_gfn(__end_user_data));
137
138 remap_user(virt_to_gfn(__start_user_bss),
139 virt_to_gfn(__end_user_bss));
140}
141
143{
144 /*
145 * Clear interrupts and halt. Xen should catch this condition and shut
146 * the VM down. If that fails, sit in a loop.
147 */
148 asm volatile("cli;"
149 "1: hlt;"
150 "pause;"
151 "jmp 1b"
152 ::: "memory");
153 unreachable();
154}
155
156/*
157 * Local variables:
158 * mode: C
159 * c-file-style: "BSD"
160 * c-basic-offset: 4
161 * tab-width: 4
162 * indent-tabs-mode: nil
163 * End:
164 */
static void lidt(const desc_ptr *idtr)
Definition: lib.h:332
static void ltr(unsigned int sel)
Definition: lib.h:342
uint8_t boot_stack[3 *PAGE_SIZE]
Definition: setup.c:21
#define __noreturn
Definition: compiler.h:10
#define __aligned(x)
Definition: compiler.h:9
#define unreachable()
Definition: compiler.h:29
x86 segment descriptor infrastructure.
static void pack_tss_desc(user_desc *d, const env_tss *t)
Definition: desc.h:201
user_desc gdt[NR_GDT_ENTRIES]
void entry_MF(void)
void entry_DE(void)
static void remap_user(unsigned int start_gfn, unsigned int end_gfn)
Definition: traps.c:80
void entry_DB(void)
env_tss tss
Definition: traps.c:35
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)
static env_tss tss_DF
Definition: traps.c:54
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)
xen_pvh_start_info_t * pvh_start_info
Definition: traps.c:11
void entry_TS(void)
void entry_NP(void)
void entry_XM(void)
void entry_NM(void)
void entry_VE(void)
x86 IDT vector infrastructure.
#define X86_VEC_RET2KERN
Return to kernel mode.
Definition: idt.h:15
#define IS_DEFINED(x)
Evalute whether the CONFIG_ token x is defined.
Definition: macro_magic.h:67
static unsigned long virt_to_gfn(const void *va)
Definition: mm.h:100
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define PAGE_SIZE
Definition: page.h:11
#define _PAGE_USER
Definition: page.h:27
#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
#define GDTE_TSS_DF
Definition: segment.h:35
#define GDTE_TSS
Definition: segment.h:34
static const struct xtf_idte idte
Definition: main.c:170
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
static void pack_task_gate(env_gate *g, unsigned int selector)
Definition: x86-gate.h:105
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
#define X86_TSS_INVALID_IO_BITMAP
Definition: x86-tss.h:66