From 6e1a12d545cbd9eda3e1aaab3b2a477ac8b4ce07 Mon Sep 17 00:00:00 2001 From: Zhou Wang Date: Mon, 20 Oct 2025 21:30:02 +0800 Subject: [PATCH] kvm: hisi_virt: tlbi: Fix wrong CPU aff3 convertion between MPIDR and SYS_LSUDVMBM_EL2 driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICURZK --------------------------------------------------------------------- TLBI broadcast CPU bitmap should be set in SYS_LSUDVMBM_EL2. Now we make a mistake when doing the convertion between MPIDR and SYS_LSUDVMBM_EL2. Fields of vDie ID and Socket ID in Aff3 are different between MPIDR and SYS_LSUDVMBM_EL2p in HIP12, however, they are same in current wrong logic. This patch fixes this problem. Fixes: 2671ba221968 ("kvm: hisi_virt: Update TLBI broadcast feature for hip12") Signed-off-by: Zhou Wang Signed-off-by: Jian Cai --- arch/arm64/kvm/hisilicon/hisi_virt.c | 33 +++++++++++++++++++++------- arch/arm64/kvm/hisilicon/hisi_virt.h | 26 +++++++++++++++++----- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.c b/arch/arm64/kvm/hisilicon/hisi_virt.c index 48b644e4b3f3..e2af6ad2b5e3 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.c +++ b/arch/arm64/kvm/hisilicon/hisi_virt.c @@ -8,6 +8,7 @@ #include #include #include "hisi_virt.h" +#include static enum hisi_cpu_type cpu_type = UNKNOWN_HI_TYPE; @@ -475,39 +476,55 @@ static void kvm_update_vm_lsudvmbm(struct kvm *kvm) kvm->arch.tlbi_dvmbm = val; } +static u64 convert_aff3_to_vdie_hip12(u64 aff3) +{ + /* + * The fields of vdie id and socket id in MPIDR are aff3[2:0] and + * aff3[4:3], however, the fields of vdie id and socket id in + * SYS_LSUDVMBM_EL2 are bit[58:57] and bit[60:59] for first vdie, + * bit[54:53] and bit[56:55] for second vdie. + */ + return FIELD_GET(MPIDR_AFF3_SOCKET_ID_MASK, aff3) << 2 | + FIELD_GET(MPIDR_AFF3_VDIE_ID_MASK, aff3); +} + static void kvm_update_vm_lsudvmbm_hip12(struct kvm *kvm) { u64 mpidr, aff3, aff2; - u64 vm_aff3s[DVMBM_MAX_DIES_HIP12]; + u64 vm_aff3s[DVMBM_MAX_VDIES_HIP12]; u64 val; int cpu, nr_dies; + u64 vdie1, vdie2; - nr_dies = kvm_dvmbm_get_dies_info(kvm, vm_aff3s, DVMBM_MAX_DIES_HIP12); + nr_dies = kvm_dvmbm_get_dies_info(kvm, vm_aff3s, DVMBM_MAX_VDIES_HIP12); if (nr_dies > 2) { val = DVMBM_RANGE_ALL_DIES << DVMBM_RANGE_SHIFT; goto out_update; } if (nr_dies == 1) { + vdie1 = convert_aff3_to_vdie_hip12(vm_aff3s[0]); val = DVMBM_RANGE_ONE_DIE << DVMBM_RANGE_SHIFT | - vm_aff3s[0] << DVMBM_DIE1_VDIE_SHIFT_HIP12; + vdie1 << DVMBM_VDIE1_SHIFT_HIP12; /* fulfill bits [11:6] */ for_each_cpu(cpu, kvm->arch.sched_cpus) { mpidr = cpu_logical_map(cpu); aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2); - val |= 1ULL << (aff2 + DVMBM_DIE1_CLUSTER_SHIFT_HIP12); + val |= 1ULL << (aff2 + DVMBM_VDIE1_CLUSTER_SHIFT_HIP12); } goto out_update; } /* nr_dies == 2 */ + vdie1 = convert_aff3_to_vdie_hip12(vm_aff3s[0]); + vdie2 = convert_aff3_to_vdie_hip12(vm_aff3s[1]); val = DVMBM_RANGE_TWO_DIES << DVMBM_RANGE_SHIFT | DVMBM_GRAN_CLUSTER << DVMBM_GRAN_SHIFT | - vm_aff3s[0] << DVMBM_DIE1_VDIE_SHIFT_HIP12 | - vm_aff3s[1] << DVMBM_DIE2_VDIE_SHIFT_HIP12; + vdie1 << DVMBM_VDIE1_SHIFT_HIP12 | + vdie2 << DVMBM_VDIE2_SHIFT_HIP12; /* and fulfill bits [11:0] */ for_each_cpu(cpu, kvm->arch.sched_cpus) { @@ -516,9 +533,9 @@ static void kvm_update_vm_lsudvmbm_hip12(struct kvm *kvm) aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2); if (aff3 == vm_aff3s[0]) - val |= 1ULL << (aff2 + DVMBM_DIE1_CLUSTER_SHIFT_HIP12); + val |= 1ULL << (aff2 + DVMBM_VDIE1_CLUSTER_SHIFT_HIP12); else - val |= 1ULL << (aff2 + DVMBM_DIE2_CLUSTER_SHIFT_HIP12); + val |= 1ULL << (aff2 + DVMBM_VDIE2_CLUSTER_SHIFT_HIP12); } out_update: diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.h b/arch/arm64/kvm/hisilicon/hisi_virt.h index 85dccafde8a6..a0ec3471e3f9 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.h +++ b/arch/arm64/kvm/hisilicon/hisi_virt.h @@ -69,12 +69,26 @@ enum hisi_cpu_type { #define DVMBM_MAX_DIES 32 -/* HIP12 */ -#define DVMBM_DIE1_VDIE_SHIFT_HIP12 57 -#define DVMBM_DIE2_VDIE_SHIFT_HIP12 53 -#define DVMBM_DIE1_CLUSTER_SHIFT_HIP12 6 -#define DVMBM_DIE2_CLUSTER_SHIFT_HIP12 0 -#define DVMBM_MAX_DIES_HIP12 8 +/* + * MPIDR_EL1 layout on HIP12 + * + * Aff3[4:3] - socket ID [0-3] + * Aff3[2:0] - vdie ID [0,1] + * Aff2[2:0] - cluster ID [0-5] + * Aff1[3:0] - core ID [0-15] + * Aff0[0] - thread ID [0,1] + * + * On HIP12, cpu die is named as vdie. Actually, + * vdie is equivalent to cpu die. + */ + +#define DVMBM_VDIE1_SHIFT_HIP12 57 +#define DVMBM_VDIE2_SHIFT_HIP12 53 +#define DVMBM_VDIE1_CLUSTER_SHIFT_HIP12 6 +#define DVMBM_VDIE2_CLUSTER_SHIFT_HIP12 0 +#define DVMBM_MAX_VDIES_HIP12 8 +#define MPIDR_AFF3_VDIE_ID_MASK GENMASK(2, 0) +#define MPIDR_AFF3_SOCKET_ID_MASK GENMASK(4, 3) void probe_hisi_cpu_type(void); bool hisi_ncsnp_supported(void); -- Gitee