From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>,
Xin Li <xin@zytor.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
David Woodhouse <dwmw2@infradead.org>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
linux-doc@vger.kernel.org, "Saenz Julienne,
Nicolas" <nsaenz@amazon.es>,
pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net,
tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
luto@kernel.org, peterz@infradead.org, chao.gao@intel.com,
hch@infradead.org, sohil.mehta@intel.com
Subject: Re: [PATCH v9 00/22] Enable FRED with KVM VMX
Date: Tue, 5 May 2026 19:30:21 +0100 [thread overview]
Message-ID: <f4cb5f8e-caf5-4513-9538-edaaea20de2d@citrix.com> (raw)
In-Reply-To: <afojoHJSlqqm2Ges@wieczorr-mobl1.localdomain>
On 05/05/2026 7:04 pm, Maciej Wieczor-Retman wrote:
> Hello!
>
>
> On 2026-04-23 at 15:56:54 -0700, Xin Li wrote:
>>> On Apr 23, 2026, at 7:35 AM, David Woodhouse <dwmw2@infradead.org> wrote:
>>> Here's one to get you started (untested as I haven't found suitable
>>> hardware to test it on).
>> Same here for me now :(
> I ran David's selftest on a PTL laptop and ran into a couple of issues.
>
>>> From bd465aabebcb124e09a26fe9f4c861354febabe4 Mon Sep 17 00:00:00 2001
>>> From: David Woodhouse <dwmw@amazon.co.uk>
>>> Date: Thu, 23 Apr 2026 15:20:11 +0100
>>> Subject: [PATCH] KVM: selftests: Add FRED event type classification test
>>>
>>> +static void __used fred_handler(struct fred_stack_frame *frame)
>>> +{
>>> + fred_ss_value = frame->ss;
>>> + fred_saved_rip = frame->rip;
>>> + fred_handler_called = true;
>>> +}
> fred_handler() has problems getting linked:
>
> /usr/bin/ld: /home/maciej/linux/tools/testing/selftests/kvm/x86/int1_fred_test.o: in function `fred_entrypoint_kernel':
> int1_fred_test.c:(.text+0x104): undefined reference to `fred_handler'
> collect2: error: ld returned 1 exit status
>
> I guess the .pushsection below makes it a different translation unit? Because
> getting rid of the static keyword takes care of the problem for me.
The problem is, being static, fred_handler() is eligible to be optimised
away, because the compiler can't see that the asm() refers to it.
Dropping static is the right fix to make.
GCC 15 can now do references out of global asm() to identify the symbols
they use, but it's going to be years before this capability is safe to
use generally.
>
>>> +
>>> +/*
>>> + * FRED entry points. MSR_IA32_FRED_CONFIG points to the page-aligned
>>> + * base. Ring 3 events enter at base+0, ring 0 events at base+0x100.
>>> + * Since ICEBP executes in ring 0, the CPU enters at fred_entrypoint
>>> + * + 256 = fred_entrypoint_kernel.
>>> + */
>>> +extern void fred_entrypoint(void);
>>> +
>>> +asm(
>>> + ".pushsection .text\n"
>>> + ".global fred_entrypoint\n"
>>> + ".balign 4096\n"
>>> +"fred_entrypoint:\n"
>>> + /* Ring 3 entry — unused, no userspace in this test */
>>> + "ud2\n"
>>> + /* Pad to +256 for ring 0 entry */
>>> + ".org fred_entrypoint + 256, 0xcc\n"
>>> +"fred_entrypoint_kernel:\n"
>>> + "movq %rsp, %rdi\n"
>>> + "call fred_handler\n"
>>> + ".byte 0xf2, 0x0f, 0x01, 0xca\n" /* ERETS */
>>> + ".popsection\n"
>>> +);
>>> +
> ...
>>> +
>>> + /* Test 1: ICEBP (INT1) — should be EVENT_TYPE_PRIV_SWEXC (5) */
>>> + fred_handler_called = false;
>>> + asm volatile("lea 1f(%%rip), %0\n\t"
>>> + ".byte 0xf1\n\t"
>>> + "1:" : "=r"(expected_rip) :: "memory");
>>> + check_fred_event(expected_rip, DB_VECTOR, EVENT_TYPE_PRIV_SWEXC,
>>> + "ICEBP");
>>> + GUEST_SYNC(0);
> The above event type test seems to fail and return 0x3 instead of 0x5:
>
> Random seed: 0x6b8b4567
> Testing FRED event types with EPT fault on stack
> ==== Test Assertion Failure ====
> x86/int1_fred_test.c:120: event_type == expected_type
> pid=16646 tid=16646 errno=4 - Interrupted system call
> 1 0x0000000000413349: assert_on_unhandled_exception at processor.c:659
> 2 0x0000000000407d36: _vcpu_run at kvm_util.c:1703
> 3 (inlined by) vcpu_run at kvm_util.c:1714
> 4 0x0000000000403104: main at int1_fred_test.c:207
> 5 0x00007ff8d4c2a1c9: ?? ??:0
> 6 0x00007ff8d4c2a28a: ?? ??:0
> 7 0x0000000000403314: _start at ??:?
> 0x3 != 0x5 (event_type != expected_type)
>
> after a little digging I think the issue could be this in arch/x86/kvm/x86.h:
>
> static inline bool kvm_exception_is_soft(unsigned int nr)
> {
> return (nr == BP_VECTOR) || (nr == OF_VECTOR);
> }
>
> Since ICEBP(INT1) results in a DB_VECTOR it's not take into account and the
> check fails. Then in vmx_inject_exception() INTR_TYPE_HARD_EXCEPTION is picked
> which is 0x3 when decoded.
That's a real bug then.
> I think you'd need to add another check in vmx_inject_exception() to handle that
> DB_VECTOR too. Simply changing the event type if the vector is of DB_VECTOR type
> fixes that problem but then the selftest fails in other places (assert
> fred_handler_called and saved rip vs expected_rip). I didn't yet have the time
> to figure out what could be wrong there, maybe you would have more of an idea :)
#DB is intercepted to mitigate CVE-2015-8104 (systemwide DoS). But, to
start with, check that the test passes when #DB is not intercepted.
That's the basecase for architectural behaviour.
When #DB is intercepted, the type in EXIT_INTR_INFO needs preserving and
forwarding into ENTRY_INTR_INFO, because that is what distinguishes an
ICEBP #DB from other #DBs. There's no way of recovering this detail
after the fact.
On the injection side, some #DB's are traps and some are faults. ICEBP
will have a fault-like VMExit but need trap semantics, so like other
soft interrupts, need INSN_LEN adding to %rip. But, type=3 #DBs need to
leave %rip unchanged.
~Andrew
next prev parent reply other threads:[~2026-05-05 18:30 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20251026201911.505204-1-xin@zytor.com>
[not found] ` <7f93eb25874ddd13a1ad6e3c75785f11041c8b7f.camel@infradead.org>
[not found] ` <DADE0E58-DD8A-4206-BF54-1DA87864117D@zytor.com>
2026-05-05 18:04 ` [PATCH v9 00/22] Enable FRED with KVM VMX Maciej Wieczor-Retman
2026-05-05 18:30 ` Andrew Cooper [this message]
2026-05-05 19:29 ` H. Peter Anvin
2026-05-05 20:20 ` Maciej Wieczor-Retman
2026-05-05 20:27 ` Andrew Cooper
2026-05-06 14:05 ` Maciej Wieczor-Retman
2026-05-07 7:49 ` David Woodhouse
2026-05-07 12:59 ` Maciej Wieczor-Retman
2026-05-07 13:35 ` David Woodhouse
2026-05-07 13:53 ` Maciej Wieczor-Retman
2026-05-07 14:01 ` David Woodhouse
2026-05-07 23:00 ` David Woodhouse
2026-05-08 14:25 ` Maciej Wieczor-Retman
2026-05-08 14:46 ` David Woodhouse
2026-05-08 18:06 ` Maciej Wieczor-Retman
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=f4cb5f8e-caf5-4513-9538-edaaea20de2d@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=bp@alien8.de \
--cc=chao.gao@intel.com \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=dwmw2@infradead.org \
--cc=hch@infradead.org \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=maciej.wieczor-retman@intel.com \
--cc=mingo@redhat.com \
--cc=nsaenz@amazon.es \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=seanjc@google.com \
--cc=sohil.mehta@intel.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=xin@zytor.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox