diff options
author | Glauber de Oliveira Costa <gcosta@redhat.com> | 2007-10-19 14:35:03 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2007-10-19 14:35:03 -0400 |
commit | 9d1c6e7c86ddc366d67f0c5fa77be9b93710037a (patch) | |
tree | 2561f09ea7393c04634352808b6cba2195099b73 | |
parent | 9d975ebda56699c1b8480e9736caf33a61ccb810 (diff) |
x86: use descriptor's functions instead of inline assembly
This patch provides a new set of functions for managing the descriptor
tables that can be used instead of putting the raw assembly in .c files.
Remodeling of store_tr() suggested by Frederik Deweerdt.
[ tglx: arch/x86 adaptation ]
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/kernel/head64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/reboot_64.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/setup64.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/suspend_64.c | 11 | ||||
-rw-r--r-- | include/asm-x86/desc_64.h | 30 |
5 files changed, 41 insertions, 9 deletions
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index a7eee0a4751d..6b3469311e42 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -58,7 +58,7 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
58 | 58 | ||
59 | for (i = 0; i < IDT_ENTRIES; i++) | 59 | for (i = 0; i < IDT_ENTRIES; i++) |
60 | set_intr_gate(i, early_idt_handler); | 60 | set_intr_gate(i, early_idt_handler); |
61 | asm volatile("lidt %0" :: "m" (idt_descr)); | 61 | load_idt((const struct desc_ptr *)&idt_descr); |
62 | 62 | ||
63 | early_printk("Kernel alive\n"); | 63 | early_printk("Kernel alive\n"); |
64 | 64 | ||
diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c index 368db2b9c5ac..776eb06b6512 100644 --- a/arch/x86/kernel/reboot_64.c +++ b/arch/x86/kernel/reboot_64.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | #include <asm/delay.h> | 13 | #include <asm/delay.h> |
14 | #include <asm/desc.h> | ||
14 | #include <asm/hw_irq.h> | 15 | #include <asm/hw_irq.h> |
15 | #include <asm/system.h> | 16 | #include <asm/system.h> |
16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
@@ -136,7 +137,7 @@ void machine_emergency_restart(void) | |||
136 | } | 137 | } |
137 | 138 | ||
138 | case BOOT_TRIPLE: | 139 | case BOOT_TRIPLE: |
139 | __asm__ __volatile__("lidt (%0)": :"r" (&no_idt)); | 140 | load_idt((const struct desc_ptr *)&no_idt); |
140 | __asm__ __volatile__("int3"); | 141 | __asm__ __volatile__("int3"); |
141 | 142 | ||
142 | reboot_type = BOOT_KBD; | 143 | reboot_type = BOOT_KBD; |
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index e11886e8d8ca..3558ac78c926 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c | |||
@@ -230,8 +230,8 @@ void __cpuinit cpu_init (void) | |||
230 | memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE); | 230 | memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE); |
231 | 231 | ||
232 | cpu_gdt_descr[cpu].size = GDT_SIZE; | 232 | cpu_gdt_descr[cpu].size = GDT_SIZE; |
233 | asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu])); | 233 | load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]); |
234 | asm volatile("lidt %0" :: "m" (idt_descr)); | 234 | load_idt((const struct desc_ptr *)&idt_descr); |
235 | 235 | ||
236 | memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); | 236 | memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); |
237 | syscall_init(); | 237 | syscall_init(); |
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index f8fafe527ff1..622bb0268284 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c | |||
@@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt) | |||
32 | /* | 32 | /* |
33 | * descriptor tables | 33 | * descriptor tables |
34 | */ | 34 | */ |
35 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); | 35 | store_gdt((struct desc_ptr *)&ctxt->gdt_limit); |
36 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); | 36 | store_idt((struct desc_ptr *)&ctxt->idt_limit); |
37 | asm volatile ("str %0" : "=m" (ctxt->tr)); | 37 | store_tr(ctxt->tr); |
38 | 38 | ||
39 | /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ | 39 | /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ |
40 | /* | 40 | /* |
@@ -91,8 +91,9 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
91 | * now restore the descriptor tables to their proper values | 91 | * now restore the descriptor tables to their proper values |
92 | * ltr is done i fix_processor_context(). | 92 | * ltr is done i fix_processor_context(). |
93 | */ | 93 | */ |
94 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | 94 | load_gdt((const struct desc_ptr *)&ctxt->gdt_limit); |
95 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | 95 | load_idt((const struct desc_ptr *)&ctxt->idt_limit); |
96 | |||
96 | 97 | ||
97 | /* | 98 | /* |
98 | * segment registers | 99 | * segment registers |
diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index ac991b5ca0fd..7d9c938e69fd 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h | |||
@@ -20,6 +20,16 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; | |||
20 | #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) | 20 | #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) |
21 | #define clear_LDT() asm volatile("lldt %w0"::"r" (0)) | 21 | #define clear_LDT() asm volatile("lldt %w0"::"r" (0)) |
22 | 22 | ||
23 | static inline unsigned long __store_tr(void) | ||
24 | { | ||
25 | unsigned long tr; | ||
26 | |||
27 | asm volatile ("str %w0":"=r" (tr)); | ||
28 | return tr; | ||
29 | } | ||
30 | |||
31 | #define store_tr(tr) (tr) = __store_tr() | ||
32 | |||
23 | /* | 33 | /* |
24 | * This is the ldt that every process will get unless we need | 34 | * This is the ldt that every process will get unless we need |
25 | * something other than this. | 35 | * something other than this. |
@@ -31,6 +41,16 @@ extern struct desc_ptr cpu_gdt_descr[]; | |||
31 | /* the cpu gdt accessor */ | 41 | /* the cpu gdt accessor */ |
32 | #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) | 42 | #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) |
33 | 43 | ||
44 | static inline void load_gdt(const struct desc_ptr *ptr) | ||
45 | { | ||
46 | asm volatile("lgdt %w0"::"m" (*ptr)); | ||
47 | } | ||
48 | |||
49 | static inline void store_gdt(struct desc_ptr *ptr) | ||
50 | { | ||
51 | asm("sgdt %w0":"=m" (*ptr)); | ||
52 | } | ||
53 | |||
34 | static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) | 54 | static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) |
35 | { | 55 | { |
36 | struct gate_struct s; | 56 | struct gate_struct s; |
@@ -71,6 +91,16 @@ static inline void set_system_gate_ist(int nr, void *func, unsigned ist) | |||
71 | _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist); | 91 | _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist); |
72 | } | 92 | } |
73 | 93 | ||
94 | static inline void load_idt(const struct desc_ptr *ptr) | ||
95 | { | ||
96 | asm volatile("lidt %w0"::"m" (*ptr)); | ||
97 | } | ||
98 | |||
99 | static inline void store_idt(struct desc_ptr *dtr) | ||
100 | { | ||
101 | asm("sidt %w0":"=m" (*dtr)); | ||
102 | } | ||
103 | |||
74 | static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, | 104 | static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, |
75 | unsigned size) | 105 | unsigned size) |
76 | { | 106 | { |