.../admin-guide/kernel-parameters.txt | 4 +- arch/x86/entry/vsyscall/vsyscall_64.c | 89 +++++++++++-------- 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, 77 insertions(+), 61 deletions(-)
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 XONLY mode (vsyscall=xonly). Changes in v2 ------------- - Pick up review tags from Dave. - Improve commit messages based on feedback from Dave and Peter. - Minor change in patch 4 to avoid unnecessary clearing of CR4.LASS. v1: https://lore.kernel.org/lkml/20260219233600.154313-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 | 89 +++++++++++-------- 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, 77 insertions(+), 61 deletions(-) base-commit: 68400c1aaf02636a97c45ba198110b66feb270a9 -- 2.43.0
Hi! Tested the patchset on a Sierra Forest system using mostly the selftest and checking out the feature status. Verified all combinations of config options and cmdline arguments behave as expected. Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com> Kind regards Maciej Wieczór-Retman On 2026-03-05 at 13:40:21 -0800, 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 XONLY mode (vsyscall=xonly). > >Changes in v2 >------------- >- Pick up review tags from Dave. >- Improve commit messages based on feedback from Dave and Peter. >- Minor change in patch 4 to avoid unnecessary clearing of CR4.LASS. > >v1: https://lore.kernel.org/lkml/20260219233600.154313-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 | 89 +++++++++++-------- > 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, 77 insertions(+), 61 deletions(-) > > >base-commit: 68400c1aaf02636a97c45ba198110b66feb270a9 >-- >2.43.0 >
Reviewing Sohil's LASS patchset inspired me to cook up a very small cleanup patch, removing some unnecessary conditional compilation. It is on top of Sohil's patchset, but it is really orthogonal to it; the patch applies with fuzz (line changes and the renaming of emulate_vsyscall() to emulate_vsyscall_pf() in the context) to the unmodified upstream kernel as well. -hpa --- arch/x86/include/asm/vsyscall.h | 3 ++- arch/x86/mm/fault.c | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-)
In one location, there is an IS_ENABLED(CONFIG_X86_64) before calling
is_vsyscall_vaddr(), in another the whole thing is under #ifdef.
Moving IS_ENABLED(CONFIG_X86_64) into is_vsyscall_vaddr(), which is an
inline function anyway, eliminates the need for both.
This exposes a dummy call to emulate_vsyscall() to the compiler on
x86-32, but that is perfectly OK since the stub inline for
!CONFIG_X86_VSYSCALL_EMULATION is available even when compiling for
x86-32.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
---
arch/x86/include/asm/vsyscall.h | 3 ++-
arch/x86/mm/fault.c | 4 +---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index 538053b1656a..57ab3da53002 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -36,7 +36,8 @@ static inline bool emulate_vsyscall_gp(struct pt_regs *regs)
*/
static inline bool is_vsyscall_vaddr(unsigned long vaddr)
{
- return unlikely((vaddr & PAGE_MASK) == VSYSCALL_ADDR);
+ return IS_ENABLED(CONFIG_X86_64) &&
+ unlikely((vaddr & PAGE_MASK) == VSYSCALL_ADDR);
}
#endif /* _ASM_X86_VSYSCALL_H */
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index f0e77e084482..fcd6b58dc0ac 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1119,7 +1119,7 @@ bool fault_in_kernel_space(unsigned long address)
* TASK_SIZE_MAX, but is not considered part of the kernel
* address space.
*/
- if (IS_ENABLED(CONFIG_X86_64) && is_vsyscall_vaddr(address))
+ if (is_vsyscall_vaddr(address))
return false;
return address >= TASK_SIZE_MAX;
@@ -1301,7 +1301,6 @@ void do_user_addr_fault(struct pt_regs *regs,
if (user_mode(regs))
flags |= FAULT_FLAG_USER;
-#ifdef CONFIG_X86_64
/*
* Faults in the vsyscall page might need emulation. The
* vsyscall page is at a high address (>PAGE_OFFSET), but is
@@ -1317,7 +1316,6 @@ void do_user_addr_fault(struct pt_regs *regs,
if (emulate_vsyscall_pf(error_code, regs, address))
return;
}
-#endif
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;
--
2.53.0
© 2016 - 2026 Red Hat, Inc.