From nobody Wed Dec 17 14:09:09 2025 Received: from out-182.mta1.migadu.com (out-182.mta1.migadu.com [95.215.58.182]) (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 9886327781D for ; Tue, 21 Oct 2025 07:48:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032909; cv=none; b=U6bcBYyEd3lxeeNRR3K3YJRkIi92FL5z99yNo8vItCuE9MZrJd1YNEbKaBraftkIcWSjsUPYHvzi2g+EU3RU5OmiJ3jO8W9F09tjmI0JXXx+LboY3SuK1t3a0wxSh/JN7YCQWW6WIeLINN1jJlsZo+K4EmfxhcMkKnqs6LtU2jQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032909; c=relaxed/simple; bh=MtifbCAcL8U05ZhL3lsSk6V4AKS5alLo7oXyL2hRp9Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=efojCglMKPWfdtqP1i160osOlpck2VtEvh2hkIa1/YXxMWjZSE6C4WuWA8f+YzRT0pkC6msqvfHLbZd/t08UO6zpFCDhlZZ+SLiYB7NP7VD+fR3fN4wDO7TdMY5xicZcquOAPuV/MKx25iUEEfyMFx1Kn7h7wz5KQrs1PAyQKZ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=ZImhPlfL; arc=none smtp.client-ip=95.215.58.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="ZImhPlfL" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032903; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KwuNI56/YT0XrwR6EWpwHEch4X2fFRdAV4JvJVFYjTw=; b=ZImhPlfLuRwNGaHKZ6vM5f6mZp1/N1SzMzVQ2MUVW1uda7p6XEtLnxBOdzF38KWrmRgDYw MvF75zcy1bac6xtBh5LlxKWHPVfINM1osLwemkealhBbKjzbY4DNl76k7+0Eje5inuwzmc RiJC6TBmAViXU5Lt99xkgPF/nG31WgI= 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 01/23] KVM: selftests: Minor improvements to asserts in test_vmx_nested_state() Date: Tue, 21 Oct 2025 07:47:14 +0000 Message-ID: <20251021074736.1324328-2-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Display the address as hex if the asserts for the vmxon_pa and vmcs12_pa fail, and assert that the flags are 0 as expected. Reviewed-by: Jim Mattson Signed-off-by: Yosry Ahmed --- .../selftests/kvm/x86/vmx_set_nested_state_test.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c b/= tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c index 67a62a5a88951..c4c400d2824c1 100644 --- a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c @@ -241,8 +241,14 @@ void test_vmx_nested_state(struct kvm_vcpu *vcpu) TEST_ASSERT(state->size >=3D sizeof(*state) && state->size <=3D state_sz, "Size must be between %ld and %d. The size returned was %d.", sizeof(*state), state_sz, state->size); - TEST_ASSERT(state->hdr.vmx.vmxon_pa =3D=3D -1ull, "vmxon_pa must be -1ull= ."); - TEST_ASSERT(state->hdr.vmx.vmcs12_pa =3D=3D -1ull, "vmcs_pa must be -1ull= ."); + TEST_ASSERT(state->hdr.vmx.vmxon_pa =3D=3D -1ull, + "vmxon_pa must be 0x%llx, but was 0x%llx", + -1ull, state->hdr.vmx.vmxon_pa); + TEST_ASSERT(state->hdr.vmx.vmcs12_pa =3D=3D -1ull, + "vmcs12_pa must be 0x%llx, but was 0x%llx", + -1llu, state->hdr.vmx.vmcs12_pa); + TEST_ASSERT(state->flags =3D=3D 0, + "Flags must be equal to 0, but was 0x%hx", state->flags); =20 free(state); } --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-181.mta1.migadu.com (out-181.mta1.migadu.com [95.215.58.181]) (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 737EC28724D for ; Tue, 21 Oct 2025 07:48:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032909; cv=none; b=uFzCP045uTxcyjdqEeftizDmhya9nVdXpqBGPJ5ina+TZrr0kqxwUPtYyHjdJQ+lHn9Qw2yv7TIEbd2Z4c80wsfPSccaTTvpqXDyvu5IaAtN/5tN0/oAEiNGZZC4QjJIr+qOb062jHBMYK192J8dgX/THJx9K9hpYiJJ8WrST+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032909; c=relaxed/simple; bh=LVaNsMENmT4737mdcGISug41MsGcyyDTOc4ia6HTcWk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uUdB9hNFpTqetpr/Lw8GxoaK/Xzp4BRL7FY2C5qWMjsHpsysm78IULtuVsHytSas1uu+2iVc524JMlF84dju/ssitGpUdxfHZLCNv2U47ZWOljuBrtwdDGrEkK048/TqPmeCiPIEdyUXsbIiAEeGMAshpjYiPOCcCt7qU8QhFG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=OsER5dzZ; arc=none smtp.client-ip=95.215.58.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="OsER5dzZ" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032905; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lTUNDlo9q1HwlAfQ4iXfIow91z31JD44qVXsfLHshAQ=; b=OsER5dzZWsRtqXfpXMBpt56h/7jdqWjImCF/BpgEp8UVwgjKxI0CWmHA7tTnEah7NltKF4 ajSQ1TbvhHrWhNfyW56c7rZ4yfeQBpwyUIaDQz0mBM2/Ncz5PbNjphuxKgs988CbOiw884 N6Y2BJ5W3Ee2aBWnUn5mDtrEgUfcPsg= 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 02/23] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM Date: Tue, 21 Oct 2025 07:47:15 +0000 Message-ID: <20251021074736.1324328-3-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add test cases for the validation checks in svm_set_nested_state(), and allow the test to run with SVM as well as VMX. The SVM test also makes sure that KVM_SET_NESTED_STATE accepts GIF being set or cleared if EFER.SVME is cleared, verifying a recently fixed bug where GIF was incorrectly expected to always be set when EFER.SVME is cleared. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/Makefile.kvm | 2 +- ...d_state_test.c =3D> set_nested_state_test.c} | 125 ++++++++++++++++-- 2 files changed, 116 insertions(+), 11 deletions(-) rename tools/testing/selftests/kvm/x86/{vmx_set_nested_state_test.c =3D> s= et_nested_state_test.c} (70%) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index b9279ce4eaab8..acfa22206e6f3 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -100,6 +100,7 @@ TEST_GEN_PROGS_x86 +=3D x86/set_sregs_test TEST_GEN_PROGS_x86 +=3D x86/smaller_maxphyaddr_emulation_test TEST_GEN_PROGS_x86 +=3D x86/smm_test TEST_GEN_PROGS_x86 +=3D x86/state_test +TEST_GEN_PROGS_x86 +=3D x86/set_nested_state_test TEST_GEN_PROGS_x86 +=3D x86/vmx_preemption_timer_test TEST_GEN_PROGS_x86 +=3D x86/svm_vmcall_test TEST_GEN_PROGS_x86 +=3D x86/svm_int_ctl_test @@ -116,7 +117,6 @@ TEST_GEN_PROGS_x86 +=3D x86/vmx_dirty_log_test TEST_GEN_PROGS_x86 +=3D x86/vmx_exception_with_invalid_guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_msrs_test TEST_GEN_PROGS_x86 +=3D x86/vmx_invalid_nested_guest_state -TEST_GEN_PROGS_x86 +=3D x86/vmx_set_nested_state_test TEST_GEN_PROGS_x86 +=3D x86/vmx_la57_nested_state_test TEST_GEN_PROGS_x86 +=3D x86/vmx_tsc_adjust_test TEST_GEN_PROGS_x86 +=3D x86/vmx_nested_tsc_scaling_test diff --git a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c b/= tools/testing/selftests/kvm/x86/set_nested_state_test.c similarity index 70% rename from tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c rename to tools/testing/selftests/kvm/x86/set_nested_state_test.c index c4c400d2824c1..fe12fffacd2ec 100644 --- a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86/set_nested_state_test.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * vmx_set_nested_state_test + * set_nested_state_test * * Copyright (C) 2019, Google LLC. * @@ -11,6 +11,7 @@ #include "kvm_util.h" #include "processor.h" #include "vmx.h" +#include "svm_util.h" =20 #include #include @@ -253,6 +254,107 @@ void test_vmx_nested_state(struct kvm_vcpu *vcpu) free(state); } =20 +static void vcpu_efer_enable_svm(struct kvm_vcpu *vcpu) +{ + uint64_t old_efer =3D vcpu_get_msr(vcpu, MSR_EFER); + + vcpu_set_msr(vcpu, MSR_EFER, old_efer | EFER_SVME); +} + +static void vcpu_efer_disable_svm(struct kvm_vcpu *vcpu) +{ + uint64_t old_efer =3D vcpu_get_msr(vcpu, MSR_EFER); + + vcpu_set_msr(vcpu, MSR_EFER, old_efer & ~EFER_SVME); +} + +void set_default_svm_state(struct kvm_nested_state *state, int size) +{ + memset(state, 0, size); + state->format =3D 1; + state->size =3D size; + state->hdr.svm.vmcb_pa =3D 0x3000; +} + +void test_svm_nested_state(struct kvm_vcpu *vcpu) +{ + /* Add a page for VMCB. */ + const int state_sz =3D sizeof(struct kvm_nested_state) + getpagesize(); + struct kvm_nested_state *state =3D + (struct kvm_nested_state *)malloc(state_sz); + + vcpu_set_cpuid_feature(vcpu, X86_FEATURE_SVM); + + /* The format must be set to 1. 0 for VMX, 1 for SVM. */ + set_default_svm_state(state, state_sz); + state->format =3D 0; + test_nested_state_expect_einval(vcpu, state); + + /* Invalid flags are rejected, KVM_STATE_NESTED_EVMCS is VMX-only */ + set_default_svm_state(state, state_sz); + state->flags =3D KVM_STATE_NESTED_EVMCS; + test_nested_state_expect_einval(vcpu, state); + + /* + * If EFER.SVME is clear, guest mode is disallowed and GIF can be set or + * cleared. + */ + vcpu_efer_disable_svm(vcpu); + + set_default_svm_state(state, state_sz); + state->flags =3D KVM_STATE_NESTED_GUEST_MODE; + test_nested_state_expect_einval(vcpu, state); + + state->flags =3D 0; + test_nested_state(vcpu, state); + + state->flags =3D KVM_STATE_NESTED_GIF_SET; + test_nested_state(vcpu, state); + + /* Enable SVM in the guest EFER. */ + vcpu_efer_enable_svm(vcpu); + + /* Setting vmcb_pa to a non-aligned address is only fine when not enterin= g guest mode */ + set_default_svm_state(state, state_sz); + state->hdr.svm.vmcb_pa =3D -1ull; + state->flags =3D 0; + test_nested_state(vcpu, state); + state->flags =3D KVM_STATE_NESTED_GUEST_MODE; + test_nested_state_expect_einval(vcpu, state); + + /* + * Size must be large enough to fit kvm_nested_state and VMCB + * only when entering guest mode. + */ + set_default_svm_state(state, state_sz/2); + state->flags =3D 0; + test_nested_state(vcpu, state); + state->flags =3D KVM_STATE_NESTED_GUEST_MODE; + test_nested_state_expect_einval(vcpu, state); + + /* + * Test that if we leave nesting the state reflects that when we get it + * again, except for vmcb_pa, which is always returned as 0 when not in + * guest mode. + */ + set_default_svm_state(state, state_sz); + state->hdr.svm.vmcb_pa =3D -1ull; + state->flags =3D KVM_STATE_NESTED_GIF_SET; + test_nested_state(vcpu, state); + vcpu_nested_state_get(vcpu, state); + TEST_ASSERT(state->size >=3D sizeof(*state) && state->size <=3D state_sz, + "Size must be between %ld and %d. The size returned was %d.", + sizeof(*state), state_sz, state->size); + TEST_ASSERT(state->hdr.svm.vmcb_pa =3D=3D 0, + "vmcb_pa must be 0, but was %llx", + state->hdr.svm.vmcb_pa); + TEST_ASSERT(state->flags =3D=3D KVM_STATE_NESTED_GIF_SET, + "Flags must be equal to 0x%hx, but was 0x%hx", + KVM_STATE_NESTED_GIF_SET, state->flags); + + free(state); +} + int main(int argc, char *argv[]) { struct kvm_vm *vm; @@ -261,20 +363,20 @@ int main(int argc, char *argv[]) =20 have_evmcs =3D kvm_check_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS); =20 + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) || + kvm_cpu_has(X86_FEATURE_SVM)); TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE)); =20 - /* - * AMD currently does not implement set_nested_state, so for now we - * just early out. - */ - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); - vm =3D vm_create_with_one_vcpu(&vcpu, NULL); =20 /* - * First run tests with VMX disabled to check error handling. + * First run tests with VMX/SVM disabled to check error handling. + * test_{vmx/svm}_nested_state() will re-enable as needed. */ - vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_VMX); + if (kvm_cpu_has(X86_FEATURE_VMX)) + vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_VMX); + else + vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_SVM); =20 /* Passing a NULL kvm_nested_state causes a EFAULT. */ test_nested_state_expect_efault(vcpu, NULL); @@ -303,7 +405,10 @@ int main(int argc, char *argv[]) state.flags =3D KVM_STATE_NESTED_RUN_PENDING; test_nested_state_expect_einval(vcpu, &state); =20 - test_vmx_nested_state(vcpu); + if (kvm_cpu_has(X86_FEATURE_VMX)) + test_vmx_nested_state(vcpu); + else + test_svm_nested_state(vcpu); =20 kvm_vm_free(vm); return 0; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) (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 994A628BAB1 for ; Tue, 21 Oct 2025 07:48:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032913; cv=none; b=aVU2KRWC7WVR6AsQPStZU9bomAzgsnmHnh2ziznx3FVd+R4hOtj16Z9grkxqeSs0zUBcFW+KX6nPTxSxWQCSo2tL2bK9LJinvKcrSzB/NPrzGYgsPqHz1eBoshEyd+txlZoeqmwBFnzNbRoRymY1ggaqxYm1sYsONbQsVQfDbPY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032913; c=relaxed/simple; bh=6Jx1MhM217SwZM+cxtA/ojGcBN3OS49NXF1+7zwaxDg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n410kaist6aZ1lDkB0oONlpQRu0LD/GfC5l1+zsHe6KHDeT1RTRf/AWDoW2FV51CqJQGV+xi59p1zKirqVWyZvwX1cKrSMD0MRywWqM4bL73chBk2xElYnyb6tzGFQkLHYdV/oIGilNYlqM+/2n+p45cHsMAtBv11vKLjT06G/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=lnmPdlU1; arc=none smtp.client-ip=95.215.58.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="lnmPdlU1" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032907; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lW5vlmOxiZfXmXD5G5Wy/XGpsW60h81v/HMTtKxjkGI=; b=lnmPdlU1V1Fm94d0Yc+TPQrV25Nlwn44sSXVKYerSrS9OaeMf7zp+emR3q3duM5sRbyqvE 93L310s0UF7UZeFGwd+s86aHI/CrNCz9OfqKUDRC3roVA0iJcODL72uv8vnL00K5cqOAGd An+hdvSr1xzD2qfKdkH0S/firAqmI0Y= 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 03/23] KVM: selftests: Extend vmx_close_while_nested_test to cover SVM Date: Tue, 21 Oct 2025 07:47:16 +0000 Message-ID: <20251021074736.1324328-4-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add SVM L1 code to run the nested guest, and allow the test to run with SVM as well as VMX. Reviewed-by: Jim Mattson Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/Makefile.kvm | 2 +- ...ested_test.c =3D> close_while_nested_test.c} | 42 +++++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-) rename tools/testing/selftests/kvm/x86/{vmx_close_while_nested_test.c =3D>= close_while_nested_test.c} (64%) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index acfa22206e6f3..e70a844a52bdc 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -112,7 +112,7 @@ TEST_GEN_PROGS_x86 +=3D x86/ucna_injection_test TEST_GEN_PROGS_x86 +=3D x86/userspace_io_test TEST_GEN_PROGS_x86 +=3D x86/userspace_msr_exit_test TEST_GEN_PROGS_x86 +=3D x86/vmx_apic_access_test -TEST_GEN_PROGS_x86 +=3D x86/vmx_close_while_nested_test +TEST_GEN_PROGS_x86 +=3D x86/close_while_nested_test TEST_GEN_PROGS_x86 +=3D x86/vmx_dirty_log_test TEST_GEN_PROGS_x86 +=3D x86/vmx_exception_with_invalid_guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_msrs_test diff --git a/tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c = b/tools/testing/selftests/kvm/x86/close_while_nested_test.c similarity index 64% rename from tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c rename to tools/testing/selftests/kvm/x86/close_while_nested_test.c index dad988351493e..cf5f24c83c448 100644 --- a/tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c +++ b/tools/testing/selftests/kvm/x86/close_while_nested_test.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * vmx_close_while_nested + * close_while_nested_test * * Copyright (C) 2019, Red Hat, Inc. * @@ -12,6 +12,7 @@ #include "kvm_util.h" #include "processor.h" #include "vmx.h" +#include "svm_util.h" =20 #include #include @@ -22,6 +23,8 @@ enum { PORT_L0_EXIT =3D 0x2000, }; =20 +#define L2_GUEST_STACK_SIZE 64 + static void l2_guest_code(void) { /* Exit to L0 */ @@ -29,9 +32,8 @@ static void l2_guest_code(void) : : [port] "d" (PORT_L0_EXIT) : "rax"); } =20 -static void l1_guest_code(struct vmx_pages *vmx_pages) +static void l1_vmx_code(struct vmx_pages *vmx_pages) { -#define L2_GUEST_STACK_SIZE 64 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; =20 GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages)); @@ -45,19 +47,43 @@ static void l1_guest_code(struct vmx_pages *vmx_pages) GUEST_ASSERT(0); } =20 +static void l1_svm_code(struct svm_test_data *svm) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + + /* Prepare the VMCB for L2 execution. */ + generic_svm_setup(svm, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + run_guest(svm->vmcb, svm->vmcb_gpa); + GUEST_ASSERT(0); +} + +static void l1_guest_code(void *data) +{ + if (this_cpu_has(X86_FEATURE_VMX)) + l1_vmx_code(data); + else + l1_svm_code(data); +} + int main(int argc, char *argv[]) { - vm_vaddr_t vmx_pages_gva; + vm_vaddr_t guest_gva; struct kvm_vcpu *vcpu; struct kvm_vm *vm; =20 - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) || + kvm_cpu_has(X86_FEATURE_SVM)); =20 vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_code); =20 - /* Allocate VMX pages and shared descriptors (vmx_pages). */ - vcpu_alloc_vmx(vm, &vmx_pages_gva); - vcpu_args_set(vcpu, 1, vmx_pages_gva); + if (kvm_cpu_has(X86_FEATURE_VMX)) + vcpu_alloc_vmx(vm, &guest_gva); + else + vcpu_alloc_svm(vm, &guest_gva); + + vcpu_args_set(vcpu, 1, guest_gva); =20 for (;;) { volatile struct kvm_run *run =3D vcpu->run; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) (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 BC6352877CF for ; Tue, 21 Oct 2025 07:48:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032915; cv=none; b=L+2kv7EdXOB1f4hpPrB3nc1ewT9N75sYqzvTZHoE11/D2oWgkPbBlwmmH6gMcxHxTe+HMVCJicZsagoEAsnz13NB3JvykWbZGcqr6OTqPQ1tVF87Aa27S00q0zfWnWW/6waDMDG5y0V4eey34FNh3ma+IsGTP4U9WuxUB5mFvKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032915; c=relaxed/simple; bh=Pz6XQMVn6Elmb7c8QL1ecDc8Oi0fpx2DIkOyBjqysYo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YpRCsrPTjcULoB5PwJUISRd/a8uC1Z6eScxvouQSxoVIZt9cHwJ+oj81QNHFeRzAxFnJLOo89Am7AL6Ft73B3WtsV9ZyrNPpfYen0lKaZt2vnRZHQL8gIYsmW0oLM1HBt5pDkzTxRsIeAUmc6GFWadyxUGDnX7YdmaKDV3J1M0Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=uoJHc+An; arc=none smtp.client-ip=95.215.58.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="uoJHc+An" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032908; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XY6Ex3U4Gi9sCANmVeHAwSsb6Q0TQQaEwGxDyLB/qkU=; b=uoJHc+AnTLiVvx/GTn1HZsBbIrwGk0uNr7QWwlvsJ/O1V6XAtp6pK0bmo2etmdMOn8SCoH RqsdwKq/nWvfObdQcY00lqCbYXl2Woh/Ng2zKRmnRujCsZebWJFiB2f0q8Y5+ZPya3wncZ hVy2lT37lnYkW0LEX+vjpPmKqhxViMw= 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 04/23] KVM: selftests: Extend vmx_nested_tsc_scaling_test to cover SVM Date: Tue, 21 Oct 2025 07:47:17 +0000 Message-ID: <20251021074736.1324328-5-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add SVM L1 code to run the nested guest, and allow the test to run with SVM as well as VMX. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/Makefile.kvm | 2 +- ...aling_test.c =3D> nested_tsc_scaling_test.c} | 48 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) rename tools/testing/selftests/kvm/x86/{vmx_nested_tsc_scaling_test.c =3D>= nested_tsc_scaling_test.c} (83%) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index e70a844a52bdc..bb2ff7927ef57 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -119,7 +119,7 @@ TEST_GEN_PROGS_x86 +=3D x86/vmx_msrs_test TEST_GEN_PROGS_x86 +=3D x86/vmx_invalid_nested_guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_la57_nested_state_test TEST_GEN_PROGS_x86 +=3D x86/vmx_tsc_adjust_test -TEST_GEN_PROGS_x86 +=3D x86/vmx_nested_tsc_scaling_test +TEST_GEN_PROGS_x86 +=3D x86/nested_tsc_scaling_test TEST_GEN_PROGS_x86 +=3D x86/apic_bus_clock_test TEST_GEN_PROGS_x86 +=3D x86/xapic_ipi_test TEST_GEN_PROGS_x86 +=3D x86/xapic_state_test diff --git a/tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c = b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c similarity index 83% rename from tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c rename to tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c index 1759fa5cb3f29..4260c9e4f4891 100644 --- a/tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c +++ b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c @@ -13,6 +13,7 @@ =20 #include "kvm_util.h" #include "vmx.h" +#include "svm_util.h" #include "kselftest.h" =20 /* L2 is scaled up (from L1's perspective) by this factor */ @@ -79,7 +80,30 @@ static void l2_guest_code(void) __asm__ __volatile__("vmcall"); } =20 -static void l1_guest_code(struct vmx_pages *vmx_pages) +static void l1_svm_code(struct svm_test_data *svm) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + + /* check that L1's frequency looks alright before launching L2 */ + check_tsc_freq(UCHECK_L1); + + generic_svm_setup(svm, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + /* enable TSC scaling for L2 */ + wrmsr(MSR_AMD64_TSC_RATIO, L2_SCALE_FACTOR << 32); + + /* launch L2 */ + run_guest(svm->vmcb, svm->vmcb_gpa); + GUEST_ASSERT(svm->vmcb->control.exit_code =3D=3D SVM_EXIT_VMMCALL); + + /* check that L1's frequency still looks good */ + check_tsc_freq(UCHECK_L1); + + GUEST_DONE(); +} + +static void l1_vmx_code(struct vmx_pages *vmx_pages) { unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; uint32_t control; @@ -116,11 +140,19 @@ static void l1_guest_code(struct vmx_pages *vmx_pages) GUEST_DONE(); } =20 +static void l1_guest_code(void *data) +{ + if (this_cpu_has(X86_FEATURE_VMX)) + l1_vmx_code(data); + else + l1_svm_code(data); +} + int main(int argc, char *argv[]) { struct kvm_vcpu *vcpu; struct kvm_vm *vm; - vm_vaddr_t vmx_pages_gva; + vm_vaddr_t guest_gva =3D 0; =20 uint64_t tsc_start, tsc_end; uint64_t tsc_khz; @@ -129,7 +161,8 @@ int main(int argc, char *argv[]) uint64_t l1_tsc_freq =3D 0; uint64_t l2_tsc_freq =3D 0; =20 - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) || + kvm_cpu_has(X86_FEATURE_SVM)); TEST_REQUIRE(kvm_has_cap(KVM_CAP_TSC_CONTROL)); TEST_REQUIRE(sys_clocksource_is_based_on_tsc()); =20 @@ -152,8 +185,13 @@ int main(int argc, char *argv[]) printf("real TSC frequency is around: %"PRIu64"\n", l0_tsc_freq); =20 vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_code); - vcpu_alloc_vmx(vm, &vmx_pages_gva); - vcpu_args_set(vcpu, 1, vmx_pages_gva); + + if (kvm_cpu_has(X86_FEATURE_VMX)) + vcpu_alloc_vmx(vm, &guest_gva); + else + vcpu_alloc_svm(vm, &guest_gva); + + vcpu_args_set(vcpu, 1, guest_gva); =20 tsc_khz =3D __vcpu_ioctl(vcpu, KVM_GET_TSC_KHZ, NULL); TEST_ASSERT(tsc_khz !=3D -1, "vcpu ioctl KVM_GET_TSC_KHZ failed"); --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-177.mta1.migadu.com (out-177.mta1.migadu.com [95.215.58.177]) (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 E1A91295516 for ; Tue, 21 Oct 2025 07:48:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032916; cv=none; b=I0mgEt24El8BY/3+XpNOs0DTln7M/tOSOIYo2hkyOEJ7T2tEhTNgGJCUafcDvpNKB1afh/81QAdccvVvcWX831gFSPNc0Bgn9hb7hlqVNXqT1mDxxMqM0CmEuCAvmp0/UBQOU29yCr5l1m38jb309Vy/Ho7e790rslzPt1B0Mvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032916; c=relaxed/simple; bh=cvs3HMhN6GheOAwab4ch6RvRzc8y2IIlbw2Kq3Nf/HA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tes/MWgDRQAMnILv7nA3ZdMpvI/yaT7m/E+Zx5DTTJMtzu7R6Nm7RkZkYF6JArk/9RD4ZmF2utDMMxkUg07Zyz/odgAonxJ6Bphd5s8FIM/R+/mU/HqUYjz/gGmW4Md1wVG5LfhuhhomBKbfElbvcuJWoQDXk3DYFnnc/SrXyTg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Gct4AoJk; arc=none smtp.client-ip=95.215.58.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Gct4AoJk" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032910; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Dg5RcfHhODublfTAqLGUz0lPtfc+ssoS6SJ2IDNtuJI=; b=Gct4AoJkHL3qL1ip3g6MiK0od4V3dEE/TL9Eoh8esqWISSp4Vq4T5xHZxK7pB97cJljJK4 MJV2Q0hUoAPCKVtW26E5aFLBUqX9B9xAnTPrpzcuKMmhsUsICqewxGbGOMP2zCVVPmCXR6 cUdO71JKNcDNvg8/uUI2IfMHfXb5uG8= 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 05/23] KVM: selftests: Move nested invalid CR3 check to its own test Date: Tue, 21 Oct 2025 07:47:18 +0000 Message-ID: <20251021074736.1324328-6-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" vmx_tsc_adjust_test currently verifies that a nested VMLAUNCH fails with an invalid CR3. This is irrelevant to TSC scaling, move it to a standalone test. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../kvm/x86/nested_invalid_cr3_test.c | 81 +++++++++++++++++++ .../selftests/kvm/x86/vmx_tsc_adjust_test.c | 10 --- 3 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 tools/testing/selftests/kvm/x86/nested_invalid_cr3_test= .c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index bb2ff7927ef57..b78700c574fc7 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -88,6 +88,7 @@ TEST_GEN_PROGS_x86 +=3D x86/kvm_pv_test TEST_GEN_PROGS_x86 +=3D x86/kvm_buslock_test TEST_GEN_PROGS_x86 +=3D x86/monitor_mwait_test TEST_GEN_PROGS_x86 +=3D x86/msrs_test +TEST_GEN_PROGS_x86 +=3D x86/nested_invalid_cr3_test TEST_GEN_PROGS_x86 +=3D x86/nested_emulation_test TEST_GEN_PROGS_x86 +=3D x86/nested_exceptions_test TEST_GEN_PROGS_x86 +=3D x86/platform_info_test diff --git a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c b/to= ols/testing/selftests/kvm/x86/nested_invalid_cr3_test.c new file mode 100644 index 0000000000000..b9853ab532cfe --- /dev/null +++ b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * nested_invalid_cr3_test + * + * Copyright (C) 2025, Google LLC. + * + * This test verifies that L1 fails to enter L2 with an invalid CR3, and + * succeeds otherwise. + */ +#include "kvm_util.h" +#include "vmx.h" +#include "kselftest.h" + + +#define L2_GUEST_STACK_SIZE 64 + +static void l2_guest_code(void) +{ + vmcall(); +} + +static void l1_vmx_code(struct vmx_pages *vmx_pages) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + uintptr_t save_cr3; + + GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages)); + GUEST_ASSERT(load_vmcs(vmx_pages)); + + prepare_vmcs(vmx_pages, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + /* Try to run L2 with invalid CR3 and make sure it fails */ + save_cr3 =3D vmreadz(GUEST_CR3); + vmwrite(GUEST_CR3, -1ull); + GUEST_ASSERT(!vmlaunch()); + GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D + (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE)); + + /* Now restore CR3 and make sure L2 runs successfully */ + vmwrite(GUEST_CR3, save_cr3); + GUEST_ASSERT(!vmlaunch()); + GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); + + GUEST_DONE(); +} + +int main(int argc, char *argv[]) +{ + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + vm_vaddr_t guest_gva =3D 0; + + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + + vm =3D vm_create_with_one_vcpu(&vcpu, l1_vmx_code); + vcpu_alloc_vmx(vm, &guest_gva); + vcpu_args_set(vcpu, 1, guest_gva); + + for (;;) { + struct ucall uc; + + vcpu_run(vcpu); + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + case UCALL_SYNC: + break; + case UCALL_DONE: + goto done; + default: + TEST_FAIL("Unknown ucall %lu", uc.cmd); + } + } + +done: + kvm_vm_free(vm); + return 0; +} diff --git a/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c b/tools/= testing/selftests/kvm/x86/vmx_tsc_adjust_test.c index 2ceb5c78c4427..2dcc0306a0d9b 100644 --- a/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c +++ b/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c @@ -77,7 +77,6 @@ static void l1_guest_code(struct vmx_pages *vmx_pages) #define L2_GUEST_STACK_SIZE 64 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; uint32_t control; - uintptr_t save_cr3; =20 GUEST_ASSERT(rdtsc() < TSC_ADJUST_VALUE); wrmsr(MSR_IA32_TSC, rdtsc() - TSC_ADJUST_VALUE); @@ -94,15 +93,6 @@ static void l1_guest_code(struct vmx_pages *vmx_pages) vmwrite(CPU_BASED_VM_EXEC_CONTROL, control); vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE); =20 - /* Jump into L2. First, test failure to load guest CR3. */ - save_cr3 =3D vmreadz(GUEST_CR3); - vmwrite(GUEST_CR3, -1ull); - GUEST_ASSERT(!vmlaunch()); - GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D - (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE)); - check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE); - vmwrite(GUEST_CR3, save_cr3); - GUEST_ASSERT(!vmlaunch()); GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); =20 --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-187.mta1.migadu.com (out-187.mta1.migadu.com [95.215.58.187]) (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 106E027A107 for ; Tue, 21 Oct 2025 07:48:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032920; cv=none; b=Wb0HC0NOvLIVdrnLy04SdVjFs8/zZvaary4QIoWGmINdbJ+f7BpjM79Ly9CoTm7k0cT7s48Fv75BSwp6kB6DdPPy+7WF1v3n7AqzfbGXTT8ZUn324XR2tHpDteK+GBvu6NZ5UrHVux4bTO+qBZ4DhRUQ4ojZpN6rhWrtmSzUe3A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032920; c=relaxed/simple; bh=AuvEhvIJR3xZSW/fboQgnttC+/rNhF/c1gYAcgwTFic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oPrllAEdw3EdD67qOdIW9Lru7r/O/a6+HRMZMNvjKidyIORl4eBScRUEJvkGg0/9MO4wSWeSjy/ovoazEaSaveDY/3nx0V2fK3MUcsvD6sQl6LwTFpewgOgpCgy79rp5NNr8hjJ/tpiOhViF/dbnXRw0zVYg/+PrYmU1AjYdIes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=KRP1DvZy; arc=none smtp.client-ip=95.215.58.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="KRP1DvZy" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032913; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TVpVX05niv4fkQ2AMp5Au3Rmh+KHdWv7OtN3c3soNew=; b=KRP1DvZyXBtXBEO1mUafQoINxkKSqK1QOimkIrGPK3goW4V6oZwVdy03sjnBnXzyai5lRd 0Iy3A2j9qeTC0h2QUMN5KfKP8RFWaRGjqRVSI0wJnpuxI6pQvjFiKAztCr4E5X1X1FDmQ3 wyg/fLeacWtYezcEOfsunUTHrbo4Ox4= 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 06/23] KVM: selftests: Extend nested_invalid_cr3_test to cover SVM Date: Tue, 21 Oct 2025 07:47:19 +0000 Message-ID: <20251021074736.1324328-7-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add SVM L1 code to run the nested guest, and allow the test to run with SVM as well as VMX. Signed-off-by: Yosry Ahmed --- .../kvm/x86/nested_invalid_cr3_test.c | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c b/to= ols/testing/selftests/kvm/x86/nested_invalid_cr3_test.c index b9853ab532cfe..2a472440cb962 100644 --- a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c +++ b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c @@ -9,6 +9,7 @@ */ #include "kvm_util.h" #include "vmx.h" +#include "svm_util.h" #include "kselftest.h" =20 =20 @@ -19,6 +20,28 @@ static void l2_guest_code(void) vmcall(); } =20 +static void l1_svm_code(struct svm_test_data *svm) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + uintptr_t save_cr3; + + generic_svm_setup(svm, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + /* Try to run L2 with invalid CR3 and make sure it fails */ + save_cr3 =3D svm->vmcb->save.cr3; + svm->vmcb->save.cr3 =3D -1ull; + run_guest(svm->vmcb, svm->vmcb_gpa); + GUEST_ASSERT(svm->vmcb->control.exit_code =3D=3D SVM_EXIT_ERR); + + /* Now restore CR3 and make sure L2 runs successfully */ + svm->vmcb->save.cr3 =3D save_cr3; + run_guest(svm->vmcb, svm->vmcb_gpa); + GUEST_ASSERT(svm->vmcb->control.exit_code =3D=3D SVM_EXIT_VMMCALL); + + GUEST_DONE(); +} + static void l1_vmx_code(struct vmx_pages *vmx_pages) { unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; @@ -45,16 +68,30 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages) GUEST_DONE(); } =20 +static void l1_guest_code(void *data) +{ + if (this_cpu_has(X86_FEATURE_VMX)) + l1_vmx_code(data); + else + l1_svm_code(data); +} + int main(int argc, char *argv[]) { struct kvm_vcpu *vcpu; struct kvm_vm *vm; vm_vaddr_t guest_gva =3D 0; =20 - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) || + kvm_cpu_has(X86_FEATURE_SVM)); + + vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_code); + + if (kvm_cpu_has(X86_FEATURE_VMX)) + vcpu_alloc_vmx(vm, &guest_gva); + else + vcpu_alloc_svm(vm, &guest_gva); =20 - vm =3D vm_create_with_one_vcpu(&vcpu, l1_vmx_code); - vcpu_alloc_vmx(vm, &guest_gva); vcpu_args_set(vcpu, 1, guest_gva); =20 for (;;) { --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-187.mta1.migadu.com (out-187.mta1.migadu.com [95.215.58.187]) (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 C724F296BB2 for ; Tue, 21 Oct 2025 07:48:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032922; cv=none; b=li5flxG4XyEaLBLTtn3zq1mTJ4i09Egnh+dM1uASFEMaf3jQGlGFUAyn3S9WbCS7m/TJ3CchhARDthE1dcwOtT33r02wMrr1W6kvcNhUX6TfYOfqd6SATENy0FPjVY0ta4j+5Zouy9TEPhxtV0RUXq3Lvw4WXdqCaJaN2VqKGzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032922; c=relaxed/simple; bh=rCagEhe5Z1joYR3E+FP00tUc6rHYfQXWv8K7pMjbJ+I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=f+a0RgSzfsZmhcVbcyrr98v0kbC43t1ux9ia5Ia2B7HktUxMiwhAIp7SCZagiXDydEDDgS0zF7aZUdnhtjy6t+8TzO/NqDw8YliS+2ceznBNC8UbEd7VPgAzZ8Ec5nUZ6mMJP2WnsG+CO30+sopsDqVk6H8O0YAnU7m9DGKnEB4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=X6tYdIR1; arc=none smtp.client-ip=95.215.58.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="X6tYdIR1" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032915; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JcQR03IuKB4fcV0BsXwSI30gbdeQ80y8fSCq4J5LmSk=; b=X6tYdIR1JNgenqWgF7NGDAebOCFz5tOQfuuIwwb4t1vA7hiA/sPsjB5MPpdDxKuDOv50Mt R8qTe5WsA/0bdMR3NM37cz/KqK9SupLLxJbDSAKsh4vg++4omekYCCM1Igm40mVqNnHLuK m/JerC3UsRchDdkQzc/xNooIFyY0rbE= 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 07/23] KVM: selftests: Extend vmx_tsc_adjust_test to cover SVM Date: Tue, 21 Oct 2025 07:47:20 +0000 Message-ID: <20251021074736.1324328-8-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add SVM L1 code to run the nested guest, and allow the test to run with SVM as well as VMX. Reviewed-by: Jim Mattson Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/Makefile.kvm | 2 +- ...adjust_test.c =3D> nested_tsc_adjust_test.c} | 69 ++++++++++++------- 2 files changed, 46 insertions(+), 25 deletions(-) rename tools/testing/selftests/kvm/x86/{vmx_tsc_adjust_test.c =3D> nested_= tsc_adjust_test.c} (61%) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index b78700c574fc7..6625ac53545e8 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -119,7 +119,7 @@ TEST_GEN_PROGS_x86 +=3D x86/vmx_exception_with_invalid_= guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_msrs_test TEST_GEN_PROGS_x86 +=3D x86/vmx_invalid_nested_guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_la57_nested_state_test -TEST_GEN_PROGS_x86 +=3D x86/vmx_tsc_adjust_test +TEST_GEN_PROGS_x86 +=3D x86/nested_tsc_adjust_test TEST_GEN_PROGS_x86 +=3D x86/nested_tsc_scaling_test TEST_GEN_PROGS_x86 +=3D x86/apic_bus_clock_test TEST_GEN_PROGS_x86 +=3D x86/xapic_ipi_test diff --git a/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c b/tools/= testing/selftests/kvm/x86/nested_tsc_adjust_test.c similarity index 61% rename from tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c rename to tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c index 2dcc0306a0d9b..cc825a0b41dbf 100644 --- a/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c +++ b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * vmx_tsc_adjust_test + * nested_tsc_adjust_test * * Copyright (C) 2018, Google LLC. * @@ -22,6 +22,7 @@ #include "kvm_util.h" #include "processor.h" #include "vmx.h" +#include "svm_util.h" =20 #include #include @@ -35,6 +36,8 @@ #define TSC_ADJUST_VALUE (1ll << 32) #define TSC_OFFSET_VALUE -(1ll << 48) =20 +#define L2_GUEST_STACK_SIZE 64 + enum { PORT_ABORT =3D 0x1000, PORT_REPORT, @@ -72,32 +75,47 @@ static void l2_guest_code(void) __asm__ __volatile__("vmcall"); } =20 -static void l1_guest_code(struct vmx_pages *vmx_pages) +static void l1_guest_code(void *data) { -#define L2_GUEST_STACK_SIZE 64 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; - uint32_t control; =20 + /* Set TSC from L1 and make sure TSC_ADJUST is updated correctly */ GUEST_ASSERT(rdtsc() < TSC_ADJUST_VALUE); wrmsr(MSR_IA32_TSC, rdtsc() - TSC_ADJUST_VALUE); check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE); =20 - GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages)); - GUEST_ASSERT(load_vmcs(vmx_pages)); - - /* Prepare the VMCS for L2 execution. */ - prepare_vmcs(vmx_pages, l2_guest_code, - &l2_guest_stack[L2_GUEST_STACK_SIZE]); - control =3D vmreadz(CPU_BASED_VM_EXEC_CONTROL); - control |=3D CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETTING; - vmwrite(CPU_BASED_VM_EXEC_CONTROL, control); - vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE); - - GUEST_ASSERT(!vmlaunch()); - GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); + /* + * Run L2 with TSC_OFFSET. L2 will write to TSC, and L1 is not + * intercepting the write so it should update L1's TSC_ADJUST. + */ + if (this_cpu_has(X86_FEATURE_VMX)) { + struct vmx_pages *vmx_pages =3D data; + uint32_t control; + + GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages)); + GUEST_ASSERT(load_vmcs(vmx_pages)); + + prepare_vmcs(vmx_pages, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + control =3D vmreadz(CPU_BASED_VM_EXEC_CONTROL); + control |=3D CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETTING; + vmwrite(CPU_BASED_VM_EXEC_CONTROL, control); + vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE); + + GUEST_ASSERT(!vmlaunch()); + GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); + } else { + struct svm_test_data *svm =3D data; + + generic_svm_setup(svm, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + svm->vmcb->control.tsc_offset =3D TSC_OFFSET_VALUE; + run_guest(svm->vmcb, svm->vmcb_gpa); + GUEST_ASSERT(svm->vmcb->control.exit_code =3D=3D SVM_EXIT_VMMCALL); + } =20 check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE); - GUEST_DONE(); } =20 @@ -109,16 +127,19 @@ static void report(int64_t val) =20 int main(int argc, char *argv[]) { - vm_vaddr_t vmx_pages_gva; + vm_vaddr_t nested_gva; struct kvm_vcpu *vcpu; =20 - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) || + kvm_cpu_has(X86_FEATURE_SVM)); =20 - vm =3D vm_create_with_one_vcpu(&vcpu, (void *) l1_guest_code); + vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_code); + if (kvm_cpu_has(X86_FEATURE_VMX)) + vcpu_alloc_vmx(vm, &nested_gva); + else + vcpu_alloc_svm(vm, &nested_gva); =20 - /* Allocate VMX pages and shared descriptors (vmx_pages). */ - vcpu_alloc_vmx(vm, &vmx_pages_gva); - vcpu_args_set(vcpu, 1, vmx_pages_gva); + vcpu_args_set(vcpu, 1, nested_gva); =20 for (;;) { struct ucall uc; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) (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 3AA9429BDAC for ; Tue, 21 Oct 2025 07:48:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032925; cv=none; b=nZKt1Br3g9gKLzhmaw8cnLIyV6a3i+L4lZ8YaPYtPWrnTylxI9o0BSMIBCHa3hCBOBwzThvNdBAgXC0DHYadW9Os2E/jVasKnhTaOOpIv/bCmV8/PuZtYwWFusUquOIxYbWsdvV1/k17avtmOFwUCsOA54PRm/VIu5/xvbQosec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032925; c=relaxed/simple; bh=ZTFj/EYC4QDe1T7YoQR1FgC56Eg5CQLiqI5uI5zXT9g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LRP8xLEBRjgEur87rgNnNqQUnU1ZZfEWtY2vfId+86l0mT3IRpN1gUn1HPRZE+j8PtUJhUqrUNKqCSS0td9oBswuYexwwQdZnJKs8eg+MJIRNFNTcuujHPkbNndUoZeuING5I96MJwvGIeEiBquFS51i28OFjxl6H18TQH4ThwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=qC0hpUFn; arc=none smtp.client-ip=95.215.58.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="qC0hpUFn" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032916; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/nwEhPwIGoPA94YiE8Cr9z5oYeZSCp28VA4jU8QsCaY=; b=qC0hpUFnezC8f2GBOGvkh+JSVIOVqT5slDT+zVEmOZynua9oZcmJgI8nsQSvuk8+Xl8VGM +GZTvaQmtRTJphg35xkGgdSTqbvF51u8PcEBnykD7J3r37qpaDtWB6+apGt/nCd9yXruJp 0vql1dJpNTiPOS2mOzAxX9Yelyo3WHk= 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 08/23] KVM: selftests: Stop hardcoding PAGE_SIZE in x86 selftests Date: Tue, 21 Oct 2025 07:47:21 +0000 Message-ID: <20251021074736.1324328-9-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Use PAGE_SIZE instead of 4096. Signed-off-by: Yosry Ahmed --- .../selftests/kvm/x86/hyperv_features.c | 2 +- tools/testing/selftests/kvm/x86/hyperv_ipi.c | 18 +++++++++--------- .../testing/selftests/kvm/x86/sev_smoke_test.c | 2 +- tools/testing/selftests/kvm/x86/state_test.c | 2 +- .../selftests/kvm/x86/userspace_io_test.c | 2 +- .../selftests/kvm/x86/vmx_dirty_log_test.c | 10 +++++----- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/hyperv_features.c b/tools/test= ing/selftests/kvm/x86/hyperv_features.c index 99d327084172f..130b9ce7e5ddd 100644 --- a/tools/testing/selftests/kvm/x86/hyperv_features.c +++ b/tools/testing/selftests/kvm/x86/hyperv_features.c @@ -94,7 +94,7 @@ static void guest_hcall(vm_vaddr_t pgs_gpa, struct hcall_= data *hcall) =20 if (!(hcall->control & HV_HYPERCALL_FAST_BIT)) { input =3D pgs_gpa; - output =3D pgs_gpa + 4096; + output =3D pgs_gpa + PAGE_SIZE; } else { input =3D output =3D 0; } diff --git a/tools/testing/selftests/kvm/x86/hyperv_ipi.c b/tools/testing/s= elftests/kvm/x86/hyperv_ipi.c index 2b5b4bc6ef7ec..ca61836c4e325 100644 --- a/tools/testing/selftests/kvm/x86/hyperv_ipi.c +++ b/tools/testing/selftests/kvm/x86/hyperv_ipi.c @@ -102,7 +102,7 @@ static void sender_guest_code(void *hcall_page, vm_vadd= r_t pgs_gpa) /* 'Slow' HvCallSendSyntheticClusterIpi to RECEIVER_VCPU_ID_1 */ ipi->vector =3D IPI_VECTOR; ipi->cpu_mask =3D 1 << RECEIVER_VCPU_ID_1; - hyperv_hypercall(HVCALL_SEND_IPI, pgs_gpa, pgs_gpa + 4096); + hyperv_hypercall(HVCALL_SEND_IPI, pgs_gpa, pgs_gpa + PAGE_SIZE); nop_loop(); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_1] =3D=3D ++ipis_expected[0]); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_2] =3D=3D ipis_expected[1]); @@ -116,13 +116,13 @@ static void sender_guest_code(void *hcall_page, vm_va= ddr_t pgs_gpa) GUEST_SYNC(stage++); =20 /* 'Slow' HvCallSendSyntheticClusterIpiEx to RECEIVER_VCPU_ID_1 */ - memset(hcall_page, 0, 4096); + memset(hcall_page, 0, PAGE_SIZE); ipi_ex->vector =3D IPI_VECTOR; ipi_ex->vp_set.format =3D HV_GENERIC_SET_SPARSE_4K; ipi_ex->vp_set.valid_bank_mask =3D 1 << 0; ipi_ex->vp_set.bank_contents[0] =3D BIT(RECEIVER_VCPU_ID_1); hyperv_hypercall(HVCALL_SEND_IPI_EX | (1 << HV_HYPERCALL_VARHEAD_OFFSET), - pgs_gpa, pgs_gpa + 4096); + pgs_gpa, pgs_gpa + PAGE_SIZE); nop_loop(); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_1] =3D=3D ++ipis_expected[0]); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_2] =3D=3D ipis_expected[1]); @@ -138,13 +138,13 @@ static void sender_guest_code(void *hcall_page, vm_va= ddr_t pgs_gpa) GUEST_SYNC(stage++); =20 /* 'Slow' HvCallSendSyntheticClusterIpiEx to RECEIVER_VCPU_ID_2 */ - memset(hcall_page, 0, 4096); + memset(hcall_page, 0, PAGE_SIZE); ipi_ex->vector =3D IPI_VECTOR; ipi_ex->vp_set.format =3D HV_GENERIC_SET_SPARSE_4K; ipi_ex->vp_set.valid_bank_mask =3D 1 << 1; ipi_ex->vp_set.bank_contents[0] =3D BIT(RECEIVER_VCPU_ID_2 - 64); hyperv_hypercall(HVCALL_SEND_IPI_EX | (1 << HV_HYPERCALL_VARHEAD_OFFSET), - pgs_gpa, pgs_gpa + 4096); + pgs_gpa, pgs_gpa + PAGE_SIZE); nop_loop(); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_1] =3D=3D ipis_expected[0]); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_2] =3D=3D ++ipis_expected[1]); @@ -160,14 +160,14 @@ static void sender_guest_code(void *hcall_page, vm_va= ddr_t pgs_gpa) GUEST_SYNC(stage++); =20 /* 'Slow' HvCallSendSyntheticClusterIpiEx to both RECEIVER_VCPU_ID_{1,2} = */ - memset(hcall_page, 0, 4096); + memset(hcall_page, 0, PAGE_SIZE); ipi_ex->vector =3D IPI_VECTOR; ipi_ex->vp_set.format =3D HV_GENERIC_SET_SPARSE_4K; ipi_ex->vp_set.valid_bank_mask =3D 1 << 1 | 1; ipi_ex->vp_set.bank_contents[0] =3D BIT(RECEIVER_VCPU_ID_1); ipi_ex->vp_set.bank_contents[1] =3D BIT(RECEIVER_VCPU_ID_2 - 64); hyperv_hypercall(HVCALL_SEND_IPI_EX | (2 << HV_HYPERCALL_VARHEAD_OFFSET), - pgs_gpa, pgs_gpa + 4096); + pgs_gpa, pgs_gpa + PAGE_SIZE); nop_loop(); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_1] =3D=3D ++ipis_expected[0]); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_2] =3D=3D ++ipis_expected[1]); @@ -183,10 +183,10 @@ static void sender_guest_code(void *hcall_page, vm_va= ddr_t pgs_gpa) GUEST_SYNC(stage++); =20 /* 'Slow' HvCallSendSyntheticClusterIpiEx to HV_GENERIC_SET_ALL */ - memset(hcall_page, 0, 4096); + memset(hcall_page, 0, PAGE_SIZE); ipi_ex->vector =3D IPI_VECTOR; ipi_ex->vp_set.format =3D HV_GENERIC_SET_ALL; - hyperv_hypercall(HVCALL_SEND_IPI_EX, pgs_gpa, pgs_gpa + 4096); + hyperv_hypercall(HVCALL_SEND_IPI_EX, pgs_gpa, pgs_gpa + PAGE_SIZE); nop_loop(); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_1] =3D=3D ++ipis_expected[0]); GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_2] =3D=3D ++ipis_expected[1]); diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testi= ng/selftests/kvm/x86/sev_smoke_test.c index 77256c89bb8de..86ad1c7d068f2 100644 --- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c +++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c @@ -104,7 +104,7 @@ static void test_sync_vmsa(uint32_t type, uint64_t poli= cy) vm_sev_launch(vm, policy, NULL); =20 /* This page is shared, so make it decrypted. */ - memset(hva, 0, 4096); + memset(hva, 0, PAGE_SIZE); =20 vcpu_run(vcpu); =20 diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/s= elftests/kvm/x86/state_test.c index 141b7fc0c965b..f2c7a1c297e37 100644 --- a/tools/testing/selftests/kvm/x86/state_test.c +++ b/tools/testing/selftests/kvm/x86/state_test.c @@ -141,7 +141,7 @@ static void __attribute__((__flatten__)) guest_code(voi= d *arg) =20 if (this_cpu_has(X86_FEATURE_XSAVE)) { uint64_t supported_xcr0 =3D this_cpu_supported_xcr0(); - uint8_t buffer[4096]; + uint8_t buffer[PAGE_SIZE]; =20 memset(buffer, 0xcc, sizeof(buffer)); =20 diff --git a/tools/testing/selftests/kvm/x86/userspace_io_test.c b/tools/te= sting/selftests/kvm/x86/userspace_io_test.c index 9481cbcf284f6..be7d72f3c029f 100644 --- a/tools/testing/selftests/kvm/x86/userspace_io_test.c +++ b/tools/testing/selftests/kvm/x86/userspace_io_test.c @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) regs.rcx =3D 1; if (regs.rcx =3D=3D 3) regs.rcx =3D 8192; - memset((void *)run + run->io.data_offset, 0xaa, 4096); + memset((void *)run + run->io.data_offset, 0xaa, PAGE_SIZE); vcpu_regs_set(vcpu, ®s); } =20 diff --git a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c b/tools/t= esting/selftests/kvm/x86/vmx_dirty_log_test.c index fa512d033205f..34a57fe747f64 100644 --- a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c @@ -122,15 +122,15 @@ static void test_vmx_dirty_log(bool enable_ept) if (enable_ept) { prepare_eptp(vmx, vm, 0); nested_map_memslot(vmx, vm, 0); - nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, 4096); - nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, 4096); + nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZE); + nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZE); } =20 bmap =3D bitmap_zalloc(TEST_MEM_PAGES); host_test_mem =3D addr_gpa2hva(vm, GUEST_TEST_MEM); =20 while (!done) { - memset(host_test_mem, 0xaa, TEST_MEM_PAGES * 4096); + memset(host_test_mem, 0xaa, TEST_MEM_PAGES * PAGE_SIZE); vcpu_run(vcpu); TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); =20 @@ -153,9 +153,9 @@ static void test_vmx_dirty_log(bool enable_ept) } =20 TEST_ASSERT(!test_bit(1, bmap), "Page 1 incorrectly reported dirty"); - TEST_ASSERT(host_test_mem[4096 / 8] =3D=3D 0xaaaaaaaaaaaaaaaaULL, "Page= 1 written by guest"); + TEST_ASSERT(host_test_mem[PAGE_SIZE / 8] =3D=3D 0xaaaaaaaaaaaaaaaaULL, = "Page 1 written by guest"); TEST_ASSERT(!test_bit(2, bmap), "Page 2 incorrectly reported dirty"); - TEST_ASSERT(host_test_mem[8192 / 8] =3D=3D 0xaaaaaaaaaaaaaaaaULL, "Page= 2 written by guest"); + TEST_ASSERT(host_test_mem[PAGE_SIZE*2 / 8] =3D=3D 0xaaaaaaaaaaaaaaaaULL= , "Page 2 written by guest"); break; case UCALL_DONE: done =3D true; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-174.mta1.migadu.com (out-174.mta1.migadu.com [95.215.58.174]) (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 5826729B8E8 for ; Tue, 21 Oct 2025 07:48:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032925; cv=none; b=g/lXlHTZWyPUmn1f806AhTgiFk/LW8/PDBUQn2MgVmXZi9DrgqM1JkUeCcW9gAwX2l2zvRG9zhiW/U269UxcaQsUkDRvH9fOnYSc1LCdEW0iwp5Qdp8Nx3y9wzGPniU9WwfNAnd20sB1gqYQrwJXqc2YMtRmWBCDZaUyn95V4GE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032925; c=relaxed/simple; bh=RzN8S5829P4atioL4zZZl4z+Fpkeovc6CUP/mqAjMNw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UeS8QscI7lGGFJcg98o4EVJ160oQRmRWX/vqe8ROfPWqyxmhrs+eYfLx1ygfVs7ZcanjPTi4q4TmKpmpacePmr6i9K78DnPMOdyBaxS9LKNezrCw4hDIRgQCMAkpCY1DibG7tqA6s5tt1APnd0xwPdyv/CpFpQ2Tpl/Z3t4vQhk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=qvhxdN8K; arc=none smtp.client-ip=95.215.58.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="qvhxdN8K" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032918; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9i8MKAwzoYVSdvC0SDkeEAnIDmKdE3d63+KzCJlfJBQ=; b=qvhxdN8KVRuqfgSxttd4dVJpzWPgIDLIWy1tDrkR1qJHCkal7CCwwghJIfEeaFe2ZjI3xO Txb11k8dsqUafPu2bC8WmSnxaoFiwMb7NwOHbgB+bTbouj9ZCHjeUOjDe3iN1AOMCPuVWo sl7LYzx7b2dGVqO3IEosOe/OoBdrrSc= 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 09/23] KVM: selftests: Remove the unused argument to prepare_eptp() Date: Tue, 21 Oct 2025 07:47:22 +0000 Message-ID: <20251021074736.1324328-10-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" eptp_memslot is unused, remove it. No functional change intended. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/include/x86/vmx.h | 3 +-- tools/testing/selftests/kvm/lib/x86/memstress.c | 2 +- tools/testing/selftests/kvm/lib/x86/vmx.c | 3 +-- tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/= selftests/kvm/include/x86/vmx.h index edb3c391b9824..96e2b4c630a9b 100644 --- a/tools/testing/selftests/kvm/include/x86/vmx.h +++ b/tools/testing/selftests/kvm/include/x86/vmx.h @@ -568,8 +568,7 @@ void nested_map_memslot(struct vmx_pages *vmx, struct k= vm_vm *vm, void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm, uint64_t addr, uint64_t size); bool kvm_cpu_has_ept(void); -void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm, - uint32_t eptp_memslot); +void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm); void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm= *vm); =20 #endif /* SELFTEST_KVM_VMX_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testin= g/selftests/kvm/lib/x86/memstress.c index 7f5d62a65c68a..0b1f288ad5564 100644 --- a/tools/testing/selftests/kvm/lib/x86/memstress.c +++ b/tools/testing/selftests/kvm/lib/x86/memstress.c @@ -63,7 +63,7 @@ void memstress_setup_ept(struct vmx_pages *vmx, struct kv= m_vm *vm) { uint64_t start, end; =20 - prepare_eptp(vmx, vm, 0); + prepare_eptp(vmx, vm); =20 /* * Identity map the first 4G and the test region with 1G pages so that diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index 1b6d4a0077980..f0023a3b0137e 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -535,8 +535,7 @@ bool kvm_cpu_has_ept(void) return ctrl & SECONDARY_EXEC_ENABLE_EPT; } =20 -void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm, - uint32_t eptp_memslot) +void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm) { TEST_ASSERT(kvm_cpu_has_ept(), "KVM doesn't support nested EPT"); =20 diff --git a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c b/tools/t= esting/selftests/kvm/x86/vmx_dirty_log_test.c index 34a57fe747f64..98cb6bdab3e6d 100644 --- a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c @@ -120,7 +120,7 @@ static void test_vmx_dirty_log(bool enable_ept) * GPAs as the EPT enabled case. */ if (enable_ept) { - prepare_eptp(vmx, vm, 0); + prepare_eptp(vmx, vm); nested_map_memslot(vmx, vm, 0); nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZE); nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZE); --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-171.mta1.migadu.com (out-171.mta1.migadu.com [95.215.58.171]) (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 D15632BE643 for ; Tue, 21 Oct 2025 07:48:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032929; cv=none; b=frJ5VTfJOtHvMRgD4H97m0/aiQhtbM6A+dmptp8TOlL9GdcxXPz5QG3PdIxPIJboUVeeNcwHKXCL25GmjDgkiBFt3j5DXrJA4Pmi2v56QIheBVBboxV9TBFAu8Vvu0gCrCcpuMKAMLnJP6gTiavetsTkWZ9lOANk/+T+SwOAORQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032929; c=relaxed/simple; bh=b1bunJvRMwHVDZOsTzIFfalAs34FSJTHmxHtOoMRcyM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XNbAcCs0sbGZFShDClUeMduTMb9ac4dIUYeFBTvchZcRuTy1j4XQuHHwkXaDVzfSxDjHL8QNaGCTeHoHbBEYq24rg2iRpyEqIYTtVl/z17/VoK7lNcJREFUqj9SzoDSG7TcYjZ/Ul6FrKd+52eOamJ0xxm2lBh+cksuZKFJ9pHw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Z9hVZa9A; arc=none smtp.client-ip=95.215.58.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Z9hVZa9A" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032920; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=t+HGmEgjIusKwLuq4N4ktk6GF6BiFVs5iCdCBOce2dE=; b=Z9hVZa9ASBWP6zxAjwDcGhvEBiB5+aNiB2eqDPWPXp0dMMXWU2znE+k3JeD0Z7YJCvBI8k QCuywtfpBBRk2puijp01KLjhzcv2aQ7lbmmREGm2PnMt+s/3kbVmefPAK1FcQZY8ECxv3j NWsboke81jrfv57Fi9cVsvSDdaDXHMc= 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 10/23] KVM: selftests: Stop using __virt_pg_map() directly in tests Date: Tue, 21 Oct 2025 07:47:23 +0000 Message-ID: <20251021074736.1324328-11-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Replace __virt_pg_map() calls in tests by high-level equivalent functions, removing some loops in the process. No functional change intended. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/mmu_stress_test.c | 6 ++---- tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/= selftests/kvm/mmu_stress_test.c index 6a437d2be9fa4..21c0f8e6552cd 100644 --- a/tools/testing/selftests/kvm/mmu_stress_test.c +++ b/tools/testing/selftests/kvm/mmu_stress_test.c @@ -361,11 +361,9 @@ int main(int argc, char *argv[]) =20 #ifdef __x86_64__ /* Identity map memory in the guest using 1gb pages. */ - for (i =3D 0; i < slot_size; i +=3D SZ_1G) - __virt_pg_map(vm, gpa + i, gpa + i, PG_LEVEL_1G); + virt_map_level(vm, gpa, gpa, slot_size, PG_LEVEL_1G); #else - for (i =3D 0; i < slot_size; i +=3D vm->page_size) - virt_pg_map(vm, gpa + i, gpa + i); + virt_map(vm, gpa, gpa, slot_size >> vm->page_shift); #endif } =20 diff --git a/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c b/tools/tes= ting/selftests/kvm/x86/hyperv_tlb_flush.c index 077cd0ec3040e..a3b7ce1559812 100644 --- a/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c +++ b/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c @@ -621,7 +621,7 @@ int main(int argc, char *argv[]) for (i =3D 0; i < NTEST_PAGES; i++) { pte =3D vm_get_page_table_entry(vm, data->test_pages + i * PAGE_SIZE); gpa =3D addr_hva2gpa(vm, pte); - __virt_pg_map(vm, gva + PAGE_SIZE * i, gpa & PAGE_MASK, PG_LEVEL_4K); + virt_pg_map(vm, gva + PAGE_SIZE * i, gpa & PAGE_MASK); data->test_pages_pte[i] =3D gva + (gpa & ~PAGE_MASK); } =20 --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) (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 42AF529D265 for ; Tue, 21 Oct 2025 07:48:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032932; cv=none; b=LqCJ8W+hYLly+notAvrPGCtu7EFM47BqIPwM+KVKpc38Z6XU8GHmjkcvqT47jvYQi3EwH7zRhlCzEzpI7LnUC00bxxcb5ETfW16WXpVAFTgbI6N0hw1RnRRDaEg6AjJ9aGsGVWxD5i9b6d9oQDsOhsqM6+Wrnw34fiTn7gIJLnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032932; c=relaxed/simple; bh=FLiWL509+4paNkCe21c7zaoLHTKMIsFRWgJVt7RlyDQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k3UrJfsApnhSrbkdAJ87qcdBtZWCy0ZTCCHcJ9NGjqIc5zVsz4MA/c7kGJcKtu1fSHLP9u2hkn5MepIvcUSGLjFkjoOxiTYQoq+fozux70lBYmLem4kEAvzwykGlpnp8nv06WQjCI5/OzF6mySaK6Gawqr4iBytKu7nAJtlZAy8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=aHJJEj4Z; arc=none smtp.client-ip=95.215.58.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="aHJJEj4Z" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032921; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qbz6uq0EIDXItWBuGg+PhUHYj6uMZIfd2BYBGlaVWhA=; b=aHJJEj4Z9951a21mv9O0n4egRuBSYHDMcM0eAvZgbExbn3RNY6Rrqk6YU6TPL8rmPvUGMC nCkn7+5/dNX4DOzRLXU+b8ZQ91E3gVUNHMJEiN/yZW6bPNPeUP4wFQRMFcPklgCaTncqkh aeRGCLt74ewg6fqzMnkrau7w0vOIaBE= 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 11/23] KVM: selftests: Make sure vm->vpages_mapped is always up-to-date Date: Tue, 21 Oct 2025 07:47:24 +0000 Message-ID: <20251021074736.1324328-12-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Call paths leading to __virt_pg_map() are currently: (a) virt_pg_map() -> virt_arch_pg_map() -> __virt_pg_map() (b) virt_map_level() -> __virt_pg_map() For (a), calls to virt_pg_map() from kvm_util.c make sure they update vm->vpages_mapped, but other callers do not. Move the sparsebit_set() call into virt_pg_map() to make sure all callers are captured. For (b), call sparsebit_set_num() from virt_map_level(). It's tempting to have a single the call inside __virt_pg_map(), however: - The call path in (a) is not x86-specific, while (b) is. Moving the call into __virt_pg_map() would require doing something similar for other archs implementing virt_pg_map(). - Incoming changes will reusue __virt_pg_map() for nested PTEs, which should not update vm->vpages_mapped. This means we'd need to break out a triple underscore version that does not update vm->vpages_mapped. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/include/kvm_util.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 3 --- tools/testing/selftests/kvm/lib/x86/processor.c | 2 ++ 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index bcbcfb4deb9a2..15c69af11a684 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -1206,6 +1206,7 @@ void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vad= dr, uint64_t paddr); static inline void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t= paddr) { virt_arch_pg_map(vm, vaddr, paddr); + sparsebit_set(vm->vpages_mapped, vaddr >> vm->page_shift); } =20 =20 diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 5e6b51768f67f..473c533774898 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1490,8 +1490,6 @@ static vm_vaddr_t ____vm_vaddr_alloc(struct kvm_vm *v= m, size_t sz, pages--, vaddr +=3D vm->page_size, paddr +=3D vm->page_size) { =20 virt_pg_map(vm, vaddr, paddr); - - sparsebit_set(vm->vpages_mapped, vaddr >> vm->page_shift); } =20 return vaddr_start; @@ -1605,7 +1603,6 @@ void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint= 64_t paddr, =20 while (npages--) { virt_pg_map(vm, vaddr, paddr); - sparsebit_set(vm->vpages_mapped, vaddr >> vm->page_shift); =20 vaddr +=3D page_size; paddr +=3D page_size; diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index c484e83255c70..4ee9fc844ee66 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -285,6 +285,8 @@ void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, = uint64_t paddr, =20 for (i =3D 0; i < nr_pages; i++) { __virt_pg_map(vm, vaddr, paddr, level); + sparsebit_set_num(vm->vpages_mapped, vaddr >> vm->page_shift, + nr_bytes / PAGE_SIZE); =20 vaddr +=3D pg_size; paddr +=3D pg_size; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) (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 41DA92BDC0E for ; Tue, 21 Oct 2025 07:48:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032931; cv=none; b=lxPbGCPpWKJI06JVNx0O7CBsqeNQzkedx9sTtdZ6bjov12ujX8Nb4jYDTqJw7EchWb91eQwpY0VuQRGV+WgVcTQzkIdDbp7B4t1XOW2/pu3zlBjRqj17dIMz5WebtWIB2iCfr595MOHx7lNkYeE1Epjtho70H5YMk27K7AlLh7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032931; c=relaxed/simple; bh=SZqOuzEjDdoKPxqV5Y9lkTH9kF6fWYp3FNbawXF6fJg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i5onXAu1EsvK1L3YPckEUwQg5Cpdc8MlbQlKt4sJ6FVAT1Hwx/PeFga0l3WqFS2bvQY8z14kjZ0MZrJfgU0ozjdssSibuovzw1yEKftIMDtPgDi/IWM9ZFLf96dKaRdQzkXVrDLo9lqmbg3GFK7EgYiHolx5jMAikQtB61Ey8+U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=tscP50w1; arc=none smtp.client-ip=95.215.58.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="tscP50w1" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032923; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NpTEio1Cyx5w3MYAM4L9C9x1WQNW7BkqB04RH3S+dnM=; b=tscP50w1d2QP11dWA0Uz3r5XodiRMtmMij0dWDJbMAatK4zxGvFs4x4ZYqyx4mbqSFIDQm cByYSjc9U597cFXg+woY6nT4eyNbPMaiBY2nqkSjmKac1vkUwQKGu1RvvalSEbq8TUcI8h SbTDudzr3MkdjWk05P5cYLqXwaxtzuM= 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 12/23] KVM: selftests: Parameterize the PTE bitmasks for virt mapping functions Date: Tue, 21 Oct 2025 07:47:25 +0000 Message-ID: <20251021074736.1324328-13-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Move the PTE bitmasks into a struct and define one for x86 page tables. Move all internal functions in lib/x86/processor.c to take in and use the structs but do not expose it to external callers. Drop the 'global' bit definition as it's currently unused, but leave the 'user' bit as it will be used in coming changes. Following changes will add support to use the virt mapping functions for EPTs and NPTs, so they will define their own bitmask structs. Leave PHYSICAL_PAGE_MASK alone, it's fixed in all page table formats and a lot of other macros depend on it. It's tempting to move all the other macros to be per-struct instead, but it would be too much noise for little benefit. While at it, make __vm_get_page_table_entry() static as it's not used in any other files. No functional change intended. Signed-off-by: Yosry Ahmed --- .../selftests/kvm/include/x86/processor.h | 27 +++--- .../testing/selftests/kvm/lib/x86/processor.c | 92 +++++++++++-------- 2 files changed, 69 insertions(+), 50 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 51cd84b9ca664..8debe0df3ffca 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -362,16 +362,6 @@ static inline unsigned int x86_model(unsigned int eax) return ((eax >> 12) & 0xf0) | ((eax >> 4) & 0x0f); } =20 -/* Page table bitfield declarations */ -#define PTE_PRESENT_MASK BIT_ULL(0) -#define PTE_WRITABLE_MASK BIT_ULL(1) -#define PTE_USER_MASK BIT_ULL(2) -#define PTE_ACCESSED_MASK BIT_ULL(5) -#define PTE_DIRTY_MASK BIT_ULL(6) -#define PTE_LARGE_MASK BIT_ULL(7) -#define PTE_GLOBAL_MASK BIT_ULL(8) -#define PTE_NX_MASK BIT_ULL(63) - #define PHYSICAL_PAGE_MASK GENMASK_ULL(51, 12) =20 #define PAGE_SHIFT 12 @@ -1367,8 +1357,6 @@ static inline bool kvm_is_ignore_msrs(void) return get_kvm_param_bool("ignore_msrs"); } =20 -uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr, - int *level); uint64_t *vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr); =20 uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2, @@ -1451,7 +1439,20 @@ enum pg_level { #define PG_SIZE_2M PG_LEVEL_SIZE(PG_LEVEL_2M) #define PG_SIZE_1G PG_LEVEL_SIZE(PG_LEVEL_1G) =20 -void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int = level); +struct pte_masks { + uint64_t present; + uint64_t writeable; + uint64_t user; + uint64_t accessed; + uint64_t dirty; + uint64_t large; + uint64_t nx; +}; + +extern const struct pte_masks x86_pte_masks; + +void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, + int level, const struct pte_masks *masks); void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, uint64_t nr_bytes, int level); =20 diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 4ee9fc844ee66..8a838f208abe4 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -169,14 +169,25 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm) } } =20 +const struct pte_masks x86_pte_masks =3D { + .present =3D BIT_ULL(0), + .writeable =3D BIT_ULL(1), + .user =3D BIT_ULL(2), + .accessed =3D BIT_ULL(5), + .dirty =3D BIT_ULL(6), + .large =3D BIT_ULL(7), + .nx =3D BIT_ULL(63), +}; + static void *virt_get_pte(struct kvm_vm *vm, uint64_t *parent_pte, - uint64_t vaddr, int level) + uint64_t vaddr, int level, + const struct pte_masks *masks) { uint64_t pt_gpa =3D PTE_GET_PA(*parent_pte); uint64_t *page_table =3D addr_gpa2hva(vm, pt_gpa); int index =3D (vaddr >> PG_LEVEL_SHIFT(level)) & 0x1ffu; =20 - TEST_ASSERT((*parent_pte & PTE_PRESENT_MASK) || parent_pte =3D=3D &vm->pg= d, + TEST_ASSERT((*parent_pte & masks->present) || parent_pte =3D=3D &vm->pgd, "Parent PTE (level %d) not PRESENT for gva: 0x%08lx", level + 1, vaddr); =20 @@ -188,16 +199,17 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm = *vm, uint64_t vaddr, uint64_t paddr, int current_level, - int target_level) + int target_level, + const struct pte_masks *masks) { - uint64_t *pte =3D virt_get_pte(vm, parent_pte, vaddr, current_level); + uint64_t *pte =3D virt_get_pte(vm, parent_pte, vaddr, current_level, mask= s); =20 paddr =3D vm_untag_gpa(vm, paddr); =20 - if (!(*pte & PTE_PRESENT_MASK)) { - *pte =3D PTE_PRESENT_MASK | PTE_WRITABLE_MASK; + if (!(*pte & masks->present)) { + *pte =3D masks->present | masks->writeable; if (current_level =3D=3D target_level) - *pte |=3D PTE_LARGE_MASK | (paddr & PHYSICAL_PAGE_MASK); + *pte |=3D masks->large | (paddr & PHYSICAL_PAGE_MASK); else *pte |=3D vm_alloc_page_table(vm) & PHYSICAL_PAGE_MASK; } else { @@ -209,14 +221,15 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm = *vm, TEST_ASSERT(current_level !=3D target_level, "Cannot create hugepage at level: %u, vaddr: 0x%lx", current_level, vaddr); - TEST_ASSERT(!(*pte & PTE_LARGE_MASK), + TEST_ASSERT(!(*pte & masks->large), "Cannot create page table at level: %u, vaddr: 0x%lx", current_level, vaddr); } return pte; } =20 -void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int = level) +void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, + int level, const struct pte_masks *masks) { const uint64_t pg_size =3D PG_LEVEL_SIZE(level); uint64_t *pte =3D &vm->pgd; @@ -246,16 +259,16 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr,= uint64_t paddr, int level) * early if a hugepage was created. */ for (current_level =3D vm->pgtable_levels; current_level > PG_LEVEL_4K; c= urrent_level--) { - pte =3D virt_create_upper_pte(vm, pte, vaddr, paddr, current_level, leve= l); - if (*pte & PTE_LARGE_MASK) + pte =3D virt_create_upper_pte(vm, pte, vaddr, paddr, current_level, leve= l, masks); + if (*pte & masks->large) return; } =20 /* Fill in page table entry. */ - pte =3D virt_get_pte(vm, pte, vaddr, PG_LEVEL_4K); - TEST_ASSERT(!(*pte & PTE_PRESENT_MASK), + pte =3D virt_get_pte(vm, pte, vaddr, PG_LEVEL_4K, masks); + TEST_ASSERT(!(*pte & masks->present), "PTE already present for 4k page at vaddr: 0x%lx", vaddr); - *pte =3D PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MA= SK); + *pte =3D masks->present | masks->writeable | (paddr & PHYSICAL_PAGE_MASK); =20 /* * Neither SEV nor TDX supports shared page tables, so only the final @@ -269,7 +282,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, u= int64_t paddr, int level) =20 void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr) { - __virt_pg_map(vm, vaddr, paddr, PG_LEVEL_4K); + __virt_pg_map(vm, vaddr, paddr, PG_LEVEL_4K, &x86_pte_masks); } =20 void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, @@ -284,7 +297,7 @@ void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, = uint64_t paddr, nr_bytes, pg_size); =20 for (i =3D 0; i < nr_pages; i++) { - __virt_pg_map(vm, vaddr, paddr, level); + __virt_pg_map(vm, vaddr, paddr, level, &x86_pte_masks); sparsebit_set_num(vm->vpages_mapped, vaddr >> vm->page_shift, nr_bytes / PAGE_SIZE); =20 @@ -293,9 +306,10 @@ void virt_map_level(struct kvm_vm *vm, uint64_t vaddr,= uint64_t paddr, } } =20 -static bool vm_is_target_pte(uint64_t *pte, int *level, int current_level) +static bool vm_is_target_pte(uint64_t *pte, int *level, int current_level, + const struct pte_masks *masks) { - if (*pte & PTE_LARGE_MASK) { + if (*pte & masks->large) { TEST_ASSERT(*level =3D=3D PG_LEVEL_NONE || *level =3D=3D current_level, "Unexpected hugepage at level %d", current_level); @@ -305,8 +319,10 @@ static bool vm_is_target_pte(uint64_t *pte, int *level= , int current_level) return *level =3D=3D current_level; } =20 -uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr, - int *level) +static uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, + uint64_t vaddr, + int *level, + const struct pte_masks *masks) { uint64_t *pte =3D &vm->pgd; int current_level; @@ -332,8 +348,8 @@ uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, = uint64_t vaddr, "Canonical check failed. The virtual address is invalid."); =20 for (current_level =3D vm->pgtable_levels; current_level >=3D PG_LEVEL_4K= ; current_level--) { - pte =3D virt_get_pte(vm, pte, vaddr, current_level); - if (vm_is_target_pte(pte, level, current_level)) + pte =3D virt_get_pte(vm, pte, vaddr, current_level, masks); + if (vm_is_target_pte(pte, level, current_level, masks)) return pte; } =20 @@ -344,11 +360,12 @@ uint64_t *vm_get_page_table_entry(struct kvm_vm *vm, = uint64_t vaddr) { int level =3D PG_LEVEL_4K; =20 - return __vm_get_page_table_entry(vm, vaddr, &level); + return __vm_get_page_table_entry(vm, vaddr, &level, &x86_pte_masks); } =20 void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent) { + const struct pte_masks *masks =3D &x86_pte_masks; uint64_t *pml4e, *pml4e_start; uint64_t *pdpe, *pdpe_start; uint64_t *pde, *pde_start; @@ -365,44 +382,44 @@ void virt_arch_dump(FILE *stream, struct kvm_vm *vm, = uint8_t indent) pml4e_start =3D (uint64_t *) addr_gpa2hva(vm, vm->pgd); for (uint16_t n1 =3D 0; n1 <=3D 0x1ffu; n1++) { pml4e =3D &pml4e_start[n1]; - if (!(*pml4e & PTE_PRESENT_MASK)) + if (!(*pml4e & masks->present)) continue; fprintf(stream, "%*spml4e 0x%-3zx %p 0x%-12lx 0x%-10llx %u " " %u\n", indent, "", pml4e - pml4e_start, pml4e, addr_hva2gpa(vm, pml4e), PTE_GET_PFN(*pml4e), - !!(*pml4e & PTE_WRITABLE_MASK), !!(*pml4e & PTE_NX_MASK)); + !!(*pml4e & masks->writeable), !!(*pml4e & masks->nx)); =20 pdpe_start =3D addr_gpa2hva(vm, *pml4e & PHYSICAL_PAGE_MASK); for (uint16_t n2 =3D 0; n2 <=3D 0x1ffu; n2++) { pdpe =3D &pdpe_start[n2]; - if (!(*pdpe & PTE_PRESENT_MASK)) + if (!(*pdpe & masks->present)) continue; fprintf(stream, "%*spdpe 0x%-3zx %p 0x%-12lx 0x%-10llx " "%u %u\n", indent, "", pdpe - pdpe_start, pdpe, addr_hva2gpa(vm, pdpe), - PTE_GET_PFN(*pdpe), !!(*pdpe & PTE_WRITABLE_MASK), - !!(*pdpe & PTE_NX_MASK)); + PTE_GET_PFN(*pdpe), !!(*pdpe & masks->writeable), + !!(*pdpe & masks->nx)); =20 pde_start =3D addr_gpa2hva(vm, *pdpe & PHYSICAL_PAGE_MASK); for (uint16_t n3 =3D 0; n3 <=3D 0x1ffu; n3++) { pde =3D &pde_start[n3]; - if (!(*pde & PTE_PRESENT_MASK)) + if (!(*pde & masks->present)) continue; fprintf(stream, "%*spde 0x%-3zx %p " "0x%-12lx 0x%-10llx %u %u\n", indent, "", pde - pde_start, pde, addr_hva2gpa(vm, pde), - PTE_GET_PFN(*pde), !!(*pde & PTE_WRITABLE_MASK), - !!(*pde & PTE_NX_MASK)); + PTE_GET_PFN(*pde), !!(*pde & masks->writeable), + !!(*pde & masks->nx)); =20 pte_start =3D addr_gpa2hva(vm, *pde & PHYSICAL_PAGE_MASK); for (uint16_t n4 =3D 0; n4 <=3D 0x1ffu; n4++) { pte =3D &pte_start[n4]; - if (!(*pte & PTE_PRESENT_MASK)) + if (!(*pte & masks->present)) continue; fprintf(stream, "%*spte 0x%-3zx %p " "0x%-12lx 0x%-10llx %u %u " @@ -411,9 +428,9 @@ void virt_arch_dump(FILE *stream, struct kvm_vm *vm, ui= nt8_t indent) pte - pte_start, pte, addr_hva2gpa(vm, pte), PTE_GET_PFN(*pte), - !!(*pte & PTE_WRITABLE_MASK), - !!(*pte & PTE_NX_MASK), - !!(*pte & PTE_DIRTY_MASK), + !!(*pte & masks->writeable), + !!(*pte & masks->nx), + !!(*pte & masks->dirty), ((uint64_t) n1 << 27) | ((uint64_t) n2 << 18) | ((uint64_t) n3 << 9) @@ -493,10 +510,11 @@ static void kvm_seg_set_kernel_data_64bit(struct kvm_= segment *segp) =20 vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva) { + const struct pte_masks *masks =3D &x86_pte_masks; int level =3D PG_LEVEL_NONE; - uint64_t *pte =3D __vm_get_page_table_entry(vm, gva, &level); + uint64_t *pte =3D __vm_get_page_table_entry(vm, gva, &level, masks); =20 - TEST_ASSERT(*pte & PTE_PRESENT_MASK, + TEST_ASSERT(*pte & masks->present, "Leaf PTE not PRESENT for gva: 0x%08lx", gva); =20 /* --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-183.mta1.migadu.com (out-183.mta1.migadu.com [95.215.58.183]) (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 4495828D8D9 for ; Tue, 21 Oct 2025 07:48:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032933; cv=none; b=aYIdAH47LKUVLbWw2EvBMNLNKv6EqGjuZ3dHvA+xKiN8UQCzlTpjdgqD3/iPvZtj6rbd3dQymrApf7IK2LXNNvrblyLUlURLseGOMXMK7j/PxBC0/Tr42KBmzPImrNkwrOTqR92w8KXNeNLdFBHVFU5iNrFGmw1aa7sxDJmUQEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032933; c=relaxed/simple; bh=QMV5SQvBkBbcpMvCiQUR2nhYeO0rDEmSV4BK+AA4VK4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bVMdCrWlzpUeIKiBzpo/ZgR5KOLRNJORV9Yd8TJJPooqpufUuPhu7iSJFGhIBKkVSW/H3SQ7u2X9IU1cSpiPNfjlpfloB7eEMgrp96MAUtHawyMnRbQ2Ra2fWegivHYQCCB8v3dnVQrXI5631hJaokCPihjPAkTqQUYnF6lIT7s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=JpzaxnZJ; arc=none smtp.client-ip=95.215.58.183 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="JpzaxnZJ" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032925; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kaqUgIzfA70/v+FwtaquFzSjQwTE2DOer6LTTMiWZzs=; b=JpzaxnZJ9BJ3bFSwGAbUdpfWFjL9R0aReRMUTrAFGrrnXtYivXWQPT3IjKggcvjnlZpEQk wpjiY1Xf+UGvFqSlvJFunXVs6xxwMlWwZXDFvbTKNKWx8EXAwhP/8casjW+pRqt8Gdk4yz xZrJslOOAAAxLgSdINMKMRQEmvoiCbg= 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 13/23] KVM: selftests: Pass the root GPA into virt_get_pte() Date: Tue, 21 Oct 2025 07:47:26 +0000 Message-ID: <20251021074736.1324328-14-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Instead of hardcoding the root check against vm->pgd, pass the root_gpa into virt_get_pte(). There's a subtle change here, instead of checking that the parent pointer has the address of vm->pgd, check if the value pointed at by the parent pointer is the root_gpa. No change in behavior expected, but this will be required for following changes that generalize __virt_pg_map() to other MMUs. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/lib/x86/processor.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 8a838f208abe4..92a2b5aefd880 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -179,15 +179,15 @@ const struct pte_masks x86_pte_masks =3D { .nx =3D BIT_ULL(63), }; =20 -static void *virt_get_pte(struct kvm_vm *vm, uint64_t *parent_pte, - uint64_t vaddr, int level, +static void *virt_get_pte(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t *parent_pte, uint64_t vaddr, int level, const struct pte_masks *masks) { uint64_t pt_gpa =3D PTE_GET_PA(*parent_pte); uint64_t *page_table =3D addr_gpa2hva(vm, pt_gpa); int index =3D (vaddr >> PG_LEVEL_SHIFT(level)) & 0x1ffu; =20 - TEST_ASSERT((*parent_pte & masks->present) || parent_pte =3D=3D &vm->pgd, + TEST_ASSERT((*parent_pte =3D=3D root_gpa) || (*parent_pte & masks->presen= t), "Parent PTE (level %d) not PRESENT for gva: 0x%08lx", level + 1, vaddr); =20 @@ -195,6 +195,7 @@ static void *virt_get_pte(struct kvm_vm *vm, uint64_t *= parent_pte, } =20 static uint64_t *virt_create_upper_pte(struct kvm_vm *vm, + vm_paddr_t root_gpa, uint64_t *parent_pte, uint64_t vaddr, uint64_t paddr, @@ -202,7 +203,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *v= m, int target_level, const struct pte_masks *masks) { - uint64_t *pte =3D virt_get_pte(vm, parent_pte, vaddr, current_level, mask= s); + uint64_t *pte =3D virt_get_pte(vm, root_gpa, parent_pte, + vaddr, current_level, masks); =20 paddr =3D vm_untag_gpa(vm, paddr); =20 @@ -259,13 +261,14 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr,= uint64_t paddr, * early if a hugepage was created. */ for (current_level =3D vm->pgtable_levels; current_level > PG_LEVEL_4K; c= urrent_level--) { - pte =3D virt_create_upper_pte(vm, pte, vaddr, paddr, current_level, leve= l, masks); + pte =3D virt_create_upper_pte(vm, vm->pgd, pte, vaddr, paddr, + current_level, level, masks); if (*pte & masks->large) return; } =20 /* Fill in page table entry. */ - pte =3D virt_get_pte(vm, pte, vaddr, PG_LEVEL_4K, masks); + pte =3D virt_get_pte(vm, vm->pgd, pte, vaddr, PG_LEVEL_4K, masks); TEST_ASSERT(!(*pte & masks->present), "PTE already present for 4k page at vaddr: 0x%lx", vaddr); *pte =3D masks->present | masks->writeable | (paddr & PHYSICAL_PAGE_MASK); @@ -348,7 +351,7 @@ static uint64_t *__vm_get_page_table_entry(struct kvm_v= m *vm, "Canonical check failed. The virtual address is invalid."); =20 for (current_level =3D vm->pgtable_levels; current_level >=3D PG_LEVEL_4K= ; current_level--) { - pte =3D virt_get_pte(vm, pte, vaddr, current_level, masks); + pte =3D virt_get_pte(vm, vm->pgd, pte, vaddr, current_level, masks); if (vm_is_target_pte(pte, level, current_level, masks)) return pte; } --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-182.mta1.migadu.com (out-182.mta1.migadu.com [95.215.58.182]) (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 B116E28CF5D for ; Tue, 21 Oct 2025 07:48:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032934; cv=none; b=lCAXeXydkzIDgmpyL1N7OoUqyE9il2tMNwPpokyAOYhDnjzAEScz7jU+5gGSRz4lqXc5mFgjIAiIW9PggmqYIxs1Co3rv+NNMvWXM3543qgVBjO1Me04XBb8Sfe8/A+cJUwEpv8X5f3nKnHYtWaFkc4NM+hBS6tOQad9EF3r1tU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032934; c=relaxed/simple; bh=nwpKTYunhpR2I0MoWw1vUHuiJF4funA/hkV+m9fRtrs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XQzUCdQyWMgmwEPvr17qdv5zGCIxb4xQdsVzBhT/ogbclWDnATrI24QZ4RRSHh/mhUXc6DAOIPgwcZuUqqXEXhtgU9SHn2ODClLlRH8iWda8uNdsccK78fjI7ehBEn+lHbmFP4qOoZzB/1ZjY+NkdILJxK+MZUzVtQRD6a6J4xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=RKXTwJX0; arc=none smtp.client-ip=95.215.58.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="RKXTwJX0" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032926; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Gu9aKJgaFjqAioSjcKo6ytfp2sq+GCP1NpEqf7iOGR4=; b=RKXTwJX0QR7FdDc+zDFHY9HJGGzCceCN+8dnlp1HwdXNLJyoKJ3SlwGwOqeYikKRUIcjHM qGGilgGfioQeKVKGp1QslmYAn+QH9OhQqu+Uab3sAskkvLIijPcSECUvplxRHhGAiTe5Zk pyChKLPvKgpx4Bk0EAQzLNhfdiJ3fwU= 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 14/23] KVM: selftests: Pass the root GPA into __virt_pg_map() Date: Tue, 21 Oct 2025 07:47:27 +0000 Message-ID: <20251021074736.1324328-15-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Pass the root_gpa into __virt_pg_map() instead of assuming vm->pgd in preparation for using it with other MMUs. No functional change intended. Signed-off-by: Yosry Ahmed --- .../testing/selftests/kvm/include/x86/processor.h | 4 ++-- tools/testing/selftests/kvm/lib/x86/processor.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 8debe0df3ffca..2f0d83b6e5952 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1451,8 +1451,8 @@ struct pte_masks { =20 extern const struct pte_masks x86_pte_masks; =20 -void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, - int level, const struct pte_masks *masks); +void __virt_pg_map(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t vaddr, + uint64_t paddr, int level, const struct pte_masks *masks); void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, uint64_t nr_bytes, int level); =20 diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 92a2b5aefd880..13e9376d5f545 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -230,11 +230,11 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm = *vm, return pte; } =20 -void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, - int level, const struct pte_masks *masks) +void __virt_pg_map(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t vaddr, + uint64_t paddr, int level, const struct pte_masks *masks) { const uint64_t pg_size =3D PG_LEVEL_SIZE(level); - uint64_t *pte =3D &vm->pgd; + uint64_t *pte =3D &root_gpa; int current_level; =20 TEST_ASSERT(vm->mode =3D=3D VM_MODE_PXXV48_4K || @@ -261,14 +261,14 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr,= uint64_t paddr, * early if a hugepage was created. */ for (current_level =3D vm->pgtable_levels; current_level > PG_LEVEL_4K; c= urrent_level--) { - pte =3D virt_create_upper_pte(vm, vm->pgd, pte, vaddr, paddr, + pte =3D virt_create_upper_pte(vm, root_gpa, pte, vaddr, paddr, current_level, level, masks); if (*pte & masks->large) return; } =20 /* Fill in page table entry. */ - pte =3D virt_get_pte(vm, vm->pgd, pte, vaddr, PG_LEVEL_4K, masks); + pte =3D virt_get_pte(vm, root_gpa, pte, vaddr, PG_LEVEL_4K, masks); TEST_ASSERT(!(*pte & masks->present), "PTE already present for 4k page at vaddr: 0x%lx", vaddr); *pte =3D masks->present | masks->writeable | (paddr & PHYSICAL_PAGE_MASK); @@ -285,7 +285,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, u= int64_t paddr, =20 void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr) { - __virt_pg_map(vm, vaddr, paddr, PG_LEVEL_4K, &x86_pte_masks); + __virt_pg_map(vm, vm->pgd, vaddr, paddr, PG_LEVEL_4K, &x86_pte_masks); } =20 void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, @@ -300,7 +300,7 @@ void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, = uint64_t paddr, nr_bytes, pg_size); =20 for (i =3D 0; i < nr_pages; i++) { - __virt_pg_map(vm, vaddr, paddr, level, &x86_pte_masks); + __virt_pg_map(vm, vm->pgd, vaddr, paddr, level, &x86_pte_masks); sparsebit_set_num(vm->vpages_mapped, vaddr >> vm->page_shift, nr_bytes / PAGE_SIZE); =20 --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-171.mta1.migadu.com (out-171.mta1.migadu.com [95.215.58.171]) (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 3AD322D3A93 for ; Tue, 21 Oct 2025 07:48:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032935; cv=none; b=kx+Wq34S3kL0hg8Wiv0P4Ohum/CP+H07iDRbwhQjNW2+Pqd43pdv8qUmA7Ukd4U5N5SaURKBkWcxx3PT5oBK6lugB43xcprnNwsIGmdN0yWgYer9bU5YD7yTpFUlUBoCm9GMnEvuiT95q0GcqbGKKjddLLzL9DlRbqmgSwg8N08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032935; c=relaxed/simple; bh=SwNsXp43um/5RC1PXrP7VWZL9LnkBMIw/GJ0R1/QAeI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W1Bn8FNHh3Eh+fXQdl446twrZRzsI4NHC2h7mb/bB181ReY2ux8E5ci6L4FayXO7Vpa7R1PEhTY+pfNkVcHL2rWjwGZCnwLiqyAZf0Vit5HepYshUU/e2PaI1borySGgQO+0zBrPR4Kbjs5eCW3K0Y82bROtY45bqSK9rTMQKjQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PT0kTIbx; arc=none smtp.client-ip=95.215.58.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PT0kTIbx" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032929; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dWmuFaMQlvpdbpcMMh0PPPyyBRYXR+jWxqqcg/LAa98=; b=PT0kTIbxDrlqm/jZQ4eGIFs+XlyS2q3Moa1J+k0H2D/KmDjNN/eOpKYCXUpLAA8GpFgbrC sLK0pzMzkUr0UeDBa0daD57egd8NZwnCQg7OAEsWzAKU8yQ5U53eIxiohYBmzWsiMoHo5O 7YghpLPzIFx+4f5McHAq2dJfjRhzyIE= 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 15/23] KVM: selftests: Stop setting AD bits on nested EPTs on creation Date: Tue, 21 Oct 2025 07:47:28 +0000 Message-ID: <20251021074736.1324328-16-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" When new nested EPTs are created, the AD bits are set. This was introduced by commit 094444204570 ("selftests: kvm: add test for dirty logging inside nested guests"), which introduced vmx_dirty_log_test. It's unclear why that was needed at the time, but regardless, the test seems to pass without them so probably no longer needed. dirty_log_perf_test (with -n to run in L2) also passes, and these are the only tests currently using nested EPT mappings. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/lib/x86/vmx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index f0023a3b0137e..36e60016fa7b2 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -436,14 +436,6 @@ void __nested_pg_map(struct vmx_pages *vmx, struct kvm= _vm *vm, =20 pt =3D addr_gpa2hva(vm, pte->address * vm->page_size); } - - /* - * For now mark these as accessed and dirty because the only - * testcase we have needs that. Can be reconsidered later. - */ - pte->accessed =3D true; - pte->dirty =3D true; - } =20 void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) (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 A7B8C29B217; Tue, 21 Oct 2025 07:48:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032936; cv=none; b=Teyu3zag8c27AKfY8DHjzipJQawSa9HQ6ZXTwpV+jEbqn64Jk4rtNfEhEnOeAAxjpStWjfJNbbCRCgZS71i7d6cRb4/k+LK2Ts5BERRx5K4k7nIe7lbT05THjXl/xhtuxIKmvPO1+R0WUzoBL6DTwSo7Opb6ck5cTyj13kyt2w4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032936; c=relaxed/simple; bh=mgC55q9T1f5jBf/8CfjvJMiQ5793zmo9lyYlDPw9u4s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dIe7TDlXnrFxvJsfl+jnuI/3/mm3sgILMWlTi9wVobSPMDjjHdmdoHkiKPxQxFD8GjKUNKyMordmb1RP4Krb7VbsHpEqJymKGsYUAORYS5pCYTd40AyaPk10kOdfwCzx6xHN2IFe4PmVeP7dUTHoL3baKRGZN3h7/n+EEx+mo/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=DLVPI02F; arc=none smtp.client-ip=95.215.58.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="DLVPI02F" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vRlNitll6uLSlbrA9R14UL9rp6yZ0zp6Csut3gOTm0g=; b=DLVPI02FdBoOOBwOryq4jlv6HCaxiutVRwxD1QSrxmoSOpkEMfvqvgV65NgiH0/vSYFTa8 smQFr0+fqrOATKNUR2cGXXAAkl8x3qJ8HPfj6wcizdS0GBM+GKJ9qZtSUMLRMCOjUbxAbT oMKg4UDhf5nJ4UXlVlrk+3jeoy+cvsE= 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 16/23] KVM: selftests: Use __virt_pg_map() for nested EPTs Date: Tue, 21 Oct 2025 07:47:29 +0000 Message-ID: <20251021074736.1324328-17-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" __nested_pg_map() bears a lot of resemblence to __virt_pg_map(). The main difference is using the EPT struct overlay instead of the PTE masks. Now that PTE masks are passed into __virt_pg_map() as a struct, define a similar struct for EPTs and use __virt_pg_map() instead of __nested_pg_map(). EPTs have no 'present' or 'user' bits, so use the 'readable' bit instead like shadow_{present/user}_mask, ignoring the fact that entries can be present and not readable if the CPU has VMX_EPT_EXECUTE_ONLY_BIT. This is simple and sufficient for testing. Opportunistically drop nested_pg_map() since it has no callers. Add an executable bitmask to struct pte_masks, and update __virt_pg_map() and friends to set the bit on newly created entries to match the EPT behavior. It's a noop for x86 page tables. Another benefit of reusing the code is having separate handling for upper-level PTEs vs 4K PTEs, which avoids some quirks like setting the large bit on a 4K PTE. Signed-off-by: Yosry Ahmed Suggested-by: Sean Christopherson --- .../selftests/kvm/include/x86/processor.h | 1 + tools/testing/selftests/kvm/include/x86/vmx.h | 4 +- .../testing/selftests/kvm/lib/x86/processor.c | 9 +- tools/testing/selftests/kvm/lib/x86/vmx.c | 113 +++--------------- 4 files changed, 27 insertions(+), 100 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 2f0d83b6e5952..0d6d335d309ef 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1447,6 +1447,7 @@ struct pte_masks { uint64_t dirty; uint64_t large; uint64_t nx; + uint64_t x; }; =20 extern const struct pte_masks x86_pte_masks; diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/= selftests/kvm/include/x86/vmx.h index 96e2b4c630a9b..5aa14ceed050a 100644 --- a/tools/testing/selftests/kvm/include/x86/vmx.h +++ b/tools/testing/selftests/kvm/include/x86/vmx.h @@ -99,6 +99,8 @@ #define VMX_EPT_VPID_CAP_1G_PAGES 0x00020000 #define VMX_EPT_VPID_CAP_AD_BITS 0x00200000 =20 +extern const struct pte_masks ept_pte_masks; + #define EXIT_REASON_FAILED_VMENTRY 0x80000000 =20 enum vmcs_field { @@ -559,8 +561,6 @@ bool load_vmcs(struct vmx_pages *vmx); =20 bool ept_1g_pages_supported(void); =20 -void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, - uint64_t nested_paddr, uint64_t paddr); void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint64_t size); void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm, diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 13e9376d5f545..caad8a9b3f067 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -177,6 +177,7 @@ const struct pte_masks x86_pte_masks =3D { .dirty =3D BIT_ULL(6), .large =3D BIT_ULL(7), .nx =3D BIT_ULL(63), + .x =3D 0, }; =20 static void *virt_get_pte(struct kvm_vm *vm, vm_paddr_t root_gpa, @@ -209,7 +210,7 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *v= m, paddr =3D vm_untag_gpa(vm, paddr); =20 if (!(*pte & masks->present)) { - *pte =3D masks->present | masks->writeable; + *pte =3D masks->present | masks->writeable | masks->x; if (current_level =3D=3D target_level) *pte |=3D masks->large | (paddr & PHYSICAL_PAGE_MASK); else @@ -256,6 +257,9 @@ void __virt_pg_map(struct kvm_vm *vm, vm_paddr_t root_g= pa, uint64_t vaddr, TEST_ASSERT(vm_untag_gpa(vm, paddr) =3D=3D paddr, "Unexpected bits in paddr: %lx", paddr); =20 + TEST_ASSERT(!masks->x || !masks->nx, + "X and NX bit masks cannot be used simultaneously"); + /* * Allocate upper level page tables, if not already present. Return * early if a hugepage was created. @@ -271,7 +275,8 @@ void __virt_pg_map(struct kvm_vm *vm, vm_paddr_t root_g= pa, uint64_t vaddr, pte =3D virt_get_pte(vm, root_gpa, pte, vaddr, PG_LEVEL_4K, masks); TEST_ASSERT(!(*pte & masks->present), "PTE already present for 4k page at vaddr: 0x%lx", vaddr); - *pte =3D masks->present | masks->writeable | (paddr & PHYSICAL_PAGE_MASK); + *pte =3D masks->present | masks->writeable | masks->x + | (paddr & PHYSICAL_PAGE_MASK); =20 /* * Neither SEV nor TDX supports shared page tables, so only the final diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index 36e60016fa7b2..46a491eb083c9 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -19,19 +19,21 @@ bool enable_evmcs; struct hv_enlightened_vmcs *current_evmcs; struct hv_vp_assist_page *current_vp_assist; =20 -struct eptPageTableEntry { - uint64_t readable:1; - uint64_t writable:1; - uint64_t executable:1; - uint64_t memory_type:3; - uint64_t ignore_pat:1; - uint64_t page_size:1; - uint64_t accessed:1; - uint64_t dirty:1; - uint64_t ignored_11_10:2; - uint64_t address:40; - uint64_t ignored_62_52:11; - uint64_t suppress_ve:1; +const struct pte_masks ept_pte_masks =3D { + /* + * EPTs do not have 'present' or 'user' bits, instead bit 0 is the + * 'readable' bit. In some cases, EPTs can be execute-only and an entry + * is present but not readable. However, for the purposes of testing we + * assume present =3D=3D user =3D=3D readable for simplicity. + */ + .present =3D BIT_ULL(0), + .user =3D BIT_ULL(0), + .writeable =3D BIT_ULL(1), + .x =3D BIT_ULL(2), + .accessed =3D BIT_ULL(5), + .dirty =3D BIT_ULL(6), + .large =3D BIT_ULL(7), + .nx =3D 0, }; =20 struct eptPageTablePointer { @@ -362,88 +364,6 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_r= ip, void *guest_rsp) init_vmcs_guest_state(guest_rip, guest_rsp); } =20 -static void nested_create_pte(struct kvm_vm *vm, - struct eptPageTableEntry *pte, - uint64_t nested_paddr, - uint64_t paddr, - int current_level, - int target_level) -{ - if (!pte->readable) { - pte->writable =3D true; - pte->readable =3D true; - pte->executable =3D true; - pte->page_size =3D (current_level =3D=3D target_level); - if (pte->page_size) - pte->address =3D paddr >> vm->page_shift; - else - pte->address =3D vm_alloc_page_table(vm) >> vm->page_shift; - } else { - /* - * Entry already present. Assert that the caller doesn't want - * a hugepage at this level, and that there isn't a hugepage at - * this level. - */ - TEST_ASSERT(current_level !=3D target_level, - "Cannot create hugepage at level: %u, nested_paddr: 0x%lx", - current_level, nested_paddr); - TEST_ASSERT(!pte->page_size, - "Cannot create page table at level: %u, nested_paddr: 0x%lx", - current_level, nested_paddr); - } -} - - -void __nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, - uint64_t nested_paddr, uint64_t paddr, int target_level) -{ - const uint64_t page_size =3D PG_LEVEL_SIZE(target_level); - struct eptPageTableEntry *pt =3D vmx->eptp_hva, *pte; - uint16_t index; - - TEST_ASSERT(vm->mode =3D=3D VM_MODE_PXXV48_4K || - vm->mode =3D=3D VM_MODE_PXXV57_4K, - "Unknown or unsupported guest mode: 0x%x", vm->mode); - - TEST_ASSERT((nested_paddr >> 48) =3D=3D 0, - "Nested physical address 0x%lx is > 48-bits and requires 5-level EPT= ", - nested_paddr); - TEST_ASSERT((nested_paddr % page_size) =3D=3D 0, - "Nested physical address not on page boundary,\n" - " nested_paddr: 0x%lx page_size: 0x%lx", - nested_paddr, page_size); - TEST_ASSERT((nested_paddr >> vm->page_shift) <=3D vm->max_gfn, - "Physical address beyond beyond maximum supported,\n" - " nested_paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x", - paddr, vm->max_gfn, vm->page_size); - TEST_ASSERT((paddr % page_size) =3D=3D 0, - "Physical address not on page boundary,\n" - " paddr: 0x%lx page_size: 0x%lx", - paddr, page_size); - TEST_ASSERT((paddr >> vm->page_shift) <=3D vm->max_gfn, - "Physical address beyond beyond maximum supported,\n" - " paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x", - paddr, vm->max_gfn, vm->page_size); - - for (int level =3D PG_LEVEL_512G; level >=3D PG_LEVEL_4K; level--) { - index =3D (nested_paddr >> PG_LEVEL_SHIFT(level)) & 0x1ffu; - pte =3D &pt[index]; - - nested_create_pte(vm, pte, nested_paddr, paddr, level, target_level); - - if (pte->page_size) - break; - - pt =3D addr_gpa2hva(vm, pte->address * vm->page_size); - } -} - -void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, - uint64_t nested_paddr, uint64_t paddr) -{ - __nested_pg_map(vmx, vm, nested_paddr, paddr, PG_LEVEL_4K); -} - /* * Map a range of EPT guest physical addresses to the VM's physical address * @@ -472,7 +392,8 @@ void __nested_map(struct vmx_pages *vmx, struct kvm_vm = *vm, TEST_ASSERT(paddr + size > paddr, "Paddr overflow"); =20 while (npages--) { - __nested_pg_map(vmx, vm, nested_paddr, paddr, level); + __virt_pg_map(vm, vmx->eptp_gpa, nested_paddr, paddr, + level, &ept_pte_masks); nested_paddr +=3D page_size; paddr +=3D page_size; } --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) (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 B89312EA48E for ; Tue, 21 Oct 2025 07:48:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032937; cv=none; b=HHjAR1htSsg2xXQTHJ1KJlH4OMBFipy+ADxTBYkl2gxWJrEvfARII4J2AcirvbYIsiPoOATF4Hkl+BC2lbMBWKvcJFn6l+s44jk1H/Qf8QX9axqmy4OkzIopOjVo+j/nZ04cHPdqGefMmg0/sGZIT9iUy0ohOLSIintYiB3mOqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032937; c=relaxed/simple; bh=mtIwWT8Nktn0uw9mNuy5ejlD6XdWbvYgsMXdyw5HXcA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pCvw7eLRDfe9qHGqGlgufWnmmcECOWj33KyXHkZRmpt9VQZX/WrDLK3pq60uNrsB6vQYrkNHJ/XITL1ZUvju60IzhfGcdN7E1I+Iyur23xtFTQVeUmllXDZHNYtKkptNnSJlze06TZ3+4/MIG8ts4slLrMtKAy1YC8DuoDF+wD8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=TrawG3Ex; arc=none smtp.client-ip=95.215.58.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="TrawG3Ex" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7BOHMwP1LaWFrXwyVNd/jaYf//p4/u+c41RTtzXqd10=; b=TrawG3ExK7CPm8ABxwoUAbjbtJ49fJ5iBtB2Ufa1g+UppwCaX4WnmC+NXxyVHLU2LqroVd qqRdhU6NZARYdRtXPHmA2hn5cc9NdxU7ElMpaCSsimjO254fimGW2pVuHluWoFyV0t0BS8 sHLh43QwFDrblPaNHgwgssuemQK0PeA= 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 17/23] KVM: selftests: Kill eptPageTablePointer Date: Tue, 21 Oct 2025 07:47:30 +0000 Message-ID: <20251021074736.1324328-18-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Replace the struct overlay with explicit bitmasks, which is clearer and less error-prone. See commit f18b4aebe107 ("kvm: selftests: do not use bitfields larger than 32-bits for PTEs") for an example of why bitfields are not preferrable. Remove the unused PAGE_SHIFT_4K definition while at it. No functional change intended. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/lib/x86/vmx.c | 37 +++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index 46a491eb083c9..75996fc00501e 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -10,10 +10,16 @@ #include "processor.h" #include "vmx.h" =20 -#define PAGE_SHIFT_4K 12 - #define KVM_EPT_PAGE_TABLE_MIN_PADDR 0x1c0000 =20 +#define EPTP_MT_SHIFT 0 /* EPTP memtype bits 2:0 */ +#define EPTP_PWL_SHIFT 3 /* EPTP page walk length bits 5:3 */ +#define EPTP_AD_ENABLED_SHIFT 6 /* EPTP AD enabled bit 6 */ + +#define EPTP_WB (X86_MEMTYPE_WB << EPTP_MT_SHIFT) +#define EPTP_PWL_4 (3ULL << EPTP_PWL_SHIFT) /* PWL is (levels - 1) */ +#define EPTP_AD_ENABLED (1ULL << EPTP_AD_ENABLED_SHIFT) + bool enable_evmcs; =20 struct hv_enlightened_vmcs *current_evmcs; @@ -36,14 +42,6 @@ const struct pte_masks ept_pte_masks =3D { .nx =3D 0, }; =20 -struct eptPageTablePointer { - uint64_t memory_type:3; - uint64_t page_walk_length:3; - uint64_t ad_enabled:1; - uint64_t reserved_11_07:5; - uint64_t address:40; - uint64_t reserved_63_52:12; -}; int vcpu_enable_evmcs(struct kvm_vcpu *vcpu) { uint16_t evmcs_ver; @@ -198,16 +196,15 @@ static inline void init_vmcs_control_fields(struct vm= x_pages *vmx) vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS)= ); =20 if (vmx->eptp_gpa) { - uint64_t ept_paddr; - struct eptPageTablePointer eptp =3D { - .memory_type =3D X86_MEMTYPE_WB, - .page_walk_length =3D 3, /* + 1 */ - .ad_enabled =3D ept_vpid_cap_supported(VMX_EPT_VPID_CAP_AD_BITS), - .address =3D vmx->eptp_gpa >> PAGE_SHIFT_4K, - }; - - memcpy(&ept_paddr, &eptp, sizeof(ept_paddr)); - vmwrite(EPT_POINTER, ept_paddr); + uint64_t eptp =3D vmx->eptp_gpa | EPTP_WB | EPTP_PWL_4; + + TEST_ASSERT((vmx->eptp_gpa & ~PHYSICAL_PAGE_MASK) =3D=3D 0, + "Illegal bits set in vmx->eptp_gpa"); + + if (ept_vpid_cap_supported(VMX_EPT_VPID_CAP_AD_BITS)) + eptp |=3D EPTP_AD_ENABLED; + + vmwrite(EPT_POINTER, eptp); sec_exec_ctl |=3D SECONDARY_EXEC_ENABLE_EPT; } =20 --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) (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 6E3622E8B76 for ; Tue, 21 Oct 2025 07:48:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032939; cv=none; b=kzaSaNW37fsDmSaFfWhC+2L56Se8lCdhR1/Pu/2Y3UkvVo8NNT4zUtVrjSs8ztdbWsFU1pi9W5dKioHgtdbGade/t6OKT72lKoXJsvNp3hsagM6aGHpVnoYN8YdcGlEiG9Z4lE/e3+GzkHlgjmSWhKbutULn2r067+11DlJ6p6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032939; c=relaxed/simple; bh=19aCZcu0vL3OtVccqeE7RWDOIWmFbC1XpRSSnDXy6MQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DBTuRNbllKTXDLYV4q6uhEJ0FICmOYj9Pu6+YnuR9OqXUTMQSk0IwpG4TPeWQaKPHNITlE1wGMSyKDqdb9JeXtyxOeSWP9aKF3pO2heCZj2+fFLkMzQyx5sLwrxZqtFVdR4AmScwvtlVLf2lJ8eLCbP2OtVYF4HoN5P+UJ1JN2I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Q7otXJ5E; arc=none smtp.client-ip=95.215.58.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Q7otXJ5E" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wrdQMUeB9V5fIrbohohZAu0JiP8CYsDeVqzmHC77NBI=; b=Q7otXJ5ELC03U1EapQ91WURdS4AmI5zJsRE6py+P/we7kq2rr0IFFzZgYGEwnd+Xbjb+0h zG2cw4hThas2+yX20tGe+4+EAWehLSh/yHyL472zooWA6xL+NCY2Po5ti5EymvRv1a84FE BBZwSMPOHHPkElN0LX7FApm6N2AZVuE= 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 18/23] KVM: selftests: Generalize nested mapping functions Date: Tue, 21 Oct 2025 07:47:31 +0000 Message-ID: <20251021074736.1324328-19-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Instead of passing in a pointer to struct vmx_pages, pass in the GPA of the root of the EPTs, as that's the only member being used. Furthermore, only use ept_pte_masks for VMX, and use x86_pte_masks otherwise (which is what NPT uses). This is in preparation of supporting NPTs as well. No functional change intended. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/include/x86/vmx.h | 6 +++--- .../testing/selftests/kvm/lib/x86/memstress.c | 4 ++-- tools/testing/selftests/kvm/lib/x86/vmx.c | 20 ++++++++++--------- .../selftests/kvm/x86/vmx_dirty_log_test.c | 6 +++--- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/= selftests/kvm/include/x86/vmx.h index 5aa14ceed050a..4429e83e1f52c 100644 --- a/tools/testing/selftests/kvm/include/x86/vmx.h +++ b/tools/testing/selftests/kvm/include/x86/vmx.h @@ -561,11 +561,11 @@ bool load_vmcs(struct vmx_pages *vmx); =20 bool ept_1g_pages_supported(void); =20 -void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, +void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t nested_paddr, uint64_t paddr, uint64_t size); -void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm, +void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, uint32_t memslot); -void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm, +void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t addr, uint64_t size); bool kvm_cpu_has_ept(void); void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm); diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testin= g/selftests/kvm/lib/x86/memstress.c index 0b1f288ad5564..5ca970a8a5c14 100644 --- a/tools/testing/selftests/kvm/lib/x86/memstress.c +++ b/tools/testing/selftests/kvm/lib/x86/memstress.c @@ -70,11 +70,11 @@ void memstress_setup_ept(struct vmx_pages *vmx, struct = kvm_vm *vm) * KVM can shadow the EPT12 with the maximum huge page size supported * by the backing source. */ - nested_identity_map_1g(vmx, vm, 0, 0x100000000ULL); + nested_identity_map_1g(vm, vmx->eptp_gpa, 0, 0x100000000ULL); =20 start =3D align_down(memstress_args.gpa, PG_SIZE_1G); end =3D align_up(memstress_args.gpa + memstress_args.size, PG_SIZE_1G); - nested_identity_map_1g(vmx, vm, start, end - start); + nested_identity_map_1g(vm, vmx->eptp_gpa, start, end - start); } =20 void memstress_setup_nested(struct kvm_vm *vm, int nr_vcpus, struct kvm_vc= pu *vcpus[]) diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index 75996fc00501e..0573b3ea717cb 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -378,34 +378,36 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_= rip, void *guest_rsp) * Within the VM given by vm, creates a nested guest translation for the * page range starting at nested_paddr to the page range starting at paddr. */ -void __nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, +void __nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t nested_paddr, uint64_t paddr, uint64_t size, int level) { size_t page_size =3D PG_LEVEL_SIZE(level); size_t npages =3D size / page_size; + const struct pte_masks *masks; + + masks =3D kvm_cpu_has(X86_FEATURE_VMX) ? &ept_pte_masks : &x86_pte_masks; =20 TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow"); TEST_ASSERT(paddr + size > paddr, "Paddr overflow"); =20 while (npages--) { - __virt_pg_map(vm, vmx->eptp_gpa, nested_paddr, paddr, - level, &ept_pte_masks); + __virt_pg_map(vm, root_gpa, nested_paddr, paddr, level, masks); nested_paddr +=3D page_size; paddr +=3D page_size; } } =20 -void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, +void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t nested_paddr, uint64_t paddr, uint64_t size) { - __nested_map(vmx, vm, nested_paddr, paddr, size, PG_LEVEL_4K); + __nested_map(vm, root_gpa, nested_paddr, paddr, size, PG_LEVEL_4K); } =20 /* Prepare an identity extended page table that maps all the * physical pages in VM. */ -void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm, +void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, uint32_t memslot) { sparsebit_idx_t i, last; @@ -419,7 +421,7 @@ void nested_map_memslot(struct vmx_pages *vmx, struct k= vm_vm *vm, if (i > last) break; =20 - nested_map(vmx, vm, + nested_map(vm, root_gpa, (uint64_t)i << vm->page_shift, (uint64_t)i << vm->page_shift, 1 << vm->page_shift); @@ -427,10 +429,10 @@ void nested_map_memslot(struct vmx_pages *vmx, struct= kvm_vm *vm, } =20 /* Identity map a region with 1GiB Pages. */ -void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm, +void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t addr, uint64_t size) { - __nested_map(vmx, vm, addr, addr, size, PG_LEVEL_1G); + __nested_map(vm, root_gpa, addr, addr, size, PG_LEVEL_1G); } =20 bool kvm_cpu_has_ept(void) diff --git a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c b/tools/t= esting/selftests/kvm/x86/vmx_dirty_log_test.c index 98cb6bdab3e6d..e54e6111164e7 100644 --- a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c @@ -121,9 +121,9 @@ static void test_vmx_dirty_log(bool enable_ept) */ if (enable_ept) { prepare_eptp(vmx, vm); - nested_map_memslot(vmx, vm, 0); - nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZE); - nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZE); + nested_map_memslot(vm, vmx->eptp_gpa, 0); + nested_map(vm, vmx->eptp_gpa, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZ= E); + nested_map(vm, vmx->eptp_gpa, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZ= E); } =20 bmap =3D bitmap_zalloc(TEST_MEM_PAGES); --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) (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 CAB5B2F6197 for ; Tue, 21 Oct 2025 07:48:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032941; cv=none; b=kFM7NgTM+h5JHlqcGZCquif68i+xboUIFFspmKE+npm1aR3vKDXbqZuNjMRxDH8RczJODmnMcIi2e2HI6cFRzJaWAXk9BDQf/oBFI8Y6nZwr6HEaEYPUo6O6kQWGFo8X0LJjrqC565XYOQQuyFi2QXReiGCvZCGb9Z+/7fHFGRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032941; c=relaxed/simple; bh=xKmiRYtJqbucxPFyXO1qbzREv9COqT6dQJyJz1PRyTM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g0f03b/fjz9ZrXrub9YRPce6qWORVNTgVp2nD9u9Zt67zd8TD2OvvjH2XOVI8nV5h0LjqQKxiAuLbwFpDQHMSKqHcyZuDdXyrnpxQV9YYezdIRJ9R8K67r5ARt3HN4bJ5owMnP0AXFHq1/Jha3hfbj3D8E82TR9rt5tlHQ5wXXw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Tg4dMFYt; arc=none smtp.client-ip=95.215.58.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Tg4dMFYt" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032937; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R9vPM/+Wp0RHQmFXmWGTKC5oYosBn2HBvZiY6RoWMuE=; b=Tg4dMFYt5FiDSWZfCXeRuGF+4W5MOaHaLgPdSg3rErfXg589Y6viUq/tIEFhblzQkrBtP6 2C8SN10+zm6mBN30G1FTzW1esg1/MyoCbuKQ8qHSNLIVZVSJDL5A8T01ta6RadQOgb8VGA kGsNjKfoZ7WBBjd6u9MJHQb6ioC/RqE= 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 19/23] KVM: selftests: Move nested MMU mapping functions outside of vmx.c Date: Tue, 21 Oct 2025 07:47:32 +0000 Message-ID: <20251021074736.1324328-20-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Now that the functions are no longer VMX-specific, move them to processor.c. Expose ept_pte_masks in vmx.h to make it accessible by __nested_map(). No functional change intended. Signed-off-by: Yosry Ahmed --- .../selftests/kvm/include/x86/processor.h | 7 ++ tools/testing/selftests/kvm/include/x86/vmx.h | 8 +- .../testing/selftests/kvm/lib/x86/processor.c | 75 +++++++++++++++++++ tools/testing/selftests/kvm/lib/x86/vmx.c | 74 ------------------ 4 files changed, 84 insertions(+), 80 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 0d6d335d309ef..13e8f4a1f589d 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1457,6 +1457,13 @@ void __virt_pg_map(struct kvm_vm *vm, vm_paddr_t roo= t_gpa, uint64_t vaddr, void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, uint64_t nr_bytes, int level); =20 +void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t nested_paddr, uint64_t paddr, uint64_t size); +void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint32_t memslot); +void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t addr, uint64_t size); + /* * Basic CPU control in CR0 */ diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/= selftests/kvm/include/x86/vmx.h index 4429e83e1f52c..b832774d99cdb 100644 --- a/tools/testing/selftests/kvm/include/x86/vmx.h +++ b/tools/testing/selftests/kvm/include/x86/vmx.h @@ -559,14 +559,10 @@ bool prepare_for_vmx_operation(struct vmx_pages *vmx); void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp); bool load_vmcs(struct vmx_pages *vmx); =20 +extern const struct pte_masks ept_pte_masks; + bool ept_1g_pages_supported(void); =20 -void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint64_t nested_paddr, uint64_t paddr, uint64_t size); -void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint32_t memslot); -void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint64_t addr, uint64_t size); bool kvm_cpu_has_ept(void); void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm); void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm= *vm); diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index caad8a9b3f067..1725f8fde2aa5 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -9,6 +9,7 @@ #include "pmu.h" #include "processor.h" #include "sev.h" +#include "vmx.h" =20 #ifndef NUM_INTERRUPTS #define NUM_INTERRUPTS 256 @@ -449,6 +450,80 @@ void virt_arch_dump(FILE *stream, struct kvm_vm *vm, u= int8_t indent) } } =20 +/* + * Map a range of EPT guest physical addresses to the VM's physical address + * + * Input Args: + * vm - Virtual Machine + * nested_paddr - Nested guest physical address to map + * paddr - VM Physical Address + * size - The size of the range to map + * level - The level at which to map the range + * + * Output Args: None + * + * Return: None + * + * Within the VM given by vm, creates a nested guest translation for the + * page range starting at nested_paddr to the page range starting at paddr. + */ +void __nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t nested_paddr, uint64_t paddr, uint64_t size, + int level) +{ + size_t page_size =3D PG_LEVEL_SIZE(level); + size_t npages =3D size / page_size; + const struct pte_masks *masks; + + masks =3D kvm_cpu_has(X86_FEATURE_VMX) ? &ept_pte_masks : &x86_pte_masks; + + TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow"); + TEST_ASSERT(paddr + size > paddr, "Paddr overflow"); + + while (npages--) { + __virt_pg_map(vm, root_gpa, nested_paddr, paddr, level, masks); + nested_paddr +=3D page_size; + paddr +=3D page_size; + } +} + +void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t nested_paddr, uint64_t paddr, uint64_t size) +{ + __nested_map(vm, root_gpa, nested_paddr, paddr, size, PG_LEVEL_4K); +} + +/* Prepare an identity extended page table that maps all the + * physical pages in VM. + */ +void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint32_t memslot) +{ + sparsebit_idx_t i, last; + struct userspace_mem_region *region =3D + memslot2region(vm, memslot); + + i =3D (region->region.guest_phys_addr >> vm->page_shift) - 1; + last =3D i + (region->region.memory_size >> vm->page_shift); + for (;;) { + i =3D sparsebit_next_clear(region->unused_phy_pages, i); + if (i > last) + break; + + nested_map(vm, root_gpa, + (uint64_t)i << vm->page_shift, + (uint64_t)i << vm->page_shift, + 1 << vm->page_shift); + } +} + +/* Identity map a region with 1GiB Pages. */ +void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t addr, uint64_t size) +{ + __nested_map(vm, root_gpa, addr, addr, size, PG_LEVEL_1G); +} + /* * Set Unusable Segment * diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index 0573b3ea717cb..1a9743cabcf4b 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -361,80 +361,6 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_r= ip, void *guest_rsp) init_vmcs_guest_state(guest_rip, guest_rsp); } =20 -/* - * Map a range of EPT guest physical addresses to the VM's physical address - * - * Input Args: - * vm - Virtual Machine - * nested_paddr - Nested guest physical address to map - * paddr - VM Physical Address - * size - The size of the range to map - * level - The level at which to map the range - * - * Output Args: None - * - * Return: None - * - * Within the VM given by vm, creates a nested guest translation for the - * page range starting at nested_paddr to the page range starting at paddr. - */ -void __nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint64_t nested_paddr, uint64_t paddr, uint64_t size, - int level) -{ - size_t page_size =3D PG_LEVEL_SIZE(level); - size_t npages =3D size / page_size; - const struct pte_masks *masks; - - masks =3D kvm_cpu_has(X86_FEATURE_VMX) ? &ept_pte_masks : &x86_pte_masks; - - TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow"); - TEST_ASSERT(paddr + size > paddr, "Paddr overflow"); - - while (npages--) { - __virt_pg_map(vm, root_gpa, nested_paddr, paddr, level, masks); - nested_paddr +=3D page_size; - paddr +=3D page_size; - } -} - -void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint64_t nested_paddr, uint64_t paddr, uint64_t size) -{ - __nested_map(vm, root_gpa, nested_paddr, paddr, size, PG_LEVEL_4K); -} - -/* Prepare an identity extended page table that maps all the - * physical pages in VM. - */ -void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint32_t memslot) -{ - sparsebit_idx_t i, last; - struct userspace_mem_region *region =3D - memslot2region(vm, memslot); - - i =3D (region->region.guest_phys_addr >> vm->page_shift) - 1; - last =3D i + (region->region.memory_size >> vm->page_shift); - for (;;) { - i =3D sparsebit_next_clear(region->unused_phy_pages, i); - if (i > last) - break; - - nested_map(vm, root_gpa, - (uint64_t)i << vm->page_shift, - (uint64_t)i << vm->page_shift, - 1 << vm->page_shift); - } -} - -/* Identity map a region with 1GiB Pages. */ -void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint64_t addr, uint64_t size) -{ - __nested_map(vm, root_gpa, addr, addr, size, PG_LEVEL_1G); -} - bool kvm_cpu_has_ept(void) { uint64_t ctrl; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (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 930382F99BE for ; Tue, 21 Oct 2025 07:49:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032942; cv=none; b=V3veMxOzYfWyIxy1+gOysbXBNF/3+ZaATfekR5CitF34yUPOZqnId7liP9TIznMjYKvlQs+B7Hc7k4hPOVoPwt34hkzzcUpFhgmeyAGq6hJxyO9pZVtvJF2iviYzbeOeQlopVWzFtAoOlrie5OQQbbaqcU1cFt14pkzYbRRp3EU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032942; c=relaxed/simple; bh=EmznAr8tmGfsTdBHmekvfG9pkapYRSGehWhfgV4sp90=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H3Rqz5yIw0M/UNbuGEUA1Q4r0oBJKiNDk6U1gSMXYH0k6wdipumQM+jeRy3i8gBnqefGT2OvL/ihNKx1lMqX4mPPMHiJGl5HAcCFpyqvW5+jdF4JW5k+MqPVN280RtgpJDQ4ZYe7CtBY/BCneJTukzakea65oPmsUQKfI2J4G8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=pKVYg/tj; arc=none smtp.client-ip=95.215.58.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="pKVYg/tj" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nN4L1HU/8fM9rmYn5HhmuTZwVxQlkWZRotXsVNYVoAk=; b=pKVYg/tjR1tdfXX+FDnTt89yFzICj/HM64BFPiG6eQ+dQLU1AmXdyQUqQ356KVHr8UQdAp 9uHmlte6E/j1ZFc7aYVQSm3Lf0lm6iBMlgGTaqJdidJYaDEZPQy+b1DksFuXLJXmm3YUO5 JxRr1JlhlzDx3VCTXavbDIbWKKAyNjo= 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 20/23] KVM: selftests: Stop passing a memslot to nested_map_memslot() Date: Tue, 21 Oct 2025 07:47:33 +0000 Message-ID: <20251021074736.1324328-21-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" On x86, KVM selftests use memslot 0 for all the default regions used by the test infrastructure. This is an implementation detail. nested_map_memslot() is currently used to map the default regions by explicitly passing slot 0, which leaks the library implementation into the caller. Rename the function to a very verbose nested_identity_map_default_memslots() to reflect what it actually does. Add an assertion that only memslot 0 is being used so that the implementation does not change from under us. No functional change intended. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/include/x86/processor.h | 3 +-- tools/testing/selftests/kvm/lib/x86/processor.c | 11 +++++++---- tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 13e8f4a1f589d..2608152b2fa27 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1459,8 +1459,7 @@ void virt_map_level(struct kvm_vm *vm, uint64_t vaddr= , uint64_t paddr, =20 void nested_map(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t nested_paddr, uint64_t paddr, uint64_t size); -void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint32_t memslot); +void nested_identity_map_default_memslots(struct kvm_vm *vm, vm_paddr_t ro= ot_gpa); void nested_identity_map_1g(struct kvm_vm *vm, vm_paddr_t root_gpa, uint64_t addr, uint64_t size); =20 diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 1725f8fde2aa5..958389ec1722d 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -496,12 +496,15 @@ void nested_map(struct kvm_vm *vm, vm_paddr_t root_gp= a, /* Prepare an identity extended page table that maps all the * physical pages in VM. */ -void nested_map_memslot(struct kvm_vm *vm, vm_paddr_t root_gpa, - uint32_t memslot) +void nested_identity_map_default_memslots(struct kvm_vm *vm, vm_paddr_t ro= ot_gpa) { + uint32_t s, memslot =3D 0; sparsebit_idx_t i, last; - struct userspace_mem_region *region =3D - memslot2region(vm, memslot); + struct userspace_mem_region *region =3D memslot2region(vm, memslot); + + /* Only memslot 0 is mapped here, ensure it's the only one being used */ + for (s =3D 0; s < NR_MEM_REGIONS; s++) + TEST_ASSERT_EQ(vm->memslots[s], 0); =20 i =3D (region->region.guest_phys_addr >> vm->page_shift) - 1; last =3D i + (region->region.memory_size >> vm->page_shift); diff --git a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c b/tools/t= esting/selftests/kvm/x86/vmx_dirty_log_test.c index e54e6111164e7..b8ebb246aaf15 100644 --- a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c @@ -121,7 +121,7 @@ static void test_vmx_dirty_log(bool enable_ept) */ if (enable_ept) { prepare_eptp(vmx, vm); - nested_map_memslot(vm, vmx->eptp_gpa, 0); + nested_identity_map_default_memslots(vm, vmx->eptp_gpa); nested_map(vm, vmx->eptp_gpa, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZ= E); nested_map(vm, vmx->eptp_gpa, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZ= E); } --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-187.mta1.migadu.com (out-187.mta1.migadu.com [95.215.58.187]) (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 823F7286897 for ; Tue, 21 Oct 2025 07:49:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032944; cv=none; b=rRj8e4j47IjBkhk2aP2zmpfKErAG28pRsX3aIXrd8cccEjJeMwXUXBcqYqCjPSlMDWY/yussv+RYqs9GpfdktoomNe+HkEEbqeCPPaXWHzYkAzh/pTua5kto3+68ThleDf/82gYed2gRIMdrJ6dPMRGkuL6bbI/RSP7BX8BtLwc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032944; c=relaxed/simple; bh=WZl+NfvTFeCIICBy80HPXyO6w6fEy2StixIcs1Ny6VM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kx67mlpJfYe+zi139ETvUWRVCnnrsI6An4HmhtXMZXd6H0SDeI3pmLvJ1VdlhDyuPilwKIeAImsIDcuJX1vWOmI94iXDzzekJqilRULRGJD5gwtg4qDxKOQmeBA0GC4yuiblmuGkf2owjR8uoAcRqVqpnhwBauxEpJdddKAcTvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Shsy/ruz; arc=none smtp.client-ip=95.215.58.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Shsy/ruz" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032940; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kJ+nTdf4y8042XWe/XSw+OeuCD1JfIcWdatLaH3A3NI=; b=Shsy/ruzjuIiopgtAiiSs+RlB9sxVVM5J0qH71bi6Z82vUS2P59ax/qN7UZmrQjf3Nr0Vr 3ov85i38X84gBqni3iWdSxBMKpXAXHxS3GCMGhSeYratWhOSM6qTCuuv/GzK35WcKxYY5W GyJD7t3ucY63vqEBoZw+Y/8UmBB9YaI= 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 21/23] KVM: selftests: Allow kvm_cpu_has_ept() to be called on AMD CPUs Date: Tue, 21 Oct 2025 07:47:34 +0000 Message-ID: <20251021074736.1324328-22-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" In preparation for generalizing the nested dirty logging test, checking if either EPT or NPT is enabled will be needed. To avoid needing to gate the kvm_cpu_has_ept() call by the CPU type, make sure the function returns false if VMX is not available instead of trying to read VMX-only MSRs. No functional change intended. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/lib/x86/vmx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/self= tests/kvm/lib/x86/vmx.c index 1a9743cabcf4b..b1f22e78aca1a 100644 --- a/tools/testing/selftests/kvm/lib/x86/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c @@ -365,6 +365,9 @@ bool kvm_cpu_has_ept(void) { uint64_t ctrl; =20 + if (!kvm_cpu_has(X86_FEATURE_VMX)) + return false; + ctrl =3D kvm_get_feature_msr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS) >> 32; if (!(ctrl & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)) return false; --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-181.mta1.migadu.com (out-181.mta1.migadu.com [95.215.58.181]) (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 5717B2FCC17 for ; Tue, 21 Oct 2025 07:49:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032946; cv=none; b=exkmk1ZNH326KCySUBtVdzZ2CNh87q3fo46a6/u0gQXgtoMAwEr7d4nGQygLhEl0En45cqAuR/UTji0cOkcdjZAItJdo5U9wxyumRFgxCcB/UUnYnZm/UkyFGzrvt2X0ATM7qxn8SWWu3DzfgGBKNu5ZmwhDaSIxBTsWA1mEU1I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032946; c=relaxed/simple; bh=mimdIqws80HVOxm1yhhjm6Tqchksppfs/5CQtKjZHfU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y7xZEO20TOR+MAW2pp9DXaoFQXwJiRe9uG9fBTZZ3mbe78fXjiH3uJQXIrIlzvzNOJA0szSblY9Xo41Mp3SlEG/s740ysp7s1DoSVCVd8TRdhqwe1yDT3YHrUY+svaNwzjlI1SI57cKxIRsGkxAB29b3o3Nww4wOdcg2wncQwKE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=xw8zX8XW; arc=none smtp.client-ip=95.215.58.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="xw8zX8XW" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032943; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VWFxHvuiWBriikDXhyh4DbqYsyF3B7/uazdqjEeTciM=; b=xw8zX8XWnCvg/+H+ajgh04dOBKzFTNGN2r2FVXLaYgqrAuF7PkWi1T0UimFIhGlBxnaYJl C62c7t48pgCtJDtnpo9QPOyeXnWu/zgEvGH++X0g8eBnK/UueXZIuhcs7380lrVF9hvgsg FV8Oisoa6bEhWcIKSWrNofNBkVjjIlc= 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 22/23] KVM: selftests: Set the user bit on nested MMU PTEs Date: Tue, 21 Oct 2025 07:47:35 +0000 Message-ID: <20251021074736.1324328-23-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Similar to KVM's shadow MMU (in most cases), set the user bit on nested PTEs. This is in preparation for supporting NPT mappings, which require the user bit to be set. This should be nop for VMX. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/lib/x86/processor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 958389ec1722d..c2912b0a49e90 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -211,7 +211,7 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *v= m, paddr =3D vm_untag_gpa(vm, paddr); =20 if (!(*pte & masks->present)) { - *pte =3D masks->present | masks->writeable | masks->x; + *pte =3D masks->present | masks->writeable | masks->x | masks->user; if (current_level =3D=3D target_level) *pte |=3D masks->large | (paddr & PHYSICAL_PAGE_MASK); else @@ -276,7 +276,7 @@ void __virt_pg_map(struct kvm_vm *vm, vm_paddr_t root_g= pa, uint64_t vaddr, pte =3D virt_get_pte(vm, root_gpa, pte, vaddr, PG_LEVEL_4K, masks); TEST_ASSERT(!(*pte & masks->present), "PTE already present for 4k page at vaddr: 0x%lx", vaddr); - *pte =3D masks->present | masks->writeable | masks->x + *pte =3D masks->present | masks->writeable | masks->x | masks->user | (paddr & PHYSICAL_PAGE_MASK); =20 /* --=20 2.51.0.869.ge66316f041-goog From nobody Wed Dec 17 14:09:09 2025 Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) (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 E70162FF16E for ; Tue, 21 Oct 2025 07:49:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032949; cv=none; b=f1XhCIcQJpjyMtOT52CxfmMTzqA243oMkuwpxsO8jqxjp9rU+MBlxTjJPmg158zBhoPIHiQCDU+pqRaEJbU1lgpIBzZtDT2WsF1JuuPzppIH9gsFApq5Dm1eAqG5xthGm6o+OfyTL6cbngBEKrOQTskKb608HBT4D9n67Po/gHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761032949; c=relaxed/simple; bh=BWjjU2HKoLpoa5fyPHPeS2e/Dk30hm1fbnvjRdjuM1o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AaDOXbc3p7bOLeGeTYa4LIqxrpgh/Aj/LIPCyIXGH8aLPNDrhE9Gr3e6vKlWf+YQt+D9IwMVbW2SpjNXQT+iN6KAZklWtsy5v7n915MeFFyeWoowveJDOUI0ngRICwQNi0uwMfPW1OehTJH50Z0d16sj6bO+VtIO2MQA/R+A+cs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=ppU0f2fb; arc=none smtp.client-ip=95.215.58.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="ppU0f2fb" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1761032945; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=43aBeNU09hJRraidYPzzQ4LCuZvZURAPpWAOqYnF9OM=; b=ppU0f2fbMfFk/9wxi4fKboQA48FVbeNvJTOjY2Prc7FPdQHFdaFwujnt2Hihh/rlOaSkv+ jRjY/BQJgVyYr6WBgdb8OEBjTrldkvcfxUcYi9iM5d2o3US4AJRWOS5lPXUIMDCUCQdgtE sV8hz0ZRTWvVfzLZhF0Ey1upvSdFw/U= 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 23/23] KVM: selftests: Extend vmx_dirty_log_test to cover SVM Date: Tue, 21 Oct 2025 07:47:36 +0000 Message-ID: <20251021074736.1324328-24-yosry.ahmed@linux.dev> In-Reply-To: <20251021074736.1324328-1-yosry.ahmed@linux.dev> References: <20251021074736.1324328-1-yosry.ahmed@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add prepare_ncr3() to initialize the nested NPTs, and enable NPT from L1 accordingly. Everything else should work for creating nested NPT mappings. Generalize the code in vmx_dirty_log_test.c by adding SVM-specific L1 code, doing some renaming (e.g. EPT -> TDP), and having setup code for both SVM and VMX in test_dirty_log(). Having multiple points to check for SVM vs VMX is not ideal, but the alternatives either include a lot of redundancy or a lot of abstracting functions that will make the test logic harder to follow. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/Makefile.kvm | 2 +- .../selftests/kvm/include/x86/svm_util.h | 8 ++ tools/testing/selftests/kvm/lib/x86/svm.c | 19 ++++ ...rty_log_test.c =3D> nested_dirty_log_test.c} | 96 +++++++++++++------ 4 files changed, 97 insertions(+), 28 deletions(-) rename tools/testing/selftests/kvm/x86/{vmx_dirty_log_test.c =3D> nested_d= irty_log_test.c} (62%) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 6625ac53545e8..5da95776fc9c2 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -114,7 +114,7 @@ TEST_GEN_PROGS_x86 +=3D x86/userspace_io_test TEST_GEN_PROGS_x86 +=3D x86/userspace_msr_exit_test TEST_GEN_PROGS_x86 +=3D x86/vmx_apic_access_test TEST_GEN_PROGS_x86 +=3D x86/close_while_nested_test -TEST_GEN_PROGS_x86 +=3D x86/vmx_dirty_log_test +TEST_GEN_PROGS_x86 +=3D x86/nested_dirty_log_test TEST_GEN_PROGS_x86 +=3D x86/vmx_exception_with_invalid_guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_msrs_test TEST_GEN_PROGS_x86 +=3D x86/vmx_invalid_nested_guest_state diff --git a/tools/testing/selftests/kvm/include/x86/svm_util.h b/tools/tes= ting/selftests/kvm/include/x86/svm_util.h index b74c6dcddcbd6..70bb22dd6de54 100644 --- a/tools/testing/selftests/kvm/include/x86/svm_util.h +++ b/tools/testing/selftests/kvm/include/x86/svm_util.h @@ -27,6 +27,11 @@ struct svm_test_data { void *msr; /* gva */ void *msr_hva; uint64_t msr_gpa; + + /* NPT */ + void *ncr3; /* gva */ + void *ncr3_hva; + uint64_t ncr3_gpa; }; =20 static inline void vmmcall(void) @@ -57,6 +62,9 @@ struct svm_test_data *vcpu_alloc_svm(struct kvm_vm *vm, v= m_vaddr_t *p_svm_gva); void generic_svm_setup(struct svm_test_data *svm, void *guest_rip, void *g= uest_rsp); void run_guest(struct vmcb *vmcb, uint64_t vmcb_gpa); =20 +bool kvm_cpu_has_npt(void); +void prepare_ncr3(struct svm_test_data *svm, struct kvm_vm *vm); + int open_sev_dev_path_or_exit(void); =20 #endif /* SELFTEST_KVM_SVM_UTILS_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/svm.c b/tools/testing/self= tests/kvm/lib/x86/svm.c index d239c20973918..190a8044dba0e 100644 --- a/tools/testing/selftests/kvm/lib/x86/svm.c +++ b/tools/testing/selftests/kvm/lib/x86/svm.c @@ -59,6 +59,20 @@ static void vmcb_set_seg(struct vmcb_seg *seg, u16 selec= tor, seg->base =3D base; } =20 +bool kvm_cpu_has_npt(void) +{ + return kvm_cpu_has(X86_FEATURE_NPT); +} + +void prepare_ncr3(struct svm_test_data *svm, struct kvm_vm *vm) +{ + TEST_ASSERT(kvm_cpu_has_npt(), "KVM doesn't support nested NPT"); + + svm->ncr3 =3D (void *)vm_vaddr_alloc_page(vm); + svm->ncr3_hva =3D addr_gva2hva(vm, (uintptr_t)svm->ncr3); + svm->ncr3_gpa =3D addr_gva2gpa(vm, (uintptr_t)svm->ncr3); +} + void generic_svm_setup(struct svm_test_data *svm, void *guest_rip, void *g= uest_rsp) { struct vmcb *vmcb =3D svm->vmcb; @@ -102,6 +116,11 @@ void generic_svm_setup(struct svm_test_data *svm, void= *guest_rip, void *guest_r vmcb->save.rip =3D (u64)guest_rip; vmcb->save.rsp =3D (u64)guest_rsp; guest_regs.rdi =3D (u64)svm; + + if (svm->ncr3_gpa) { + ctrl->nested_ctl |=3D SVM_NESTED_CTL_NP_ENABLE; + ctrl->nested_cr3 =3D svm->ncr3_gpa; + } } =20 /* diff --git a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c b/tools/t= esting/selftests/kvm/x86/nested_dirty_log_test.c similarity index 62% rename from tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c rename to tools/testing/selftests/kvm/x86/nested_dirty_log_test.c index b8ebb246aaf15..06c94e77b44bd 100644 --- a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c @@ -12,6 +12,7 @@ #include "test_util.h" #include "kvm_util.h" #include "processor.h" +#include "svm_util.h" #include "vmx.h" =20 /* The memory slot index to track dirty pages */ @@ -25,6 +26,8 @@ #define NESTED_TEST_MEM1 0xc0001000 #define NESTED_TEST_MEM2 0xc0002000 =20 +#define L2_GUEST_STACK_SIZE 64 + static void l2_guest_code(u64 *a, u64 *b) { READ_ONCE(*a); @@ -42,20 +45,19 @@ static void l2_guest_code(u64 *a, u64 *b) vmcall(); } =20 -static void l2_guest_code_ept_enabled(void) +static void l2_guest_code_tdp_enabled(void) { l2_guest_code((u64 *)NESTED_TEST_MEM1, (u64 *)NESTED_TEST_MEM2); } =20 -static void l2_guest_code_ept_disabled(void) +static void l2_guest_code_tdp_disabled(void) { - /* Access the same L1 GPAs as l2_guest_code_ept_enabled() */ + /* Access the same L1 GPAs as l2_guest_code_tdp_enabled() */ l2_guest_code((u64 *)GUEST_TEST_MEM, (u64 *)GUEST_TEST_MEM); } =20 -void l1_guest_code(struct vmx_pages *vmx) +void l1_vmx_code(struct vmx_pages *vmx) { -#define L2_GUEST_STACK_SIZE 64 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; void *l2_rip; =20 @@ -64,23 +66,51 @@ void l1_guest_code(struct vmx_pages *vmx) GUEST_ASSERT(load_vmcs(vmx)); =20 if (vmx->eptp_gpa) - l2_rip =3D l2_guest_code_ept_enabled; + l2_rip =3D l2_guest_code_tdp_enabled; else - l2_rip =3D l2_guest_code_ept_disabled; + l2_rip =3D l2_guest_code_tdp_disabled; =20 prepare_vmcs(vmx, l2_rip, &l2_guest_stack[L2_GUEST_STACK_SIZE]); =20 GUEST_SYNC(false); GUEST_ASSERT(!vmlaunch()); GUEST_SYNC(false); - GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); + GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL); + GUEST_DONE(); +} + +static void l1_svm_code(struct svm_test_data *svm) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + void *l2_rip; + + if (svm->ncr3_gpa) + l2_rip =3D l2_guest_code_tdp_enabled; + else + l2_rip =3D l2_guest_code_tdp_disabled; + + generic_svm_setup(svm, l2_rip, &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + GUEST_SYNC(false); + run_guest(svm->vmcb, svm->vmcb_gpa); + GUEST_SYNC(false); + GUEST_ASSERT_EQ(svm->vmcb->control.exit_code, SVM_EXIT_VMMCALL); GUEST_DONE(); } =20 -static void test_vmx_dirty_log(bool enable_ept) +static void l1_guest_code(void *data) { - vm_vaddr_t vmx_pages_gva =3D 0; - struct vmx_pages *vmx; + if (this_cpu_has(X86_FEATURE_VMX)) + l1_vmx_code(data); + else + l1_svm_code(data); +} + +static void test_dirty_log(bool nested_tdp) +{ + struct svm_test_data *svm =3D NULL; + struct vmx_pages *vmx =3D NULL; + vm_vaddr_t nested_gva =3D 0; unsigned long *bmap; uint64_t *host_test_mem; =20 @@ -89,12 +119,16 @@ static void test_vmx_dirty_log(bool enable_ept) struct ucall uc; bool done =3D false; =20 - pr_info("Nested EPT: %s\n", enable_ept ? "enabled" : "disabled"); + pr_info("Nested TDP: %s\n", nested_tdp ? "enabled" : "disabled"); =20 /* Create VM */ vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_code); - vmx =3D vcpu_alloc_vmx(vm, &vmx_pages_gva); - vcpu_args_set(vcpu, 1, vmx_pages_gva); + if (kvm_cpu_has(X86_FEATURE_VMX)) + vmx =3D vcpu_alloc_vmx(vm, &nested_gva); + else + svm =3D vcpu_alloc_svm(vm, &nested_gva); + + vcpu_args_set(vcpu, 1, nested_gva); =20 /* Add an extra memory slot for testing dirty logging */ vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, @@ -113,17 +147,25 @@ static void test_vmx_dirty_log(bool enable_ept) * ... pages in the L2 GPA range [0xc0001000, 0xc0003000) will map to * 0xc0000000. * - * Note that prepare_eptp should be called only L1's GPA map is done, - * meaning after the last call to virt_map. + * Note that prepare_eptp()/prepare_ncr3() should be called only when + * L1's GPA map is done, meaning after the last call to virt_map. * - * When EPT is disabled, the L2 guest code will still access the same L1 - * GPAs as the EPT enabled case. + * When TDP is disabled, the L2 guest code will still access the same L1 + * GPAs as the TDP enabled case. */ - if (enable_ept) { - prepare_eptp(vmx, vm); - nested_identity_map_default_memslots(vm, vmx->eptp_gpa); - nested_map(vm, vmx->eptp_gpa, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZ= E); - nested_map(vm, vmx->eptp_gpa, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZ= E); + if (nested_tdp) { + uint64_t root_gpa; + + if (kvm_cpu_has(X86_FEATURE_VMX)) { + prepare_eptp(vmx, vm); + root_gpa =3D vmx->eptp_gpa; + } else { + prepare_ncr3(svm, vm); + root_gpa =3D svm->ncr3_gpa; + } + nested_identity_map_default_memslots(vm, root_gpa); + nested_map(vm, root_gpa, NESTED_TEST_MEM1, GUEST_TEST_MEM, PAGE_SIZE); + nested_map(vm, root_gpa, NESTED_TEST_MEM2, GUEST_TEST_MEM, PAGE_SIZE); } =20 bmap =3D bitmap_zalloc(TEST_MEM_PAGES); @@ -168,12 +210,12 @@ static void test_vmx_dirty_log(bool enable_ept) =20 int main(int argc, char *argv[]) { - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) || kvm_cpu_has(X86_FEATURE_SVM)= ); =20 - test_vmx_dirty_log(/*enable_ept=3D*/false); + test_dirty_log(/*nested_tdp=3D*/false); =20 - if (kvm_cpu_has_ept()) - test_vmx_dirty_log(/*enable_ept=3D*/true); + if (kvm_cpu_has_ept() || kvm_cpu_has_npt()) + test_dirty_log(/*nested_tdp=3D*/true); =20 return 0; } --=20 2.51.0.869.ge66316f041-goog