All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86: Add Kconfig option to require NX bit support
@ 2023-06-01 17:43 Alejandro Vallejo
  2023-06-02  8:31 ` Jan Beulich
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Alejandro Vallejo @ 2023-06-01 17:43 UTC (permalink / raw)
  To: Xen-devel
  Cc: Alejandro Vallejo, Jan Beulich, Andrew Cooper,
	Roger Pau Monné,
	Wei Liu

This allows replacing many instances of runtime checks with folded
constants. The patch asserts support for the NX bit in PTEs at boot time
and if so short-circuits cpu_has_nx to 1. This has several knock-on effects
that improve codegen:
  * _PAGE_NX matches _PAGE_NX_BIT, optimising the macro to a constant.
  * Many PAGE_HYPERVISOR_X are also folded into constants
  * A few if ( cpu_has_nx ) statements are optimised out

We save 2.5KiB off the text section and remove the runtime dependency for
applying NX, which hardens our security posture. The config option defaults
to OFF for compatibility with previous behaviour.

Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
---
 xen/arch/x86/Kconfig                  | 10 ++++++++++
 xen/arch/x86/boot/head.S              | 19 ++++++++++++++++---
 xen/arch/x86/boot/trampoline.S        |  3 ++-
 xen/arch/x86/efi/efi-boot.h           |  9 +++++++++
 xen/arch/x86/include/asm/cpufeature.h |  3 ++-
 5 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 406445a358..0983915372 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -307,6 +307,16 @@ config MEM_SHARING
 	bool "Xen memory sharing support (UNSUPPORTED)" if UNSUPPORTED
 	depends on HVM
 
+config REQUIRE_NX_BIT
+	def_bool n
+	prompt "Require NX bit support"
+	---help---
+	  Makes Xen require NX bit support on page table entries. This
+	  allows the resulting code to have folded constants where
+	  otherwise branches are required, yielding a smaller binary as a
+	  result. Requiring NX trades compatibility with older CPUs for
+	  improvements in speed and code size.
+
 endmenu
 
 source "common/Kconfig"
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 09bebf8635..8414266281 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -123,6 +123,7 @@ multiboot2_header:
 .Lbad_ldr_nih: .asciz "ERR: EFI ImageHandle is not provided by bootloader!"
 .Lbad_efi_msg: .asciz "ERR: EFI IA-32 platforms are not supported!"
 .Lbag_alg_msg: .asciz "ERR: Xen must be loaded at a 2Mb boundary!"
+.Lno_nx_bit_msg: .asciz "ERR: Not an NX-bit capable CPU!"
 
         .section .init.data, "aw", @progbits
         .align 4
@@ -151,6 +152,11 @@ not_multiboot:
 .Lnot_aligned:
         add     $sym_offs(.Lbag_alg_msg),%esi   # Error message
         jmp     .Lget_vtb
+#if IS_ENABLED(CONFIG_REQUIRE_NX_BIT)
+no_nx_bit:
+        add     $sym_offs(.Lno_nx_bit_msg),%esi   # Error message
+        jmp     .Lget_vtb
+#endif
 .Lmb2_no_st:
         /*
          * Here we are on EFI platform. vga_text_buffer was zapped earlier
@@ -647,11 +653,18 @@ trampoline_setup:
         cpuid
 1:      mov     %edx, CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM) + sym_esi(boot_cpu_data)
 
-        /* Check for NX. Adjust EFER setting if available. */
+        /*
+         * Check for NX:
+         *   - If Xen was compiled requiring it simply assert it's
+         *     supported. The trampoline already has the right constant.
+         *   - Otherwise, update the trampoline EFER mask accordingly.
+         */
         bt      $cpufeat_bit(X86_FEATURE_NX), %edx
-        jnc     1f
+        jnc     no_nx_bit
+#if !IS_ENABLED(CONFIG_REQUIRE_NX_BIT)
         orb     $EFER_NXE >> 8, 1 + sym_esi(trampoline_efer)
-1:
+no_nx_bit:
+#endif
 
         /* Check for availability of long mode. */
         bt      $cpufeat_bit(X86_FEATURE_LM),%edx
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index c6005fa33d..b964031085 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -147,7 +147,8 @@ GLOBAL(trampoline_misc_enable_off)
 
 /* EFER OR-mask for boot paths.  SCE conditional on PV support, NX added when available. */
 GLOBAL(trampoline_efer)
-        .long   EFER_LME | (EFER_SCE * IS_ENABLED(CONFIG_PV))
+        .long   EFER_LME | (EFER_SCE * IS_ENABLED(CONFIG_PV)) | \
+                (EFER_NXE * IS_ENABLED(CONFIG_REQUIRE_NX_BIT))
 
 GLOBAL(trampoline_xen_phys_start)
         .long   0
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index c94e53d139..641d6996c9 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -751,6 +751,15 @@ static void __init efi_arch_cpu(void)
     {
         caps[FEATURESET_e1d] = cpuid_edx(0x80000001);
 
+        /*
+         * This check purposefully doesn't use cpu_has_nx because
+         * cpu_has_nx bypasses the boot_cpu_data read if Xen was compiled
+         * with CONFIG_REQUIRE_NX_BIT
+         */
+        if ( IS_ENABLED(CONFIG_REQUIRE_NX_BIT) &&
+             !boot_cpu_has(X86_FEATURE_NX) )
+            blexit(L"This Xen build requires NX bit support");
+
         if ( cpu_has_nx )
             trampoline_efer |= EFER_NXE;
     }
diff --git a/xen/arch/x86/include/asm/cpufeature.h b/xen/arch/x86/include/asm/cpufeature.h
index ace31e3b1f..166f480bbc 100644
--- a/xen/arch/x86/include/asm/cpufeature.h
+++ b/xen/arch/x86/include/asm/cpufeature.h
@@ -91,7 +91,8 @@ static inline bool boot_cpu_has(unsigned int feat)
 #define cpu_has_hypervisor      boot_cpu_has(X86_FEATURE_HYPERVISOR)
 
 /* CPUID level 0x80000001.edx */
-#define cpu_has_nx              boot_cpu_has(X86_FEATURE_NX)
+#define cpu_has_nx              (IS_ENABLED(CONFIG_REQUIRE_NX_BIT) || \
+                                 boot_cpu_has(X86_FEATURE_NX))
 #define cpu_has_page1gb         boot_cpu_has(X86_FEATURE_PAGE1GB)
 #define cpu_has_rdtscp          boot_cpu_has(X86_FEATURE_RDTSCP)
 #define cpu_has_3dnow_ext       boot_cpu_has(X86_FEATURE_3DNOWEXT)
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-06-02 16:15 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-01 17:43 [PATCH] x86: Add Kconfig option to require NX bit support Alejandro Vallejo
2023-06-02  8:31 ` Jan Beulich
2023-06-02  9:45   ` Andrew Cooper
2023-06-02 11:04   ` Alejandro Vallejo
2023-06-02 12:05 ` Andrew Cooper
2023-06-02 13:02   ` Jan Beulich
2023-06-02 14:22 ` Andrew Cooper
2023-06-02 16:08   ` Alejandro Vallejo
2023-06-02 16:14     ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.