[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: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Родитель
1956c73bb5
Коммит
c5413fbe89
|
@ -638,6 +638,18 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *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
|
||||
* initialized (naturally) in the bootstrap process, such as the GDT
|
||||
|
@ -668,6 +680,7 @@ void __cpuinit cpu_init(void)
|
|||
}
|
||||
|
||||
load_idt(&idt_descr);
|
||||
switch_to_new_gdt();
|
||||
|
||||
/*
|
||||
* Set up and load the per-CPU TSS and LDT
|
||||
|
|
|
@ -1177,18 +1177,6 @@ void __init native_smp_prepare_cpus(unsigned int 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)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
|
|
@ -750,6 +750,7 @@ extern void enable_sep_cpu(void);
|
|||
extern int sysenter_setup(void);
|
||||
|
||||
extern void cpu_set_gdt(int);
|
||||
extern void switch_to_new_gdt(void);
|
||||
extern void cpu_init(void);
|
||||
|
||||
extern int force_mwait;
|
||||
|
|
|
@ -75,7 +75,11 @@
|
|||
#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
|
||||
|
||||
#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
|
||||
#ifdef CONFIG_SMP
|
||||
#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
|
||||
#else
|
||||
#define __KERNEL_PERCPU 0
|
||||
#endif
|
||||
|
||||
#define GDT_ENTRY_DOUBLEFAULT_TSS 31
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче