KVM tracks when EFER.SVME is set and cleared to initialize and tear down nested state. However, it doesn't differentiate if EFER.SVME is getting toggled in L1 or L2+. Toggling EFER.SVME in L2+ is inconsequential from KVM's perspective, as the vCPU is still obviously using nested. This causes a problem if L2 sets then clears EFER.SVME without L1 interception, as KVM exits guest mode and tears down nested state while L2 is running, executing L1 without injecting a proper #VMEXIT. Technically, it's not a bug as the APM states that an L1 hypervisor should intercept EFER writes: The effect of turning off EFER.SVME while a guest is running is undefined; therefore, the VMM should always prevent guests from writing EFER. However, it would be nice if KVM handled it more gracefully. Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/svm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 4575a6a7d6c4e..eaf0f8053fbfb 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -208,6 +208,13 @@ static int svm_set_efer_svme(struct kvm_vcpu *vcpu, u64 old_efer, u64 new_efer) if ((old_efer & EFER_SVME) == (new_efer & EFER_SVME)) return 0; + /* + * An L2 guest setting or clearing EFER_SVME does not change whether or + * not the vCPU can use nested from KVM's perspective. + */ + if (is_guest_mode(vcpu)) + return 0; + if (new_efer & EFER_SVME) { r = svm_allocate_nested(svm); if (r) -- 2.53.0.rc1.225.gd81095ad13-goog