Skip to content

Commit 04df08e

Browse files
committed
Merge branch 'bits/030-misc' into asahi-wip
2 parents ed310ef + dcbd8b9 commit 04df08e

38 files changed

Lines changed: 596 additions & 187 deletions

File tree

arch/arm64/include/asm/apple_m1_pmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define PMCR0_PMI_ENABLE_8_9 GENMASK(45, 44)
3838

3939
#define SYS_IMP_APL_PMCR1_EL1 sys_reg(3, 1, 15, 1, 0)
40+
#define SYS_IMP_APL_PMCR1_EL12 sys_reg(3, 1, 15, 7, 2)
4041
#define PMCR1_COUNT_A64_EL0_0_7 GENMASK(15, 8)
4142
#define PMCR1_COUNT_A64_EL1_0_7 GENMASK(23, 16)
4243
#define PMCR1_COUNT_A64_EL0_8_9 GENMASK(41, 40)

arch/arm64/include/asm/cpucaps.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ cpucap_is_possible(const unsigned int cap)
7171
* KVM MPAM support doesn't rely on the host kernel supporting MPAM.
7272
*/
7373
return true;
74+
case ARM64_HAS_PMUV3:
75+
return IS_ENABLED(CONFIG_HW_PERF_EVENTS);
7476
}
7577

7678
return true;

arch/arm64/include/asm/cpufeature.h

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -525,29 +525,6 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
525525
return cpuid_feature_extract_unsigned_field_width(features, field, 4);
526526
}
527527

528-
/*
529-
* Fields that identify the version of the Performance Monitors Extension do
530-
* not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825,
531-
* "Alternative ID scheme used for the Performance Monitors Extension version".
532-
*/
533-
static inline u64 __attribute_const__
534-
cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
535-
{
536-
u64 val = cpuid_feature_extract_unsigned_field(features, field);
537-
u64 mask = GENMASK_ULL(field + 3, field);
538-
539-
/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
540-
if (val == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
541-
val = 0;
542-
543-
if (val > cap) {
544-
features &= ~mask;
545-
features |= (cap << field) & mask;
546-
}
547-
548-
return features;
549-
}
550-
551528
static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
552529
{
553530
return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
@@ -866,6 +843,11 @@ static __always_inline bool system_supports_mpam_hcr(void)
866843
return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
867844
}
868845

846+
static inline bool system_supports_pmuv3(void)
847+
{
848+
return cpus_have_final_cap(ARM64_HAS_PMUV3);
849+
}
850+
869851
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
870852
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
871853

arch/arm64/include/asm/memory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112

113113
#define DIRECT_MAP_PHYSMEM_END __pa(PAGE_END - 1)
114114

115-
#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT)
115+
#define MIN_THREAD_SHIFT (15 + KASAN_THREAD_SHIFT)
116116

117117
/*
118118
* VMAP'd stacks are allocated at page granularity, so we must ensure that such

arch/arm64/kernel/cpu_errata.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,43 @@ has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
194194
return is_midr_in_range(midr, &range) && has_dic;
195195
}
196196

197+
static const struct midr_range impdef_pmuv3_cpus[] = {
198+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
199+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
200+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_PRO),
201+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_PRO),
202+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_MAX),
203+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_MAX),
204+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
205+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
206+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),
207+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO),
208+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX),
209+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX),
210+
{},
211+
};
212+
213+
static bool has_impdef_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
214+
{
215+
u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
216+
unsigned int pmuver;
217+
218+
if (!is_kernel_in_hyp_mode())
219+
return false;
220+
221+
pmuver = cpuid_feature_extract_unsigned_field(dfr0,
222+
ID_AA64DFR0_EL1_PMUVer_SHIFT);
223+
if (pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
224+
return false;
225+
226+
return is_midr_in_range_list(read_cpuid_id(), impdef_pmuv3_cpus);
227+
}
228+
229+
static void cpu_enable_impdef_pmuv3_traps(const struct arm64_cpu_capabilities *__unused)
230+
{
231+
sysreg_clear_set_s(SYS_HACR_EL2, 0, BIT(56));
232+
}
233+
197234
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
198235
static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
199236
#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
@@ -786,6 +823,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
786823
ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
787824
},
788825
#endif
826+
{
827+
.desc = "Apple IMPDEF PMUv3 Traps",
828+
.capability = ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS,
829+
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
830+
.matches = has_impdef_pmuv3,
831+
.cpu_enable = cpu_enable_impdef_pmuv3_traps,
832+
},
789833
{
790834
.desc = "Broken CNTVOFF_EL2",
791835
.capability = ARM64_WORKAROUND_QCOM_ORYON_CNTVOFF,

arch/arm64/kernel/cpufeature.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,26 @@ static bool has_lpa2(const struct arm64_cpu_capabilities *entry, int scope)
18981898
}
18991899
#endif
19001900

1901+
static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
1902+
{
1903+
u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
1904+
unsigned int pmuver;
1905+
1906+
/*
1907+
* PMUVer follows the standard ID scheme for an unsigned field with the
1908+
* exception of 0xF (IMP_DEF) which is treated specially and implies
1909+
* FEAT_PMUv3 is not implemented.
1910+
*
1911+
* See DDI0487L.a D24.1.3.2 for more details.
1912+
*/
1913+
pmuver = cpuid_feature_extract_unsigned_field(dfr0,
1914+
ID_AA64DFR0_EL1_PMUVer_SHIFT);
1915+
if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
1916+
return false;
1917+
1918+
return pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP;
1919+
}
1920+
19011921
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
19021922
#define KPTI_NG_TEMP_VA (-(1UL << PMD_SHIFT))
19031923

@@ -2998,6 +3018,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
29983018
.matches = has_cpuid_feature,
29993019
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
30003020
},
3021+
#endif
3022+
#ifdef CONFIG_HW_PERF_EVENTS
3023+
{
3024+
.desc = "PMUv3",
3025+
.capability = ARM64_HAS_PMUV3,
3026+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
3027+
.matches = has_pmuv3,
3028+
},
30013029
#endif
30023030
{},
30033031
};

arch/arm64/kernel/image-vars.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,6 @@ KVM_NVHE_ALIAS(broken_cntvoff_key);
112112
KVM_NVHE_ALIAS(__start___kvm_ex_table);
113113
KVM_NVHE_ALIAS(__stop___kvm_ex_table);
114114

115-
/* PMU available static key */
116-
#ifdef CONFIG_HW_PERF_EVENTS
117-
KVM_NVHE_ALIAS(kvm_arm_pmu_available);
118-
#endif
119-
120115
/* Position-independent library routines */
121116
KVM_NVHE_ALIAS_HYP(clear_page, __pi_clear_page);
122117
KVM_NVHE_ALIAS_HYP(copy_page, __pi_copy_page);

arch/arm64/kvm/arm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
366366
r = get_num_wrps();
367367
break;
368368
case KVM_CAP_ARM_PMU_V3:
369-
r = kvm_arm_support_pmu_v3();
369+
r = kvm_supports_guest_pmuv3();
370370
break;
371371
case KVM_CAP_ARM_INJECT_SERROR_ESR:
372372
r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
@@ -1390,7 +1390,7 @@ static unsigned long system_supported_vcpu_features(void)
13901390
if (!cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
13911391
clear_bit(KVM_ARM_VCPU_EL1_32BIT, &features);
13921392

1393-
if (!kvm_arm_support_pmu_v3())
1393+
if (!kvm_supports_guest_pmuv3())
13941394
clear_bit(KVM_ARM_VCPU_PMU_V3, &features);
13951395

13961396
if (!system_supports_sve())

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
244244
* counter, which could make a PMXEVCNTR_EL0 access UNDEF at
245245
* EL1 instead of being trapped to EL2.
246246
*/
247-
if (kvm_arm_support_pmu_v3()) {
247+
if (system_supports_pmuv3()) {
248248
struct kvm_cpu_context *hctxt;
249249

250250
write_sysreg(0, pmselr_el0);
@@ -281,7 +281,7 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
281281
write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
282282

283283
write_sysreg(0, hstr_el2);
284-
if (kvm_arm_support_pmu_v3()) {
284+
if (system_supports_pmuv3()) {
285285
struct kvm_cpu_context *hctxt;
286286

287287
hctxt = host_data_ptr(host_ctxt);

arch/arm64/kvm/hyp/vhe/switch.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,25 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
527527
return kvm_hyp_handle_sysreg(vcpu, exit_code);
528528
}
529529

530+
static bool kvm_hyp_handle_impdef(struct kvm_vcpu *vcpu, u64 *exit_code)
531+
{
532+
u64 iss;
533+
534+
if (!cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
535+
return false;
536+
537+
/*
538+
* Compute a synthetic ESR for a sysreg trap. Conveniently, AFSR1_EL2
539+
* is populated with a correct ISS for a sysreg trap. These fruity
540+
* parts are 64bit only, so unconditionally set IL.
541+
*/
542+
iss = ESR_ELx_ISS(read_sysreg_s(SYS_AFSR1_EL2));
543+
vcpu->arch.fault.esr_el2 = FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SYS64) |
544+
FIELD_PREP(ESR_ELx_ISS_MASK, iss) |
545+
ESR_ELx_IL;
546+
return false;
547+
}
548+
530549
static const exit_handler_fn hyp_exit_handlers[] = {
531550
[0 ... ESR_ELx_EC_MAX] = NULL,
532551
[ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32,
@@ -538,6 +557,9 @@ static const exit_handler_fn hyp_exit_handlers[] = {
538557
[ESR_ELx_EC_WATCHPT_LOW] = kvm_hyp_handle_watchpt_low,
539558
[ESR_ELx_EC_ERET] = kvm_hyp_handle_eret,
540559
[ESR_ELx_EC_MOPS] = kvm_hyp_handle_mops,
560+
561+
/* Apple shenanigans */
562+
[0x3F] = kvm_hyp_handle_impdef,
541563
};
542564

543565
static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)

0 commit comments

Comments
 (0)