4
4
#include <asm/desc_defs.h>
7
8
#include <linux/smp.h>
8
9
#include <linux/mm_types.h>
10
static inline void fill_ldt(struct desc_struct *desc,
11
const struct user_desc *info)
11
static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info)
13
desc->limit0 = info->limit & 0x0ffff;
14
desc->base0 = info->base_addr & 0x0000ffff;
16
desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
17
desc->type = (info->read_exec_only ^ 1) << 1;
18
desc->type |= info->contents << 2;
21
desc->p = info->seg_not_present ^ 1;
22
desc->limit = (info->limit & 0xf0000) >> 16;
23
desc->avl = info->useable;
24
desc->d = info->seg_32bit;
25
desc->g = info->limit_in_pages;
26
desc->base2 = (info->base_addr & 0xff000000) >> 24;
13
desc->limit0 = info->limit & 0x0ffff;
15
desc->base0 = (info->base_addr & 0x0000ffff);
16
desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
18
desc->type = (info->read_exec_only ^ 1) << 1;
19
desc->type |= info->contents << 2;
23
desc->p = info->seg_not_present ^ 1;
24
desc->limit = (info->limit & 0xf0000) >> 16;
25
desc->avl = info->useable;
26
desc->d = info->seg_32bit;
27
desc->g = info->limit_in_pages;
29
desc->base2 = (info->base_addr & 0xff000000) >> 24;
28
31
* Don't allow setting of the lm bit. It is useless anyway
29
32
* because 64bit system calls require __USER_CS:
34
37
extern struct desc_ptr idt_descr;
49
53
static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
50
54
unsigned dpl, unsigned ist, unsigned seg)
52
gate->offset_low = PTR_LOW(func);
53
gate->segment = __KERNEL_CS;
60
gate->offset_middle = PTR_MIDDLE(func);
61
gate->offset_high = PTR_HIGH(func);
56
gate->offset_low = PTR_LOW(func);
57
gate->segment = __KERNEL_CS;
64
gate->offset_middle = PTR_MIDDLE(func);
65
gate->offset_high = PTR_HIGH(func);
76
79
static inline int desc_empty(const void *ptr)
78
81
const u32 *desc = ptr;
79
83
return !(desc[0] | desc[1]);
82
86
#ifdef CONFIG_PARAVIRT
83
87
#include <asm/paravirt.h>
85
#define load_TR_desc() native_load_tr_desc()
86
#define load_gdt(dtr) native_load_gdt(dtr)
87
#define load_idt(dtr) native_load_idt(dtr)
88
#define load_tr(tr) asm volatile("ltr %0"::"m" (tr))
89
#define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt))
91
#define store_gdt(dtr) native_store_gdt(dtr)
92
#define store_idt(dtr) native_store_idt(dtr)
93
#define store_tr(tr) (tr = native_store_tr())
95
#define load_TLS(t, cpu) native_load_tls(t, cpu)
96
#define set_ldt native_set_ldt
89
#define load_TR_desc() native_load_tr_desc()
90
#define load_gdt(dtr) native_load_gdt(dtr)
91
#define load_idt(dtr) native_load_idt(dtr)
92
#define load_tr(tr) asm volatile("ltr %0"::"m" (tr))
93
#define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt))
95
#define store_gdt(dtr) native_store_gdt(dtr)
96
#define store_idt(dtr) native_store_idt(dtr)
97
#define store_tr(tr) (tr = native_store_tr())
99
#define load_TLS(t, cpu) native_load_tls(t, cpu)
100
#define set_ldt native_set_ldt
97
102
#ifdef CONFIG_X86_32
98
#define load_user_cs_desc native_load_user_cs_desc
103
#define load_user_cs_desc native_load_user_cs_desc
99
104
#endif /*CONFIG_X86_32*/
101
#define write_ldt_entry(dt, entry, desc) \
102
native_write_ldt_entry(dt, entry, desc)
103
#define write_gdt_entry(dt, entry, desc, type) \
104
native_write_gdt_entry(dt, entry, desc, type)
105
#define write_idt_entry(dt, entry, g) \
106
native_write_idt_entry(dt, entry, g)
106
#define write_ldt_entry(dt, entry, desc) native_write_ldt_entry(dt, entry, desc)
107
#define write_gdt_entry(dt, entry, desc, type) native_write_gdt_entry(dt, entry, desc, type)
108
#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g)
108
110
static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
117
119
#define store_ldt(ldt) asm("sldt %0" : "=m"(ldt))
119
static inline void native_write_idt_entry(gate_desc *idt, int entry,
120
const gate_desc *gate)
121
static inline void native_write_idt_entry(gate_desc *idt, int entry, const gate_desc *gate)
122
123
memcpy(&idt[entry], gate, sizeof(*gate));
125
static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
126
static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, const void *desc)
128
128
memcpy(&ldt[entry], desc, 8);
131
static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
132
const void *desc, int type)
132
native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int type)
134
134
unsigned int size;
137
size = sizeof(tss_desc);
140
size = sizeof(ldt_desc);
143
size = sizeof(struct desc_struct);
137
case DESC_TSS: size = sizeof(tss_desc); break;
138
case DESC_LDT: size = sizeof(ldt_desc); break;
139
default: size = sizeof(*gdt); break;
146
142
memcpy(&gdt[entry], desc, size);
161
static inline void set_tssldt_descriptor(void *d, unsigned long addr,
162
unsigned type, unsigned size)
157
static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size)
164
159
#ifdef CONFIG_X86_64
165
160
struct ldttss_desc64 *desc = d;
166
162
memset(desc, 0, sizeof(*desc));
167
desc->limit0 = size & 0xFFFF;
168
desc->base0 = PTR_LOW(addr);
169
desc->base1 = PTR_MIDDLE(addr) & 0xFF;
172
desc->limit1 = (size >> 16) & 0xF;
173
desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF;
174
desc->base3 = PTR_HIGH(addr);
164
desc->limit0 = size & 0xFFFF;
165
desc->base0 = PTR_LOW(addr);
166
desc->base1 = PTR_MIDDLE(addr) & 0xFF;
169
desc->limit1 = (size >> 16) & 0xF;
170
desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF;
171
desc->base3 = PTR_HIGH(addr);
176
173
pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
241
238
static inline unsigned long native_store_tr(void)
243
240
unsigned long tr;
244
242
asm volatile("str %0":"=r" (tr));
248
247
static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
249
struct desc_struct *gdt = get_cpu_gdt_table(cpu);
251
struct desc_struct *gdt = get_cpu_gdt_table(cpu);
253
252
for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
254
253
gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];