From nobody Mon Feb 9 07:54:52 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27FF52E7BC7 for ; Fri, 12 Sep 2025 23:24:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757719477; cv=none; b=vB4SpdXEDFE4XrjlLcpCKJIkCINd7uVgNgxSNKw3EIgDR+age+r0A5W0gT3XkclGwPKwBqz79+i+u0am1JSTn1OsXGY6aMJS3xVvTLlT3dBG59RLJa5sXOdGPRChCGLablOxgUz5g1U8izQW2MGyr76g1gbPFzl1s+7v7ohliCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757719477; c=relaxed/simple; bh=2wjGULkmS/6PwRSQm8osqaxXFXmRY0fiL5uBUNzOoGg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ZmLpDT3XqG2+nd7zXy+u6uhwTgRBoDUXQ5hVOnv0YQ9ZwbaoNLL7bBmQQl3NRdQRPIbGpdBLL+CfPvVCgIyslh0asnDqzluj1jQx2OY1iheCcRmnZ2K7Qow9r4UPa6RfMMb1bib70WRqFOevsvMP4w/dD3FJLQuoWAQIXXHeb7w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=UzdDs0Up; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="UzdDs0Up" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b54ac2658acso1040685a12.1 for ; Fri, 12 Sep 2025 16:24:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757719475; x=1758324275; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=zRTuC+/aMJy18zeUD9dpYx1dSaF5QGiJuAN55i0w7BI=; b=UzdDs0Uptb+D/xhaHbru0ON/EqdbgltGXbOqHkt7Zx08pQ9NGx0afOyZAhunYC3i2i jQFrUj4O2lvox1CrS+VcRgoOPmTU8sdx4jT48DE6h/LbxuCrdeDe6EXWLfJ2x4MTB6fo D73irkEBgoiyTel/sLT1UIXVj+idVGAjCW/TlxQ5N5DhX/UJDUVZkrP8X/XesTUJz9Po wUhfJaEta91YpduGThwT/nulg41bIt73IZtIQrWSoSoVhgE9xgiM0pxyir06TM75wjTJ F46mK4xCEiEZrXWZjcLlJuttrnhisxOgSqj44ie4jKaLeMgUxeXsfl9v3ErszLU9kXqc +0CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757719475; x=1758324275; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=zRTuC+/aMJy18zeUD9dpYx1dSaF5QGiJuAN55i0w7BI=; b=TAiE9u3x4zq9jtmwoZOQ18wsNQl32XxhfRyJ87TjpA/W7cCbM0r03knk0MzTvjoCnn kNkmvwQzI1/zpyapDQroYRqv7rZxxUSPW6fNniWH6g9SGwkI9lN4jMHEj24r1igThIXc TMpgY+NVdjTF4Oc3BPZwE1KLMsaTEOKB+SwDxqmgKB7RbF5QxFzw13FLGD+fvyl2QqqE NaBmlYY2uHkbgiSf9zGWaGJRON4KG6DbIWB3PPep0AvXS1JWg/ccS4FEkvsJHG4y/gFo HhHGO8JZ6dxlL1yg6ymyKLCVZzmbZ4qHJ9hyWWzhYlCDwHdr9gtkVB6Dvi5msKzz7FCB HtGw== X-Forwarded-Encrypted: i=1; AJvYcCVkBiDk4WlX25OmitVufj2JGEu2B1l00+ztmxClmRF3Lg4Jp8zz6uPkiiMT1eWBo8OU/amX8OdxhGGBvcQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwwVAL4F5EBa0TWNWMRNvwfLlOhKA0RIA3uNXuNZFP5gIr6KLDZ 95xL6sLDEadqMnTRQANa2Pe2mXQjlluP6EzgUHiLduYuGLBfvPuhLHuaeBBFKoAKM3VOIVkdKna IbfNGbw== X-Google-Smtp-Source: AGHT+IGsu99kW011YxagBqZtOacoDUyKS0gh7c2D27eBAO6VPWe3gQBMghuflC0M7c+1GCHeLayGgWXbLRo= X-Received: from pgha19.prod.google.com ([2002:a63:d413:0:b0:b54:ace3:bd08]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7d9f:b0:249:9c7a:7702 with SMTP id adf61e73a8af0-2602c243603mr6351072637.36.1757719474660; Fri, 12 Sep 2025 16:24:34 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 12 Sep 2025 16:23:17 -0700 In-Reply-To: <20250912232319.429659-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250912232319.429659-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.384.g4c02a37b29-goog Message-ID: <20250912232319.429659-40-seanjc@google.com> Subject: [PATCH v15 39/41] KVM: selftests: Add coverate for KVM-defined registers in MSRs test From: Sean Christopherson To: Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Tom Lendacky , Mathias Krause , John Allen , Rick Edgecombe , Chao Gao , Maxim Levitsky , Xiaoyao Li , Zhang Yi Z Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add test coverage for the KVM-defined GUEST_SSP "register" in the MSRs test. While _KVM's_ goal is to not tie the uAPI of KVM-defined registers to any particular internal implementation, i.e. to not commit in uAPI to handling GUEST_SSP as an MSR, treating GUEST_SSP as an MSR for testing purposes is a-ok and is a naturally fit given the semantics of SSP. Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/x86/msrs_test.c | 97 ++++++++++++++++++++- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/msrs_test.c b/tools/testing/se= lftests/kvm/x86/msrs_test.c index 53e155ba15d4..6a956cfe0c65 100644 --- a/tools/testing/selftests/kvm/x86/msrs_test.c +++ b/tools/testing/selftests/kvm/x86/msrs_test.c @@ -17,9 +17,10 @@ struct kvm_msr { const u64 write_val; const u64 rsvd_val; const u32 index; + const bool is_kvm_defined; }; =20 -#define ____MSR_TEST(msr, str, val, rsvd, reset, feat, f2) \ +#define ____MSR_TEST(msr, str, val, rsvd, reset, feat, f2, is_kvm) \ { \ .index =3D msr, \ .name =3D str, \ @@ -28,10 +29,11 @@ struct kvm_msr { .reset_val =3D reset, \ .feature =3D X86_FEATURE_ ##feat, \ .feature2 =3D X86_FEATURE_ ##f2, \ + .is_kvm_defined =3D is_kvm, \ } =20 #define __MSR_TEST(msr, str, val, rsvd, reset, feat) \ - ____MSR_TEST(msr, str, val, rsvd, reset, feat, feat) + ____MSR_TEST(msr, str, val, rsvd, reset, feat, feat, false) =20 #define MSR_TEST_NON_ZERO(msr, val, rsvd, reset, feat) \ __MSR_TEST(msr, #msr, val, rsvd, reset, feat) @@ -40,7 +42,7 @@ struct kvm_msr { __MSR_TEST(msr, #msr, val, rsvd, 0, feat) =20 #define MSR_TEST2(msr, val, rsvd, feat, f2) \ - ____MSR_TEST(msr, #msr, val, rsvd, 0, feat, f2) + ____MSR_TEST(msr, #msr, val, rsvd, 0, feat, f2, false) =20 /* * Note, use a page aligned value for the canonical value so that the value @@ -51,6 +53,9 @@ static const u64 canonical_val =3D 0x123456789000ull; #define MSR_TEST_CANONICAL(msr, feat) \ __MSR_TEST(msr, #msr, canonical_val, NONCANONICAL, 0, feat) =20 +#define MSR_TEST_KVM(msr, val, rsvd, feat) \ + ____MSR_TEST(KVM_REG_ ##msr, #msr, val, rsvd, 0, feat, feat, true) + /* * The main struct must be scoped to a function due to the use of structur= es to * define features. For the global structure, allocate enough space for t= he @@ -156,6 +161,83 @@ static void guest_main(void) static bool has_one_reg; static bool use_one_reg; =20 +#define KVM_X86_MAX_NR_REGS 1 + +static bool vcpu_has_reg(struct kvm_vcpu *vcpu, u64 reg) +{ + struct { + struct kvm_reg_list list; + u64 regs[KVM_X86_MAX_NR_REGS]; + } regs =3D {}; + int r, i; + + /* + * If KVM_GET_REG_LIST succeeds with n=3D0, i.e. there are no supported + * regs, then the vCPU obviously doesn't support the reg. + */ + r =3D __vcpu_ioctl(vcpu, KVM_GET_REG_LIST, ®s.list.n); + if (!r) + return false; + + TEST_ASSERT_EQ(errno, E2BIG); + + /* + * KVM x86 is expected to support enumerating a relative small number + * of regs. The majority of registers supported by KVM_{G,S}ET_ONE_REG + * are enumerated via other ioctls, e.g. KVM_GET_MSR_INDEX_LIST. For + * simplicity, hardcode the maximum number of regs and manually update + * the test as necessary. + */ + TEST_ASSERT(regs.list.n <=3D KVM_X86_MAX_NR_REGS, + "KVM reports %llu regs, test expects at most %u regs, stale test?", + regs.list.n, KVM_X86_MAX_NR_REGS); + + vcpu_ioctl(vcpu, KVM_GET_REG_LIST, ®s.list.n); + for (i =3D 0; i < regs.list.n; i++) { + if (regs.regs[i] =3D=3D reg) + return true; + } + + return false; +} + +static void host_test_kvm_reg(struct kvm_vcpu *vcpu) +{ + bool has_reg =3D vcpu_cpuid_has(vcpu, msrs[idx].feature); + u64 reset_val =3D msrs[idx].reset_val; + u64 write_val =3D msrs[idx].write_val; + u64 rsvd_val =3D msrs[idx].rsvd_val; + u32 reg =3D msrs[idx].index; + u64 val; + int r; + + if (!use_one_reg) + return; + + TEST_ASSERT_EQ(vcpu_has_reg(vcpu, KVM_X86_REG_KVM(reg)), has_reg); + + if (!has_reg) { + r =3D __vcpu_get_reg(vcpu, KVM_X86_REG_KVM(reg), &val); + TEST_ASSERT(r && errno =3D=3D EINVAL, + "Expected failure on get_reg(0x%x)", reg); + rsvd_val =3D 0; + goto out; + } + + val =3D vcpu_get_reg(vcpu, KVM_X86_REG_KVM(reg)); + TEST_ASSERT(val =3D=3D reset_val, "Wanted 0x%lx from get_reg(0x%x), got 0= x%lx", + reset_val, reg, val); + + vcpu_set_reg(vcpu, KVM_X86_REG_KVM(reg), write_val); + val =3D vcpu_get_reg(vcpu, KVM_X86_REG_KVM(reg)); + TEST_ASSERT(val =3D=3D write_val, "Wanted 0x%lx from get_reg(0x%x), got 0= x%lx", + write_val, reg, val); + +out: + r =3D __vcpu_set_reg(vcpu, KVM_X86_REG_KVM(reg), rsvd_val); + TEST_ASSERT(r, "Expected failure on set_reg(0x%x, 0x%lx)", reg, rsvd_val); +} + static void host_test_msr(struct kvm_vcpu *vcpu, u64 guest_val) { u64 reset_val =3D msrs[idx].reset_val; @@ -265,6 +347,8 @@ static void test_msrs(void) MSR_TEST(MSR_IA32_PL2_SSP, canonical_val, canonical_val | 1, SHSTK), MSR_TEST_CANONICAL(MSR_IA32_PL3_SSP, SHSTK), MSR_TEST(MSR_IA32_PL3_SSP, canonical_val, canonical_val | 1, SHSTK), + + MSR_TEST_KVM(GUEST_SSP, canonical_val, NONCANONICAL, SHSTK), }; =20 const struct kvm_x86_cpu_feature feat_none =3D X86_FEATURE_NONE; @@ -280,6 +364,7 @@ static void test_msrs(void) const int NR_VCPUS =3D 3; struct kvm_vcpu *vcpus[NR_VCPUS]; struct kvm_vm *vm; + int i; =20 kvm_static_assert(sizeof(__msrs) <=3D sizeof(msrs)); kvm_static_assert(ARRAY_SIZE(__msrs) <=3D ARRAY_SIZE(msrs)); @@ -307,6 +392,12 @@ static void test_msrs(void) } =20 for (idx =3D 0; idx < ARRAY_SIZE(__msrs); idx++) { + if (msrs[idx].is_kvm_defined) { + for (i =3D 0; i < NR_VCPUS; i++) + host_test_kvm_reg(vcpus[i]); + continue; + } + sync_global_to_guest(vm, idx); =20 vcpus_run(vcpus, NR_VCPUS); --=20 2.51.0.384.g4c02a37b29-goog