From nobody Thu Apr 9 20:26:47 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 60F0233A9DE; Thu, 5 Mar 2026 20:30:25 +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=1772742625; cv=none; b=Uo4LWBP2A8OfJvIkqBo9WIRuORraJG/4LKNfoKiZx3lauKR1tpmHxv8XKTg6WvaixNzJBBD9+q50INGoFTpMdeU94OSM6G16fgkt+HJo6RdkfI6ie22E74H/QN0ZwdOAzx+LmQNzKWA64d/nzhDXRn5JTOEQz78SSLQs/6CvY/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772742625; c=relaxed/simple; bh=rSa2W0G7aR8oOklcUQq87bd3yTbbQ5Kd8Baa+AD/1iY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MvtVP0O6XX5x3o3hhejLENdgFlLWybgJToFv6Y6clrAIIJwFwXBzxdeIz6kynWq3FDZh4isRi8fYpThdvAprjVDAtSX1Bnk1iuhYDbthf8C81ntUjcOTpzwFmgbwMSt/G9Ex9gt2aph2e/3qH1mdbrpn/vpqLuSwJoWu1z0pvfA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RUSOa6nO; 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="RUSOa6nO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DEB8FC19422; Thu, 5 Mar 2026 20:30:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772742625; bh=rSa2W0G7aR8oOklcUQq87bd3yTbbQ5Kd8Baa+AD/1iY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RUSOa6nOBiKNmzJpkdg/KEjaV/dUDdPQYAz+DGv/436F1+KK/auKIIbqo8qYHaqkC s4XhQSD4kv4kCv/Jd31o7DEsmQ+8rpkC5zSKgGBzGjVtLCzAglMjB+9U6IqWYu0WFM ULhsEee2FD5YrNItpS5VuushXm6nv/gwFQ6kgEBA+4zwaPmd9pPgPSoq7mA0s/ph8P 2r2v9fHPrGHLlKE7UmDdd9ocBpyJ2mimUWqAEI1UK9+RAxrbJH3GEKUlnoWeuZ4BB7 EkoIicdrrSkON8/7QlRykFq1jIVlwoxr+YOP5mcyAh4u5FEABAdb84zmXMegOcQYaw zmK0iXhnizfmw== From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH 1/2] KVM: nSVM: Simplify error handling of nested_svm_copy_vmcb12_to_cache() Date: Thu, 5 Mar 2026 20:30:04 +0000 Message-ID: <20260305203005.1021335-2-yosry@kernel.org> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog In-Reply-To: <20260305203005.1021335-1-yosry@kernel.org> References: <20260305203005.1021335-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" nested_svm_vmrun() currently stores the return value of nested_svm_copy_vmcb12_to_cache() in a local variable 'err', separate from the generally used 'ret' variable. This is done to have a single call to kvm_skip_emulated_instruction(), such that we can store the return value of kvm_skip_emulated_instruction() in 'ret', and then re-check the return value of nested_svm_copy_vmcb12_to_cache() in 'err'. The code is unnecessarily confusing. Instead, call kvm_skip_emulated_instruction() in the failure path of nested_svm_copy_vmcb12_to_cache() if the return value is not -EFAULT, and drop 'err'. Suggested-by: Sean Christopherson Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/nested.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index b191c6cab57db..54227bacc12e4 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1079,7 +1079,7 @@ static int nested_svm_copy_vmcb12_to_cache(struct kvm= _vcpu *vcpu, u64 vmcb12_gpa int nested_svm_vmrun(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm =3D to_svm(vcpu); - int ret, err; + int ret; u64 vmcb12_gpa; struct vmcb *vmcb01 =3D svm->vmcb01.ptr; =20 @@ -1104,19 +1104,20 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) return -EINVAL; =20 vmcb12_gpa =3D svm->vmcb->save.rax; - err =3D nested_svm_copy_vmcb12_to_cache(vcpu, vmcb12_gpa); - if (err =3D=3D -EFAULT) { - kvm_inject_gp(vcpu, 0); - return 1; + ret =3D nested_svm_copy_vmcb12_to_cache(vcpu, vmcb12_gpa); + if (ret) { + /* + * Advance RIP if #GP or #UD are not injected, but otherwise + * stop if copying and checking vmcb12 failed. + */ + if (ret =3D=3D -EFAULT) { + kvm_inject_gp(vcpu, 0); + return 1; + } + return kvm_skip_emulated_instruction(vcpu); } =20 - /* - * Advance RIP if #GP or #UD are not injected, but otherwise stop if - * copying and checking vmcb12 failed. - */ ret =3D kvm_skip_emulated_instruction(vcpu); - if (err) - return ret; =20 /* * Since vmcb01 is not in use, we can use it to store some of the L1 --=20 2.53.0.473.g4a7958ca14-goog From nobody Thu Apr 9 20:26:47 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 D63C133A9FF; Thu, 5 Mar 2026 20:30:25 +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=1772742626; cv=none; b=uXp7cgyYEhF1wSZOIjd5t+bXfOJD5u7Yc5jnYiZXsuS+U6Pw0HSHmeJcJRzvgUDBXX7PK4PrIb4YYgmaQLQiMAkE27HTtcPK6iPsalrx0z9ZW98u8k3gkwIhDbLBWb5EUjo0mf2MjnZim4ckcua5w6O7K6LJfY3rrA+eac5hUMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772742626; c=relaxed/simple; bh=czB0idmCQXOwrXDrOdJ3Ftkm+nhGFiwI7nJsQQe6uEc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gfdXt6HR0xuTZtFwsADPehPCcmN2ZH3Dh7+2vD5mZ71o1AXcbuDP2GSpe616YyvLQkAbHbpjrdYpe+NWWQ7+aQqkxatxFrGMWevzpy6E269Sbr0m7YmD83yaUpuvgwKb6vw0+G7wRW/nz/qRq0NwsLjinLddehQfQkNtzLceKFo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dU4JRJpE; 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="dU4JRJpE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4283EC2BCAF; Thu, 5 Mar 2026 20:30:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772742625; bh=czB0idmCQXOwrXDrOdJ3Ftkm+nhGFiwI7nJsQQe6uEc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dU4JRJpEmznYO4h51LQ6mRt11jH/zAgZw9dpEOh3846V0HrRyYqi2qMNK4ou86ztt OlBKd6Jg2FhGqRf3WYG/H0ZCHsLIWV7NcZzBtNzu2B8kbNw0dZassHvbN/GPzgAjv/ fcmZVL/TwVLoZlqWCEHUQPfM5W/SsqBKEYeuOsxA3eisuDe2gLOOjoT/gn/qVXNG8b fRHzaw5GJziikvOOZBwKgWNX8n7xRT3EdONRkQQf9U/OomOV4xU4KcXVuUS4FGWa3J ZRCHMuO3oQeaPMVH0q/CvycqRSP6hDCQLmETe3d5S9hohOtlSaTxdMajPaiza4ZYDY OswaO6ygZFlgg== From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH 2/2] KVM: selftests: Actually check #GP on VMRUN with invalid vmcb12 Date: Thu, 5 Mar 2026 20:30:05 +0000 Message-ID: <20260305203005.1021335-3-yosry@kernel.org> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog In-Reply-To: <20260305203005.1021335-1-yosry@kernel.org> References: <20260305203005.1021335-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" in svm_nested_invalid_vmcb12_gpa test, run_guest() is called with an unmappable vmcb12 GPA to make sure KVM injects a #GP. However, run_guest() executes VMLOAD first, so the #GP does not actually come from the VMRUN handler. Execute VMRUN directly from L1 code with the invalid GPA instead of calling into run_guest(), and have the #GP handler skip over it (instead of fixing up the VMCBA GPA). A separate run_guest() call is then done for the remaining test cases. Also assert that #GP happened on VMRUN to avoid falling into the same problem. Opportunisitically drop the GUEST_SYNC() from the #GP handler, as L1 already asserts gp_triggered is 1. Signed-off-by: Yosry Ahmed --- .../kvm/x86/svm_nested_invalid_vmcb12_gpa.c | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/svm_nested_invalid_vmcb12_gpa.= c b/tools/testing/selftests/kvm/x86/svm_nested_invalid_vmcb12_gpa.c index c6d5f712120d1..8b681796b48ef 100644 --- a/tools/testing/selftests/kvm/x86/svm_nested_invalid_vmcb12_gpa.c +++ b/tools/testing/selftests/kvm/x86/svm_nested_invalid_vmcb12_gpa.c @@ -10,23 +10,25 @@ =20 #define L2_GUEST_STACK_SIZE 64 =20 -#define SYNC_GP 101 -#define SYNC_L2_STARTED 102 +#define VMRUN_OPCODE 0x000f01d8 =20 -u64 valid_vmcb12_gpa; int gp_triggered; =20 static void guest_gp_handler(struct ex_regs *regs) { + unsigned char *insn =3D (unsigned char *)regs->rip; + u32 opcode =3D (insn[0] << 16) | (insn[1] << 8) | insn[2]; + + GUEST_ASSERT_EQ(opcode, VMRUN_OPCODE); GUEST_ASSERT(!gp_triggered); - GUEST_SYNC(SYNC_GP); + gp_triggered =3D 1; - regs->rax =3D valid_vmcb12_gpa; + regs->rip +=3D 3; /* Skip over VMRUN */ } =20 static void l2_guest_code(void) { - GUEST_SYNC(SYNC_L2_STARTED); + GUEST_SYNC(1); vmcall(); } =20 @@ -37,11 +39,12 @@ static void l1_guest_code(struct svm_test_data *svm, u6= 4 invalid_vmcb12_gpa) generic_svm_setup(svm, l2_guest_code, &l2_guest_stack[L2_GUEST_STACK_SIZE]); =20 - valid_vmcb12_gpa =3D svm->vmcb_gpa; + asm volatile ("vmrun %[invalid_vmcb12_gpa]" : + : [invalid_vmcb12_gpa] "a" (invalid_vmcb12_gpa) + : "memory"); + GUEST_ASSERT_EQ(gp_triggered, 1); =20 - run_guest(svm->vmcb, invalid_vmcb12_gpa); /* #GP */ - - /* GP handler should jump here */ + run_guest(svm->vmcb, svm->vmcb_gpa); GUEST_ASSERT(svm->vmcb->control.exit_code =3D=3D SVM_EXIT_VMMCALL); GUEST_DONE(); } @@ -70,12 +73,6 @@ int main(int argc, char *argv[]) vcpu_alloc_svm(vm, &nested_gva); vcpu_args_set(vcpu, 2, nested_gva, max_legal_gpa); =20 - /* VMRUN with max_legal_gpa, KVM injects a #GP */ - vcpu_run(vcpu); - TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); - TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_SYNC); - TEST_ASSERT_EQ(uc.args[1], SYNC_GP); - /* * Enter L2 (with a legit vmcb12 GPA), then overwrite vmcb12 GPA with * max_legal_gpa. KVM will fail to map vmcb12 on nested VM-Exit and @@ -84,7 +81,7 @@ int main(int argc, char *argv[]) vcpu_run(vcpu); TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_SYNC); - TEST_ASSERT_EQ(uc.args[1], SYNC_L2_STARTED); + TEST_ASSERT_EQ(uc.args[1], 1); =20 state =3D vcpu_save_state(vcpu); state->nested.hdr.svm.vmcb_pa =3D max_legal_gpa; --=20 2.53.0.473.g4a7958ca14-goog