diff options
-rw-r--r-- | arch/i386/kernel/apm.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/common.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/i386/kernel/i386_ksyms.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 6 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/bioscalls.c | 22 | ||||
-rw-r--r-- | include/asm-i386/desc.h | 8 |
7 files changed, 29 insertions, 17 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 1e60acbed3c1..6c8e483ce9e4 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -2317,6 +2317,8 @@ static int __init apm_init(void) | |||
2317 | 2317 | ||
2318 | for (i = 0; i < NR_CPUS; i++) { | 2318 | for (i = 0; i < NR_CPUS; i++) { |
2319 | struct desc_struct *gdt = get_cpu_gdt_table(i); | 2319 | struct desc_struct *gdt = get_cpu_gdt_table(i); |
2320 | if (!gdt) | ||
2321 | continue; | ||
2320 | set_base(gdt[APM_CS >> 3], | 2322 | set_base(gdt[APM_CS >> 3], |
2321 | __va((unsigned long)apm_info.bios.cseg << 4)); | 2323 | __va((unsigned long)apm_info.bios.cseg << 4)); |
2322 | set_base(gdt[APM_CS_16 >> 3], | 2324 | set_base(gdt[APM_CS_16 >> 3], |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 31e344b26bae..cbc32069683f 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -18,9 +18,6 @@ | |||
18 | 18 | ||
19 | #include "cpu.h" | 19 | #include "cpu.h" |
20 | 20 | ||
21 | DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]); | ||
22 | EXPORT_PER_CPU_SYMBOL(cpu_gdt_table); | ||
23 | |||
24 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 21 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); |
25 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); | 22 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); |
26 | 23 | ||
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index e437fb367498..870f20bf33c8 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -525,3 +525,5 @@ ENTRY(cpu_gdt_table) | |||
525 | .quad 0x0000000000000000 /* 0xf0 - unused */ | 525 | .quad 0x0000000000000000 /* 0xf0 - unused */ |
526 | .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ | 526 | .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ |
527 | 527 | ||
528 | /* Be sure this is zeroed to avoid false validations in Xen */ | ||
529 | .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0 | ||
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 180f070d03cb..3999bec50c33 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c | |||
@@ -3,8 +3,7 @@ | |||
3 | #include <asm/checksum.h> | 3 | #include <asm/checksum.h> |
4 | #include <asm/desc.h> | 4 | #include <asm/desc.h> |
5 | 5 | ||
6 | /* This is definitely a GPL-only symbol */ | 6 | EXPORT_SYMBOL_GPL(cpu_gdt_descr); |
7 | EXPORT_SYMBOL_GPL(cpu_gdt_table); | ||
8 | 7 | ||
9 | EXPORT_SYMBOL(__down_failed); | 8 | EXPORT_SYMBOL(__down_failed); |
10 | EXPORT_SYMBOL(__down_failed_interruptible); | 9 | EXPORT_SYMBOL(__down_failed_interruptible); |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 9ed449af8e9f..b3c2e2c26743 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -903,6 +903,12 @@ static int __devinit do_boot_cpu(int apicid, int cpu) | |||
903 | unsigned long start_eip; | 903 | unsigned long start_eip; |
904 | unsigned short nmi_high = 0, nmi_low = 0; | 904 | unsigned short nmi_high = 0, nmi_low = 0; |
905 | 905 | ||
906 | if (!cpu_gdt_descr[cpu].address && | ||
907 | !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) { | ||
908 | printk("Failed to allocate GDT for CPU %d\n", cpu); | ||
909 | return 1; | ||
910 | } | ||
911 | |||
906 | ++cpucount; | 912 | ++cpucount; |
907 | 913 | ||
908 | /* | 914 | /* |
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 6b7583f497d0..7cb476ed7f91 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c | |||
@@ -69,14 +69,16 @@ __asm__( | |||
69 | 69 | ||
70 | #define Q_SET_SEL(cpu, selname, address, size) \ | 70 | #define Q_SET_SEL(cpu, selname, address, size) \ |
71 | do { \ | 71 | do { \ |
72 | set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \ | 72 | struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ |
73 | set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ | 73 | set_base(gdt[(selname) >> 3], __va((u32)(address))); \ |
74 | set_limit(gdt[(selname) >> 3], size); \ | ||
74 | } while(0) | 75 | } while(0) |
75 | 76 | ||
76 | #define Q2_SET_SEL(cpu, selname, address, size) \ | 77 | #define Q2_SET_SEL(cpu, selname, address, size) \ |
77 | do { \ | 78 | do { \ |
78 | set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \ | 79 | struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ |
79 | set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ | 80 | set_base(gdt[(selname) >> 3], (u32)(address)); \ |
81 | set_limit(gdt[(selname) >> 3], size); \ | ||
80 | } while(0) | 82 | } while(0) |
81 | 83 | ||
82 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; | 84 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
@@ -115,8 +117,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, | |||
115 | return PNP_FUNCTION_NOT_SUPPORTED; | 117 | return PNP_FUNCTION_NOT_SUPPORTED; |
116 | 118 | ||
117 | cpu = get_cpu(); | 119 | cpu = get_cpu(); |
118 | save_desc_40 = per_cpu(cpu_gdt_table,cpu)[0x40 / 8]; | 120 | save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; |
119 | per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = bad_bios_desc; | 121 | get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; |
120 | 122 | ||
121 | /* On some boxes IRQ's during PnP BIOS calls are deadly. */ | 123 | /* On some boxes IRQ's during PnP BIOS calls are deadly. */ |
122 | spin_lock_irqsave(&pnp_bios_lock, flags); | 124 | spin_lock_irqsave(&pnp_bios_lock, flags); |
@@ -158,7 +160,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, | |||
158 | ); | 160 | ); |
159 | spin_unlock_irqrestore(&pnp_bios_lock, flags); | 161 | spin_unlock_irqrestore(&pnp_bios_lock, flags); |
160 | 162 | ||
161 | per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = save_desc_40; | 163 | get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; |
162 | put_cpu(); | 164 | put_cpu(); |
163 | 165 | ||
164 | /* If we get here and this is set then the PnP BIOS faulted on us. */ | 166 | /* If we get here and this is set then the PnP BIOS faulted on us. */ |
@@ -535,8 +537,10 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) | |||
535 | 537 | ||
536 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); | 538 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
537 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); | 539 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
538 | for(i=0; i < NR_CPUS; i++) | 540 | for (i = 0; i < NR_CPUS; i++) { |
539 | { | 541 | struct desc_struct *gdt = get_cpu_gdt_table(i); |
542 | if (!gdt) | ||
543 | continue; | ||
540 | Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024); | 544 | Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024); |
541 | Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024); | 545 | Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024); |
542 | Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024); | 546 | Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024); |
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 29b851a18c6e..494e73bca095 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h | |||
@@ -15,9 +15,6 @@ | |||
15 | #include <asm/mmu.h> | 15 | #include <asm/mmu.h> |
16 | 16 | ||
17 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; | 17 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; |
18 | DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]); | ||
19 | |||
20 | #define get_cpu_gdt_table(_cpu) (per_cpu(cpu_gdt_table,_cpu)) | ||
21 | 18 | ||
22 | DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 19 | DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); |
23 | 20 | ||
@@ -29,6 +26,11 @@ struct Xgt_desc_struct { | |||
29 | 26 | ||
30 | extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS]; | 27 | extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS]; |
31 | 28 | ||
29 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | ||
30 | { | ||
31 | return ((struct desc_struct *)cpu_gdt_descr[cpu].address); | ||
32 | } | ||
33 | |||
32 | #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) | 34 | #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) |
33 | #define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)) | 35 | #define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)) |
34 | 36 | ||