Xen Test Framework
desc.h
Go to the documentation of this file.
1 
7 #ifndef XTF_X86_DESC_H
8 #define XTF_X86_DESC_H
9 
10 #include <xtf/types.h>
11 #include <xtf/compiler.h>
12 
13 #include <arch/x86-gate.h>
14 #include <arch/x86-tss.h>
15 
16 #include <arch/segment.h>
17 
20  union {
22  struct {
23  uint32_t lo, hi;
24  };
25  struct {
29  union {
31  struct __packed {
32  unsigned int type:4;
33 
34  bool s:1;
35  unsigned int dpl:2;
36  bool p:1;
37 
38  unsigned int limit1:4;
39 
40  bool avl:1, :1, :1, g:1;
41  };
43  struct __packed {
44  bool a:1, r:1, c:1, x:1;
45  unsigned int :4, :4;
46  bool :1, l:1, d:1, :1;
47  };
49  struct __packed {
50  bool :1, w:1, e:1, :1;
51  unsigned int :4, :4;
52  bool :1, :1, b:1, :1;
53  };
54  };
56  };
57  /* Full width backing integer. */
59  };
60 };
61 
62 /* GDT/LDT attribute flags for user segments */
63 
64 /* Common */
65 #define SEG_ATTR_G 0x8000
66 #define SEG_ATTR_AVL 0x1000
67 #define SEG_ATTR_P 0x0080
68 #define SEG_ATTR_S 0x0010
69 #define SEG_ATTR_A 0x0001
71 #define SEG_ATTR_COMMON 0x8091
73 #define SEG_ATTR_DPL0 0x0000
74 #define SEG_ATTR_DPL1 0x0020
75 #define SEG_ATTR_DPL2 0x0040
76 #define SEG_ATTR_DPL3 0x0060
77 #define SEG_ATTR_CODE 0x0008
78 #define SEG_ATTR_DATA 0x0000
80 /* Code segments */
81 #define SEG_ATTR_D 0x4000
82 #define SEG_ATTR_L 0x2000
83 #define SEG_ATTR_C 0x0004
84 #define SEG_ATTR_R 0x0002
86 /* Data segments */
87 #define SEG_ATTR_B 0x4000
90 #define SEG_ATTR_E 0x0004
91 #define SEG_ATTR_W 0x0002
100 #define INIT_GDTE(base, limit, attr) { { { \
101  .lo = (((base) & 0xffff) << 16) | ((limit) & 0xffff), \
102  .hi = ((base) & 0xff000000) | ((limit) & 0xf0000) | \
103  (((attr) & 0xf0ff) << 8) | (((base) & 0xff0000) >> 16) \
104  } } }
105 
109 #define GDTE(base, limit, attr) ((user_desc)INIT_GDTE(base, limit, attr))
110 
112 struct __packed desc_ptr64 {
113  uint16_t limit;
114  uint64_t base;
115 };
126 struct __packed far_ptr64 {
127  union {
128  uint64_t offset_intel;
129  struct {
130  uint32_t :32;
131  uint32_t offset_amd;
132  };
133  };
134  uint16_t selector;
135 };
138 struct __packed desc_ptr32 {
139  uint16_t limit;
140  uint32_t base;
141 };
144 struct __packed far_ptr32 {
145  uint32_t offset;
146  uint16_t selector;
147 };
149 #if defined(__x86_64__)
150 
151 typedef struct desc_ptr64 desc_ptr;
152 typedef struct seg_desc32 user_desc;
153 typedef struct seg_gate64 gate_desc;
154 typedef struct far_ptr64 far_ptr;
155 
156 #elif defined(__i386__)
157 
158 typedef struct desc_ptr32 desc_ptr;
159 typedef struct seg_desc32 user_desc;
160 typedef struct seg_gate32 gate_desc;
161 typedef struct far_ptr32 far_ptr;
162 
163 #else
164 # error Bad architecture for descriptor infrastructure
165 #endif
166 
167 extern user_desc gdt[NR_GDT_ENTRIES];
168 extern desc_ptr gdt_ptr;
169 
170 #if defined(CONFIG_HVM)
171 extern env_gate idt[256];
172 extern desc_ptr idt_ptr;
173 
174 extern env_tss tss;
175 #endif
176 
177 static inline unsigned long user_desc_base(const user_desc *d)
178 {
179  unsigned long base = (d->base0 |
180  ((unsigned long)d->base1) << 16 |
181  ((unsigned long)d->base2) << 24 );
182 #ifdef __x86_64__
183  /* Long mode system segments use adjacent slot. */
184  if ( !d->s )
185  base |= ((unsigned long)d[1].lo) << 32;
186 #endif
187 
188  return base;
189 }
190 
191 static inline unsigned int user_desc_limit(const user_desc *d)
192 {
193  unsigned int limit = (d->limit0 |
194  ((unsigned int)d->limit1) << 16);
195  if ( d->g )
196  limit = limit << 12 | 0xfff;
197 
198  return limit;
199 }
200 
201 static inline void pack_tss_desc(user_desc *d, const env_tss *t)
202 {
203  unsigned long base = (unsigned long)t;
204 
205  d[0] = GDTE(base, sizeof(*t) - 1, 0x89);
206 #ifdef __x86_64__
207  d[1] = (user_desc){{{ .lo = base >> 32, .hi = 0 }}};
208 #endif
209  barrier(); /* Force desc update before ltr. */
210 }
211 
212 static inline void pack_ldt_desc(user_desc *d, const user_desc *ldt,
213  unsigned int limit)
214 {
215  unsigned long base = (unsigned long)ldt;
216 
217  d[0] = GDTE(base, limit, 0x82);
218 #ifdef __x86_64__
219  d[1] = (user_desc){{{ .lo = base >> 32, .hi = 0 }}};
220 #endif
221  barrier(); /* Force desc update before lldt. */
222 }
223 
224 #endif /* XTF_X86_DESC_H */
225 
226 /*
227  * Local variables:
228  * mode: C
229  * c-file-style: "BSD"
230  * c-basic-offset: 4
231  * tab-width: 4
232  * indent-tabs-mode: nil
233  * End:
234  */
uint16_t limit0
Definition: desc.h:26
bool x
Definition: desc.h:44
Common declarations for all tests.
8 byte user segment descriptor (GDT/LDT entries with .s = 1)
Definition: desc.h:19
bool s
Definition: desc.h:34
static void pack_ldt_desc(user_desc *d, const user_desc *ldt, unsigned int limit)
Definition: desc.h:214
#define barrier()
Definition: compiler.h:30
uint8_t base1
Definition: desc.h:28
Protected mode lgdt/lidt table pointer.
Definition: desc.h:140
uint64_t raw
Definition: desc.h:58
x86 Gate Descriptor infrastructure.
static unsigned long user_desc_base(const user_desc *d)
Definition: desc.h:179
bool p
Definition: desc.h:36
unsigned int type
Definition: desc.h:32
desc_ptr gdt_ptr
_Bool bool
Definition: stdbool.h:9
bool g
Definition: desc.h:40
user_desc gdt[NR_GDT_ENTRIES]
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
x86 Task State Segment infrastructure.
unsigned l
Definition: desc.h:45
unsigned int limit1
Definition: desc.h:38
#define GDTE(base, limit, attr)
As INIT_GDTE(), but creates a user_desc object.
Definition: desc.h:111
env_tss tss
Definition: traps.c:35
__UINT32_TYPE__ uint32_t
Definition: stdint.h:16
static unsigned int user_desc_limit(const user_desc *d)
Definition: desc.h:193
#define __packed
Definition: compiler.h:11
Protected mode lcall/ljmp memory operand.
Definition: desc.h:146
Long mode lgdt/lidt table pointer.
Definition: desc.h:114
uint8_t base2
Definition: desc.h:55
uint32_t lo
Definition: desc.h:23
unsigned int dpl
Definition: desc.h:35
__UINT16_TYPE__ uint16_t
Definition: stdint.h:15
static void pack_tss_desc(user_desc *d, const env_tss *t)
Definition: desc.h:203
bool w
Definition: desc.h:50
uint16_t base0
Definition: desc.h:27
__UINT8_TYPE__ uint8_t
Definition: stdint.h:14
#define NR_GDT_ENTRIES
Definition: segment.h:44
Long mode lcall/ljmp memory operand.
Definition: desc.h:128