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 */
14 void entry_DE(void);
15 void entry_DB(void);
16 void entry_NMI(void);
17 void entry_BP(void);
18 void entry_OF(void);
19 void entry_BR(void);
20 void entry_UD(void);
21 void entry_NM(void);
22 void entry_DF(void);
23 void entry_TS(void);
24 void entry_NP(void);
25 void entry_SS(void);
26 void entry_GP(void);
27 void entry_PF(void);
28 void entry_MF(void);
29 void entry_AC(void);
30 void entry_MC(void);
31 void entry_XM(void);
32 void entry_VE(void);
33 void entry_ret_to_kernel(void);
34 
35 env_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 
54 static 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 
73 int 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 
80 static 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 
86 void arch_init_traps(void)
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  {
111  pack_task_gate(&idt[X86_EXC_DF], GDTE_TSS_DF * 8);
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  */
void entry_NP(void)
xen_pvh_start_info_t * pvh_start_info
Definition: traps.c:11
void entry_OF(void)
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
void entry_BR(void)
#define IS_DEFINED(x)
Evalute whether the CONFIG_ token x is defined.
Definition: macro_magic.h:67
void arch_crash_hard(void)
Definition: traps.c:142
#define __noreturn
Definition: compiler.h:10
static void lidt(const desc_ptr *idtr)
Definition: lib.h:332
void entry_AC(void)
#define GDTE_TSS_DF
Definition: segment.h:35
unsigned long addr
Definition: idt.h:28
void entry_PF(void)
#define X86_EXC_DF
Definition: processor.h:110
x86 segment descriptor infrastructure.
#define X86_EXC_MF
Definition: processor.h:118
void entry_ret_to_kernel(void)
#define X86_EXC_OF
Definition: processor.h:106
void entry_GP(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
x86 IDT vector infrastructure.
#define X86_EXC_MC
Definition: processor.h:120
#define X86_EXC_GP
Definition: processor.h:115
static env_tss tss_DF
Definition: traps.c:54
#define X86_EXC_NM
Definition: processor.h:109
void entry_UD(void)
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
void entry_DB(void)
#define X86_EXC_BP
Definition: processor.h:105
#define X86_EXC_DE
Definition: processor.h:102
void entry_MF(void)
#define X86_EXC_XM
Definition: processor.h:121
unsigned int cs
Definition: idt.h:29
void entry_TS(void)
#define X86_TSS_INVALID_IO_BITMAP
Definition: x86-tss.h:66
void entry_MC(void)
void entry_NMI(void)
static void remap_user(unsigned int start_gfn, unsigned int end_gfn)
Definition: traps.c:80
void entry_DE(void)
static void ltr(unsigned int sel)
Definition: lib.h:342
void arch_init_traps(void)
Definition: traps.c:86
void entry_VE(void)
user_desc gdt[NR_GDT_ENTRIES]
static unsigned long virt_to_gfn(const void *va)
Definition: mm.h:100
void entry_BP(void)
#define X86_EXC_NP
Definition: processor.h:113
env_tss tss
Definition: traps.c:35
static const struct xtf_idte idte
Definition: main.c:164
unsigned int dpl
Definition: idt.h:29
#define X86_EXC_UD
Definition: processor.h:108
#define X86_EXC_VE
Definition: processor.h:122
void entry_XM(void)
#define X86_EXC_AC
Definition: processor.h:119
#define unreachable()
Definition: compiler.h:29
uint8_t boot_stack[3 *PAGE_SIZE]
Definition: setup.c:21
#define X86_EXC_DB
Definition: processor.h:103
#define X86_EXC_BR
Definition: processor.h:107
#define PAGE_SIZE
Definition: page.h:11
#define _PAGE_USER
Definition: page.h:27
#define X86_VEC_RET2KERN
Return to kernel mode.
Definition: idt.h:15
A guest agnostic represention of IDT information.
Definition: idt.h:26
#define X86_EXC_NMI
Definition: processor.h:104
#define X86_EXC_SS
Definition: processor.h:114
void entry_NM(void)
#define X86_EXC_TS
Definition: processor.h:112
#define GDTE_TSS
Definition: segment.h:34
static void pack_tss_desc(user_desc *d, const env_tss *t)
Definition: desc.h:203
#define X86_EXC_PF
Definition: processor.h:116
static void pack_task_gate(env_gate *g, unsigned int selector)
Definition: x86-gate.h:105
#define __aligned(x)
Definition: compiler.h:9
void entry_DF(void)
void entry_SS(void)