All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: no-reply@sashiko.virtuozzo.com
To: devel@openvz.org, Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
Subject: Re: [Devel] [PATCH RK VZ10] x86/traps: emulate CPUID faults for user tasks in exc_general_protection()
Date: Mon, 2 Nov 2026 10:11:48 +0000	[thread overview]
Message-ID: <010701a19bbe65dd-10c6c0d5-dfff-48a7-9a20-3fd925d4848c-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261102100432.15867-1-vladimir.riabchun@virtuozzo.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] x86/vdso: check_cpuid_fault() only matches bare 0f a2 and adds a fixed 2 to IP
- [Low] x86/vdso: misspelled label try_fixup_cupid in fixup_vdso_exception()
- [Low] x86/vdso: check_cpuid_fault() uses convert_ip_to_linear() and a bare get_user()
--

commit c9d27b496f26c56280e62cfc00914a978e22f21d
Author: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>

x86/traps: emulate CPUID faults for user tasks in exc_general_protection()

This commit adds a CPUID-fault emulation helper to
arch/x86/entry/vdso/extable.c and calls it from fixup_vdso_exception() on
the path where no vDSO fixup applies. The aim is for a user-mode #GP(0)
caused by CPUID to be emulated with the cpuid_override table instead of
ending in SIGSEGV.

Link: http://lore.virtuozzo.com/20261006-b4-prep-khorenko-vstor-148656-just-cpuid-v1-1-6f2a2a6deef3@virtuozzo.com

> diff --git a/arch/x86/entry/vdso/extable.c b/arch/x86/entry/vdso/extable.c
> index afcf5b65beef7..ca8c184925ec2 100644
> --- a/arch/x86/entry/vdso/extable.c
> +++ b/arch/x86/entry/vdso/extable.c
> @@ -9,6 +9,30 @@ struct vdso_exception_table_entry {
>  	int insn, fixup;
>  };
>  
> +static int check_cpuid_fault(struct pt_regs *regs, long error_code)
> +{
> +	unsigned long addr;
> +	unsigned short opcode;
> +
> +	if (error_code != 0)
> +		return 0;
> +
> +	if (test_thread_flag(TIF_NOCPUID))
> +		return 0;
> +
> +	addr = convert_ip_to_linear(current, regs);

[Severity: Low]
Can convert_ip_to_linear() give the wrong address here?

With CONFIG_MODIFY_LDT_SYSCALL, convert_ip_to_linear() adds
get_desc_base(desc) for an LDT code segment. It never checks the 64-bit (L)
bit, and in long mode the hardware ignores that base.

If a task installs an LDT code segment with a non-zero base via
modify_ldt() and takes a #GP(0), get_user() reads the opcode from ip+base
instead of ip. Two things can then happen:

- A non-CPUID fault is treated as CPUID. do_cpuid_fault() runs and
  regs->ip is advanced by 2, so the task survives a fault that should have
  raised SIGSEGV.
- A genuine CPUID is missed, and the task gets SIGSEGV instead of the
  override.

The existing check_cpuid_fault() in arch/x86/kernel/traps.c uses
insn_fetch_from_user() and insn_decode_from_regs(), which handle segment
and mode details. Could the new helper use the same approach?

> +	if (get_user(opcode, (unsigned short __user *)addr))
> +		return 0;
> +
> +	if (opcode != 0xa20f)
> +		return 0;

[Severity: Medium]
Does this check decline a CPUID that has a prefix?

The helper accepts only the bare two-byte encoding 0f a2. A prefixed
encoding such as 66 0f a2, 48 0f a2 or a legacy prefix fails the compare,
and check_cpuid_fault() returns 0.

The traps.c version decodes the instruction and checks both opcode bytes:

  if (insn.opcode.bytes[0] != 0x0f || insn.opcode.bytes[1] != 0xa2)
          return 0;
  do_cpuid_fault(regs);
  regs->ip += insn.length;

The commit message says the traps.c call is unreachable for user-mode #GP
on the livepatch target. If so, this helper is the only emulation path
there. A task with TIF_CPUID_OVERRIDE that runs a prefixed CPUID would then
reach gp_user_force_sig_segv(), which is the failure this patch is meant to
remove.

In the tree I reviewed, exc_general_protection() still calls the
decoder-based check_cpuid_fault() inside the user_mode() branch after
fixup_vdso_exception(), so prefixed CPUID would fall back to it there.
Compilers and glibc normally emit a bare CPUID, so this should be rare.

> +
> +	do_cpuid_fault(regs);
> +
> +	regs->ip += 2;

[Severity: Medium]
Is the fixed increment of 2 correct for every CPUID encoding?

The traps.c version advances ip by insn.length, so the two functions can
disagree. Could this helper decode the instruction and use the real length,
as the traps.c helper does?

> +	return 1;
> +}
> +
>  bool fixup_vdso_exception(struct pt_regs *regs, int trapnr,
>  			  unsigned long error_code, unsigned long fault_addr)
>  {

[ ... ]

> @@ -26,7 +50,7 @@ bool fixup_vdso_exception(struct pt_regs *regs, int trapnr,
>  		return false;
>  
>  	if (!current->mm->context.vdso)
> -		return false;
> +		goto try_fixup_cupid;
>  
> [ ... ]
> +try_fixup_cupid:

[Severity: Low]
This isn't a bug, but the label is misspelled: try_fixup_cupid should
presumably be try_fixup_cpuid.

> +	/* Only exc_general_protection can go this way */
> +	if (trapnr == X86_TRAP_GP && check_cpuid_fault(regs, error_code))
> +		return true;

This isn't a bug, but the comment "Only exc_general_protection can go
this way" describes a caller convention that the code doesn't enforce. The
only real gate is trapnr == X86_TRAP_GP.

> +
>  	return false;
>  }

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261102100432.15867-1-vladimir.riabchun@virtuozzo.com?part=1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  reply	other threads:[~2026-11-02 10:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 10:04 Vladimir Riabchun
2026-11-02 10:11 ` no-reply [this message]
2026-11-02 10:20 ` Vasileios Almpanis
2026-11-02 15:15 ` Pavel Tikhomirov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=010701a19bbe65dd-10c6c0d5-dfff-48a7-9a20-3fd925d4848c-000000@eu-central-1.amazonses.com \
    --to=no-reply@sashiko.virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=vladimir.riabchun@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.