lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240411-tso-v1-1-754f11abfbff@marcan.st>
Date: Thu, 11 Apr 2024 09:51:20 +0900
From: Hector Martin <marcan@...can.st>
To: Catalin Marinas <catalin.marinas@....com>, 
 Will Deacon <will@...nel.org>, Marc Zyngier <maz@...nel.org>, 
 Mark Rutland <mark.rutland@....com>
Cc: Zayd Qumsieh <zayd_qumsieh@...le.com>, Justin Lu <ih_justin@...le.com>, 
 Ryan Houdek <Houdek.Ryan@...-emu.org>, Mark Brown <broonie@...nel.org>, 
 Ard Biesheuvel <ardb@...nel.org>, Mateusz Guzik <mjguzik@...il.com>, 
 Anshuman Khandual <anshuman.khandual@....com>, 
 Oliver Upton <oliver.upton@...ux.dev>, Miguel Luis <miguel.luis@...cle.com>, 
 Joey Gouly <joey.gouly@....com>, Christoph Paasch <cpaasch@...le.com>, 
 Kees Cook <keescook@...omium.org>, Sami Tolvanen <samitolvanen@...gle.com>, 
 Baoquan He <bhe@...hat.com>, Joel Granados <j.granados@...sung.com>, 
 Dawei Li <dawei.li@...ngroup.cn>, Andrew Morton <akpm@...ux-foundation.org>, 
 Florent Revest <revest@...omium.org>, David Hildenbrand <david@...hat.com>, 
 Stefan Roesch <shr@...kernel.io>, Andy Chiu <andy.chiu@...ive.com>, 
 Josh Triplett <josh@...htriplett.org>, Oleg Nesterov <oleg@...hat.com>, 
 Helge Deller <deller@....de>, Zev Weiss <zev@...ilderbeest.net>, 
 Ondrej Mosnacek <omosnace@...hat.com>, Miguel Ojeda <ojeda@...nel.org>, 
 linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org, 
 Asahi Linux <asahi@...ts.linux.dev>, Hector Martin <marcan@...can.st>
Subject: [PATCH 1/4] prctl: Introduce PR_{SET,GET}_MEM_MODEL

On some architectures, it is possible to query and/or change the CPU
memory model. This allows userspace to switch to a stricter memory model
for performance reasons, such as when emulating code for another
architecture where that model is the default.

Introduce two prctls to allow userspace to query and set the memory
model for a thread. Two models are initially defined:

- PR_SET_MEM_MODEL_DEFAULT requests the default memory model for the
  architecture.
- PR_SET_MEM_MODEL_TSO requests the x86 TSO memory model.

PR_SET_MEM_MODEL is allowed to set a stricter memory model than
requested if available, in which case it will return successfully. If
the requested memory model cannot be fulfilled, it will return an error.
The memory model that was actually set can be queried by a subsequent
call to PR_GET_MEM_MODEL.

Examples:
- On a CPU with not support for a memory model at least as strong as
  TSO, PR_SET_MEM_MODEL(PR_SET_MEM_MODEL_TSO) fails.
- On a CPU with runtime-configurable TSO support, PR_SET_MEM_MODEL can
  toggle the memory model between DEFAULT and TSO at will.
- On a CPU where the only memory model is at least as strict as TSO,
  PR_GET_MEM_MODEL will return PR_SET_MEM_MODEL_DEFAULT, and
  PR_SET_MEM_MODEL(PR_SET_MEM_MODEL_TSO) will return success but leave
  the memory model at PR_SET_MEM_MODEL_DEFAULT. This implies that the
  default is in fact at least as strict as TSO.

Signed-off-by: Hector Martin <marcan@...can.st>
---
 include/linux/memory_ordering_model.h | 11 +++++++++++
 include/uapi/linux/prctl.h            |  5 +++++
 kernel/sys.c                          | 21 +++++++++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/include/linux/memory_ordering_model.h b/include/linux/memory_ordering_model.h
new file mode 100644
index 000000000000..267a12ca6630
--- /dev/null
+++ b/include/linux/memory_ordering_model.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MEMORY_ORDERING_MODEL_H
+#define __ASM_MEMORY_ORDERING_MODEL_H
+
+/* Arch hooks to implement the PR_{GET_SET}_MEM_MODEL prctls */
+
+struct task_struct;
+int arch_prctl_mem_model_get(struct task_struct *t);
+int arch_prctl_mem_model_set(struct task_struct *t, unsigned long val);
+
+#endif
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index 370ed14b1ae0..961216093f11 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -306,4 +306,9 @@ struct prctl_mm_map {
 # define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK	0xc
 # define PR_RISCV_V_VSTATE_CTRL_MASK		0x1f
 
+#define PR_GET_MEM_MODEL	0x6d4d444c
+#define PR_SET_MEM_MODEL	0x4d4d444c
+# define PR_SET_MEM_MODEL_DEFAULT	0
+# define PR_SET_MEM_MODEL_TSO		1
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index f8e543f1e38a..6af659a9f826 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -45,6 +45,7 @@
 #include <linux/version.h>
 #include <linux/ctype.h>
 #include <linux/syscall_user_dispatch.h>
+#include <linux/memory_ordering_model.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -2442,6 +2443,16 @@ static int prctl_get_auxv(void __user *addr, unsigned long len)
 	return sizeof(mm->saved_auxv);
 }
 
+int __weak arch_prctl_mem_model_get(struct task_struct *t)
+{
+	return -EINVAL;
+}
+
+int __weak arch_prctl_mem_model_set(struct task_struct *t, unsigned long val)
+{
+	return -EINVAL;
+}
+
 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		unsigned long, arg4, unsigned long, arg5)
 {
@@ -2757,6 +2768,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case PR_RISCV_V_GET_CONTROL:
 		error = RISCV_V_GET_CONTROL();
 		break;
+	case PR_GET_MEM_MODEL:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_prctl_mem_model_get(me);
+		break;
+	case PR_SET_MEM_MODEL:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_prctl_mem_model_set(me, arg2);
+		break;
 	default:
 		error = -EINVAL;
 		break;

-- 
2.44.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ