Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1707779/?format=api
{ "id": 1707779, "url": "http://patchwork.ozlabs.org/api/patches/1707779/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-um/patch/20221122100759.208290-18-benjamin@sipsolutions.net/", "project": { "id": 60, "url": "http://patchwork.ozlabs.org/api/projects/60/?format=api", "name": "User-mode Linux Development", "link_name": "linux-um", "list_id": "linux-um.lists.infradead.org", "list_email": "linux-um@lists.infradead.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20221122100759.208290-18-benjamin@sipsolutions.net>", "list_archive_url": null, "date": "2022-11-22T10:07:48", "name": "[v2,17/28] um: Rework syscall handling", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": false, "hash": "55392985ab66e407a9b27e52a54863ef4fe3e9a1", "submitter": { "id": 67525, "url": "http://patchwork.ozlabs.org/api/people/67525/?format=api", "name": "Benjamin Berg", "email": "benjamin@sipsolutions.net" }, "delegate": { "id": 54851, "url": "http://patchwork.ozlabs.org/api/users/54851/?format=api", "username": "rw", "first_name": "Richard", "last_name": "Weinberger", "email": "richard@nod.at" }, "mbox": "http://patchwork.ozlabs.org/project/linux-um/patch/20221122100759.208290-18-benjamin@sipsolutions.net/mbox/", "series": [ { "id": 329466, "url": "http://patchwork.ozlabs.org/api/series/329466/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-um/list/?series=329466", "date": "2022-11-22T10:07:37", "name": "Implement SECCOMP based userland", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/329466/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1707779/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1707779/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=<UNKNOWN>)", "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=cp55DE8g;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256\n header.s=desiato.20200630 header.b=MgPrzW2N;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=sipsolutions.net header.i=@sipsolutions.net\n header.a=rsa-sha256 header.s=mail header.b=MYZJFx5J;\n\tdkim-atps=neutral" ], "Received": [ "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4NGgRq3MFKz23nl\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 22 Nov 2022 21:27:19 +1100 (AEDT)", "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))\n\tid 1oxQUd-007o5c-Og; Tue, 22 Nov 2022 10:27:07 +0000", "from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05])\n\tby bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))\n\tid 1oxQTM-007nKg-Rw\n\tfor linux-um@bombadil.infradead.org; Tue, 22 Nov 2022 10:25:49 +0000", "from s3.sipsolutions.net ([2a01:4f8:191:4433::2]\n helo=sipsolutions.net)\n\tby desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))\n\tid 1oxQF1-003P1p-1J\n\tfor linux-um@lists.infradead.org; Tue, 22 Nov 2022 10:11:04 +0000", "by sipsolutions.net with esmtpsa\n (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)\n\t(Exim 4.96)\n\t(envelope-from <benjamin@sipsolutions.net>)\n\tid 1oxQEq-006IGn-1B;\n\tTue, 22 Nov 2022 11:10:48 +0100" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=XL/gNVrLjqwbYNG+Xs8wF90+JvthMwjuy4MC0G5FleY=; b=cp55DE8ggUc3KY\n\tAwPTFQkBRjfkbkoeiHhJrNut6gocXuWEvUdkwj9wQEmM9feWeIJQJ1yMvszbbJF711saEWqam0mtP\n\tls3ruZS9u+RjfFYXk+4spzdHNbjBpcXadGgzBH/09xDHJXd3lDhXeLb6vVm3ViEA1FjO1CiYkxDcR\n\tAcRGpevx3tK/AZKA4XBPmWkuRGY/LXSVQfWZZwB4joWVEfoKdFItFVMI+hWlwO13vf/MwhDuf8fjf\n\tjxPvdsPO4j1AWMUFLVqrheCHZR0eig6Jmt5QZsj4hEaMQVCTlUfuOOdLkPOJZy/ld6nMEAc40OORY\n\ts3G91YSsRzVVduMgYdaQ==;", "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version\n\t:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:\n\tContent-Type:Content-ID:Content-Description;\n\tbh=3lJJDAv/JxGQR41iia2ptwBV555w9SpozAvbIjZ9Q2o=; b=MgPrzW2NUPH4V++2PDzQbdh6kc\n\tp80tkP1xf9mHRXLUhqJKP6tIZBnwT8oKIa8a76JZ1ukQW9XimR4H5oqDR50jVqrOioicIVnodUZnM\n\tdYqRteS74ULDAFxmNzWfwmA1fDN8MCXMA+1xfNE2YlpYmPc2KZQPX9q0V9ebyG7WE2ku+OErz6SWD\n\tLxNmS05kpeLpR1h6PgTEmTSeKw3vskGbrnDXesUeiRg3QShnvbM3fe7oO9OFdheFAlb5AWmxT683j\n\t4wxQWSDb6UTowzY5MoVtEtcjPhOIVeAMNqGLdMZSh3pKQnYmIjp04ppYxdGlTh4fzRHvL/0U8GPJ0\n\tuFMX1w1Q==;", "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version:\n\tReferences:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Content-Type:Sender\n\t:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To:\n\tResent-Cc:Resent-Message-ID; bh=3lJJDAv/JxGQR41iia2ptwBV555w9SpozAvbIjZ9Q2o=;\n\tt=1669111858; x=1670321458; b=MYZJFx5JcNlqMrybRZ8ilRCduadtbmu0WvhUySuV0fXy0E0\n\tA8gdL47kTDtb10er949iHkBYsESvEOdUELldAoKUORNMhCsj4SgnLBbyyvTLISEFaz80Ud5es0M9J\n\t9IH3HZ38QNGQJZ5667gyQvGGHdRzWQsmzjy6VZMxeHtjW/KP1hdh5hpgHGhDowI+/98yUOWPXSmE1\n\tY1VkBFE5di2vuZtvQxzlJccg9zcfafmqO+8k0KUI0A67eJNzb+LynQHHOlmqme208AxAuXPXpbi2j\n\t/RO+wk3uC8j3umeMxZU140RvnJI1qYuhpkVobBtab4f28AiUoPvlpyXc35stE7Hg==;" ], "From": "benjamin@sipsolutions.net", "To": "linux-um@lists.infradead.org", "Cc": "Benjamin Berg <benjamin@sipsolutions.net>", "Subject": "[PATCH v2 17/28] um: Rework syscall handling", "Date": "Tue, 22 Nov 2022 11:07:48 +0100", "Message-Id": "<20221122100759.208290-18-benjamin@sipsolutions.net>", "X-Mailer": "git-send-email 2.38.1", "In-Reply-To": "<20221122100759.208290-1-benjamin@sipsolutions.net>", "References": "<20221122100759.208290-1-benjamin@sipsolutions.net>", "MIME-Version": "1.0", "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ", "X-CRM114-CacheID": "sfid-20221122_101059_599220_8BBBA5BF ", "X-CRM114-Status": "GOOD ( 33.39 )", "X-Spam-Score": "-0.2 (/)", "X-Spam-Report": "Spam detection software,\n running on the system \"desiato.infradead.org\",\n has NOT identified this incoming email as spam. The original\n message has been attached to this so you can view it or label\n similar future email. If you have any questions, see\n the administrator of that system for details.\n Content preview: From: Benjamin Berg <benjamin@sipsolutions.net> Rework\n syscall\n handling to be platform independent. Also create a clean split between\n queueing\n of syscalls and flushing them out, removing the need to keep state in the\n code that triggers the syscalls [...]\n Content analysis details: (-0.2 points, 5.0 required)\n pts rule name description\n ---- ----------------------\n --------------------------------------------------\n -0.0 SPF_PASS SPF: sender matches SPF record\n -0.0 SPF_HELO_PASS SPF: HELO matches SPF record\n -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from\n author's domain\n -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from\n envelope-from domain\n 0.1 DKIM_SIGNED Message has a DKIM or DK signature,\n not necessarily\n valid\n -0.1 DKIM_VALID Message has at least one valid DKIM or DK\n signature", "X-BeenThere": "linux-um@lists.infradead.org", "X-Mailman-Version": "2.1.34", "Precedence": "list", "List-Id": "<linux-um.lists.infradead.org>", "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/linux-um>,\n <mailto:linux-um-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/linux-um/>", "List-Post": "<mailto:linux-um@lists.infradead.org>", "List-Help": "<mailto:linux-um-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/linux-um>,\n <mailto:linux-um-request@lists.infradead.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "\"linux-um\" <linux-um-bounces@lists.infradead.org>", "Errors-To": "linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org" }, "content": "From: Benjamin Berg <benjamin@sipsolutions.net>\n\nRework syscall handling to be platform independent. Also create a clean\nsplit between queueing of syscalls and flushing them out, removing the\nneed to keep state in the code that triggers the syscalls.\n\nThe code adds syscall_data_len to the global mm_id structure. This will\nbe used later to allow surrounding code to track whether syscalls still\nneed to run and if errors occurred.\n\nSigned-off-by: Benjamin Berg <benjamin@sipsolutions.net>\n---\n arch/um/include/shared/os.h | 24 ++-\n arch/um/include/shared/skas/mm_id.h | 1 +\n arch/um/include/shared/skas/stub-data.h | 14 +-\n arch/um/include/shared/user.h | 8 +\n arch/um/kernel/exec.c | 10 +-\n arch/um/kernel/skas/Makefile | 4 +-\n arch/um/kernel/skas/clone.c | 2 +-\n arch/um/kernel/skas/stub.c | 47 +++++\n arch/um/kernel/tlb.c | 42 ++---\n arch/um/os-Linux/skas/mem.c | 241 +++++++++++++-----------\n arch/um/os-Linux/skas/process.c | 4 +-\n arch/x86/um/Makefile | 2 +-\n arch/x86/um/ldt.c | 47 ++---\n arch/x86/um/shared/sysdep/stub.h | 1 +\n arch/x86/um/stub_32.S | 56 ------\n arch/x86/um/stub_64.S | 50 -----\n 16 files changed, 259 insertions(+), 294 deletions(-)\n create mode 100644 arch/um/kernel/skas/stub.c\n delete mode 100644 arch/x86/um/stub_32.S\n delete mode 100644 arch/x86/um/stub_64.S", "diff": "diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h\nindex aff8906304ea..22ea525165b7 100644\n--- a/arch/um/include/shared/os.h\n+++ b/arch/um/include/shared/os.h\n@@ -268,19 +268,17 @@ extern long long os_persistent_clock_emulation(void);\n extern long long os_nsecs(void);\n \n /* skas/mem.c */\n-extern long run_syscall_stub(struct mm_id * mm_idp,\n-\t\t\t int syscall, unsigned long *args, long expected,\n-\t\t\t void **addr, int done);\n-extern long syscall_stub_data(struct mm_id * mm_idp,\n-\t\t\t unsigned long *data, int data_count,\n-\t\t\t void **addr, void **stub_addr);\n-extern int map(struct mm_id * mm_idp, unsigned long virt,\n-\t unsigned long len, int prot, int phys_fd,\n-\t unsigned long long offset, int done, void **data);\n-extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,\n-\t\t int done, void **data);\n-extern int protect(struct mm_id * mm_idp, unsigned long addr,\n-\t\t unsigned long len, unsigned int prot, int done, void **data);\n+int syscall_stub_flush(struct mm_id *mm_idp);\n+struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp,\n+\t\t\t\t\tunsigned long data_len,\n+\t\t\t\t\tunsigned long *data_addr);\n+\n+void map(struct mm_id *mm_idp, unsigned long virt,\n+\t unsigned long len, int prot, int phys_fd,\n+\t unsigned long long offset);\n+void unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len);\n+void protect(struct mm_id *mm_idp, unsigned long addr,\n+\t unsigned long len, unsigned int prot);\n \n /* skas/process.c */\n extern int is_skas_winch(int pid, int fd, void *data);\ndiff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h\nindex e82e203f5f41..bcb951719b51 100644\n--- a/arch/um/include/shared/skas/mm_id.h\n+++ b/arch/um/include/shared/skas/mm_id.h\n@@ -13,6 +13,7 @@ struct mm_id {\n \t} u;\n \tunsigned long stack;\n \tint kill;\n+\tint syscall_data_len;\n };\n \n #endif\ndiff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h\nindex 3281809a7272..821c1e98c051 100644\n--- a/arch/um/include/shared/skas/stub-data.h\n+++ b/arch/um/include/shared/skas/stub-data.h\n@@ -11,11 +11,23 @@\n #include <linux/compiler_types.h>\n #include <as-layout.h>\n \n+#define STUB_NEXT_SYSCALL(s) \\\n+\t((struct stub_syscall *) (((unsigned long) s) + (s)->cmd_len))\n+\n+struct stub_syscall {\n+\tlong syscall;\n+\tint cmd_len;\n+\tlong expected_result;\n+\tlong arg[6];\n+\tlong data[];\n+};\n+\n struct stub_data {\n \tunsigned long offset;\n \tint fd;\n-\tlong parent_err, child_err;\n+\tlong err, child_err;\n \n+\tint syscall_data_len;\n \t/* 128 leaves enough room for additional fields in the struct */\n \tunsigned char syscall_data[UM_KERN_PAGE_SIZE - 128] __aligned(16);\n \ndiff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h\nindex bda66e5a9d4e..ee9e5ac45d02 100644\n--- a/arch/um/include/shared/user.h\n+++ b/arch/um/include/shared/user.h\n@@ -42,11 +42,19 @@ extern void panic(const char *fmt, ...)\n #define printk(...) _printk(__VA_ARGS__)\n extern int _printk(const char *fmt, ...)\n \t__attribute__ ((format (printf, 1, 2)));\n+extern void print_hex_dump(const char *level, const char *prefix_str,\n+\t\t\t int prefix_type, int rowsize, int groupsize,\n+\t\t\t const void *buf, size_t len, _Bool ascii);\n #else\n static inline int printk(const char *fmt, ...)\n {\n \treturn 0;\n }\n+static inline void print_hex_dump(const char *level, const char *prefix_str,\n+\t\t\t\t int prefix_type, int rowsize, int groupsize,\n+\t\t\t\t const void *buf, size_t len, _Bool ascii)\n+{\n+}\n #endif\n \n extern int in_aton(char *str);\ndiff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c\nindex 827a0d3fa589..5c8836b012e9 100644\n--- a/arch/um/kernel/exec.c\n+++ b/arch/um/kernel/exec.c\n@@ -22,15 +22,11 @@\n \n void flush_thread(void)\n {\n-\tvoid *data = NULL;\n-\tint ret;\n-\n \tarch_flush_thread(¤t->thread.arch);\n \n-\tret = unmap(¤t->mm->context.id, 0, TASK_SIZE, 1, &data);\n-\tif (ret) {\n-\t\tprintk(KERN_ERR \"%s - clearing address space failed, err = %d\\n\",\n-\t\t __func__, ret);\n+\tunmap(¤t->mm->context.id, 0, TASK_SIZE);\n+\tif (syscall_stub_flush(¤t->mm->context.id) < 0) {\n+\t\tprintk(KERN_ERR \"%s - clearing address space failed\", __func__);\n \t\tforce_sig(SIGKILL);\n \t}\n \tget_safe_registers(current_pt_regs()->regs.gp,\ndiff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile\nindex f3d494a4fd9b..a863638cc1f0 100644\n--- a/arch/um/kernel/skas/Makefile\n+++ b/arch/um/kernel/skas/Makefile\n@@ -3,14 +3,14 @@\n # Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)\n #\n \n-obj-y := clone.o mmu.o process.o syscall.o uaccess.o\n+obj-y := clone.o stub.o mmu.o process.o syscall.o uaccess.o\n \n # clone.o is in the stub, so it can't be built with profiling\n # GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->\n # disable it\n \n CFLAGS_clone.o := $(CFLAGS_NO_HARDENING)\n-UNPROFILE_OBJS := clone.o\n+UNPROFILE_OBJS := clone.o stub.o\n \n KCOV_INSTRUMENT := n\n \ndiff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c\nindex a631566e4a20..8b6ea9c00133 100644\n--- a/arch/um/kernel/skas/clone.c\n+++ b/arch/um/kernel/skas/clone.c\n@@ -33,7 +33,7 @@ stub_clone_handler(void)\n \t\t\t\t\t sizeof(data->syscall_data) / 2 -\n \t\t\t\t\t sizeof(void *));\n \tif (err) {\n-\t\tdata->parent_err = err;\n+\t\tdata->err = err;\n \t\tgoto done;\n \t}\n \ndiff --git a/arch/um/kernel/skas/stub.c b/arch/um/kernel/skas/stub.c\nnew file mode 100644\nindex 000000000000..0a13f5d21d08\n--- /dev/null\n+++ b/arch/um/kernel/skas/stub.c\n@@ -0,0 +1,47 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (C) 2021 Benjamin Berg <benjamin@sipsolutions.net>\n+ */\n+\n+#include <sysdep/stub.h>\n+\n+static __always_inline int syscall_handler(struct stub_data *d)\n+{\n+\tstruct stub_syscall *sc;\n+\tlong ret;\n+\n+\tfor (sc = (void *)&d->syscall_data;\n+\t (unsigned long)sc - (unsigned long)d->syscall_data < d->syscall_data_len;\n+\t sc = STUB_NEXT_SYSCALL(sc)) {\n+\t\tret = stub_syscall6(sc->syscall,\n+\t\t\t\t sc->arg[0], sc->arg[1], sc->arg[2],\n+\t\t\t\t sc->arg[3], sc->arg[4], sc->arg[5]);\n+\n+\t\t/*\n+\t\t * If there was an error, then set d->err and set\n+\t\t * d->syscall_data_len to point to the failed syscall.\n+\t\t */\n+\t\tif (ret != sc->expected_result) {\n+\t\t\td->err = ret;\n+\t\t\td->syscall_data_len = (unsigned long)sc -\n+\t\t\t\t\t (unsigned long)d->syscall_data;\n+\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\td->err = 0;\n+\td->syscall_data_len = 0;\n+\n+\treturn 0;\n+}\n+\n+void __section(\".__syscall_stub\")\n+stub_syscall_handler(void)\n+{\n+\tstruct stub_data *d = get_stub_page();\n+\n+\tsyscall_handler(d);\n+\n+\ttrap_myself();\n+}\ndiff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c\nindex 3c709e6146dc..c15cac380fcd 100644\n--- a/arch/um/kernel/tlb.c\n+++ b/arch/um/kernel/tlb.c\n@@ -70,21 +70,19 @@ static int do_ops(struct host_vm_change *hvc, int end,\n \t\tswitch (op->type) {\n \t\tcase MMAP:\n \t\t\tif (hvc->userspace)\n-\t\t\t\tret = map(&hvc->mm->context.id, op->u.mmap.addr,\n-\t\t\t\t\t op->u.mmap.len, op->u.mmap.prot,\n-\t\t\t\t\t op->u.mmap.fd,\n-\t\t\t\t\t op->u.mmap.offset, finished,\n-\t\t\t\t\t &hvc->data);\n+\t\t\t\tmap(&hvc->mm->context.id, op->u.mmap.addr,\n+\t\t\t\t op->u.mmap.len, op->u.mmap.prot,\n+\t\t\t\t op->u.mmap.fd,\n+\t\t\t\t op->u.mmap.offset);\n \t\t\telse\n \t\t\t\tmap_memory(op->u.mmap.addr, op->u.mmap.offset,\n \t\t\t\t\t op->u.mmap.len, 1, 1, 1);\n \t\t\tbreak;\n \t\tcase MUNMAP:\n \t\t\tif (hvc->userspace)\n-\t\t\t\tret = unmap(&hvc->mm->context.id,\n-\t\t\t\t\t op->u.munmap.addr,\n-\t\t\t\t\t op->u.munmap.len, finished,\n-\t\t\t\t\t &hvc->data);\n+\t\t\t\tunmap(&hvc->mm->context.id,\n+\t\t\t\t op->u.munmap.addr,\n+\t\t\t\t op->u.munmap.len);\n \t\t\telse\n \t\t\t\tret = os_unmap_memory(\n \t\t\t\t\t(void *) op->u.munmap.addr,\n@@ -93,11 +91,10 @@ static int do_ops(struct host_vm_change *hvc, int end,\n \t\t\tbreak;\n \t\tcase MPROTECT:\n \t\t\tif (hvc->userspace)\n-\t\t\t\tret = protect(&hvc->mm->context.id,\n-\t\t\t\t\t op->u.mprotect.addr,\n-\t\t\t\t\t op->u.mprotect.len,\n-\t\t\t\t\t op->u.mprotect.prot,\n-\t\t\t\t\t finished, &hvc->data);\n+\t\t\t\tprotect(&hvc->mm->context.id,\n+\t\t\t\t\top->u.mprotect.addr,\n+\t\t\t\t\top->u.mprotect.len,\n+\t\t\t\t\top->u.mprotect.prot);\n \t\t\telse\n \t\t\t\tret = os_protect_memory(\n \t\t\t\t\t(void *) op->u.mprotect.addr,\n@@ -112,6 +109,9 @@ static int do_ops(struct host_vm_change *hvc, int end,\n \t\t}\n \t}\n \n+\tif (hvc->userspace && finished)\n+\t\tret = syscall_stub_flush(&hvc->mm->context.id);\n+\n \tif (ret == -ENOMEM)\n \t\treport_enomem();\n \n@@ -460,7 +460,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)\n \tpmd_t *pmd;\n \tpte_t *pte;\n \tstruct mm_struct *mm = vma->vm_mm;\n-\tvoid *flush = NULL;\n \tint r, w, x, prot, err = 0;\n \tstruct mm_id *mm_id;\n \n@@ -503,14 +502,13 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)\n \t\t\tint fd;\n \n \t\t\tfd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);\n-\t\t\terr = map(mm_id, address, PAGE_SIZE, prot, fd, offset,\n-\t\t\t\t 1, &flush);\n-\t\t}\n-\t\telse err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);\n-\t}\n-\telse if (pte_newprot(*pte))\n-\t\terr = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);\n+\t\t\tmap(mm_id, address, PAGE_SIZE, prot, fd, offset);\n+\t\t} else\n+\t\t\tunmap(mm_id, address, PAGE_SIZE);\n+\t} else if (pte_newprot(*pte))\n+\t\tprotect(mm_id, address, PAGE_SIZE, prot);\n \n+\terr = syscall_stub_flush(mm_id);\n \tif (err) {\n \t\tif (err == -ENOMEM)\n \t\t\treport_enomem();\ndiff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c\nindex 953fb10f3f93..28e50349ab91 100644\n--- a/arch/um/os-Linux/skas/mem.c\n+++ b/arch/um/os-Linux/skas/mem.c\n@@ -1,5 +1,6 @@\n // SPDX-License-Identifier: GPL-2.0\n /*\n+ * Copyright (C) 2021 Benjamin Berg <benjamin@sipsolutions.net>\n * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)\n */\n \n@@ -18,11 +19,11 @@\n #include <sysdep/ptrace.h>\n #include <sysdep/stub.h>\n \n-extern char batch_syscall_stub[], __syscall_stub_start[];\n+extern char __syscall_stub_start[];\n \n extern void wait_stub_done(int pid);\n \n-static inline unsigned long *check_init_stack(struct mm_id * mm_idp,\n+static inline unsigned long *check_init_stack(struct mm_id *mm_idp,\n \t\t\t\t\t unsigned long *stack)\n {\n \tif (stack == NULL) {\n@@ -37,22 +38,24 @@ static unsigned long syscall_regs[MAX_REG_NR];\n static int __init init_syscall_regs(void)\n {\n \tget_safe_registers(syscall_regs, NULL);\n+\n \tsyscall_regs[REGS_IP_INDEX] = STUB_CODE +\n-\t\t((unsigned long) batch_syscall_stub -\n+\t\t((unsigned long) stub_syscall_handler -\n \t\t (unsigned long) __syscall_stub_start);\n-\tsyscall_regs[REGS_SP_INDEX] = STUB_DATA;\n+\tsyscall_regs[REGS_SP_INDEX] = STUB_DATA +\n+\t\toffsetof(struct stub_data, sigstack) +\n+\t\tsizeof(((struct stub_data *) 0)->sigstack) -\n+\t\tsizeof(void *);\n \n \treturn 0;\n }\n \n __initcall(init_syscall_regs);\n \n-static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)\n+static inline long do_syscall_stub(struct mm_id *mm_idp)\n {\n+\tstruct stub_data *proc_data = (void *)mm_idp->stack;\n \tint n, i;\n-\tlong ret, offset;\n-\tunsigned long * data;\n-\tunsigned long * syscall;\n \tint err, pid = mm_idp->u.pid;\n \n \tn = ptrace_setregs(pid, syscall_regs);\n@@ -64,6 +67,9 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)\n \t\t __func__, -n);\n \t}\n \n+\t/* Inform process how much we have filled in. */\n+\tproc_data->syscall_data_len = mm_idp->syscall_data_len;\n+\n \terr = ptrace(PTRACE_CONT, pid, 0, 0);\n \tif (err)\n \t\tpanic(\"Failed to continue stub, pid = %d, errno = %d\\n\", pid,\n@@ -72,135 +78,148 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)\n \twait_stub_done(pid);\n \n \t/*\n-\t * When the stub stops, we find the following values on the\n-\t * beginning of the stack:\n-\t * (long )return_value\n-\t * (long )offset to failed sycall-data (0, if no error)\n+\t * proc_data->err will be non-zero if there was an (unexpected) error.\n+\t * In that case, syscall_data_len points to the last executed syscall,\n+\t * otherwise it will be zero (but we do not need to rely on that).\n \t */\n-\tret = *((unsigned long *) mm_idp->stack);\n-\toffset = *((unsigned long *) mm_idp->stack + 1);\n-\tif (offset) {\n-\t\tdata = (unsigned long *)(mm_idp->stack + offset - STUB_DATA);\n-\t\tprintk(UM_KERN_ERR \"%s : ret = %ld, offset = %ld, data = %p\\n\",\n-\t\t __func__, ret, offset, data);\n-\t\tsyscall = (unsigned long *)((unsigned long)data + data[0]);\n-\t\tprintk(UM_KERN_ERR \"%s: syscall %ld failed, return value = 0x%lx, expected return value = 0x%lx\\n\",\n-\t\t __func__, syscall[0], ret, syscall[7]);\n+\tif (proc_data->err) {\n+\t\tstruct stub_syscall *sc;\n+\n+\t\tif (proc_data->syscall_data_len < 0 ||\n+\t\t proc_data->syscall_data_len > (long) mm_idp->syscall_data_len - sizeof(*sc))\n+\t\t\tpanic(\"Syscall data was corrupted by stub (len is: %d, expected maximum: %d)!\",\n+\t\t\t proc_data->syscall_data_len,\n+\t\t\t mm_idp->syscall_data_len);\n+\n+\t\tsc = (void *) (((unsigned long) &proc_data->syscall_data) +\n+\t\t\t proc_data->syscall_data_len);\n+\n+\t\tprintk(UM_KERN_ERR \"%s : length = %d, last offset = %d\",\n+\t\t __func__, mm_idp->syscall_data_len,\n+\t\t proc_data->syscall_data_len);\n+\t\tprintk(UM_KERN_ERR \"%s : syscall %ld failed, return value = 0x%lx, expected return value = 0x%lx\\n\",\n+\t\t __func__, sc->syscall, proc_data->err,\n+\t\t sc->expected_result);\n+\n \t\tprintk(UM_KERN_ERR \" syscall parameters: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\\n\",\n-\t\t syscall[1], syscall[2], syscall[3],\n-\t\t syscall[4], syscall[5], syscall[6]);\n-\t\tfor (n = 1; n < data[0]/sizeof(long); n++) {\n-\t\t\tif (n == 1)\n-\t\t\t\tprintk(UM_KERN_ERR \" additional syscall data:\");\n-\t\t\tif (n % 4 == 1)\n-\t\t\t\tprintk(\"\\n\" UM_KERN_ERR \" \");\n-\t\t\tprintk(\" 0x%lx\", data[n]);\n+\t\t sc->arg[0], sc->arg[1], sc->arg[2],\n+\t\t sc->arg[3], sc->arg[4], sc->arg[5]);\n+\n+\t\tn = sc->cmd_len - sizeof(*sc);\n+\t\tif (n > 0) {\n+\t\t\tprintk(UM_KERN_ERR \" syscall data 0x%lx + %d\",\n+\t\t\t STUB_DATA + ((unsigned long) (&sc->data) &\n+\t\t\t\t\t (UM_KERN_PAGE_SIZE - 1)),\n+\t\t\t n);\n+\t\t\tprint_hex_dump(UM_KERN_ERR,\n+\t\t\t\t \" syscall data: \", 0,\n+\t\t\t\t 16, 4, sc->data, n, 0);\n \t\t}\n-\t\tif (n > 1)\n-\t\t\tprintk(\"\\n\");\n-\t}\n-\telse ret = 0;\n \n-\t*addr = check_init_stack(mm_idp, NULL);\n+\t\t/* Store error code in case someone tries to add more syscalls */\n+\t\tmm_idp->syscall_data_len = proc_data->err;\n+\t} else {\n+\t\tmm_idp->syscall_data_len = 0;\n+\t}\n \n-\treturn ret;\n+\treturn mm_idp->syscall_data_len;\n }\n \n-long run_syscall_stub(struct mm_id * mm_idp, int syscall,\n-\t\t unsigned long *args, long expected, void **addr,\n-\t\t int done)\n+int syscall_stub_flush(struct mm_id *mm_idp)\n {\n-\tunsigned long *stack = check_init_stack(mm_idp, *addr);\n-\n-\t*stack += sizeof(long);\n-\tstack += *stack / sizeof(long);\n-\n-\t*stack++ = syscall;\n-\t*stack++ = args[0];\n-\t*stack++ = args[1];\n-\t*stack++ = args[2];\n-\t*stack++ = args[3];\n-\t*stack++ = args[4];\n-\t*stack++ = args[5];\n-\t*stack++ = expected;\n-\t*stack = 0;\n-\n-\tif (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <\n-\t\t UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {\n-\t\t*addr = stack;\n+\tint res;\n+\n+\tif (mm_idp->syscall_data_len == 0)\n \t\treturn 0;\n+\n+\t/* If an error happened already, report it and reset the state. */\n+\tif (mm_idp->syscall_data_len < 0) {\n+\t\tres = mm_idp->syscall_data_len;\n+\t\tmm_idp->syscall_data_len = 0;\n+\t\treturn res;\n \t}\n \n-\treturn do_syscall_stub(mm_idp, addr);\n+\tres = do_syscall_stub(mm_idp);\n+\tmm_idp->syscall_data_len = 0;\n+\n+\treturn res;\n }\n \n-long syscall_stub_data(struct mm_id * mm_idp,\n-\t\t unsigned long *data, int data_count,\n-\t\t void **addr, void **stub_addr)\n+struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp,\n+\t\t\t\t\tunsigned long data_len,\n+\t\t\t\t\tunsigned long *data_addr)\n {\n-\tunsigned long *stack;\n-\tint ret = 0;\n-\n-\t/*\n-\t * If *addr still is uninitialized, it *must* contain NULL.\n-\t * Thus in this case do_syscall_stub correctly won't be called.\n-\t */\n-\tif ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=\n-\t UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {\n-\t\tret = do_syscall_stub(mm_idp, addr);\n-\t\t/* in case of error, don't overwrite data on stack */\n-\t\tif (ret)\n-\t\t\treturn ret;\n+\tstruct stub_syscall *sc;\n+\tstruct stub_data *proc_data = (struct stub_data *) mm_idp->stack;\n+\tint len;\n+\n+\t/* Align to sizeof(long) */\n+\tdata_len = (data_len + sizeof(long) - 1) & ~(sizeof(long) - 1);\n+\tlen = sizeof(struct stub_syscall) + data_len;\n+\n+\tif (len > sizeof(proc_data->syscall_data))\n+\t\tpanic(\"Syscall data too large to marshal!\");\n+\n+\tif (mm_idp->syscall_data_len > 0 &&\n+\t mm_idp->syscall_data_len + len > sizeof(proc_data->syscall_data))\n+\t\tdo_syscall_stub(mm_idp);\n+\n+\tif (mm_idp->syscall_data_len < 0) {\n+\t\t/* Return dummy without changing the syscall_next_offset to\n+\t\t * retain error state.\n+\t\t */\n+\t\tsc = (void *) &proc_data->syscall_data;\n+\t} else {\n+\t\tsc = (void *) (((unsigned long) &proc_data->syscall_data) +\n+\t\t\t mm_idp->syscall_data_len);\n+\t\tmm_idp->syscall_data_len += len;\n \t}\n+\tmemset(sc, 0, len);\n+\tsc->cmd_len = len;\n \n-\tstack = check_init_stack(mm_idp, *addr);\n-\t*addr = stack;\n-\n-\t*stack = data_count * sizeof(long);\n+\tif (data_addr)\n+\t\t*data_addr = STUB_DATA +\n+\t\t\t ((unsigned long) (&sc->data) &\n+\t\t\t (UM_KERN_PAGE_SIZE - 1));\n \n-\tmemcpy(stack + 1, data, data_count * sizeof(long));\n-\n-\t*stub_addr = (void *)(((unsigned long)(stack + 1) &\n-\t\t\t ~UM_KERN_PAGE_MASK) + STUB_DATA);\n-\n-\treturn 0;\n+\treturn sc;\n }\n \n-int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,\n-\tint phys_fd, unsigned long long offset, int done, void **data)\n-{\n-\tint ret;\n-\tunsigned long args[] = { virt, len, prot,\n-\t\t\t\t MAP_SHARED | MAP_FIXED, phys_fd,\n-\t\t\t\t MMAP_OFFSET(offset) };\n-\n-\tret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,\n-\t\t\t data, done);\n \n-\treturn ret;\n+void map(struct mm_id *mm_idp, unsigned long virt, unsigned long len, int prot,\n+\tint phys_fd, unsigned long long offset)\n+{\n+\tstruct stub_syscall *sc;\n+\n+\tsc = syscall_stub_alloc(mm_idp, 0, NULL);\n+\tsc->syscall = STUB_MMAP_NR;\n+\tsc->expected_result = virt;\n+\tsc->arg[0] = virt;\n+\tsc->arg[1] = len;\n+\tsc->arg[2] = prot;\n+\tsc->arg[3] = MAP_SHARED | MAP_FIXED;\n+\tsc->arg[4] = phys_fd;\n+\tsc->arg[5] = MMAP_OFFSET(offset);\n }\n \n-int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,\n-\t int done, void **data)\n+void unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len)\n {\n-\tint ret;\n-\tunsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,\n-\t\t\t\t 0 };\n+\tstruct stub_syscall *sc;\n \n-\tret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,\n-\t\t\t data, done);\n-\n-\treturn ret;\n+\tsc = syscall_stub_alloc(mm_idp, 0, NULL);\n+\tsc->syscall = __NR_munmap;\n+\tsc->arg[0] = addr;\n+\tsc->arg[1] = len;\n }\n \n-int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,\n-\t unsigned int prot, int done, void **data)\n+void protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len,\n+\t unsigned int prot)\n {\n-\tint ret;\n-\tunsigned long args[] = { addr, len, prot, 0, 0, 0 };\n-\n-\tret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,\n-\t\t\t data, done);\n+\tstruct stub_syscall *sc;\n \n-\treturn ret;\n+\tsc = syscall_stub_alloc(mm_idp, 0, NULL);\n+\tsc->syscall = __NR_mprotect;\n+\tsc->arg[0] = addr;\n+\tsc->arg[1] = len;\n+\tsc->arg[2] = prot;\n }\ndiff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c\nindex 3917bd862315..17164c4a7d7c 100644\n--- a/arch/um/os-Linux/skas/process.c\n+++ b/arch/um/os-Linux/skas/process.c\n@@ -499,7 +499,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)\n \t*data = ((struct stub_data) {\n \t\t.offset\t= MMAP_OFFSET(new_offset),\n \t\t.fd = new_fd,\n-\t\t.parent_err = -ESRCH,\n+\t\t.err = -ESRCH,\n \t\t.child_err = 0,\n \t});\n \n@@ -536,7 +536,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)\n \n \twait_stub_done(pid);\n \n-\tpid = data->parent_err;\n+\tpid = data->err;\n \tif (pid < 0) {\n \t\tprintk(UM_KERN_ERR \"%s - stub-parent reports error %d\\n\",\n \t\t __func__, -pid);\ndiff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile\nindex 3d5cd2e57820..ab0857399b8f 100644\n--- a/arch/x86/um/Makefile\n+++ b/arch/x86/um/Makefile\n@@ -11,7 +11,7 @@ endif\n \n obj-y = bugs_$(BITS).o delay.o fault.o ldt.o \\\n \tptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \\\n-\tstub_$(BITS).o stub_segv.o \\\n+\tstub_segv.o \\\n \tsys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \\\n \tmem_$(BITS).o subarch.o os-$(OS)/\n \ndiff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c\nindex 255a44dd415a..56e80c626d8a 100644\n--- a/arch/x86/um/ldt.c\n+++ b/arch/x86/um/ldt.c\n@@ -12,33 +12,26 @@\n #include <os.h>\n #include <skas.h>\n #include <sysdep/tls.h>\n+#include <stub-data.h>\n \n static inline int modify_ldt (int func, void *ptr, unsigned long bytecount)\n {\n \treturn syscall(__NR_modify_ldt, func, ptr, bytecount);\n }\n \n-static long write_ldt_entry(struct mm_id *mm_idp, int func,\n-\t\t struct user_desc *desc, void **addr, int done)\n+static void write_ldt_entry(struct mm_id *mm_idp, int func,\n+\t\t struct user_desc *desc)\n {\n-\tlong res;\n-\tvoid *stub_addr;\n-\n-\tBUILD_BUG_ON(sizeof(*desc) % sizeof(long));\n-\n-\tres = syscall_stub_data(mm_idp, (unsigned long *)desc,\n-\t\t\t\tsizeof(*desc) / sizeof(long),\n-\t\t\t\taddr, &stub_addr);\n-\tif (!res) {\n-\t\tunsigned long args[] = { func,\n-\t\t\t\t\t (unsigned long)stub_addr,\n-\t\t\t\t\t sizeof(*desc),\n-\t\t\t\t\t 0, 0, 0 };\n-\t\tres = run_syscall_stub(mm_idp, __NR_modify_ldt, args,\n-\t\t\t\t 0, addr, done);\n-\t}\n-\n-\treturn res;\n+\tstruct stub_syscall *sc;\n+\tunsigned long data_addr;\n+\n+\tsc = syscall_stub_alloc(mm_idp, sizeof(*desc), &data_addr);\n+\tmemcpy(sc->data, desc, sizeof(*desc));\n+\tsc->expected_result = 0;\n+\tsc->syscall = __NR_modify_ldt;\n+\tsc->arg[0] = func;\n+\tsc->arg[1] = data_addr;\n+\tsc->arg[2] = sizeof(*desc);\n }\n \n /*\n@@ -127,7 +120,6 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)\n \tint i, err;\n \tstruct user_desc ldt_info;\n \tstruct ldt_entry entry0, *ldt_p;\n-\tvoid *addr = NULL;\n \n \terr = -EINVAL;\n \tif (bytecount != sizeof(ldt_info))\n@@ -148,7 +140,8 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)\n \n \tmutex_lock(&ldt->lock);\n \n-\terr = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);\n+\twrite_ldt_entry(mm_idp, func, &ldt_info);\n+\terr = syscall_stub_flush(mm_idp);\n \tif (err)\n \t\tgoto out_unlock;\n \n@@ -166,7 +159,8 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)\n \t\t\t\terr = -ENOMEM;\n \t\t\t\t/* Undo the change in host */\n \t\t\t\tmemset(&ldt_info, 0, sizeof(ldt_info));\n-\t\t\t\twrite_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);\n+\t\t\t\twrite_ldt_entry(mm_idp, 1, &ldt_info);\n+\t\t\t\terr = syscall_stub_flush(mm_idp);\n \t\t\t\tgoto out_unlock;\n \t\t\t}\n \t\t\tif (i == 0) {\n@@ -303,7 +297,6 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)\n \tshort * num_p;\n \tint i;\n \tlong page, err=0;\n-\tvoid *addr = NULL;\n \n \n \tmutex_init(&new_mm->arch.ldt.lock);\n@@ -318,11 +311,9 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)\n \t\tldt_get_host_info();\n \t\tfor (num_p=host_ldt_entries; *num_p != -1; num_p++) {\n \t\t\tdesc.entry_number = *num_p;\n-\t\t\terr = write_ldt_entry(&new_mm->id, 1, &desc,\n-\t\t\t\t\t &addr, *(num_p + 1) == -1);\n-\t\t\tif (err)\n-\t\t\t\tbreak;\n+\t\t\twrite_ldt_entry(&new_mm->id, 1, &desc);\n \t\t}\n+\t\terr = syscall_stub_flush(&new_mm->id);\n \t\tnew_mm->arch.ldt.entry_count = 0;\n \n \t\tgoto out;\ndiff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h\nindex ce0ca46ad383..579681d12158 100644\n--- a/arch/x86/um/shared/sysdep/stub.h\n+++ b/arch/x86/um/shared/sysdep/stub.h\n@@ -12,4 +12,5 @@\n #endif\n \n extern void stub_segv_handler(int, siginfo_t *, void *);\n+extern void stub_syscall_handler(void);\n extern void stub_clone_handler(void);\ndiff --git a/arch/x86/um/stub_32.S b/arch/x86/um/stub_32.S\ndeleted file mode 100644\nindex 8291899e6aaf..000000000000\n--- a/arch/x86/um/stub_32.S\n+++ /dev/null\n@@ -1,56 +0,0 @@\n-/* SPDX-License-Identifier: GPL-2.0 */\n-#include <as-layout.h>\n-\n-.section .__syscall_stub, \"ax\"\n-\n-\t.globl batch_syscall_stub\n-batch_syscall_stub:\n-\t/* %esp comes in as \"top of page\" */\n-\tmov %esp, %ecx\n-\t/* %esp has pointer to first operation */\n-\tadd $8, %esp\n-again:\n-\t/* load length of additional data */\n-\tmov\t0x0(%esp), %eax\n-\n-\t/* if(length == 0) : end of list */\n-\t/* write possible 0 to header */\n-\tmov\t%eax, 0x4(%ecx)\n-\tcmpl\t$0, %eax\n-\tjz\tdone\n-\n-\t/* save current pointer */\n-\tmov\t%esp, 0x4(%ecx)\n-\n-\t/* skip additional data */\n-\tadd\t%eax, %esp\n-\n-\t/* load syscall-# */\n-\tpop\t%eax\n-\n-\t/* load syscall params */\n-\tpop\t%ebx\n-\tpop\t%ecx\n-\tpop\t%edx\n-\tpop\t%esi\n- \tpop\t%edi\n-\tpop\t%ebp\n-\n-\t/* execute syscall */\n-\tint\t$0x80\n-\n-\t/* restore top of page pointer in %ecx */\n-\tmov\t%esp, %ecx\n-\tandl\t$(~UM_KERN_PAGE_SIZE) + 1, %ecx\n-\n-\t/* check return value */\n-\tpop\t%ebx\n-\tcmp\t%ebx, %eax\n-\tje\tagain\n-\n-done:\n-\t/* save return value */\n-\tmov\t%eax, (%ecx)\n-\n-\t/* stop */\n-\tint3\ndiff --git a/arch/x86/um/stub_64.S b/arch/x86/um/stub_64.S\ndeleted file mode 100644\nindex f3404640197a..000000000000\n--- a/arch/x86/um/stub_64.S\n+++ /dev/null\n@@ -1,50 +0,0 @@\n-/* SPDX-License-Identifier: GPL-2.0 */\n-#include <as-layout.h>\n-\n-.section .__syscall_stub, \"ax\"\n-\t.globl batch_syscall_stub\n-batch_syscall_stub:\n-\t/* %rsp has the pointer to first operation */\n-\tmov\t%rsp, %rbx\n-\tadd\t$0x10, %rsp\n-again:\n-\t/* load length of additional data */\n-\tmov\t0x0(%rsp), %rax\n-\n-\t/* if(length == 0) : end of list */\n-\t/* write possible 0 to header */\n-\tmov\t%rax, 8(%rbx)\n-\tcmp\t$0, %rax\n-\tjz\tdone\n-\n-\t/* save current pointer */\n-\tmov\t%rsp, 8(%rbx)\n-\n-\t/* skip additional data */\n-\tadd\t%rax, %rsp\n-\n-\t/* load syscall-# */\n-\tpop\t%rax\n-\n-\t/* load syscall params */\n-\tpop\t%rdi\n-\tpop\t%rsi\n-\tpop\t%rdx\n-\tpop\t%r10\n- \tpop\t%r8\n-\tpop\t%r9\n-\n-\t/* execute syscall */\n-\tsyscall\n-\n-\t/* check return value */\n-\tpop\t%rcx\n-\tcmp\t%rcx, %rax\n-\tje\tagain\n-\n-done:\n-\t/* save return value */\n-\tmov\t%rax, (%rbx)\n-\n-\t/* stop */\n-\tint3\n", "prefixes": [ "v2", "17/28" ] }