[svsm-devel] [EXTERNAL] Re: EDK2 CAA Page Fragmented Allocation
Jon Lange
jlange at microsoft.com
Tue May 20 18:17:26 CEST 2025
The error you are seeing indicates that the page being read has not been PVALIDATEd. Unfortunately, the #VC exception won't tell you which GPA is failing, so you'll have to do some debugging to figure out which access is causing a problem. Because the exception occurs on a MOVS instruction, you can't even be sure whether the page validation error is occurring on the source address or the destination address, though it's rather unlikely that the validation error is occurring on a page owned by the SVSM itself.
I cannot guess why the GPA is not validated in this case. The calling area address is established by the SVSM when the CPU is created, so this specific SVSM call cannot be specifying a bad address (because it is not specifying an address at all) - unless this SVSM call is the REMAP_CAA call. I don't know whether it's possible that Linux is issuing a PVALIDATE request to the SVSM (remember that all PVALIDATE operations must be performed by the SVSM) to revoke page validation on this page. I also don't know whether it's possible that the specific flow you're looking at involves the VMM deciding to remove the physical page associated with the CAA's GPA and to replace it later - this would result in a non-validated page being present in the address space. If I were debugging this issue, I would try to get some debug traces of what PVALIDATE calls the SVSM is issuing and what page removal/insertion operations the VMM Is performing so you can narrow down how this GPA is winding up in a non-validated state. And of course, it's worth verifying that the GPA being accessed here is the one you actually intend, to see whether there is some other issue that is causing an incorrect access.
-Jon
-----Original Message-----
From: Gerd Hoffmann <kraxel at redhat.com>
Sent: Tuesday, May 20, 2025 6:14 AM
To: Jon Lange <jlange at microsoft.com>
Cc: Adam Dunlap <acdunlap at google.com>; coconut-svsm at lists.linux.dev; svsm-devel at coconut-svsm.dev
Subject: Re: [EXTERNAL] Re: [svsm-devel] EDK2 CAA Page Fragmented Allocation
[You don't often get email from kraxel at redhat.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
On Mon, May 19, 2025 at 04:07:49PM +0000, Jon Lange wrote:
> Gerd wrote:
>
> > Well. Linux relocates the CAA page, and I don't think there is some way for UEFI runtime services to use that.
> > First because UEFI can't figure the address of the Linux CAA page.
> > And second because linux wouldn't map the CAA page into the efi runtime service sandbox anyway.
>
> This is why MSR C001_F000 is defined in the SVSM specification (see
> Section 4.2 - Post Boot). UEFI runtime services can read that MSR,
> which will result in a #VC being delivered to Linux. The Linux #VC
> handler should resolve the #VC by supplying the address of the CAA
> page. This will enable UEFI runtime services to obtain the address of
> the Linux CAA page so it can make SVSM calls.
>
> It seems that Linux would have to map at least the #VC handler into
> the UEFI runtime sandbox because there is the potential for UEFI
> runtime services to cause other #VC exceptions, which must not be
> fatal to the execution of the UEFI runtime. If Linux must do that,
> then it seems like a small additional step to map the CAA page into
> that sandbox as well.
Thanks for your hints. Got that mostly working.
Mapping the #vc handler is not needed, I think on exceptions linux switches to kernel context anyway. The instruction emulation needed a fix though so it goes fetch the faulting instruction from efi_mm context. Mapping the CAA page into the sandbox (aka efi_mm context) is needed indeed. It's done already for the ghcs pages, so I added caa there.
Now svsm calls from uefi runtime actually land in svsm. Progress!
Next problem is that svsm reading the caa page seems to fail. The code doesn't get past the calling_area.read() call in get_and_clear_caa_request_flag(), and I have no idea why. The linux kernel doing the same thing with the same caa page works just fine. And given that svsm uses its own page mapping for the caa page I think it should not matter whenever the call comes from linux kernel context or efi_mm context ...
debug log:
[SVSM] ERROR: #VC handling error: Insn(DecodeOpCode) [SVSM] ERROR: Panic on CPU[0]! COCONUT-SVSM Version: a7c20912+ [SVSM] ERROR: Info: panicked at kernel/src/cpu/idt/svsm.rs:319:13:
Failed to handle #VC from kernel-mode at RIP 0xffffff800021faf8 code: 0x0000000000000404
stack trace:
(gdb) bt ctxt.frame.rsp
#0 0xffffff80001dea39 in svsm::debug::gdbstub::svsm_gdbstub::debug_break () at kernel/src/debug/gdbstub.rs:173
#1 0xffffff8000129d13 in svsm::panic (info=0xfffffe008000b010) at kernel/src/svsm.rs:398
#2 0xffffff80002d65e0 in core::panicking::panic_fmt (fmt=...) at library/core/src/panicking.rs:75
#3 0xffffff8000195ee1 in svsm::cpu::idt::svsm::ex_handler_vmm_communication (ctxt=0xfffffe008000b4f8, vector=29) at kernel/src/cpu/idt/svsm.rs:319
#4 0xffffff80002db9cc in L64 ()
#5 0x0000000000000000 in ?? ()
context:
(gdb) print /x *ctxt
$3 = svsm::cpu::idt::common::X86ExceptionContext {ssp: 0x0, _padding: [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0], regs: svsm::cpu::registers::X86GeneralRegs {r15: 0x0, r14: 0x0, r13: 0x0, r12: 0x0, r11: 0xfffffe008000bc90, r10: 0x8, r9: 0x40, r8: 0x1, rbp: 0xfffffe008000b610, rdi: 0xfffffe008000b670, rsi: 0xffffff0000002000, rdx: 0xfffffe008000b670, rcx: 0x8, rbx: 0x0, rax: 0xfffffe008000b698}, error_code: 0x404, frame: svsm::cpu::registers::X86InterruptFrame {rip: 0xffffff800021faf8, cs: 0x8, flags: 0x10096, rsp: 0xfffffe008000b5b8, ss: 0x0}}
exception raised here:
(gdb) disas ctxt.frame.rip
Dump of assembler code for function _ZN4svsm2mm8guestmem10copy_bytes17hb74ce3bae1bdb91fE:
0xffffff800021fad0 <+0>: push %rbp
0xffffff800021fad1 <+1>: mov %rsp,%rbp
0xffffff800021fad4 <+4>: sub $0x58,%rsp
0xffffff800021fad8 <+8>: mov %rdx,-0x58(%rbp)
0xffffff800021fadc <+12>: mov %rdi,%rax
0xffffff800021fadf <+15>: mov -0x58(%rbp),%rdi
0xffffff800021fae3 <+19>: mov %rax,-0x50(%rbp)
0xffffff800021fae7 <+23>: mov %rax,-0x48(%rbp)
0xffffff800021faeb <+27>: mov %rsi,-0x18(%rbp)
0xffffff800021faef <+31>: mov %rdi,-0x10(%rbp)
0xffffff800021faf3 <+35>: mov %rcx,-0x8(%rbp)
0xffffff800021faf7 <+39>: cld
0xffffff800021faf8 <+40>: rep movsb %ds:(%rsi),%es:(%rdi)
take care,
Gerd
More information about the Svsm-devel
mailing list