aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/smp.c')
-rw-r--r--arch/x86/xen/smp.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 7005974c3ff3..c670d7518cf4 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -37,6 +37,7 @@
37#include <xen/hvc-console.h> 37#include <xen/hvc-console.h>
38#include "xen-ops.h" 38#include "xen-ops.h"
39#include "mmu.h" 39#include "mmu.h"
40#include "smp.h"
40 41
41cpumask_var_t xen_cpu_initialized_map; 42cpumask_var_t xen_cpu_initialized_map;
42 43
@@ -99,10 +100,14 @@ static void cpu_bringup(void)
99 wmb(); /* make sure everything is out */ 100 wmb(); /* make sure everything is out */
100} 101}
101 102
102/* Note: cpu parameter is only relevant for PVH */ 103/*
103static void cpu_bringup_and_idle(int cpu) 104 * Note: cpu parameter is only relevant for PVH. The reason for passing it
105 * is we can't do smp_processor_id until the percpu segments are loaded, for
106 * which we need the cpu number! So we pass it in rdi as first parameter.
107 */
108asmlinkage __visible void cpu_bringup_and_idle(int cpu)
104{ 109{
105#ifdef CONFIG_X86_64 110#ifdef CONFIG_XEN_PVH
106 if (xen_feature(XENFEAT_auto_translated_physmap) && 111 if (xen_feature(XENFEAT_auto_translated_physmap) &&
107 xen_feature(XENFEAT_supervisor_mode_kernel)) 112 xen_feature(XENFEAT_supervisor_mode_kernel))
108 xen_pvh_secondary_vcpu_init(cpu); 113 xen_pvh_secondary_vcpu_init(cpu);
@@ -374,11 +379,10 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
374 ctxt->user_regs.fs = __KERNEL_PERCPU; 379 ctxt->user_regs.fs = __KERNEL_PERCPU;
375 ctxt->user_regs.gs = __KERNEL_STACK_CANARY; 380 ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
376#endif 381#endif
377 ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle;
378
379 memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); 382 memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
380 383
381 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 384 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
385 ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle;
382 ctxt->flags = VGCF_IN_KERNEL; 386 ctxt->flags = VGCF_IN_KERNEL;
383 ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ 387 ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */
384 ctxt->user_regs.ds = __USER_DS; 388 ctxt->user_regs.ds = __USER_DS;
@@ -413,15 +417,18 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
413 (unsigned long)xen_failsafe_callback; 417 (unsigned long)xen_failsafe_callback;
414 ctxt->user_regs.cs = __KERNEL_CS; 418 ctxt->user_regs.cs = __KERNEL_CS;
415 per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir); 419 per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir);
416#ifdef CONFIG_X86_32
417 } 420 }
418#else 421#ifdef CONFIG_XEN_PVH
419 } else 422 else {
420 /* N.B. The user_regs.eip (cpu_bringup_and_idle) is called with 423 /*
421 * %rdi having the cpu number - which means are passing in 424 * The vcpu comes on kernel page tables which have the NX pte
422 * as the first parameter the cpu. Subtle! 425 * bit set. This means before DS/SS is touched, NX in
426 * EFER must be set. Hence the following assembly glue code.
423 */ 427 */
428 ctxt->user_regs.eip = (unsigned long)xen_pvh_early_cpu_init;
424 ctxt->user_regs.rdi = cpu; 429 ctxt->user_regs.rdi = cpu;
430 ctxt->user_regs.rsi = true; /* entry == true */
431 }
425#endif 432#endif
426 ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); 433 ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
427 ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir)); 434 ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));