Re: [PATCH] KVM: x86: Fix incorrect memory constraint for FXSAVE in emulator
From: Paolo Bonzini
Date: Thu Feb 12 2026 - 08:06:12 EST
On 2/12/26 11:27, Uros Bizjak wrote:
The inline asm used to invoke FXSAVE in em_fxsave() and fxregs_fixup()
incorrectly specifies the memory operand as read-write ("+m"). FXSAVE
does not read from the destination operand; it only writes the current
FPU state to memory.
Using a read-write constraint is incorrect and misleading, as it tells
the compiler that the previous contents of the buffer are consumed by
the instruction. In both cases, the buffer passed to FXSAVE is
uninitialized, and marking it as read-write can therefore create a
false dependency on uninitialized memory.
Fix the constraint to write-only ("=m") to accurately describe the
instruction’s behavior and avoid implying that the buffer is read.
IIRC FXSAVE/FXRSTOR may (at least on some microarchitectures?) leave reserved fields untouched.
Intel suggests writing zeros first, and then the "+m" constraint would be the right one because "=m" would cause the memset to be dead.
Paolo
No functional change intended.
Signed-off-by: Uros Bizjak <ubizjak@xxxxxxxxx>
Cc: Sean Christopherson <seanjc@xxxxxxxxxx>
Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
---
arch/x86/kvm/emulate.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c8e292e9a24d..d60094080e3f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3717,7 +3717,7 @@ static int em_fxsave(struct x86_emulate_ctxt *ctxt)
kvm_fpu_get();
- rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_state));
+ rc = asm_safe("fxsave %[fx]", , [fx] "=m"(fx_state));
kvm_fpu_put();
@@ -3741,7 +3741,7 @@ static noinline int fxregs_fixup(struct fxregs_state *fx_state,
struct fxregs_state fx_tmp;
int rc;
- rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_tmp));
+ rc = asm_safe("fxsave %[fx]", , [fx] "=m"(fx_tmp));
memcpy((void *)fx_state + used_size, (void *)&fx_tmp + used_size,
__fxstate_size(16) - used_size);