You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'arch-timer-errata' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into clockevents/4.12
arm64 arch timer workaround series, including the base patches that will also go via the arm64 tree. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
This commit is contained in:
@@ -54,6 +54,7 @@ stable kernels.
|
||||
| ARM | Cortex-A57 | #852523 | N/A |
|
||||
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/bug.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <clocksource/arm_arch_timer.h>
|
||||
@@ -37,24 +38,44 @@ extern struct static_key_false arch_timer_read_ool_enabled;
|
||||
#define needs_unstable_timer_counter_workaround() false
|
||||
#endif
|
||||
|
||||
enum arch_timer_erratum_match_type {
|
||||
ate_match_dt,
|
||||
ate_match_local_cap_id,
|
||||
ate_match_acpi_oem_info,
|
||||
};
|
||||
|
||||
struct clock_event_device;
|
||||
|
||||
struct arch_timer_erratum_workaround {
|
||||
const char *id; /* Indicate the Erratum ID */
|
||||
enum arch_timer_erratum_match_type match_type;
|
||||
const void *id;
|
||||
const char *desc;
|
||||
u32 (*read_cntp_tval_el0)(void);
|
||||
u32 (*read_cntv_tval_el0)(void);
|
||||
u64 (*read_cntvct_el0)(void);
|
||||
int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
|
||||
int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
|
||||
};
|
||||
|
||||
extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
|
||||
DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
|
||||
timer_unstable_counter_workaround);
|
||||
|
||||
#define arch_timer_reg_read_stable(reg) \
|
||||
({ \
|
||||
u64 _val; \
|
||||
if (needs_unstable_timer_counter_workaround()) \
|
||||
_val = timer_unstable_counter_workaround->read_##reg();\
|
||||
else \
|
||||
_val = read_sysreg(reg); \
|
||||
_val; \
|
||||
#define arch_timer_reg_read_stable(reg) \
|
||||
({ \
|
||||
u64 _val; \
|
||||
if (needs_unstable_timer_counter_workaround()) { \
|
||||
const struct arch_timer_erratum_workaround *wa; \
|
||||
preempt_disable(); \
|
||||
wa = __this_cpu_read(timer_unstable_counter_workaround); \
|
||||
if (wa && wa->read_##reg) \
|
||||
_val = wa->read_##reg(); \
|
||||
else \
|
||||
_val = read_sysreg(reg); \
|
||||
preempt_enable(); \
|
||||
} else { \
|
||||
_val = read_sysreg(reg); \
|
||||
} \
|
||||
_val; \
|
||||
})
|
||||
|
||||
/*
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
#define ARM64_HAS_NO_FPSIMD 16
|
||||
#define ARM64_WORKAROUND_REPEAT_TLBI 17
|
||||
#define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18
|
||||
#define ARM64_WORKAROUND_858921 19
|
||||
|
||||
#define ARM64_NCAPS 19
|
||||
#define ARM64_NCAPS 20
|
||||
|
||||
#endif /* __ASM_CPUCAPS_H */
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#define ARM_CPU_PART_FOUNDATION 0xD00
|
||||
#define ARM_CPU_PART_CORTEX_A57 0xD07
|
||||
#define ARM_CPU_PART_CORTEX_A53 0xD03
|
||||
#define ARM_CPU_PART_CORTEX_A73 0xD09
|
||||
|
||||
#define APM_CPU_PART_POTENZA 0x000
|
||||
|
||||
@@ -92,6 +93,7 @@
|
||||
|
||||
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
|
||||
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
|
||||
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||
#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1)
|
||||
|
||||
@@ -175,6 +175,8 @@
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/types.h>
|
||||
|
||||
|
||||
@@ -53,6 +53,13 @@ static int cpu_enable_trap_ctr_access(void *__unused)
|
||||
.midr_range_min = min, \
|
||||
.midr_range_max = max
|
||||
|
||||
#define MIDR_ALL_VERSIONS(model) \
|
||||
.def_scope = SCOPE_LOCAL_CPU, \
|
||||
.matches = is_affected_midr_range, \
|
||||
.midr_model = model, \
|
||||
.midr_range_min = 0, \
|
||||
.midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
|
||||
|
||||
const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
#if defined(CONFIG_ARM64_ERRATUM_826319) || \
|
||||
defined(CONFIG_ARM64_ERRATUM_827319) || \
|
||||
@@ -150,6 +157,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
MIDR_CPU_VAR_REV(0, 0),
|
||||
MIDR_CPU_VAR_REV(0, 0)),
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_ERRATUM_858921
|
||||
{
|
||||
/* Cortex-A73 all versions */
|
||||
.desc = "ARM erratum 858921",
|
||||
.capability = ARM64_WORKAROUND_858921,
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
|
||||
},
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1090,20 +1090,29 @@ static void __init setup_feature_capabilities(void)
|
||||
* Check if the current CPU has a given feature capability.
|
||||
* Should be called from non-preemptible context.
|
||||
*/
|
||||
bool this_cpu_has_cap(unsigned int cap)
|
||||
static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array,
|
||||
unsigned int cap)
|
||||
{
|
||||
const struct arm64_cpu_capabilities *caps;
|
||||
|
||||
if (WARN_ON(preemptible()))
|
||||
return false;
|
||||
|
||||
for (caps = arm64_features; caps->desc; caps++)
|
||||
for (caps = cap_array; caps->desc; caps++)
|
||||
if (caps->capability == cap && caps->matches)
|
||||
return caps->matches(caps, SCOPE_LOCAL_CPU);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extern const struct arm64_cpu_capabilities arm64_errata[];
|
||||
|
||||
bool this_cpu_has_cap(unsigned int cap)
|
||||
{
|
||||
return (__this_cpu_has_cap(arm64_features, cap) ||
|
||||
__this_cpu_has_cap(arm64_errata, cap));
|
||||
}
|
||||
|
||||
void __init setup_cpu_features(void)
|
||||
{
|
||||
u32 cwg;
|
||||
|
||||
@@ -505,6 +505,14 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs)
|
||||
regs->pc += 4;
|
||||
}
|
||||
|
||||
static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
|
||||
|
||||
pt_regs_write_reg(regs, rt, arch_counter_get_cntvct());
|
||||
regs->pc += 4;
|
||||
}
|
||||
|
||||
struct sys64_hook {
|
||||
unsigned int esr_mask;
|
||||
unsigned int esr_val;
|
||||
@@ -523,6 +531,12 @@ static struct sys64_hook sys64_hooks[] = {
|
||||
.esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ,
|
||||
.handler = ctr_read_handler,
|
||||
},
|
||||
{
|
||||
/* Trap read access to CNTVCT_EL0 */
|
||||
.esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
|
||||
.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT,
|
||||
.handler = cntvct_read_handler,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
@@ -368,6 +368,17 @@ config HISILICON_ERRATUM_161010101
|
||||
161010101. The workaround will be active if the hisilicon,erratum-161010101
|
||||
property is found in the timer node.
|
||||
|
||||
config ARM64_ERRATUM_858921
|
||||
bool "Workaround for Cortex-A73 erratum 858921"
|
||||
default y
|
||||
select ARM_ARCH_TIMER_OOL_WORKAROUND
|
||||
depends on ARM_ARCH_TIMER && ARM64
|
||||
help
|
||||
This option enables a workaround applicable to Cortex-A73
|
||||
(all versions), whose counter may return incorrect values.
|
||||
The workaround will be dynamically enabled when an affected
|
||||
core is detected.
|
||||
|
||||
config ARM_GLOBAL_TIMER
|
||||
bool "Support for the ARM global timer" if COMPILE_TEST
|
||||
select CLKSRC_OF if OF
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user