From patchwork Fri Oct 20 21:40:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 13431217 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C5E31C25B41 for ; Fri, 20 Oct 2023 21:41:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:Message-ID: Mime-Version:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=dpru/7Wmj6MeOfblyb6gD8b6vPByEvxBwG4kp14KyOE=; b=pH6 X7rSw4FQCeaNtva9ZXbsXX7BTIdslKWgsieIqGKJFvCEFcuomUcceqbfuMMgeGZM5z1V857sTSZHW B2ifExviuiMOGa9rl4EiXebF7fZ0luVJRJ3oVxe+UNff8a7fTi1+//blODNbSkH6a9VfR//5SGPar WwFU3ARLgboYihPqcm9ah0REWToZNu78JP5WN+V0aFSM0ucG82A8vZf9pJxGNQ49m5T3w/xGeVCa+ GdaVn9/eZ9PqYiL7AgYn3sEZnbkZFZNWP1/boSR+E0db6UPrRn2dAg5hYQ4f/2uPepaCFN4O8M/TR 5uz3yZmsTWLu3ef7N8l3q8IEp/BxHrg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qtxEx-0034I1-1W; Fri, 20 Oct 2023 21:41:07 +0000 Received: from mail-oi1-x24a.google.com ([2607:f8b0:4864:20::24a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qtxEp-0034Fe-2q for linux-arm-kernel@lists.infradead.org; Fri, 20 Oct 2023 21:41:05 +0000 Received: by mail-oi1-x24a.google.com with SMTP id 5614622812f47-3b3447c72c4so2089683b6e.1 for ; Fri, 20 Oct 2023 14:40:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1697838057; x=1698442857; darn=lists.infradead.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=9uyJIMwTKYCyWOffk6DDwTmldfLUB0YlKCSR4JSJIpA=; b=2TOzNvF52SEZ8ZuDBC3eXycf4PIvSHEWy2wuum9au3UkDFmtYxEfLXX7oVd/6iD4N7 bXNGxWHx1Jiic7uimyPDPvoGLdjXJws+zMqwzaG80wygMuELKLA923xQYxnbnpWKuAb2 7rq7M4pvXdV1+x/Ors9REPtSUzdTdzybDOosEbEvRJoOioZvTZHnVy/JmyHeoKn66A0u 42P9zEUAvxgHjeSxhTLxEx4Ea9Hto0b2dDQaY72fdJ47EKGdyn0SBz701rvuRgLoM/Iq VmvIflAcPrq+ewoZlmIT8YH/yOpDEd7GsY2m2Ge0EmWNU06zi4YIphHQyqluYZTgChqE 0VVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697838057; x=1698442857; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=9uyJIMwTKYCyWOffk6DDwTmldfLUB0YlKCSR4JSJIpA=; b=BbhaMVqhOTb3KUsqExCOO40bsuB+XVMHpXV/cR8PcR4uoowK4VeIKZQQuLpWgj8xO3 jbANHopTqC9l0wvj4JFhQXgydti3HJH1IEKQKIQD2iZCLiuU/gSj8WWgwvxupWISGhOM GKbP4Swh3pfPPwMrDB2xOwnR0OQSDXP37mIopc95oFMmhPDwZNSH1mPQn6w4B3LH/Vn5 43X7TZJ+Sy4Hoz44Q7J1ccldT+BJHA+2dL5Lau6+zNsMuToySgCJtyaj5Tg04hYs6ioO 5spiYWg0eoX1L2S+K261XmIIHKqDKte4M5GoeY0p+wfWhNeIFH68ezY4cIZIPJoxNsO5 J5lg== X-Gm-Message-State: AOJu0YyduDehthtf17b+ThPa/pvjmI/YNI+phZRy///IwRQswh5bh0uz C5sBAxuxBv7K70NIYO26C2oA1GBRvNVZ X-Google-Smtp-Source: AGHT+IEVJCO6jjS10yQjQNjSGC21aaOcD4Beut4oHBDK6jrEqw40q2pxVUdIyGgKdLHvaRO+kKxVcl4Nm5I0 X-Received: from rananta-linux.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:20a1]) (user=rananta job=sendgmr) by 2002:a05:6808:308f:b0:3ae:2710:cf87 with SMTP id bl15-20020a056808308f00b003ae2710cf87mr1055498oib.7.1697838056993; Fri, 20 Oct 2023 14:40:56 -0700 (PDT) Date: Fri, 20 Oct 2023 21:40:40 +0000 Mime-Version: 1.0 X-Mailer: git-send-email 2.42.0.655.g421f12c284-goog Message-ID: <20231020214053.2144305-1-rananta@google.com> Subject: [PATCH v8 00/13] KVM: arm64: PMU: Allow userspace to limit the number of PMCs on vCPU From: Raghavendra Rao Ananta To: Oliver Upton , Marc Zyngier Cc: Alexandru Elisei , James Morse , Suzuki K Poulose , Paolo Bonzini , Zenghui Yu , Shaoqin Huang , Jing Zhang , Reiji Watanabe , Colton Lewis , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231020_144059_944538_AEB1E764 X-CRM114-Status: GOOD ( 33.52 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hello, The goal of this series is to allow userspace to limit the number of PMU event counters on the vCPU. We need this to support migration across systems that implement different numbers of counters. The number of PMU event counters is indicated in PMCR_EL0.N. For a vCPU with PMUv3 configured, its value will be the same as the current PE by default. Userspace can set PMCR_EL0.N for the vCPU to any value even with the current KVM using KVM_SET_ONE_REG. However, it is practically unsupported, as KVM resets PMCR_EL0.N to the host value on vCPU reset and some KVM code uses the host value to identify (un)implemented event counters on the vCPU. This series will ensure that the PMCR_EL0.N value is preserved on vCPU reset and that KVM doesn't use the host value to identify (un)implemented event counters on the vCPU. This allows userspace to limit the number of the PMU event counters on the vCPU. The series is based on kvmarm/next @0a3a1665cbc59 to include the vCPU reset and feature flags cleanup/fixes series [1] and the new sysreg definitions [2] that the selftests in this series utilizes. Patch 1 adds helper functions to set a PMU for the guest. This helper will make it easier for the following patches to add modify codes for that process. Patch 2 makes the default PMU for the guest set before the first vCPU reset. Patch 3 adds a helper to read vCPU's PMCR_EL0. Patch 4 changes the code to use the guest's PMCR_EL0.N, instead of the PE's PMCR_EL0.N. Patch 5 adds userspace handlers for PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} to consider the guest's PMCR.N. Patch 6 sanitizes the PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} registers before the first run of the guest based on the number of counters configured. Patch 7 adds support userspace modifying PMCR_EL0.N. Patch 8-13 adds a selftest to verify reading and writing PMU registers for implemented or unimplemented PMU event counters on the vCPU. v8: Thanks, Oliver, Sebastian, and Eric for suggestions - Drop v7 patches 3 and 4, and bring back initializing the PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} registers with unknown values. (Eric) - Implement {get,set}_user callbacks for PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} registers. (Oliver) - Sanitize PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} registers before starting the first vCPU run. (Oliver) - Rename kvm_vcpu_set_pmu() to kvm_setup_vcpu(). (Oliver) - Rename kvm_arm_get_num_counters() to kvm_arm_pmu_get_max_counters() and squash it into the caller's patch. (Oliver) - In set_pmcr() implementation, do not initialize the pmcr register with kvm_vcpu_read_pmcr(). (Oliver) - Introduce test_create_vpmu_vm_with_pmcr_n() in the selftest to carry the commonly used code of creating a VM and configuring its PMCR.N field. (Eric) - Add a selftest scenario to check the immutable behavior of the registers. (Sebastian) - Add a selftest scenario to check the valid behavior of PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} registers when accessed from userspace. - Address other nits. v7: Thanks, Oliver for the suggestions - Rebase the series onto kvmarm/next. - Move the logic to set the default PMU for the guest from kvm_reset_vcpu() to __kvm_vcpu_set_target() to deal with the error returned. - Add a helper, kvm_arm_get_num_counters(), to read the number of general-purpose counters. - Use this helper to fix the error reported by kernel test robot [3]. v6: Thanks, Oliver and Shaoqin for the suggestions - Split the previously defined kvm_arm_set_vm_pmu() into separate functions: default arm_pmu and a caller requested arm_pmu. - Send -EINVAL from kvm_reset_vcpu(), instead of -ENODEV for the case where KVM fails to set a default arm_pmu, to remain consistent with the existing behavior. - Drop the v5 patch-5/12 that removes ARMV8_PMU_PMCR_N_MASK and adds ARMV8_PMU_PMCR_N. Make corresponding changes to v5 patch-6/12. - Disregard introducing 'pmcr_n_limit' in kvm->arch as a member to be accessed later in 'set_pmcr()'. Instead, directly obtain the value by accessing the saved 'arm_pmu'. - 'set_pmcr()' ignores the error when userspace tries to set PMCR.N greater than the hardware limit to keep the existing API behavior. - 'set_pmcr()' ignores modifications to the register after the VM has started and returns a success to userspace. - Introduce [get|set]_pmcr_n() helpers in the selftest to make modifications to the field easier. - Define the 'vpmu_vm' globally in the selftest, instead of allocating it every time a VM is created. - Use the new printf style __GUEST_ASSERT()s in the selftest. v5: https://lore.kernel.org/all/20230817003029.3073210-1-rananta@google.com/ - Drop the patches (v4 3,4) related to PMU version fixes as it's now being handled in a separate series [4]. - Switch to config_lock, instead of kvm->lock, while configuring the guest PMU. - Instead of continuing after a WARN_ON() for the return value of kvm_arm_set_vm_pmu() in kvm_arm_pmu_v3_set_pmu(), patch-1 now returns from the function immediately with the error code. - Fix WARN_ON() logic in kvm_host_pmu_init() (patch v4 9/14). - Instead of returning 0, return -ENODEV from the kvm_arm_set_vm_pmu() stub function. - Do not define the PMEVN_CASE() and PMEVN_SWITCH() macros in the selftest code as they are now included in the imported arm_pmuv3.h header. - Since the (initial) purpose of the selftest is to test the accessibility of the counter registers, remove the functional test at the end of test_access_pmc_regs(). It'll be added later in a separate series. - Introduce additional helper functions (destroy_vpmu_vm(), PMC_ACC_TO_IDX()) in the selftest for ease of maintenance and debugging. v4: https://lore.kernel.org/all/20230211031506.4159098-1-reijiw@google.com/ - Fix the selftest bug in patch 13 (Have test_access_pmc_regs() to specify pmc index for test_bitmap_pmu_regs() instead of bit-shifted value (Thank you Raghavendra for the reporting the issue!). v3: https://lore.kernel.org/all/20230203040242.1792453-1-reijiw@google.com/ - Remove reset_pmu_reg(), and use reset_val() instead. [Marc] - Fixed the initial value of PMCR_EL0.N on heterogeneous PMU systems. [Oliver] - Fixed PMUVer issues on heterogeneous PMU systems. - Fixed typos [Shaoqin] v2: https://lore.kernel.org/all/20230117013542.371944-1-reijiw@google.com/ - Added the sys_reg's set_user() handler for the PMCR_EL0 to disallow userspace to set PMCR_EL0.N for the vCPU to a value that is greater than the host value (and added a new test case for this behavior). [Oliver] - Added to the commit log of the patch 2 that PMUSERENR_EL0 and PMCCFILTR_EL0 have UNKNOWN reset values. v1: https://lore.kernel.org/all/20221230035928.3423990-1-reijiw@google.com/ Thank you. Raghavendra [1]: https://lore.kernel.org/all/20230920195036.1169791-1-oliver.upton@linux.dev/ [2]: https://lore.kernel.org/all/20231011195740.3349631-5-oliver.upton@linux.dev/ [3]: https://lore.kernel.org/all/202309290607.Qgg05wKw-lkp@intel.com/ [4]: https://lore.kernel.org/all/20230728181907.1759513-1-reijiw@google.com/ Raghavendra Rao Ananta (6): KVM: arm64: PMU: Set PMCR_EL0.N for vCPU based on the associated PMU KVM: arm64: Add {get,set}_user for PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} KVM: arm64: Sanitize PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} before first run tools: Import arm_pmuv3.h KVM: selftests: aarch64: vPMU test for validating user accesses KVM: selftests: aarch64: vPMU test for immutability Reiji Watanabe (7): KVM: arm64: PMU: Introduce helpers to set the guest's PMU KVM: arm64: PMU: Set the default PMU for the guest before vCPU reset KVM: arm64: PMU: Add a helper to read a vCPU's PMCR_EL0 KVM: arm64: PMU: Allow userspace to limit PMCR_EL0.N for the guest KVM: selftests: aarch64: Introduce vpmu_counter_access test KVM: selftests: aarch64: vPMU register test for implemented counters KVM: selftests: aarch64: vPMU register test for unimplemented counters arch/arm64/include/asm/kvm_host.h | 3 + arch/arm64/kvm/arm.c | 22 +- arch/arm64/kvm/pmu-emul.c | 112 ++- arch/arm64/kvm/sys_regs.c | 180 ++++- include/kvm/arm_pmu.h | 20 + tools/include/perf/arm_pmuv3.h | 308 ++++++++ tools/testing/selftests/kvm/Makefile | 1 + .../kvm/aarch64/vpmu_counter_access.c | 726 ++++++++++++++++++ .../selftests/kvm/include/aarch64/processor.h | 1 + 9 files changed, 1319 insertions(+), 54 deletions(-) create mode 100644 tools/include/perf/arm_pmuv3.h create mode 100644 tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c base-commit: 0a3a1665cbc59ee8d6326aa6c0b4a8d1cd67dda3