Re: [PATCH] KVM: Never clear KVM_REQ_VM_DEAD from a vCPU's requests
From: Huang, Kai
Date: Sun Aug 09 2026 - 21:30:11 EST
On Thu, 2026-08-06 at 14:46 -0700, Sean Christopherson wrote:
> Use kvm_test_request() instead of kvm_check_request() when querying
> KVM_REQ_VM_DEAD, i.e. don't clear KVM_REQ_VM_DEAD, as the entire purpose
> of KVM_REQ_VM_DEAD is to prevent the vCPU from enterring the guest ever
> again, even if userspace insists on redoing KVM_RUN.
>
> Ensuring KVM_REQ_VM_DEAD is never cleared will allow relaxing KVM's rule
> that ioctls can't be invoked on dead VMs, to only disallow ioctls if the
> VM is bugged, i.e. if KVM hit a KVM_BUG_ON().
>
> Opportunistically add compile-time assertions to guard against clearing
> KVM_REQ_VM_DEAD through the standard APIs.
>
> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Reviewed-by: Kai Huang <kai.huang@xxxxxxxxx>
FWIW, I build tested that both gcc and clang could build successfully (both -O2
and -Os).
[...]
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -2324,13 +2324,18 @@ static inline bool kvm_test_request(int req, struct kvm_vcpu *vcpu)
> return test_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests);
> }
>
> -static inline void kvm_clear_request(int req, struct kvm_vcpu *vcpu)
> +static __always_inline void kvm_clear_request(int req, struct kvm_vcpu *vcpu)
> {
> + BUILD_BUG_ON(req == KVM_REQ_VM_DEAD);
> +
> clear_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests);
> }
>
> -static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
> +static __always_inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
> {
> + /* Once a VM is dead, it needs to stay dead. */
> + BUILD_BUG_ON(req == KVM_REQ_VM_DEAD);
> +
> if (kvm_test_request(req, vcpu)) {
> kvm_clear_request(req, vcpu);
>
Nit: AFAICT the change to __always_inline is to avoid build failure. Perhaps
explicitly mention this in changelog?
Btw, I also tried building the kernel after reverting __always_inline to plain
inline, but indeed got build error when using clang (clang failed with both -O2
and -Os, but gcc was fine for both, though).