All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
To: Jan Beulich <jbeulich@suse.com>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>,
	"Jason Andryuk" <jason.andryuk@amd.com>,
	xen-devel@lists.xenproject.org
Subject: Re: [PATCH v3 2/4] x86/hvm: Disable cross-vendor handling in #UD handler
Date: Wed, 11 Mar 2026 11:21:56 +0100	[thread overview]
Message-ID: <DGZVMOYWFGY5.3NSQ9DUBFDOLR@amd.com> (raw)
In-Reply-To: <f5b74658-3a5f-47ac-8eaa-3f7fbf431a32@suse.com>

On Wed Mar 11, 2026 at 10:30 AM CET, Jan Beulich wrote:
> On 11.03.2026 10:25, Alejandro Vallejo wrote:
>> On Wed Mar 11, 2026 at 9:35 AM CET, Jan Beulich wrote:
>>> On 13.02.2026 12:42, Alejandro Vallejo wrote:
>>>> --- a/xen/arch/x86/hvm/hvm.c
>>>> +++ b/xen/arch/x86/hvm/hvm.c
>>>> @@ -3832,69 +3832,47 @@ int hvm_descriptor_access_intercept(uint64_t exit_info,
>>>>      return X86EMUL_OKAY;
>>>>  }
>>>>  
>>>> -static bool cf_check is_cross_vendor(
>>>> -    const struct x86_emulate_state *state, const struct x86_emulate_ctxt *ctxt)
>>>> -{
>>>> -    switch ( ctxt->opcode )
>>>> -    {
>>>> -    case X86EMUL_OPC(0x0f, 0x05): /* syscall */
>>>> -    case X86EMUL_OPC(0x0f, 0x34): /* sysenter */
>>>> -    case X86EMUL_OPC(0x0f, 0x35): /* sysexit */
>>>> -        return true;
>>>> -    }
>>>> -
>>>> -    return false;
>>>> -}
>>>> -
>>>>  void hvm_ud_intercept(struct cpu_user_regs *regs)
>>>>  {
>>>>      struct vcpu *cur = current;
>>>> -    bool should_emulate =
>>>> -        cur->domain->arch.cpuid->x86_vendor != boot_cpu_data.x86_vendor;
>>>>      struct hvm_emulate_ctxt ctxt;
>>>> +    const struct segment_register *cs = &ctxt.seg_reg[x86_seg_cs];
>>>> +    uint32_t walk = PFEC_insn_fetch;
>>>> +    unsigned long addr;
>>>> +    char sig[5]; /* ud2; .ascii "xen" */
>>>>  
>>>> -    hvm_emulate_init_once(&ctxt, opt_hvm_fep ? NULL : is_cross_vendor, regs);
>>>> +    if ( !opt_hvm_fep )
>>>> +        goto reinject;
>>>
>>> Is this possible at all, i.e. shouldn't there be ASSERT_UNREACHABLE() in
>>> addition if already the check is kept?
>> 
>> It isn't.
>> 
>> v2 used to BUG_ON() at VMEXIT when !HVM_FEP and compile out this handler
>> altogether, but Andrew was unhappy with it because he uses it occasionally and
>> it'd be more of a PITA to undo the removal or force a HVM_FEP-enabled hypervisor
>> for the #UD handler to be present at all.
>> 
>> I have no strong views on the ASSERT. It's not expected to happen, but I don't
>> expect the existing conditions to change either, and if they do that will warrant
>> a change in the handler too. 
>> 
>> If you want it I can add it, but if we're not killing the handler in release I
>> don't think it's very helpful to assert/bug_on.
>
> I see two options: Drop the if() or add ASSERT_UNREACHABLE() to its body.

I'll go for that second option then.

>
>>>> -    if ( opt_hvm_fep )
>>>> -    {
>>>> -        const struct segment_register *cs = &ctxt.seg_reg[x86_seg_cs];
>>>> -        uint32_t walk = ((ctxt.seg_reg[x86_seg_ss].dpl == 3)
>>>> -                         ? PFEC_user_mode : 0) | PFEC_insn_fetch;
>>>
>>> Why is this initializer not retained?
>> 
>> It is, it's just that the diff is terrible. An unfortunate side effect of the
>> removal of the braces. The scope collapsing forces it on top of the function,
>> before the emulation context is initialised.
>> 
>> It's set up in steps. walk is unconditionally initialised as isnsn_fetch, and
>> later (after emulate_init_once()), OR'd with PFEC_user_mode for DPL == 3. See...
>> 
>>>
>>>> -        unsigned long addr;
>>>> -        char sig[5]; /* ud2; .ascii "xen" */
>>>> -
>>>> -        if ( hvm_virtual_to_linear_addr(x86_seg_cs, cs, regs->rip,
>>>> -                                        sizeof(sig), hvm_access_insn_fetch,
>>>> -                                        cs, &addr) &&
>>>> -             (hvm_copy_from_guest_linear(sig, addr, sizeof(sig),
>>>> -                                         walk, NULL) == HVMTRANS_okay) &&
>>>> -             (memcmp(sig, "\xf\xb" "xen", sizeof(sig)) == 0) )
>>>> -        {
>>>> -            regs->rip += sizeof(sig);
>>>> -            regs->eflags &= ~X86_EFLAGS_RF;
>>>> +    hvm_emulate_init_once(&ctxt, NULL, regs);
>>>>  
>>>> -            /* Zero the upper 32 bits of %rip if not in 64bit mode. */
>>>> -            if ( !(hvm_long_mode_active(cur) && cs->l) )
>>>> -                regs->rip = (uint32_t)regs->rip;
>>>> +    if ( ctxt.seg_reg[x86_seg_ss].dpl == 3 )
>>>> +        walk |= PFEC_user_mode;
>> 
>> ... here.
>
> But that's the point of my question: Why did you split it? All you mean to
> do is re-indentation.

Because I need to declare "walk" ahead of the statements. Thus this...

    uint32_t walk = ((ctxt.seg_reg[x86_seg_ss].dpl == 3)
                     ? PFEC_user_mode : 0) | PFEC_insn_fetch;

must (by necessity) have the declaration placed on top before the emulator
context initialisation. The options are...

    uint32_t walk;
    [... lines ...]
    walk = ((ctxt.seg_reg[x86_seg_ss].dpl == 3)
            ? PFEC_user_mode : 0) | PFEC_insn_fetch;

... or...

    uint32_t walk = PFEC_insn_fetch;
    [... lines ...]
    if ( ctxt.seg_reg[x86_seg_ss].dpl == 3 )
        walk |= PFEC_user_mode;

Line count remains at 3 in both cases, but in the former case there's a
comparison, a ternary operator and an OR all adding cognitive load to the
same statement. In the latter case there's an assignment in the 1st statement,
an if+comparison in a separate line, and a separate OR in the final statement.
It's just simpler to meantally parse because the complexity is evenly
distributed.

I can see how the current form was preferred to avoid a third line (and
then a forth due to the required newline, doubling the total). But with the
rearrangement that's no longer relevant.

If you have a very strong preference for the prior form I could keep it, though
I do have a preference myself for the latter out of improved readability.

Cheers,
Alejandro


  reply	other threads:[~2026-03-11 10:22 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-13 11:42 [PATCH v3 0/4] x86: Drop cross-vendor support Alejandro Vallejo
2026-02-13 11:42 ` [PATCH v3 1/4] x86: Reject CPU policies with vendors other than the host's Alejandro Vallejo
2026-03-11  8:26   ` Jan Beulich
2026-03-11 12:43     ` Alejandro Vallejo
2026-02-13 11:42 ` [PATCH v3 2/4] x86/hvm: Disable cross-vendor handling in #UD handler Alejandro Vallejo
2026-03-11  8:35   ` Jan Beulich
2026-03-11  9:25     ` Alejandro Vallejo
2026-03-11  9:30       ` Jan Beulich
2026-03-11 10:21         ` Alejandro Vallejo [this message]
2026-03-11 11:06           ` Jan Beulich
2026-03-11 12:40             ` Alejandro Vallejo
2026-02-13 11:42 ` [PATCH v3 3/4] x86/hvm: Remove cross-vendor checks from MSR handlers Alejandro Vallejo
2026-03-11  8:39   ` Jan Beulich
2026-02-13 11:42 ` [PATCH v3 4/4] x86/svm: Drop emulation of Intel's SYSENTER behaviour on AMD systems Alejandro Vallejo
2026-03-11  8:46   ` Jan Beulich
2026-03-11  9:27     ` Alejandro Vallejo
2026-03-11  8:54 ` [PATCH v3 0/4] x86: Drop cross-vendor support Jan Beulich
2026-03-11  9:46   ` Alejandro Vallejo
2026-03-11 10:11     ` Jan Beulich

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=DGZVMOYWFGY5.3NSQ9DUBFDOLR@amd.com \
    --to=alejandro.garciavallejo@amd.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=jason.andryuk@amd.com \
    --cc=jbeulich@suse.com \
    --cc=roger.pau@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /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.