mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
um: remove copy_context_skas0
The kernel flushes the memory ranges anyway for CoW and does not assume that the userspace process has anything set up already. So, start with a fresh process for the new mm context. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Link: https://patch.msgid.link/20240703134536.1161108-8-benjamin@sipsolutions.net Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
7911b650a0
commit
a5d2cfe749
@ -285,7 +285,6 @@ void protect(struct mm_id *mm_idp, unsigned long addr,
|
||||
/* skas/process.c */
|
||||
extern int is_skas_winch(int pid, int fd, void *data);
|
||||
extern int start_userspace(unsigned long stub_stack);
|
||||
extern int copy_context_skas0(unsigned long stack, int pid);
|
||||
extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs);
|
||||
extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
|
||||
extern void switch_threads(jmp_buf *me, jmp_buf *you);
|
||||
|
@ -36,7 +36,6 @@ struct stub_syscall {
|
||||
|
||||
struct stub_data {
|
||||
unsigned long offset;
|
||||
int fd;
|
||||
long err, child_err;
|
||||
|
||||
int syscall_data_len;
|
||||
|
@ -3,16 +3,14 @@
|
||||
# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
#
|
||||
|
||||
obj-y := clone.o stub.o mmu.o process.o syscall.o uaccess.o
|
||||
obj-y := stub.o mmu.o process.o syscall.o uaccess.o
|
||||
|
||||
# clone.o and stub.o are in the stub, so it can't be built with profiling
|
||||
# stub.o is in the stub, so it can't be built with profiling
|
||||
# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
|
||||
# disable it
|
||||
|
||||
CFLAGS_clone.o := $(CFLAGS_NO_HARDENING)
|
||||
CFLAGS_stub.o := $(CFLAGS_NO_HARDENING)
|
||||
UNPROFILE_OBJS := clone.o stub.o
|
||||
|
||||
UNPROFILE_OBJS := stub.o
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
include $(srctree)/arch/um/scripts/Makefile.rules
|
||||
|
@ -1,50 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
|
||||
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <as-layout.h>
|
||||
#include <ptrace_user.h>
|
||||
#include <stub-data.h>
|
||||
#include <sysdep/stub.h>
|
||||
|
||||
/*
|
||||
* This is in a separate file because it needs to be compiled with any
|
||||
* extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
|
||||
*
|
||||
* Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize
|
||||
* on some systems.
|
||||
*/
|
||||
|
||||
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||
stub_clone_handler(void)
|
||||
{
|
||||
struct stub_data *data = get_stub_data();
|
||||
long err;
|
||||
|
||||
/* syscall data as a temporary stack area (bottom half). */
|
||||
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
||||
(unsigned long) data->syscall_data +
|
||||
sizeof(data->syscall_data) / 2 -
|
||||
sizeof(void *));
|
||||
if (err) {
|
||||
data->err = err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
|
||||
if (err) {
|
||||
data->child_err = err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
remap_stack_and_trap();
|
||||
|
||||
done:
|
||||
trap_myself();
|
||||
}
|
@ -21,8 +21,7 @@ static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
|
||||
|
||||
int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
{
|
||||
struct mm_context *from_mm = NULL;
|
||||
struct mm_context *to_mm = &mm->context;
|
||||
struct mm_id *new_id = &mm->context.id;
|
||||
unsigned long stack = 0;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
@ -30,27 +29,22 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
if (stack == 0)
|
||||
goto out;
|
||||
|
||||
to_mm->id.stack = stack;
|
||||
if (current->mm != NULL && current->mm != &init_mm)
|
||||
from_mm = ¤t->mm->context;
|
||||
new_id->stack = stack;
|
||||
|
||||
block_signals_trace();
|
||||
if (from_mm)
|
||||
to_mm->id.u.pid = copy_context_skas0(stack,
|
||||
from_mm->id.u.pid);
|
||||
else to_mm->id.u.pid = start_userspace(stack);
|
||||
new_id->u.pid = start_userspace(stack);
|
||||
unblock_signals_trace();
|
||||
|
||||
if (to_mm->id.u.pid < 0) {
|
||||
ret = to_mm->id.u.pid;
|
||||
if (new_id->u.pid < 0) {
|
||||
ret = new_id->u.pid;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
if (to_mm->id.stack != 0)
|
||||
free_pages(to_mm->id.stack, ilog2(STUB_DATA_PAGES));
|
||||
if (new_id->stack != 0)
|
||||
free_pages(new_id->stack, ilog2(STUB_DATA_PAGES));
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -464,114 +464,6 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long thread_regs[MAX_REG_NR];
|
||||
static unsigned long thread_fp_regs[FP_SIZE];
|
||||
|
||||
static int __init init_thread_regs(void)
|
||||
{
|
||||
get_safe_registers(thread_regs, thread_fp_regs);
|
||||
/* Set parent's instruction pointer to start of clone-stub */
|
||||
thread_regs[REGS_IP_INDEX] = STUB_CODE +
|
||||
(unsigned long) stub_clone_handler -
|
||||
(unsigned long) __syscall_stub_start;
|
||||
|
||||
/* syscall data as a temporary stack area (top half). */
|
||||
thread_regs[REGS_SP_INDEX] = STUB_DATA +
|
||||
offsetof(struct stub_data, syscall_data) +
|
||||
sizeof(((struct stub_data *) 0)->syscall_data) -
|
||||
sizeof(void *);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(init_thread_regs);
|
||||
|
||||
int copy_context_skas0(unsigned long new_stack, int pid)
|
||||
{
|
||||
int err;
|
||||
unsigned long current_stack = current_stub_stack();
|
||||
struct stub_data *data = (struct stub_data *) current_stack;
|
||||
struct stub_data *child_data = (struct stub_data *) new_stack;
|
||||
unsigned long long new_offset;
|
||||
int new_fd = phys_mapping(uml_to_phys((void *)new_stack), &new_offset);
|
||||
|
||||
/*
|
||||
* prepare offset and fd of child's stack as argument for parent's
|
||||
* and child's mmap2 calls
|
||||
*/
|
||||
*data = ((struct stub_data) {
|
||||
.offset = MMAP_OFFSET(new_offset),
|
||||
.fd = new_fd,
|
||||
.err = -ESRCH,
|
||||
.child_err = 0,
|
||||
});
|
||||
|
||||
*child_data = ((struct stub_data) {
|
||||
.child_err = -ESRCH,
|
||||
});
|
||||
|
||||
err = ptrace_setregs(pid, thread_regs);
|
||||
if (err < 0) {
|
||||
err = -errno;
|
||||
printk(UM_KERN_ERR "%s : PTRACE_SETREGS failed, pid = %d, errno = %d\n",
|
||||
__func__, pid, -err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = put_fp_registers(pid, thread_fp_regs);
|
||||
if (err < 0) {
|
||||
printk(UM_KERN_ERR "%s : put_fp_registers failed, pid = %d, err = %d\n",
|
||||
__func__, pid, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait, until parent has finished its work: read child's pid from
|
||||
* parent's stack, and check, if bad result.
|
||||
*/
|
||||
err = ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
if (err) {
|
||||
err = -errno;
|
||||
printk(UM_KERN_ERR "Failed to continue new process, pid = %d, errno = %d\n",
|
||||
pid, errno);
|
||||
return err;
|
||||
}
|
||||
|
||||
wait_stub_done(pid);
|
||||
|
||||
pid = data->err;
|
||||
if (pid < 0) {
|
||||
printk(UM_KERN_ERR "%s - stub-parent reports error %d\n",
|
||||
__func__, -pid);
|
||||
return pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait, until child has finished too: read child's result from
|
||||
* child's stack and check it.
|
||||
*/
|
||||
wait_stub_done(pid);
|
||||
if (child_data->child_err != STUB_DATA) {
|
||||
printk(UM_KERN_ERR "%s - stub-child %d reports error %ld\n",
|
||||
__func__, pid, data->child_err);
|
||||
err = data->child_err;
|
||||
goto out_kill;
|
||||
}
|
||||
|
||||
if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
|
||||
(void *)PTRACE_O_TRACESYSGOOD) < 0) {
|
||||
err = -errno;
|
||||
printk(UM_KERN_ERR "%s : PTRACE_SETOPTIONS failed, errno = %d\n",
|
||||
__func__, errno);
|
||||
goto out_kill;
|
||||
}
|
||||
|
||||
return pid;
|
||||
|
||||
out_kill:
|
||||
os_kill_ptraced_process(pid, 1);
|
||||
return err;
|
||||
}
|
||||
|
||||
void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
|
||||
{
|
||||
(*buf)[0].JB_IP = (unsigned long) handler;
|
||||
|
@ -13,4 +13,3 @@
|
||||
|
||||
extern void stub_segv_handler(int, siginfo_t *, void *);
|
||||
extern void stub_syscall_handler(void);
|
||||
extern void stub_clone_handler(void);
|
||||
|
@ -107,30 +107,6 @@ static __always_inline void trap_myself(void)
|
||||
__asm("int3");
|
||||
}
|
||||
|
||||
static __always_inline void remap_stack_and_trap(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"movl %%esp,%%ebx ;"
|
||||
"andl %0,%%ebx ;"
|
||||
"movl %1,%%eax ;"
|
||||
"movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;"
|
||||
"movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;"
|
||||
"int $0x80 ;"
|
||||
"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
|
||||
"int $3"
|
||||
: :
|
||||
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
|
||||
"g" (STUB_MMAP_NR),
|
||||
"g" (offsetof(struct stub_data, fd)),
|
||||
"g" (offsetof(struct stub_data, offset)),
|
||||
"g" (offsetof(struct stub_data, child_err)),
|
||||
"c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
|
||||
"d" (PROT_READ | PROT_WRITE),
|
||||
"S" (MAP_FIXED | MAP_SHARED)
|
||||
:
|
||||
"memory");
|
||||
}
|
||||
|
||||
static __always_inline void *get_stub_data(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
@ -101,32 +101,6 @@ static __always_inline void trap_myself(void)
|
||||
__asm("int3");
|
||||
}
|
||||
|
||||
static __always_inline void remap_stack_and_trap(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"movq %0,%%rax ;"
|
||||
"movq %%rsp,%%rdi ;"
|
||||
"andq %1,%%rdi ;"
|
||||
"movq %2,%%r10 ;"
|
||||
"movq %%rdi,%%r8 ; addq %3,%%r8 ; movq (%%r8),%%r8 ;"
|
||||
"movq %%rdi,%%r9 ; addq %4,%%r9 ; movq (%%r9),%%r9 ;"
|
||||
__syscall ";"
|
||||
"movq %%rsp,%%rdi ; andq %1,%%rdi ;"
|
||||
"addq %5,%%rdi ; movq %%rax, (%%rdi) ;"
|
||||
"int3"
|
||||
: :
|
||||
"g" (STUB_MMAP_NR),
|
||||
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
|
||||
"g" (MAP_FIXED | MAP_SHARED),
|
||||
"g" (offsetof(struct stub_data, fd)),
|
||||
"g" (offsetof(struct stub_data, offset)),
|
||||
"g" (offsetof(struct stub_data, child_err)),
|
||||
"S" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
|
||||
"d" (PROT_READ | PROT_WRITE)
|
||||
:
|
||||
__syscall_clobber, "r10", "r8", "r9");
|
||||
}
|
||||
|
||||
static __always_inline void *get_stub_data(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
Loading…
Reference in New Issue
Block a user