diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-05-02 13:27:11 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:11 -0400 |
commit | 4fbb5968810b237e81977f131986b9efd5245368 (patch) | |
tree | e2d67eee96c143da26ccad791b3e1f23c3bcbe03 | |
parent | 141f9cfe0a948c8fe26e5669364ee62c03ea42e8 (diff) |
[PATCH] i386: cleanup GDT Access
Now we have an explicit per-cpu GDT variable, we don't need to keep the
descriptors around to use them to find the GDT: expose cpu_gdt directly.
We could go further and make load_gdt() pack the descriptor for us, or even
assume it means "load the current cpu's GDT" which is what it always does.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r-- | arch/i386/kernel/cpu/common.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/efi.c | 16 | ||||
-rw-r--r-- | arch/i386/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 12 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 4 | ||||
-rw-r--r-- | include/asm-i386/desc.h | 7 |
6 files changed, 19 insertions, 27 deletions
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 2a26956fce42..5faf675aab4b 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -22,9 +22,6 @@ | |||
22 | 22 | ||
23 | #include "cpu.h" | 23 | #include "cpu.h" |
24 | 24 | ||
25 | DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); | ||
26 | EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); | ||
27 | |||
28 | DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { | 25 | DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { |
29 | [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, | 26 | [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, |
30 | [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, | 27 | [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, |
@@ -52,6 +49,7 @@ DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = { | |||
52 | [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, | 49 | [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, |
53 | [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */ | 50 | [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */ |
54 | }; | 51 | }; |
52 | EXPORT_PER_CPU_SYMBOL_GPL(cpu_gdt); | ||
55 | 53 | ||
56 | DEFINE_PER_CPU(struct i386_pda, _cpu_pda); | 54 | DEFINE_PER_CPU(struct i386_pda, _cpu_pda); |
57 | EXPORT_PER_CPU_SYMBOL(_cpu_pda); | 55 | EXPORT_PER_CPU_SYMBOL(_cpu_pda); |
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 8f9c624ace6f..dd9e7faafa7c 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c | |||
@@ -69,13 +69,11 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) | |||
69 | { | 69 | { |
70 | unsigned long cr4; | 70 | unsigned long cr4; |
71 | unsigned long temp; | 71 | unsigned long temp; |
72 | struct Xgt_desc_struct *cpu_gdt_descr; | 72 | struct Xgt_desc_struct gdt_descr; |
73 | 73 | ||
74 | spin_lock(&efi_rt_lock); | 74 | spin_lock(&efi_rt_lock); |
75 | local_irq_save(efi_rt_eflags); | 75 | local_irq_save(efi_rt_eflags); |
76 | 76 | ||
77 | cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); | ||
78 | |||
79 | /* | 77 | /* |
80 | * If I don't have PSE, I should just duplicate two entries in page | 78 | * If I don't have PSE, I should just duplicate two entries in page |
81 | * directory. If I have PSE, I just need to duplicate one entry in | 79 | * directory. If I have PSE, I just need to duplicate one entry in |
@@ -105,17 +103,19 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) | |||
105 | */ | 103 | */ |
106 | local_flush_tlb(); | 104 | local_flush_tlb(); |
107 | 105 | ||
108 | cpu_gdt_descr->address = __pa(cpu_gdt_descr->address); | 106 | gdt_descr.address = __pa(get_cpu_gdt_table(0)); |
109 | load_gdt(cpu_gdt_descr); | 107 | gdt_descr.size = GDT_SIZE - 1; |
108 | load_gdt(&gdt_descr); | ||
110 | } | 109 | } |
111 | 110 | ||
112 | static void efi_call_phys_epilog(void) __releases(efi_rt_lock) | 111 | static void efi_call_phys_epilog(void) __releases(efi_rt_lock) |
113 | { | 112 | { |
114 | unsigned long cr4; | 113 | unsigned long cr4; |
115 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); | 114 | struct Xgt_desc_struct gdt_descr; |
116 | 115 | ||
117 | cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address); | 116 | gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); |
118 | load_gdt(cpu_gdt_descr); | 117 | gdt_descr.size = GDT_SIZE - 1; |
118 | load_gdt(&gdt_descr); | ||
119 | 119 | ||
120 | cr4 = read_cr4(); | 120 | cr4 = read_cr4(); |
121 | 121 | ||
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 922cc38dc405..c61c6b67e856 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S | |||
@@ -561,8 +561,7 @@ END(syscall_badsys) | |||
561 | #define FIXUP_ESPFIX_STACK \ | 561 | #define FIXUP_ESPFIX_STACK \ |
562 | /* since we are on a wrong stack, we cant make it a C code :( */ \ | 562 | /* since we are on a wrong stack, we cant make it a C code :( */ \ |
563 | movl %fs:PDA_cpu, %ebx; \ | 563 | movl %fs:PDA_cpu, %ebx; \ |
564 | PER_CPU(cpu_gdt_descr, %ebx); \ | 564 | PER_CPU(cpu_gdt, %ebx); \ |
565 | movl GDS_address(%ebx), %ebx; \ | ||
566 | GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ | 565 | GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ |
567 | addl %esp, %eax; \ | 566 | addl %esp, %eax; \ |
568 | pushl $__KERNEL_DS; \ | 567 | pushl $__KERNEL_DS; \ |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 954245f6d307..b0ad04d9ef21 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -786,13 +786,9 @@ static inline struct task_struct * alloc_idle_task(int cpu) | |||
786 | secondary which will soon come up. */ | 786 | secondary which will soon come up. */ |
787 | static __cpuinit void init_gdt(int cpu, struct task_struct *idle) | 787 | static __cpuinit void init_gdt(int cpu, struct task_struct *idle) |
788 | { | 788 | { |
789 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | 789 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
790 | struct desc_struct *gdt = per_cpu(cpu_gdt, cpu); | ||
791 | struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); | 790 | struct i386_pda *pda = &per_cpu(_cpu_pda, cpu); |
792 | 791 | ||
793 | cpu_gdt_descr->address = (unsigned long)gdt; | ||
794 | cpu_gdt_descr->size = GDT_SIZE - 1; | ||
795 | |||
796 | pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, | 792 | pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, |
797 | (u32 *)&gdt[GDT_ENTRY_PDA].b, | 793 | (u32 *)&gdt[GDT_ENTRY_PDA].b, |
798 | (unsigned long)pda, sizeof(*pda) - 1, | 794 | (unsigned long)pda, sizeof(*pda) - 1, |
@@ -1187,7 +1183,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
1187 | * it's on the real one. */ | 1183 | * it's on the real one. */ |
1188 | static inline void switch_to_new_gdt(void) | 1184 | static inline void switch_to_new_gdt(void) |
1189 | { | 1185 | { |
1190 | load_gdt(&per_cpu(cpu_gdt_descr, smp_processor_id())); | 1186 | struct Xgt_desc_struct gdt_descr; |
1187 | |||
1188 | gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); | ||
1189 | gdt_descr.size = GDT_SIZE - 1; | ||
1190 | load_gdt(&gdt_descr); | ||
1191 | asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); | 1191 | asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); |
1192 | } | 1192 | } |
1193 | 1193 | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 58dfecc8e36c..8722444cacaa 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -1030,9 +1030,7 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, | |||
1030 | fastcall unsigned long patch_espfix_desc(unsigned long uesp, | 1030 | fastcall unsigned long patch_espfix_desc(unsigned long uesp, |
1031 | unsigned long kesp) | 1031 | unsigned long kesp) |
1032 | { | 1032 | { |
1033 | int cpu = smp_processor_id(); | 1033 | struct desc_struct *gdt = __get_cpu_var(cpu_gdt); |
1034 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | ||
1035 | struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; | ||
1036 | unsigned long base = (kesp - uesp) & -THREAD_SIZE; | 1034 | unsigned long base = (kesp - uesp) & -THREAD_SIZE; |
1037 | unsigned long new_kesp = kesp - base; | 1035 | unsigned long new_kesp = kesp - base; |
1038 | unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; | 1036 | unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; |
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 13f701ea9a8f..4a974064e928 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h | |||
@@ -18,16 +18,13 @@ struct Xgt_desc_struct { | |||
18 | unsigned short pad; | 18 | unsigned short pad; |
19 | } __attribute__ ((packed)); | 19 | } __attribute__ ((packed)); |
20 | 20 | ||
21 | extern struct Xgt_desc_struct idt_descr; | ||
22 | DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); | ||
23 | DECLARE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); | 21 | DECLARE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]); |
24 | extern struct Xgt_desc_struct early_gdt_descr; | ||
25 | |||
26 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | 22 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) |
27 | { | 23 | { |
28 | return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; | 24 | return per_cpu(cpu_gdt, cpu); |
29 | } | 25 | } |
30 | 26 | ||
27 | extern struct Xgt_desc_struct idt_descr; | ||
31 | extern struct desc_struct idt_table[]; | 28 | extern struct desc_struct idt_table[]; |
32 | extern void set_intr_gate(unsigned int irq, void * addr); | 29 | extern void set_intr_gate(unsigned int irq, void * addr); |
33 | 30 | ||