[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250915134932.8137-1-jiaqingtong@huawei.com>
Date: Mon, 15 Sep 2025 21:49:29 +0800
From: Jia Qingtong <jiaqingtong97@...il.com>
To: oliver.upton@...ux.dev,
maz@...nel.org
Cc: will@...nel.org,
catalin.marinas@....com,
mark.rutland@....com,
cohuck@...hat.com,
linux-kernel@...r.kernel.org,
kvmarm@...ts.linux.dev,
linux-arm-kernel@...ts.infradead.org,
jiaqingtong@...wei.com,
jiaqingtong97@...il.com,
yuzenghui@...wei.com,
jiangkunkun@...wei.com
Subject: [RFC RESEND PATCH] arm64: Rename is_midr_in_range_list and add is_midr_subset_of_range_list
From: Jia Qingtong <jiaqingtong@...wei.com>
Regarding the is_midr_in_range_list function, from the early discussions
during submission [1][2], we know:
1. The VMM must ensure the correctness of the target impl CPU set.
2. For errata-related fixes, if any target impl CPU is affected,
then all CPUs are considered affected.
However, in commit e403e8538359 ("arm64: errata: Assume that unknown CPUs
_are_ vulnerable to Spectre BHB")
and commit d4647f0a2ad7 ("arm64: Rewrite Spectre-v2 mitigation code"),
the functions is_spectre_bhb_safe and
spectre_v2_get_cpu_hw_mitigation_state use is_midr_in_range_list
to determine whether the current chip is not affected by the issue
(rather than, as we might expect, whether it is affected by the erratum).
Therefore, for the arg ranges of is_midr_in_range_list being tested,
as long as there is one MIDR present in the target impl CPUs,
the current VM (and the target impl CPUs) are considered not affected by
the issue.
This seems somewhat contrary to the original idea, since the VMM does not
know whether KVM implements positive or negative logic.
Hence, we may need to rename is_midr_in_range_list to
is_any_midr_in_range_listto explicitly mean "if any target impl CPU is
in range_list" and additionally introduce is_midr_subset_of_range_list
for someone like is_spectre_bhb_safe to use.
This patch just show is_midr_subset_of_range_list and it's example usage.
[1] https://lore.kernel.org/kvmarm/86cyftty9q.wl-maz@kernel.org/
[2] https://lore.kernel.org/kvmarm/ZyG3FiUiyOi4t3rQ@linux.dev/
Fixes: 86edf6bdcf05 ("smccc/kvm_guest: Enable errata based on implementation CPUs")
Signed-off-by: Jia Qingtong <jiaqingtong@...wei.com>
---
arch/arm64/include/asm/cputype.h | 1 +
arch/arm64/kernel/cpu_errata.c | 41 +++++++++++++++++++++++++++++++-
arch/arm64/kernel/proton-pack.c | 4 ++--
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 661735616787..1339a2e37104 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -304,6 +304,7 @@ struct target_impl_cpu {
bool cpu_errata_set_target_impl(u64 num, void *impl_cpus);
bool is_midr_in_range_list(struct midr_range const *ranges);
+bool is_midr_subset_of_range_list(struct midr_range const *ranges);
static inline u64 __attribute_const__ read_cpuid_mpidr(void)
{
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 59d723c9ab8f..30cc91f875d9 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -53,6 +53,45 @@ bool is_midr_in_range_list(struct midr_range const *ranges)
}
EXPORT_SYMBOL_GPL(is_midr_in_range_list);
+bool is_midr_subset_of_range_list(struct midr_range const *ranges)
+{
+ int i;
+ unsigned long midr;
+ struct midr_range const *range_ptr;
+
+ if (!target_impl_cpu_num) {
+ midr = read_cpuid_id();
+ range_ptr = ranges;
+ while (range_ptr->model) {
+ if (midr_is_cpu_model_range(midr, range_ptr->model,
+ range_ptr->rv_min, range_ptr->rv_max))
+ break;
+ range_ptr++;
+ }
+ return range_ptr->model != 0;
+ }
+
+ for (i = 0; i < target_impl_cpu_num; i++) {
+ bool found = false;
+
+ midr = target_impl_cpus[i].midr;
+ range_ptr = ranges;
+
+ while (range_ptr->model) {
+ if (midr_is_cpu_model_range(midr, range_ptr->model,
+ range_ptr->rv_min, range_ptr->rv_max)) {
+ found = true;
+ break;
+ }
+ range_ptr++;
+ }
+ if (!found)
+ return false;
+ }
+ return true;
+}
+EXPORT_SYMBOL_GPL(is_midr_subset_of_range_list);
+
static bool __maybe_unused
__is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
u32 midr, u32 revidr)
@@ -276,7 +315,7 @@ static bool has_impdef_pmuv3(const struct arm64_cpu_capabilities *entry, int sco
if (pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
return false;
- return is_midr_in_range_list(impdef_pmuv3_cpus);
+ return is_midr_subset_of_range_list(impdef_pmuv3_cpus);
}
static void cpu_enable_impdef_pmuv3_traps(const struct arm64_cpu_capabilities *__unused)
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index edf1783ffc81..ce3660625743 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -172,7 +172,7 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void)
return SPECTRE_UNAFFECTED;
/* Alternatively, we have a list of unaffected CPUs */
- if (is_midr_in_range_list(spectre_v2_safe_list))
+ if (is_midr_subset_of_range_list(spectre_v2_safe_list))
return SPECTRE_UNAFFECTED;
return SPECTRE_VULNERABLE;
@@ -864,7 +864,7 @@ static bool is_spectre_bhb_safe(int scope)
if (scope != SCOPE_LOCAL_CPU)
return all_safe;
- if (is_midr_in_range_list(spectre_bhb_safe_list))
+ if (is_midr_subset_of_range_list(spectre_bhb_safe_list))
return true;
all_safe = false;
base-commit: d69eb204c255c35abd9e8cb621484e8074c75eaa
--
2.51.0
Powered by blists - more mailing lists