mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
KVM: VMX: Mark RCX, RDX and RSI as clobbered in vmx_vcpu_run()'s asm blob
Based on upstream commitf3689e3f17. Save RCX, RDX and RSI to fake outputs to coerce the compiler into treating them as clobbered. RCX in particular is likely to be reused by the compiler to dereference the 'struct vcpu_vmx' pointer, which will result in a null pointer dereference now that RCX is zeroed by the asm blob. Tag the asm() blob as volatile to prevent GCC from dropping the blob, which is possible now that the blob has output values, all of which are unused. Upstream commitf3689e3f17("KVM: VMX: Save RSI to an unused output in the vCPU-run asm blob") is not a direct equivalent of this patch. As its shortlog states, it only tagged RSI as clobbered, whereas here RCX and RDX are also clobbered. In upstream at the time of the offending commit (b4be98039ain 4.19,0e0ab73c9aupstream), the inline asm blob had previously been moved to a dedicated helper, __vmx_vcpu_run(). For unrelated reasons, __vmx_vcpu_run() was put into its own optimization unit, which for all intents and purposes made it impossible to consume clobbered registers because RCX, RDX and RSI are volatile and __vmx_vcpu_run() couldn't itself be inlined. In other words, the bug existed but couldn't be hit. Similarly, the lack of "volatile" was also a bug in upstream that was hidden by an unrelated change that exists in upstream but not in 4.19. In this case, the asm blob also uses ASM_CALL_CONSTRAINT (marks RSP as being an input/output constraint) in upstream to play nice with objtool due the blob making a CALL. In 4.19, there is no CALL and thus no ASM_CALL_CONSTRAINT. Furthermore, both of the lurking bugs were blasted away in upstream by commits5e0781df18("KVM: VMX: Move vCPU-run code to a proper assembly routine") andfc2ba5a27a("KVM: VMX: Call vCPU-run asm sub-routine from C and remove clobbering"), i.e. these bugs will never be directly fixed in upstream. Reported-by: Tobias Urdin <tobias.urdin@binero.com> Fixes:b4be98039a("KVM: VMX: Zero out *all* general purpose registers after VM-Exit") Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0590bcdea7
commit
52d5afedf3
@@ -10771,7 +10771,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
else if (static_branch_unlikely(&mds_user_clear))
|
||||
mds_clear_cpu_buffers();
|
||||
|
||||
asm(
|
||||
asm volatile (
|
||||
/* Store host registers */
|
||||
"push %%" _ASM_DX "; push %%" _ASM_BP ";"
|
||||
"push %%" _ASM_CX " \n\t" /* placeholder for guest rcx */
|
||||
@@ -10882,7 +10882,8 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
".global vmx_return \n\t"
|
||||
"vmx_return: " _ASM_PTR " 2b \n\t"
|
||||
".popsection"
|
||||
: : "c"(vmx), "d"((unsigned long)HOST_RSP), "S"(evmcs_rsp),
|
||||
: "=c"((int){0}), "=d"((int){0}), "=S"((int){0})
|
||||
: "c"(vmx), "d"((unsigned long)HOST_RSP), "S"(evmcs_rsp),
|
||||
[launched]"i"(offsetof(struct vcpu_vmx, __launched)),
|
||||
[fail]"i"(offsetof(struct vcpu_vmx, fail)),
|
||||
[host_rsp]"i"(offsetof(struct vcpu_vmx, host_rsp)),
|
||||
|
||||
Reference in New Issue
Block a user