From patchwork Thu Jan 27 16:20:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727027 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 86B95C433F5 for ; Thu, 27 Jan 2022 16:22:30 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=8I7CbslfJA5stmDgx+lbgTiEUnBlq6tAiub0OiSBHUU=; b=Q7v6E1q2yP64MB XvC6phLku+EeJdAHNVB6T2dKE/83Dx3l8YH59xBfLgwq31uG9yHLlJ3lJCAWs1XAksJ0SYN1PEB7x qq92MyFjPRO7Pu7HcrcDevJbNbub0E62EdxWUd4s68+kH2YKNOUrRlDfgu6S+QU2UAeSksQ6WTuYd 0pdD3a2JYWxlmC4406tAlixkAHKLzHwqXwVREvH/TTwYpgeXmAc4HrfWHw2DKIEE9d6eEqYt7NH0K FBceZ5JSgV1LHYSqD9bv62zsAxU/xhC5nhIEPb1t+ng0jrTz5BWo6yf6OYH1elm4b2GwubJhWn5yg xXxhnc1W75JFUUaCSz0w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7WC-00GRzP-GF; Thu, 27 Jan 2022 16:21:04 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vc-00GRl6-Dg for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:29 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D4399113E; Thu, 27 Jan 2022 08:20:27 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 660703F766; Thu, 27 Jan 2022 08:20:25 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 01/10] linux/err.h: Add missing stdbool.h include Date: Thu, 27 Jan 2022 16:20:24 +0000 Message-Id: <20220127162033.54290-2-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082028_545086_2393438C X-CRM114-Status: UNSURE ( 8.03 ) X-CRM114-Notice: Please train this message. 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 Add missing header stdbool.h to avoid errors like this one, which can happen if the including file doesn't include stdbool.h: include/linux/err.h:33:15: error: type defaults to ‘int’ in declaration of ‘bool’ [-Werror=implicit-int] 33 | static inline bool __must_check IS_ERR(__force const void *ptr) | ^~~~ include/linux/err.h:33:15: error: variable ‘bool’ declared ‘inline’ [-Werror] include/linux/err.h:33:1: error: ‘warn_unused_result’ attribute only applies to function types [-Werror=attributes] 33 | static inline bool __must_check IS_ERR(__force const void *ptr) | ^~~~~~ include/linux/err.h:33:33: error: expected ‘,’ or ‘;’ before ‘IS_ERR’ 33 | static inline bool __must_check IS_ERR(__force const void *ptr) | ^~~~~~ include/linux/err.h:38:15: error: type defaults to ‘int’ in declaration of ‘bool’ [-Werror=implicit-int] 38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) | ^~~~ include/linux/err.h:38:15: error: variable ‘bool’ declared ‘inline’ [-Werror] include/linux/err.h:38:1: error: ‘warn_unused_result’ attribute only applies to function types [-Werror=attributes] 38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) | ^~~~~~ include/linux/err.h:38:15: error: redundant redeclaration of ‘bool’ [-Werror=redundant-decls] 38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) | ^~~~ include/linux/err.h:33:15: note: previous declaration of ‘bool’ was here 33 | static inline bool __must_check IS_ERR(__force const void *ptr) | ^~~~ include/linux/err.h:38:33: error: expected ‘,’ or ‘;’ before ‘IS_ERR_OR_NULL’ 38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) | ^~~~~~~~~~~~~~ include/linux/err.h: In function ‘PTR_ERR_OR_ZERO’: include/linux/err.h:58:6: error: implicit declaration of function ‘IS_ERR’ [-Werror=implicit-function-declaration] 58 | if (IS_ERR(ptr)) | ^~~~~~ include/linux/err.h:58:6: error: nested extern declaration of ‘IS_ERR’ [-Werror=nested-externs] Signed-off-by: Alexandru Elisei --- include/linux/err.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/err.h b/include/linux/err.h index a729120644d5..1256c7abfefa 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -1,6 +1,8 @@ #ifndef _LINUX_ERR_H #define _LINUX_ERR_H +#include + #include #include From patchwork Thu Jan 27 16:20:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727028 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 ABAABC433EF for ; Thu, 27 Jan 2022 16:22:40 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OB3TpkzBJii4ibWvhYUY92ccqK7hQMFqfN6FiSm94JE=; b=h7MLJidcG7batR 51djpzgPuyc+c1+4CxALbfbi0zjQuxY4JQTF1ymLjCGW3VRgl8tA6HDDKYzKvDem4DDucAd4055Iw DaPUEfU/kar5bmLvRYPlt63mA+NGGVsug6B2fUukv1MIcfOW3hsoZ5OY092vVSvLHUpb4XJso8mZE QNpHk3zwEZKcSrSo7rVq+ktZuzUjTpXFONdIGQK8hy7uD6m9+ACeaYjSAyD560YOPN3pJLC8war/O V9oa4EKR62NnImaDWs6yXLwmms/OwMCUilh86Tmv3aQtOORXRfgJElYUKq6/SCS9WDr5RbgHZy2rO JSYeM+k18zu5Ror1AVJg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7WU-00GS6N-MR; Thu, 27 Jan 2022 16:21:22 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Ve-00GRmh-KW for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:32 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AD6A41063; Thu, 27 Jan 2022 08:20:29 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 21C193F766; Thu, 27 Jan 2022 08:20:27 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 02/10] bitops.h: Include wordsize.h to provide the __WORDSIZE define Date: Thu, 27 Jan 2022 16:20:25 +0000 Message-Id: <20220127162033.54290-3-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082030_785107_BCAC7906 X-CRM114-Status: UNSURE ( 9.31 ) X-CRM114-Notice: Please train this message. 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 Trying to build a source file which included bitops.h, but didn't also bring in the definition for __WORDSIZE (by including limits.h, for example) would result in the following error: include/linux/bitops.h:8:23: error: ‘__WORDSIZE’ undeclared (first use in this function) 8 | #define BITS_PER_LONG __WORDSIZE | ^~~~~~~~~~ The symbol is defined in the bits/wordsize.h header file, include it. Signed-off-by: Alexandru Elisei --- include/linux/bitops.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 56448b71ebbf..3d31f0acf48e 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -1,6 +1,8 @@ #ifndef _KVM_LINUX_BITOPS_H_ #define _KVM_LINUX_BITOPS_H_ +#include + #include #include #include From patchwork Thu Jan 27 16:20:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727029 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 E6BF9C433EF for ; Thu, 27 Jan 2022 16:23:02 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YkBJgJ45d2cfm6BD/BnXRChjfjRymuNtH+dhst3GCPI=; b=y3WiN5lC01eTIi DWd9XYltnn0ykMgBRK8otlUw5FLzB1x9RWFecvHakSXiWBO61YbUacu+tQD93qcVIj3TXk2PXvYQf lt9Ek0zVk8XnYgmHQhVjqjSIUQOxT6PiC2f7p8/c/K74Gl1BzpNp3BdqoPMXdMa5uZt8vkVA3NEdC /ICMjpww89DIV10Ptpit2K4Hh6WeRotoNlPffEOKZ/6xgPkGIhF0MeoCnCD4Qv3Ism2+//XTHRv86 IBPDQuxLwwhj18pcvWZK75wZLyboaCgbtEExji0rM+83jTLq5w1+bvqrU+EubyP7DIHWgkjrg0+Gy TEjiH7WpZ5+BzCU+T1zw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Wx-00GSIh-1H; Thu, 27 Jan 2022 16:21:51 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vg-00GRnO-8m for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:33 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D25E3113E; Thu, 27 Jan 2022 08:20:31 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F010B3F766; Thu, 27 Jan 2022 08:20:29 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 03/10] arm: Move arch specific VCPU features to the arch specific function Date: Thu, 27 Jan 2022 16:20:26 +0000 Message-Id: <20220127162033.54290-4-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082032_408034_7944F507 X-CRM114-Status: GOOD ( 15.19 ) 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 KVM_CAP_ARM_EL1_32BIT and KVM_CAP_ARM_PMU_V3 are arm64 specific features. They are set based on arm64 specific command line options and they target arm64 hardware features. It makes little sense for kvmtool to set the features in the code that is shared between arm and arm64. Move the logic to set the feature bits to the arch specific function kvm_cpu__select_features(), which is already used by arm64 to set other arm64 specific features. Signed-off-by: Alexandru Elisei --- arm/aarch64/include/kvm/kvm-cpu-arch.h | 4 +--- arm/aarch64/kvm-cpu.c | 12 ++++++++++++ arm/kvm-cpu.c | 8 -------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h index 8dfb82ecbc37..016cf5b2b9ea 100644 --- a/arm/aarch64/include/kvm/kvm-cpu-arch.h +++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h @@ -6,9 +6,7 @@ #include "arm-common/kvm-cpu-arch.h" #define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid) { \ - [0] = ((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) | \ - (!!(kvm)->cfg.arch.aarch32_guest << KVM_ARM_VCPU_EL1_32BIT) | \ - (!!(kvm)->cfg.arch.has_pmuv3 << KVM_ARM_VCPU_PMU_V3)) \ + [0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF), \ } #define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c index 9f3e8586880c..3b6224a599c8 100644 --- a/arm/aarch64/kvm-cpu.c +++ b/arm/aarch64/kvm-cpu.c @@ -130,6 +130,18 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu) void kvm_cpu__select_features(struct kvm *kvm, struct kvm_vcpu_init *init) { + if (kvm->cfg.arch.aarch32_guest) { + if (!kvm__supports_extension(kvm, KVM_CAP_ARM_EL1_32BIT)) + die("32bit guests are not supported\n"); + init->features[0] |= 1UL << KVM_ARM_VCPU_EL1_32BIT; + } + + if (kvm->cfg.arch.has_pmuv3) { + if (!kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3)) + die("PMUv3 is not supported"); + init->features[0] |= 1UL << KVM_ARM_VCPU_PMU_V3; + } + /* Enable pointer authentication if available */ if (kvm__supports_extension(kvm, KVM_CAP_ARM_PTRAUTH_ADDRESS) && kvm__supports_extension(kvm, KVM_CAP_ARM_PTRAUTH_GENERIC)) { diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c index 6a2408c632df..554414f81b7a 100644 --- a/arm/kvm-cpu.c +++ b/arm/kvm-cpu.c @@ -46,14 +46,6 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) .features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id) }; - if (kvm->cfg.arch.aarch32_guest && - !kvm__supports_extension(kvm, KVM_CAP_ARM_EL1_32BIT)) - die("32bit guests are not supported\n"); - - if (kvm->cfg.arch.has_pmuv3 && - !kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3)) - die("PMUv3 is not supported"); - vcpu = calloc(1, sizeof(struct kvm_cpu)); if (!vcpu) return NULL; From patchwork Thu Jan 27 16:20:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727041 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 4823AC433EF for ; Thu, 27 Jan 2022 16:23:38 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1zfFGv159CQR3jZgttOYnxzKKLblYKSHBtXxZOcROYM=; b=sOacxCUZK1X2yn /QZpXHJt97/EL7+BDh2/x+Fm3hPh28XsDyh0dif518botUM2zoesgAAaB19dmi8Pvi4KdEN8LMx2k wy3jcJg97FNubCyXVYlSCUQYKAmhaMEw1mG3fWUCTqkkOxkP7sh/juyog+csxcgsjMFW6596zVbqB wZ+03bPtZ2+JRaeSiVdJc8zNnQ6pIzvA/ywATzd8fNEz1iV6kZX+BDnOTJJGXsyKErAckFSh+WmEw s4UbN9wc51WjSuvC9Kp+R7W17ytCh5W3rf0hvSA6Fk7K7+kpM+8FZRCNpqLFiM4rB1fEz9HukM4Xw 6yfTgqQ+KjOSEFrrcPhQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7XL-00GSUC-Pl; Thu, 27 Jan 2022 16:22:15 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vi-00GRp5-PO for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:36 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3519E1063; Thu, 27 Jan 2022 08:20:34 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 22BAB3F766; Thu, 27 Jan 2022 08:20:31 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 04/10] arm: Get rid of the ARM_VCPU_FEATURE_FLAGS() macro Date: Thu, 27 Jan 2022 16:20:27 +0000 Message-Id: <20220127162033.54290-5-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082034_936924_67F8704F X-CRM114-Status: GOOD ( 13.65 ) 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 The ARM_VCPU_FEATURE_FLAGS() macro sets a feature bit in a rather convoluted way: if cpu_id is 0, then bit KVM_ARM_VCPU_POWER_OFF is 0, otherwise is set to 1. There's really no need for this indirection, especially considering that the macro has been changed to return the same value for both the arm and arm64 architectures. Replace it with a simple conditional statement in kvm_cpu__arch_init(), which makes it clearer to understand. Signed-off-by: Alexandru Elisei --- arm/aarch32/include/kvm/kvm-cpu-arch.h | 4 ---- arm/aarch64/include/kvm/kvm-cpu-arch.h | 4 ---- arm/kvm-cpu.c | 6 +++++- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arm/aarch32/include/kvm/kvm-cpu-arch.h b/arm/aarch32/include/kvm/kvm-cpu-arch.h index 780e0e2f0934..fc9aef9f6320 100644 --- a/arm/aarch32/include/kvm/kvm-cpu-arch.h +++ b/arm/aarch32/include/kvm/kvm-cpu-arch.h @@ -5,10 +5,6 @@ #include "arm-common/kvm-cpu-arch.h" -#define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid) { \ - [0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF), \ -} - #define ARM_MPIDR_HWID_BITMASK 0xFFFFFF #define ARM_CPU_ID 0, 0, 0 #define ARM_CPU_ID_MPIDR 5 diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h index 016cf5b2b9ea..17b80493e2c0 100644 --- a/arm/aarch64/include/kvm/kvm-cpu-arch.h +++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h @@ -5,10 +5,6 @@ #include "arm-common/kvm-cpu-arch.h" -#define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid) { \ - [0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF), \ -} - #define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL #define ARM_CPU_ID 3, 0, 0, 0 #define ARM_CPU_ID_MPIDR 5 diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c index 554414f81b7a..62177ea73f82 100644 --- a/arm/kvm-cpu.c +++ b/arm/kvm-cpu.c @@ -43,7 +43,7 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) unsigned int i; struct kvm_vcpu_init preferred_init; struct kvm_vcpu_init vcpu_init = { - .features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id) + .features = {}, }; vcpu = calloc(1, sizeof(struct kvm_cpu)); @@ -63,6 +63,10 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) if (vcpu->kvm_run == MAP_FAILED) die("unable to mmap vcpu fd"); + /* VCPU 0 is the boot CPU, the others start in a poweroff state. */ + if (cpu_id > 0) + vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_POWER_OFF); + /* Set KVM_ARM_VCPU_PSCI_0_2 if available */ if (kvm__supports_extension(kvm, KVM_CAP_ARM_PSCI_0_2)) { vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_PSCI_0_2); From patchwork Thu Jan 27 16:20:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727042 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 8CCE2C433F5 for ; Thu, 27 Jan 2022 16:24:17 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=R346FgMGCcA2ZE4pMtf1fhWqFTHe4mwgGee6l1Gs6lI=; b=zrwIWDv6VwMSG3 3ujllBZzpiinyoDb3d4GtR/dyjwBeBMwO6LmaStUeF7y+K6Oi7lbeIp9llNWVUXqrT6lNbIlAXnLQ cuOwu/FkTixWvE+LGfIExGjajgIZVCTG4v1BvF/K4UU76sEhFy+RKncTQscMcHCnPQSP2xP72MWyO L+HCM31a3C6Mm5azuaAG5A9k1fXMeNNpmM0G6LHz8VZhl0GTH3Hci0gFXsNwceqSBgMOFV3sllTHN miG6FbP1ZVYetXNSFhJtCc7OmfN1TTWMsjROuqyhWJ7QSjm5yd+Ee1ot6CQ/H6USYGpVAVl69q4mE BwWkJDYbWZx4O7SFXPVw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Xq-00GSjc-Ve; Thu, 27 Jan 2022 16:22:47 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vk-00GRph-JB for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:38 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0DA5E113E; Thu, 27 Jan 2022 08:20:36 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 76AB53F766; Thu, 27 Jan 2022 08:20:34 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 05/10] arm: Make the PMUv3 emulation code arm64 specific Date: Thu, 27 Jan 2022 16:20:28 +0000 Message-Id: <20220127162033.54290-6-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082036_723230_0C346AC0 X-CRM114-Status: GOOD ( 11.92 ) 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 KVM for aarch32 does not exist anymore, PMUv3 is a hardware feature present only on aarch64 CPUs, the command line option to enable the feature for a VCPU is aarch64 specific, the PMU code is called only from an aarch64 function and it compiles to an empty stub when ARCH=arm. There is no reason to have the PMUv3 emulation code in the common code area for arm and arm64, so move it to the arm64 directory, where it can be expanded in the future without fear of breaking aarch32 support. Signed-off-by: Alexandru Elisei --- Makefile | 4 ++-- arm/aarch64/arm-cpu.c | 3 ++- arm/{include/arm-common => aarch64/include/asm}/pmu.h | 0 arm/{ => aarch64}/pmu.c | 7 ++----- 4 files changed, 6 insertions(+), 8 deletions(-) rename arm/{include/arm-common => aarch64/include/asm}/pmu.h (100%) rename arm/{ => aarch64}/pmu.c (93%) diff --git a/Makefile b/Makefile index f25114755701..2fe5fb0fba62 100644 --- a/Makefile +++ b/Makefile @@ -159,8 +159,7 @@ endif # ARM OBJS_ARM_COMMON := arm/fdt.o arm/gic.o arm/gicv2m.o arm/ioport.o \ - arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o \ - arm/pmu.o + arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o HDRS_ARM_COMMON := arm/include ifeq ($(ARCH), arm) DEFINES += -DCONFIG_ARM @@ -182,6 +181,7 @@ ifeq ($(ARCH), arm64) OBJS += arm/aarch64/arm-cpu.o OBJS += arm/aarch64/kvm-cpu.o OBJS += arm/aarch64/kvm.o + OBJS += arm/aarch64/pmu.o ARCH_INCLUDE := $(HDRS_ARM_COMMON) ARCH_INCLUDE += -Iarm/aarch64/include diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c index d7572b7790b1..1ec37fa60c50 100644 --- a/arm/aarch64/arm-cpu.c +++ b/arm/aarch64/arm-cpu.c @@ -5,7 +5,8 @@ #include "arm-common/gic.h" #include "arm-common/timer.h" -#include "arm-common/pmu.h" + +#include "asm/pmu.h" #include #include diff --git a/arm/include/arm-common/pmu.h b/arm/aarch64/include/asm/pmu.h similarity index 100% rename from arm/include/arm-common/pmu.h rename to arm/aarch64/include/asm/pmu.h diff --git a/arm/pmu.c b/arm/aarch64/pmu.c similarity index 93% rename from arm/pmu.c rename to arm/aarch64/pmu.c index 5b058eabb49d..6b190c5e2ae5 100644 --- a/arm/pmu.c +++ b/arm/aarch64/pmu.c @@ -4,9 +4,9 @@ #include "kvm/util.h" #include "arm-common/gic.h" -#include "arm-common/pmu.h" -#ifdef CONFIG_ARM64 +#include "asm/pmu.h" + static int set_pmu_attr(struct kvm *kvm, int vcpu_idx, struct kvm_device_attr *attr) { @@ -71,6 +71,3 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); _FDT(fdt_end_node(fdt)); } -#else -void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) { } -#endif From patchwork Thu Jan 27 16:20:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727043 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 59387C433F5 for ; Thu, 27 Jan 2022 16:24:30 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=xBlyg6VMrnWdteePQ+sUz7eGFzOUSxwFf7GyPAclGlU=; b=x6uTs1XlJuv4x5 17wtS6VEPeEj4rARBj5KU1GnaWKCQkjVsdPAOq4N84P3UQn6NObomfJCOYcjcaQKzJS3fBOe3k7uT PCzGPxbM+ISBaOyQcPJzBsAzb17OxtI9uVIruarlZXP7UfAOEQHmmEcdsH0iblHFbeEdW68jwcxgL kaKgw3mWNApeHl/2+S6sIQMVotu7KGhQ/nqoHm55llfdPdNKNRuKxXLc44b9jRhAPTx6LeIhUuSA0 aNra45aZEojFbAdEJQwcLbgXGtIiHLVuDIUQLJGuCQfrac8bi5/TiFkcw4PAvMf0ABVXX8IMlYfvc HkbqbdVUPiuFitlPvzvQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7YA-00GSvB-I0; Thu, 27 Jan 2022 16:23:06 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vm-00GRql-ME for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:40 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0A14A1063; Thu, 27 Jan 2022 08:20:38 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4EA803F766; Thu, 27 Jan 2022 08:20:36 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 06/10] arm64: Rework set_pmu_attr() Date: Thu, 27 Jan 2022 16:20:29 +0000 Message-Id: <20220127162033.54290-7-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082038_869786_7CE4E972 X-CRM114-Status: GOOD ( 15.01 ) 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 By the time kvmtool generates the DTB node for the PMU, the KVM_ARM_VCPU_PMU_V3 VCPU feature is already set by kvm_cpu__arch_init(). KVM refuses to run a VCPU if the PMU hasn't been initialized. A PMU cannot be initialized if the interrupt ID hasn't been set by userspace. As a consequence, kvmtool will get an error if the interrupt ID or if the PMU has not been initialized: KVM_RUN failed: Invalid argument To make debugging easier, exit with an error message as soon as one the PMU ioctls fails, instead of waiting until the VCPU is first run. To avoid the repetition of assigning a new kvm_device_attr struct in the main body of pmu__generate_fdt_nodes(), which hinders readability of the function, move the struct to set_pmu_attr(). Signed-off-by: Alexandru Elisei --- arm/aarch64/pmu.c | 48 ++++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/arm/aarch64/pmu.c b/arm/aarch64/pmu.c index 6b190c5e2ae5..ac5b7bcd6ca9 100644 --- a/arm/aarch64/pmu.c +++ b/arm/aarch64/pmu.c @@ -7,30 +7,31 @@ #include "asm/pmu.h" -static int set_pmu_attr(struct kvm *kvm, int vcpu_idx, - struct kvm_device_attr *attr) +static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr) { - int ret, fd; - - fd = kvm->cpus[vcpu_idx]->vcpu_fd; + struct kvm_device_attr pmu_attr = { + .group = KVM_ARM_VCPU_PMU_V3_CTRL, + .addr = (u64)addr, + .attr = attr, + }; + int ret; - ret = ioctl(fd, KVM_HAS_DEVICE_ATTR, attr); + ret = ioctl(vcpu->vcpu_fd, KVM_HAS_DEVICE_ATTR, &pmu_attr); if (!ret) { - ret = ioctl(fd, KVM_SET_DEVICE_ATTR, attr); + ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr); if (ret) - perror("PMU KVM_SET_DEVICE_ATTR failed"); + die_perror("PMU KVM_SET_DEVICE_ATTR"); } else { - pr_err("Unsupported PMU on vcpu%d\n", vcpu_idx); + die_perror("PMU KVM_HAS_DEVICE_ATTR"); } - - return ret; } void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) { const char compatible[] = "arm,armv8-pmuv3"; int irq = KVM_ARM_PMUv3_PPI; - int i, ret; + struct kvm_cpu *vcpu; + int i; u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \ & GIC_FDT_IRQ_PPI_CPU_MASK; @@ -44,26 +45,9 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) return; for (i = 0; i < kvm->nrcpus; i++) { - struct kvm_device_attr pmu_attr; - - pmu_attr = (struct kvm_device_attr){ - .group = KVM_ARM_VCPU_PMU_V3_CTRL, - .addr = (u64)(unsigned long)&irq, - .attr = KVM_ARM_VCPU_PMU_V3_IRQ, - }; - - ret = set_pmu_attr(kvm, i, &pmu_attr); - if (ret) - return; - - pmu_attr = (struct kvm_device_attr){ - .group = KVM_ARM_VCPU_PMU_V3_CTRL, - .attr = KVM_ARM_VCPU_PMU_V3_INIT, - }; - - ret = set_pmu_attr(kvm, i, &pmu_attr); - if (ret) - return; + vcpu = kvm->cpus[i]; + set_pmu_attr(vcpu, &irq, KVM_ARM_VCPU_PMU_V3_IRQ); + set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT); } _FDT(fdt_begin_node(fdt, "pmu")); From patchwork Thu Jan 27 16:20:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727044 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 8F8D3C433EF for ; Thu, 27 Jan 2022 16:25:18 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Muqvwaoft2KU2+if1e2OWNuR1zaO8yNocUMK++z92qc=; b=g7HY20iUJlZA4k OrS1LApxWX17eIhF1+1o8sg77zBD1YsYiXI7k/h+Q97Y2h0vJRaFlXTYtAqZdL/s8za7gaEDevzqR DVZCy7yPY6uypt1Fo58d+016rOHaJBWayobDYRHduwhRKOoHNykCvVlK8fegYdEVIVMcnbqv+vVrP iLqrT3ZjFoec1WilGRxismrnyAshm4A+0LjZ6d1h66Hq8G5/2Vzm1Ik0KVoZj6bxYucU1PuQeDlsf UbGyE8GAfuCCIJ5WtxfFn6o/AYt+fBrvQw68DHDLtq0pu0t59M6RuA5b0FnfTD8t5irYaAoTvFpX0 gUGtPBgadyVGAWsuN/AQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Yl-00GTGm-6E; Thu, 27 Jan 2022 16:23:43 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vq-00GRsU-38 for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:44 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 84F07113E; Thu, 27 Jan 2022 08:20:41 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4BDA03F766; Thu, 27 Jan 2022 08:20:38 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 07/10] Add cpumask functions Date: Thu, 27 Jan 2022 16:20:30 +0000 Message-Id: <20220127162033.54290-8-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082042_288363_716FF2A3 X-CRM114-Status: GOOD ( 28.15 ) 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 Add a handful of cpumask functions, some of which will be used when dealing with different PMUs on heterogeneous systems. The maximum number of CPUs in a system, NR_CPUS, which dictates the size of the cpumask, has been taken from the Kconfig file for each architecture, from Linux version 5.16. Signed-off-by: Alexandru Elisei --- Makefile | 2 + arm/aarch32/include/asm/kernel.h | 8 + arm/aarch64/include/asm/kernel.h | 8 + include/linux/bitmap.h | 71 +++++++++ include/linux/bitops.h | 2 + include/linux/bits.h | 8 + include/linux/cpumask.h | 62 ++++++++ include/linux/find.h | 30 ++++ include/linux/kernel.h | 6 + mips/include/asm/kernel.h | 8 + powerpc/include/asm/kernel.h | 8 + util/bitmap.c | 256 +++++++++++++++++++++++++++++++ util/find.c | 40 +++++ x86/include/asm/kernel.h | 8 + 14 files changed, 517 insertions(+) create mode 100644 arm/aarch32/include/asm/kernel.h create mode 100644 arm/aarch64/include/asm/kernel.h create mode 100644 include/linux/bitmap.h create mode 100644 include/linux/bits.h create mode 100644 include/linux/cpumask.h create mode 100644 include/linux/find.h create mode 100644 mips/include/asm/kernel.h create mode 100644 powerpc/include/asm/kernel.h create mode 100644 util/bitmap.c create mode 100644 util/find.c create mode 100644 x86/include/asm/kernel.h diff --git a/Makefile b/Makefile index 2fe5fb0fba62..8bc0bba80833 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,8 @@ OBJS += net/uip/buf.o OBJS += net/uip/csum.o OBJS += net/uip/dhcp.o OBJS += kvm-cmd.o +OBJS += util/bitmap.o +OBJS += util/find.o OBJS += util/init.o OBJS += util/iovec.o OBJS += util/rbtree.o diff --git a/arm/aarch32/include/asm/kernel.h b/arm/aarch32/include/asm/kernel.h new file mode 100644 index 000000000000..61296094deb1 --- /dev/null +++ b/arm/aarch32/include/asm/kernel.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_KERNEL_H +#define __ASM_KERNEL_H + +#define NR_CPUS 32 + +#endif /* __ASM_KERNEL_H */ diff --git a/arm/aarch64/include/asm/kernel.h b/arm/aarch64/include/asm/kernel.h new file mode 100644 index 000000000000..a2a8d9ed4059 --- /dev/null +++ b/arm/aarch64/include/asm/kernel.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_KERNEL_H +#define __ASM_KERNEL_H + +#define NR_CPUS 4096 + +#endif /* __ASM_KERNEL_H */ diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h new file mode 100644 index 000000000000..2b36e9f42cb8 --- /dev/null +++ b/include/linux/bitmap.h @@ -0,0 +1,71 @@ +#ifndef KVM__BITMAP_H +#define KVM__BITMAP_H + +#include +#include + +#include "linux/bitops.h" + +#define DECLARE_BITMAP(name,bits) \ + unsigned long name[BITS_TO_LONGS(bits)] + +#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) +#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) + +static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) +{ + unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memset(dst, 0, len); +} + +#ifdef __LITTLE_ENDIAN +#define BITMAP_MEM_ALIGNMENT 8 +#else +#define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long)) +#endif +#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1) + +void __bitmap_set(unsigned long *map, unsigned int start, int len); + +static inline void bitmap_set(unsigned long *map, unsigned int start, + unsigned int nbits) +{ + if (__builtin_constant_p(nbits) && nbits == 1) + set_bit(start, map); + else if (__builtin_constant_p(start & BITMAP_MEM_MASK) && + IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) && + __builtin_constant_p(nbits & BITMAP_MEM_MASK) && + IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT)) + memset((char *)map + start / 8, 0xff, nbits / 8); + else + __bitmap_set(map, start, nbits); +} + +bool __bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits); + +static inline bool bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + if (nbits >= 0 && nbits <= BITS_PER_LONG) + return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0; + + return __bitmap_and(dst, src1, src2, nbits); +} + +int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits); + +bool __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2, + unsigned int nbits); + +static inline bool bitmap_subset(const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + if (nbits >= 0 && nbits <= BITS_PER_LONG) + return !((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); + + return __bitmap_subset(src1, src2, nbits); +} + + +#endif /* KVM__BITMAP_H */ diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 3d31f0acf48e..ae33922f5743 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -11,6 +11,8 @@ #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) + static inline void set_bit(int nr, unsigned long *addr) { addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); diff --git a/include/linux/bits.h b/include/linux/bits.h new file mode 100644 index 000000000000..b6b1c2c3f96d --- /dev/null +++ b/include/linux/bits.h @@ -0,0 +1,8 @@ +#ifndef KVM__BITS_H_ +#define KVM__BITS_H_ + +#define GENMASK(h, l) \ + ((~0UL - (1UL << (l)) + 1) & \ + (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#endif /* KVM__BITS_H */ diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h new file mode 100644 index 000000000000..19aff92bdb5b --- /dev/null +++ b/include/linux/cpumask.h @@ -0,0 +1,62 @@ +#ifndef KVM__CPUMASK_H +#define KVM__CPUMASK_H + +#include + +#include "linux/bitmap.h" +#include "linux/find.h" +#include "linux/kernel.h" + +typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; + +#define cpumask_bits(maskp) ((maskp)->bits) + +static inline void cpumask_set_cpu(int cpu, cpumask_t *dstp) +{ + set_bit(cpu, cpumask_bits(dstp)); +} + +static inline void cpumask_clear_cpu(int cpu, cpumask_t *dstp) +{ + clear_bit(cpu, cpumask_bits(dstp)); +} + +static inline bool cpumask_test_cpu(int cpu, const cpumask_t *cpumask) +{ + return test_bit(cpu, cpumask_bits((cpumask))); +} + +static inline void cpumask_clear(cpumask_t *dstp) +{ + bitmap_zero(cpumask_bits(dstp), NR_CPUS); +} + +static inline bool cpumask_and(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p) +{ + return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), NR_CPUS); +} + +static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) +{ + return find_next_bit(cpumask_bits(srcp), NR_CPUS, n + 1); +} + +#define for_each_cpu(cpu, maskp) \ + for ((cpu) = -1; \ + (cpu) = cpumask_next((cpu), (maskp)), \ + (cpu) < NR_CPUS;) + +static inline int cpulist_parse(const char *buf, cpumask_t *dstp) +{ + return bitmap_parselist(buf, cpumask_bits(dstp), NR_CPUS); +} + +static inline bool cpumask_subset(const cpumask_t *src1p, + const cpumask_t *src2p) +{ + return bitmap_subset(cpumask_bits(src1p), cpumask_bits(src2p), NR_CPUS); +} + +#endif /* KVM__CPUMASK_H */ diff --git a/include/linux/find.h b/include/linux/find.h new file mode 100644 index 000000000000..29c0d67bcd30 --- /dev/null +++ b/include/linux/find.h @@ -0,0 +1,30 @@ +#ifndef KVM__FIND_H +#define KVM__FIND_H + +#include + +#include "linux/bitops.h" +#include "linux/bits.h" + +unsigned long _find_next_bit(const unsigned long *addr1, + const unsigned long *addr2, unsigned long nbits, + unsigned long start, unsigned long invert); + +static inline +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + if (size >= 0 && size <= BITS_PER_LONG) { + unsigned long val; + + if (offset >= size) + return size; + + val = *addr & GENMASK(size - 1, offset); + return val ? (unsigned long)__builtin_ctzl(val) : size; + } + + return _find_next_bit(addr, NULL, size, offset, 0); +} + +#endif /* KVM__FIND_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index f2bff5f12b61..6c22f1c06f6d 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -2,10 +2,16 @@ #ifndef KVM__LINUX_KERNEL_H_ #define KVM__LINUX_KERNEL_H_ +#include "asm/kernel.h" + +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) +#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) #ifndef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) diff --git a/mips/include/asm/kernel.h b/mips/include/asm/kernel.h new file mode 100644 index 000000000000..cbceffd02acd --- /dev/null +++ b/mips/include/asm/kernel.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_KERNEL_H +#define __ASM_KERNEL_H + +#define NR_CPUS 256 + +#endif /* __ASM_KERNEL_H */ diff --git a/powerpc/include/asm/kernel.h b/powerpc/include/asm/kernel.h new file mode 100644 index 000000000000..7b4fe88efd65 --- /dev/null +++ b/powerpc/include/asm/kernel.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_KERNEL_H +#define __ASM_KERNEL_H + +#define NR_CPUS 2048 + +#endif /* __ASM_KERNEL_H */ diff --git a/util/bitmap.c b/util/bitmap.c new file mode 100644 index 000000000000..8bae1c91499d --- /dev/null +++ b/util/bitmap.c @@ -0,0 +1,256 @@ +/* + * Taken from Linux kernel version v5.15. + */ +#include +#include +#include +#include + +#include "linux/bitmap.h" +#include "linux/bitops.h" +#include "linux/err.h" + +/* + * Region 9-38:4/10 describes the following bitmap structure: + * 0 9 12 18 38 N + * .........****......****......****.................. + * ^ ^ ^ ^ ^ + * start off group_len end nbits + */ +struct region { + unsigned int start; + unsigned int off; + unsigned int group_len; + unsigned int end; + unsigned int nbits; +}; + +void __bitmap_set(unsigned long *map, unsigned int start, int len) +{ + unsigned long *p = map + BIT_WORD(start); + const unsigned int size = start + len; + int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); + + while (len - bits_to_set >= 0) { + *p |= mask_to_set; + len -= bits_to_set; + bits_to_set = BITS_PER_LONG; + mask_to_set = ~0UL; + p++; + } + if (len) { + mask_to_set &= BITMAP_LAST_WORD_MASK(size); + *p |= mask_to_set; + } +} + +static void bitmap_set_region(const struct region *r, unsigned long *bitmap) +{ + unsigned int start; + + for (start = r->start; start <= r->end; start += r->group_len) + bitmap_set(bitmap, start, min(r->end - start + 1, r->off)); +} + +static inline bool __end_of_region(char c) +{ + return isspace(c) || c == ','; +} + +static inline bool end_of_str(char c) +{ + return c == '\0' || c == '\n'; +} + +static inline bool end_of_region(char c) +{ + return __end_of_region(c) || end_of_str(c); +} + +/* + * The format allows commas and whitespaces at the beginning + * of the region. + */ +static const char *bitmap_find_region(const char *str) +{ + while (__end_of_region(*str)) + str++; + + return end_of_str(*str) ? NULL : str; +} + +static int bitmap_check_region(const struct region *r) +{ + if (r->start > r->end || r->group_len == 0 || r->off > r->group_len) + return -EINVAL; + + if (r->end >= r->nbits) + return -ERANGE; + + return 0; +} + +static const char *bitmap_getnum(const char *str, unsigned int *num, + unsigned int lastbit) +{ + unsigned long long n; + char *endptr; + + if (str[0] == 'N') { + *num = lastbit; + return str + 1; + } + + n = strtoll(str, &endptr, 10); + /* No digits found. */ + if (n == 0 && endptr == str) + return ERR_PTR(-EINVAL); + /* Check for overflows and negative numbers. */ + if (n == ULLONG_MAX || n != (unsigned long)n || n != (unsigned int)n) + return ERR_PTR(-EOVERFLOW); + + *num = n; + return endptr; +} + +static const char *bitmap_parse_region(const char *str, struct region *r) +{ + unsigned int lastbit = r->nbits - 1; + + if (!strncasecmp(str, "all", 3)) { + r->start = 0; + r->end = lastbit; + str += 3; + + goto check_pattern; + } + + str = bitmap_getnum(str, &r->start, lastbit); + if (IS_ERR(str)) + return str; + + if (end_of_region(*str)) + goto no_end; + + if (*str != '-') + return ERR_PTR(-EINVAL); + + str = bitmap_getnum(str + 1, &r->end, lastbit); + if (IS_ERR(str)) + return str; + +check_pattern: + if (end_of_region(*str)) + goto no_pattern; + + if (*str != ':') + return ERR_PTR(-EINVAL); + + str = bitmap_getnum(str + 1, &r->off, lastbit); + if (IS_ERR(str)) + return str; + + if (*str != '/') + return ERR_PTR(-EINVAL); + + return bitmap_getnum(str + 1, &r->group_len, lastbit); + +no_end: + r->end = r->start; +no_pattern: + r->off = r->end + 1; + r->group_len = r->end + 1; + + return end_of_str(*str) ? NULL : str; +} + +/** + * bitmap_parselist - convert list format ASCII string to bitmap + * @buf: read user string from this buffer; must be terminated + * with a \0 or \n. + * @maskp: write resulting mask here + * @nmaskbits: number of bits in mask to be written + * + * Input format is a comma-separated list of decimal numbers and + * ranges. Consecutively set bits are shown as two hyphen-separated + * decimal numbers, the smallest and largest bit numbers set in + * the range. + * Optionally each range can be postfixed to denote that only parts of it + * should be set. The range will divided to groups of specific size. + * From each group will be used only defined amount of bits. + * Syntax: range:used_size/group_size + * Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769 + * The value 'N' can be used as a dynamically substituted token for the + * maximum allowed value; i.e (nmaskbits - 1). Keep in mind that it is + * dynamic, so if system changes cause the bitmap width to change, such + * as more cores in a CPU list, then any ranges using N will also change. + * + * Returns: 0 on success, -errno on invalid input strings. Error values: + * + * - ``-EINVAL``: wrong region format + * - ``-EINVAL``: invalid character in string + * - ``-ERANGE``: bit number specified too large for mask + * - ``-EOVERFLOW``: integer overflow in the input parameters + */ +int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits) +{ + struct region r; + long ret; + + r.nbits = nmaskbits; + bitmap_zero(maskp, r.nbits); + + while (buf) { + buf = bitmap_find_region(buf); + if (buf == NULL) + return 0; + + buf = bitmap_parse_region(buf, &r); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + ret = bitmap_check_region(&r); + if (ret) + return ret; + + bitmap_set_region(&r, maskp); + } + + return 0; +} + +bool __bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + unsigned int lim = nbits / BITS_PER_LONG; + unsigned long result = 0; + unsigned int k; + + for (k = 0; k < lim; k++) + result |= (dst[k] = src1[k] & src2[k]); + + if (nbits % BITS_PER_LONG) { + result |= (dst[k] = src1[k] & src2[k] & + BITMAP_LAST_WORD_MASK(nbits)); + } + + return result != 0; +} + +bool __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2, + unsigned int nbits) +{ + unsigned int k, lim = nbits / BITS_PER_LONG; + + for (k = 0; k < lim; k++) + if (bitmap1[k] & ~bitmap2[k]) + return false; + + if (nbits % BITS_PER_LONG) { + if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(nbits)) + return false; + } + + return true; +} diff --git a/util/find.c b/util/find.c new file mode 100644 index 000000000000..a438f2388e00 --- /dev/null +++ b/util/find.c @@ -0,0 +1,40 @@ +/* + * Taken from Linux kernel version v5.16. + */ +#include "linux/bitmap.h" +#include "linux/find.h" +#include "linux/kernel.h" + +unsigned long _find_next_bit(const unsigned long *addr1, + const unsigned long *addr2, unsigned long nbits, + unsigned long start, unsigned long invert) +{ + unsigned long tmp, mask; + + if (start >= nbits) + return nbits; + + tmp = addr1[start / BITS_PER_LONG]; + if (addr2) + tmp &= addr2[start / BITS_PER_LONG]; + tmp ^= invert; + + /* Handle 1st word. */ + mask = BITMAP_FIRST_WORD_MASK(start); + tmp &= mask; + + start = round_down(start, BITS_PER_LONG); + + while (!tmp) { + start += BITS_PER_LONG; + if (start >= nbits) + return nbits; + + tmp = addr1[start / BITS_PER_LONG]; + if (addr2) + tmp &= addr2[start / BITS_PER_LONG]; + tmp ^= invert; + } + + return min(start + __builtin_ctzl(tmp), nbits); +} diff --git a/x86/include/asm/kernel.h b/x86/include/asm/kernel.h new file mode 100644 index 000000000000..87fad2a0300a --- /dev/null +++ b/x86/include/asm/kernel.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_KERNEL_H +#define _ASM_KERNEL_H + +#define NR_CPUS 8196 + +#endif /* _ASM_KERNEL_H */ From patchwork Thu Jan 27 16:20:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727045 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 7BB5DC433EF for ; Thu, 27 Jan 2022 16:25:41 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=xyq7HmZ8fjXLCsqkVCL9zJhtWzwVykNguE4CLwqMlko=; b=cutGWUGAJCVkqy xw6okYWS1eKvlh+ak5ciP+V1w3AlZHE893qAGx5CbKfZ68jMaV7QkoVfvBoSVPHenPRVl0D8RkIy3 x4FKfWqToZ6FlcIFy/pkolae9Pi6A5kbLge7A/D5UM/R03NPn7yRK/8ytibq9rUyRnMMiwTFFtpje 1Dwvbzv6egT571+09vKY7/gbk0YuwFQ0JFO6MkJ4xknozs+fkcJnjwUrIPaQaetexS20mifeQXnF+ OGB3qURJ/4gV4C3u49tSohopvsInEvBIZp09XMi2VcglNm/f8mKCrVWGGcZrthxrb1hcZGzTGUL7t oTexF2kclu3XopAN2lYA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7ZO-00GTaI-CC; Thu, 27 Jan 2022 16:24:22 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vs-00GRtT-Bi for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:46 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 619EF11D4; Thu, 27 Jan 2022 08:20:43 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C78033F766; Thu, 27 Jan 2022 08:20:41 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 08/10] update_headers.sh: Sync headers with Linux v5.17-rc1 + SET_PMU attribute Date: Thu, 27 Jan 2022 16:20:31 +0000 Message-Id: <20220127162033.54290-9-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082044_554246_1A870B3D X-CRM114-Status: GOOD ( 13.47 ) 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 Signed-off-by: Alexandru Elisei --- arm/aarch64/include/asm/kvm.h | 4 ++++ include/linux/kvm.h | 16 ++++++++++++++++ x86/include/asm/kvm.h | 16 +++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h index b3edde68bc3e..d49f714f48e6 100644 --- a/arm/aarch64/include/asm/kvm.h +++ b/arm/aarch64/include/asm/kvm.h @@ -362,6 +362,7 @@ struct kvm_arm_copy_mte_tags { #define KVM_ARM_VCPU_PMU_V3_IRQ 0 #define KVM_ARM_VCPU_PMU_V3_INIT 1 #define KVM_ARM_VCPU_PMU_V3_FILTER 2 +#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 #define KVM_ARM_VCPU_TIMER_CTRL 1 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 @@ -413,6 +414,9 @@ struct kvm_arm_copy_mte_tags { #define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS #define KVM_PSCI_RET_DENIED PSCI_RET_DENIED +/* run->fail_entry.hardware_entry_failure_reason codes. */ +#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0) + #endif #endif /* __ARM_KVM_H__ */ diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 1daa45268de2..9563d294f181 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -1131,6 +1131,8 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204 #define KVM_CAP_ARM_MTE 205 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206 +#define KVM_CAP_VM_GPA_BITS 207 +#define KVM_CAP_XSAVE2 208 #ifdef KVM_CAP_IRQ_ROUTING @@ -1162,11 +1164,20 @@ struct kvm_irq_routing_hv_sint { __u32 sint; }; +struct kvm_irq_routing_xen_evtchn { + __u32 port; + __u32 vcpu; + __u32 priority; +}; + +#define KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL ((__u32)(-1)) + /* gsi routing entry types */ #define KVM_IRQ_ROUTING_IRQCHIP 1 #define KVM_IRQ_ROUTING_MSI 2 #define KVM_IRQ_ROUTING_S390_ADAPTER 3 #define KVM_IRQ_ROUTING_HV_SINT 4 +#define KVM_IRQ_ROUTING_XEN_EVTCHN 5 struct kvm_irq_routing_entry { __u32 gsi; @@ -1178,6 +1189,7 @@ struct kvm_irq_routing_entry { struct kvm_irq_routing_msi msi; struct kvm_irq_routing_s390_adapter adapter; struct kvm_irq_routing_hv_sint hv_sint; + struct kvm_irq_routing_xen_evtchn xen_evtchn; __u32 pad[8]; } u; }; @@ -1208,6 +1220,7 @@ struct kvm_x86_mce { #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1) #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) #define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3) +#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4) struct kvm_xen_hvm_config { __u32 flags; @@ -1610,6 +1623,9 @@ struct kvm_enc_region { #define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3) #define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4) +/* Available with KVM_CAP_XSAVE2 */ +#define KVM_GET_XSAVE2 _IOR(KVMIO, 0xcf, struct kvm_xsave) + struct kvm_s390_pv_sec_parm { __u64 origin; __u64 length; diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h index 5a776a08f78c..2da3316bb559 100644 --- a/x86/include/asm/kvm.h +++ b/x86/include/asm/kvm.h @@ -373,9 +373,23 @@ struct kvm_debugregs { __u64 reserved[9]; }; -/* for KVM_CAP_XSAVE */ +/* for KVM_CAP_XSAVE and KVM_CAP_XSAVE2 */ struct kvm_xsave { + /* + * KVM_GET_XSAVE2 and KVM_SET_XSAVE write and read as many bytes + * as are returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2) + * respectively, when invoked on the vm file descriptor. + * + * The size value returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2) + * will always be at least 4096. Currently, it is only greater + * than 4096 if a dynamic feature has been enabled with + * ``arch_prctl()``, but this may change in the future. + * + * The offsets of the state save areas in struct kvm_xsave follow + * the contents of CPUID leaf 0xD on the host. + */ __u32 region[1024]; + __u32 extra[0]; }; #define KVM_MAX_XCRS 16 From patchwork Thu Jan 27 16:20:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727046 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 6B3A5C433F5 for ; Thu, 27 Jan 2022 16:26:45 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=cZyZN3W2HAzmRbXxlHxLUB3sdFltNmjc3LesRFe7mUY=; b=McXcHvwgmmNAqD /hS9jR95wsUfCo9CNhd7GJSa04M1WYYsgLJQ4moSYeshwgRZLus3me/D46u0SJRD6PyhIRnxGsq+L AG7mkZqcZJWzlQEyoRbA29BteiIsQ/mOv6zmIVfRcX/FcGMCf9B093nVgpbe4oZ+6dhHFwhrOab6j ci24HU1Y0o6iAIgza85nwqHtDND8aUclJYKCvABq7MDiwPoXYyTnlfKj2+Zvy8H2uVwHlH1ygfZCS Mg6DVsOQ/qNKrant1tj+OQrHLwQs4LTo33bswdk+U3f6EWgPqVtr6PRTYrSrUC06bwaLgdhpXz2GW l5GW6nZM8/nxde4/XRPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7aG-00GTxn-64; Thu, 27 Jan 2022 16:25:16 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vu-00GRuX-Ly for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:48 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id ED8A3113E; Thu, 27 Jan 2022 08:20:45 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A35383F766; Thu, 27 Jan 2022 08:20:43 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 09/10] arm64: Add support for KVM_ARM_VCPU_PMU_V3_SET_PMU Date: Thu, 27 Jan 2022 16:20:32 +0000 Message-Id: <20220127162033.54290-10-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082046_889187_4736F93E X-CRM114-Status: GOOD ( 22.13 ) 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 The KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU ioctl is used to assign a physical PMU to the events that KVM creates when emulating the PMU for that VCPU. This is useful on heterogeneous systems, when there is more than one hardware PMU present. The assumption that is made in the implementation is that the user will pin the kvmtool process on a set of CPUs that share the same PMU. This allows kvmtool to set the same PMU for all VCPUs from the main thread, instead of in the individual VCPU threads. Signed-off-by: Alexandru Elisei --- arm/aarch64/pmu.c | 148 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/arm/aarch64/pmu.c b/arm/aarch64/pmu.c index ac5b7bcd6ca9..c0fc95ca01c4 100644 --- a/arm/aarch64/pmu.c +++ b/arm/aarch64/pmu.c @@ -1,3 +1,9 @@ +#include +#include + +#include "linux/cpumask.h" +#include "linux/err.h" + #include "kvm/fdt.h" #include "kvm/kvm.h" #include "kvm/kvm-cpu.h" @@ -7,6 +13,18 @@ #include "asm/pmu.h" +static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr) +{ + struct kvm_device_attr pmu_attr = { + .group = KVM_ARM_VCPU_PMU_V3_CTRL, + .attr = attr, + }; + int ret; + + ret = ioctl(vcpu->vcpu_fd, KVM_HAS_DEVICE_ATTR, &pmu_attr); + return ret == 0; +} + static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr) { struct kvm_device_attr pmu_attr = { @@ -16,8 +34,7 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr) }; int ret; - ret = ioctl(vcpu->vcpu_fd, KVM_HAS_DEVICE_ATTR, &pmu_attr); - if (!ret) { + if (pmu_has_attr(vcpu, attr)) { ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr); if (ret) die_perror("PMU KVM_SET_DEVICE_ATTR"); @@ -26,11 +43,126 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr) } } +#define SYS_EVENT_SOURCE "/sys/bus/event_source/devices/" +/* + * int is 32 bits and INT_MAX translates in decimal to 2 * 10^9. + * Make room for newline and NUL. + */ +#define PMU_ID_MAXLEN 12 + +/* + * In the case of homogeneous systems, there only one hardware PMU, and all + * VCPUs will use the same PMU, regardless of where the attribute gets set. + * + * For heterogeneous systems, the assumption is that the user has pinned the VM + * (via taskset or similar) to a set of CPUs that share the same hardware PMU. + * This simplifies things for kvmtool, as correctness is not affected by setting + * the PMU for each VCPU from the main thread, instead of setting it from each + * individual VCPU thread. + */ +static int find_pmu(void) +{ + char buf[PMU_ID_MAXLEN]; + struct dirent *dirent; + char *cpulist, *path; + int pmu_id = -ENXIO; + unsigned long val; + cpumask_t cpumask; + ssize_t fd_sz; + int this_cpu; + int fd, ret; + DIR *dir; + + memset(buf, 0, PMU_ID_MAXLEN); + + this_cpu = sched_getcpu(); + if (this_cpu < 0) + return -errno; + + cpulist = calloc(1, PAGE_SIZE); + if (!cpulist) + return -ENOMEM; + + path = calloc(1, PAGE_SIZE); + if (!path) { + pmu_id = -ENOMEM; + goto out_free_cpulist; + } + /* Make the compiler happy by copying the NULL terminating byte. */ + strncpy(path, SYS_EVENT_SOURCE, strlen(SYS_EVENT_SOURCE) + 1); + + dir = opendir(SYS_EVENT_SOURCE); + if (!dir) { + pmu_id = -errno; + goto out_free; + } + + while ((dirent = readdir(dir))) { + if (dirent->d_type != DT_LNK) + continue; + + strcat(path, dirent->d_name); + strcat(path, "/cpus"); + fd = open(path, O_RDONLY); + if (fd < 0) + goto next_dir; + + fd_sz = read_file(fd, cpulist, PAGE_SIZE); + if (fd_sz < 0) { + pmu_id = -errno; + goto out_free; + } + close(fd); + + ret = cpulist_parse(cpulist, &cpumask); + if (ret) { + pmu_id = ret; + goto out_free; + } + + if (!cpumask_test_cpu(this_cpu, &cpumask)) + goto next_dir; + + strcpy(&path[strlen(path) - 4], "type"); + fd = open(path, O_RDONLY); + if (fd < 0) + goto next_dir; + + fd_sz = read_file(fd, buf, PMU_ID_MAXLEN - 1); + if (fd_sz < 0) { + pmu_id = -errno; + goto out_free; + } + close(fd); + + val = strtoul(buf, NULL, 10); + if (val > INT_MAX) { + pmu_id = -EOVERFLOW; + goto out_free; + } + pmu_id = (int)val; + pr_debug("Using PMU: %s (id: %d)", dirent->d_name, pmu_id); + break; + +next_dir: + /* Reset path. */ + memset(&path[strlen(SYS_EVENT_SOURCE)], '\0', + strlen(path) - strlen(SYS_EVENT_SOURCE)); + } + +out_free: + free(path); +out_free_cpulist: + free(cpulist); + return pmu_id; +} + void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) { const char compatible[] = "arm,armv8-pmuv3"; int irq = KVM_ARM_PMUv3_PPI; struct kvm_cpu *vcpu; + int pmu_id = -ENXIO; int i; u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \ @@ -44,9 +176,21 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) if (!kvm->cfg.arch.has_pmuv3) return; + if (pmu_has_attr(kvm->cpus[0], KVM_ARM_VCPU_PMU_V3_SET_PMU)) { + pmu_id = find_pmu(); + if (pmu_id < 0) + pr_debug("Failed to find a PMU (errno = %d)", -pmu_id); + } + for (i = 0; i < kvm->nrcpus; i++) { vcpu = kvm->cpus[i]; set_pmu_attr(vcpu, &irq, KVM_ARM_VCPU_PMU_V3_IRQ); + /* + * PMU IDs 0-5 are reserved; a positive value means a PMU was + * found. + */ + if (pmu_id > 0) + set_pmu_attr(vcpu, &pmu_id, KVM_ARM_VCPU_PMU_V3_SET_PMU); set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT); } From patchwork Thu Jan 27 16:20:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12727047 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 64BABC433F5 for ; Thu, 27 Jan 2022 16:27:22 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=H+3pBgA3iOL4qWJS06TkB7PQZ2kfj/a61pisS5IHV+M=; b=AvdMSgMDAKAi2/ lz7wHgta8jZRfrbvG/h2DjkA7cBIgIW49y1HJ/NSNH0pXjMHPlro5PE94QdM9Sk19az4pg/eC+ewP fmW0NIWwkFcscTAOdUz4vFlZPguobkAZMpqcuO/orm7m2Ym1RvV/ovikXn3CVB/kUv5jpF5kqAaqt Yj+tpAdR+wrogjg4entLBMLpzXDgSuwV7nbph3LE9qWWTb6feRtMVwniOXYz+/KJqvdMkmWQKxpTp v6CJVar58UOQfHgOepOt9xbqTcNBrA+TwHuAOtrnNeTNUJQ6X/ZpWg7yy14jlj8wIPxihqZ21XE05 n0pZDr50B//H8VeuEMfg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7ap-00GUGH-Gp; Thu, 27 Jan 2022 16:25:52 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nD7Vx-00GRvl-54 for linux-arm-kernel@lists.infradead.org; Thu, 27 Jan 2022 16:20:52 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AE08F12FC; Thu, 27 Jan 2022 08:20:48 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3B4BE3F766; Thu, 27 Jan 2022 08:20:46 -0800 (PST) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, andre.przywara@arm.com Subject: [PATCH v2 kvmtool 10/10] arm64: Add --vcpu-affinity command line argument Date: Thu, 27 Jan 2022 16:20:33 +0000 Message-Id: <20220127162033.54290-11-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com> References: <20220127162033.54290-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220127_082049_385350_040EAD6E X-CRM114-Status: GOOD ( 26.36 ) 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 Add a new command line argument, --vcpu-affinity, to set the CPU affinity for the VCPUs. The affinity is expressed as a cpulist and will apply to all VCPU threads. This gives the user a second option for choosing the PMU on a heterogeneous system. The PMU setup code, when --vcpu-affinity is specified, will search for the PMU associated with the CPUs specified with this command line argument instead of the PMU associated with the CPU on which the main thread is executing. Signed-off-by: Alexandru Elisei --- arm/aarch64/include/kvm/kvm-config-arch.h | 5 ++ arm/aarch64/kvm-cpu.c | 9 +++ arm/aarch64/kvm.c | 32 +++++++++++ arm/aarch64/pmu.c | 70 ++++++++++++++++------- arm/include/arm-common/kvm-arch.h | 7 +++ arm/include/arm-common/kvm-config-arch.h | 1 + include/linux/cpumask.h | 5 ++ 7 files changed, 109 insertions(+), 20 deletions(-) diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h index 04be43dfa9b2..04c04a8865c9 100644 --- a/arm/aarch64/include/kvm/kvm-config-arch.h +++ b/arm/aarch64/include/kvm/kvm-config-arch.h @@ -1,11 +1,16 @@ #ifndef KVM__KVM_CONFIG_ARCH_H #define KVM__KVM_CONFIG_ARCH_H +int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset); + #define ARM_OPT_ARCH_RUN(cfg) \ OPT_BOOLEAN('\0', "aarch32", &(cfg)->aarch32_guest, \ "Run AArch32 guest"), \ OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3, \ "Create PMUv3 device"), \ + OPT_CALLBACK('\0', "vcpu-affinity", kvm, "cpulist", \ + "Specify the CPU affinity that will apply to " \ + "all VCPUs", vcpu_affinity_parser, kvm), \ OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed, \ "Specify random seed for Kernel Address Space " \ "Layout Randomization (KASLR)"), diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c index 3b6224a599c8..27ec8c1d4070 100644 --- a/arm/aarch64/kvm-cpu.c +++ b/arm/aarch64/kvm-cpu.c @@ -90,6 +90,15 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu) struct kvm_one_reg reg; u64 data; + cpu_set_t *affinity = kvm->arch.vcpu_affinity_cpuset; + int ret; + + if (affinity) { + ret = sched_setaffinity(0, sizeof(cpu_set_t), affinity); + if (ret == -1) + die_perror("sched_setaffinity"); + } + reg.addr = (u64)&data; /* pstate = all interrupts masked */ diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c index 56a0aedc263d..764f1091ec87 100644 --- a/arm/aarch64/kvm.c +++ b/arm/aarch64/kvm.c @@ -3,8 +3,40 @@ #include #include +#include + #include +int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset) +{ + struct kvm *kvm = opt->ptr; + const char *cpulist = arg; + cpumask_t *cpumask; + int cpu, ret; + + kvm->cfg.arch.vcpu_affinity = cpulist; + + cpumask = calloc(1, cpumask_size()); + if (!cpumask) + die_perror("calloc"); + + ret = cpulist_parse(cpulist, cpumask); + if (ret) { + free(cpumask); + return ret; + } + + kvm->arch.vcpu_affinity_cpuset = CPU_ALLOC(NR_CPUS); + if (!kvm->arch.vcpu_affinity_cpuset) + die_perror("CPU_ALLOC"); + CPU_ZERO_S(CPU_ALLOC_SIZE(NR_CPUS), kvm->arch.vcpu_affinity_cpuset); + + for_each_cpu(cpu, cpumask) + CPU_SET(cpu, kvm->arch.vcpu_affinity_cpuset); + + return 0; +} + /* * Return the TEXT_OFFSET value that the guest kernel expects. Note * that pre-3.17 kernels expose this value using the native endianness diff --git a/arm/aarch64/pmu.c b/arm/aarch64/pmu.c index c0fc95ca01c4..3cf36d79414c 100644 --- a/arm/aarch64/pmu.c +++ b/arm/aarch64/pmu.c @@ -50,35 +50,20 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr) */ #define PMU_ID_MAXLEN 12 -/* - * In the case of homogeneous systems, there only one hardware PMU, and all - * VCPUs will use the same PMU, regardless of where the attribute gets set. - * - * For heterogeneous systems, the assumption is that the user has pinned the VM - * (via taskset or similar) to a set of CPUs that share the same hardware PMU. - * This simplifies things for kvmtool, as correctness is not affected by setting - * the PMU for each VCPU from the main thread, instead of setting it from each - * individual VCPU thread. - */ -static int find_pmu(void) +static int find_pmu_cpumask(struct kvm *kvm, cpumask_t *cpumask) { + cpumask_t pmu_cpumask, tmp; char buf[PMU_ID_MAXLEN]; struct dirent *dirent; char *cpulist, *path; int pmu_id = -ENXIO; unsigned long val; - cpumask_t cpumask; ssize_t fd_sz; - int this_cpu; int fd, ret; DIR *dir; memset(buf, 0, PMU_ID_MAXLEN); - this_cpu = sched_getcpu(); - if (this_cpu < 0) - return -errno; - cpulist = calloc(1, PAGE_SIZE); if (!cpulist) return -ENOMEM; @@ -114,15 +99,20 @@ static int find_pmu(void) } close(fd); - ret = cpulist_parse(cpulist, &cpumask); + ret = cpulist_parse(cpulist, &pmu_cpumask); if (ret) { pmu_id = ret; goto out_free; } - if (!cpumask_test_cpu(this_cpu, &cpumask)) + if (!cpumask_and(&tmp, cpumask, &pmu_cpumask)) goto next_dir; + if (!cpumask_subset(cpumask, &pmu_cpumask)) { + die("Unable to find a PMU associated with CPUs %s", + kvm->cfg.arch.vcpu_affinity); + } + strcpy(&path[strlen(path) - 4], "type"); fd = open(path, O_RDONLY); if (fd < 0) @@ -157,6 +147,46 @@ out_free_cpulist: return pmu_id; } +/* + * In the case of homogeneous systems, there only one hardware PMU, and all + * VCPUs will use the same PMU, regardless of the physical CPUs on which the + * VCPU threads will be executing. + * + * For heterogeneous systems, there are 2 ways for the user to ensure that the + * VM runs on CPUs that have the same PMU: + * + * 1. By pinning the entire VM to the desired CPUs, in which case kvmtool will + * choose the PMU associated with the CPU on which the main thread is executing + * (the thread that calls find_pmu()). + * + * 2. By setting the affinity mask for the VCPUs with the --vcpu-affinity + * command line argument. All CPUs in the affinity mask must have the same PMU, + * otherwise kvmtool will not be able to set a PMU. + */ +static int find_pmu(struct kvm *kvm) +{ + cpumask_t *cpumask; + int i, this_cpu; + + cpumask = calloc(1, cpumask_size()); + if (!cpumask) + die_perror("calloc"); + + if (!kvm->arch.vcpu_affinity_cpuset) { + this_cpu = sched_getcpu(); + if (this_cpu < 0) + return -errno; + cpumask_set_cpu(this_cpu, cpumask); + } else { + for (i = 0; i < CPU_SETSIZE; i ++) { + if (CPU_ISSET(i, kvm->arch.vcpu_affinity_cpuset)) + cpumask_set_cpu(i, cpumask); + } + } + + return find_pmu_cpumask(kvm, cpumask); +} + void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) { const char compatible[] = "arm,armv8-pmuv3"; @@ -177,7 +207,7 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) return; if (pmu_has_attr(kvm->cpus[0], KVM_ARM_VCPU_PMU_V3_SET_PMU)) { - pmu_id = find_pmu(); + pmu_id = find_pmu(kvm); if (pmu_id < 0) pr_debug("Failed to find a PMU (errno = %d)", -pmu_id); } diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h index c645ac001bca..b28beb0b06cf 100644 --- a/arm/include/arm-common/kvm-arch.h +++ b/arm/include/arm-common/kvm-arch.h @@ -2,6 +2,11 @@ #define ARM_COMMON__KVM_ARCH_H #include +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include + #include #include @@ -101,6 +106,8 @@ struct kvm_arch { u64 initrd_guest_start; u64 initrd_size; u64 dtb_guest_start; + + cpu_set_t *vcpu_affinity_cpuset; }; #endif /* ARM_COMMON__KVM_ARCH_H */ diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h index 5734c46ab9e6..d2de3b0892f2 100644 --- a/arm/include/arm-common/kvm-config-arch.h +++ b/arm/include/arm-common/kvm-config-arch.h @@ -12,6 +12,7 @@ struct kvm_config_arch { u64 kaslr_seed; enum irqchip_type irqchip; u64 fw_addr; + const char *vcpu_affinity; }; int irqchip_parser(const struct option *opt, const char *arg, int unset); diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 19aff92bdb5b..f53d453c3e7d 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -11,6 +11,11 @@ typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; #define cpumask_bits(maskp) ((maskp)->bits) +static inline unsigned int cpumask_size(void) +{ + return BITS_TO_LONGS(NR_CPUS) * sizeof(long); +} + static inline void cpumask_set_cpu(int cpu, cpumask_t *dstp) { set_bit(cpu, cpumask_bits(dstp));