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 10:25:41 +0100	[thread overview]
Message-ID: <DGZUFMGSILDF.3ES3YACXM6AG4@amd.com> (raw)
In-Reply-To: <813d3fc9-170a-4f25-872a-3688946c236d@suse.com>

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.

>
>> -    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.

>>  
>> -            add_taint(TAINT_HVM_FEP);
>> +    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;
>>  
>> -            should_emulate = true;
>> -        }
>> -    }
>> +        /* 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 ( !should_emulate )
>> -    {
>> -        hvm_inject_hw_exception(X86_EXC_UD, X86_EVENT_NO_EC);
>> -        return;
>> +        add_taint(TAINT_HVM_FEP);
>>      }
>> +    else
>> +        goto reinject;
>>  
>>      switch ( hvm_emulate_one(&ctxt, VIO_no_completion) )
>>      {
>>      case X86EMUL_UNHANDLEABLE:
>>      case X86EMUL_UNIMPLEMENTED:
>> -        hvm_inject_hw_exception(X86_EXC_UD, X86_EVENT_NO_EC);
>> -        break;
>> +        goto reinject;
>
> How about placing the reinject label here, along with the two case one?
>
> Jan

Sure. That works too.

Cheers,
Alejandro


  reply	other threads:[~2026-03-11  9:26 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 [this message]
2026-03-11  9:30       ` Jan Beulich
2026-03-11 10:21         ` Alejandro Vallejo
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=DGZUFMGSILDF.3ES3YACXM6AG4@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.