mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 06:41:39 -04:00
Add initial symmetric multi-processing (SMP) support to UML. With this support enabled, users can tell UML to start multiple virtual processors, each represented as a separate host thread. In UML, kthreads and normal threads (when running in kernel mode) can be scheduled and executed simultaneously on different virtual processors. However, the userspace code of normal threads still runs within their respective single-threaded stubs. That is, SMP support is currently available both within the kernel and across different processes, but still remains limited within threads of the same process in userspace. Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com> Link: https://patch.msgid.link/20251027001815.1666872-6-tiwei.bie@linux.dev Signed-off-by: Johannes Berg <johannes.berg@intel.com>
80 lines
1.5 KiB
C
80 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/sched/mm.h>
|
|
#include <linux/sched/task_stack.h>
|
|
#include <linux/sched/task.h>
|
|
#include <linux/smp-internal.h>
|
|
|
|
#include <asm/tlbflush.h>
|
|
|
|
#include <as-layout.h>
|
|
#include <kern.h>
|
|
#include <os.h>
|
|
#include <skas.h>
|
|
#include <kern_util.h>
|
|
|
|
extern void start_kernel(void);
|
|
|
|
static int __init start_kernel_proc(void *unused)
|
|
{
|
|
block_signals_trace();
|
|
|
|
start_kernel();
|
|
return 0;
|
|
}
|
|
|
|
char cpu_irqstacks[NR_CPUS][THREAD_SIZE] __aligned(THREAD_SIZE);
|
|
|
|
int __init start_uml(void)
|
|
{
|
|
stack_protections((unsigned long) &cpu_irqstacks[0]);
|
|
set_sigstack(cpu_irqstacks[0], THREAD_SIZE);
|
|
|
|
init_new_thread_signals();
|
|
|
|
init_task.thread.request.thread.proc = start_kernel_proc;
|
|
init_task.thread.request.thread.arg = NULL;
|
|
return start_idle_thread(task_stack_page(&init_task),
|
|
&init_task.thread.switch_buf);
|
|
}
|
|
|
|
unsigned long current_stub_stack(void)
|
|
{
|
|
if (current->mm == NULL)
|
|
return 0;
|
|
|
|
return current->mm->context.id.stack;
|
|
}
|
|
|
|
struct mm_id *current_mm_id(void)
|
|
{
|
|
if (current->mm == NULL)
|
|
return NULL;
|
|
|
|
return ¤t->mm->context.id;
|
|
}
|
|
|
|
void current_mm_sync(void)
|
|
{
|
|
if (current->mm == NULL)
|
|
return;
|
|
|
|
um_tlb_sync(current->mm);
|
|
}
|
|
|
|
static DEFINE_SPINLOCK(initial_jmpbuf_spinlock);
|
|
|
|
void initial_jmpbuf_lock(void)
|
|
{
|
|
spin_lock_irq(&initial_jmpbuf_spinlock);
|
|
}
|
|
|
|
void initial_jmpbuf_unlock(void)
|
|
{
|
|
spin_unlock_irq(&initial_jmpbuf_spinlock);
|
|
}
|