static int xen_pv_cpu_up(unsigned int cpu, struct task_struct *idle) { int rc; common_cpu_up(cpu, idle); xen_setup_runstate_info(cpu); /* * PV VCPUs are always successfully taken down (see 'while' loop * in xen_cpu_die()), so -EBUSY is an error. */ rc = cpu_check_up_prepare(cpu); if (rc) return rc; /* make sure interrupts start blocked */ per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; rc = cpu_initialize_context(cpu, idle); if (rc) return rc; xen_pmu_init(cpu); rc = HYPERVISOR_vcpu_op(VCPUOP_up, xen_vcpu_nr(cpu), NULL); BUG_ON(rc); while (cpu_report_state(cpu) != CPU_ONLINE) HYPERVISOR_sched_op(SCHEDOP_yield, NULL); return 0; }
static int xen_start_vcpu(uint vcpu, ulong entry) { DBG("%s: starting vcpu: %d\n", __func__, vcpu); cpu_initialize_context(vcpu, entry); DBG("%s: Spinning up vcpu: %d\n", __func__, vcpu); return HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL); }
static int __cpuinit xen_cpu_up(unsigned int cpu) { struct task_struct *idle = idle_task(cpu); int rc; #ifdef CONFIG_X86_64 /* Allocate node local memory for AP pdas */ WARN_ON(cpu == 0); if (cpu > 0) { rc = get_local_pda(cpu); if (rc) return rc; } #endif #ifdef CONFIG_X86_32 init_gdt(cpu); per_cpu(current_task, cpu) = idle; irq_ctx_init(cpu); #else cpu_pda(cpu)->pcurrent = idle; clear_tsk_thread_flag(idle, TIF_FORK); #endif xen_setup_timer(cpu); xen_init_lock_cpu(cpu); per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* make sure interrupts start blocked */ per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; rc = cpu_initialize_context(cpu, idle); if (rc) return rc; if (num_online_cpus() == 1) alternatives_smp_switch(1); rc = xen_smp_intr_init(cpu); if (rc) return rc; rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); BUG_ON(rc); while(per_cpu(cpu_state, cpu) != CPU_ONLINE) { HYPERVISOR_sched_op(SCHEDOP_yield, 0); barrier(); } return 0; }
static int __cpuinit xen_cpu_up(unsigned int cpu) { struct task_struct *idle = idle_task(cpu); int rc; per_cpu(current_task, cpu) = idle; #ifdef CONFIG_X86_32 irq_ctx_init(cpu); #else clear_tsk_thread_flag(idle, TIF_FORK); per_cpu(kernel_stack, cpu) = (unsigned long)task_stack_page(idle) - KERNEL_STACK_OFFSET + THREAD_SIZE; per_cpu(kernel_stack8k, cpu) = (unsigned long)task_stack_page(idle) - KERNEL_STACK_OFFSET + THREAD_SIZE - 8192; #endif xen_setup_runstate_info(cpu); xen_setup_timer(cpu); xen_init_lock_cpu(cpu); per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* make sure interrupts start blocked */ per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; rc = cpu_initialize_context(cpu, idle); if (rc) return rc; if (num_online_cpus() == 1) alternatives_smp_switch(1); rc = xen_smp_intr_init(cpu); if (rc) return rc; rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); BUG_ON(rc); while(per_cpu(cpu_state, cpu) != CPU_ONLINE) { HYPERVISOR_sched_op(SCHEDOP_yield, NULL); barrier(); } return 0; }
static int start_ap(int apic_id) { int ms; /* used as a watchpoint to signal AP startup */ cpus = mp_naps; cpu_initialize_context(apic_id); /* Wait up to 5 seconds for it to start. */ for (ms = 0; ms < 5000; ms++) { if (mp_naps > cpus) return 1; /* return SUCCESS */ DELAY(1000); } return 0; /* return FAILURE */ }
static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle) { int rc; per_cpu(current_task, cpu) = idle; per_cpu(current_tinfo, cpu) = &idle->tinfo; #ifdef CONFIG_X86_32 irq_ctx_init(cpu); #else clear_tsk_thread_flag(idle, TIF_FORK); per_cpu(kernel_stack, cpu) = (unsigned long)task_stack_page(idle) - 16 + THREAD_SIZE; #endif xen_setup_runstate_info(cpu); xen_setup_timer(cpu); xen_init_lock_cpu(cpu); per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* make sure interrupts start blocked */ per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; rc = cpu_initialize_context(cpu, idle); if (rc) return rc; if (num_online_cpus() == 1) /* Just in case we booted with a single CPU. */ alternatives_enable_smp(); rc = xen_smp_intr_init(cpu); if (rc) return rc; rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); BUG_ON(rc); while(per_cpu(cpu_state, cpu) != CPU_ONLINE) { HYPERVISOR_sched_op(SCHEDOP_yield, NULL); barrier(); } return 0; }
int __cpuinit xen_cpu_up(unsigned int cpu) { struct task_struct *idle = idle_task(cpu); int rc; #if 0 rc = cpu_up_check(cpu); if (rc) return rc; #endif init_gdt(cpu); per_cpu(current_task, cpu) = idle; irq_ctx_init(cpu); xen_setup_timer(cpu); /* make sure interrupts start blocked */ per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; rc = cpu_initialize_context(cpu, idle); if (rc) return rc; if (num_online_cpus() == 1) alternatives_smp_switch(1); rc = xen_smp_intr_init(cpu); if (rc) return rc; smp_store_cpu_info(cpu); set_cpu_sibling_map(cpu); /* This must be done before setting cpu_online_map */ wmb(); cpu_set(cpu, cpu_online_map); rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); BUG_ON(rc); return 0; }
void init_smp(void) { unsigned int cpu; int res; memset(percpu, 0, sizeof(struct cpu_private) * MAX_VIRT_CPUS); init_cpu_pda(0); /* * Init of CPU0 is completed, smp_init_completed must be set before we * initialise remaining CPUs, because smp_proccessor_id macro will not * work properly */ smp_init_completed = 1; /* * We have now completed the init of cpu0 */ if (trace_smp()) tprintk("Initing SMP cpus.\n"); for (cpu = 1; cpu < MAX_VIRT_CPUS; cpu++) { per_cpu(cpu, cpu_state) = CPU_DOWN; res = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL); if (res >= 0) { if (trace_smp()) tprintk("Bringing up CPU=%d\n", cpu); cpu_initialize_context(cpu); BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)); spin_lock(&cpu_lock); smp_active++; spin_unlock(&cpu_lock); } } if (trace_smp()) { tprintk("SMP: %d CPUs active\n", smp_active); for (cpu = 0; cpu < MAX_VIRT_CPUS; cpu++) { tprintk("SMP: cpu_state %d %d\n", cpu, per_cpu(cpu, cpu_state)); } } if (trace_sched()) ttprintk("SMP %d\n", smp_active); }