[PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad

H. Peter Anvin posted 6 patches 3 months, 2 weeks ago
[PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad
Posted by H. Peter Anvin 3 months, 2 weeks ago
There is no fundamental reason for the int80_landing_pad symbol. If ip
falls within the vdso, and the vdso is moved, we should change the ip
accordingly, regardless of mode or location within the vdso. This
*currently* can only happen on 32 bits, but there isn't any reason not
to do so generically.

Note that if this is ever possible from a vdso-internal call, then the
user space stack will also needed to be adjusted (as well as the
shadow stack, if enabled.) Fortunately this is not currently the case.

At the moment, we don't even consider other threads when moving the
vdso. The assumption is that it is only used by process freeze/thaw
for migration, where this is not an issue.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
---
 arch/x86/entry/vdso/vdso32/system_call.S |  1 -
 arch/x86/entry/vdso/vma.c                | 16 ++++++----------
 arch/x86/tools/vdso2c.c                  |  1 -
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S
index 2a15634bbe75..d14eca4403c5 100644
--- a/arch/x86/entry/vdso/vdso32/system_call.S
+++ b/arch/x86/entry/vdso/vdso32/system_call.S
@@ -62,7 +62,6 @@ __kernel_vsyscall:
 
 	/* Enter using int $0x80 */
 	int	$0x80
-SYM_INNER_LABEL(int80_landing_pad, SYM_L_GLOBAL)
 
 	/*
 	 * Restore EDX and ECX in case they were clobbered.  EBP is not
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 8f98c2d7c7a9..e7fd7517370f 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -65,16 +65,12 @@ static vm_fault_t vdso_fault(const struct vm_special_mapping *sm,
 static void vdso_fix_landing(const struct vdso_image *image,
 		struct vm_area_struct *new_vma)
 {
-	if (in_ia32_syscall() && image == &vdso32_image) {
-		struct pt_regs *regs = current_pt_regs();
-		unsigned long vdso_land = image->sym_int80_landing_pad;
-		unsigned long old_land_addr = vdso_land +
-			(unsigned long)current->mm->context.vdso;
-
-		/* Fixing userspace landing - look at do_fast_syscall_32 */
-		if (regs->ip == old_land_addr)
-			regs->ip = new_vma->vm_start + vdso_land;
-	}
+	struct pt_regs *regs = current_pt_regs();
+	unsigned long ipoffset = regs->ip -
+		(unsigned long)current->mm->context.vdso;
+
+	if (ipoffset < image->size)
+		regs->ip = new_vma->vm_start + ipoffset;
 }
 
 static int vdso_mremap(const struct vm_special_mapping *sm,
diff --git a/arch/x86/tools/vdso2c.c b/arch/x86/tools/vdso2c.c
index f84e8f8fa5fe..c81bb32b1e6c 100644
--- a/arch/x86/tools/vdso2c.c
+++ b/arch/x86/tools/vdso2c.c
@@ -79,7 +79,6 @@ struct vdso_sym required_syms[] = {
 	{"__kernel_vsyscall", true},
 	{"__kernel_sigreturn", true},
 	{"__kernel_rt_sigreturn", true},
-	{"int80_landing_pad", true},
 	{"vdso32_rt_sigreturn_landing_pad", true},
 	{"vdso32_sigreturn_landing_pad", true},
 };
-- 
2.51.1
Re: [PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad
Posted by Brian Gerst 3 months, 1 week ago
On Sun, Oct 26, 2025 at 6:12 PM H. Peter Anvin <hpa@zytor.com> wrote:
>
> There is no fundamental reason for the int80_landing_pad symbol. If ip
> falls within the vdso, and the vdso is moved, we should change the ip
> accordingly, regardless of mode or location within the vdso. This
> *currently* can only happen on 32 bits, but there isn't any reason not
> to do so generically.
>
> Note that if this is ever possible from a vdso-internal call, then the
> user space stack will also needed to be adjusted (as well as the
> shadow stack, if enabled.) Fortunately this is not currently the case.
>
> At the moment, we don't even consider other threads when moving the
> vdso. The assumption is that it is only used by process freeze/thaw
> for migration, where this is not an issue.
>
> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
> ---
>  arch/x86/entry/vdso/vdso32/system_call.S |  1 -
>  arch/x86/entry/vdso/vma.c                | 16 ++++++----------
>  arch/x86/tools/vdso2c.c                  |  1 -
>  3 files changed, 6 insertions(+), 12 deletions(-)
>
> diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S
> index 2a15634bbe75..d14eca4403c5 100644
> --- a/arch/x86/entry/vdso/vdso32/system_call.S
> +++ b/arch/x86/entry/vdso/vdso32/system_call.S
> @@ -62,7 +62,6 @@ __kernel_vsyscall:
>
>         /* Enter using int $0x80 */
>         int     $0x80
> -SYM_INNER_LABEL(int80_landing_pad, SYM_L_GLOBAL)

This is still needed by do_fast_syscall_32().


Brian Gerst
Re: [PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad
Posted by H. Peter Anvin 3 months, 1 week ago
On October 28, 2025 11:54:43 PM PDT, Brian Gerst <brgerst@gmail.com> wrote:
>On Sun, Oct 26, 2025 at 6:12 PM H. Peter Anvin <hpa@zytor.com> wrote:
>>
>> There is no fundamental reason for the int80_landing_pad symbol. If ip
>> falls within the vdso, and the vdso is moved, we should change the ip
>> accordingly, regardless of mode or location within the vdso. This
>> *currently* can only happen on 32 bits, but there isn't any reason not
>> to do so generically.
>>
>> Note that if this is ever possible from a vdso-internal call, then the
>> user space stack will also needed to be adjusted (as well as the
>> shadow stack, if enabled.) Fortunately this is not currently the case.
>>
>> At the moment, we don't even consider other threads when moving the
>> vdso. The assumption is that it is only used by process freeze/thaw
>> for migration, where this is not an issue.
>>
>> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
>> ---
>>  arch/x86/entry/vdso/vdso32/system_call.S |  1 -
>>  arch/x86/entry/vdso/vma.c                | 16 ++++++----------
>>  arch/x86/tools/vdso2c.c                  |  1 -
>>  3 files changed, 6 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S
>> index 2a15634bbe75..d14eca4403c5 100644
>> --- a/arch/x86/entry/vdso/vdso32/system_call.S
>> +++ b/arch/x86/entry/vdso/vdso32/system_call.S
>> @@ -62,7 +62,6 @@ __kernel_vsyscall:
>>
>>         /* Enter using int $0x80 */
>>         int     $0x80
>> -SYM_INNER_LABEL(int80_landing_pad, SYM_L_GLOBAL)
>
>This is still needed by do_fast_syscall_32().
>
>
>Brian Gerst
>

Yeah, that was a complete brainfart on my part. I'm already reworking the patchset, fixing this and adding more improvements. 
Re: [PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad
Posted by kernel test robot 3 months, 2 weeks ago

Hello,

kernel test robot noticed "segfault_at_ip_sp_error" on:

commit: 19009b8428dfbeea0ecf043c063cf3336282eb2b ("[PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad")
url: https://github.com/intel-lab-lkp/linux/commits/H-Peter-Anvin/x86-entry-vdso-rename-vdso_image_-to-vdso-_image/20251027-061505
base: https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git ad74016b919cbad78d203fa1c459ae18e73ce586
patch link: https://lore.kernel.org/all/20251026221208.1938173-4-hpa@zytor.com/
patch subject: [PATCH 3/6] x86/entry/vdso32: remove int80_landing_pad

in testcase: boot

config: i386-randconfig-002-20251027
compiler: gcc-14
test machine: qemu-system-i386 -enable-kvm -cpu SandyBridge -smp 2 -m 4G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+-----------------------------------------------------------+------------+------------+
|                                                           | 28c61beafa | 19009b8428 |
+-----------------------------------------------------------+------------+------------+
| boot_successes                                            | 6          | 0          |
| boot_failures                                             | 0          | 6          |
| segfault_at_ip_sp_error                                   | 0          | 6          |
| Kernel_panic-not_syncing:Attempted_to_kill_init!exitcode= | 0          | 6          |
+-----------------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202510281407.1fbe8f8b-lkp@intel.com


[   12.230099][    T1]     selinux=0
[   12.230498][    T1]     prompt_ramdisk=0
[   12.230942][    T1]     vga=normal
[   12.231367][    T1]     audit=0
[   12.231748][    T1]     ia32_emulation=on
[   12.246128][    T1] init[1]: segfault at 1 ip 37fad006 sp 3fb8051f error 6 likely on CPU 0 (core 0, socket 0)
[   12.247169][    T1] Code: Unable to access opcode bytes at 0x37facfdc.

Code starting with the faulting instruction
===========================================
[   12.247782][    T1] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[   12.248459][    T1] CPU: 0 UID: 0 PID: 1 Comm: init Not tainted 6.18.0-rc1-00004-g19009b8428df #1 PREEMPT(lazy)  515832f7b4d7c2dccd9418532bf066894e2da3fd
[   12.249461][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   12.250250][    T1] Call Trace:
[   12.250556][    T1]  ? dump_stack_lvl (kbuild/src/consumer/lib/dump_stack.c:122)
[   12.250943][    T1]  ? dump_stack (kbuild/src/consumer/lib/dump_stack.c:130)
[   12.251324][    T1]  ? vpanic (kbuild/src/consumer/kernel/panic.c:404 kbuild/src/consumer/kernel/panic.c:511)
[   12.251677][    T1]  ? panic (kbuild/src/consumer/kernel/panic.c:365)
[   12.252001][    T1]  ? do_exit.cold (kbuild/src/consumer/kernel/exit.c:1027)


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20251028/202510281407.1fbe8f8b-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki