[PATCH v1 1/8] x86/sev: Make SVSM calls preemption-safe
From: Melody Wang
Date: Fri Aug 28 2026 - 23:40:33 EST
Two functions in the the SVSM vTPM guest implementation do not disable
preemption when fetching CAA.
The SVSM calling area is a per-CPU structure. When a thread is preempted
and migrated to a different CPU after fetching the per-CPU Calling Area
Address (CAA), the SVSM call will execute on the new CPU with the
original CPU's CAA. Which is wrong.
Move the CAA fetching operation inside svsm_perform_call_protocol()
which disables interrupts around the SVSM call and thus runs
preemption-safe.
Signed-off-by: Melody Wang <huibo.wang@xxxxxxx>
---
arch/x86/coco/sev/svsm.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/coco/sev/svsm.c b/arch/x86/coco/sev/svsm.c
index 916d62cd17dc..92ea93f506c0 100644
--- a/arch/x86/coco/sev/svsm.c
+++ b/arch/x86/coco/sev/svsm.c
@@ -74,6 +74,15 @@ int svsm_perform_call_protocol(struct svsm_call *call)
flags = native_local_irq_save();
+ /*
+ * 'caa' is a per-CPU variable. To avoid using a stale or incorrect
+ * 'caa' if the task is preempted or migrates to another CPU after it
+ * is fetched, always fetch 'caa' and then issue the SVSM call with
+ * interrupts disabled. This ensures the correct 'caa' is used even
+ * under preemption or CPU migration.
+ */
+ call->caa = svsm_get_caa();
+
ghcb = __sev_get_ghcb(&state);
do {
@@ -321,7 +330,6 @@ int snp_svsm_vtpm_send_command(u8 *buffer)
{
struct svsm_call call = {};
- call.caa = svsm_get_caa();
call.rax = SVSM_VTPM_CALL(SVSM_VTPM_CMD);
call.rcx = __pa(buffer);
@@ -345,7 +353,6 @@ bool snp_svsm_vtpm_probe(void)
if (!snp_vmpl)
return false;
- call.caa = svsm_get_caa();
call.rax = SVSM_VTPM_CALL(SVSM_VTPM_QUERY);
if (svsm_perform_call_protocol(&call))
--
2.43.0