Commit c5413fbe authored by Jeremy Fitzhardinge's avatar Jeremy Fitzhardinge Committed by Andi Kleen

[PATCH] i386: Fix UP gdt bugs

Fixes two problems with the GDT when compiling for uniprocessor:
 - There's no percpu segment, so trying to load its selector into %fs fails.
   Use a null selector instead.
 - The real gdt needs to be loaded at some point.  Do it in cpu_init().
Signed-off-by: default avatarChris Wright <chrisw@sous-sol.org>
Signed-off-by: default avatarJeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
parent 1956c73b
...@@ -638,6 +638,18 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) ...@@ -638,6 +638,18 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
return regs; return regs;
} }
/* Current gdt points %fs at the "master" per-cpu area: after this,
* it's on the real one. */
void switch_to_new_gdt(void)
{
struct Xgt_desc_struct gdt_descr;
gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
gdt_descr.size = GDT_SIZE - 1;
load_gdt(&gdt_descr);
asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
}
/* /*
* cpu_init() initializes state that is per-CPU. Some data is already * cpu_init() initializes state that is per-CPU. Some data is already
* initialized (naturally) in the bootstrap process, such as the GDT * initialized (naturally) in the bootstrap process, such as the GDT
...@@ -668,6 +680,7 @@ void __cpuinit cpu_init(void) ...@@ -668,6 +680,7 @@ void __cpuinit cpu_init(void)
} }
load_idt(&idt_descr); load_idt(&idt_descr);
switch_to_new_gdt();
/* /*
* Set up and load the per-CPU TSS and LDT * Set up and load the per-CPU TSS and LDT
......
...@@ -1177,18 +1177,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) ...@@ -1177,18 +1177,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
smp_boot_cpus(max_cpus); smp_boot_cpus(max_cpus);
} }
/* Current gdt points %fs at the "master" per-cpu area: after this,
* it's on the real one. */
static inline void switch_to_new_gdt(void)
{
struct Xgt_desc_struct gdt_descr;
gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
gdt_descr.size = GDT_SIZE - 1;
load_gdt(&gdt_descr);
asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
}
void __init native_smp_prepare_boot_cpu(void) void __init native_smp_prepare_boot_cpu(void)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
......
...@@ -750,6 +750,7 @@ extern void enable_sep_cpu(void); ...@@ -750,6 +750,7 @@ extern void enable_sep_cpu(void);
extern int sysenter_setup(void); extern int sysenter_setup(void);
extern void cpu_set_gdt(int); extern void cpu_set_gdt(int);
extern void switch_to_new_gdt(void);
extern void cpu_init(void); extern void cpu_init(void);
extern int force_mwait; extern int force_mwait;
......
...@@ -75,7 +75,11 @@ ...@@ -75,7 +75,11 @@
#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) #define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
#ifdef CONFIG_SMP
#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
#else
#define __KERNEL_PERCPU 0
#endif
#define GDT_ENTRY_DOUBLEFAULT_TSS 31 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment