Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c5413fbe894924ddb8aa474a4d4da52e7a6c7e0b
Commit:     c5413fbe894924ddb8aa474a4d4da52e7a6c7e0b
Parent:     1956c73bb5bf81ee577ed7d3c64e3cad876ad2a5
Author:     Jeremy Fitzhardinge <[EMAIL PROTECTED]>
AuthorDate: Wed May 2 19:27:16 2007 +0200
Committer:  Andi Kleen <[EMAIL PROTECTED]>
CommitDate: Wed May 2 19:27:16 2007 +0200

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
    Signed-off-by: Andi Kleen <[EMAIL PROTECTED]>
    Cc: Rusty Russell <[EMAIL PROTECTED]>
---
 arch/i386/kernel/cpu/common.c |   13 +++++++++++++
 arch/i386/kernel/smpboot.c    |   12 ------------
 include/asm-i386/processor.h  |    1 +
 include/asm-i386/segment.h    |    4 ++++
 4 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 27e0056..794d593 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -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
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index f79b623..7c1dbef 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -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();
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index ced2da8..70f3515 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -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;
diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h
index 07e7062..597a47c 100644
--- a/include/asm-i386/segment.h
+++ b/include/asm-i386/segment.h
@@ -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
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to