// SPDX-License-Identifier: GPL-2.0 /* * Xen SMP support * * This file implements the Xen versions of smp_ops. SMP under Xen is * very straightforward. Bringing a CPU up is simply a matter of * loading its initial context and setting it running. * * IPIs are handled through the Xen event mechanism. * * Because virtual CPUs can be scheduled onto any real CPU, there's no * useful topology information for the kernel to make use of. As a * result, all CPUs are treated as if they're single-core and * single-threaded.
*/ #include <linux/sched.h> #include <linux/sched/task_stack.h> #include <linux/err.h> #include <linux/slab.h> #include <linux/smp.h> #include <linux/irq_work.h> #include <linux/tick.h> #include <linux/nmi.h> #include <linux/cpuhotplug.h> #include <linux/stackprotector.h> #include <linux/pgtable.h>
/* PVH runs in ring 0 and allows us to do native syscalls. Yay! */ if (!xen_feature(XENFEAT_supervisor_mode_kernel)) {
xen_enable_sysenter();
xen_enable_syscall();
}
cpu = smp_processor_id();
identify_secondary_cpu(cpu);
set_cpu_sibling_map(cpu);
speculative_store_bypass_ht_init();
xen_setup_cpu_clockevents();
notify_cpu_starting(cpu);
set_cpu_online(cpu, true);
smp_mb();
/* We can take interrupts now: we're officially "up". */
local_irq_enable();
}
if (!xen_feature(XENFEAT_writable_page_tables)) /* We've switched to the "real" per-cpu gdt, so make
* sure the old memory can be recycled. */
make_lowmem_page_readwrite(xen_initial_gdt);
xen_setup_vcpu_info_placement();
/* * The alternative logic (which patches the unlock/lock) runs before * the smp bootup up code is activated. Hence we need to set this up * the core kernel is being patched. Otherwise we will have only * modules patched but not core code.
*/
xen_init_spinlocks();
}
if (ioapic_is_disabled) { char *m = (max_cpus == 0) ? "The nosmp parameter is incompatible with Xen; " \ "use Xen dom0_max_vcpus=1 parameter" : "The noapic parameter is incompatible with Xen";
/* * Bring up the CPU in cpu_bringup_and_idle() with the stack * pointing just below where pt_regs would be if it were a normal * kernel entry.
*/
ctxt->user_regs.eip = (unsignedlong)asm_cpu_bringup_and_idle;
ctxt->flags = VGCF_IN_KERNEL;
ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */
ctxt->user_regs.ds = __USER_DS;
ctxt->user_regs.es = __USER_DS;
ctxt->user_regs.ss = __KERNEL_DS;
ctxt->user_regs.cs = __KERNEL_CS;
ctxt->user_regs.esp = (unsignedlong)task_pt_regs(idle);
/* * Set SS:SP that Xen will use when entering guest kernel mode * from guest user mode. Subsequent calls to load_sp0() can * change this value.
*/
ctxt->kernel_ss = __KERNEL_DS;
ctxt->kernel_sp = task_top_of_stack(idle);
rc = cpu_initialize_context(cpu, idle); if (rc) return rc;
xen_pmu_init(cpu);
/* * Why is this a BUG? If the hypercall fails then everything can be * rolled back, no?
*/
BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_up, xen_vcpu_nr(cpu), NULL));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.