Drop kvm_vcpu_arch.send_always and instead use msr_en_val as the source of truth to reduce the probability of operating on stale data. This fixes flaws where KVM fails to update send_always when APF is explicitly disabled by the guest or implicitly disabled by KVM on INIT. Absent other bugs, the flaws are benign as KVM *shouldn't* consume send_always when PV APF support is disabled. Simply delete the field, as there's zero benefit to maintaining a separate "cache" of the state. Opportunistically turn the enabled vs. disabled logic at the end of kvm_pv_enable_async_pf() into an if-else instead of using an early return, e.g. so that it's more obvious that both paths are "success" paths. Fixes: 6adba5274206 ("KVM: Let host know whether the guest can handle async PF in non-userspace context.") Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm_host.h | 1 - arch/x86/kvm/x86.c | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index fae1f4aeca5a..2a6906597637 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1038,7 +1038,6 @@ struct kvm_vcpu_arch { u16 vec; u32 id; u32 host_apf_flags; - bool send_always; bool pageready_pending; } apf; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4632222a5d1c..e24877353f17 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3659,16 +3659,12 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) vcpu->arch.apf.msr_en_val = data; - if (!__kvm_pv_async_pf_enabled(data)) { + if (__kvm_pv_async_pf_enabled(data)) { + kvm_async_pf_wakeup_all(vcpu); + } else { kvm_clear_async_pf_completion_queue(vcpu); kvm_async_pf_hash_reset(vcpu); - return 0; } - - vcpu->arch.apf.send_always = (data & KVM_ASYNC_PF_SEND_ALWAYS); - - kvm_async_pf_wakeup_all(vcpu); - return 0; } @@ -14025,7 +14021,7 @@ static bool kvm_can_deliver_async_pf(struct kvm_vcpu *vcpu) if (!kvm_pv_async_pf_enabled(vcpu)) return false; - if (!vcpu->arch.apf.send_always && + if (!(vcpu->arch.apf.msr_en_val & KVM_ASYNC_PF_SEND_ALWAYS) && (vcpu->arch.guest_state_protected || !kvm_x86_call(get_cpl)(vcpu))) return false; -- 2.53.0.1213.gd9a14994de-goog