Commit 3c83170d authored by Benjamin Berg's avatar Benjamin Berg Committed by Johannes Berg
Browse files

um: Delay flushing syscalls until the thread is restarted



As running the syscalls is expensive due to context switches, we should
do so as late as possible in case more syscalls need to be queued later
on. This will also benefit a later move to a SECCOMP enabled userspace
as in that case the need for extra context switches is removed entirely.

Signed-off-by: default avatarBenjamin Berg <benjamin@sipsolutions.net>
Link: https://patch.msgid.link/20240703134536.1161108-9-benjamin@sipsolutions.net


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a5d2cfe7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -195,6 +195,9 @@ extern void get_host_cpu_features(
/* mem.c */
extern int create_mem_file(unsigned long long len);

/* tlb.c */
extern void report_enomem(void);

/* process.c */
extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid);
@@ -274,6 +277,7 @@ extern long long os_nsecs(void);
/* skas/mem.c */
int syscall_stub_flush(struct mm_id *mm_idp);
struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp);
void syscall_stub_dump_error(struct mm_id *mm_idp);

void map(struct mm_id *mm_idp, unsigned long virt,
	 unsigned long len, int prot, int phys_fd,
+0 −1
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@ struct mm_id {
		int pid;
	} u;
	unsigned long stack;
	int kill;
	int syscall_data_len;
};

+1 −0
Original line number Diff line number Diff line
@@ -15,5 +15,6 @@ extern void new_thread_handler(void);
extern void handle_syscall(struct uml_pt_regs *regs);
extern long execute_syscall_skas(void *r);
extern unsigned long current_stub_stack(void);
extern struct mm_id *current_mm_id(void);

#endif
+8 −0
Original line number Diff line number Diff line
@@ -50,3 +50,11 @@ unsigned long current_stub_stack(void)

	return current->mm->context.id.stack;
}

struct mm_id *current_mm_id(void)
{
	if (current->mm == NULL)
		return NULL;

	return &current->mm->context.id;
}
+2 −19
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ struct host_vm_change {
	   .index	= 0, \
	   .force	= force })

static void report_enomem(void)
void report_enomem(void)
{
	printk(KERN_ERR "UML ran out of memory on the host side! "
			"This can happen due to a memory limitation or "
@@ -338,15 +338,6 @@ static void fix_range_common(struct mm_struct *mm, unsigned long start_addr,

	if (!ret)
		ret = do_ops(&hvc, hvc.index, 1);

	/* This is not an else because ret is modified above */
	if (ret) {
		struct mm_id *mm_idp = &current->mm->context.id;

		printk(KERN_ERR "fix_range_common: failed, killing current "
		       "process: %d\n", task_tgid_vnr(current));
		mm_idp->kill = 1;
	}
}

static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
@@ -461,7 +452,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
	pmd_t *pmd;
	pte_t *pte;
	struct mm_struct *mm = vma->vm_mm;
	int r, w, x, prot, err = 0;
	int r, w, x, prot;
	struct mm_id *mm_id;

	address &= PAGE_MASK;
@@ -509,14 +500,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
	} else if (pte_newprot(*pte))
		protect(mm_id, address, PAGE_SIZE, prot);

	err = syscall_stub_flush(mm_id);
	if (err) {
		if (err == -ENOMEM)
			report_enomem();

		goto kill;
	}

	*pte = pte_mkuptodate(*pte);

	return;
Loading