aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2009-01-30 03:47:54 -0500
committerTejun Heo <tj@kernel.org>2009-01-31 00:28:54 -0500
commit11e3a840cd5b731cdd8f6f956dfae78a8046d09c (patch)
treebf92ad6319e658d00994a846a044874672942d15 /arch/x86
parent552be871e67ff577ed36beb2f53d078b42304739 (diff)
x86: split loading percpu segments from loading gdt
Impact: split out a function, no functional change Xen needs to be able to access percpu data from very early on. For various reasons, it cannot also load the gdt at that time. It does, however, have a pefectly functional gdt at that point, so there's no pressing need to reload the gdt. Split the function to load the segment registers off, so Xen can call it directly. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/kernel/cpu/common.c18
2 files changed, 13 insertions, 6 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 1c25eb69ea86..656d02ea509b 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -769,6 +769,7 @@ extern struct desc_ptr early_gdt_descr;
769 769
770extern void cpu_set_gdt(int); 770extern void cpu_set_gdt(int);
771extern void switch_to_new_gdt(int); 771extern void switch_to_new_gdt(int);
772extern void load_percpu_segment(int);
772extern void cpu_init(void); 773extern void cpu_init(void);
773 774
774static inline unsigned long get_debugctlmsr(void) 775static inline unsigned long get_debugctlmsr(void)
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 6eacd64b602e..0f73ea423089 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -253,6 +253,16 @@ static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c)
253 253
254__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; 254__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
255 255
256void load_percpu_segment(int cpu)
257{
258#ifdef CONFIG_X86_32
259 loadsegment(fs, __KERNEL_PERCPU);
260#else
261 loadsegment(gs, 0);
262 wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
263#endif
264}
265
256/* Current gdt points %fs at the "master" per-cpu area: after this, 266/* Current gdt points %fs at the "master" per-cpu area: after this,
257 * it's on the real one. */ 267 * it's on the real one. */
258void switch_to_new_gdt(int cpu) 268void switch_to_new_gdt(int cpu)
@@ -263,12 +273,8 @@ void switch_to_new_gdt(int cpu)
263 gdt_descr.size = GDT_SIZE - 1; 273 gdt_descr.size = GDT_SIZE - 1;
264 load_gdt(&gdt_descr); 274 load_gdt(&gdt_descr);
265 /* Reload the per-cpu base */ 275 /* Reload the per-cpu base */
266#ifdef CONFIG_X86_32 276
267 loadsegment(fs, __KERNEL_PERCPU); 277 load_percpu_segment(cpu);
268#else
269 loadsegment(gs, 0);
270 wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
271#endif
272} 278}
273 279
274static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; 280static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};