From nobody Wed Dec 17 15:59:41 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B021F2FFDEC; Tue, 30 Sep 2025 10:32:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759228342; cv=none; b=NIzoAEmxXwzAigby3ilYOqqFmhlaeUaXMeUM0tp0Gr/RNS1H8xxiTx3PJZpvPD7uLNyfI2knvoUM1aMSm0YEvDKiBLaxKw2nEgwFqCRPnOFppQs/htNt3CmmZjIoVNy8gTWuwjvLe6oWY/ynjYO3il+s+uSkh0DRlOmYgcL7FRs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759228342; c=relaxed/simple; bh=/MsqTiziGjy7u2uwCD5wvYRfRdawZe5qkZpfxdFjiW4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m9OvTlZ9/pHPdP3ulDu+aURGfTkdBgrY3ZZv6nzS1/r9Bk87BuJphITMr1Gq6u7GYul/C1Oj6gvlZdn9FvYrKBIh0E5UqzjdUfCmiemoI0G7dA3hdMFDT2tuA37N4xmL6pyN/3GyXDfWWJ6rL/eiNRNOueO+nf0bdVIU2pQz8pU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 497D026B9; Tue, 30 Sep 2025 03:32:12 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.1.197.1]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id EFEAD3F66E; Tue, 30 Sep 2025 03:32:18 -0700 (PDT) From: Suzuki K Poulose To: kvmarm@lists.linux.dev Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, will@kernel.org, oliver.upton@linux.dev, maz@kernel.org, alexandru.elisei@arm.com, aneesh.kumar@kernel.org, steven.price@arm.com, tabba@google.com, Suzuki K Poulose Subject: [PATCH kvmtool v4 12/15] arm64: psci: Implement AFFINITY_INFO Date: Tue, 30 Sep 2025 11:31:27 +0100 Message-ID: <20250930103130.197534-14-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250930103130.197534-1-suzuki.poulose@arm.com> References: <20250930103130.197534-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Oliver Upton Implement support for PSCI AFFINITY_INFO by iteratively searching all of the vCPUs in a VM for those that match the specified affinity. Pause the VM to avoid racing against other PSCI calls in the system that might change the power state of the vCPUs. Signed-off-by: Oliver Upton Signed-off-by: Suzuki K Poulose --- arm64/include/kvm/kvm-cpu-arch.h | 12 ++++++- arm64/psci.c | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/arm64/include/kvm/kvm-cpu-arch.h b/arm64/include/kvm/kvm-cpu-a= rch.h index dbd90647..d9eb5f0e 100644 --- a/arm64/include/kvm/kvm-cpu-arch.h +++ b/arm64/include/kvm/kvm-cpu-arch.h @@ -7,7 +7,6 @@ #include #include =20 -#define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL #define ARM_CPU_ID 3, 0, 0, 0 #define ARM_CPU_ID_MPIDR 5 #define ARM_CPU_CTRL 3, 0, 1, 0 @@ -67,6 +66,17 @@ unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vc= pu); int kvm_cpu__setup_pvtime(struct kvm_cpu *vcpu); int kvm_cpu__teardown_pvtime(struct kvm *kvm); =20 +#define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL +#define ARM_MPIDR_LEVEL_BITS_SHIFT 3 +#define ARM_MPIDR_LEVEL_BITS (1 << ARM_MPIDR_LEVEL_BITS_SHIFT) +#define ARM_MPIDR_LEVEL_MASK ((1 << ARM_MPIDR_LEVEL_BITS) - 1) + +#define ARM_MPIDR_LEVEL_SHIFT(level) \ + (((1 << level) >> 1) << ARM_MPIDR_LEVEL_BITS_SHIFT) + +#define ARM_MPIDR_AFFINITY_LEVEL(mpidr, level) \ + ((mpidr >> ARM_MPIDR_LEVEL_SHIFT(level)) & ARM_MPIDR_LEVEL_MASK) + static inline __u64 __core_reg_id(__u64 offset) { __u64 id =3D KVM_REG_ARM64 | KVM_REG_ARM_CORE | offset; diff --git a/arm64/psci.c b/arm64/psci.c index 14c98639..94e39d40 100644 --- a/arm64/psci.c +++ b/arm64/psci.c @@ -6,6 +6,16 @@ #include #include =20 +#define AFFINITY_MASK(level) ~((0x1UL << ((level) * ARM_MPIDR_LEVEL_BITS))= - 1) + +static unsigned long psci_affinity_mask(unsigned long affinity_level) +{ + if (affinity_level <=3D 3) + return ARM_MPIDR_HWID_BITMASK & AFFINITY_MASK(affinity_level); + + return 0; +} + static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res) { u32 arg =3D smccc_get_arg(vcpu, 1); @@ -20,6 +30,8 @@ static void psci_features(struct kvm_cpu *vcpu, struct ar= m_smccc_res *res) case PSCI_0_2_FN_CPU_OFF: case PSCI_0_2_FN_CPU_ON: case PSCI_0_2_FN64_CPU_ON: + case PSCI_0_2_FN_AFFINITY_INFO: + case PSCI_0_2_FN64_AFFINITY_INFO: case ARM_SMCCC_VERSION_FUNC_ID: res->a0 =3D PSCI_RET_SUCCESS; break; @@ -111,6 +123,49 @@ out_continue: kvm__continue(vcpu->kvm); } =20 +static void affinity_info(struct kvm_cpu *vcpu, struct arm_smccc_res *res) +{ + u64 target_affinity =3D smccc_get_arg(vcpu, 1); + u64 lowest_level =3D smccc_get_arg(vcpu, 2); + u64 mpidr_mask =3D psci_affinity_mask(lowest_level); + struct kvm *kvm =3D vcpu->kvm; + bool matched =3D false; + int i; + + if (!psci_valid_affinity(target_affinity) || lowest_level > 3) { + res->a0 =3D PSCI_RET_INVALID_PARAMS; + return; + } + + kvm__pause(vcpu->kvm); + + for (i =3D 0; i < kvm->nrcpus; i++) { + struct kvm_cpu *tmp =3D kvm->cpus[i]; + u64 mpidr =3D kvm_cpu__get_vcpu_mpidr(tmp); + struct kvm_mp_state mp_state; + + if ((mpidr & mpidr_mask) !=3D target_affinity) + continue; + + if (ioctl(tmp->vcpu_fd, KVM_GET_MP_STATE, &mp_state)) + die_perror("KVM_GET_MP_STATE failed"); + + if (mp_state.mp_state !=3D KVM_MP_STATE_STOPPED) { + res->a0 =3D PSCI_0_2_AFFINITY_LEVEL_ON; + goto out_continue; + } + + matched =3D true; + } + + if (matched) + res->a0 =3D PSCI_0_2_AFFINITY_LEVEL_OFF; + else + res->a0 =3D PSCI_RET_INVALID_PARAMS; +out_continue: + kvm__continue(vcpu->kvm); +} + void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res) { switch (vcpu->kvm_run->hypercall.nr) { @@ -131,6 +186,10 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smcc= c_res *res) case PSCI_0_2_FN64_CPU_ON: cpu_on(vcpu, res); break; + case PSCI_0_2_FN_AFFINITY_INFO: + case PSCI_0_2_FN64_AFFINITY_INFO: + affinity_info(vcpu, res); + break; default: res->a0 =3D PSCI_RET_NOT_SUPPORTED; } --=20 2.43.0