diff mbox series

[RFC,01/11] x86/mm: Bare minimum ASI API for page_alloc integration

Message ID 20250313-asi-page-alloc-v1-1-04972e046cea@google.com (mailing list archive)
State New
Headers show
Series mm: ASI integration for the page allocator | expand

Commit Message

Brendan Jackman March 13, 2025, 6:11 p.m. UTC
This commit serves to provide a minimal framework to present an ASI
integration into the page allocator, without getting distracted by
irrelevant details. There's no need to review this actively, just refer
back to it as-needed when reading the later patches.

In a real [PATCH] series this should be several separate commits.

Aside from missing the actual core address-space switching and security
logic, this is missing runtime-disablement of ASI. If you enable it in
Kconfig, ASI's mm logic gets run unconditionally. That isn't what we
want in the real implementation (certainly not in the initial version,
anyway).

- Add CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION. Attempt to follow the
  proposal by Mike Rapoport here:
  https://lore.kernel.org/linux-mm/Z8K2B3WJoICVbDj3@kernel.org/

  In this RFC, there's only a small amount of x86-specific logic,
  perhaps it's possible to implement this logic without any arch/
  dependency. But, this is absolutely not true of the full ASI
  implementation. So that's already reflected in the Kconfig stuff
  here.

- Introduce struct asi, which is an "ASI domain", i.e. an address space.
  For now this is nothing but a wrapper for a PGD.

- Introduce the "global nonsensitive" ASI domain. This contains all the
  mappings that do not need to be protected from any attacker.
  Maintaining these mappings is the subject of this RFC.

Signed-off-by: Brendan Jackman <jackmanb@google.com>
---
 arch/Kconfig               | 14 ++++++++++++++
 arch/x86/Kconfig           |  1 +
 arch/x86/include/asm/asi.h | 28 ++++++++++++++++++++++++++++
 arch/x86/mm/Makefile       |  1 +
 arch/x86/mm/asi.c          |  8 ++++++++
 arch/x86/mm/init.c         |  3 ++-
 include/linux/asi.h        | 18 ++++++++++++++++++
 7 files changed, 72 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/arch/Kconfig b/arch/Kconfig
index b8a4ff36558228240080a5677f702d37f4f8d547..871ad0987c8740205ceec675a6b7304c644f28e1 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -17,6 +17,20 @@  config CPU_MITIGATIONS
 	def_bool y
 endif
 
+config ARCH_HAS_MITIGATION_ADDRESS_SPACE_ISOLATION
+	bool
+
+config MITIGATION_ADDRESS_SPACE_ISOLATION
+	bool "Allow code to run with a reduced kernel address space"
+	default n
+	depends on ARCH_HAS_MITIGATION_ADDRESS_SPACE_ISOLATION && !PARAVIRT
+	help
+	  This feature provides the ability to run some kernel code
+	  with a reduced kernel address space. This can be used to
+	  mitigate some speculative execution attacks.
+
+	  !PARAVIRT dependency is a temporary hack while ASI has custom
+	  pagetable manipulation code.
 #
 # Selected by architectures that need custom DMA operations for e.g. legacy
 # IOMMUs not handled by dma-iommu.  Drivers must never select this symbol.
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0e27ebd7e36a9e3d69ad3e77c8db5dcf11ae3016..19ceecf5978bbe62e0742072c192c8ee952082dc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -36,6 +36,7 @@  config X86_64
 	select ARCH_HAS_ELFCORE_COMPAT
 	select ZONE_DMA32
 	select EXECMEM if DYNAMIC_FTRACE
+	select ARCH_HAS_MITIGATION_ADDRESS_SPACE_ISOLATION
 
 config FORCE_DYNAMIC_FTRACE
 	def_bool y
diff --git a/arch/x86/include/asm/asi.h b/arch/x86/include/asm/asi.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8f604df6a36508acbc10710f821d5f95e8cdceb
--- /dev/null
+++ b/arch/x86/include/asm/asi.h
@@ -0,0 +1,28 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ASI_H
+#define _ASM_X86_ASI_H
+
+#include <asm/pgtable_types.h>
+
+#ifdef CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION
+
+extern struct asi __asi_global_nonsensitive;
+#define ASI_GLOBAL_NONSENSITIVE	(&__asi_global_nonsensitive)
+
+/*
+ * An ASI domain (struct asi) represents a restricted address space. The
+ * unrestricted address space (and user address space under PTI) are not
+ * represented as a domain.
+ */
+struct asi {
+	pgd_t *pgd;
+};
+
+static __always_inline pgd_t *asi_pgd(struct asi *asi)
+{
+	return asi ? asi->pgd : NULL;
+}
+
+#endif /* CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION */
+
+#endif /* _ASM_X86_ASI_H */
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 690fbf48e8538b62a176ce838820e363575b7897..89ade7363798cc20d5e5643526eba7378174baa0 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -61,6 +61,7 @@  obj-$(CONFIG_ACPI_NUMA)		+= srat.o
 obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS)	+= pkeys.o
 obj-$(CONFIG_RANDOMIZE_MEMORY)			+= kaslr.o
 obj-$(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION)	+= pti.o
+obj-$(CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION)		+= asi.o
 
 obj-$(CONFIG_X86_MEM_ENCRYPT)	+= mem_encrypt.o
 obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= mem_encrypt_amd.o
diff --git a/arch/x86/mm/asi.c b/arch/x86/mm/asi.c
new file mode 100644
index 0000000000000000000000000000000000000000..e5a981a7b3192655cd981633514fbf945b92c9b6
--- /dev/null
+++ b/arch/x86/mm/asi.c
@@ -0,0 +1,8 @@ 
+// SPDX-License-Identifier: GPL-2.0
+#include <asm/asi.h>
+
+static __aligned(PAGE_SIZE) pgd_t asi_global_nonsensitive_pgd[PTRS_PER_PGD];
+
+struct asi __asi_global_nonsensitive = {
+	.pgd = asi_global_nonsensitive_pgd,
+};
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 62aa4d66a032d59191e79d34fc0cdaa4f32f88db..44d3dc574881dd23bb48f9af3f6191be309405ef 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -250,7 +250,8 @@  static void __init probe_page_size_mask(void)
 	/* By the default is everything supported: */
 	__default_kernel_pte_mask = __supported_pte_mask;
 	/* Except when with PTI where the kernel is mostly non-Global: */
-	if (cpu_feature_enabled(X86_FEATURE_PTI))
+	if (cpu_feature_enabled(X86_FEATURE_PTI) ||
+	    IS_ENABLED(CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION))
 		__default_kernel_pte_mask &= ~_PAGE_GLOBAL;
 
 	/* Enable 1 GB linear kernel mappings if available: */
diff --git a/include/linux/asi.h b/include/linux/asi.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d3049d5fe423e139dcce8f3d68cdffcc0ec0bfe
--- /dev/null
+++ b/include/linux/asi.h
@@ -0,0 +1,18 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _INCLUDE_ASI_H
+#define _INCLUDE_ASI_H
+
+#include <asm/pgtable_types.h>
+
+#ifdef CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION
+#include <asm/asi.h>
+#else
+
+#define ASI_GLOBAL_NONSENSITIVE NULL
+
+struct asi {};
+
+static inline pgd_t *asi_pgd(struct asi *asi) { return NULL; }
+
+#endif /* CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION */
+#endif /* _INCLUDE_ASI_H */