Re: [PATCH v9 00/22] Enable FRED with KVM VMX
From: Maciej Wieczor-Retman
Date: Thu May 07 2026 - 09:57:13 EST
On 2026-05-07 at 14:35:41 +0100, David Woodhouse wrote:
>On Thu, 2026-05-07 at 14:59 +0200, Maciej Wieczor-Retman wrote:
>> On 2026-05-07 at 08:49:27 +0100, David Woodhouse wrote:
>> > On Tue, 2026-05-05 at 22:20 +0200, Maciej Wieczor-Retman wrote:
>> > >
>> > > I take it you mean dropping the ICEBP selftest test case and just checking INT3
>> > > and INT $0x20? In that case the other two tests pass after a minor change -
>> > > namely in guest_code() the expected_rip needs to be volatile as well. Otherwise
>> > > there is a RIP mismatch.
>> >
>> > I don't understand the part about making expected_rip volatile. Are the
>> > asm constraints there not correct? If not I'd rather *fix* them than
>> > use 'volatile' to paper over it. I can't see the issue though.
>> >
>> > Can you show the generated asm both with and without it?
>>
>> ---------- not volatile ---------------- | -------------- volatile -----------------
>> #APP #APP
>> # 156 "x86/int1_fred_test.c" 1 # 156 "x86/int1_fred_test.c" 1
>> lea 1f(%rip), %rdi | lea 1f(%rip), %rax
>> int3 int3
>> 1: 1:
>> # 0 "" 2 # 0 "" 2
>> .LVL42: <
>> .loc 3 159 2 view .LVU146 <
>> #NO_APP #NO_APP
>> > movq %rax, 8(%rsp)
>> > .loc 3 159 2 view .LVU146
>> > movq 8(%rsp), %rdi
>> movl $6, %edx movl $6, %edx
>> movl $3, %esi movl $3, %esi
>> call check_fred_event.isra.0 call check_fred_event.isra.0
>>
>> I think that when the FRED event happens it doesn't save RDI and overwrites it
>> before going into check_fred_event. In the volatile case it is saved to the
>> stack before check_fred_event() (.loc 159 is the check_fred_event() call).
>
>That looks OK to me. When it calls check_fred_event(), expected_rip is
>the first argument and thus lives in %rdi. On the right hand side where
>it's volatile, it gets explicitly loaded again from 8(%rsp) for the
>call to check_fred_event().
>
>On the left hand side, the compiler doesn't mess with it at all; just
>chooses %rdi as the register to use for the output %0 of the inline
>assembly. So it's loaded *directly* into %rdi by our 'lea' and it goes
>straight from there to the check_fred_event() function as it should.
>
>Your version turns it into a memory operand and forces it to get
>written out to the stack, after which the compiler has to load it
>again, so yes it'll look a lot more like your right hand side.
>
>But I don't see anything actually wrong with the original.
My theory is that after 'int3' call the FRED event is handled elsewhere and %rdi
is not preserved. So the original version of the assembly looks okay but I was
thinking that int3 has side effects.
Below is the test output of the RIPs not matching when running the original,
does that help in any way?
Random seed: 0x6b8b4567
Testing FRED event types with EPT fault on stack
==== Test Assertion Failure ====
x86/int1_fred_test.c:114: fred_saved_rip == expected_rip
pid=193114 tid=193114 errno=4 - Interrupted system call
1 0x0000000000413319: assert_on_unhandled_exception at processor.c:659
2 0x0000000000407d06: _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:209
5 0x00007f90b3c2a1c9: ?? ??:0
6 0x00007f90b3c2a28a: ?? ??:0
7 0x0000000000403314: _start at ??:?
0x40446b != 0xabaf80 (fred_saved_rip != expected_rip)
--
Kind regards
Maciej Wieczór-Retman