Skip to content

Commit 6bb5412

Browse files
committed
Merge branch 'bits/030-misc' into asahi-wip
2 parents 221c1fa + c90d1ee commit 6bb5412

39 files changed

Lines changed: 708 additions & 191 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/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
}
791835
};

arch/arm64/kernel/cpufeature.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,19 @@ static bool has_lpa2(const struct arm64_cpu_capabilities *entry, int scope)
18761876
}
18771877
#endif
18781878

1879+
static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
1880+
{
1881+
u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
1882+
unsigned int pmuver;
1883+
1884+
pmuver = cpuid_feature_extract_unsigned_field(dfr0,
1885+
ID_AA64DFR0_EL1_PMUVer_SHIFT);
1886+
if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
1887+
return false;
1888+
1889+
return pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP;
1890+
}
1891+
18791892
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
18801893
#define KPTI_NG_TEMP_VA (-(1UL << PMD_SHIFT))
18811894

@@ -2977,6 +2990,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
29772990
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
29782991
},
29792992
#endif
2993+
{
2994+
.desc = "PMUv3",
2995+
.capability = ARM64_HAS_PMUV3,
2996+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
2997+
.matches = has_pmuv3,
2998+
},
29802999
{},
29813000
};
29823001

arch/arm64/kernel/image-vars.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,6 @@ KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
109109
KVM_NVHE_ALIAS(__start___kvm_ex_table);
110110
KVM_NVHE_ALIAS(__stop___kvm_ex_table);
111111

112-
/* PMU available static key */
113-
#ifdef CONFIG_HW_PERF_EVENTS
114-
KVM_NVHE_ALIAS(kvm_arm_pmu_available);
115-
#endif
116-
117112
/* Position-independent library routines */
118113
KVM_NVHE_ALIAS_HYP(clear_page, __pi_clear_page);
119114
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
@@ -391,7 +391,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
391391
r = get_num_wrps();
392392
break;
393393
case KVM_CAP_ARM_PMU_V3:
394-
r = kvm_arm_support_pmu_v3();
394+
r = kvm_supports_guest_pmuv3();
395395
break;
396396
case KVM_CAP_ARM_INJECT_SERROR_ESR:
397397
r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
@@ -1395,7 +1395,7 @@ static unsigned long system_supported_vcpu_features(void)
13951395
if (!cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
13961396
clear_bit(KVM_ARM_VCPU_EL1_32BIT, &features);
13971397

1398-
if (!kvm_arm_support_pmu_v3())
1398+
if (!kvm_supports_guest_pmuv3())
13991399
clear_bit(KVM_ARM_VCPU_PMU_V3, &features);
14001400

14011401
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
@@ -418,6 +418,25 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
418418
return kvm_hyp_handle_sysreg(vcpu, exit_code);
419419
}
420420

421+
static bool kvm_hyp_handle_impdef(struct kvm_vcpu *vcpu, u64 *exit_code)
422+
{
423+
u64 iss;
424+
425+
if (!cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
426+
return false;
427+
428+
/*
429+
* Compute a synthetic ESR for a sysreg trap. Conveniently, AFSR1_EL2
430+
* is populated with a correct ISS for a sysreg trap. These fruity
431+
* parts are 64bit only, so unconditionally set IL.
432+
*/
433+
iss = ESR_ELx_ISS(read_sysreg_s(SYS_AFSR1_EL2));
434+
vcpu->arch.fault.esr_el2 = FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SYS64) |
435+
FIELD_PREP(ESR_ELx_ISS_MASK, iss) |
436+
ESR_ELx_IL;
437+
return false;
438+
}
439+
421440
static const exit_handler_fn hyp_exit_handlers[] = {
422441
[0 ... ESR_ELx_EC_MAX] = NULL,
423442
[ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32,
@@ -429,6 +448,9 @@ static const exit_handler_fn hyp_exit_handlers[] = {
429448
[ESR_ELx_EC_WATCHPT_LOW] = kvm_hyp_handle_watchpt_low,
430449
[ESR_ELx_EC_ERET] = kvm_hyp_handle_eret,
431450
[ESR_ELx_EC_MOPS] = kvm_hyp_handle_mops,
451+
452+
/* Apple shenanigans */
453+
[0x3F] = kvm_hyp_handle_impdef,
432454
};
433455

434456
static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)

0 commit comments

Comments
 (0)