From nobody Thu Apr 9 16:59:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEDC248A2AE; Fri, 6 Mar 2026 21:09:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772831352; cv=none; b=lS17pmHvjcE0uBOgAL3V+m+IYfT0a6xtSRBo5AnLcJWAGvhOTONWjckmoNuRRckIATf8bbNguyPKHZ5+//A8NTvYX+BE/uR/ZNFQBTvsTPi4/eXMOFYTSLrb6129NVIsgJQ0/Oj6tVw0wspPU+amxjvRdkC77sRiJmnIe/azQmg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772831352; c=relaxed/simple; bh=W1GDvhBjURiDIQSdO6sAf7i/CnmSx/BtLxKrERUXc7Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TZv/bKwqbrx7gVAb7qBYKSa4h/48YPf9u43IPoVFF6VqT0OZO0ZMsS72HBp+jyeg7R2bRlDe8XuWbnavgbgdbvaVihpMZuDMxOuLDdBp3TJ6UWU7YKJpSZiGheJvW659K8y9Gcvg63OqvwHFdXw1NObyww6Qn781b+FKyTbVKUM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dQt1nSsX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dQt1nSsX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3D10DC2BC9E; Fri, 6 Mar 2026 21:09:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772831352; bh=W1GDvhBjURiDIQSdO6sAf7i/CnmSx/BtLxKrERUXc7Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dQt1nSsXr0JyiwaryAGSWx9p2npmCf/1gWOYpifa/dfwWIi8HaEQytM6FPnbbYGyq sQ52Y4PTgCAyaLWnkR2lu9ubVvsk5MspUqz+2BKvvov8/GgI+zq4OUS8axNds1iD5P 0gQVKmFSFtj/3s44rHf8i8J2HChVP3TMCcuR8LClDsTaAQ6wMgi4jJoniUEkMfgCq4 1VL9H/Ok0lfv9dJOU0+WGMIPFFOi7/4VjvhO/q8aWPJQW7FD4pIkFGejforGK1DZlI PTFBuAwPGqreOSd7qiZC8/7B2PWemxJVo8x4Tn8ii40B3BEJ2bumBMD1IfU67nS4Wh PKW7lXRZL6BsA== From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , Jim Mattson , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH v2 4/6] KVM: nSVM: Fail emulation of VMRUN/VMLOAD/VMSAVE if mapping vmcb12 fails Date: Fri, 6 Mar 2026 21:08:58 +0000 Message-ID: <20260306210900.1933788-5-yosry@kernel.org> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog In-Reply-To: <20260306210900.1933788-1-yosry@kernel.org> References: <20260306210900.1933788-1-yosry@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" KVM currently injects a #GP if mapping vmcb12 fails when emulating VMRUN/VMLOAD/VMSAVE. This is not architectural behavior, as #GP should only be injected if the physical address is not supported or not aligned (which hardware will do before the VMRUN intercept is checked). Instead, handle it as an emulation failure, similar to how nVMX handles failures to read/write guest memory in several emulation paths. When virtual VMLOAD/VMSAVE is enabled, if vmcb12's GPA is not mapped in the NPTs a VMEXIT(#NPF) will be generated, and KVM will install an MMIO SPTE and emulate the instruction if there is no corresponding memslot. x86_emulate_insn() will return EMULATION_FAILED as VMLOAD/VMSAVE are not handled as part of the twobyte_insn cases. Even though this will also result in an emulation failure, it will only result in a straight return to userspace if KVM_CAP_EXIT_ON_EMULATION_FAILURE is set. Otherwise, it would inject #UD and only exit to userspace if not in guest mode. So the behavior is slightly different if virtual VMLOAD/VMSAVE is enabled. Fixes: 3d6368ef580a ("KVM: SVM: Add VMRUN handler") Reported-by: Jim Mattson Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/nested.c | 13 ++++++------- arch/x86/kvm/svm/svm.c | 6 ++---- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 6d4c053778b21..089cdcfd60340 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1107,15 +1107,14 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) ret =3D nested_svm_copy_vmcb12_to_cache(vcpu, vmcb12_gpa); =20 /* - * Advance RIP if #GP or #UD are not injected, but otherwise - * stop if copying and checking vmcb12 failed. + * Advance RIP if instruction emulation completes, whether it's a + * successful VMRUN or a failed one with #VMEXIT(INVALID), but not if + * #GP/#UD is injected, or if reading vmcb12 fails. */ - if (ret =3D=3D -EFAULT) { - kvm_inject_gp(vcpu, 0); - return 1; - } else if (ret) { + if (ret =3D=3D -EFAULT) + return kvm_handle_memory_failure(vcpu, X86EMUL_IO_NEEDED, NULL); + else if (ret) return kvm_skip_emulated_instruction(vcpu); - } =20 ret =3D kvm_skip_emulated_instruction(vcpu); =20 diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 7ec0b0e8945fe..35433bd345eff 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2190,10 +2190,8 @@ static int vmload_vmsave_interception(struct kvm_vcp= u *vcpu, bool vmload) if (nested_svm_check_permissions(vcpu)) return 1; =20 - if (kvm_vcpu_map(vcpu, gpa_to_gfn(svm->vmcb->save.rax), &map)) { - kvm_inject_gp(vcpu, 0); - return 1; - } + if (kvm_vcpu_map(vcpu, gpa_to_gfn(svm->vmcb->save.rax), &map)) + return kvm_handle_memory_failure(vcpu, X86EMUL_IO_NEEDED, NULL); =20 vmcb12 =3D map.hva; =20 --=20 2.53.0.473.g4a7958ca14-goog