linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Bharata B Rao <bharata@amd.com>
To: <linux-kernel@vger.kernel.org>
Cc: <linux-mm@kvack.org>, <x86@kernel.org>,
	<kirill.shutemov@linux.intel.com>, <tglx@linutronix.de>,
	<mingo@redhat.com>, <bp@alien8.de>, <dave.hansen@linux.intel.com>,
	<catalin.marinas@arm.com>, <will@kernel.org>, <shuah@kernel.org>,
	<oleg@redhat.com>, <ananth.narayan@amd.com>,
	"Bharata B Rao" <bharata@amd.com>
Subject: [RFC PATCH v0 6/6] x86: Add prctl() options to control tagged user addresses ABI
Date: Thu, 10 Mar 2022 16:45:45 +0530	[thread overview]
Message-ID: <20220310111545.10852-7-bharata@amd.com> (raw)
In-Reply-To: <20220310111545.10852-1-bharata@amd.com>

Provide an option for applications to opt-in for a relaxed
tagged ABI via prtcl(). This allows them to pass tagged addresses
to syscalls as pointer arguments.

The implementation is kept separate for AMD UAI as the equivalent
implementation for Intel LAM is likely to be different.

Signed-off-by: Bharata B Rao <bharata@amd.com>
---
 arch/x86/Kconfig                 |   9 +++
 arch/x86/include/asm/processor.h |  12 +++
 arch/x86/include/asm/uaccess.h   |   3 +-
 arch/x86/kernel/process.c        | 134 +++++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9f5bd41bf660..b73414eb1c01 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2436,6 +2436,15 @@ config STRICT_SIGALTSTACK_SIZE
 
 source "kernel/livepatch/Kconfig"
 
+config X86_TAGGED_ADDR_ABI
+	bool "Enable the tagged user addresses syscall ABI"
+	depends on X86_64 && CPU_SUP_AMD
+	default y
+	help
+	  When this option is enabled, user applications can opt-in to a
+	  relaxed ABI via prctl() allowing tagged addresses to be passed
+	  to system calls as pointer arguments.
+
 endmenu
 
 config ARCH_HAS_ADD_PAGES
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2c5f12ae7d04..414e2c039c34 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -863,4 +863,16 @@ bool arch_is_platform_page(u64 paddr);
 #define arch_is_platform_page arch_is_platform_page
 #endif
 
+#ifdef CONFIG_X86_TAGGED_ADDR_ABI
+/* PR_{SET,GET}_TAGGED_ADDR_CTRL prctl */
+long set_tagged_addr_ctrl(struct task_struct *task, unsigned long flags,
+			  int __user *nr_bits, int __user *offset);
+long get_tagged_addr_ctrl(struct task_struct *task,
+			  int __user *nr_bits, int __user *offset);
+#define SET_TAGGED_ADDR_CTRL(flags, nr_bits, offset)	\
+	set_tagged_addr_ctrl(current, flags, nr_bits, offset)
+#define GET_TAGGED_ADDR_CTRL(nr_bits, offset)		\
+	get_tagged_addr_ctrl(current, nr_bits, offset)
+#endif
+
 #endif /* _ASM_X86_PROCESSOR_H */
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index feb2e21c7e09..e415523dc425 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -38,7 +38,8 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
 static inline bool __range_not_ok(const void __user *addr, unsigned long size,
 				  unsigned long limit)
 {
-	if (test_thread_flag(TIF_TAGGED_ADDR))
+	if (IS_ENABLED(CONFIG_X86_TAGGED_ADDR_ABI) &&
+	    (current->flags & PF_KTHREAD || test_thread_flag(TIF_TAGGED_ADDR)))
 		addr = untagged_addr(addr);
 
 	__chk_user_ptr(addr);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 81d8ef036637..2bc44efdd994 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -26,6 +26,7 @@
 #include <linux/elf-randomize.h>
 #include <trace/events/power.h>
 #include <linux/hw_breakpoint.h>
+#include <linux/sysctl.h>
 #include <asm/cpu.h>
 #include <asm/apic.h>
 #include <linux/uaccess.h>
@@ -231,6 +232,12 @@ static void pkru_flush_thread(void)
 	pkru_write_default();
 }
 
+static void flush_tagged_addr_state(void)
+{
+	if (IS_ENABLED(CONFIG_X86_TAGGED_ADDR_ABI))
+		clear_thread_flag(TIF_TAGGED_ADDR);
+}
+
 void flush_thread(void)
 {
 	struct task_struct *tsk = current;
@@ -240,6 +247,7 @@ void flush_thread(void)
 
 	fpu_flush_thread();
 	pkru_flush_thread();
+	flush_tagged_addr_state();
 }
 
 void disable_TSC(void)
@@ -1000,3 +1008,129 @@ long do_arch_prctl_common(struct task_struct *task, int option,
 
 	return -EINVAL;
 }
+
+#ifdef CONFIG_X86_TAGGED_ADDR_ABI
+/*
+ * Control the relaxed ABI allowing tagged user addresses into the kernel.
+ */
+static unsigned int tagged_addr_disabled;
+
+#ifdef CONFIG_CPU_SUP_AMD
+#define UAI_TAG_BITS	7
+
+static long amd_set_tagged_addr_ctrl(unsigned long flags, int __user *nr_bits,
+				     int __user *offset)
+{
+	int val;
+
+	if (!boot_cpu_has(X86_FEATURE_UAI))
+		return -EINVAL;
+
+	/* Disable tagging */
+	if (!(flags & PR_TAGGED_ADDR_ENABLE)) {
+		clear_thread_flag(TIF_TAGGED_ADDR);
+		return 0;
+	}
+
+	if (!nr_bits || !offset)
+		return -EINVAL;
+
+	/*
+	 * Do not allow the enabling of the tagged address ABI if globally
+	 * disabled via sysctl abi.tagged_addr_disabled.
+	 */
+	if (tagged_addr_disabled)
+		return -EINVAL;
+
+	if (get_user(val, nr_bits))
+		return -EFAULT;
+
+	if (val != UAI_TAG_BITS)
+		return -EINVAL;
+
+	if (put_user(val, nr_bits) || put_user(64 - val, offset))
+		return -EFAULT;
+
+	set_thread_flag(TIF_TAGGED_ADDR);
+	return 0;
+}
+
+static long amd_get_tagged_addr_ctrl(int __user *nr_bits, int __user *offset)
+{
+	long ret = 0;
+
+	if (!boot_cpu_has(X86_FEATURE_UAI))
+		return -EINVAL;
+
+	if (test_thread_flag(TIF_TAGGED_ADDR)) {
+		if (nr_bits && put_user(UAI_TAG_BITS, nr_bits))
+			return -EFAULT;
+		if (offset && put_user(64 - UAI_TAG_BITS, offset))
+			return -EFAULT;
+		ret = PR_TAGGED_ADDR_ENABLE;
+	} else {
+		/* Report max tag size */
+		if (nr_bits && put_user(UAI_TAG_BITS, nr_bits))
+			return -EFAULT;
+	}
+	return ret;
+}
+#endif
+
+long set_tagged_addr_ctrl(struct task_struct *task, unsigned long flags,
+			  int __user *nr_bits, int __user *offset)
+{
+	unsigned long valid_mask = PR_TAGGED_ADDR_ENABLE;
+
+	if (in_32bit_syscall())
+		return -EINVAL;
+
+	if (flags & ~valid_mask)
+		return -EINVAL;
+
+	if (IS_ENABLED(CONFIG_CPU_SUP_AMD))
+		return amd_set_tagged_addr_ctrl(flags, nr_bits, offset);
+	else
+		return -EINVAL;
+}
+
+long get_tagged_addr_ctrl(struct task_struct *task,
+			  int __user *nr_bits, int __user *offset)
+{
+
+	if (in_32bit_syscall())
+		return -EINVAL;
+
+	if (IS_ENABLED(CONFIG_CPU_SUP_AMD))
+		return amd_get_tagged_addr_ctrl(nr_bits, offset);
+	else
+		return -EINVAL;
+}
+
+/*
+ * Global sysctl to disable the tagged user addresses support. This control
+ * only prevents the tagged address ABI enabling via prctl() and does not
+ * disable it for tasks that already opted in to the relaxed ABI.
+ */
+static struct ctl_table tagged_addr_sysctl_table[] = {
+	{
+		.procname	= "tagged_addr_disabled",
+		.mode		= 0644,
+		.data		= &tagged_addr_disabled,
+		.maxlen		= sizeof(int),
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= SYSCTL_ONE,
+	},
+	{ }
+};
+
+static int __init tagged_addr_init(void)
+{
+	if (!register_sysctl("abi", tagged_addr_sysctl_table))
+		return -EINVAL;
+	return 0;
+}
+
+core_initcall(tagged_addr_init);
+#endif	/* CONFIG_X86_TAGGED_ADDR_ABI */
-- 
2.25.1



  parent reply	other threads:[~2022-03-10 11:16 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-10 11:15 [RFC PATCH v0 0/6] x86/AMD: Userspace address tagging Bharata B Rao
2022-03-10 11:15 ` [RFC PATCH v0 1/6] mm, arm64: Update PR_SET/GET_TAGGED_ADDR_CTRL interface Bharata B Rao
2022-03-10 11:15 ` [RFC PATCH v0 2/6] x86/cpufeatures: Add Upper Address Ignore(UAI) as CPU feature Bharata B Rao
2022-03-10 11:15 ` [RFC PATCH v0 3/6] x86: Enable Upper Address Ignore(UAI) feature Bharata B Rao
2022-03-10 19:46   ` Andrew Cooper
2022-03-10 22:37     ` David Laight
2022-03-10 22:46       ` Dave Hansen
2022-03-11 12:37   ` Boris Petkov
2022-03-10 11:15 ` [RFC PATCH v0 4/6] x86: Provide an implementation of untagged_addr() Bharata B Rao
2022-03-10 11:15 ` [RFC PATCH v0 5/6] x86: Untag user pointers in access_ok() Bharata B Rao
2022-03-10 11:15 ` Bharata B Rao [this message]
2022-03-10 14:32 ` [RFC PATCH v0 0/6] x86/AMD: Userspace address tagging David Laight
2022-03-10 16:45   ` Dave Hansen
2022-03-10 17:19     ` David Laight
2022-03-11  5:42       ` Bharata B Rao
2022-03-11  8:15         ` David Laight
2022-03-11  9:11           ` Bharata B Rao
2022-03-11  9:36             ` David Laight
2022-03-11 16:51               ` Dave Hansen
2022-03-10 15:16 ` Dave Hansen
2022-03-10 15:22   ` Dave Hansen
2022-03-14  5:00   ` Bharata B Rao
2022-03-14  7:03     ` Dave Hansen
2022-03-21 22:29 ` Andy Lutomirski
2022-03-21 22:59   ` Thomas Gleixner
2022-03-22  5:31   ` David Laight
2022-03-23  7:48   ` Bharata B Rao
2022-04-01 19:25     ` Dave Hansen
2022-04-05  5:58       ` Bharata B Rao
2022-04-01 19:41     ` Andy Lutomirski
2022-04-05  8:14     ` Peter Zijlstra
2022-04-05  8:40       ` Bharata B Rao
2022-04-08 17:41   ` Catalin Marinas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220310111545.10852-7-bharata@amd.com \
    --to=bharata@amd.com \
    --cc=ananth.narayan@amd.com \
    --cc=bp@alien8.de \
    --cc=catalin.marinas@arm.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mingo@redhat.com \
    --cc=oleg@redhat.com \
    --cc=shuah@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).