From patchwork Thu Jun 8 11:34:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jinrong Liang X-Patchwork-Id: 13272157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44C3BC7EE25 for ; Thu, 8 Jun 2023 11:34:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236100AbjFHLel (ORCPT ); Thu, 8 Jun 2023 07:34:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235973AbjFHLej (ORCPT ); Thu, 8 Jun 2023 07:34:39 -0400 Received: from mail-il1-x142.google.com (mail-il1-x142.google.com [IPv6:2607:f8b0:4864:20::142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E166C1721; Thu, 8 Jun 2023 04:34:37 -0700 (PDT) Received: by mail-il1-x142.google.com with SMTP id e9e14a558f8ab-33b1e83e1daso1422625ab.0; Thu, 08 Jun 2023 04:34:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686224077; x=1688816077; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=37yFKoZm2e70geEHgnXSIVZd3bC8hUwwUl4q2cKbqZE=; b=QVis7OW0T0e24fmwfS4XCMlnUK+mfYgDce0w6O1w+k/npw5AJO11o9tqZitLvMohSJ +gS/svL3y7K2B7X+BOz63yTh55Du1EvTjC1iI/CHtTfWic4U8ljHGoDvxgPUzLUK8ZNY s9XedMV3Ilql/dpzJx1GF1rp9xmb5aD3yqtX4tBlyuE3QWz5fEcBU9AdNfCVAUFHcWu7 7lWOZ83tyLm0fXFuoK8K/b65keJynlpKY6xvDfva7VTrq4mCTNko1rHjZrnxrNnQJaCl jexeDLovDqNVqPOmIGFF3H6XHllD5dvxJmWRe35pOYnuZlWxC4UiYeD7i8Lsst3fm6NA H0cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686224077; x=1688816077; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=37yFKoZm2e70geEHgnXSIVZd3bC8hUwwUl4q2cKbqZE=; b=Q32/waLMhHs+0cBmbBMuGZaixvmaO9R9d7intoIoeUXQ9K5AOqunquB45FYmLoXLlH efurBzxc2+X+nhkn0O2T3cJqf+pCP17A6C4b/V13yVZQVFazz/R83FIJZ+LnrijcxbbH NSmL2+mYe5ILqlUcywwNlgFOxjSttlIFXn6JSa5HZRKhvGc2acewP+CtiineGkOIm6xW Mr+Ao+62cmscK+X/IBRcJbCmwi0wDBhZ6VYGGVMCxY3FveBvgmJ2M1vVi4XmNBMJ4Dfe 6dnXKrdEiZDcWLh05QtQskUABOKpVf9s2JAdSfb4u4gFCCXTzOcCpue52faVhYDf11kK OZSg== X-Gm-Message-State: AC+VfDzmhRPkfKspWeWkVbCOxjNR3BYSYC4DZ5RPLPMi6aTT+7E64GrK Zj+2YgqmTZcN0siiO/uhKjs= X-Google-Smtp-Source: ACHHUZ42OlDGTlLHy3K04uVhmeFJYpa9thyzdyXyN02sfyyUd/e4VmxIqqJum6Bbut+ibtrr9AAg7g== X-Received: by 2002:a92:da8c:0:b0:339:f9d:9f6b with SMTP id u12-20020a92da8c000000b003390f9d9f6bmr8088428iln.1.1686224076937; Thu, 08 Jun 2023 04:34:36 -0700 (PDT) Received: from CLOUDLIANG-MB2.tencent.com ([103.7.29.32]) by smtp.gmail.com with ESMTPSA id qa2-20020a17090b4fc200b002310ed024adsm2900456pjb.12.2023.06.08.04.34.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jun 2023 04:34:36 -0700 (PDT) From: Jinrong Liang X-Google-Original-From: Jinrong Liang To: Sean Christopherson Cc: Paolo Bonzini , Wanpeng Li , Like Xu , Jinrong Liang , linux-kselftest@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] KVM: selftests: Test consistency of setting MSR_IA32_DS_AREA Date: Thu, 8 Jun 2023 19:34:19 +0800 Message-Id: <20230608113420.14695-2-cloudliang@tencent.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230608113420.14695-1-cloudliang@tencent.com> References: <20230608113420.14695-1-cloudliang@tencent.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Jinrong Liang Tests have been added to this commit to check if setting MSR_IA32_DS_AREA with a non-classical address causes a fault. By verifying that KVM is correctly faulting non-classical addresses in MSR_IA32_DS_AREA, it helps ensure the accuracy and stability of the KVM subsystem. Signed-off-by: Jinrong Liang --- .../selftests/kvm/x86_64/vmx_pmu_caps_test.c | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c index 4c90f76930f9..02903084598f 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c @@ -19,6 +19,9 @@ #include "kvm_util.h" #include "vmx.h" +#define MAX_LINEAR_ADDR_MASK GENMASK_ULL(15, 8) +#define ADDR_OFS_BIT 8 + union perf_capabilities { struct { u64 lbr_format:6; @@ -232,6 +235,102 @@ static void test_lbr_perf_capabilities(union perf_capabilities host_cap) kvm_vm_free(vm); } +/* + * Generate a non-canonical address for a given number of address bits. + * @addr_bits: The number of address bits used in the system. + * + * This function calculates a non-canonical address by setting the most + * significant bit to 1 and adding an offset equal to the maximum value + * that can be represented by the remaining bits. This ensures that the + * generated address is outside the valid address range and is consistent. + */ +static inline uint64_t non_canonical_address(unsigned int addr_bits) +{ + return (1ULL << (addr_bits - 1)) + ((1ULL << (addr_bits - 1)) - 1); +} + +static uint64_t get_addr_bits(struct kvm_vcpu *vcpu) +{ + const struct kvm_cpuid_entry2 *kvm_entry; + unsigned int addr_bits; + struct kvm_sregs sregs; + + kvm_entry = get_cpuid_entry(kvm_get_supported_cpuid(), 0x80000008, 0); + addr_bits = (kvm_entry->eax & MAX_LINEAR_ADDR_MASK) >> ADDR_OFS_BIT; + /* + * Get the size of the virtual address space by checking the LA57 bit + * in the CR4 control register. If the LA57 bit is set, then the virtual + * address space is 57 bits. Otherwise, it's 48 bits. + */ + if (addr_bits != 32) { + vcpu_sregs_get(vcpu, &sregs); + addr_bits = (sregs.cr4 & X86_CR4_LA57) ? 57 : 48; + } + + return addr_bits; +} + +static void test_ds_guest_code(uint64_t bad_addr) +{ + uint8_t vector = 0; + + vector = wrmsr_safe(MSR_IA32_DS_AREA, bad_addr); + GUEST_SYNC(vector); +} + +/* Check if setting MSR_IA32_DS_AREA in guest and kvm userspace will fail. */ +static void test_ds_area_noncanonical_address(union perf_capabilities host_cap) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + unsigned int r, addr_bits; + uint64_t bad_addr, without_pebs_fmt_caps; + struct ucall uc; + + vm = vm_create_with_one_vcpu(&vcpu, test_ds_guest_code); + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vcpu); + + /* Check that Setting MSR_IA32_DS_AREA with 0 should succeed. */ + r = _vcpu_set_msr(vcpu, MSR_IA32_DS_AREA, 0); + TEST_ASSERT(r, "Setting MSR_IA32_DS_AREA with 0 should succeed."); + + /* + * Check that if PEBS_FMT is not set setting MSR_IA32_DS_AREA will + * succeed. + */ + without_pebs_fmt_caps = host_cap.capabilities & ~PERF_CAP_PEBS_FORMAT; + vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, without_pebs_fmt_caps); + r = _vcpu_set_msr(vcpu, MSR_IA32_DS_AREA, 1); + TEST_ASSERT(r, "Setting MSR_IA32_DS_AREA with bad addr should fail."); + + /* + * Check that setting MSR_IA32_DS_AREA in kvm userspace to use a + * non-canonical address should fail. + */ + vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities); + addr_bits = get_addr_bits(vcpu); + bad_addr = non_canonical_address(addr_bits); + r = _vcpu_set_msr(vcpu, MSR_IA32_DS_AREA, bad_addr); + TEST_ASSERT(!r, "Setting MSR_IA32_DS_AREA with bad addr should fail."); + + /* + * Check that setting MSR_IA32_DS_AREA in guest to use a non-canonical + * address should cause the #GP. + */ + vcpu_args_set(vcpu, 1, bad_addr); + vcpu_run(vcpu); + + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + get_ucall(vcpu, &uc); + TEST_ASSERT(uc.cmd == UCALL_SYNC, + "Received ucall other than UCALL_SYNC: %lu", uc.cmd); + TEST_ASSERT(uc.args[1] == GP_VECTOR, + "Setting MSR_IA32_DS_AREA with bad addr should fail."); + + kvm_vm_free(vm); +} + int main(int argc, char *argv[]) { union perf_capabilities host_cap; @@ -252,4 +351,5 @@ int main(int argc, char *argv[]) test_immutable_perf_capabilities(host_cap); test_guest_wrmsr_perf_capabilities(host_cap); test_lbr_perf_capabilities(host_cap); + test_ds_area_noncanonical_address(host_cap); } From patchwork Thu Jun 8 11:34:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jinrong Liang X-Patchwork-Id: 13272158 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79A7CC7EE25 for ; Thu, 8 Jun 2023 11:34:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236164AbjFHLen (ORCPT ); Thu, 8 Jun 2023 07:34:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236054AbjFHLel (ORCPT ); Thu, 8 Jun 2023 07:34:41 -0400 Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 05F5583; Thu, 8 Jun 2023 04:34:40 -0700 (PDT) Received: by mail-pl1-x644.google.com with SMTP id d9443c01a7336-1b24ff03400so2258205ad.3; Thu, 08 Jun 2023 04:34:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686224079; x=1688816079; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cxviogz62WRh4UdCAHRdGMDNc2EolqwlGW0uyOFKQOw=; b=jaKqKAvGtxaPuZtmYEGIqoY8AjqKJwG64gGMIYr+NIW0KP6ffbiNFNWuecsrYjvjKB u+8bAWp1+2IUHU/tKlSk/hwxm4+d98JLEPV53NzOD4Mt5hNa3o8OLwggdAkaZT6+GQrp OrxlNpPbRLseaMu/r4IBgy1NqnOVlyNlCtHV9lt1a+HLGThFw8I7z5ih+LAX5yi3QitQ Shl+/t4E2xGpbQD+StoC+ef3PJ4liN/uYKxnn6dgIYJvezfqjsvctkhr+unJ0NHpbVQv DoJQKzJOEhLBHY/BgjnfcqRxI0M3G6fgqWOrr03sKk9GRJLvwXJv/WAD2mfDH3uRrITR W4ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686224079; x=1688816079; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cxviogz62WRh4UdCAHRdGMDNc2EolqwlGW0uyOFKQOw=; b=O5LqWKe4mRizibQSxTu3ej4B/SepmP2Z68kdMCv5t6Upp5EijsWcY656ZUTeXeX5O4 CWf3mFfhsxSnpPW04lJZI6Qfnq8bHVLMy6mS/7pISgdWS0VJKV/XTduVjVj3jih6HRfF nmIJWx1+uE1/owLlRFM34fDVq041l4DtiRIYt4+1M6A+hkAD9i+nF1hHH/FchGxIXfGr 1Z0Bc/jrWOdQ2VTU1FR3uPFF5KJtFLIv1zCwiyH2zxKC/Qcqc7pg9u4cdbnQwYIsA4zM Y+7+nCBIzNlfXRhfqKaQbtI/Z9eAdY4h9uAlD2qPaqMLApO15daa0qsjqfaoF50u6zTj X9zA== X-Gm-Message-State: AC+VfDwerAzEbYPTiRj1K109DI+SAoODRu1uZbSwvJ5GltIf330dGcVg SYPRGwldI4GigEAS1eai9NU= X-Google-Smtp-Source: ACHHUZ7RQ9uZYrw/RqUDp/wWMVX0LPzJ/GPFPegXOQi5ILGbE0uuxNfyyV+n/ZKwuMjRp62sdsm6hQ== X-Received: by 2002:a17:902:9888:b0:1af:ffda:855a with SMTP id s8-20020a170902988800b001afffda855amr4251022plp.9.1686224079376; Thu, 08 Jun 2023 04:34:39 -0700 (PDT) Received: from CLOUDLIANG-MB2.tencent.com ([103.7.29.32]) by smtp.gmail.com with ESMTPSA id qa2-20020a17090b4fc200b002310ed024adsm2900456pjb.12.2023.06.08.04.34.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jun 2023 04:34:39 -0700 (PDT) From: Jinrong Liang X-Google-Original-From: Jinrong Liang To: Sean Christopherson Cc: Paolo Bonzini , Wanpeng Li , Like Xu , Jinrong Liang , linux-kselftest@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] KVM: selftests: Add PEBS test for MSR_IA32_PERF_CAPABILITIES Date: Thu, 8 Jun 2023 19:34:20 +0800 Message-Id: <20230608113420.14695-3-cloudliang@tencent.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230608113420.14695-1-cloudliang@tencent.com> References: <20230608113420.14695-1-cloudliang@tencent.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Jinrong Liang This commit adds a PEBS test that verifies all possible combinations of PEBS-related bits in MSR_IA32_PERF_CAPABILITIES. This comprehensive test ensures the accuracy of the PEBS feature. Signed-off-by: Jinrong Liang --- .../selftests/kvm/x86_64/vmx_pmu_caps_test.c | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c index 02903084598f..c1b1ba44bc26 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c @@ -21,6 +21,12 @@ #define MAX_LINEAR_ADDR_MASK GENMASK_ULL(15, 8) #define ADDR_OFS_BIT 8 +#define PMU_CAP_LBR_FMT 0x3f +#define PMU_CAP_SMM_FREEZE BIT_ULL(12) +#define PMU_CAP_FW_WRITES BIT_ULL(13) +#define PMU_CAP_PERF_METRICS_AVAILABLE BIT_ULL(PERF_CAP_METRICS_IDX) +#define PMU_CAP_PEBS_OUTPUT_PT_AVAIL BIT_ULL(PERF_CAP_PT_IDX) +#define PMU_CAP_PEBS_ALL (PERF_CAP_PEBS_MASK | PMU_CAP_PEBS_OUTPUT_PT_AVAIL) union perf_capabilities { struct { @@ -331,6 +337,70 @@ static void test_ds_area_noncanonical_address(union perf_capabilities host_cap) kvm_vm_free(vm); } +static void test_pebs_bit_combinations(union perf_capabilities host_cap) +{ + int ret; + uint64_t pebs_val, val; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm = vm_create_with_one_vcpu(&vcpu, NULL); + + TEST_REQUIRE(kvm_cpu_property(X86_PROPERTY_PMU_VERSION) > 1); + TEST_REQUIRE(host_cap.capabilities & PERF_CAP_PEBS_FORMAT); + TEST_REQUIRE(vcpu_get_msr(vcpu, MSR_IA32_MISC_ENABLE) & + MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL); + + /* + * Test if PEBS_REC_FMT is set and the value is the same as host, + * the other PEBS bits are allowed to be set only if they are the + * same as host. + */ + pebs_val = host_cap.capabilities & PMU_CAP_PEBS_ALL; + + vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, pebs_val); + ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), + (u64)pebs_val); + + /* Test all PEBS bit combinations. */ + for (val = 0x0; val <= (~0ul & PMU_CAP_PEBS_ALL); val++) { + /* Skips values that are not related to PEBS. */ + if (val & (PMU_CAP_LBR_FMT | PMU_CAP_SMM_FREEZE | + PMU_CAP_FW_WRITES | PMU_CAP_PERF_METRICS_AVAILABLE)) + continue; + + /* + * Test that value of PEBS is rejected when the KVM doesn't + * supports Intel PT. + */ + if ((val & PMU_CAP_PEBS_OUTPUT_PT_AVAIL) && + (!(host_cap.capabilities & PMU_CAP_PEBS_OUTPUT_PT_AVAIL))) { + ret = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val); + TEST_ASSERT(!ret, "Bad PEBS auxiliary bits = 0x%lx didn't fail", val); + + continue; + } + + /* + * Test that value of PEBS is rejected when carrying + * PEBS_REC_FMT if the value of PEBS is not equal to host. + */ + if ((val & PERF_CAP_PEBS_FORMAT) && val != pebs_val) { + ret = _vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val); + TEST_ASSERT(!ret, "Bad PEBS auxiliary bits = 0x%lx didn't fail", val); + + continue; + } + + /* + * Test that PEBS bits can be written simultaneously or + * independently if PEBS_REC_FMT is not carried. + */ + vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, val); + ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_PERF_CAPABILITIES), val); + } + + kvm_vm_free(vm); +} + int main(int argc, char *argv[]) { union perf_capabilities host_cap; @@ -352,4 +422,5 @@ int main(int argc, char *argv[]) test_guest_wrmsr_perf_capabilities(host_cap); test_lbr_perf_capabilities(host_cap); test_ds_area_noncanonical_address(host_cap); + test_pebs_bit_combinations(host_cap); }