aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/apm.c2
-rw-r--r--arch/i386/kernel/cpu/common.c3
-rw-r--r--arch/i386/kernel/head.S2
-rw-r--r--arch/i386/kernel/i386_ksyms.c3
-rw-r--r--arch/i386/kernel/smpboot.c6
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c22
-rw-r--r--include/asm-i386/desc.h8
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
21DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
22EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
23
24DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); 21DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
25EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); 22EXPORT_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 */ 6EXPORT_SYMBOL_GPL(cpu_gdt_descr);
7EXPORT_SYMBOL_GPL(cpu_gdt_table);
8 7
9EXPORT_SYMBOL(__down_failed); 8EXPORT_SYMBOL(__down_failed);
10EXPORT_SYMBOL(__down_failed_interruptible); 9EXPORT_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) \
71do { \ 71do { \
72set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \ 72struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
73set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ 73set_base(gdt[(selname) >> 3], __va((u32)(address))); \
74set_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) \
77do { \ 78do { \
78set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \ 79struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
79set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ 80set_base(gdt[(selname) >> 3], (u32)(address)); \
81set_limit(gdt[(selname) >> 3], size); \
80} while(0) 82} while(0)
81 83
82static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; 84static 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
17extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; 17extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
18DECLARE_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
22DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); 19DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
23 20
@@ -29,6 +26,11 @@ struct Xgt_desc_struct {
29 26
30extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS]; 27extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
31 28
29static 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