mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode
@ 2026-03-09 18:10 Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 1/5] x86/vsyscall: Reorganize the page fault emulation code Sohil Mehta
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Sohil Mehta @ 2026-03-09 18:10 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Sohil Mehta, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

Linear Address Space Separation (LASS) is currently disabled [1] when
support for vsyscall emulation is configured. This series extends LASS
support specifically to the default mode (vsyscall=xonly).

Changes in v3
-------------
 - Pick up review tags from Peter Anvin.
 - Pick up tested-by tags from Maciej.
 - Minor change in patch 1 to make the reorganized code flow similar to
   the original.

Note, Peter suggested a few more changes to tighten the #PF vsyscall
emulation code. I'll post those separately as they are beyond the scope
of this series.

v2: https://lore.kernel.org/lkml/20260305214026.3887452-1-sohil.mehta@intel.com/

Patches
-------
These patches were originally part of the v10 LASS series [2] before
being split out into a smaller series to make it easier to review and
merge. The overall approach to enable vsyscall support was okayed by
Andy Lutomirski [3].

The patches are based on the tip x86/cpu branch which has the recently
merged LASS-EFI series [4].

Issue
-----
Userspace attempts to access any kernel address generate a #GP when LASS
is enabled. Legacy vsyscall functions are located in the address range
0xffffffffff600000 - 0xffffffffff601000. Prior to LASS, default access
(XONLY) to the vsyscall page would generate a page fault and the access
would be emulated in the kernel. Currently, as the #GP handler lacks any
emulation support, LASS is disabled when config X86_VSYSCALL_EMULATION
is set.

Solution
--------
These patches primarily update the #GP handler to reuse the existing
vsyscall emulation code for #PF. In XONLY mode, the faulting RIP is
readily available and can be used to determine if the #GP was triggered
due to a vsyscall access.

In contrast, the vsyscall EMULATE mode is deprecated and not expected to
be used by anyone. Supporting EMULATE mode with LASS would require
complex instruction decoding in the #GP fault handler, which is not
worth the effort. So, LASS is disabled in the rare case when someone
absolutely needs to enable vsyscall=emulate via the command line.

Please find more details in the individual commit messages.

Links
-----
[1]: https://lore.kernel.org/lkml/20251118182911.2983253-1-sohil.mehta@intel.com/
[2]: https://lore.kernel.org/lkml/20251007065119.148605-1-sohil.mehta@intel.com/
[3]: https://lore.kernel.org/lkml/f4ae0030-9bc2-4675-ae43-e477cd894750@app.fastmail.com/
[4]: https://lore.kernel.org/lkml/20260120234730.2215498-1-sohil.mehta@intel.com/

Sohil Mehta (5):
  x86/vsyscall: Reorganize the page fault emulation code
  x86/traps: Consolidate user fixups in the #GP handler
  x86/vsyscall: Restore vsyscall=xonly mode under LASS
  x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE
  x86/cpu: Remove LASS restriction on vsyscall emulation

 .../admin-guide/kernel-parameters.txt         |  4 +-
 arch/x86/entry/vsyscall/vsyscall_64.c         | 91 ++++++++++++-------
 arch/x86/include/asm/vsyscall.h               | 13 ++-
 arch/x86/kernel/cpu/common.c                  | 15 ---
 arch/x86/kernel/traps.c                       | 12 ++-
 arch/x86/kernel/umip.c                        |  3 +
 arch/x86/mm/fault.c                           |  2 +-
 7 files changed, 79 insertions(+), 61 deletions(-)


base-commit: 68400c1aaf02636a97c45ba198110b66feb270a9
-- 
2.43.0


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

* [PATCH v3 1/5] x86/vsyscall: Reorganize the page fault emulation code
  2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
@ 2026-03-09 18:10 ` Sohil Mehta
  2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 2/5] x86/traps: Consolidate user fixups in the #GP handler Sohil Mehta
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Sohil Mehta @ 2026-03-09 18:10 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Sohil Mehta, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

With LASS, vsyscall page accesses will cause a #GP instead of a #PF.
Separate out the core vsyscall emulation code from the #PF specific
handling in preparation for the upcoming #GP emulation.

No functional change intended.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
v3:
 - Minor change to keep the data access return code flow the same as the
   original.
 - Pick up review and tested-by tags.

v2:
 - No change
---
 arch/x86/entry/vsyscall/vsyscall_64.c | 66 ++++++++++++++-------------
 arch/x86/include/asm/vsyscall.h       |  7 ++-
 arch/x86/mm/fault.c                   |  2 +-
 3 files changed, 39 insertions(+), 36 deletions(-)

diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 4bd1e271bb22..398b1ed16f1e 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -111,43 +111,13 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size)
 	}
 }
 
-bool emulate_vsyscall(unsigned long error_code,
-		      struct pt_regs *regs, unsigned long address)
+static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 {
 	unsigned long caller;
 	int vsyscall_nr, syscall_nr, tmp;
 	long ret;
 	unsigned long orig_dx;
 
-	/* Write faults or kernel-privilege faults never get fixed up. */
-	if ((error_code & (X86_PF_WRITE | X86_PF_USER)) != X86_PF_USER)
-		return false;
-
-	/*
-	 * Assume that faults at regs->ip are because of an
-	 * instruction fetch. Return early and avoid
-	 * emulation for faults during data accesses:
-	 */
-	if (address != regs->ip) {
-		/* Failed vsyscall read */
-		if (vsyscall_mode == EMULATE)
-			return false;
-
-		/*
-		 * User code tried and failed to read the vsyscall page.
-		 */
-		warn_bad_vsyscall(KERN_INFO, regs, "vsyscall read attempt denied -- look up the vsyscall kernel parameter if you need a workaround");
-		return false;
-	}
-
-	/*
-	 * X86_PF_INSTR is only set when NX is supported.  When
-	 * available, use it to double-check that the emulation code
-	 * is only being used for instruction fetches:
-	 */
-	if (cpu_feature_enabled(X86_FEATURE_NX))
-		WARN_ON_ONCE(!(error_code & X86_PF_INSTR));
-
 	/*
 	 * No point in checking CS -- the only way to get here is a user mode
 	 * trap to a high address, which means that we're in 64-bit user code.
@@ -280,6 +250,40 @@ bool emulate_vsyscall(unsigned long error_code,
 	return true;
 }
 
+bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs,
+			 unsigned long address)
+{
+	/* Write faults or kernel-privilege faults never get fixed up. */
+	if ((error_code & (X86_PF_WRITE | X86_PF_USER)) != X86_PF_USER)
+		return false;
+
+	/*
+	 * Assume that faults at regs->ip are because of an instruction
+	 * fetch. Return early and avoid emulation for faults during
+	 * data accesses:
+	 */
+	if (address != regs->ip) {
+		/* Failed vsyscall read */
+		if (vsyscall_mode == EMULATE)
+			return false;
+
+		/* User code tried and failed to read the vsyscall page. */
+		warn_bad_vsyscall(KERN_INFO, regs,
+				  "vsyscall read attempt denied -- look up the vsyscall kernel parameter if you need a workaround");
+		return false;
+	}
+
+	/*
+	 * X86_PF_INSTR is only set when NX is supported.  When
+	 * available, use it to double-check that the emulation code
+	 * is only being used for instruction fetches:
+	 */
+	if (cpu_feature_enabled(X86_FEATURE_NX))
+		WARN_ON_ONCE(!(error_code & X86_PF_INSTR));
+
+	return __emulate_vsyscall(regs, address);
+}
+
 /*
  * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
  * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index 472f0263dbc6..f34902364972 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -14,12 +14,11 @@ extern void set_vsyscall_pgtable_user_bits(pgd_t *root);
  * Called on instruction fetch fault in vsyscall page.
  * Returns true if handled.
  */
-extern bool emulate_vsyscall(unsigned long error_code,
-			     struct pt_regs *regs, unsigned long address);
+bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs, unsigned long address);
 #else
 static inline void map_vsyscall(void) {}
-static inline bool emulate_vsyscall(unsigned long error_code,
-				    struct pt_regs *regs, unsigned long address)
+static inline bool emulate_vsyscall_pf(unsigned long error_code,
+				       struct pt_regs *regs, unsigned long address)
 {
 	return false;
 }
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index b83a06739b51..f0e77e084482 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1314,7 +1314,7 @@ void do_user_addr_fault(struct pt_regs *regs,
 	 * to consider the PF_PK bit.
 	 */
 	if (is_vsyscall_vaddr(address)) {
-		if (emulate_vsyscall(error_code, regs, address))
+		if (emulate_vsyscall_pf(error_code, regs, address))
 			return;
 	}
 #endif
-- 
2.43.0


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

* [PATCH v3 2/5] x86/traps: Consolidate user fixups in the #GP handler
  2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 1/5] x86/vsyscall: Reorganize the page fault emulation code Sohil Mehta
@ 2026-03-09 18:10 ` Sohil Mehta
  2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 3/5] x86/vsyscall: Restore vsyscall=xonly mode under LASS Sohil Mehta
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Sohil Mehta @ 2026-03-09 18:10 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Sohil Mehta, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

Move the UMIP exception fixup under the common "if (user_mode(regs))"
condition where the rest of user mode fixups reside. Also, move the UMIP
feature check into its fixup function to keep the calling code
consistent and clean.

No functional change intended.

Suggested-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
v3:
 - Pickup review and tested-by tags.

v2:
 - No change
---
 arch/x86/kernel/traps.c | 8 +++-----
 arch/x86/kernel/umip.c  | 3 +++
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 4dbff8ef9b1c..614a281bd419 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -921,11 +921,6 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 
 	cond_local_irq_enable(regs);
 
-	if (static_cpu_has(X86_FEATURE_UMIP)) {
-		if (user_mode(regs) && fixup_umip_exception(regs))
-			goto exit;
-	}
-
 	if (v8086_mode(regs)) {
 		local_irq_enable();
 		handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
@@ -940,6 +935,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 		if (fixup_vdso_exception(regs, X86_TRAP_GP, error_code, 0))
 			goto exit;
 
+		if (fixup_umip_exception(regs))
+			goto exit;
+
 		gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
 		goto exit;
 	}
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c
index d432f3824f0c..3ce99cbcf187 100644
--- a/arch/x86/kernel/umip.c
+++ b/arch/x86/kernel/umip.c
@@ -354,6 +354,9 @@ bool fixup_umip_exception(struct pt_regs *regs)
 	void __user *uaddr;
 	struct insn insn;
 
+	if (!cpu_feature_enabled(X86_FEATURE_UMIP))
+		return false;
+
 	if (!regs)
 		return false;
 
-- 
2.43.0


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

* [PATCH v3 3/5] x86/vsyscall: Restore vsyscall=xonly mode under LASS
  2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 1/5] x86/vsyscall: Reorganize the page fault emulation code Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 2/5] x86/traps: Consolidate user fixups in the #GP handler Sohil Mehta
@ 2026-03-09 18:10 ` Sohil Mehta
  2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 4/5] x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE Sohil Mehta
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Sohil Mehta @ 2026-03-09 18:10 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Sohil Mehta, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

Background
==========
The vsyscall page is located in the high/kernel part of the address
space. Prior to LASS, a vsyscall page access from userspace would always
generate a #PF. The kernel emulates the accesses in the #PF handler and
returns the appropriate values to userspace.

Vsyscall emulation has two modes of operation, specified by the
vsyscall={xonly, emulate} kernel command line option. The vsyscall page
behaves as execute-only in XONLY mode or read-execute in EMULATE mode.
XONLY mode is the default and the only one expected to be commonly used.
The EMULATE mode has been deprecated since 2022 and is considered
insecure.

With LASS, a vsyscall page access triggers a #GP instead of a #PF.
Currently, LASS is only enabled when all vsyscall modes are disabled.

LASS with XONLY mode
====================
Now add support for LASS specifically with XONLY vsyscall emulation. For
XONLY mode, all that is needed is the faulting RIP, which is trivially
available regardless of the type of fault. Reuse the #PF emulation code
during the #GP when the fault address points to the vsyscall page.

As multiple fault handlers will now be using the emulation code, add a
sanity check to ensure that the fault truly happened in 64-bit user
mode.

LASS with EMULATE mode
======================
Supporting vsyscall=emulate with LASS is much harder because the #GP
doesn't provide enough error information (such as PFEC and CR2 as in
case of a #PF). So, complex instruction decoding would be required to
emulate this mode in the #GP handler.

This isn't worth the effort as remaining users of EMULATE mode can be
reasonably assumed to be niche users, who are already trading off
security for compatibility. LASS and vsyscall=emulate will be kept
mutually exclusive for simplicity.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
v3:
 - Pick up review and tested-by tags.

v2:
 - Rewrote the commit message
---
 arch/x86/entry/vsyscall/vsyscall_64.c | 22 +++++++++++++++++-----
 arch/x86/include/asm/vsyscall.h       |  6 ++++++
 arch/x86/kernel/traps.c               |  4 ++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 398b1ed16f1e..e740f3b42278 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -23,7 +23,7 @@
  * soon be no new userspace code that will ever use a vsyscall.
  *
  * The code in this file emulates vsyscalls when notified of a page
- * fault to a vsyscall address.
+ * fault or a general protection fault to a vsyscall address.
  */
 
 #include <linux/kernel.h>
@@ -118,10 +118,9 @@ static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 	long ret;
 	unsigned long orig_dx;
 
-	/*
-	 * No point in checking CS -- the only way to get here is a user mode
-	 * trap to a high address, which means that we're in 64-bit user code.
-	 */
+	/* Confirm that the fault happened in 64-bit user mode */
+	if (!user_64bit_mode(regs))
+		return false;
 
 	if (vsyscall_mode == NONE) {
 		warn_bad_vsyscall(KERN_INFO, regs,
@@ -284,6 +283,19 @@ bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs,
 	return __emulate_vsyscall(regs, address);
 }
 
+bool emulate_vsyscall_gp(struct pt_regs *regs)
+{
+	/* Without LASS, vsyscall accesses are expected to generate a #PF */
+	if (!cpu_feature_enabled(X86_FEATURE_LASS))
+		return false;
+
+	/* Emulate only if the RIP points to the vsyscall address */
+	if (!is_vsyscall_vaddr(regs->ip))
+		return false;
+
+	return __emulate_vsyscall(regs, regs->ip);
+}
+
 /*
  * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
  * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index f34902364972..538053b1656a 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -15,6 +15,7 @@ extern void set_vsyscall_pgtable_user_bits(pgd_t *root);
  * Returns true if handled.
  */
 bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs, unsigned long address);
+bool emulate_vsyscall_gp(struct pt_regs *regs);
 #else
 static inline void map_vsyscall(void) {}
 static inline bool emulate_vsyscall_pf(unsigned long error_code,
@@ -22,6 +23,11 @@ static inline bool emulate_vsyscall_pf(unsigned long error_code,
 {
 	return false;
 }
+
+static inline bool emulate_vsyscall_gp(struct pt_regs *regs)
+{
+	return false;
+}
 #endif
 
 /*
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 614a281bd419..0ca3912ecb7f 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -70,6 +70,7 @@
 #include <asm/tdx.h>
 #include <asm/cfi.h>
 #include <asm/msr.h>
+#include <asm/vsyscall.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/x86_init.h>
@@ -938,6 +939,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 		if (fixup_umip_exception(regs))
 			goto exit;
 
+		if (emulate_vsyscall_gp(regs))
+			goto exit;
+
 		gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
 		goto exit;
 	}
-- 
2.43.0


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

* [PATCH v3 4/5] x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE
  2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
                   ` (2 preceding siblings ...)
  2026-03-09 18:10 ` [PATCH v3 3/5] x86/vsyscall: Restore vsyscall=xonly mode under LASS Sohil Mehta
@ 2026-03-09 18:10 ` Sohil Mehta
  2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
  2026-03-09 18:10 ` [PATCH v3 5/5] x86/cpu: Remove LASS restriction on vsyscall emulation Sohil Mehta
  2026-03-19 18:46 ` [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
  5 siblings, 1 reply; 12+ messages in thread
From: Sohil Mehta @ 2026-03-09 18:10 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Sohil Mehta, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

The EMULATE mode of vsyscall maps the vsyscall page with a high kernel
address directly into user address space. Reading the vsyscall page in
EMULATE mode would cause LASS to trigger a #GP.

Fixing the LASS violation in EMULATE mode would require complex
instruction decoding because the resulting #GP does include the
necessary error information, and the vsyscall address is not
readily available in the RIP.

The EMULATE mode has been deprecated since 2022 and can only be enabled
using the command line parameter vsyscall=emulate. See commit
bf00745e7791 ("x86/vsyscall: Remove CONFIG_LEGACY_VSYSCALL_EMULATE") for
details. At this point, no one is expected to be using this insecure
mode. The rare usages that need it obviously do not care about security.

Disable LASS when EMULATE mode is requested to avoid breaking legacy
user software. Also, update the vsyscall documentation to reflect this.
LASS will only be supported if vsyscall mode is set to XONLY (default)
or NONE.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
Eventually, the plan is to get rid of the EMULATE mode altogether. Linus
and AndyL seem to be okay with such a change. However, those changes are
beyond the scope of this series.

v3:
 - Pick up review and tested-by tags.

v2:
 - Picked up Dave's review tag
 - Removed unnecessary CR4 clearing during vsyscall_setup().
   CR4.LASS is enabled much later via a late_initcall().
---
 Documentation/admin-guide/kernel-parameters.txt | 4 +++-
 arch/x86/entry/vsyscall/vsyscall_64.c           | 5 +++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index cb850e5290c2..64df2c52b2e5 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -8376,7 +8376,9 @@ Kernel parameters
 
 			emulate     Vsyscalls turn into traps and are emulated
 			            reasonably safely.  The vsyscall page is
-				    readable.
+				    readable.  This disables the Linear
+				    Address Space Separation (LASS) security
+				    feature and makes the system less secure.
 
 			xonly       [default] Vsyscalls turn into traps and are
 			            emulated reasonably safely.  The vsyscall
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index e740f3b42278..ea36de9fa864 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -62,6 +62,11 @@ static int __init vsyscall_setup(char *str)
 		else
 			return -EINVAL;
 
+		if (cpu_feature_enabled(X86_FEATURE_LASS) && vsyscall_mode == EMULATE) {
+			setup_clear_cpu_cap(X86_FEATURE_LASS);
+			pr_warn_once("x86/cpu: Disabling LASS due to vsyscall=emulate\n");
+		}
+
 		return 0;
 	}
 
-- 
2.43.0


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

* [PATCH v3 5/5] x86/cpu: Remove LASS restriction on vsyscall emulation
  2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
                   ` (3 preceding siblings ...)
  2026-03-09 18:10 ` [PATCH v3 4/5] x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE Sohil Mehta
@ 2026-03-09 18:10 ` Sohil Mehta
  2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
  2026-03-19 18:46 ` [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
  5 siblings, 1 reply; 12+ messages in thread
From: Sohil Mehta @ 2026-03-09 18:10 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Sohil Mehta, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

Vsyscall emulation has two modes of operation: XONLY and EMULATE. The
default XONLY mode is now supported with a LASS-triggered #GP. OTOH,
LASS is disabled if someone requests the deprecated EMULATE mode via the
vsyscall=emulate command line option. So, remove the restriction on LASS
when the overall vsyscall emulation support is compiled in.

As a result, there is no need for setup_lass() anymore. LASS is enabled
by default through a late_initcall().

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
v3:
 - Pick up review and tested-by tags.

v2:
 - Picked up Dave's review tag
 - Improve commit message
---
 arch/x86/kernel/cpu/common.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 3557f0e6b3aa..02472fc763d9 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -406,20 +406,6 @@ static __always_inline void setup_umip(struct cpuinfo_x86 *c)
 	cr4_clear_bits(X86_CR4_UMIP);
 }
 
-static __always_inline void setup_lass(struct cpuinfo_x86 *c)
-{
-	if (!cpu_feature_enabled(X86_FEATURE_LASS))
-		return;
-
-	/*
-	 * Legacy vsyscall page access causes a #GP when LASS is active.
-	 * Disable LASS because the #GP handler doesn't support vsyscall
-	 * emulation.
-	 */
-	if (IS_ENABLED(CONFIG_X86_VSYSCALL_EMULATION))
-		setup_clear_cpu_cap(X86_FEATURE_LASS);
-}
-
 static int enable_lass(unsigned int cpu)
 {
 	cr4_set_bits(X86_CR4_LASS);
@@ -2061,7 +2047,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 	setup_smep(c);
 	setup_smap(c);
 	setup_umip(c);
-	setup_lass(c);
 
 	/* Enable FSGSBASE instructions if available. */
 	if (cpu_has(c, X86_FEATURE_FSGSBASE)) {
-- 
2.43.0


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

* Re: [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode
  2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
                   ` (4 preceding siblings ...)
  2026-03-09 18:10 ` [PATCH v3 5/5] x86/cpu: Remove LASS restriction on vsyscall emulation Sohil Mehta
@ 2026-03-19 18:46 ` Sohil Mehta
  5 siblings, 0 replies; 12+ messages in thread
From: Sohil Mehta @ 2026-03-19 18:46 UTC (permalink / raw)
  To: Dave Hansen, x86, Andy Lutomirski, Borislav Petkov
  Cc: Jonathan Corbet, Shuah Khan, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, Peter Zijlstra, Kiryl Shutsemau,
	Brendan Jackman, Sean Christopherson, Nam Cao, Cedric Xing,
	Rick Edgecombe, Andrew Cooper, Tony Luck, Alexander Shishkin,
	Maciej Wieczor-Retman, linux-doc, linux-kernel

On 3/9/2026 11:10 AM, Sohil Mehta wrote:
> Linear Address Space Separation (LASS) is currently disabled [1] when
> support for vsyscall emulation is configured. This series extends LASS
> support specifically to the default mode (vsyscall=xonly).
> 

x86 maintainers, this series seems to be ready to me. Are there any
additional changes you are looking for?

There are a couple of small vsyscall related improvements that are based
on this series. They are completely independent of LASS, so I haven't
included them here.

https://lore.kernel.org/lkml/20260305232136.224922-1-hpa@zytor.com/

https://lore.kernel.org/lkml/51f5dc8d-e130-4769-84e2-588553c7fde3@intel.com/

Please let me know if you would prefer that I include them at the end
and send out another version.

> Sohil Mehta (5):
>   x86/vsyscall: Reorganize the page fault emulation code
>   x86/traps: Consolidate user fixups in the #GP handler
>   x86/vsyscall: Restore vsyscall=xonly mode under LASS
>   x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE
>   x86/cpu: Remove LASS restriction on vsyscall emulation
> 
>  .../admin-guide/kernel-parameters.txt         |  4 +-
>  arch/x86/entry/vsyscall/vsyscall_64.c         | 91 ++++++++++++-------
>  arch/x86/include/asm/vsyscall.h               | 13 ++-
>  arch/x86/kernel/cpu/common.c                  | 15 ---
>  arch/x86/kernel/traps.c                       | 12 ++-
>  arch/x86/kernel/umip.c                        |  3 +
>  arch/x86/mm/fault.c                           |  2 +-
>  7 files changed, 79 insertions(+), 61 deletions(-)
> 
> 
> base-commit: 68400c1aaf02636a97c45ba198110b66feb270a9


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

* [tip: x86/cpu] x86/cpu: Remove LASS restriction on vsyscall emulation
  2026-03-09 18:10 ` [PATCH v3 5/5] x86/cpu: Remove LASS restriction on vsyscall emulation Sohil Mehta
@ 2026-03-19 22:59   ` tip-bot2 for Sohil Mehta
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Sohil Mehta @ 2026-03-19 22:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sohil Mehta, Dave Hansen, H. Peter Anvin (Intel),
	Maciej Wieczor-Retman, x86, linux-kernel

The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     584d752b8a1f0ee3a7d5a831e55623c10e7ca0ee
Gitweb:        https://git.kernel.org/tip/584d752b8a1f0ee3a7d5a831e55623c10e7ca0ee
Author:        Sohil Mehta <sohil.mehta@intel.com>
AuthorDate:    Mon, 09 Mar 2026 11:10:29 -07:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Thu, 19 Mar 2026 15:11:13 -07:00

x86/cpu: Remove LASS restriction on vsyscall emulation

Vsyscall emulation has two modes of operation: XONLY and EMULATE. The
default XONLY mode is now supported with a LASS-triggered #GP. OTOH,
LASS is disabled if someone requests the deprecated EMULATE mode via the
vsyscall=emulate command line option. So, remove the restriction on LASS
when the overall vsyscall emulation support is compiled in.

As a result, there is no need for setup_lass() anymore. LASS is enabled
by default through a late_initcall().

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by:
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Link: https://patch.msgid.link/20260309181029.398498-6-sohil.mehta@intel.com
---
 arch/x86/kernel/cpu/common.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 3557f0e..02472fc 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -406,20 +406,6 @@ out:
 	cr4_clear_bits(X86_CR4_UMIP);
 }
 
-static __always_inline void setup_lass(struct cpuinfo_x86 *c)
-{
-	if (!cpu_feature_enabled(X86_FEATURE_LASS))
-		return;
-
-	/*
-	 * Legacy vsyscall page access causes a #GP when LASS is active.
-	 * Disable LASS because the #GP handler doesn't support vsyscall
-	 * emulation.
-	 */
-	if (IS_ENABLED(CONFIG_X86_VSYSCALL_EMULATION))
-		setup_clear_cpu_cap(X86_FEATURE_LASS);
-}
-
 static int enable_lass(unsigned int cpu)
 {
 	cr4_set_bits(X86_CR4_LASS);
@@ -2061,7 +2047,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 	setup_smep(c);
 	setup_smap(c);
 	setup_umip(c);
-	setup_lass(c);
 
 	/* Enable FSGSBASE instructions if available. */
 	if (cpu_has(c, X86_FEATURE_FSGSBASE)) {

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

* [tip: x86/cpu] x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE
  2026-03-09 18:10 ` [PATCH v3 4/5] x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE Sohil Mehta
@ 2026-03-19 22:59   ` tip-bot2 for Sohil Mehta
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Sohil Mehta @ 2026-03-19 22:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sohil Mehta, Dave Hansen, Rick Edgecombe, H. Peter Anvin (Intel),
	Maciej Wieczor-Retman, x86, linux-kernel

The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     b36d1f53d90c869d5f02fe0d8603f825013e746e
Gitweb:        https://git.kernel.org/tip/b36d1f53d90c869d5f02fe0d8603f825013e746e
Author:        Sohil Mehta <sohil.mehta@intel.com>
AuthorDate:    Mon, 09 Mar 2026 11:10:28 -07:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Thu, 19 Mar 2026 15:11:13 -07:00

x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE

The EMULATE mode of vsyscall maps the vsyscall page with a high kernel
address directly into user address space. Reading the vsyscall page in
EMULATE mode would cause LASS to trigger a #GP.

Fixing the LASS violation in EMULATE mode would require complex
instruction decoding because the resulting #GP does include the
necessary error information, and the vsyscall address is not
readily available in the RIP.

The EMULATE mode has been deprecated since 2022 and can only be enabled
using the command line parameter vsyscall=emulate. See commit
bf00745e7791 ("x86/vsyscall: Remove CONFIG_LEGACY_VSYSCALL_EMULATE") for
details. At this point, no one is expected to be using this insecure
mode. The rare usages that need it obviously do not care about security.

Disable LASS when EMULATE mode is requested to avoid breaking legacy
user software. Also, update the vsyscall documentation to reflect this.
LASS will only be supported if vsyscall mode is set to XONLY (default)
or NONE.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Link: https://patch.msgid.link/20260309181029.398498-5-sohil.mehta@intel.com
---
 Documentation/admin-guide/kernel-parameters.txt | 4 +++-
 arch/x86/entry/vsyscall/vsyscall_64.c           | 5 +++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index cb850e5..64df2c5 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -8376,7 +8376,9 @@ Kernel parameters
 
 			emulate     Vsyscalls turn into traps and are emulated
 			            reasonably safely.  The vsyscall page is
-				    readable.
+				    readable.  This disables the Linear
+				    Address Space Separation (LASS) security
+				    feature and makes the system less secure.
 
 			xonly       [default] Vsyscalls turn into traps and are
 			            emulated reasonably safely.  The vsyscall
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index e740f3b..ea36de9 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -62,6 +62,11 @@ static int __init vsyscall_setup(char *str)
 		else
 			return -EINVAL;
 
+		if (cpu_feature_enabled(X86_FEATURE_LASS) && vsyscall_mode == EMULATE) {
+			setup_clear_cpu_cap(X86_FEATURE_LASS);
+			pr_warn_once("x86/cpu: Disabling LASS due to vsyscall=emulate\n");
+		}
+
 		return 0;
 	}
 

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

* [tip: x86/cpu] x86/vsyscall: Restore vsyscall=xonly mode under LASS
  2026-03-09 18:10 ` [PATCH v3 3/5] x86/vsyscall: Restore vsyscall=xonly mode under LASS Sohil Mehta
@ 2026-03-19 22:59   ` tip-bot2 for Sohil Mehta
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Sohil Mehta @ 2026-03-19 22:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sohil Mehta, Dave Hansen, H. Peter Anvin (Intel),
	Maciej Wieczor-Retman, x86, linux-kernel

The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     8376b503b0f18d7425b42621798518e61e2ea601
Gitweb:        https://git.kernel.org/tip/8376b503b0f18d7425b42621798518e61e2ea601
Author:        Sohil Mehta <sohil.mehta@intel.com>
AuthorDate:    Mon, 09 Mar 2026 11:10:27 -07:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Thu, 19 Mar 2026 15:11:13 -07:00

x86/vsyscall: Restore vsyscall=xonly mode under LASS

Background
==========
The vsyscall page is located in the high/kernel part of the address
space. Prior to LASS, a vsyscall page access from userspace would always
generate a #PF. The kernel emulates the accesses in the #PF handler and
returns the appropriate values to userspace.

Vsyscall emulation has two modes of operation, specified by the
vsyscall={xonly, emulate} kernel command line option. The vsyscall page
behaves as execute-only in XONLY mode or read-execute in EMULATE mode.
XONLY mode is the default and the only one expected to be commonly used.
The EMULATE mode has been deprecated since 2022 and is considered
insecure.

With LASS, a vsyscall page access triggers a #GP instead of a #PF.
Currently, LASS is only enabled when all vsyscall modes are disabled.

LASS with XONLY mode
====================
Now add support for LASS specifically with XONLY vsyscall emulation. For
XONLY mode, all that is needed is the faulting RIP, which is trivially
available regardless of the type of fault. Reuse the #PF emulation code
during the #GP when the fault address points to the vsyscall page.

As multiple fault handlers will now be using the emulation code, add a
sanity check to ensure that the fault truly happened in 64-bit user
mode.

LASS with EMULATE mode
======================
Supporting vsyscall=emulate with LASS is much harder because the #GP
doesn't provide enough error information (such as PFEC and CR2 as in
case of a #PF). So, complex instruction decoding would be required to
emulate this mode in the #GP handler.

This isn't worth the effort as remaining users of EMULATE mode can be
reasonably assumed to be niche users, who are already trading off
security for compatibility. LASS and vsyscall=emulate will be kept
mutually exclusive for simplicity.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Link: https://patch.msgid.link/20260309181029.398498-4-sohil.mehta@intel.com
---
 arch/x86/entry/vsyscall/vsyscall_64.c | 22 +++++++++++++++++-----
 arch/x86/include/asm/vsyscall.h       |  6 ++++++
 arch/x86/kernel/traps.c               |  4 ++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 398b1ed..e740f3b 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -23,7 +23,7 @@
  * soon be no new userspace code that will ever use a vsyscall.
  *
  * The code in this file emulates vsyscalls when notified of a page
- * fault to a vsyscall address.
+ * fault or a general protection fault to a vsyscall address.
  */
 
 #include <linux/kernel.h>
@@ -118,10 +118,9 @@ static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 	long ret;
 	unsigned long orig_dx;
 
-	/*
-	 * No point in checking CS -- the only way to get here is a user mode
-	 * trap to a high address, which means that we're in 64-bit user code.
-	 */
+	/* Confirm that the fault happened in 64-bit user mode */
+	if (!user_64bit_mode(regs))
+		return false;
 
 	if (vsyscall_mode == NONE) {
 		warn_bad_vsyscall(KERN_INFO, regs,
@@ -284,6 +283,19 @@ bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs,
 	return __emulate_vsyscall(regs, address);
 }
 
+bool emulate_vsyscall_gp(struct pt_regs *regs)
+{
+	/* Without LASS, vsyscall accesses are expected to generate a #PF */
+	if (!cpu_feature_enabled(X86_FEATURE_LASS))
+		return false;
+
+	/* Emulate only if the RIP points to the vsyscall address */
+	if (!is_vsyscall_vaddr(regs->ip))
+		return false;
+
+	return __emulate_vsyscall(regs, regs->ip);
+}
+
 /*
  * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
  * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index f349023..538053b 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -15,6 +15,7 @@ extern void set_vsyscall_pgtable_user_bits(pgd_t *root);
  * Returns true if handled.
  */
 bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs, unsigned long address);
+bool emulate_vsyscall_gp(struct pt_regs *regs);
 #else
 static inline void map_vsyscall(void) {}
 static inline bool emulate_vsyscall_pf(unsigned long error_code,
@@ -22,6 +23,11 @@ static inline bool emulate_vsyscall_pf(unsigned long error_code,
 {
 	return false;
 }
+
+static inline bool emulate_vsyscall_gp(struct pt_regs *regs)
+{
+	return false;
+}
 #endif
 
 /*
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 614a281..0ca3912 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -70,6 +70,7 @@
 #include <asm/tdx.h>
 #include <asm/cfi.h>
 #include <asm/msr.h>
+#include <asm/vsyscall.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/x86_init.h>
@@ -938,6 +939,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 		if (fixup_umip_exception(regs))
 			goto exit;
 
+		if (emulate_vsyscall_gp(regs))
+			goto exit;
+
 		gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
 		goto exit;
 	}

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

* [tip: x86/cpu] x86/traps: Consolidate user fixups in the #GP handler
  2026-03-09 18:10 ` [PATCH v3 2/5] x86/traps: Consolidate user fixups in the #GP handler Sohil Mehta
@ 2026-03-19 22:59   ` tip-bot2 for Sohil Mehta
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Sohil Mehta @ 2026-03-19 22:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Dave Hansen, Sohil Mehta, Dave Hansen, H. Peter Anvin (Intel),
	Maciej Wieczor-Retman, x86, linux-kernel

The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     4e57fdd11083d5cd44febc4b6613777291ec936e
Gitweb:        https://git.kernel.org/tip/4e57fdd11083d5cd44febc4b6613777291ec936e
Author:        Sohil Mehta <sohil.mehta@intel.com>
AuthorDate:    Mon, 09 Mar 2026 11:10:26 -07:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Thu, 19 Mar 2026 15:11:13 -07:00

x86/traps: Consolidate user fixups in the #GP handler

Move the UMIP exception fixup under the common "if (user_mode(regs))"
condition where the rest of user mode fixups reside. Also, move the UMIP
feature check into its fixup function to keep the calling code
consistent and clean.

No functional change intended.

Suggested-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Link: https://patch.msgid.link/20260309181029.398498-3-sohil.mehta@intel.com
---
 arch/x86/kernel/traps.c | 8 +++-----
 arch/x86/kernel/umip.c  | 3 +++
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 4dbff8e..614a281 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -921,11 +921,6 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 
 	cond_local_irq_enable(regs);
 
-	if (static_cpu_has(X86_FEATURE_UMIP)) {
-		if (user_mode(regs) && fixup_umip_exception(regs))
-			goto exit;
-	}
-
 	if (v8086_mode(regs)) {
 		local_irq_enable();
 		handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
@@ -940,6 +935,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 		if (fixup_vdso_exception(regs, X86_TRAP_GP, error_code, 0))
 			goto exit;
 
+		if (fixup_umip_exception(regs))
+			goto exit;
+
 		gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
 		goto exit;
 	}
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c
index d432f38..3ce99cb 100644
--- a/arch/x86/kernel/umip.c
+++ b/arch/x86/kernel/umip.c
@@ -354,6 +354,9 @@ bool fixup_umip_exception(struct pt_regs *regs)
 	void __user *uaddr;
 	struct insn insn;
 
+	if (!cpu_feature_enabled(X86_FEATURE_UMIP))
+		return false;
+
 	if (!regs)
 		return false;
 

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

* [tip: x86/cpu] x86/vsyscall: Reorganize the page fault emulation code
  2026-03-09 18:10 ` [PATCH v3 1/5] x86/vsyscall: Reorganize the page fault emulation code Sohil Mehta
@ 2026-03-19 22:59   ` tip-bot2 for Sohil Mehta
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Sohil Mehta @ 2026-03-19 22:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Sohil Mehta, Dave Hansen, H. Peter Anvin (Intel),
	Maciej Wieczor-Retman, x86, linux-kernel

The following commit has been merged into the x86/cpu branch of tip:

Commit-ID:     3ddd2e12c704f22c28efb714817c88ee4e25688a
Gitweb:        https://git.kernel.org/tip/3ddd2e12c704f22c28efb714817c88ee4e25688a
Author:        Sohil Mehta <sohil.mehta@intel.com>
AuthorDate:    Mon, 09 Mar 2026 11:10:25 -07:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Thu, 19 Mar 2026 15:11:12 -07:00

x86/vsyscall: Reorganize the page fault emulation code

With LASS, vsyscall page accesses will cause a #GP instead of a #PF.
Separate out the core vsyscall emulation code from the #PF specific
handling in preparation for the upcoming #GP emulation.

No functional change intended.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Link: https://patch.msgid.link/20260309181029.398498-2-sohil.mehta@intel.com
---
 arch/x86/entry/vsyscall/vsyscall_64.c | 66 +++++++++++++-------------
 arch/x86/include/asm/vsyscall.h       |  7 +--
 arch/x86/mm/fault.c                   |  2 +-
 3 files changed, 39 insertions(+), 36 deletions(-)

diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 4bd1e27..398b1ed 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -111,43 +111,13 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size)
 	}
 }
 
-bool emulate_vsyscall(unsigned long error_code,
-		      struct pt_regs *regs, unsigned long address)
+static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 {
 	unsigned long caller;
 	int vsyscall_nr, syscall_nr, tmp;
 	long ret;
 	unsigned long orig_dx;
 
-	/* Write faults or kernel-privilege faults never get fixed up. */
-	if ((error_code & (X86_PF_WRITE | X86_PF_USER)) != X86_PF_USER)
-		return false;
-
-	/*
-	 * Assume that faults at regs->ip are because of an
-	 * instruction fetch. Return early and avoid
-	 * emulation for faults during data accesses:
-	 */
-	if (address != regs->ip) {
-		/* Failed vsyscall read */
-		if (vsyscall_mode == EMULATE)
-			return false;
-
-		/*
-		 * User code tried and failed to read the vsyscall page.
-		 */
-		warn_bad_vsyscall(KERN_INFO, regs, "vsyscall read attempt denied -- look up the vsyscall kernel parameter if you need a workaround");
-		return false;
-	}
-
-	/*
-	 * X86_PF_INSTR is only set when NX is supported.  When
-	 * available, use it to double-check that the emulation code
-	 * is only being used for instruction fetches:
-	 */
-	if (cpu_feature_enabled(X86_FEATURE_NX))
-		WARN_ON_ONCE(!(error_code & X86_PF_INSTR));
-
 	/*
 	 * No point in checking CS -- the only way to get here is a user mode
 	 * trap to a high address, which means that we're in 64-bit user code.
@@ -280,6 +250,40 @@ sigsegv:
 	return true;
 }
 
+bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs,
+			 unsigned long address)
+{
+	/* Write faults or kernel-privilege faults never get fixed up. */
+	if ((error_code & (X86_PF_WRITE | X86_PF_USER)) != X86_PF_USER)
+		return false;
+
+	/*
+	 * Assume that faults at regs->ip are because of an instruction
+	 * fetch. Return early and avoid emulation for faults during
+	 * data accesses:
+	 */
+	if (address != regs->ip) {
+		/* Failed vsyscall read */
+		if (vsyscall_mode == EMULATE)
+			return false;
+
+		/* User code tried and failed to read the vsyscall page. */
+		warn_bad_vsyscall(KERN_INFO, regs,
+				  "vsyscall read attempt denied -- look up the vsyscall kernel parameter if you need a workaround");
+		return false;
+	}
+
+	/*
+	 * X86_PF_INSTR is only set when NX is supported.  When
+	 * available, use it to double-check that the emulation code
+	 * is only being used for instruction fetches:
+	 */
+	if (cpu_feature_enabled(X86_FEATURE_NX))
+		WARN_ON_ONCE(!(error_code & X86_PF_INSTR));
+
+	return __emulate_vsyscall(regs, address);
+}
+
 /*
  * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
  * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index 472f026..f349023 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -14,12 +14,11 @@ extern void set_vsyscall_pgtable_user_bits(pgd_t *root);
  * Called on instruction fetch fault in vsyscall page.
  * Returns true if handled.
  */
-extern bool emulate_vsyscall(unsigned long error_code,
-			     struct pt_regs *regs, unsigned long address);
+bool emulate_vsyscall_pf(unsigned long error_code, struct pt_regs *regs, unsigned long address);
 #else
 static inline void map_vsyscall(void) {}
-static inline bool emulate_vsyscall(unsigned long error_code,
-				    struct pt_regs *regs, unsigned long address)
+static inline bool emulate_vsyscall_pf(unsigned long error_code,
+				       struct pt_regs *regs, unsigned long address)
 {
 	return false;
 }
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index b83a067..f0e77e0 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1314,7 +1314,7 @@ void do_user_addr_fault(struct pt_regs *regs,
 	 * to consider the PF_PK bit.
 	 */
 	if (is_vsyscall_vaddr(address)) {
-		if (emulate_vsyscall(error_code, regs, address))
+		if (emulate_vsyscall_pf(error_code, regs, address))
 			return;
 	}
 #endif

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

end of thread, other threads:[~2026-03-19 22:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-09 18:10 [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta
2026-03-09 18:10 ` [PATCH v3 1/5] x86/vsyscall: Reorganize the page fault emulation code Sohil Mehta
2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
2026-03-09 18:10 ` [PATCH v3 2/5] x86/traps: Consolidate user fixups in the #GP handler Sohil Mehta
2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
2026-03-09 18:10 ` [PATCH v3 3/5] x86/vsyscall: Restore vsyscall=xonly mode under LASS Sohil Mehta
2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
2026-03-09 18:10 ` [PATCH v3 4/5] x86/vsyscall: Disable LASS if vsyscall mode is set to EMULATE Sohil Mehta
2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
2026-03-09 18:10 ` [PATCH v3 5/5] x86/cpu: Remove LASS restriction on vsyscall emulation Sohil Mehta
2026-03-19 22:59   ` [tip: x86/cpu] " tip-bot2 for Sohil Mehta
2026-03-19 18:46 ` [PATCH v3 0/5] x86: Enable LASS support with vsyscall=xonly mode Sohil Mehta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox