All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] clocksource/arch_timer: Errata workaround infrastructure rework
@ 2017-03-20 17:48 ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

It has recently become obvious that a number of arm64 systems have
been blessed with a set of timers that are slightly less than perfect,
and require a bit of hand-holding. We already have a bunch of
errata-specific code to deal with this, but as we're adding more
potential detection methods (DT, ACPI, capability), things are getting
a bit out of hands.

Instead of adding more ad-hoc fixes to an already difficult code base,
let's give ourselves a bit of an infrastructure that can deal with
this and hide most of the uggliness behind frendly accessors.

The series is structured as such:

- A bunch of arm64 specific patches that allow the rest of the
  workaround infrastructure to be built upon (such as being able to
  trap userspace access to the virtual counter). These are now
  separate in order to allow the creation of a shared branch between
  the arm64 and clocksource trees.

- The following patches rework the existing workarounds, allowing
  errata to be matched using a given detection method

- Another patch allows a workaround to affect a subset of the CPUs,
  and not the whole system

- We then work around a Cortex-A73 erratum, whose counter can return a
  wrong value if read while crossing a 32bit boundary

- Finally, we add some ACPI-specific workarounds for HiSilicon
  platforms that have the HISILICON_ERRATUM_161010101 defect.

Note that so far, we only deal with arm64. Once the infrastructure is
agreed upon, we can look at generalizing it (to some extent) to 32bit
ARM (typical use case would be a 32bit guest running on an affected
host).

* From v1:
  - Addressed Hanjun and Mark review comments
  - Moved arm64 specific patches to the beginning of the series,
    leaving the clocksource patches at the end, resulting in an extra
    patch.
  - Added RBs, TBs, and Acks.

Marc Zyngier (18):
  arm64: Allow checking of a CPU-local erratum
  arm64: Add CNTVCT_EL0 trap handler
  arm64: Define Cortex-A73 MIDR
  arm64: cpu_errata: Allow an erratum to be match for all revisions of a
    core
  arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum
    858921
  arm64: arch_timer: Add infrastructure for multiple erratum detection
    methods
  arm64: arch_timer: Add erratum handler for globally defined capability
  arm64: arch_timer: Add erratum handler for CPU-specific capability
  arm64: arch_timer: Move arch_timer_reg_read/write around
  arm64: arch_timer: Get rid of erratum_workaround_set_sne
  arm64: arch_timer: Rework the set_next_event workarounds
  arm64: arch_timer: Make workaround methods optional
  arm64: arch_timer: Allows a CPU-specific erratum to only affect a
    subset of CPUs
  arm64: arch_timer: Move clocksource_counter and co around
  arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled
  arm64: arch_timer: Workaround for Cortex-A73 erratum 858921
  arm64: arch_timer: Allow erratum matching with ACPI OEM information
  arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data

 Documentation/arm64/silicon-errata.txt |   1 +
 arch/arm64/include/asm/arch_timer.h    |  44 ++-
 arch/arm64/include/asm/cpucaps.h       |   3 +-
 arch/arm64/include/asm/cputype.h       |   2 +
 arch/arm64/include/asm/esr.h           |   2 +
 arch/arm64/kernel/cpu_errata.c         |  15 +
 arch/arm64/kernel/cpufeature.c         |  13 +-
 arch/arm64/kernel/traps.c              |  14 +
 drivers/clocksource/Kconfig            |  11 +
 drivers/clocksource/arm_arch_timer.c   | 535 +++++++++++++++++++++++----------
 10 files changed, 471 insertions(+), 169 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 00/18] clocksource/arch_timer: Errata workaround infrastructure rework
@ 2017-03-20 17:48 ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

It has recently become obvious that a number of arm64 systems have
been blessed with a set of timers that are slightly less than perfect,
and require a bit of hand-holding. We already have a bunch of
errata-specific code to deal with this, but as we're adding more
potential detection methods (DT, ACPI, capability), things are getting
a bit out of hands.

Instead of adding more ad-hoc fixes to an already difficult code base,
let's give ourselves a bit of an infrastructure that can deal with
this and hide most of the uggliness behind frendly accessors.

The series is structured as such:

- A bunch of arm64 specific patches that allow the rest of the
  workaround infrastructure to be built upon (such as being able to
  trap userspace access to the virtual counter). These are now
  separate in order to allow the creation of a shared branch between
  the arm64 and clocksource trees.

- The following patches rework the existing workarounds, allowing
  errata to be matched using a given detection method

- Another patch allows a workaround to affect a subset of the CPUs,
  and not the whole system

- We then work around a Cortex-A73 erratum, whose counter can return a
  wrong value if read while crossing a 32bit boundary

- Finally, we add some ACPI-specific workarounds for HiSilicon
  platforms that have the HISILICON_ERRATUM_161010101 defect.

Note that so far, we only deal with arm64. Once the infrastructure is
agreed upon, we can look at generalizing it (to some extent) to 32bit
ARM (typical use case would be a 32bit guest running on an affected
host).

* From v1:
  - Addressed Hanjun and Mark review comments
  - Moved arm64 specific patches to the beginning of the series,
    leaving the clocksource patches at the end, resulting in an extra
    patch.
  - Added RBs, TBs, and Acks.

Marc Zyngier (18):
  arm64: Allow checking of a CPU-local erratum
  arm64: Add CNTVCT_EL0 trap handler
  arm64: Define Cortex-A73 MIDR
  arm64: cpu_errata: Allow an erratum to be match for all revisions of a
    core
  arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum
    858921
  arm64: arch_timer: Add infrastructure for multiple erratum detection
    methods
  arm64: arch_timer: Add erratum handler for globally defined capability
  arm64: arch_timer: Add erratum handler for CPU-specific capability
  arm64: arch_timer: Move arch_timer_reg_read/write around
  arm64: arch_timer: Get rid of erratum_workaround_set_sne
  arm64: arch_timer: Rework the set_next_event workarounds
  arm64: arch_timer: Make workaround methods optional
  arm64: arch_timer: Allows a CPU-specific erratum to only affect a
    subset of CPUs
  arm64: arch_timer: Move clocksource_counter and co around
  arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled
  arm64: arch_timer: Workaround for Cortex-A73 erratum 858921
  arm64: arch_timer: Allow erratum matching with ACPI OEM information
  arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data

 Documentation/arm64/silicon-errata.txt |   1 +
 arch/arm64/include/asm/arch_timer.h    |  44 ++-
 arch/arm64/include/asm/cpucaps.h       |   3 +-
 arch/arm64/include/asm/cputype.h       |   2 +
 arch/arm64/include/asm/esr.h           |   2 +
 arch/arm64/kernel/cpu_errata.c         |  15 +
 arch/arm64/kernel/cpufeature.c         |  13 +-
 arch/arm64/kernel/traps.c              |  14 +
 drivers/clocksource/Kconfig            |  11 +
 drivers/clocksource/arm_arch_timer.c   | 535 +++++++++++++++++++++++----------
 10 files changed, 471 insertions(+), 169 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 01/18] arm64: Allow checking of a CPU-local erratum
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

this_cpu_has_cap() only checks the feature array, and not the errata
one. In order to be able to check for a CPU-local erratum, allow it
to inspect the latter as well.

This is consistent with cpus_have_cap()'s behaviour, which includes
errata already.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/cpufeature.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index abda8e861865..6eb77ae99b79 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -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;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 01/18] arm64: Allow checking of a CPU-local erratum
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

this_cpu_has_cap() only checks the feature array, and not the errata
one. In order to be able to check for a CPU-local erratum, allow it
to inspect the latter as well.

This is consistent with cpus_have_cap()'s behaviour, which includes
errata already.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/cpufeature.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index abda8e861865..6eb77ae99b79 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -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;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 02/18] arm64: Add CNTVCT_EL0 trap handler
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Since people seem to make a point in breaking the userspace visible
counter, we have no choice but to trap the access. Add the required
handler.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/esr.h |  2 ++
 arch/arm64/kernel/traps.c    | 14 ++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d14c478976d0..ad42e79a5d4d 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -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>
 
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index e52be6aa44ee..1de444e6c669 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -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,
+	},
 	{},
 };
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 02/18] arm64: Add CNTVCT_EL0 trap handler
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Since people seem to make a point in breaking the userspace visible
counter, we have no choice but to trap the access. Add the required
handler.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/esr.h |  2 ++
 arch/arm64/kernel/traps.c    | 14 ++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d14c478976d0..ad42e79a5d4d 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -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>
 
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index e52be6aa44ee..1de444e6c669 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -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,
+	},
 	{},
 };
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 03/18] arm64: Define Cortex-A73 MIDR
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

As we're about to introduce a new workaround that is specific to
Cortex-A73, let's define the coresponding MIDR.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index fc502713ab37..0984d1b3a8f2 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.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)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 03/18] arm64: Define Cortex-A73 MIDR
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

As we're about to introduce a new workaround that is specific to
Cortex-A73, let's define the coresponding MIDR.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index fc502713ab37..0984d1b3a8f2 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.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)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 04/18] arm64: cpu_errata: Allow an erratum to be match for all revisions of a core
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Some minor erratum may not be fixed in further revisions of a core,
leading to a situation where the workaround needs to be updated each
time an updated core is released.

Introduce a MIDR_ALL_VERSIONS match helper that will work for all
versions of that MIDR, once and for all.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/cpu_errata.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index f6cc67e7626e..2be1d1c05303 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -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) || \
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 04/18] arm64: cpu_errata: Allow an erratum to be match for all revisions of a core
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Some minor erratum may not be fixed in further revisions of a core,
leading to a situation where the workaround needs to be updated each
time an updated core is released.

Introduce a MIDR_ALL_VERSIONS match helper that will work for all
versions of that MIDR, once and for all.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/cpu_errata.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index f6cc67e7626e..2be1d1c05303 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -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) || \
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 05/18] arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum 858921
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

In order to work around Cortex-A73 erratum 858921 in a subsequent
patch, add the required capability that advertise the erratum.

As the configuration option it depends on is not present yet,
this has no immediate effect.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 Documentation/arm64/silicon-errata.txt | 1 +
 arch/arm64/include/asm/cpucaps.h       | 3 ++-
 arch/arm64/kernel/cpu_errata.c         | 8 ++++++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 2f66683500b8..10f2dddbf449 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -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        |
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index fb78a5d3b60b..b3aab8a17868 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -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 */
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 2be1d1c05303..2ed2a7657711 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -158,6 +158,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 			   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
 	{
 	}
 };
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 05/18] arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum 858921
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

In order to work around Cortex-A73 erratum 858921 in a subsequent
patch, add the required capability that advertise the erratum.

As the configuration option it depends on is not present yet,
this has no immediate effect.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 Documentation/arm64/silicon-errata.txt | 1 +
 arch/arm64/include/asm/cpucaps.h       | 3 ++-
 arch/arm64/kernel/cpu_errata.c         | 8 ++++++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 2f66683500b8..10f2dddbf449 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -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        |
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index fb78a5d3b60b..b3aab8a17868 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -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 */
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 2be1d1c05303..2ed2a7657711 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -158,6 +158,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 			   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
 	{
 	}
 };
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

We're currently stuck with DT when it comes to handling errata, which
is pretty restrictive. In order to make things more flexible, let's
introduce an infrastructure that could support alternative discovery
methods. No change in functionality.

Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  7 +++-
 drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
 2 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index b4b34004a21e..5cd964e90d11 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -37,9 +37,14 @@ 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,
+};
 
 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);
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 7a8a4117f123..6a0f0e161a0f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
 static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 #ifdef CONFIG_FSL_ERRATUM_A008585
 	{
+		.match_type = ate_match_dt,
 		.id = "fsl,erratum-a008585",
+		.desc = "Freescale erratum a005858",
 		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
@@ -190,13 +192,78 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 #endif
 #ifdef CONFIG_HISILICON_ERRATUM_161010101
 	{
+		.match_type = ate_match_dt,
 		.id = "hisilicon,erratum-161010101",
+		.desc = "HiSilicon erratum 161010101",
 		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
 	},
 #endif
 };
+
+typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
+			       const void *);
+
+static
+bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
+				 const void *arg)
+{
+	const struct device_node *np = arg;
+
+	return of_property_read_bool(np, wa->id);
+}
+
+static const struct arch_timer_erratum_workaround *
+arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
+			  ate_match_fn_t match_fn,
+			  void *arg)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
+		if (ool_workarounds[i].match_type != type)
+			continue;
+
+		if (match_fn(&ool_workarounds[i], arg))
+			return &ool_workarounds[i];
+	}
+
+	return NULL;
+}
+
+static
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
+{
+	timer_unstable_counter_workaround = wa;
+	static_branch_enable(&arch_timer_read_ool_enabled);
+}
+
+static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
+					    void *arg)
+{
+	const struct arch_timer_erratum_workaround *wa;
+	ate_match_fn_t match_fn = NULL;
+
+	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
+		return;
+
+	switch (type) {
+	case ate_match_dt:
+		match_fn = arch_timer_check_dt_erratum;
+		break;
+	}
+
+	wa = arch_timer_iterate_errata(type, match_fn, arg);
+	if (!wa)
+		return;
+
+	arch_timer_enable_workaround(wa);
+	pr_info("Enabling global workaround for %s\n", wa->desc);
+}
+
+#else
+#define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline
@@ -960,17 +1027,8 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
 
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-	for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
-		if (of_property_read_bool(np, ool_workarounds[i].id)) {
-			timer_unstable_counter_workaround = &ool_workarounds[i];
-			static_branch_enable(&arch_timer_read_ool_enabled);
-			pr_info("arch_timer: Enabling workaround for %s\n",
-				timer_unstable_counter_workaround->id);
-			break;
-		}
-	}
-#endif
+	/* Check for globally applicable workarounds */
+	arch_timer_check_ool_workaround(ate_match_dt, np);
 
 	/*
 	 * If we cannot rely on firmware initializing the timer registers then
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

We're currently stuck with DT when it comes to handling errata, which
is pretty restrictive. In order to make things more flexible, let's
introduce an infrastructure that could support alternative discovery
methods. No change in functionality.

Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  7 +++-
 drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
 2 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index b4b34004a21e..5cd964e90d11 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -37,9 +37,14 @@ 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,
+};
 
 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);
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 7a8a4117f123..6a0f0e161a0f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
 static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 #ifdef CONFIG_FSL_ERRATUM_A008585
 	{
+		.match_type = ate_match_dt,
 		.id = "fsl,erratum-a008585",
+		.desc = "Freescale erratum a005858",
 		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
@@ -190,13 +192,78 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 #endif
 #ifdef CONFIG_HISILICON_ERRATUM_161010101
 	{
+		.match_type = ate_match_dt,
 		.id = "hisilicon,erratum-161010101",
+		.desc = "HiSilicon erratum 161010101",
 		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
 	},
 #endif
 };
+
+typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
+			       const void *);
+
+static
+bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
+				 const void *arg)
+{
+	const struct device_node *np = arg;
+
+	return of_property_read_bool(np, wa->id);
+}
+
+static const struct arch_timer_erratum_workaround *
+arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
+			  ate_match_fn_t match_fn,
+			  void *arg)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
+		if (ool_workarounds[i].match_type != type)
+			continue;
+
+		if (match_fn(&ool_workarounds[i], arg))
+			return &ool_workarounds[i];
+	}
+
+	return NULL;
+}
+
+static
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
+{
+	timer_unstable_counter_workaround = wa;
+	static_branch_enable(&arch_timer_read_ool_enabled);
+}
+
+static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
+					    void *arg)
+{
+	const struct arch_timer_erratum_workaround *wa;
+	ate_match_fn_t match_fn = NULL;
+
+	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
+		return;
+
+	switch (type) {
+	case ate_match_dt:
+		match_fn = arch_timer_check_dt_erratum;
+		break;
+	}
+
+	wa = arch_timer_iterate_errata(type, match_fn, arg);
+	if (!wa)
+		return;
+
+	arch_timer_enable_workaround(wa);
+	pr_info("Enabling global workaround for %s\n", wa->desc);
+}
+
+#else
+#define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline
@@ -960,17 +1027,8 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
 
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-	for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
-		if (of_property_read_bool(np, ool_workarounds[i].id)) {
-			timer_unstable_counter_workaround = &ool_workarounds[i];
-			static_branch_enable(&arch_timer_read_ool_enabled);
-			pr_info("arch_timer: Enabling workaround for %s\n",
-				timer_unstable_counter_workaround->id);
-			break;
-		}
-	}
-#endif
+	/* Check for globally applicable workarounds */
+	arch_timer_check_ool_workaround(ate_match_dt, np);
 
 	/*
 	 * If we cannot rely on firmware initializing the timer registers then
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 07/18] arm64: arch_timer: Add erratum handler for globally defined capability
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Should we ever have a workaround for an erratum that is detected using
a capability (and affecting the whole system), it'd be nice to have
a way to probe them directly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  1 +
 drivers/clocksource/arm_arch_timer.c | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 5cd964e90d11..48bd730d568f 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -39,6 +39,7 @@ extern struct static_key_false arch_timer_read_ool_enabled;
 
 enum arch_timer_erratum_match_type {
 	ate_match_dt,
+	ate_match_global_cap_id,
 };
 
 struct arch_timer_erratum_workaround {
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 6a0f0e161a0f..a0b1108a4a24 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -214,6 +214,13 @@ bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
 	return of_property_read_bool(np, wa->id);
 }
 
+static
+bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
+					 const void *arg)
+{
+	return cpus_have_cap((uintptr_t)wa->id);
+}
+
 static const struct arch_timer_erratum_workaround *
 arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 			  ate_match_fn_t match_fn,
@@ -252,6 +259,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 	case ate_match_dt:
 		match_fn = arch_timer_check_dt_erratum;
 		break;
+	case ate_match_global_cap_id:
+		match_fn = arch_timer_check_global_cap_erratum;
+		break;
 	}
 
 	wa = arch_timer_iterate_errata(type, match_fn, arg);
@@ -1029,6 +1039,7 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	/* Check for globally applicable workarounds */
 	arch_timer_check_ool_workaround(ate_match_dt, np);
+	arch_timer_check_ool_workaround(ate_match_global_cap_id, NULL);
 
 	/*
 	 * If we cannot rely on firmware initializing the timer registers then
@@ -1185,6 +1196,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 	/* Always-on capability */
 	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
 
+	/* Check for globally applicable workarounds */
+	arch_timer_check_ool_workaround(ate_match_global_cap_id, NULL);
+
 	arch_timer_init();
 	return 0;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 07/18] arm64: arch_timer: Add erratum handler for globally defined capability
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Should we ever have a workaround for an erratum that is detected using
a capability (and affecting the whole system), it'd be nice to have
a way to probe them directly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  1 +
 drivers/clocksource/arm_arch_timer.c | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 5cd964e90d11..48bd730d568f 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -39,6 +39,7 @@ extern struct static_key_false arch_timer_read_ool_enabled;
 
 enum arch_timer_erratum_match_type {
 	ate_match_dt,
+	ate_match_global_cap_id,
 };
 
 struct arch_timer_erratum_workaround {
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 6a0f0e161a0f..a0b1108a4a24 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -214,6 +214,13 @@ bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
 	return of_property_read_bool(np, wa->id);
 }
 
+static
+bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
+					 const void *arg)
+{
+	return cpus_have_cap((uintptr_t)wa->id);
+}
+
 static const struct arch_timer_erratum_workaround *
 arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 			  ate_match_fn_t match_fn,
@@ -252,6 +259,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 	case ate_match_dt:
 		match_fn = arch_timer_check_dt_erratum;
 		break;
+	case ate_match_global_cap_id:
+		match_fn = arch_timer_check_global_cap_erratum;
+		break;
 	}
 
 	wa = arch_timer_iterate_errata(type, match_fn, arg);
@@ -1029,6 +1039,7 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	/* Check for globally applicable workarounds */
 	arch_timer_check_ool_workaround(ate_match_dt, np);
+	arch_timer_check_ool_workaround(ate_match_global_cap_id, NULL);
 
 	/*
 	 * If we cannot rely on firmware initializing the timer registers then
@@ -1185,6 +1196,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 	/* Always-on capability */
 	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
 
+	/* Check for globally applicable workarounds */
+	arch_timer_check_ool_workaround(ate_match_global_cap_id, NULL);
+
 	arch_timer_init();
 	return 0;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 08/18] arm64: arch_timer: Add erratum handler for CPU-specific capability
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Should we ever have a workaround for an erratum that is detected using
a capability and affecting a particular CPU, it'd be nice to have
a way to probe them directly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  1 +
 drivers/clocksource/arm_arch_timer.c | 28 ++++++++++++++++++++++++----
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 48bd730d568f..e5325299aa6d 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -40,6 +40,7 @@ extern struct static_key_false arch_timer_read_ool_enabled;
 enum arch_timer_erratum_match_type {
 	ate_match_dt,
 	ate_match_global_cap_id,
+	ate_match_local_cap_id,
 };
 
 struct arch_timer_erratum_workaround {
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index a0b1108a4a24..5069cb3d4326 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -221,6 +221,13 @@ bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaro
 	return cpus_have_cap((uintptr_t)wa->id);
 }
 
+static
+bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workaround *wa,
+					const void *arg)
+{
+	return this_cpu_has_cap((uintptr_t)wa->id);
+}
+
 static const struct arch_timer_erratum_workaround *
 arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 			  ate_match_fn_t match_fn,
@@ -251,9 +258,7 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 {
 	const struct arch_timer_erratum_workaround *wa;
 	ate_match_fn_t match_fn = NULL;
-
-	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
-		return;
+	bool local = false;
 
 	switch (type) {
 	case ate_match_dt:
@@ -262,14 +267,27 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 	case ate_match_global_cap_id:
 		match_fn = arch_timer_check_global_cap_erratum;
 		break;
+	case ate_match_local_cap_id:
+		match_fn = arch_timer_check_local_cap_erratum;
+		local = true;
+		break;
 	}
 
 	wa = arch_timer_iterate_errata(type, match_fn, arg);
 	if (!wa)
 		return;
 
+	if (static_branch_unlikely(&arch_timer_read_ool_enabled)) {
+		if (wa != timer_unstable_counter_workaround)
+			pr_warn("Can't enable workaround for %s (clashes with %s\n)",
+				wa->desc,
+				timer_unstable_counter_workaround->desc);
+		return;
+	}
+
 	arch_timer_enable_workaround(wa);
-	pr_info("Enabling global workaround for %s\n", wa->desc);
+	pr_info("Enabling %s workaround for %s\n",
+		local ? "local" : "global", wa->desc);
 }
 
 #else
@@ -529,6 +547,8 @@ static void __arch_timer_setup(unsigned type,
 			BUG();
 		}
 
+		arch_timer_check_ool_workaround(ate_match_local_cap_id, NULL);
+
 		erratum_workaround_set_sne(clk);
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 08/18] arm64: arch_timer: Add erratum handler for CPU-specific capability
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Should we ever have a workaround for an erratum that is detected using
a capability and affecting a particular CPU, it'd be nice to have
a way to probe them directly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  1 +
 drivers/clocksource/arm_arch_timer.c | 28 ++++++++++++++++++++++++----
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 48bd730d568f..e5325299aa6d 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -40,6 +40,7 @@ extern struct static_key_false arch_timer_read_ool_enabled;
 enum arch_timer_erratum_match_type {
 	ate_match_dt,
 	ate_match_global_cap_id,
+	ate_match_local_cap_id,
 };
 
 struct arch_timer_erratum_workaround {
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index a0b1108a4a24..5069cb3d4326 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -221,6 +221,13 @@ bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaro
 	return cpus_have_cap((uintptr_t)wa->id);
 }
 
+static
+bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workaround *wa,
+					const void *arg)
+{
+	return this_cpu_has_cap((uintptr_t)wa->id);
+}
+
 static const struct arch_timer_erratum_workaround *
 arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 			  ate_match_fn_t match_fn,
@@ -251,9 +258,7 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 {
 	const struct arch_timer_erratum_workaround *wa;
 	ate_match_fn_t match_fn = NULL;
-
-	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
-		return;
+	bool local = false;
 
 	switch (type) {
 	case ate_match_dt:
@@ -262,14 +267,27 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 	case ate_match_global_cap_id:
 		match_fn = arch_timer_check_global_cap_erratum;
 		break;
+	case ate_match_local_cap_id:
+		match_fn = arch_timer_check_local_cap_erratum;
+		local = true;
+		break;
 	}
 
 	wa = arch_timer_iterate_errata(type, match_fn, arg);
 	if (!wa)
 		return;
 
+	if (static_branch_unlikely(&arch_timer_read_ool_enabled)) {
+		if (wa != timer_unstable_counter_workaround)
+			pr_warn("Can't enable workaround for %s (clashes with %s\n)",
+				wa->desc,
+				timer_unstable_counter_workaround->desc);
+		return;
+	}
+
 	arch_timer_enable_workaround(wa);
-	pr_info("Enabling global workaround for %s\n", wa->desc);
+	pr_info("Enabling %s workaround for %s\n",
+		local ? "local" : "global", wa->desc);
 }
 
 #else
@@ -529,6 +547,8 @@ static void __arch_timer_setup(unsigned type,
 			BUG();
 		}
 
+		arch_timer_check_ool_workaround(ate_match_local_cap_id, NULL);
+
 		erratum_workaround_set_sne(clk);
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 09/18] arm64: arch_timer: Move arch_timer_reg_read/write around
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

As we're about to move things around, let's start with the low
level read/write functions. This allows us to use these functions
in the errata handling code without having to use forward declaration
of static functions.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 124 +++++++++++++++++------------------
 1 file changed, 62 insertions(+), 62 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5069cb3d4326..e0e4b0e6825d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -96,6 +96,68 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
  * Architected system timer support.
  */
 
+static __always_inline
+void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
+			  struct clock_event_device *clk)
+{
+	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			writel_relaxed(val, timer->base + CNTP_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			writel_relaxed(val, timer->base + CNTP_TVAL);
+			break;
+		}
+	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			writel_relaxed(val, timer->base + CNTV_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			writel_relaxed(val, timer->base + CNTV_TVAL);
+			break;
+		}
+	} else {
+		arch_timer_reg_write_cp15(access, reg, val);
+	}
+}
+
+static __always_inline
+u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
+			struct clock_event_device *clk)
+{
+	u32 val;
+
+	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			val = readl_relaxed(timer->base + CNTP_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			val = readl_relaxed(timer->base + CNTP_TVAL);
+			break;
+		}
+	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			val = readl_relaxed(timer->base + CNTV_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			val = readl_relaxed(timer->base + CNTV_TVAL);
+			break;
+		}
+	} else {
+		val = arch_timer_reg_read_cp15(access, reg);
+	}
+
+	return val;
+}
+
 #ifdef CONFIG_FSL_ERRATUM_A008585
 /*
  * The number of retries is an arbitrary value well beyond the highest number
@@ -294,68 +356,6 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
-static __always_inline
-void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
-			  struct clock_event_device *clk)
-{
-	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			writel_relaxed(val, timer->base + CNTP_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed(val, timer->base + CNTP_TVAL);
-			break;
-		}
-	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			writel_relaxed(val, timer->base + CNTV_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed(val, timer->base + CNTV_TVAL);
-			break;
-		}
-	} else {
-		arch_timer_reg_write_cp15(access, reg, val);
-	}
-}
-
-static __always_inline
-u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
-			struct clock_event_device *clk)
-{
-	u32 val;
-
-	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			val = readl_relaxed(timer->base + CNTP_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			val = readl_relaxed(timer->base + CNTP_TVAL);
-			break;
-		}
-	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			val = readl_relaxed(timer->base + CNTV_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			val = readl_relaxed(timer->base + CNTV_TVAL);
-			break;
-		}
-	} else {
-		val = arch_timer_reg_read_cp15(access, reg);
-	}
-
-	return val;
-}
-
 static __always_inline irqreturn_t timer_handler(const int access,
 					struct clock_event_device *evt)
 {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 09/18] arm64: arch_timer: Move arch_timer_reg_read/write around
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

As we're about to move things around, let's start with the low
level read/write functions. This allows us to use these functions
in the errata handling code without having to use forward declaration
of static functions.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 124 +++++++++++++++++------------------
 1 file changed, 62 insertions(+), 62 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5069cb3d4326..e0e4b0e6825d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -96,6 +96,68 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
  * Architected system timer support.
  */
 
+static __always_inline
+void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
+			  struct clock_event_device *clk)
+{
+	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			writel_relaxed(val, timer->base + CNTP_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			writel_relaxed(val, timer->base + CNTP_TVAL);
+			break;
+		}
+	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			writel_relaxed(val, timer->base + CNTV_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			writel_relaxed(val, timer->base + CNTV_TVAL);
+			break;
+		}
+	} else {
+		arch_timer_reg_write_cp15(access, reg, val);
+	}
+}
+
+static __always_inline
+u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
+			struct clock_event_device *clk)
+{
+	u32 val;
+
+	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			val = readl_relaxed(timer->base + CNTP_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			val = readl_relaxed(timer->base + CNTP_TVAL);
+			break;
+		}
+	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
+		struct arch_timer *timer = to_arch_timer(clk);
+		switch (reg) {
+		case ARCH_TIMER_REG_CTRL:
+			val = readl_relaxed(timer->base + CNTV_CTL);
+			break;
+		case ARCH_TIMER_REG_TVAL:
+			val = readl_relaxed(timer->base + CNTV_TVAL);
+			break;
+		}
+	} else {
+		val = arch_timer_reg_read_cp15(access, reg);
+	}
+
+	return val;
+}
+
 #ifdef CONFIG_FSL_ERRATUM_A008585
 /*
  * The number of retries is an arbitrary value well beyond the highest number
@@ -294,68 +356,6 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
-static __always_inline
-void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
-			  struct clock_event_device *clk)
-{
-	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			writel_relaxed(val, timer->base + CNTP_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed(val, timer->base + CNTP_TVAL);
-			break;
-		}
-	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			writel_relaxed(val, timer->base + CNTV_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed(val, timer->base + CNTV_TVAL);
-			break;
-		}
-	} else {
-		arch_timer_reg_write_cp15(access, reg, val);
-	}
-}
-
-static __always_inline
-u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
-			struct clock_event_device *clk)
-{
-	u32 val;
-
-	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			val = readl_relaxed(timer->base + CNTP_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			val = readl_relaxed(timer->base + CNTP_TVAL);
-			break;
-		}
-	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
-		struct arch_timer *timer = to_arch_timer(clk);
-		switch (reg) {
-		case ARCH_TIMER_REG_CTRL:
-			val = readl_relaxed(timer->base + CNTV_CTL);
-			break;
-		case ARCH_TIMER_REG_TVAL:
-			val = readl_relaxed(timer->base + CNTV_TVAL);
-			break;
-		}
-	} else {
-		val = arch_timer_reg_read_cp15(access, reg);
-	}
-
-	return val;
-}
-
 static __always_inline irqreturn_t timer_handler(const int access,
 					struct clock_event_device *evt)
 {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 10/18] arm64: arch_timer: Get rid of erratum_workaround_set_sne
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Let's move the handling of workarounds affecting set_next_event
to the affected function, instead of overriding the pointers
as an afterthough. Yes, this is an extra indirection on the
erratum handling path, but the HW is busted anyway.

This will allow for some more flexibility later.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 89 ++++++++++++++++--------------------
 1 file changed, 40 insertions(+), 49 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index e0e4b0e6825d..4caafbdefb9d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -241,6 +241,38 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
 DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
 EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
 
+static void erratum_set_next_event_tval_generic(const int access, unsigned long evt,
+						struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+	u64 cval = evt + arch_counter_get_cntvct();
+
+	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
+	ctrl |= ARCH_TIMER_CTRL_ENABLE;
+	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
+
+	if (access == ARCH_TIMER_PHYS_ACCESS)
+		write_sysreg(cval, cntp_cval_el0);
+	else
+		write_sysreg(cval, cntv_cval_el0);
+
+	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
+}
+
+static int erratum_set_next_event_tval_virt(unsigned long evt,
+					    struct clock_event_device *clk)
+{
+	erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+	return 0;
+}
+
+static int erratum_set_next_event_tval_phys(unsigned long evt,
+					    struct clock_event_device *clk)
+{
+	erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+	return 0;
+}
+
 static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 #ifdef CONFIG_FSL_ERRATUM_A008585
 	{
@@ -354,6 +386,8 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 
 #else
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
+#define erratum_set_next_event_tval_virt(...)		({BUG(); 0;})
+#define erratum_set_next_event_tval_phys(...)		({BUG(); 0;})
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline irqreturn_t timer_handler(const int access,
@@ -443,43 +477,12 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-static __always_inline void erratum_set_next_event_generic(const int access,
-		unsigned long evt, struct clock_event_device *clk)
-{
-	unsigned long ctrl;
-	u64 cval = evt + arch_counter_get_cntvct();
-
-	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
-	ctrl |= ARCH_TIMER_CTRL_ENABLE;
-	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
-
-	if (access == ARCH_TIMER_PHYS_ACCESS)
-		write_sysreg(cval, cntp_cval_el0);
-	else if (access == ARCH_TIMER_VIRT_ACCESS)
-		write_sysreg(cval, cntv_cval_el0);
-
-	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
-}
-
-static int erratum_set_next_event_virt(unsigned long evt,
-					   struct clock_event_device *clk)
-{
-	erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
-	return 0;
-}
-
-static int erratum_set_next_event_phys(unsigned long evt,
-					   struct clock_event_device *clk)
-{
-	erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
-	return 0;
-}
-#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
-
 static int arch_timer_set_next_event_virt(unsigned long evt,
 					  struct clock_event_device *clk)
 {
+	if (needs_unstable_timer_counter_workaround())
+		return erratum_set_next_event_tval_virt(evt, clk);
+
 	set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
 }
@@ -487,6 +490,9 @@ static int arch_timer_set_next_event_virt(unsigned long evt,
 static int arch_timer_set_next_event_phys(unsigned long evt,
 					  struct clock_event_device *clk)
 {
+	if (needs_unstable_timer_counter_workaround())
+		return erratum_set_next_event_tval_phys(evt, clk);
+
 	set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
 }
@@ -505,19 +511,6 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
 	return 0;
 }
 
-static void erratum_workaround_set_sne(struct clock_event_device *clk)
-{
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-	if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
-		return;
-
-	if (arch_timer_uses_ppi == VIRT_PPI)
-		clk->set_next_event = erratum_set_next_event_virt;
-	else
-		clk->set_next_event = erratum_set_next_event_phys;
-#endif
-}
-
 static void __arch_timer_setup(unsigned type,
 			       struct clock_event_device *clk)
 {
@@ -548,8 +541,6 @@ static void __arch_timer_setup(unsigned type,
 		}
 
 		arch_timer_check_ool_workaround(ate_match_local_cap_id, NULL);
-
-		erratum_workaround_set_sne(clk);
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
 		clk->name = "arch_mem_timer";
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 10/18] arm64: arch_timer: Get rid of erratum_workaround_set_sne
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Let's move the handling of workarounds affecting set_next_event
to the affected function, instead of overriding the pointers
as an afterthough. Yes, this is an extra indirection on the
erratum handling path, but the HW is busted anyway.

This will allow for some more flexibility later.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 89 ++++++++++++++++--------------------
 1 file changed, 40 insertions(+), 49 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index e0e4b0e6825d..4caafbdefb9d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -241,6 +241,38 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
 DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
 EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
 
+static void erratum_set_next_event_tval_generic(const int access, unsigned long evt,
+						struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+	u64 cval = evt + arch_counter_get_cntvct();
+
+	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
+	ctrl |= ARCH_TIMER_CTRL_ENABLE;
+	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
+
+	if (access == ARCH_TIMER_PHYS_ACCESS)
+		write_sysreg(cval, cntp_cval_el0);
+	else
+		write_sysreg(cval, cntv_cval_el0);
+
+	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
+}
+
+static int erratum_set_next_event_tval_virt(unsigned long evt,
+					    struct clock_event_device *clk)
+{
+	erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+	return 0;
+}
+
+static int erratum_set_next_event_tval_phys(unsigned long evt,
+					    struct clock_event_device *clk)
+{
+	erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+	return 0;
+}
+
 static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 #ifdef CONFIG_FSL_ERRATUM_A008585
 	{
@@ -354,6 +386,8 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 
 #else
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
+#define erratum_set_next_event_tval_virt(...)		({BUG(); 0;})
+#define erratum_set_next_event_tval_phys(...)		({BUG(); 0;})
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline irqreturn_t timer_handler(const int access,
@@ -443,43 +477,12 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-static __always_inline void erratum_set_next_event_generic(const int access,
-		unsigned long evt, struct clock_event_device *clk)
-{
-	unsigned long ctrl;
-	u64 cval = evt + arch_counter_get_cntvct();
-
-	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
-	ctrl |= ARCH_TIMER_CTRL_ENABLE;
-	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
-
-	if (access == ARCH_TIMER_PHYS_ACCESS)
-		write_sysreg(cval, cntp_cval_el0);
-	else if (access == ARCH_TIMER_VIRT_ACCESS)
-		write_sysreg(cval, cntv_cval_el0);
-
-	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
-}
-
-static int erratum_set_next_event_virt(unsigned long evt,
-					   struct clock_event_device *clk)
-{
-	erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
-	return 0;
-}
-
-static int erratum_set_next_event_phys(unsigned long evt,
-					   struct clock_event_device *clk)
-{
-	erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
-	return 0;
-}
-#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
-
 static int arch_timer_set_next_event_virt(unsigned long evt,
 					  struct clock_event_device *clk)
 {
+	if (needs_unstable_timer_counter_workaround())
+		return erratum_set_next_event_tval_virt(evt, clk);
+
 	set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
 }
@@ -487,6 +490,9 @@ static int arch_timer_set_next_event_virt(unsigned long evt,
 static int arch_timer_set_next_event_phys(unsigned long evt,
 					  struct clock_event_device *clk)
 {
+	if (needs_unstable_timer_counter_workaround())
+		return erratum_set_next_event_tval_phys(evt, clk);
+
 	set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
 }
@@ -505,19 +511,6 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
 	return 0;
 }
 
-static void erratum_workaround_set_sne(struct clock_event_device *clk)
-{
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-	if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
-		return;
-
-	if (arch_timer_uses_ppi == VIRT_PPI)
-		clk->set_next_event = erratum_set_next_event_virt;
-	else
-		clk->set_next_event = erratum_set_next_event_phys;
-#endif
-}
-
 static void __arch_timer_setup(unsigned type,
 			       struct clock_event_device *clk)
 {
@@ -548,8 +541,6 @@ static void __arch_timer_setup(unsigned type,
 		}
 
 		arch_timer_check_ool_workaround(ate_match_local_cap_id, NULL);
-
-		erratum_workaround_set_sne(clk);
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
 		clk->name = "arch_mem_timer";
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 11/18] arm64: arch_timer: Rework the set_next_event workarounds
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

The way we work around errata affecting set_next_event is not very
nice, at it imposes this workaround on errata that do not need it.

Add new workaround hooks and let the existing workarounds use them.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  4 ++++
 drivers/clocksource/arm_arch_timer.c | 30 ++++++++++++++++++++++++++----
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index e5325299aa6d..58572d38e9db 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -43,6 +43,8 @@ enum arch_timer_erratum_match_type {
 	ate_match_local_cap_id,
 };
 
+struct clock_event_device;
+
 struct arch_timer_erratum_workaround {
 	enum arch_timer_erratum_match_type match_type;
 	const void *id;
@@ -50,6 +52,8 @@ struct arch_timer_erratum_workaround {
 	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;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 4caafbdefb9d..b9f01daafdfa 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -282,6 +282,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
 #endif
 #ifdef CONFIG_HISILICON_ERRATUM_161010101
@@ -292,6 +294,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
 #endif
 };
@@ -384,10 +388,24 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 		local ? "local" : "global", wa->desc);
 }
 
+#define erratum_handler(fn, r, ...)					\
+({									\
+	bool __val;							\
+	if (needs_unstable_timer_counter_workaround() &&		\
+	    timer_unstable_counter_workaround->fn) {			\
+		r = timer_unstable_counter_workaround->fn(__VA_ARGS__);	\
+		__val = true;						\
+	} else {							\
+		__val = false;						\
+	}								\
+	__val;								\
+})
+
 #else
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #define erratum_set_next_event_tval_virt(...)		({BUG(); 0;})
 #define erratum_set_next_event_tval_phys(...)		({BUG(); 0;})
+#define erratum_handler(fn, r, ...)			({false;})
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline irqreturn_t timer_handler(const int access,
@@ -480,8 +498,10 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 static int arch_timer_set_next_event_virt(unsigned long evt,
 					  struct clock_event_device *clk)
 {
-	if (needs_unstable_timer_counter_workaround())
-		return erratum_set_next_event_tval_virt(evt, clk);
+	int ret;
+
+	if (erratum_handler(set_next_event_virt, ret, evt, clk))
+		return ret;
 
 	set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
@@ -490,8 +510,10 @@ static int arch_timer_set_next_event_virt(unsigned long evt,
 static int arch_timer_set_next_event_phys(unsigned long evt,
 					  struct clock_event_device *clk)
 {
-	if (needs_unstable_timer_counter_workaround())
-		return erratum_set_next_event_tval_phys(evt, clk);
+	int ret;
+
+	if (erratum_handler(set_next_event_phys, ret, evt, clk))
+		return ret;
 
 	set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 11/18] arm64: arch_timer: Rework the set_next_event workarounds
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

The way we work around errata affecting set_next_event is not very
nice, at it imposes this workaround on errata that do not need it.

Add new workaround hooks and let the existing workarounds use them.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  4 ++++
 drivers/clocksource/arm_arch_timer.c | 30 ++++++++++++++++++++++++++----
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index e5325299aa6d..58572d38e9db 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -43,6 +43,8 @@ enum arch_timer_erratum_match_type {
 	ate_match_local_cap_id,
 };
 
+struct clock_event_device;
+
 struct arch_timer_erratum_workaround {
 	enum arch_timer_erratum_match_type match_type;
 	const void *id;
@@ -50,6 +52,8 @@ struct arch_timer_erratum_workaround {
 	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;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 4caafbdefb9d..b9f01daafdfa 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -282,6 +282,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
 #endif
 #ifdef CONFIG_HISILICON_ERRATUM_161010101
@@ -292,6 +294,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
 		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
 #endif
 };
@@ -384,10 +388,24 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 		local ? "local" : "global", wa->desc);
 }
 
+#define erratum_handler(fn, r, ...)					\
+({									\
+	bool __val;							\
+	if (needs_unstable_timer_counter_workaround() &&		\
+	    timer_unstable_counter_workaround->fn) {			\
+		r = timer_unstable_counter_workaround->fn(__VA_ARGS__);	\
+		__val = true;						\
+	} else {							\
+		__val = false;						\
+	}								\
+	__val;								\
+})
+
 #else
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #define erratum_set_next_event_tval_virt(...)		({BUG(); 0;})
 #define erratum_set_next_event_tval_phys(...)		({BUG(); 0;})
+#define erratum_handler(fn, r, ...)			({false;})
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline irqreturn_t timer_handler(const int access,
@@ -480,8 +498,10 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 static int arch_timer_set_next_event_virt(unsigned long evt,
 					  struct clock_event_device *clk)
 {
-	if (needs_unstable_timer_counter_workaround())
-		return erratum_set_next_event_tval_virt(evt, clk);
+	int ret;
+
+	if (erratum_handler(set_next_event_virt, ret, evt, clk))
+		return ret;
 
 	set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
@@ -490,8 +510,10 @@ static int arch_timer_set_next_event_virt(unsigned long evt,
 static int arch_timer_set_next_event_phys(unsigned long evt,
 					  struct clock_event_device *clk)
 {
-	if (needs_unstable_timer_counter_workaround())
-		return erratum_set_next_event_tval_phys(evt, clk);
+	int ret;
+
+	if (erratum_handler(set_next_event_phys, ret, evt, clk))
+		return ret;
 
 	set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 12/18] arm64: arch_timer: Make workaround methods optional
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Not all errata need to workaround all access types. Allow them to
be optional.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 58572d38e9db..d46cf21e8b80 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -61,8 +61,9 @@ extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workar
 #define arch_timer_reg_read_stable(reg) 		\
 ({							\
 	u64 _val;					\
-	if (needs_unstable_timer_counter_workaround())		\
-		_val = timer_unstable_counter_workaround->read_##reg();\
+	if (needs_unstable_timer_counter_workaround() &&		\
+	    timer_unstable_counter_workaround->read_##reg)		\
+		_val = timer_unstable_counter_workaround->read_##reg();	\
 	else						\
 		_val = read_sysreg(reg);		\
 	_val;						\
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 12/18] arm64: arch_timer: Make workaround methods optional
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Not all errata need to workaround all access types. Allow them to
be optional.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 58572d38e9db..d46cf21e8b80 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -61,8 +61,9 @@ extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workar
 #define arch_timer_reg_read_stable(reg) 		\
 ({							\
 	u64 _val;					\
-	if (needs_unstable_timer_counter_workaround())		\
-		_val = timer_unstable_counter_workaround->read_##reg();\
+	if (needs_unstable_timer_counter_workaround() &&		\
+	    timer_unstable_counter_workaround->read_##reg)		\
+		_val = timer_unstable_counter_workaround->read_##reg();	\
 	else						\
 		_val = read_sysreg(reg);		\
 	_val;						\
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 13/18] arm64: arch_timer: Allows a CPU-specific erratum to only affect a subset of CPUs
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Instead of applying a CPU-specific workaround to all CPUs in the system,
allow it to only affect a subset of them (typical big-little case).

This is done by turning the erratum pointer into a per-CPU variable.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  | 31 ++++++++++++++++----------
 drivers/clocksource/arm_arch_timer.c | 42 +++++++++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index d46cf21e8b80..3cba3a5e4ba1 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -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>
@@ -56,17 +57,25 @@ struct arch_timer_erratum_workaround {
 	int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
 };
 
-extern 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() &&		\
-	    timer_unstable_counter_workaround->read_##reg)		\
-		_val = timer_unstable_counter_workaround->read_##reg();	\
-	else						\
-		_val = read_sysreg(reg);		\
-	_val;						\
+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()) {		\
+		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;								\
 })
 
 /*
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index b9f01daafdfa..2b17b99922a1 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -235,7 +235,8 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
 #endif
 
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
+DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *,
+	       timer_unstable_counter_workaround);
 EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
 
 DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
@@ -345,9 +346,18 @@ arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 }
 
 static
-void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa,
+				  bool local)
 {
-	timer_unstable_counter_workaround = wa;
+	int i;
+
+	if (local) {
+		__this_cpu_write(timer_unstable_counter_workaround, wa);
+	} else {
+		for_each_possible_cpu(i)
+			per_cpu(timer_unstable_counter_workaround, i) = wa;
+	}
+
 	static_branch_enable(&arch_timer_read_ool_enabled);
 }
 
@@ -376,14 +386,17 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 		return;
 
 	if (static_branch_unlikely(&arch_timer_read_ool_enabled)) {
-		if (wa != timer_unstable_counter_workaround)
+		const struct arch_timer_erratum_workaround *__wa;
+		__wa = __this_cpu_read(timer_unstable_counter_workaround);
+		if (__wa && wa != __wa)
 			pr_warn("Can't enable workaround for %s (clashes with %s\n)",
-				wa->desc,
-				timer_unstable_counter_workaround->desc);
-		return;
+				wa->desc, __wa->desc);
+
+		if (__wa)
+			return;
 	}
 
-	arch_timer_enable_workaround(wa);
+	arch_timer_enable_workaround(wa, local);
 	pr_info("Enabling %s workaround for %s\n",
 		local ? "local" : "global", wa->desc);
 }
@@ -391,10 +404,15 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 #define erratum_handler(fn, r, ...)					\
 ({									\
 	bool __val;							\
-	if (needs_unstable_timer_counter_workaround() &&		\
-	    timer_unstable_counter_workaround->fn) {			\
-		r = timer_unstable_counter_workaround->fn(__VA_ARGS__);	\
-		__val = true;						\
+	if (needs_unstable_timer_counter_workaround()) {		\
+		const struct arch_timer_erratum_workaround *__wa;	\
+		__wa = __this_cpu_read(timer_unstable_counter_workaround); \
+		if (__wa && __wa->fn) {					\
+			r = __wa->fn(__VA_ARGS__);			\
+			__val = true;					\
+		} else {						\
+			__val = false;					\
+		}							\
 	} else {							\
 		__val = false;						\
 	}								\
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 13/18] arm64: arch_timer: Allows a CPU-specific erratum to only affect a subset of CPUs
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of applying a CPU-specific workaround to all CPUs in the system,
allow it to only affect a subset of them (typical big-little case).

This is done by turning the erratum pointer into a per-CPU variable.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  | 31 ++++++++++++++++----------
 drivers/clocksource/arm_arch_timer.c | 42 +++++++++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index d46cf21e8b80..3cba3a5e4ba1 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -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>
@@ -56,17 +57,25 @@ struct arch_timer_erratum_workaround {
 	int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
 };
 
-extern 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() &&		\
-	    timer_unstable_counter_workaround->read_##reg)		\
-		_val = timer_unstable_counter_workaround->read_##reg();	\
-	else						\
-		_val = read_sysreg(reg);		\
-	_val;						\
+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()) {		\
+		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;								\
 })
 
 /*
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index b9f01daafdfa..2b17b99922a1 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -235,7 +235,8 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
 #endif
 
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
+DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *,
+	       timer_unstable_counter_workaround);
 EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
 
 DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
@@ -345,9 +346,18 @@ arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 }
 
 static
-void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa,
+				  bool local)
 {
-	timer_unstable_counter_workaround = wa;
+	int i;
+
+	if (local) {
+		__this_cpu_write(timer_unstable_counter_workaround, wa);
+	} else {
+		for_each_possible_cpu(i)
+			per_cpu(timer_unstable_counter_workaround, i) = wa;
+	}
+
 	static_branch_enable(&arch_timer_read_ool_enabled);
 }
 
@@ -376,14 +386,17 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 		return;
 
 	if (static_branch_unlikely(&arch_timer_read_ool_enabled)) {
-		if (wa != timer_unstable_counter_workaround)
+		const struct arch_timer_erratum_workaround *__wa;
+		__wa = __this_cpu_read(timer_unstable_counter_workaround);
+		if (__wa && wa != __wa)
 			pr_warn("Can't enable workaround for %s (clashes with %s\n)",
-				wa->desc,
-				timer_unstable_counter_workaround->desc);
-		return;
+				wa->desc, __wa->desc);
+
+		if (__wa)
+			return;
 	}
 
-	arch_timer_enable_workaround(wa);
+	arch_timer_enable_workaround(wa, local);
 	pr_info("Enabling %s workaround for %s\n",
 		local ? "local" : "global", wa->desc);
 }
@@ -391,10 +404,15 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 #define erratum_handler(fn, r, ...)					\
 ({									\
 	bool __val;							\
-	if (needs_unstable_timer_counter_workaround() &&		\
-	    timer_unstable_counter_workaround->fn) {			\
-		r = timer_unstable_counter_workaround->fn(__VA_ARGS__);	\
-		__val = true;						\
+	if (needs_unstable_timer_counter_workaround()) {		\
+		const struct arch_timer_erratum_workaround *__wa;	\
+		__wa = __this_cpu_read(timer_unstable_counter_workaround); \
+		if (__wa && __wa->fn) {					\
+			r = __wa->fn(__VA_ARGS__);			\
+			__val = true;					\
+		} else {						\
+			__val = false;					\
+		}							\
 	} else {							\
 		__val = false;						\
 	}								\
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 14/18] arm64: arch_timer: Move clocksource_counter and co around
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

In order to access clocksource_counter from the errata handling code,
move it (together with the related structures and functions) towards
the top of the file.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 62 ++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 2b17b99922a1..70eb42bd6784 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -158,6 +158,37 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 	return val;
 }
 
+/*
+ * Default to cp15 based access because arm64 uses this function for
+ * sched_clock() before DT is probed and the cp15 method is guaranteed
+ * to exist on arm64. arm doesn't use this before DT is probed so even
+ * if we don't have the cp15 accessors we won't have a problem.
+ */
+u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct;
+
+static u64 arch_counter_read(struct clocksource *cs)
+{
+	return arch_timer_read_counter();
+}
+
+static u64 arch_counter_read_cc(const struct cyclecounter *cc)
+{
+	return arch_timer_read_counter();
+}
+
+static struct clocksource clocksource_counter = {
+	.name	= "arch_sys_counter",
+	.rating	= 400,
+	.read	= arch_counter_read,
+	.mask	= CLOCKSOURCE_MASK(56),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static struct cyclecounter cyclecounter __ro_after_init = {
+	.read	= arch_counter_read_cc,
+	.mask	= CLOCKSOURCE_MASK(56),
+};
+
 #ifdef CONFIG_FSL_ERRATUM_A008585
 /*
  * The number of retries is an arbitrary value well beyond the highest number
@@ -749,37 +780,6 @@ static u64 arch_counter_get_cntvct_mem(void)
 	return ((u64) vct_hi << 32) | vct_lo;
 }
 
-/*
- * Default to cp15 based access because arm64 uses this function for
- * sched_clock() before DT is probed and the cp15 method is guaranteed
- * to exist on arm64. arm doesn't use this before DT is probed so even
- * if we don't have the cp15 accessors we won't have a problem.
- */
-u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct;
-
-static u64 arch_counter_read(struct clocksource *cs)
-{
-	return arch_timer_read_counter();
-}
-
-static u64 arch_counter_read_cc(const struct cyclecounter *cc)
-{
-	return arch_timer_read_counter();
-}
-
-static struct clocksource clocksource_counter = {
-	.name	= "arch_sys_counter",
-	.rating	= 400,
-	.read	= arch_counter_read,
-	.mask	= CLOCKSOURCE_MASK(56),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static struct cyclecounter cyclecounter __ro_after_init = {
-	.read	= arch_counter_read_cc,
-	.mask	= CLOCKSOURCE_MASK(56),
-};
-
 static struct arch_timer_kvm_info arch_timer_kvm_info;
 
 struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 14/18] arm64: arch_timer: Move clocksource_counter and co around
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

In order to access clocksource_counter from the errata handling code,
move it (together with the related structures and functions) towards
the top of the file.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 62 ++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 2b17b99922a1..70eb42bd6784 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -158,6 +158,37 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 	return val;
 }
 
+/*
+ * Default to cp15 based access because arm64 uses this function for
+ * sched_clock() before DT is probed and the cp15 method is guaranteed
+ * to exist on arm64. arm doesn't use this before DT is probed so even
+ * if we don't have the cp15 accessors we won't have a problem.
+ */
+u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct;
+
+static u64 arch_counter_read(struct clocksource *cs)
+{
+	return arch_timer_read_counter();
+}
+
+static u64 arch_counter_read_cc(const struct cyclecounter *cc)
+{
+	return arch_timer_read_counter();
+}
+
+static struct clocksource clocksource_counter = {
+	.name	= "arch_sys_counter",
+	.rating	= 400,
+	.read	= arch_counter_read,
+	.mask	= CLOCKSOURCE_MASK(56),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static struct cyclecounter cyclecounter __ro_after_init = {
+	.read	= arch_counter_read_cc,
+	.mask	= CLOCKSOURCE_MASK(56),
+};
+
 #ifdef CONFIG_FSL_ERRATUM_A008585
 /*
  * The number of retries is an arbitrary value well beyond the highest number
@@ -749,37 +780,6 @@ static u64 arch_counter_get_cntvct_mem(void)
 	return ((u64) vct_hi << 32) | vct_lo;
 }
 
-/*
- * Default to cp15 based access because arm64 uses this function for
- * sched_clock() before DT is probed and the cp15 method is guaranteed
- * to exist on arm64. arm doesn't use this before DT is probed so even
- * if we don't have the cp15 accessors we won't have a problem.
- */
-u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct;
-
-static u64 arch_counter_read(struct clocksource *cs)
-{
-	return arch_timer_read_counter();
-}
-
-static u64 arch_counter_read_cc(const struct cyclecounter *cc)
-{
-	return arch_timer_read_counter();
-}
-
-static struct clocksource clocksource_counter = {
-	.name	= "arch_sys_counter",
-	.rating	= 400,
-	.read	= arch_counter_read,
-	.mask	= CLOCKSOURCE_MASK(56),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static struct cyclecounter cyclecounter __ro_after_init = {
-	.read	= arch_counter_read_cc,
-	.mask	= CLOCKSOURCE_MASK(56),
-};
-
 static struct arch_timer_kvm_info arch_timer_kvm_info;
 
 struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 15/18] arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Userspace being allowed to use read CNTVCT_EL0 anytime (and not
only in the VDSO), we need to enable trapping whenever a cntvct
workaround is enabled on a given CPU.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 42 +++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 70eb42bd6784..eccff0fedf2c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -83,6 +83,7 @@ static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
 static bool arch_timer_c3stop;
 static bool arch_timer_mem_use_virtual;
 static bool arch_counter_suspend_stop;
+static bool vdso_default = true;
 
 static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
 
@@ -390,6 +391,17 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
 	}
 
 	static_branch_enable(&arch_timer_read_ool_enabled);
+
+	/*
+	 * Don't use the vdso fastpath if errata require using the
+	 * out-of-line counter accessor. We may change our mind pretty
+	 * late in the game (with a per-CPU erratum, for example), so
+	 * change both the default value and the vdso itself.
+	 */
+	if (wa->read_cntvct_el0) {
+		clocksource_counter.archdata.vdso_direct = false;
+		vdso_default = false;
+	}
 }
 
 static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
@@ -450,11 +462,19 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 	__val;								\
 })
 
+static bool arch_timer_this_cpu_has_cntvct_wa(void)
+{
+	const struct arch_timer_erratum_workaround *wa;
+
+	wa = __this_cpu_read(timer_unstable_counter_workaround);
+	return wa && wa->read_cntvct_el0;
+}
 #else
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #define erratum_set_next_event_tval_virt(...)		({BUG(); 0;})
 #define erratum_set_next_event_tval_phys(...)		({BUG(); 0;})
 #define erratum_handler(fn, r, ...)			({false;})
+#define arch_timer_this_cpu_has_cntvct_wa()		({false;})
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline irqreturn_t timer_handler(const int access,
@@ -674,8 +694,15 @@ static void arch_counter_set_user_access(void)
 			| ARCH_TIMER_VIRT_EVT_EN
 			| ARCH_TIMER_USR_PCT_ACCESS_EN);
 
-	/* Enable user access to the virtual counter */
-	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+	/*
+	 * Enable user access to the virtual counter if it doesn't
+	 * need to be workaround. The vdso may have been already
+	 * disabled though.
+	 */
+	if (arch_timer_this_cpu_has_cntvct_wa())
+		pr_info("CPU%d: Trapping CNTVCT access\n", smp_processor_id());
+	else
+		cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
 
 	arch_timer_set_cntkctl(cntkctl);
 }
@@ -798,16 +825,7 @@ static void __init arch_counter_register(unsigned type)
 		else
 			arch_timer_read_counter = arch_counter_get_cntpct;
 
-		clocksource_counter.archdata.vdso_direct = true;
-
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-		/*
-		 * Don't use the vdso fastpath if errata require using
-		 * the out-of-line counter accessor.
-		 */
-		if (static_branch_unlikely(&arch_timer_read_ool_enabled))
-			clocksource_counter.archdata.vdso_direct = false;
-#endif
+		clocksource_counter.archdata.vdso_direct = vdso_default;
 	} else {
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 	}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 15/18] arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Userspace being allowed to use read CNTVCT_EL0 anytime (and not
only in the VDSO), we need to enable trapping whenever a cntvct
workaround is enabled on a given CPU.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 42 +++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 70eb42bd6784..eccff0fedf2c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -83,6 +83,7 @@ static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
 static bool arch_timer_c3stop;
 static bool arch_timer_mem_use_virtual;
 static bool arch_counter_suspend_stop;
+static bool vdso_default = true;
 
 static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
 
@@ -390,6 +391,17 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
 	}
 
 	static_branch_enable(&arch_timer_read_ool_enabled);
+
+	/*
+	 * Don't use the vdso fastpath if errata require using the
+	 * out-of-line counter accessor. We may change our mind pretty
+	 * late in the game (with a per-CPU erratum, for example), so
+	 * change both the default value and the vdso itself.
+	 */
+	if (wa->read_cntvct_el0) {
+		clocksource_counter.archdata.vdso_direct = false;
+		vdso_default = false;
+	}
 }
 
 static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
@@ -450,11 +462,19 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 	__val;								\
 })
 
+static bool arch_timer_this_cpu_has_cntvct_wa(void)
+{
+	const struct arch_timer_erratum_workaround *wa;
+
+	wa = __this_cpu_read(timer_unstable_counter_workaround);
+	return wa && wa->read_cntvct_el0;
+}
 #else
 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
 #define erratum_set_next_event_tval_virt(...)		({BUG(); 0;})
 #define erratum_set_next_event_tval_phys(...)		({BUG(); 0;})
 #define erratum_handler(fn, r, ...)			({false;})
+#define arch_timer_this_cpu_has_cntvct_wa()		({false;})
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline irqreturn_t timer_handler(const int access,
@@ -674,8 +694,15 @@ static void arch_counter_set_user_access(void)
 			| ARCH_TIMER_VIRT_EVT_EN
 			| ARCH_TIMER_USR_PCT_ACCESS_EN);
 
-	/* Enable user access to the virtual counter */
-	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+	/*
+	 * Enable user access to the virtual counter if it doesn't
+	 * need to be workaround. The vdso may have been already
+	 * disabled though.
+	 */
+	if (arch_timer_this_cpu_has_cntvct_wa())
+		pr_info("CPU%d: Trapping CNTVCT access\n", smp_processor_id());
+	else
+		cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
 
 	arch_timer_set_cntkctl(cntkctl);
 }
@@ -798,16 +825,7 @@ static void __init arch_counter_register(unsigned type)
 		else
 			arch_timer_read_counter = arch_counter_get_cntpct;
 
-		clocksource_counter.archdata.vdso_direct = true;
-
-#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-		/*
-		 * Don't use the vdso fastpath if errata require using
-		 * the out-of-line counter accessor.
-		 */
-		if (static_branch_unlikely(&arch_timer_read_ool_enabled))
-			clocksource_counter.archdata.vdso_direct = false;
-#endif
+		clocksource_counter.archdata.vdso_direct = vdso_default;
 	} else {
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 	}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 16/18] arm64: arch_timer: Workaround for Cortex-A73 erratum 858921
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Cortex-A73 (all versions) counter read can return a wrong value
when the counter crosses a 32bit boundary.

The workaround involves performing the read twice, and to return
one or the other depending on whether a transition has taken place.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/Kconfig          | 11 +++++++++++
 drivers/clocksource/arm_arch_timer.c | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 3356ab821624..af80a7c44faf 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -366,6 +366,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
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index eccff0fedf2c..ba4be5859aa4 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -266,6 +266,17 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
 }
 #endif
 
+#ifdef CONFIG_ARM64_ERRATUM_858921
+static u64 notrace arm64_858921_read_cntvct_el0(void)
+{
+	u64 old, new;
+
+	old = read_sysreg(cntvct_el0);
+	new = read_sysreg(cntvct_el0);
+	return (((old ^ new) >> 32) & 1) ? old : new;
+}
+#endif
+
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *,
 	       timer_unstable_counter_workaround);
@@ -331,6 +342,14 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_858921
+	{
+		.match_type = ate_match_local_cap_id,
+		.id = (void *)ARM64_WORKAROUND_858921,
+		.desc = "ARM erratum 858921",
+		.read_cntvct_el0 = arm64_858921_read_cntvct_el0,
+	},
+#endif
 };
 
 typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 16/18] arm64: arch_timer: Workaround for Cortex-A73 erratum 858921
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Cortex-A73 (all versions) counter read can return a wrong value
when the counter crosses a 32bit boundary.

The workaround involves performing the read twice, and to return
one or the other depending on whether a transition has taken place.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/Kconfig          | 11 +++++++++++
 drivers/clocksource/arm_arch_timer.c | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 3356ab821624..af80a7c44faf 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -366,6 +366,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
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index eccff0fedf2c..ba4be5859aa4 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -266,6 +266,17 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
 }
 #endif
 
+#ifdef CONFIG_ARM64_ERRATUM_858921
+static u64 notrace arm64_858921_read_cntvct_el0(void)
+{
+	u64 old, new;
+
+	old = read_sysreg(cntvct_el0);
+	new = read_sysreg(cntvct_el0);
+	return (((old ^ new) >> 32) & 1) ? old : new;
+}
+#endif
+
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *,
 	       timer_unstable_counter_workaround);
@@ -331,6 +342,14 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_858921
+	{
+		.match_type = ate_match_local_cap_id,
+		.id = (void *)ARM64_WORKAROUND_858921,
+		.desc = "ARM erratum 858921",
+		.read_cntvct_el0 = arm64_858921_read_cntvct_el0,
+	},
+#endif
 };
 
 typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 17/18] arm64: arch_timer: Allow erratum matching with ACPI OEM information
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Just as we're able to identify a broken platform using some DT
information, let's enable a way to spot the offenders with ACPI.

The difference is that we can only match on some OEM info instead
of implementation-specific properties. So in order to avoid the
insane multiplication of errata structures, we allow an array
of OEM descriptions to be attached to an erratum structure.

Tested-by: dann frazier <dann.frazier@canonical.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  1 +
 drivers/clocksource/arm_arch_timer.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 3cba3a5e4ba1..a79c6932bf3f 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -42,6 +42,7 @@ enum arch_timer_erratum_match_type {
 	ate_match_dt,
 	ate_match_global_cap_id,
 	ate_match_local_cap_id,
+	ate_match_acpi_oem_info,
 };
 
 struct clock_event_device;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index ba4be5859aa4..9e8cef63e59e 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -190,6 +190,12 @@ static struct cyclecounter cyclecounter __ro_after_init = {
 	.mask	= CLOCKSOURCE_MASK(56),
 };
 
+struct ate_acpi_oem_info {
+	char oem_id[ACPI_OEM_ID_SIZE + 1];
+	char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+	u32 oem_revision;
+};
+
 #ifdef CONFIG_FSL_ERRATUM_A008585
 /*
  * The number of retries is an arbitrary value well beyond the highest number
@@ -378,6 +384,28 @@ bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workarou
 	return this_cpu_has_cap((uintptr_t)wa->id);
 }
 
+
+static
+bool arch_timer_check_acpi_oem_erratum(const struct arch_timer_erratum_workaround *wa,
+				       const void *arg)
+{
+	static const struct ate_acpi_oem_info empty_oem_info = {};
+	const struct ate_acpi_oem_info *info = wa->id;
+	const struct acpi_table_header *table = arg;
+
+	/* Iterate over the ACPI OEM info array, looking for a match */
+	while (memcmp(info, &empty_oem_info, sizeof(*info))) {
+		if (!memcmp(info->oem_id, table->oem_id, ACPI_OEM_ID_SIZE) &&
+		    !memcmp(info->oem_table_id, table->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) &&
+		    info->oem_revision == table->oem_revision)
+			return true;
+
+		info++;
+	}
+
+	return false;
+}
+
 static const struct arch_timer_erratum_workaround *
 arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 			  ate_match_fn_t match_fn,
@@ -441,6 +469,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 		match_fn = arch_timer_check_local_cap_erratum;
 		local = true;
 		break;
+	case ate_match_acpi_oem_info:
+		match_fn = arch_timer_check_acpi_oem_erratum;
+		break;
 	}
 
 	wa = arch_timer_iterate_errata(type, match_fn, arg);
@@ -1286,6 +1317,7 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 
 	/* Check for globally applicable workarounds */
 	arch_timer_check_ool_workaround(ate_match_global_cap_id, NULL);
+	arch_timer_check_ool_workaround(ate_match_acpi_oem_info, table);
 
 	arch_timer_init();
 	return 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 17/18] arm64: arch_timer: Allow erratum matching with ACPI OEM information
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Just as we're able to identify a broken platform using some DT
information, let's enable a way to spot the offenders with ACPI.

The difference is that we can only match on some OEM info instead
of implementation-specific properties. So in order to avoid the
insane multiplication of errata structures, we allow an array
of OEM descriptions to be attached to an erratum structure.

Tested-by: dann frazier <dann.frazier@canonical.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_timer.h  |  1 +
 drivers/clocksource/arm_arch_timer.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 3cba3a5e4ba1..a79c6932bf3f 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -42,6 +42,7 @@ enum arch_timer_erratum_match_type {
 	ate_match_dt,
 	ate_match_global_cap_id,
 	ate_match_local_cap_id,
+	ate_match_acpi_oem_info,
 };
 
 struct clock_event_device;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index ba4be5859aa4..9e8cef63e59e 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -190,6 +190,12 @@ static struct cyclecounter cyclecounter __ro_after_init = {
 	.mask	= CLOCKSOURCE_MASK(56),
 };
 
+struct ate_acpi_oem_info {
+	char oem_id[ACPI_OEM_ID_SIZE + 1];
+	char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+	u32 oem_revision;
+};
+
 #ifdef CONFIG_FSL_ERRATUM_A008585
 /*
  * The number of retries is an arbitrary value well beyond the highest number
@@ -378,6 +384,28 @@ bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workarou
 	return this_cpu_has_cap((uintptr_t)wa->id);
 }
 
+
+static
+bool arch_timer_check_acpi_oem_erratum(const struct arch_timer_erratum_workaround *wa,
+				       const void *arg)
+{
+	static const struct ate_acpi_oem_info empty_oem_info = {};
+	const struct ate_acpi_oem_info *info = wa->id;
+	const struct acpi_table_header *table = arg;
+
+	/* Iterate over the ACPI OEM info array, looking for a match */
+	while (memcmp(info, &empty_oem_info, sizeof(*info))) {
+		if (!memcmp(info->oem_id, table->oem_id, ACPI_OEM_ID_SIZE) &&
+		    !memcmp(info->oem_table_id, table->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) &&
+		    info->oem_revision == table->oem_revision)
+			return true;
+
+		info++;
+	}
+
+	return false;
+}
+
 static const struct arch_timer_erratum_workaround *
 arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 			  ate_match_fn_t match_fn,
@@ -441,6 +469,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 		match_fn = arch_timer_check_local_cap_erratum;
 		local = true;
 		break;
+	case ate_match_acpi_oem_info:
+		match_fn = arch_timer_check_acpi_oem_erratum;
+		break;
 	}
 
 	wa = arch_timer_iterate_errata(type, match_fn, arg);
@@ -1286,6 +1317,7 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 
 	/* Check for globally applicable workarounds */
 	arch_timer_check_ool_workaround(ate_match_global_cap_id, NULL);
+	arch_timer_check_ool_workaround(ate_match_acpi_oem_info, table);
 
 	arch_timer_init();
 	return 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 18/18] arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-20 17:48   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

In order to deal with ACPI enabled platforms suffering from the
HISILICON_ERRATUM_161010101, let's add the required OEM data that
allow the workaround to be enabled.

Tested-by: dann frazier <dann.frazier@canonical.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 9e8cef63e59e..bbca0883c878 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -270,6 +270,29 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
 {
 	return __hisi_161010101_read_reg(cntvct_el0);
 }
+
+static struct ate_acpi_oem_info hisi_161010101_oem_info[] = {
+	/*
+	 * Note that trailing spaces are required to properly match
+	 * the OEM table information.
+	 */
+	{
+		.oem_id		= "HISI  ",
+		.oem_table_id	= "HIP05   ",
+		.oem_revision	= 0,
+	},
+	{
+		.oem_id		= "HISI  ",
+		.oem_table_id	= "HIP06   ",
+		.oem_revision	= 0,
+	},
+	{
+		.oem_id		= "HISI  ",
+		.oem_table_id	= "HIP07   ",
+		.oem_revision	= 0,
+	},
+	{ /* Sentinel indicating the end of the OEM array */ },
+};
 #endif
 
 #ifdef CONFIG_ARM64_ERRATUM_858921
@@ -347,6 +370,16 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.set_next_event_phys = erratum_set_next_event_tval_phys,
 		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
+	{
+		.match_type = ate_match_acpi_oem_info,
+		.id = hisi_161010101_oem_info,
+		.desc = "HiSilicon erratum 161010101",
+		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
+		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
+	},
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_858921
 	{
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH v2 18/18] arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data
@ 2017-03-20 17:48   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-20 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

In order to deal with ACPI enabled platforms suffering from the
HISILICON_ERRATUM_161010101, let's add the required OEM data that
allow the workaround to be enabled.

Tested-by: dann frazier <dann.frazier@canonical.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/clocksource/arm_arch_timer.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 9e8cef63e59e..bbca0883c878 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -270,6 +270,29 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
 {
 	return __hisi_161010101_read_reg(cntvct_el0);
 }
+
+static struct ate_acpi_oem_info hisi_161010101_oem_info[] = {
+	/*
+	 * Note that trailing spaces are required to properly match
+	 * the OEM table information.
+	 */
+	{
+		.oem_id		= "HISI  ",
+		.oem_table_id	= "HIP05   ",
+		.oem_revision	= 0,
+	},
+	{
+		.oem_id		= "HISI  ",
+		.oem_table_id	= "HIP06   ",
+		.oem_revision	= 0,
+	},
+	{
+		.oem_id		= "HISI  ",
+		.oem_table_id	= "HIP07   ",
+		.oem_revision	= 0,
+	},
+	{ /* Sentinel indicating the end of the OEM array */ },
+};
 #endif
 
 #ifdef CONFIG_ARM64_ERRATUM_858921
@@ -347,6 +370,16 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.set_next_event_phys = erratum_set_next_event_tval_phys,
 		.set_next_event_virt = erratum_set_next_event_tval_virt,
 	},
+	{
+		.match_type = ate_match_acpi_oem_info,
+		.id = hisi_161010101_oem_info,
+		.desc = "HiSilicon erratum 161010101",
+		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
+		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
+	},
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_858921
 	{
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 01/18] arm64: Allow checking of a CPU-local erratum
  2017-03-20 17:48   ` Marc Zyngier
@ 2017-03-22  9:22     ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22  9:22 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Mon, Mar 20, 2017 at 05:48:12PM +0000, Marc Zyngier wrote:
> this_cpu_has_cap() only checks the feature array, and not the errata
> one. In order to be able to check for a CPU-local erratum, allow it
> to inspect the latter as well.
> 
> This is consistent with cpus_have_cap()'s behaviour, which includes
> errata already.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 01/18] arm64: Allow checking of a CPU-local erratum
@ 2017-03-22  9:22     ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 20, 2017 at 05:48:12PM +0000, Marc Zyngier wrote:
> this_cpu_has_cap() only checks the feature array, and not the errata
> one. In order to be able to check for a CPU-local erratum, allow it
> to inspect the latter as well.
> 
> This is consistent with cpus_have_cap()'s behaviour, which includes
> errata already.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 00/18] clocksource/arch_timer: Errata workaround infrastructure rework
  2017-03-20 17:48 ` Marc Zyngier
@ 2017-03-22 13:56   ` Ding Tianhong
  -1 siblings, 0 replies; 88+ messages in thread
From: Ding Tianhong @ 2017-03-22 13:56 UTC (permalink / raw)
  To: Marc Zyngier, linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, Catalin Marinas, Daniel Lezcano, Will Deacon,
	Scott Wood, Hanjun Guo, dann frazier

Tested-by: Ding Tianhong <dingtianhong@huawei.com>

On 2017/3/21 1:48, Marc Zyngier wrote:
> It has recently become obvious that a number of arm64 systems have
> been blessed with a set of timers that are slightly less than perfect,
> and require a bit of hand-holding. We already have a bunch of
> errata-specific code to deal with this, but as we're adding more
> potential detection methods (DT, ACPI, capability), things are getting
> a bit out of hands.
> 
> Instead of adding more ad-hoc fixes to an already difficult code base,
> let's give ourselves a bit of an infrastructure that can deal with
> this and hide most of the uggliness behind frendly accessors.
> 
> The series is structured as such:
> 
> - A bunch of arm64 specific patches that allow the rest of the
>   workaround infrastructure to be built upon (such as being able to
>   trap userspace access to the virtual counter). These are now
>   separate in order to allow the creation of a shared branch between
>   the arm64 and clocksource trees.
> 
> - The following patches rework the existing workarounds, allowing
>   errata to be matched using a given detection method
> 
> - Another patch allows a workaround to affect a subset of the CPUs,
>   and not the whole system
> 
> - We then work around a Cortex-A73 erratum, whose counter can return a
>   wrong value if read while crossing a 32bit boundary
> 
> - Finally, we add some ACPI-specific workarounds for HiSilicon
>   platforms that have the HISILICON_ERRATUM_161010101 defect.
> 
> Note that so far, we only deal with arm64. Once the infrastructure is
> agreed upon, we can look at generalizing it (to some extent) to 32bit
> ARM (typical use case would be a 32bit guest running on an affected
> host).
> 
> * From v1:
>   - Addressed Hanjun and Mark review comments
>   - Moved arm64 specific patches to the beginning of the series,
>     leaving the clocksource patches at the end, resulting in an extra
>     patch.
>   - Added RBs, TBs, and Acks.
> 
> Marc Zyngier (18):
>   arm64: Allow checking of a CPU-local erratum
>   arm64: Add CNTVCT_EL0 trap handler
>   arm64: Define Cortex-A73 MIDR
>   arm64: cpu_errata: Allow an erratum to be match for all revisions of a
>     core
>   arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum
>     858921
>   arm64: arch_timer: Add infrastructure for multiple erratum detection
>     methods
>   arm64: arch_timer: Add erratum handler for globally defined capability
>   arm64: arch_timer: Add erratum handler for CPU-specific capability
>   arm64: arch_timer: Move arch_timer_reg_read/write around
>   arm64: arch_timer: Get rid of erratum_workaround_set_sne
>   arm64: arch_timer: Rework the set_next_event workarounds
>   arm64: arch_timer: Make workaround methods optional
>   arm64: arch_timer: Allows a CPU-specific erratum to only affect a
>     subset of CPUs
>   arm64: arch_timer: Move clocksource_counter and co around
>   arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled
>   arm64: arch_timer: Workaround for Cortex-A73 erratum 858921
>   arm64: arch_timer: Allow erratum matching with ACPI OEM information
>   arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data
> 
>  Documentation/arm64/silicon-errata.txt |   1 +
>  arch/arm64/include/asm/arch_timer.h    |  44 ++-
>  arch/arm64/include/asm/cpucaps.h       |   3 +-
>  arch/arm64/include/asm/cputype.h       |   2 +
>  arch/arm64/include/asm/esr.h           |   2 +
>  arch/arm64/kernel/cpu_errata.c         |  15 +
>  arch/arm64/kernel/cpufeature.c         |  13 +-
>  arch/arm64/kernel/traps.c              |  14 +
>  drivers/clocksource/Kconfig            |  11 +
>  drivers/clocksource/arm_arch_timer.c   | 535 +++++++++++++++++++++++----------
>  10 files changed, 471 insertions(+), 169 deletions(-)
> 

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 00/18] clocksource/arch_timer: Errata workaround infrastructure rework
@ 2017-03-22 13:56   ` Ding Tianhong
  0 siblings, 0 replies; 88+ messages in thread
From: Ding Tianhong @ 2017-03-22 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

Tested-by: Ding Tianhong <dingtianhong@huawei.com>

On 2017/3/21 1:48, Marc Zyngier wrote:
> It has recently become obvious that a number of arm64 systems have
> been blessed with a set of timers that are slightly less than perfect,
> and require a bit of hand-holding. We already have a bunch of
> errata-specific code to deal with this, but as we're adding more
> potential detection methods (DT, ACPI, capability), things are getting
> a bit out of hands.
> 
> Instead of adding more ad-hoc fixes to an already difficult code base,
> let's give ourselves a bit of an infrastructure that can deal with
> this and hide most of the uggliness behind frendly accessors.
> 
> The series is structured as such:
> 
> - A bunch of arm64 specific patches that allow the rest of the
>   workaround infrastructure to be built upon (such as being able to
>   trap userspace access to the virtual counter). These are now
>   separate in order to allow the creation of a shared branch between
>   the arm64 and clocksource trees.
> 
> - The following patches rework the existing workarounds, allowing
>   errata to be matched using a given detection method
> 
> - Another patch allows a workaround to affect a subset of the CPUs,
>   and not the whole system
> 
> - We then work around a Cortex-A73 erratum, whose counter can return a
>   wrong value if read while crossing a 32bit boundary
> 
> - Finally, we add some ACPI-specific workarounds for HiSilicon
>   platforms that have the HISILICON_ERRATUM_161010101 defect.
> 
> Note that so far, we only deal with arm64. Once the infrastructure is
> agreed upon, we can look at generalizing it (to some extent) to 32bit
> ARM (typical use case would be a 32bit guest running on an affected
> host).
> 
> * From v1:
>   - Addressed Hanjun and Mark review comments
>   - Moved arm64 specific patches to the beginning of the series,
>     leaving the clocksource patches at the end, resulting in an extra
>     patch.
>   - Added RBs, TBs, and Acks.
> 
> Marc Zyngier (18):
>   arm64: Allow checking of a CPU-local erratum
>   arm64: Add CNTVCT_EL0 trap handler
>   arm64: Define Cortex-A73 MIDR
>   arm64: cpu_errata: Allow an erratum to be match for all revisions of a
>     core
>   arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum
>     858921
>   arm64: arch_timer: Add infrastructure for multiple erratum detection
>     methods
>   arm64: arch_timer: Add erratum handler for globally defined capability
>   arm64: arch_timer: Add erratum handler for CPU-specific capability
>   arm64: arch_timer: Move arch_timer_reg_read/write around
>   arm64: arch_timer: Get rid of erratum_workaround_set_sne
>   arm64: arch_timer: Rework the set_next_event workarounds
>   arm64: arch_timer: Make workaround methods optional
>   arm64: arch_timer: Allows a CPU-specific erratum to only affect a
>     subset of CPUs
>   arm64: arch_timer: Move clocksource_counter and co around
>   arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled
>   arm64: arch_timer: Workaround for Cortex-A73 erratum 858921
>   arm64: arch_timer: Allow erratum matching with ACPI OEM information
>   arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data
> 
>  Documentation/arm64/silicon-errata.txt |   1 +
>  arch/arm64/include/asm/arch_timer.h    |  44 ++-
>  arch/arm64/include/asm/cpucaps.h       |   3 +-
>  arch/arm64/include/asm/cputype.h       |   2 +
>  arch/arm64/include/asm/esr.h           |   2 +
>  arch/arm64/kernel/cpu_errata.c         |  15 +
>  arch/arm64/kernel/cpufeature.c         |  13 +-
>  arch/arm64/kernel/traps.c              |  14 +
>  drivers/clocksource/Kconfig            |  11 +
>  drivers/clocksource/arm_arch_timer.c   | 535 +++++++++++++++++++++++----------
>  10 files changed, 471 insertions(+), 169 deletions(-)
> 

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 04/18] arm64: cpu_errata: Allow an erratum to be match for all revisions of a core
  2017-03-20 17:48   ` Marc Zyngier
@ 2017-03-22 14:57     ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 14:57 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Mon, Mar 20, 2017 at 05:48:15PM +0000, Marc Zyngier wrote:
> Some minor erratum may not be fixed in further revisions of a core,
> leading to a situation where the workaround needs to be updated each
> time an updated core is released.
> 
> Introduce a MIDR_ALL_VERSIONS match helper that will work for all
> versions of that MIDR, once and for all.
> 
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>


-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 04/18] arm64: cpu_errata: Allow an erratum to be match for all revisions of a core
@ 2017-03-22 14:57     ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 20, 2017 at 05:48:15PM +0000, Marc Zyngier wrote:
> Some minor erratum may not be fixed in further revisions of a core,
> leading to a situation where the workaround needs to be updated each
> time an updated core is released.
> 
> Introduce a MIDR_ALL_VERSIONS match helper that will work for all
> versions of that MIDR, once and for all.
> 
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>


-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 05/18] arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum 858921
  2017-03-20 17:48   ` Marc Zyngier
@ 2017-03-22 15:01     ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 15:01 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Mon, Mar 20, 2017 at 05:48:16PM +0000, Marc Zyngier wrote:
> In order to work around Cortex-A73 erratum 858921 in a subsequent
> patch, add the required capability that advertise the erratum.
> 
> As the configuration option it depends on is not present yet,
> this has no immediate effect.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>



-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 05/18] arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum 858921
@ 2017-03-22 15:01     ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 20, 2017 at 05:48:16PM +0000, Marc Zyngier wrote:
> In order to work around Cortex-A73 erratum 858921 in a subsequent
> patch, add the required capability that advertise the erratum.
> 
> As the configuration option it depends on is not present yet,
> this has no immediate effect.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>



-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-20 17:48   ` Marc Zyngier
@ 2017-03-22 15:41     ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 15:41 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
> We're currently stuck with DT when it comes to handling errata, which
> is pretty restrictive. In order to make things more flexible, let's
> introduce an infrastructure that could support alternative discovery
> methods. No change in functionality.
> 
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>  2 files changed, 75 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index b4b34004a21e..5cd964e90d11 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -37,9 +37,14 @@ 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,
> +};
>  
>  struct arch_timer_erratum_workaround {
> -	const char *id;		/* Indicate the Erratum ID */
> +	enum arch_timer_erratum_match_type match_type;

Putting the match_fn instead will be much more simpler and the code won't
have to deal with ate_match_type, no ?

[ ... ]

> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
> +					    void *arg)
> +{
> +	const struct arch_timer_erratum_workaround *wa;
> +	ate_match_fn_t match_fn = NULL;
> +
> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
> +		return;
> +

Why is this check necessary ?

[ ... ]



-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-22 15:41     ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
> We're currently stuck with DT when it comes to handling errata, which
> is pretty restrictive. In order to make things more flexible, let's
> introduce an infrastructure that could support alternative discovery
> methods. No change in functionality.
> 
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>  2 files changed, 75 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index b4b34004a21e..5cd964e90d11 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -37,9 +37,14 @@ 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,
> +};
>  
>  struct arch_timer_erratum_workaround {
> -	const char *id;		/* Indicate the Erratum ID */
> +	enum arch_timer_erratum_match_type match_type;

Putting the match_fn instead will be much more simpler and the code won't
have to deal with ate_match_type, no ?

[ ... ]

> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
> +					    void *arg)
> +{
> +	const struct arch_timer_erratum_workaround *wa;
> +	ate_match_fn_t match_fn = NULL;
> +
> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
> +		return;
> +

Why is this check necessary ?

[ ... ]



-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 09/18] arm64: arch_timer: Move arch_timer_reg_read/write around
  2017-03-20 17:48   ` Marc Zyngier
@ 2017-03-22 15:47     ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 15:47 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Mon, Mar 20, 2017 at 05:48:20PM +0000, Marc Zyngier wrote:
> As we're about to move things around, let's start with the low
> level read/write functions. This allows us to use these functions
> in the errata handling code without having to use forward declaration
> of static functions.
> 
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 09/18] arm64: arch_timer: Move arch_timer_reg_read/write around
@ 2017-03-22 15:47     ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 15:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 20, 2017 at 05:48:20PM +0000, Marc Zyngier wrote:
> As we're about to move things around, let's start with the low
> level read/write functions. This allows us to use these functions
> in the errata handling code without having to use forward declaration
> of static functions.
> 
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-22 15:41     ` Daniel Lezcano
@ 2017-03-22 15:53       ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-22 15:53 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On 22/03/17 15:41, Daniel Lezcano wrote:
> On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
>> We're currently stuck with DT when it comes to handling errata, which
>> is pretty restrictive. In order to make things more flexible, let's
>> introduce an infrastructure that could support alternative discovery
>> methods. No change in functionality.
>>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index b4b34004a21e..5cd964e90d11 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -37,9 +37,14 @@ 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,
>> +};
>>  
>>  struct arch_timer_erratum_workaround {
>> -	const char *id;		/* Indicate the Erratum ID */
>> +	enum arch_timer_erratum_match_type match_type;
> 
> Putting the match_fn instead will be much more simpler and the code won't
> have to deal with ate_match_type, no ?

I'm not sure about the "much simpler" aspect. Each function is not
necessarily standalone (see patches 8 and 13 for example, dealing with
CPU-local defects). We

> 
> [ ... ]
> 
>> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
>> +					    void *arg)
>> +{
>> +	const struct arch_timer_erratum_workaround *wa;
>> +	ate_match_fn_t match_fn = NULL;
>> +
>> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
>> +		return;
>> +
> 
> Why is this check necessary ?

We don't allow cumulative workarounds at this stage. This restriction
gets lifted (to some extent) later in the series.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-22 15:53       ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-22 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 22/03/17 15:41, Daniel Lezcano wrote:
> On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
>> We're currently stuck with DT when it comes to handling errata, which
>> is pretty restrictive. In order to make things more flexible, let's
>> introduce an infrastructure that could support alternative discovery
>> methods. No change in functionality.
>>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index b4b34004a21e..5cd964e90d11 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -37,9 +37,14 @@ 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,
>> +};
>>  
>>  struct arch_timer_erratum_workaround {
>> -	const char *id;		/* Indicate the Erratum ID */
>> +	enum arch_timer_erratum_match_type match_type;
> 
> Putting the match_fn instead will be much more simpler and the code won't
> have to deal with ate_match_type, no ?

I'm not sure about the "much simpler" aspect. Each function is not
necessarily standalone (see patches 8 and 13 for example, dealing with
CPU-local defects). We

> 
> [ ... ]
> 
>> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
>> +					    void *arg)
>> +{
>> +	const struct arch_timer_erratum_workaround *wa;
>> +	ate_match_fn_t match_fn = NULL;
>> +
>> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
>> +		return;
>> +
> 
> Why is this check necessary ?

We don't allow cumulative workarounds at this stage. This restriction
gets lifted (to some extent) later in the series.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-22 15:41     ` Daniel Lezcano
@ 2017-03-22 15:59       ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-22 15:59 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

[Sorry, sent too quickly]

On 22/03/17 15:41, Daniel Lezcano wrote:
> On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
>> We're currently stuck with DT when it comes to handling errata, which
>> is pretty restrictive. In order to make things more flexible, let's
>> introduce an infrastructure that could support alternative discovery
>> methods. No change in functionality.
>>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index b4b34004a21e..5cd964e90d11 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -37,9 +37,14 @@ 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,
>> +};
>>  
>>  struct arch_timer_erratum_workaround {
>> -	const char *id;		/* Indicate the Erratum ID */
>> +	enum arch_timer_erratum_match_type match_type;
> 
> Putting the match_fn instead will be much more simpler and the code won't
> have to deal with ate_match_type, no ?

I'm not sure about the "much simpler" aspect. Each function is not
necessarily standalone (see patches 8 and 13 for example, dealing with
CPU-local defects).

Also, given that we have two architectures to cater for, as well as two
firmware interfaces, it makes more sense (at least to me) to have
something that doesn't require to define a bunch of empty stubs (we
already have too many of them) depending on arm vs arm64, DT vs ACPI,
errata handling enabled vs disabled.

We're sidestepping this at the moment because it all lives under one
single config option that cannot be enabled from 32bit, but I hope to
change that.

> 
> [ ... ]
> 
>> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
>> +					    void *arg)
>> +{
>> +	const struct arch_timer_erratum_workaround *wa;
>> +	ate_match_fn_t match_fn = NULL;
>> +
>> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
>> +		return;
>> +
> 
> Why is this check necessary ?

We don't allow cumulative workarounds at this stage. This restriction
gets lifted (to some extent) later in the series.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-22 15:59       ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-22 15:59 UTC (permalink / raw)
  To: linux-arm-kernel

[Sorry, sent too quickly]

On 22/03/17 15:41, Daniel Lezcano wrote:
> On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
>> We're currently stuck with DT when it comes to handling errata, which
>> is pretty restrictive. In order to make things more flexible, let's
>> introduce an infrastructure that could support alternative discovery
>> methods. No change in functionality.
>>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index b4b34004a21e..5cd964e90d11 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -37,9 +37,14 @@ 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,
>> +};
>>  
>>  struct arch_timer_erratum_workaround {
>> -	const char *id;		/* Indicate the Erratum ID */
>> +	enum arch_timer_erratum_match_type match_type;
> 
> Putting the match_fn instead will be much more simpler and the code won't
> have to deal with ate_match_type, no ?

I'm not sure about the "much simpler" aspect. Each function is not
necessarily standalone (see patches 8 and 13 for example, dealing with
CPU-local defects).

Also, given that we have two architectures to cater for, as well as two
firmware interfaces, it makes more sense (at least to me) to have
something that doesn't require to define a bunch of empty stubs (we
already have too many of them) depending on arm vs arm64, DT vs ACPI,
errata handling enabled vs disabled.

We're sidestepping this at the moment because it all lives under one
single config option that cannot be enabled from 32bit, but I hope to
change that.

> 
> [ ... ]
> 
>> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
>> +					    void *arg)
>> +{
>> +	const struct arch_timer_erratum_workaround *wa;
>> +	ate_match_fn_t match_fn = NULL;
>> +
>> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
>> +		return;
>> +
> 
> Why is this check necessary ?

We don't allow cumulative workarounds at this stage. This restriction
gets lifted (to some extent) later in the series.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-22 15:59       ` Marc Zyngier
@ 2017-03-22 16:52         ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 16:52 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Wed, Mar 22, 2017 at 03:59:21PM +0000, Marc Zyngier wrote:
> [Sorry, sent too quickly]
> 

[ ... ]

> >>  struct arch_timer_erratum_workaround {
> >> -	const char *id;		/* Indicate the Erratum ID */
> >> +	enum arch_timer_erratum_match_type match_type;
> > 
> > Putting the match_fn instead will be much more simpler and the code won't
> > have to deal with ate_match_type, no ?
> 
> I'm not sure about the "much simpler" aspect. Each function is not
> necessarily standalone (see patches 8 and 13 for example, dealing with
> CPU-local defects).

Why not write always errata on a per cpu basis ? So there is no need to go
through global/local (at the timer level).

You have been probably looking at this much longer than me and perhaps I'm
missing something. However, I think we can find a way to simplify the approach. 

Give me one day to see if I'm right.

> Also, given that we have two architectures to cater for, as well as two
> firmware interfaces, it makes more sense (at least to me) to have
> something that doesn't require to define a bunch of empty stubs (we
> already have too many of them) depending on arm vs arm64, DT vs ACPI,
> errata handling enabled vs disabled.

That is a fair point.
 
> We're sidestepping this at the moment because it all lives under one
> single config option that cannot be enabled from 32bit, but I hope to
> change that.

Ok, that sounds good.

Thanks for proposing something to deal elegantly with the errata.

  -- Daniel


> > [ ... ]
> > 
> >> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
> >> +					    void *arg)
> >> +{
> >> +	const struct arch_timer_erratum_workaround *wa;
> >> +	ate_match_fn_t match_fn = NULL;
> >> +
> >> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
> >> +		return;
> >> +
> > 
> > Why is this check necessary ?
> 
> We don't allow cumulative workarounds at this stage. This restriction
> gets lifted (to some extent) later in the series.
> 
> Thanks,
> 
> 	M.
> -- 
> Jazz is not dead. It just smells funny...

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-22 16:52         ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-22 16:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 03:59:21PM +0000, Marc Zyngier wrote:
> [Sorry, sent too quickly]
> 

[ ... ]

> >>  struct arch_timer_erratum_workaround {
> >> -	const char *id;		/* Indicate the Erratum ID */
> >> +	enum arch_timer_erratum_match_type match_type;
> > 
> > Putting the match_fn instead will be much more simpler and the code won't
> > have to deal with ate_match_type, no ?
> 
> I'm not sure about the "much simpler" aspect. Each function is not
> necessarily standalone (see patches 8 and 13 for example, dealing with
> CPU-local defects).

Why not write always errata on a per cpu basis ? So there is no need to go
through global/local (at the timer level).

You have been probably looking at this much longer than me and perhaps I'm
missing something. However, I think we can find a way to simplify the approach. 

Give me one day to see if I'm right.

> Also, given that we have two architectures to cater for, as well as two
> firmware interfaces, it makes more sense (at least to me) to have
> something that doesn't require to define a bunch of empty stubs (we
> already have too many of them) depending on arm vs arm64, DT vs ACPI,
> errata handling enabled vs disabled.

That is a fair point.
 
> We're sidestepping this at the moment because it all lives under one
> single config option that cannot be enabled from 32bit, but I hope to
> change that.

Ok, that sounds good.

Thanks for proposing something to deal elegantly with the errata.

  -- Daniel


> > [ ... ]
> > 
> >> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
> >> +					    void *arg)
> >> +{
> >> +	const struct arch_timer_erratum_workaround *wa;
> >> +	ate_match_fn_t match_fn = NULL;
> >> +
> >> +	if (static_branch_unlikely(&arch_timer_read_ool_enabled))
> >> +		return;
> >> +
> > 
> > Why is this check necessary ?
> 
> We don't allow cumulative workarounds at this stage. This restriction
> gets lifted (to some extent) later in the series.
> 
> Thanks,
> 
> 	M.
> -- 
> Jazz is not dead. It just smells funny...

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-22 15:59       ` Marc Zyngier
@ 2017-03-23 17:30         ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-23 17:30 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Wed, Mar 22, 2017 at 03:59:21PM +0000, Marc Zyngier wrote:
> [Sorry, sent too quickly]
> 
> On 22/03/17 15:41, Daniel Lezcano wrote:
> > On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
> >> We're currently stuck with DT when it comes to handling errata, which
> >> is pretty restrictive. In order to make things more flexible, let's
> >> introduce an infrastructure that could support alternative discovery
> >> methods. No change in functionality.
> >>
> >> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
> >>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
> >>  2 files changed, 75 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> >> index b4b34004a21e..5cd964e90d11 100644
> >> --- a/arch/arm64/include/asm/arch_timer.h
> >> +++ b/arch/arm64/include/asm/arch_timer.h
> >> @@ -37,9 +37,14 @@ 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,
> >> +};
> >>  
> >>  struct arch_timer_erratum_workaround {
> >> -	const char *id;		/* Indicate the Erratum ID */
> >> +	enum arch_timer_erratum_match_type match_type;
> > 
> > Putting the match_fn instead will be much more simpler and the code won't
> > have to deal with ate_match_type, no ?
> 
> I'm not sure about the "much simpler" aspect. Each function is not
> necessarily standalone (see patches 8 and 13 for example, dealing with
> CPU-local defects).

Hi Marc,

I have been through the driver after applying the patchset. Again thanks for
taking care of this. It is not a simple issue to solve, so here is my minor
contribution.

The resulting code sounds like over-engineered because the errata check and its
workaround are done at the same place/moment, that forces to deal with an array
with element from different origin.

I understand you wanted to create a single array to handle the errata
information from the DT, ACPI and CAPS. But IMHO, it does not fit well.

I would suggest to create 3 arrays: ACPI, DT and CAPS.

Those arrays contains the errata id *and* an unique private id.

At boot time, you go through the corresponding array and fill a list of
detected errata with the private id.

On the other side, an array with the private id and its workaround makes the
assocation. The private id is the contract between the errata and the workaround.

So the errata handling will occur in two steps:
 1. Boot => errata detection
 2. CPU up => workaround put in place

With this approach, you can write everything on a per cpu basis, getting rid of
'global' / 'local'.

What is this different from your approach ?

 - no match_id
 - clear separation of errata and workaround
 - Simpler code
 - clear the scene for a more generic errata framework

That said, now it would make sense to create a generic errata framework to be
filled by the different arch at boot time and retrieve from the different
subsystem in an agnostic way. Well, may be that is a long term suggestion.

What do you think ?

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-23 17:30         ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-23 17:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 03:59:21PM +0000, Marc Zyngier wrote:
> [Sorry, sent too quickly]
> 
> On 22/03/17 15:41, Daniel Lezcano wrote:
> > On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
> >> We're currently stuck with DT when it comes to handling errata, which
> >> is pretty restrictive. In order to make things more flexible, let's
> >> introduce an infrastructure that could support alternative discovery
> >> methods. No change in functionality.
> >>
> >> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
> >>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
> >>  2 files changed, 75 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> >> index b4b34004a21e..5cd964e90d11 100644
> >> --- a/arch/arm64/include/asm/arch_timer.h
> >> +++ b/arch/arm64/include/asm/arch_timer.h
> >> @@ -37,9 +37,14 @@ 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,
> >> +};
> >>  
> >>  struct arch_timer_erratum_workaround {
> >> -	const char *id;		/* Indicate the Erratum ID */
> >> +	enum arch_timer_erratum_match_type match_type;
> > 
> > Putting the match_fn instead will be much more simpler and the code won't
> > have to deal with ate_match_type, no ?
> 
> I'm not sure about the "much simpler" aspect. Each function is not
> necessarily standalone (see patches 8 and 13 for example, dealing with
> CPU-local defects).

Hi Marc,

I have been through the driver after applying the patchset. Again thanks for
taking care of this. It is not a simple issue to solve, so here is my minor
contribution.

The resulting code sounds like over-engineered because the errata check and its
workaround are done at the same place/moment, that forces to deal with an array
with element from different origin.

I understand you wanted to create a single array to handle the errata
information from the DT, ACPI and CAPS. But IMHO, it does not fit well.

I would suggest to create 3 arrays: ACPI, DT and CAPS.

Those arrays contains the errata id *and* an unique private id.

At boot time, you go through the corresponding array and fill a list of
detected errata with the private id.

On the other side, an array with the private id and its workaround makes the
assocation. The private id is the contract between the errata and the workaround.

So the errata handling will occur in two steps:
 1. Boot => errata detection
 2. CPU up => workaround put in place

With this approach, you can write everything on a per cpu basis, getting rid of
'global' / 'local'.

What is this different from your approach ?

 - no match_id
 - clear separation of errata and workaround
 - Simpler code
 - clear the scene for a more generic errata framework

That said, now it would make sense to create a generic errata framework to be
filled by the different arch at boot time and retrieve from the different
subsystem in an agnostic way. Well, may be that is a long term suggestion.

What do you think ?

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-23 17:30         ` Daniel Lezcano
@ 2017-03-24 13:51           ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-24 13:51 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

Hi Daniel,

On 23/03/17 17:30, Daniel Lezcano wrote:
> On Wed, Mar 22, 2017 at 03:59:21PM +0000, Marc Zyngier wrote:
>> [Sorry, sent too quickly]
>>
>> On 22/03/17 15:41, Daniel Lezcano wrote:
>>> On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
>>>> We're currently stuck with DT when it comes to handling errata, which
>>>> is pretty restrictive. In order to make things more flexible, let's
>>>> introduce an infrastructure that could support alternative discovery
>>>> methods. No change in functionality.
>>>>
>>>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> ---
>>>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>>>> index b4b34004a21e..5cd964e90d11 100644
>>>> --- a/arch/arm64/include/asm/arch_timer.h
>>>> +++ b/arch/arm64/include/asm/arch_timer.h
>>>> @@ -37,9 +37,14 @@ 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,
>>>> +};
>>>>  
>>>>  struct arch_timer_erratum_workaround {
>>>> -	const char *id;		/* Indicate the Erratum ID */
>>>> +	enum arch_timer_erratum_match_type match_type;
>>>
>>> Putting the match_fn instead will be much more simpler and the code won't
>>> have to deal with ate_match_type, no ?
>>
>> I'm not sure about the "much simpler" aspect. Each function is not
>> necessarily standalone (see patches 8 and 13 for example, dealing with
>> CPU-local defects).
> 
> Hi Marc,
> 
> I have been through the driver after applying the patchset. Again thanks for
> taking care of this. It is not a simple issue to solve, so here is my minor
> contribution.
> 
> The resulting code sounds like over-engineered because the errata check and its
> workaround are done at the same place/moment, that forces to deal with an array
> with element from different origin.
> 
> I understand you wanted to create a single array to handle the errata
> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
> 
> I would suggest to create 3 arrays: ACPI, DT and CAPS.
> 
> Those arrays contains the errata id *and* an unique private id.
> 
> At boot time, you go through the corresponding array and fill a list of
> detected errata with the private id.
> 
> On the other side, an array with the private id and its workaround makes the
> assocation. The private id is the contract between the errata and the workaround.
> 
> So the errata handling will occur in two steps:
>  1. Boot => errata detection
>  2. CPU up => workaround put in place
> 
> With this approach, you can write everything on a per cpu basis, getting rid of
> 'global' / 'local'.
> 
> What is this different from your approach ?
> 
>  - no match_id
>  - clear separation of errata and workaround
>  - Simpler code
>  - clear the scene for a more generic errata framework
> 
> That said, now it would make sense to create a generic errata framework to be
> filled by the different arch at boot time and retrieve from the different
> subsystem in an agnostic way. Well, may be that is a long term suggestion.
> 
> What do you think ?

I don't think this buys us anything at all. Separating detection and
enablement is not always feasible. In your example above, you assume
that all errata are detectable at boot time. Consider that with CPU
hotplug, we can bring up a new core at any time, possibly with an
erratum that you haven't detected yet.

And even then, what do we get: we trade a simple match ID for a list we
build at runtime, another private ID, and additional code to perform
that match. The gain is not obvious to me...

What would such a generic errata framework look like? A table containing
match functions returning a boolean, used to decide whether you need to
call yet another function with a bunch of arbitrary parameters.

In my experience, such a framework will be either an empty shell
(because you need to keep it as generic as possible), or will be riddled
with data structures ending up being the union of all the possible cases
you've encountered in the kernel. Not a pretty sight.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-24 13:51           ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-24 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On 23/03/17 17:30, Daniel Lezcano wrote:
> On Wed, Mar 22, 2017 at 03:59:21PM +0000, Marc Zyngier wrote:
>> [Sorry, sent too quickly]
>>
>> On 22/03/17 15:41, Daniel Lezcano wrote:
>>> On Mon, Mar 20, 2017 at 05:48:17PM +0000, Marc Zyngier wrote:
>>>> We're currently stuck with DT when it comes to handling errata, which
>>>> is pretty restrictive. In order to make things more flexible, let's
>>>> introduce an infrastructure that could support alternative discovery
>>>> methods. No change in functionality.
>>>>
>>>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> ---
>>>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>>>> index b4b34004a21e..5cd964e90d11 100644
>>>> --- a/arch/arm64/include/asm/arch_timer.h
>>>> +++ b/arch/arm64/include/asm/arch_timer.h
>>>> @@ -37,9 +37,14 @@ 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,
>>>> +};
>>>>  
>>>>  struct arch_timer_erratum_workaround {
>>>> -	const char *id;		/* Indicate the Erratum ID */
>>>> +	enum arch_timer_erratum_match_type match_type;
>>>
>>> Putting the match_fn instead will be much more simpler and the code won't
>>> have to deal with ate_match_type, no ?
>>
>> I'm not sure about the "much simpler" aspect. Each function is not
>> necessarily standalone (see patches 8 and 13 for example, dealing with
>> CPU-local defects).
> 
> Hi Marc,
> 
> I have been through the driver after applying the patchset. Again thanks for
> taking care of this. It is not a simple issue to solve, so here is my minor
> contribution.
> 
> The resulting code sounds like over-engineered because the errata check and its
> workaround are done at the same place/moment, that forces to deal with an array
> with element from different origin.
> 
> I understand you wanted to create a single array to handle the errata
> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
> 
> I would suggest to create 3 arrays: ACPI, DT and CAPS.
> 
> Those arrays contains the errata id *and* an unique private id.
> 
> At boot time, you go through the corresponding array and fill a list of
> detected errata with the private id.
> 
> On the other side, an array with the private id and its workaround makes the
> assocation. The private id is the contract between the errata and the workaround.
> 
> So the errata handling will occur in two steps:
>  1. Boot => errata detection
>  2. CPU up => workaround put in place
> 
> With this approach, you can write everything on a per cpu basis, getting rid of
> 'global' / 'local'.
> 
> What is this different from your approach ?
> 
>  - no match_id
>  - clear separation of errata and workaround
>  - Simpler code
>  - clear the scene for a more generic errata framework
> 
> That said, now it would make sense to create a generic errata framework to be
> filled by the different arch at boot time and retrieve from the different
> subsystem in an agnostic way. Well, may be that is a long term suggestion.
> 
> What do you think ?

I don't think this buys us anything at all. Separating detection and
enablement is not always feasible. In your example above, you assume
that all errata are detectable at boot time. Consider that with CPU
hotplug, we can bring up a new core at any time, possibly with an
erratum that you haven't detected yet.

And even then, what do we get: we trade a simple match ID for a list we
build at runtime, another private ID, and additional code to perform
that match. The gain is not obvious to me...

What would such a generic errata framework look like? A table containing
match functions returning a boolean, used to decide whether you need to
call yet another function with a bunch of arbitrary parameters.

In my experience, such a framework will be either an empty shell
(because you need to keep it as generic as possible), or will be riddled
with data structures ending up being the union of all the possible cases
you've encountered in the kernel. Not a pretty sight.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-20 17:48   ` Marc Zyngier
@ 2017-03-24 17:48     ` dann frazier
  -1 siblings, 0 replies; 88+ messages in thread
From: dann frazier @ 2017-03-24 17:48 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Daniel Lezcano, Will Deacon, Scott Wood, Hanjun Guo,
	Ding Tianhong, Seth Forshee

On Mon, Mar 20, 2017 at 11:48 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> We're currently stuck with DT when it comes to handling errata, which
> is pretty restrictive. In order to make things more flexible, let's
> introduce an infrastructure that could support alternative discovery
> methods. No change in functionality.
>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>  2 files changed, 75 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index b4b34004a21e..5cd964e90d11 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -37,9 +37,14 @@ 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,
> +};
>
>  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);
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 7a8a4117f123..6a0f0e161a0f 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
>  static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  #ifdef CONFIG_FSL_ERRATUM_A008585
>         {
> +               .match_type = ate_match_dt,
>                 .id = "fsl,erratum-a008585",
> +               .desc = "Freescale erratum a005858",
>                 .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
>                 .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>                 .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
> @@ -190,13 +192,78 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  #endif
>  #ifdef CONFIG_HISILICON_ERRATUM_161010101
>         {
> +               .match_type = ate_match_dt,
>                 .id = "hisilicon,erratum-161010101",
> +               .desc = "HiSilicon erratum 161010101",
>                 .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
>                 .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>         },
>  #endif
>  };
> +
> +typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
> +                              const void *);
> +
> +static
> +bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
> +                                const void *arg)
> +{
> +       const struct device_node *np = arg;
> +
> +       return of_property_read_bool(np, wa->id);
> +}
> +
> +static const struct arch_timer_erratum_workaround *
> +arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
> +                         ate_match_fn_t match_fn,
> +                         void *arg)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
> +               if (ool_workarounds[i].match_type != type)
> +                       continue;
> +
> +               if (match_fn(&ool_workarounds[i], arg))
> +                       return &ool_workarounds[i];
> +       }
> +
> +       return NULL;
> +}
> +
> +static
> +void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
> +{
> +       timer_unstable_counter_workaround = wa;
> +       static_branch_enable(&arch_timer_read_ool_enabled);
> +}
> +
> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
> +                                           void *arg)
> +{
> +       const struct arch_timer_erratum_workaround *wa;
> +       ate_match_fn_t match_fn = NULL;
> +
> +       if (static_branch_unlikely(&arch_timer_read_ool_enabled))
> +               return;
> +
> +       switch (type) {
> +       case ate_match_dt:
> +               match_fn = arch_timer_check_dt_erratum;
> +               break;

hey Marc,
   Would it make sense to have a default case here that warns &
returns? That wouldn't get hit by this series as-is, but might avoid a
NULL callback in the future.

  -dann

> +       }
> +
> +       wa = arch_timer_iterate_errata(type, match_fn, arg);
> +       if (!wa)
> +               return;
> +
> +       arch_timer_enable_workaround(wa);
> +       pr_info("Enabling global workaround for %s\n", wa->desc);
> +}
> +
> +#else
> +#define arch_timer_check_ool_workaround(t,a)           do { } while(0)
>  #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
>
>  static __always_inline
> @@ -960,17 +1027,8 @@ static int __init arch_timer_of_init(struct device_node *np)
>
>         arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>
> -#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
> -       for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
> -               if (of_property_read_bool(np, ool_workarounds[i].id)) {
> -                       timer_unstable_counter_workaround = &ool_workarounds[i];
> -                       static_branch_enable(&arch_timer_read_ool_enabled);
> -                       pr_info("arch_timer: Enabling workaround for %s\n",
> -                               timer_unstable_counter_workaround->id);
> -                       break;
> -               }
> -       }
> -#endif
> +       /* Check for globally applicable workarounds */
> +       arch_timer_check_ool_workaround(ate_match_dt, np);
>
>         /*
>          * If we cannot rely on firmware initializing the timer registers then
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-24 17:48     ` dann frazier
  0 siblings, 0 replies; 88+ messages in thread
From: dann frazier @ 2017-03-24 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 20, 2017 at 11:48 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> We're currently stuck with DT when it comes to handling errata, which
> is pretty restrictive. In order to make things more flexible, let's
> introduce an infrastructure that could support alternative discovery
> methods. No change in functionality.
>
> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>  2 files changed, 75 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index b4b34004a21e..5cd964e90d11 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -37,9 +37,14 @@ 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,
> +};
>
>  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);
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 7a8a4117f123..6a0f0e161a0f 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
>  static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  #ifdef CONFIG_FSL_ERRATUM_A008585
>         {
> +               .match_type = ate_match_dt,
>                 .id = "fsl,erratum-a008585",
> +               .desc = "Freescale erratum a005858",
>                 .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
>                 .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>                 .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
> @@ -190,13 +192,78 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  #endif
>  #ifdef CONFIG_HISILICON_ERRATUM_161010101
>         {
> +               .match_type = ate_match_dt,
>                 .id = "hisilicon,erratum-161010101",
> +               .desc = "HiSilicon erratum 161010101",
>                 .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
>                 .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>         },
>  #endif
>  };
> +
> +typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
> +                              const void *);
> +
> +static
> +bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
> +                                const void *arg)
> +{
> +       const struct device_node *np = arg;
> +
> +       return of_property_read_bool(np, wa->id);
> +}
> +
> +static const struct arch_timer_erratum_workaround *
> +arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
> +                         ate_match_fn_t match_fn,
> +                         void *arg)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
> +               if (ool_workarounds[i].match_type != type)
> +                       continue;
> +
> +               if (match_fn(&ool_workarounds[i], arg))
> +                       return &ool_workarounds[i];
> +       }
> +
> +       return NULL;
> +}
> +
> +static
> +void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
> +{
> +       timer_unstable_counter_workaround = wa;
> +       static_branch_enable(&arch_timer_read_ool_enabled);
> +}
> +
> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
> +                                           void *arg)
> +{
> +       const struct arch_timer_erratum_workaround *wa;
> +       ate_match_fn_t match_fn = NULL;
> +
> +       if (static_branch_unlikely(&arch_timer_read_ool_enabled))
> +               return;
> +
> +       switch (type) {
> +       case ate_match_dt:
> +               match_fn = arch_timer_check_dt_erratum;
> +               break;

hey Marc,
   Would it make sense to have a default case here that warns &
returns? That wouldn't get hit by this series as-is, but might avoid a
NULL callback in the future.

  -dann

> +       }
> +
> +       wa = arch_timer_iterate_errata(type, match_fn, arg);
> +       if (!wa)
> +               return;
> +
> +       arch_timer_enable_workaround(wa);
> +       pr_info("Enabling global workaround for %s\n", wa->desc);
> +}
> +
> +#else
> +#define arch_timer_check_ool_workaround(t,a)           do { } while(0)
>  #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
>
>  static __always_inline
> @@ -960,17 +1027,8 @@ static int __init arch_timer_of_init(struct device_node *np)
>
>         arch_timer_c3stop = !of_property_read_bool(np, "always-on");
>
> -#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
> -       for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
> -               if (of_property_read_bool(np, ool_workarounds[i].id)) {
> -                       timer_unstable_counter_workaround = &ool_workarounds[i];
> -                       static_branch_enable(&arch_timer_read_ool_enabled);
> -                       pr_info("arch_timer: Enabling workaround for %s\n",
> -                               timer_unstable_counter_workaround->id);
> -                       break;
> -               }
> -       }
> -#endif
> +       /* Check for globally applicable workarounds */
> +       arch_timer_check_ool_workaround(ate_match_dt, np);
>
>         /*
>          * If we cannot rely on firmware initializing the timer registers then
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-24 17:48     ` dann frazier
@ 2017-03-24 18:00       ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-24 18:00 UTC (permalink / raw)
  To: dann frazier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Daniel Lezcano, Will Deacon, Scott Wood, Hanjun Guo,
	Ding Tianhong, Seth Forshee

Hi Dann,

On 24/03/17 17:48, dann frazier wrote:
> On Mon, Mar 20, 2017 at 11:48 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
>> We're currently stuck with DT when it comes to handling errata, which
>> is pretty restrictive. In order to make things more flexible, let's
>> introduce an infrastructure that could support alternative discovery
>> methods. No change in functionality.
>>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index b4b34004a21e..5cd964e90d11 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -37,9 +37,14 @@ 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,
>> +};
>>
>>  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);
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 7a8a4117f123..6a0f0e161a0f 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
>>  static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>>  #ifdef CONFIG_FSL_ERRATUM_A008585
>>         {
>> +               .match_type = ate_match_dt,
>>                 .id = "fsl,erratum-a008585",
>> +               .desc = "Freescale erratum a005858",
>>                 .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
>>                 .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>>                 .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
>> @@ -190,13 +192,78 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>>  #endif
>>  #ifdef CONFIG_HISILICON_ERRATUM_161010101
>>         {
>> +               .match_type = ate_match_dt,
>>                 .id = "hisilicon,erratum-161010101",
>> +               .desc = "HiSilicon erratum 161010101",
>>                 .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
>>                 .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>>         },
>>  #endif
>>  };
>> +
>> +typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
>> +                              const void *);
>> +
>> +static
>> +bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
>> +                                const void *arg)
>> +{
>> +       const struct device_node *np = arg;
>> +
>> +       return of_property_read_bool(np, wa->id);
>> +}
>> +
>> +static const struct arch_timer_erratum_workaround *
>> +arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
>> +                         ate_match_fn_t match_fn,
>> +                         void *arg)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
>> +               if (ool_workarounds[i].match_type != type)
>> +                       continue;
>> +
>> +               if (match_fn(&ool_workarounds[i], arg))
>> +                       return &ool_workarounds[i];
>> +       }
>> +
>> +       return NULL;
>> +}
>> +
>> +static
>> +void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
>> +{
>> +       timer_unstable_counter_workaround = wa;
>> +       static_branch_enable(&arch_timer_read_ool_enabled);
>> +}
>> +
>> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
>> +                                           void *arg)
>> +{
>> +       const struct arch_timer_erratum_workaround *wa;
>> +       ate_match_fn_t match_fn = NULL;
>> +
>> +       if (static_branch_unlikely(&arch_timer_read_ool_enabled))
>> +               return;
>> +
>> +       switch (type) {
>> +       case ate_match_dt:
>> +               match_fn = arch_timer_check_dt_erratum;
>> +               break;
> 
> hey Marc,
>    Would it make sense to have a default case here that warns &
> returns? That wouldn't get hit by this series as-is, but might avoid a
> NULL callback in the future.

Sure, I can add that in the next version of this series. I would have
hoped that GCC would warn you if you don't handle all the values of an
enum, but it doesn't hurt to be cautious.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-24 18:00       ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-24 18:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dann,

On 24/03/17 17:48, dann frazier wrote:
> On Mon, Mar 20, 2017 at 11:48 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
>> We're currently stuck with DT when it comes to handling errata, which
>> is pretty restrictive. In order to make things more flexible, let's
>> introduce an infrastructure that could support alternative discovery
>> methods. No change in functionality.
>>
>> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/include/asm/arch_timer.h  |  7 +++-
>>  drivers/clocksource/arm_arch_timer.c | 80 +++++++++++++++++++++++++++++++-----
>>  2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
>> index b4b34004a21e..5cd964e90d11 100644
>> --- a/arch/arm64/include/asm/arch_timer.h
>> +++ b/arch/arm64/include/asm/arch_timer.h
>> @@ -37,9 +37,14 @@ 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,
>> +};
>>
>>  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);
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 7a8a4117f123..6a0f0e161a0f 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
>>  static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>>  #ifdef CONFIG_FSL_ERRATUM_A008585
>>         {
>> +               .match_type = ate_match_dt,
>>                 .id = "fsl,erratum-a008585",
>> +               .desc = "Freescale erratum a005858",
>>                 .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
>>                 .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>>                 .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
>> @@ -190,13 +192,78 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>>  #endif
>>  #ifdef CONFIG_HISILICON_ERRATUM_161010101
>>         {
>> +               .match_type = ate_match_dt,
>>                 .id = "hisilicon,erratum-161010101",
>> +               .desc = "HiSilicon erratum 161010101",
>>                 .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
>>                 .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>>         },
>>  #endif
>>  };
>> +
>> +typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
>> +                              const void *);
>> +
>> +static
>> +bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa,
>> +                                const void *arg)
>> +{
>> +       const struct device_node *np = arg;
>> +
>> +       return of_property_read_bool(np, wa->id);
>> +}
>> +
>> +static const struct arch_timer_erratum_workaround *
>> +arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
>> +                         ate_match_fn_t match_fn,
>> +                         void *arg)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
>> +               if (ool_workarounds[i].match_type != type)
>> +                       continue;
>> +
>> +               if (match_fn(&ool_workarounds[i], arg))
>> +                       return &ool_workarounds[i];
>> +       }
>> +
>> +       return NULL;
>> +}
>> +
>> +static
>> +void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
>> +{
>> +       timer_unstable_counter_workaround = wa;
>> +       static_branch_enable(&arch_timer_read_ool_enabled);
>> +}
>> +
>> +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
>> +                                           void *arg)
>> +{
>> +       const struct arch_timer_erratum_workaround *wa;
>> +       ate_match_fn_t match_fn = NULL;
>> +
>> +       if (static_branch_unlikely(&arch_timer_read_ool_enabled))
>> +               return;
>> +
>> +       switch (type) {
>> +       case ate_match_dt:
>> +               match_fn = arch_timer_check_dt_erratum;
>> +               break;
> 
> hey Marc,
>    Would it make sense to have a default case here that warns &
> returns? That wouldn't get hit by this series as-is, but might avoid a
> NULL callback in the future.

Sure, I can add that in the next version of this series. I would have
hoped that GCC would warn you if you don't handle all the values of an
enum, but it doesn't hurt to be cautious.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-24 13:51           ` Marc Zyngier
@ 2017-03-27  7:56             ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-27  7:56 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:

[ ... ]

> > Hi Marc,
> > 
> > I have been through the driver after applying the patchset. Again thanks for
> > taking care of this. It is not a simple issue to solve, so here is my minor
> > contribution.
> > 
> > The resulting code sounds like over-engineered because the errata check and its
> > workaround are done at the same place/moment, that forces to deal with an array
> > with element from different origin.
> > 
> > I understand you wanted to create a single array to handle the errata
> > information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
> > 
> > I would suggest to create 3 arrays: ACPI, DT and CAPS.
> > 
> > Those arrays contains the errata id *and* an unique private id.
> > 
> > At boot time, you go through the corresponding array and fill a list of
> > detected errata with the private id.
> > 
> > On the other side, an array with the private id and its workaround makes the
> > assocation. The private id is the contract between the errata and the workaround.
> > 
> > So the errata handling will occur in two steps:
> >  1. Boot => errata detection
> >  2. CPU up => workaround put in place
> > 
> > With this approach, you can write everything on a per cpu basis, getting rid of
> > 'global' / 'local'.
> > 
> > What is this different from your approach ?
> > 
> >  - no match_id
> >  - clear separation of errata and workaround
> >  - Simpler code
> >  - clear the scene for a more generic errata framework
> > 
> > That said, now it would make sense to create a generic errata framework to be
> > filled by the different arch at boot time and retrieve from the different
> > subsystem in an agnostic way. Well, may be that is a long term suggestion.
> > 
> > What do you think ?
> 
> I don't think this buys us anything at all. Separating detection and
> enablement is not always feasible. In your example above, you assume
> that all errata are detectable at boot time. Consider that with CPU
> hotplug, we can bring up a new core at any time, possibly with an
> erratum that you haven't detected yet.

I guess it has to pass through an init function before being powered on.
 
> And even then, what do we get: we trade a simple match ID for a list we
> build at runtime, another private ID, and additional code to perform
> that match. The gain is not obvious to me...
>
> What would such a generic errata framework look like? A table containing
> match functions returning a boolean, used to decide whether you need to
> call yet another function with a bunch of arbitrary parameters.
> 
> In my experience, such a framework will be either an empty shell
> (because you need to keep it as generic as possible), or will be riddled
> with data structures ending up being the union of all the possible cases
> you've encountered in the kernel. Not a pretty sight.

I disagree but I can understand you don't see the point to write a generic
framework while the patchset does the job.

Let's refocus on the patchset itself.

Can you do the change to have a percpu basis errata in order to remove
local/global ?

Something as below:

 
 static
-bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
-					 const void *arg)
+bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
+				  const void *arg)
 {
-	return cpus_have_cap((uintptr_t)wa->id);
+	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
 }
 
 static
-bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workaround *wa,
-					const void *arg)
-{
-	return this_cpu_has_cap((uintptr_t)wa->id);
-}
-
-
-static
 bool arch_timer_check_acpi_oem_erratum(const struct arch_timer_erratum_workaround *wa,
 				       const void *arg)
 {
@@ -458,17 +450,9 @@ arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 }
 
 static
-void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa,
-				  bool local)
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
 {
-	int i;
-
-	if (local) {
-		__this_cpu_write(timer_unstable_counter_workaround, wa);
-	} else {
-		for_each_possible_cpu(i)
-			per_cpu(timer_unstable_counter_workaround, i) = wa;
-	}
+	__this_cpu_write(timer_unstable_counter_workaround, wa);
 
 	static_branch_enable(&arch_timer_read_ool_enabled);
 
@@ -489,18 +473,16 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 {
 	const struct arch_timer_erratum_workaround *wa;
 	ate_match_fn_t match_fn = NULL;
-	bool local = false;
 
 	switch (type) {
 	case ate_match_dt:
 		match_fn = arch_timer_check_dt_erratum;
 		break;
 	case ate_match_global_cap_id:
-		match_fn = arch_timer_check_global_cap_erratum;
+		match_fn = arch_timer_check_cap_erratum;
 		break;
 	case ate_match_local_cap_id:
-		match_fn = arch_timer_check_local_cap_erratum;
-		local = true;
+		match_fn = arch_timer_check_cap_erratum;
 		break;
 	case ate_match_acpi_oem_info:
 		match_fn = arch_timer_check_acpi_oem_erratum;
@@ -522,9 +504,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 			return;
 	}
 
-	arch_timer_enable_workaround(wa, local);
-	pr_info("Enabling %s workaround for %s\n",
-		local ? "local" : "global", wa->desc);
+	arch_timer_enable_workaround(wa);
+	pr_info("Enabling %s workaround for cpu %d\n",
+		wa->desc, smp_processor_id());
 }
 
 #define erratum_handler(fn, r, ...)					\


-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-27  7:56             ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-27  7:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:

[?... ]

> > Hi Marc,
> > 
> > I have been through the driver after applying the patchset. Again thanks for
> > taking care of this. It is not a simple issue to solve, so here is my minor
> > contribution.
> > 
> > The resulting code sounds like over-engineered because the errata check and its
> > workaround are done at the same place/moment, that forces to deal with an array
> > with element from different origin.
> > 
> > I understand you wanted to create a single array to handle the errata
> > information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
> > 
> > I would suggest to create 3 arrays: ACPI, DT and CAPS.
> > 
> > Those arrays contains the errata id *and* an unique private id.
> > 
> > At boot time, you go through the corresponding array and fill a list of
> > detected errata with the private id.
> > 
> > On the other side, an array with the private id and its workaround makes the
> > assocation. The private id is the contract between the errata and the workaround.
> > 
> > So the errata handling will occur in two steps:
> >  1. Boot => errata detection
> >  2. CPU up => workaround put in place
> > 
> > With this approach, you can write everything on a per cpu basis, getting rid of
> > 'global' / 'local'.
> > 
> > What is this different from your approach ?
> > 
> >  - no match_id
> >  - clear separation of errata and workaround
> >  - Simpler code
> >  - clear the scene for a more generic errata framework
> > 
> > That said, now it would make sense to create a generic errata framework to be
> > filled by the different arch at boot time and retrieve from the different
> > subsystem in an agnostic way. Well, may be that is a long term suggestion.
> > 
> > What do you think ?
> 
> I don't think this buys us anything at all. Separating detection and
> enablement is not always feasible. In your example above, you assume
> that all errata are detectable at boot time. Consider that with CPU
> hotplug, we can bring up a new core at any time, possibly with an
> erratum that you haven't detected yet.

I guess it has to pass through an init function before being powered on.
 
> And even then, what do we get: we trade a simple match ID for a list we
> build at runtime, another private ID, and additional code to perform
> that match. The gain is not obvious to me...
>
> What would such a generic errata framework look like? A table containing
> match functions returning a boolean, used to decide whether you need to
> call yet another function with a bunch of arbitrary parameters.
> 
> In my experience, such a framework will be either an empty shell
> (because you need to keep it as generic as possible), or will be riddled
> with data structures ending up being the union of all the possible cases
> you've encountered in the kernel. Not a pretty sight.

I disagree but I can understand you don't see the point to write a generic
framework while the patchset does the job.

Let's refocus on the patchset itself.

Can you do the change to have a percpu basis errata in order to remove
local/global ?

Something as below:

 
 static
-bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
-					 const void *arg)
+bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
+				  const void *arg)
 {
-	return cpus_have_cap((uintptr_t)wa->id);
+	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
 }
 
 static
-bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workaround *wa,
-					const void *arg)
-{
-	return this_cpu_has_cap((uintptr_t)wa->id);
-}
-
-
-static
 bool arch_timer_check_acpi_oem_erratum(const struct arch_timer_erratum_workaround *wa,
 				       const void *arg)
 {
@@ -458,17 +450,9 @@ arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
 }
 
 static
-void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa,
-				  bool local)
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
 {
-	int i;
-
-	if (local) {
-		__this_cpu_write(timer_unstable_counter_workaround, wa);
-	} else {
-		for_each_possible_cpu(i)
-			per_cpu(timer_unstable_counter_workaround, i) = wa;
-	}
+	__this_cpu_write(timer_unstable_counter_workaround, wa);
 
 	static_branch_enable(&arch_timer_read_ool_enabled);
 
@@ -489,18 +473,16 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 {
 	const struct arch_timer_erratum_workaround *wa;
 	ate_match_fn_t match_fn = NULL;
-	bool local = false;
 
 	switch (type) {
 	case ate_match_dt:
 		match_fn = arch_timer_check_dt_erratum;
 		break;
 	case ate_match_global_cap_id:
-		match_fn = arch_timer_check_global_cap_erratum;
+		match_fn = arch_timer_check_cap_erratum;
 		break;
 	case ate_match_local_cap_id:
-		match_fn = arch_timer_check_local_cap_erratum;
-		local = true;
+		match_fn = arch_timer_check_cap_erratum;
 		break;
 	case ate_match_acpi_oem_info:
 		match_fn = arch_timer_check_acpi_oem_erratum;
@@ -522,9 +504,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
 			return;
 	}
 
-	arch_timer_enable_workaround(wa, local);
-	pr_info("Enabling %s workaround for %s\n",
-		local ? "local" : "global", wa->desc);
+	arch_timer_enable_workaround(wa);
+	pr_info("Enabling %s workaround for cpu %d\n",
+		wa->desc, smp_processor_id());
 }
 
 #define erratum_handler(fn, r, ...)					\


-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-27  7:56             ` Daniel Lezcano
@ 2017-03-28 13:07               ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 13:07 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On 27/03/17 08:56, Daniel Lezcano wrote:
> On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:
> 
> [ ... ]
> 
>>> Hi Marc,
>>>
>>> I have been through the driver after applying the patchset. Again thanks for
>>> taking care of this. It is not a simple issue to solve, so here is my minor
>>> contribution.
>>>
>>> The resulting code sounds like over-engineered because the errata check and its
>>> workaround are done at the same place/moment, that forces to deal with an array
>>> with element from different origin.
>>>
>>> I understand you wanted to create a single array to handle the errata
>>> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
>>>
>>> I would suggest to create 3 arrays: ACPI, DT and CAPS.
>>>
>>> Those arrays contains the errata id *and* an unique private id.
>>>
>>> At boot time, you go through the corresponding array and fill a list of
>>> detected errata with the private id.
>>>
>>> On the other side, an array with the private id and its workaround makes the
>>> assocation. The private id is the contract between the errata and the workaround.
>>>
>>> So the errata handling will occur in two steps:
>>>  1. Boot => errata detection
>>>  2. CPU up => workaround put in place
>>>
>>> With this approach, you can write everything on a per cpu basis, getting rid of
>>> 'global' / 'local'.
>>>
>>> What is this different from your approach ?
>>>
>>>  - no match_id
>>>  - clear separation of errata and workaround
>>>  - Simpler code
>>>  - clear the scene for a more generic errata framework
>>>
>>> That said, now it would make sense to create a generic errata framework to be
>>> filled by the different arch at boot time and retrieve from the different
>>> subsystem in an agnostic way. Well, may be that is a long term suggestion.
>>>
>>> What do you think ?
>>
>> I don't think this buys us anything at all. Separating detection and
>> enablement is not always feasible. In your example above, you assume
>> that all errata are detectable at boot time. Consider that with CPU
>> hotplug, we can bring up a new core at any time, possibly with an
>> erratum that you haven't detected yet.
> 
> I guess it has to pass through an init function before being powered on.

Sure, I never said that the CPU would appear ex-nihilo. But that
somewhat defeats your boot detection vs workaround application construct.

>> And even then, what do we get: we trade a simple match ID for a list we
>> build at runtime, another private ID, and additional code to perform
>> that match. The gain is not obvious to me...
>>
>> What would such a generic errata framework look like? A table containing
>> match functions returning a boolean, used to decide whether you need to
>> call yet another function with a bunch of arbitrary parameters.
>>
>> In my experience, such a framework will be either an empty shell
>> (because you need to keep it as generic as possible), or will be riddled
>> with data structures ending up being the union of all the possible cases
>> you've encountered in the kernel. Not a pretty sight.
> 
> I disagree but I can understand you don't see the point to write a generic
> framework while the patchset does the job.

It is not about this series. Far from it. I'm convinced that a generic
errata framework cannot be written without being either completely
devoid of any useful semantic, or be the union of all possible
semantics. There is simply too much diversity in the problem space. But
feel free to prove me wrong! ;-)

> Let's refocus on the patchset itself.
> 
> Can you do the change to have a percpu basis errata in order to remove
> local/global ?
> 
> Something as below:
> 
>  
>  static
> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> -					 const void *arg)
> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> +				  const void *arg)
>  {
> -	return cpus_have_cap((uintptr_t)wa->id);
> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);

Not quite. Here, you're making all capability-based errata to be be
global (if a single CPU in the system has a capability, then by
transitivity cpus_have_cap returns true). If that's a big-little system,
you end-up applying the workaround to all CPUs, including those unaffected.

I'd rather drop cpus_have_cap altogether and rely on individual CPU
matching (since we don't have a need for a global capability erratum
handling yet).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 13:07               ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/03/17 08:56, Daniel Lezcano wrote:
> On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:
> 
> [ ... ]
> 
>>> Hi Marc,
>>>
>>> I have been through the driver after applying the patchset. Again thanks for
>>> taking care of this. It is not a simple issue to solve, so here is my minor
>>> contribution.
>>>
>>> The resulting code sounds like over-engineered because the errata check and its
>>> workaround are done at the same place/moment, that forces to deal with an array
>>> with element from different origin.
>>>
>>> I understand you wanted to create a single array to handle the errata
>>> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
>>>
>>> I would suggest to create 3 arrays: ACPI, DT and CAPS.
>>>
>>> Those arrays contains the errata id *and* an unique private id.
>>>
>>> At boot time, you go through the corresponding array and fill a list of
>>> detected errata with the private id.
>>>
>>> On the other side, an array with the private id and its workaround makes the
>>> assocation. The private id is the contract between the errata and the workaround.
>>>
>>> So the errata handling will occur in two steps:
>>>  1. Boot => errata detection
>>>  2. CPU up => workaround put in place
>>>
>>> With this approach, you can write everything on a per cpu basis, getting rid of
>>> 'global' / 'local'.
>>>
>>> What is this different from your approach ?
>>>
>>>  - no match_id
>>>  - clear separation of errata and workaround
>>>  - Simpler code
>>>  - clear the scene for a more generic errata framework
>>>
>>> That said, now it would make sense to create a generic errata framework to be
>>> filled by the different arch at boot time and retrieve from the different
>>> subsystem in an agnostic way. Well, may be that is a long term suggestion.
>>>
>>> What do you think ?
>>
>> I don't think this buys us anything at all. Separating detection and
>> enablement is not always feasible. In your example above, you assume
>> that all errata are detectable at boot time. Consider that with CPU
>> hotplug, we can bring up a new core at any time, possibly with an
>> erratum that you haven't detected yet.
> 
> I guess it has to pass through an init function before being powered on.

Sure, I never said that the CPU would appear ex-nihilo. But that
somewhat defeats your boot detection vs workaround application construct.

>> And even then, what do we get: we trade a simple match ID for a list we
>> build at runtime, another private ID, and additional code to perform
>> that match. The gain is not obvious to me...
>>
>> What would such a generic errata framework look like? A table containing
>> match functions returning a boolean, used to decide whether you need to
>> call yet another function with a bunch of arbitrary parameters.
>>
>> In my experience, such a framework will be either an empty shell
>> (because you need to keep it as generic as possible), or will be riddled
>> with data structures ending up being the union of all the possible cases
>> you've encountered in the kernel. Not a pretty sight.
> 
> I disagree but I can understand you don't see the point to write a generic
> framework while the patchset does the job.

It is not about this series. Far from it. I'm convinced that a generic
errata framework cannot be written without being either completely
devoid of any useful semantic, or be the union of all possible
semantics. There is simply too much diversity in the problem space. But
feel free to prove me wrong! ;-)

> Let's refocus on the patchset itself.
> 
> Can you do the change to have a percpu basis errata in order to remove
> local/global ?
> 
> Something as below:
> 
>  
>  static
> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> -					 const void *arg)
> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> +				  const void *arg)
>  {
> -	return cpus_have_cap((uintptr_t)wa->id);
> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);

Not quite. Here, you're making all capability-based errata to be be
global (if a single CPU in the system has a capability, then by
transitivity cpus_have_cap returns true). If that's a big-little system,
you end-up applying the workaround to all CPUs, including those unaffected.

I'd rather drop cpus_have_cap altogether and rely on individual CPU
matching (since we don't have a need for a global capability erratum
handling yet).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 13:07               ` Marc Zyngier
@ 2017-03-28 13:34                 ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-28 13:34 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Tue, Mar 28, 2017 at 02:07:30PM +0100, Marc Zyngier wrote:
> On 27/03/17 08:56, Daniel Lezcano wrote:
> > On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:
> > 
> > [ ... ]
> > 
> >>> Hi Marc,
> >>>
> >>> I have been through the driver after applying the patchset. Again thanks for
> >>> taking care of this. It is not a simple issue to solve, so here is my minor
> >>> contribution.
> >>>
> >>> The resulting code sounds like over-engineered because the errata check and its
> >>> workaround are done at the same place/moment, that forces to deal with an array
> >>> with element from different origin.
> >>>
> >>> I understand you wanted to create a single array to handle the errata
> >>> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
> >>>
> >>> I would suggest to create 3 arrays: ACPI, DT and CAPS.
> >>>
> >>> Those arrays contains the errata id *and* an unique private id.
> >>>
> >>> At boot time, you go through the corresponding array and fill a list of
> >>> detected errata with the private id.
> >>>
> >>> On the other side, an array with the private id and its workaround makes the
> >>> assocation. The private id is the contract between the errata and the workaround.
> >>>
> >>> So the errata handling will occur in two steps:
> >>>  1. Boot => errata detection
> >>>  2. CPU up => workaround put in place
> >>>
> >>> With this approach, you can write everything on a per cpu basis, getting rid of
> >>> 'global' / 'local'.
> >>>
> >>> What is this different from your approach ?
> >>>
> >>>  - no match_id
> >>>  - clear separation of errata and workaround
> >>>  - Simpler code
> >>>  - clear the scene for a more generic errata framework
> >>>
> >>> That said, now it would make sense to create a generic errata framework to be
> >>> filled by the different arch at boot time and retrieve from the different
> >>> subsystem in an agnostic way. Well, may be that is a long term suggestion.
> >>>
> >>> What do you think ?
> >>
> >> I don't think this buys us anything at all. Separating detection and
> >> enablement is not always feasible. In your example above, you assume
> >> that all errata are detectable at boot time. Consider that with CPU
> >> hotplug, we can bring up a new core at any time, possibly with an
> >> erratum that you haven't detected yet.
> > 
> > I guess it has to pass through an init function before being powered on.
> 
> Sure, I never said that the CPU would appear ex-nihilo. But that
> somewhat defeats your boot detection vs workaround application construct.
> 
> >> And even then, what do we get: we trade a simple match ID for a list we
> >> build at runtime, another private ID, and additional code to perform
> >> that match. The gain is not obvious to me...
> >>
> >> What would such a generic errata framework look like? A table containing
> >> match functions returning a boolean, used to decide whether you need to
> >> call yet another function with a bunch of arbitrary parameters.
> >>
> >> In my experience, such a framework will be either an empty shell
> >> (because you need to keep it as generic as possible), or will be riddled
> >> with data structures ending up being the union of all the possible cases
> >> you've encountered in the kernel. Not a pretty sight.
> > 
> > I disagree but I can understand you don't see the point to write a generic
> > framework while the patchset does the job.
> 
> It is not about this series. Far from it. I'm convinced that a generic
> errata framework cannot be written without being either completely
> devoid of any useful semantic, or be the union of all possible
> semantics. There is simply too much diversity in the problem space. But
> feel free to prove me wrong! ;-)

I still think we can write something generic. However, as I have just recently
went through the errata handling, I'm certainly missing something. So perhaps,
if I have spare time, I can have a closer look and write some skeleton.

> > Let's refocus on the patchset itself.
> > 
> > Can you do the change to have a percpu basis errata in order to remove
> > local/global ?
> > 
> > Something as below:
> > 
> >  
> >  static
> > -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> > -					 const void *arg)
> > +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> > +				  const void *arg)
> >  {
> > -	return cpus_have_cap((uintptr_t)wa->id);
> > +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> 
> Not quite. Here, you're making all capability-based errata to be be
> global (if a single CPU in the system has a capability, then by
> transitivity cpus_have_cap returns true). If that's a big-little system,
> you end-up applying the workaround to all CPUs, including those unaffected.
> 
> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> matching (since we don't have a need for a global capability erratum
> handling yet).

Ok, thanks.

  -- Daniel

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 13:34                 ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-28 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 28, 2017 at 02:07:30PM +0100, Marc Zyngier wrote:
> On 27/03/17 08:56, Daniel Lezcano wrote:
> > On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:
> > 
> > [ ... ]
> > 
> >>> Hi Marc,
> >>>
> >>> I have been through the driver after applying the patchset. Again thanks for
> >>> taking care of this. It is not a simple issue to solve, so here is my minor
> >>> contribution.
> >>>
> >>> The resulting code sounds like over-engineered because the errata check and its
> >>> workaround are done at the same place/moment, that forces to deal with an array
> >>> with element from different origin.
> >>>
> >>> I understand you wanted to create a single array to handle the errata
> >>> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
> >>>
> >>> I would suggest to create 3 arrays: ACPI, DT and CAPS.
> >>>
> >>> Those arrays contains the errata id *and* an unique private id.
> >>>
> >>> At boot time, you go through the corresponding array and fill a list of
> >>> detected errata with the private id.
> >>>
> >>> On the other side, an array with the private id and its workaround makes the
> >>> assocation. The private id is the contract between the errata and the workaround.
> >>>
> >>> So the errata handling will occur in two steps:
> >>>  1. Boot => errata detection
> >>>  2. CPU up => workaround put in place
> >>>
> >>> With this approach, you can write everything on a per cpu basis, getting rid of
> >>> 'global' / 'local'.
> >>>
> >>> What is this different from your approach ?
> >>>
> >>>  - no match_id
> >>>  - clear separation of errata and workaround
> >>>  - Simpler code
> >>>  - clear the scene for a more generic errata framework
> >>>
> >>> That said, now it would make sense to create a generic errata framework to be
> >>> filled by the different arch at boot time and retrieve from the different
> >>> subsystem in an agnostic way. Well, may be that is a long term suggestion.
> >>>
> >>> What do you think ?
> >>
> >> I don't think this buys us anything at all. Separating detection and
> >> enablement is not always feasible. In your example above, you assume
> >> that all errata are detectable at boot time. Consider that with CPU
> >> hotplug, we can bring up a new core at any time, possibly with an
> >> erratum that you haven't detected yet.
> > 
> > I guess it has to pass through an init function before being powered on.
> 
> Sure, I never said that the CPU would appear ex-nihilo. But that
> somewhat defeats your boot detection vs workaround application construct.
> 
> >> And even then, what do we get: we trade a simple match ID for a list we
> >> build at runtime, another private ID, and additional code to perform
> >> that match. The gain is not obvious to me...
> >>
> >> What would such a generic errata framework look like? A table containing
> >> match functions returning a boolean, used to decide whether you need to
> >> call yet another function with a bunch of arbitrary parameters.
> >>
> >> In my experience, such a framework will be either an empty shell
> >> (because you need to keep it as generic as possible), or will be riddled
> >> with data structures ending up being the union of all the possible cases
> >> you've encountered in the kernel. Not a pretty sight.
> > 
> > I disagree but I can understand you don't see the point to write a generic
> > framework while the patchset does the job.
> 
> It is not about this series. Far from it. I'm convinced that a generic
> errata framework cannot be written without being either completely
> devoid of any useful semantic, or be the union of all possible
> semantics. There is simply too much diversity in the problem space. But
> feel free to prove me wrong! ;-)

I still think we can write something generic. However, as I have just recently
went through the errata handling, I'm certainly missing something. So perhaps,
if I have spare time, I can have a closer look and write some skeleton.

> > Let's refocus on the patchset itself.
> > 
> > Can you do the change to have a percpu basis errata in order to remove
> > local/global ?
> > 
> > Something as below:
> > 
> >  
> >  static
> > -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> > -					 const void *arg)
> > +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> > +				  const void *arg)
> >  {
> > -	return cpus_have_cap((uintptr_t)wa->id);
> > +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> 
> Not quite. Here, you're making all capability-based errata to be be
> global (if a single CPU in the system has a capability, then by
> transitivity cpus_have_cap returns true). If that's a big-little system,
> you end-up applying the workaround to all CPUs, including those unaffected.
> 
> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> matching (since we don't have a need for a global capability erratum
> handling yet).

Ok, thanks.

  -- Daniel

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 13:34                 ` Daniel Lezcano
@ 2017-03-28 14:07                   ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 14:07 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On 28/03/17 14:34, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 02:07:30PM +0100, Marc Zyngier wrote:
>> On 27/03/17 08:56, Daniel Lezcano wrote:
>>> On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:
>>>
>>> [ ... ]
>>>
>>>>> Hi Marc,
>>>>>
>>>>> I have been through the driver after applying the patchset. Again thanks for
>>>>> taking care of this. It is not a simple issue to solve, so here is my minor
>>>>> contribution.
>>>>>
>>>>> The resulting code sounds like over-engineered because the errata check and its
>>>>> workaround are done at the same place/moment, that forces to deal with an array
>>>>> with element from different origin.
>>>>>
>>>>> I understand you wanted to create a single array to handle the errata
>>>>> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
>>>>>
>>>>> I would suggest to create 3 arrays: ACPI, DT and CAPS.
>>>>>
>>>>> Those arrays contains the errata id *and* an unique private id.
>>>>>
>>>>> At boot time, you go through the corresponding array and fill a list of
>>>>> detected errata with the private id.
>>>>>
>>>>> On the other side, an array with the private id and its workaround makes the
>>>>> assocation. The private id is the contract between the errata and the workaround.
>>>>>
>>>>> So the errata handling will occur in two steps:
>>>>>  1. Boot => errata detection
>>>>>  2. CPU up => workaround put in place
>>>>>
>>>>> With this approach, you can write everything on a per cpu basis, getting rid of
>>>>> 'global' / 'local'.
>>>>>
>>>>> What is this different from your approach ?
>>>>>
>>>>>  - no match_id
>>>>>  - clear separation of errata and workaround
>>>>>  - Simpler code
>>>>>  - clear the scene for a more generic errata framework
>>>>>
>>>>> That said, now it would make sense to create a generic errata framework to be
>>>>> filled by the different arch at boot time and retrieve from the different
>>>>> subsystem in an agnostic way. Well, may be that is a long term suggestion.
>>>>>
>>>>> What do you think ?
>>>>
>>>> I don't think this buys us anything at all. Separating detection and
>>>> enablement is not always feasible. In your example above, you assume
>>>> that all errata are detectable at boot time. Consider that with CPU
>>>> hotplug, we can bring up a new core at any time, possibly with an
>>>> erratum that you haven't detected yet.
>>>
>>> I guess it has to pass through an init function before being powered on.
>>
>> Sure, I never said that the CPU would appear ex-nihilo. But that
>> somewhat defeats your boot detection vs workaround application construct.
>>
>>>> And even then, what do we get: we trade a simple match ID for a list we
>>>> build at runtime, another private ID, and additional code to perform
>>>> that match. The gain is not obvious to me...
>>>>
>>>> What would such a generic errata framework look like? A table containing
>>>> match functions returning a boolean, used to decide whether you need to
>>>> call yet another function with a bunch of arbitrary parameters.
>>>>
>>>> In my experience, such a framework will be either an empty shell
>>>> (because you need to keep it as generic as possible), or will be riddled
>>>> with data structures ending up being the union of all the possible cases
>>>> you've encountered in the kernel. Not a pretty sight.
>>>
>>> I disagree but I can understand you don't see the point to write a generic
>>> framework while the patchset does the job.
>>
>> It is not about this series. Far from it. I'm convinced that a generic
>> errata framework cannot be written without being either completely
>> devoid of any useful semantic, or be the union of all possible
>> semantics. There is simply too much diversity in the problem space. But
>> feel free to prove me wrong! ;-)
> 
> I still think we can write something generic. However, as I have just recently
> went through the errata handling, I'm certainly missing something. So perhaps,
> if I have spare time, I can have a closer look and write some skeleton.
> 
>>> Let's refocus on the patchset itself.
>>>
>>> Can you do the change to have a percpu basis errata in order to remove
>>> local/global ?
>>>
>>> Something as below:
>>>
>>>  
>>>  static
>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>> -					 const void *arg)
>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>> +				  const void *arg)
>>>  {
>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>
>> Not quite. Here, you're making all capability-based errata to be be
>> global (if a single CPU in the system has a capability, then by
>> transitivity cpus_have_cap returns true). If that's a big-little system,
>> you end-up applying the workaround to all CPUs, including those unaffected.
>>
>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>> matching (since we don't have a need for a global capability erratum
>> handling yet).
> 
> Ok, thanks.

Quick update. I've just implemented this, and found out that getting rid
of local/global has an unfortunate effect:

Since we only probe the global errata (using ACPI for example) on the
boot CPU path, we lose propagation of the erratum across the secondary
CPUs. One way of solving this is to convert the secondary boot path to
be aware of DT vs ACPI vs detection method of the month. Which isn't
easy, since by the time we boot secondary CPUs, we don't have the
pointers to the various ACPI tables anymore. Also, assuming we were
careful and saved the pointers, the tables may have been unmapped. Fun.

Given that, I'm reintroducing the global/local flag for good. It's not
pretty, but it doesn't require reinventing new ways of dealing with CPUs
booting late.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 14:07                   ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 28/03/17 14:34, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 02:07:30PM +0100, Marc Zyngier wrote:
>> On 27/03/17 08:56, Daniel Lezcano wrote:
>>> On Fri, Mar 24, 2017 at 01:51:47PM +0000, Marc Zyngier wrote:
>>>
>>> [ ... ]
>>>
>>>>> Hi Marc,
>>>>>
>>>>> I have been through the driver after applying the patchset. Again thanks for
>>>>> taking care of this. It is not a simple issue to solve, so here is my minor
>>>>> contribution.
>>>>>
>>>>> The resulting code sounds like over-engineered because the errata check and its
>>>>> workaround are done at the same place/moment, that forces to deal with an array
>>>>> with element from different origin.
>>>>>
>>>>> I understand you wanted to create a single array to handle the errata
>>>>> information from the DT, ACPI and CAPS. But IMHO, it does not fit well.
>>>>>
>>>>> I would suggest to create 3 arrays: ACPI, DT and CAPS.
>>>>>
>>>>> Those arrays contains the errata id *and* an unique private id.
>>>>>
>>>>> At boot time, you go through the corresponding array and fill a list of
>>>>> detected errata with the private id.
>>>>>
>>>>> On the other side, an array with the private id and its workaround makes the
>>>>> assocation. The private id is the contract between the errata and the workaround.
>>>>>
>>>>> So the errata handling will occur in two steps:
>>>>>  1. Boot => errata detection
>>>>>  2. CPU up => workaround put in place
>>>>>
>>>>> With this approach, you can write everything on a per cpu basis, getting rid of
>>>>> 'global' / 'local'.
>>>>>
>>>>> What is this different from your approach ?
>>>>>
>>>>>  - no match_id
>>>>>  - clear separation of errata and workaround
>>>>>  - Simpler code
>>>>>  - clear the scene for a more generic errata framework
>>>>>
>>>>> That said, now it would make sense to create a generic errata framework to be
>>>>> filled by the different arch at boot time and retrieve from the different
>>>>> subsystem in an agnostic way. Well, may be that is a long term suggestion.
>>>>>
>>>>> What do you think ?
>>>>
>>>> I don't think this buys us anything at all. Separating detection and
>>>> enablement is not always feasible. In your example above, you assume
>>>> that all errata are detectable at boot time. Consider that with CPU
>>>> hotplug, we can bring up a new core at any time, possibly with an
>>>> erratum that you haven't detected yet.
>>>
>>> I guess it has to pass through an init function before being powered on.
>>
>> Sure, I never said that the CPU would appear ex-nihilo. But that
>> somewhat defeats your boot detection vs workaround application construct.
>>
>>>> And even then, what do we get: we trade a simple match ID for a list we
>>>> build at runtime, another private ID, and additional code to perform
>>>> that match. The gain is not obvious to me...
>>>>
>>>> What would such a generic errata framework look like? A table containing
>>>> match functions returning a boolean, used to decide whether you need to
>>>> call yet another function with a bunch of arbitrary parameters.
>>>>
>>>> In my experience, such a framework will be either an empty shell
>>>> (because you need to keep it as generic as possible), or will be riddled
>>>> with data structures ending up being the union of all the possible cases
>>>> you've encountered in the kernel. Not a pretty sight.
>>>
>>> I disagree but I can understand you don't see the point to write a generic
>>> framework while the patchset does the job.
>>
>> It is not about this series. Far from it. I'm convinced that a generic
>> errata framework cannot be written without being either completely
>> devoid of any useful semantic, or be the union of all possible
>> semantics. There is simply too much diversity in the problem space. But
>> feel free to prove me wrong! ;-)
> 
> I still think we can write something generic. However, as I have just recently
> went through the errata handling, I'm certainly missing something. So perhaps,
> if I have spare time, I can have a closer look and write some skeleton.
> 
>>> Let's refocus on the patchset itself.
>>>
>>> Can you do the change to have a percpu basis errata in order to remove
>>> local/global ?
>>>
>>> Something as below:
>>>
>>>  
>>>  static
>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>> -					 const void *arg)
>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>> +				  const void *arg)
>>>  {
>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>
>> Not quite. Here, you're making all capability-based errata to be be
>> global (if a single CPU in the system has a capability, then by
>> transitivity cpus_have_cap returns true). If that's a big-little system,
>> you end-up applying the workaround to all CPUs, including those unaffected.
>>
>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>> matching (since we don't have a need for a global capability erratum
>> handling yet).
> 
> Ok, thanks.

Quick update. I've just implemented this, and found out that getting rid
of local/global has an unfortunate effect:

Since we only probe the global errata (using ACPI for example) on the
boot CPU path, we lose propagation of the erratum across the secondary
CPUs. One way of solving this is to convert the secondary boot path to
be aware of DT vs ACPI vs detection method of the month. Which isn't
easy, since by the time we boot secondary CPUs, we don't have the
pointers to the various ACPI tables anymore. Also, assuming we were
careful and saved the pointers, the tables may have been unmapped. Fun.

Given that, I'm reintroducing the global/local flag for good. It's not
pretty, but it doesn't require reinventing new ways of dealing with CPUs
booting late.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 14:07                   ` Marc Zyngier
@ 2017-03-28 14:36                     ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:36 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:

[ ... ]

> >>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>> -					 const void *arg)
> >>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>> +				  const void *arg)
> >>>  {
> >>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>
> >> Not quite. Here, you're making all capability-based errata to be be
> >> global (if a single CPU in the system has a capability, then by
> >> transitivity cpus_have_cap returns true). If that's a big-little system,
> >> you end-up applying the workaround to all CPUs, including those unaffected.
> >>
> >> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >> matching (since we don't have a need for a global capability erratum
> >> handling yet).
> > 
> > Ok, thanks.
> 
> Quick update. I've just implemented this, and found out that getting rid
> of local/global has an unfortunate effect:
> 
> Since we only probe the global errata (using ACPI for example) on the
> boot CPU path, we lose propagation of the erratum across the secondary
> CPUs. One way of solving this is to convert the secondary boot path to
> be aware of DT vs ACPI vs detection method of the month. Which isn't
> easy, since by the time we boot secondary CPUs, we don't have the
> pointers to the various ACPI tables anymore. Also, assuming we were
> careful and saved the pointers, the tables may have been unmapped. Fun.

My proposal was supposed to prevent that. The detecion is done in the
subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
errata. The drivers get the errata and enable the workaround. The id
association <-> errata self contains errata types (void *, char *, int). So
everything can be done in a CPU basis without local / global dance.

> Given that, I'm reintroducing the global/local flag for good. It's not
> pretty, but it doesn't require reinventing new ways of dealing with CPUs
> booting late.



-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 14:36                     ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:

[ ... ]

> >>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>> -					 const void *arg)
> >>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>> +				  const void *arg)
> >>>  {
> >>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>
> >> Not quite. Here, you're making all capability-based errata to be be
> >> global (if a single CPU in the system has a capability, then by
> >> transitivity cpus_have_cap returns true). If that's a big-little system,
> >> you end-up applying the workaround to all CPUs, including those unaffected.
> >>
> >> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >> matching (since we don't have a need for a global capability erratum
> >> handling yet).
> > 
> > Ok, thanks.
> 
> Quick update. I've just implemented this, and found out that getting rid
> of local/global has an unfortunate effect:
> 
> Since we only probe the global errata (using ACPI for example) on the
> boot CPU path, we lose propagation of the erratum across the secondary
> CPUs. One way of solving this is to convert the secondary boot path to
> be aware of DT vs ACPI vs detection method of the month. Which isn't
> easy, since by the time we boot secondary CPUs, we don't have the
> pointers to the various ACPI tables anymore. Also, assuming we were
> careful and saved the pointers, the tables may have been unmapped. Fun.

My proposal was supposed to prevent that. The detecion is done in the
subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
errata. The drivers get the errata and enable the workaround. The id
association <-> errata self contains errata types (void *, char *, int). So
everything can be done in a CPU basis without local / global dance.

> Given that, I'm reintroducing the global/local flag for good. It's not
> pretty, but it doesn't require reinventing new ways of dealing with CPUs
> booting late.



-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 14:36                     ` Daniel Lezcano
@ 2017-03-28 14:48                       ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 14:48 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On 28/03/17 15:36, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> 
> [ ... ]
> 
>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>> -					 const void *arg)
>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>> +				  const void *arg)
>>>>>  {
>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>>>
>>>> Not quite. Here, you're making all capability-based errata to be be
>>>> global (if a single CPU in the system has a capability, then by
>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
>>>> you end-up applying the workaround to all CPUs, including those unaffected.
>>>>
>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>>>> matching (since we don't have a need for a global capability erratum
>>>> handling yet).
>>>
>>> Ok, thanks.
>>
>> Quick update. I've just implemented this, and found out that getting rid
>> of local/global has an unfortunate effect:
>>
>> Since we only probe the global errata (using ACPI for example) on the
>> boot CPU path, we lose propagation of the erratum across the secondary
>> CPUs. One way of solving this is to convert the secondary boot path to
>> be aware of DT vs ACPI vs detection method of the month. Which isn't
>> easy, since by the time we boot secondary CPUs, we don't have the
>> pointers to the various ACPI tables anymore. Also, assuming we were
>> careful and saved the pointers, the tables may have been unmapped. Fun.
> 
> My proposal was supposed to prevent that. The detecion is done in the
> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> errata. The drivers get the errata and enable the workaround. The id
> association <-> errata self contains errata types (void *, char *, int). So
> everything can be done in a CPU basis without local / global dance.

I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
a fly (I'm staying away from the frozen shark metaphor here). You're
willing to add a whole list of things with private ids that need
matching to kill a flag? I don't think this buys us anything but extra
complexity and another maintenance headache.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 14:48                       ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 14:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 28/03/17 15:36, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> 
> [ ... ]
> 
>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>> -					 const void *arg)
>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>> +				  const void *arg)
>>>>>  {
>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>>>
>>>> Not quite. Here, you're making all capability-based errata to be be
>>>> global (if a single CPU in the system has a capability, then by
>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
>>>> you end-up applying the workaround to all CPUs, including those unaffected.
>>>>
>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>>>> matching (since we don't have a need for a global capability erratum
>>>> handling yet).
>>>
>>> Ok, thanks.
>>
>> Quick update. I've just implemented this, and found out that getting rid
>> of local/global has an unfortunate effect:
>>
>> Since we only probe the global errata (using ACPI for example) on the
>> boot CPU path, we lose propagation of the erratum across the secondary
>> CPUs. One way of solving this is to convert the secondary boot path to
>> be aware of DT vs ACPI vs detection method of the month. Which isn't
>> easy, since by the time we boot secondary CPUs, we don't have the
>> pointers to the various ACPI tables anymore. Also, assuming we were
>> careful and saved the pointers, the tables may have been unmapped. Fun.
> 
> My proposal was supposed to prevent that. The detecion is done in the
> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> errata. The drivers get the errata and enable the workaround. The id
> association <-> errata self contains errata types (void *, char *, int). So
> everything can be done in a CPU basis without local / global dance.

I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
a fly (I'm staying away from the frozen shark metaphor here). You're
willing to add a whole list of things with private ids that need
matching to kill a flag? I don't think this buys us anything but extra
complexity and another maintenance headache.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 14:48                       ` Marc Zyngier
@ 2017-03-28 14:55                         ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:55 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
> On 28/03/17 15:36, Daniel Lezcano wrote:
> > On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> > 
> > [ ... ]
> > 
> >>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>> -					 const void *arg)
> >>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>> +				  const void *arg)
> >>>>>  {
> >>>>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>>>
> >>>> Not quite. Here, you're making all capability-based errata to be be
> >>>> global (if a single CPU in the system has a capability, then by
> >>>> transitivity cpus_have_cap returns true). If that's a big-little system,
> >>>> you end-up applying the workaround to all CPUs, including those unaffected.
> >>>>
> >>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >>>> matching (since we don't have a need for a global capability erratum
> >>>> handling yet).
> >>>
> >>> Ok, thanks.
> >>
> >> Quick update. I've just implemented this, and found out that getting rid
> >> of local/global has an unfortunate effect:
> >>
> >> Since we only probe the global errata (using ACPI for example) on the
> >> boot CPU path, we lose propagation of the erratum across the secondary
> >> CPUs. One way of solving this is to convert the secondary boot path to
> >> be aware of DT vs ACPI vs detection method of the month. Which isn't
> >> easy, since by the time we boot secondary CPUs, we don't have the
> >> pointers to the various ACPI tables anymore. Also, assuming we were
> >> careful and saved the pointers, the tables may have been unmapped. Fun.
> > 
> > My proposal was supposed to prevent that. The detecion is done in the
> > subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> > errata. The drivers get the errata and enable the workaround. The id
> > association <-> errata self contains errata types (void *, char *, int). So
> > everything can be done in a CPU basis without local / global dance.
> 
> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
> a fly (I'm staying away from the frozen shark metaphor here). You're
> willing to add a whole list of things with private ids that need
> matching to kill a flag? I don't think this buys us anything but extra
> complexity and another maintenance headache.

Well, it is like your approach except it is split in two steps.

Can you explain where is the extra complexity ? May be I am missing the point.

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 14:55                         ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-28 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
> On 28/03/17 15:36, Daniel Lezcano wrote:
> > On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> > 
> > [ ... ]
> > 
> >>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>> -					 const void *arg)
> >>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>> +				  const void *arg)
> >>>>>  {
> >>>>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>>>
> >>>> Not quite. Here, you're making all capability-based errata to be be
> >>>> global (if a single CPU in the system has a capability, then by
> >>>> transitivity cpus_have_cap returns true). If that's a big-little system,
> >>>> you end-up applying the workaround to all CPUs, including those unaffected.
> >>>>
> >>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >>>> matching (since we don't have a need for a global capability erratum
> >>>> handling yet).
> >>>
> >>> Ok, thanks.
> >>
> >> Quick update. I've just implemented this, and found out that getting rid
> >> of local/global has an unfortunate effect:
> >>
> >> Since we only probe the global errata (using ACPI for example) on the
> >> boot CPU path, we lose propagation of the erratum across the secondary
> >> CPUs. One way of solving this is to convert the secondary boot path to
> >> be aware of DT vs ACPI vs detection method of the month. Which isn't
> >> easy, since by the time we boot secondary CPUs, we don't have the
> >> pointers to the various ACPI tables anymore. Also, assuming we were
> >> careful and saved the pointers, the tables may have been unmapped. Fun.
> > 
> > My proposal was supposed to prevent that. The detecion is done in the
> > subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> > errata. The drivers get the errata and enable the workaround. The id
> > association <-> errata self contains errata types (void *, char *, int). So
> > everything can be done in a CPU basis without local / global dance.
> 
> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
> a fly (I'm staying away from the frozen shark metaphor here). You're
> willing to add a whole list of things with private ids that need
> matching to kill a flag? I don't think this buys us anything but extra
> complexity and another maintenance headache.

Well, it is like your approach except it is split in two steps.

Can you explain where is the extra complexity ? May be I am missing the point.

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 14:55                         ` Daniel Lezcano
@ 2017-03-28 15:38                           ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 15:38 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On 28/03/17 15:55, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
>> On 28/03/17 15:36, Daniel Lezcano wrote:
>>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
>>>
>>> [ ... ]
>>>
>>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>> -					 const void *arg)
>>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>> +				  const void *arg)
>>>>>>>  {
>>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>>>>>
>>>>>> Not quite. Here, you're making all capability-based errata to be be
>>>>>> global (if a single CPU in the system has a capability, then by
>>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
>>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
>>>>>>
>>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>>>>>> matching (since we don't have a need for a global capability erratum
>>>>>> handling yet).
>>>>>
>>>>> Ok, thanks.
>>>>
>>>> Quick update. I've just implemented this, and found out that getting rid
>>>> of local/global has an unfortunate effect:
>>>>
>>>> Since we only probe the global errata (using ACPI for example) on the
>>>> boot CPU path, we lose propagation of the erratum across the secondary
>>>> CPUs. One way of solving this is to convert the secondary boot path to
>>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
>>>> easy, since by the time we boot secondary CPUs, we don't have the
>>>> pointers to the various ACPI tables anymore. Also, assuming we were
>>>> careful and saved the pointers, the tables may have been unmapped. Fun.
>>>
>>> My proposal was supposed to prevent that. The detecion is done in the
>>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
>>> errata. The drivers get the errata and enable the workaround. The id
>>> association <-> errata self contains errata types (void *, char *, int). So
>>> everything can be done in a CPU basis without local / global dance.
>>
>> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
>> a fly (I'm staying away from the frozen shark metaphor here). You're
>> willing to add a whole list of things with private ids that need
>> matching to kill a flag? I don't think this buys us anything but extra
>> complexity and another maintenance headache.
> 
> Well, it is like your approach except it is split in two steps.
> 
> Can you explain where is the extra complexity ? May be I am missing the point.

This is how I understand your approach:

- Boot the first CPU
- Build a list of errata discovered at that time
- Apply erratum on the boot CPU if required, using a yet-to-be-invented
private id matching mechanism,
- Boot a secondary CPU
- Apply erratum if required, parsing the list
- Realise that you don't have the full list (this CPU comes with an
erratum that was not in the initial list)
- Add more to the list
- Apply erratum, using the same matching mechanism

This is mine:

- Boot the first CPU
- Apply global erratum to all CPUs
- Apply local erratum
- Boot a secondary CPU
- Apply local erratum

In my case, everything is static, and I don't need to rematch each CPU
against the list of globally applicable errata.

If my understanding is flawed, let me know.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-28 15:38                           ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-28 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 28/03/17 15:55, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
>> On 28/03/17 15:36, Daniel Lezcano wrote:
>>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
>>>
>>> [ ... ]
>>>
>>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>> -					 const void *arg)
>>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>> +				  const void *arg)
>>>>>>>  {
>>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>>>>>
>>>>>> Not quite. Here, you're making all capability-based errata to be be
>>>>>> global (if a single CPU in the system has a capability, then by
>>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
>>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
>>>>>>
>>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>>>>>> matching (since we don't have a need for a global capability erratum
>>>>>> handling yet).
>>>>>
>>>>> Ok, thanks.
>>>>
>>>> Quick update. I've just implemented this, and found out that getting rid
>>>> of local/global has an unfortunate effect:
>>>>
>>>> Since we only probe the global errata (using ACPI for example) on the
>>>> boot CPU path, we lose propagation of the erratum across the secondary
>>>> CPUs. One way of solving this is to convert the secondary boot path to
>>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
>>>> easy, since by the time we boot secondary CPUs, we don't have the
>>>> pointers to the various ACPI tables anymore. Also, assuming we were
>>>> careful and saved the pointers, the tables may have been unmapped. Fun.
>>>
>>> My proposal was supposed to prevent that. The detecion is done in the
>>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
>>> errata. The drivers get the errata and enable the workaround. The id
>>> association <-> errata self contains errata types (void *, char *, int). So
>>> everything can be done in a CPU basis without local / global dance.
>>
>> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
>> a fly (I'm staying away from the frozen shark metaphor here). You're
>> willing to add a whole list of things with private ids that need
>> matching to kill a flag? I don't think this buys us anything but extra
>> complexity and another maintenance headache.
> 
> Well, it is like your approach except it is split in two steps.
> 
> Can you explain where is the extra complexity ? May be I am missing the point.

This is how I understand your approach:

- Boot the first CPU
- Build a list of errata discovered at that time
- Apply erratum on the boot CPU if required, using a yet-to-be-invented
private id matching mechanism,
- Boot a secondary CPU
- Apply erratum if required, parsing the list
- Realise that you don't have the full list (this CPU comes with an
erratum that was not in the initial list)
- Add more to the list
- Apply erratum, using the same matching mechanism

This is mine:

- Boot the first CPU
- Apply global erratum to all CPUs
- Apply local erratum
- Boot a secondary CPU
- Apply local erratum

In my case, everything is static, and I don't need to rematch each CPU
against the list of globally applicable errata.

If my understanding is flawed, let me know.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-28 15:38                           ` Marc Zyngier
@ 2017-03-29 14:27                             ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-29 14:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Tue, Mar 28, 2017 at 04:38:41PM +0100, Marc Zyngier wrote:
> On 28/03/17 15:55, Daniel Lezcano wrote:
> > On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
> >> On 28/03/17 15:36, Daniel Lezcano wrote:
> >>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> >>>
> >>> [ ... ]
> >>>
> >>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>> -					 const void *arg)
> >>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>> +				  const void *arg)
> >>>>>>>  {
> >>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>>>>>
> >>>>>> Not quite. Here, you're making all capability-based errata to be be
> >>>>>> global (if a single CPU in the system has a capability, then by
> >>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
> >>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
> >>>>>>
> >>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >>>>>> matching (since we don't have a need for a global capability erratum
> >>>>>> handling yet).
> >>>>>
> >>>>> Ok, thanks.
> >>>>
> >>>> Quick update. I've just implemented this, and found out that getting rid
> >>>> of local/global has an unfortunate effect:
> >>>>
> >>>> Since we only probe the global errata (using ACPI for example) on the
> >>>> boot CPU path, we lose propagation of the erratum across the secondary
> >>>> CPUs. One way of solving this is to convert the secondary boot path to
> >>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
> >>>> easy, since by the time we boot secondary CPUs, we don't have the
> >>>> pointers to the various ACPI tables anymore. Also, assuming we were
> >>>> careful and saved the pointers, the tables may have been unmapped. Fun.
> >>>
> >>> My proposal was supposed to prevent that. The detecion is done in the
> >>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> >>> errata. The drivers get the errata and enable the workaround. The id
> >>> association <-> errata self contains errata types (void *, char *, int). So
> >>> everything can be done in a CPU basis without local / global dance.
> >>
> >> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
> >> a fly (I'm staying away from the frozen shark metaphor here). You're
> >> willing to add a whole list of things with private ids that need
> >> matching to kill a flag? I don't think this buys us anything but extra
> >> complexity and another maintenance headache.
> > 
> > Well, it is like your approach except it is split in two steps.
> > 
> > Can you explain where is the extra complexity ? May be I am missing the point.
> 
> This is how I understand your approach:
> 
> - Boot the first CPU
> - Build a list of errata discovered at that time
> - Apply erratum on the boot CPU if required, using a yet-to-be-invented
> private id matching mechanism,
> - Boot a secondary CPU
> - Apply erratum if required, parsing the list
> - Realise that you don't have the full list (this CPU comes with an
> erratum that was not in the initial list)
> - Add more to the list
> - Apply erratum, using the same matching mechanism
> 
> This is mine:
> 
> - Boot the first CPU
> - Apply global erratum to all CPUs
> - Apply local erratum
> - Boot a secondary CPU
> - Apply local erratum
> 
> In my case, everything is static, and I don't need to rematch each CPU
> against the list of globally applicable errata.
> 
> If my understanding is flawed, let me know.

Any of our understanding is flawed. I think that needs a maturation period.

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-29 14:27                             ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-29 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 28, 2017 at 04:38:41PM +0100, Marc Zyngier wrote:
> On 28/03/17 15:55, Daniel Lezcano wrote:
> > On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
> >> On 28/03/17 15:36, Daniel Lezcano wrote:
> >>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> >>>
> >>> [ ... ]
> >>>
> >>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>> -					 const void *arg)
> >>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>> +				  const void *arg)
> >>>>>>>  {
> >>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>>>>>
> >>>>>> Not quite. Here, you're making all capability-based errata to be be
> >>>>>> global (if a single CPU in the system has a capability, then by
> >>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
> >>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
> >>>>>>
> >>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >>>>>> matching (since we don't have a need for a global capability erratum
> >>>>>> handling yet).
> >>>>>
> >>>>> Ok, thanks.
> >>>>
> >>>> Quick update. I've just implemented this, and found out that getting rid
> >>>> of local/global has an unfortunate effect:
> >>>>
> >>>> Since we only probe the global errata (using ACPI for example) on the
> >>>> boot CPU path, we lose propagation of the erratum across the secondary
> >>>> CPUs. One way of solving this is to convert the secondary boot path to
> >>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
> >>>> easy, since by the time we boot secondary CPUs, we don't have the
> >>>> pointers to the various ACPI tables anymore. Also, assuming we were
> >>>> careful and saved the pointers, the tables may have been unmapped. Fun.
> >>>
> >>> My proposal was supposed to prevent that. The detecion is done in the
> >>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> >>> errata. The drivers get the errata and enable the workaround. The id
> >>> association <-> errata self contains errata types (void *, char *, int). So
> >>> everything can be done in a CPU basis without local / global dance.
> >>
> >> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
> >> a fly (I'm staying away from the frozen shark metaphor here). You're
> >> willing to add a whole list of things with private ids that need
> >> matching to kill a flag? I don't think this buys us anything but extra
> >> complexity and another maintenance headache.
> > 
> > Well, it is like your approach except it is split in two steps.
> > 
> > Can you explain where is the extra complexity ? May be I am missing the point.
> 
> This is how I understand your approach:
> 
> - Boot the first CPU
> - Build a list of errata discovered at that time
> - Apply erratum on the boot CPU if required, using a yet-to-be-invented
> private id matching mechanism,
> - Boot a secondary CPU
> - Apply erratum if required, parsing the list
> - Realise that you don't have the full list (this CPU comes with an
> erratum that was not in the initial list)
> - Add more to the list
> - Apply erratum, using the same matching mechanism
> 
> This is mine:
> 
> - Boot the first CPU
> - Apply global erratum to all CPUs
> - Apply local erratum
> - Boot a secondary CPU
> - Apply local erratum
> 
> In my case, everything is static, and I don't need to rematch each CPU
> against the list of globally applicable errata.
> 
> If my understanding is flawed, let me know.

Any of our understanding is flawed. I think that needs a maturation period.

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-29 14:27                             ` Daniel Lezcano
@ 2017-03-29 14:56                               ` Marc Zyngier
  -1 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-29 14:56 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On 29/03/17 15:27, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 04:38:41PM +0100, Marc Zyngier wrote:
>> On 28/03/17 15:55, Daniel Lezcano wrote:
>>> On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
>>>> On 28/03/17 15:36, Daniel Lezcano wrote:
>>>>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
>>>>>
>>>>> [ ... ]
>>>>>
>>>>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>>>> -					 const void *arg)
>>>>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>>>> +				  const void *arg)
>>>>>>>>>  {
>>>>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>>>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>>>>>>>
>>>>>>>> Not quite. Here, you're making all capability-based errata to be be
>>>>>>>> global (if a single CPU in the system has a capability, then by
>>>>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
>>>>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
>>>>>>>>
>>>>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>>>>>>>> matching (since we don't have a need for a global capability erratum
>>>>>>>> handling yet).
>>>>>>>
>>>>>>> Ok, thanks.
>>>>>>
>>>>>> Quick update. I've just implemented this, and found out that getting rid
>>>>>> of local/global has an unfortunate effect:
>>>>>>
>>>>>> Since we only probe the global errata (using ACPI for example) on the
>>>>>> boot CPU path, we lose propagation of the erratum across the secondary
>>>>>> CPUs. One way of solving this is to convert the secondary boot path to
>>>>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
>>>>>> easy, since by the time we boot secondary CPUs, we don't have the
>>>>>> pointers to the various ACPI tables anymore. Also, assuming we were
>>>>>> careful and saved the pointers, the tables may have been unmapped. Fun.
>>>>>
>>>>> My proposal was supposed to prevent that. The detecion is done in the
>>>>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
>>>>> errata. The drivers get the errata and enable the workaround. The id
>>>>> association <-> errata self contains errata types (void *, char *, int). So
>>>>> everything can be done in a CPU basis without local / global dance.
>>>>
>>>> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
>>>> a fly (I'm staying away from the frozen shark metaphor here). You're
>>>> willing to add a whole list of things with private ids that need
>>>> matching to kill a flag? I don't think this buys us anything but extra
>>>> complexity and another maintenance headache.
>>>
>>> Well, it is like your approach except it is split in two steps.
>>>
>>> Can you explain where is the extra complexity ? May be I am missing the point.
>>
>> This is how I understand your approach:
>>
>> - Boot the first CPU
>> - Build a list of errata discovered at that time
>> - Apply erratum on the boot CPU if required, using a yet-to-be-invented
>> private id matching mechanism,
>> - Boot a secondary CPU
>> - Apply erratum if required, parsing the list
>> - Realise that you don't have the full list (this CPU comes with an
>> erratum that was not in the initial list)
>> - Add more to the list
>> - Apply erratum, using the same matching mechanism
>>
>> This is mine:
>>
>> - Boot the first CPU
>> - Apply global erratum to all CPUs
>> - Apply local erratum
>> - Boot a secondary CPU
>> - Apply local erratum
>>
>> In my case, everything is static, and I don't need to rematch each CPU
>> against the list of globally applicable errata.
>>
>> If my understanding is flawed, let me know.
> 
> Any of our understanding is flawed. I think that needs a maturation period.

Well, these patches have been maturing for a while, and time is running
out. If you have a better idea that is more than a concept, please post
the code, I'd be happy to review it.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-29 14:56                               ` Marc Zyngier
  0 siblings, 0 replies; 88+ messages in thread
From: Marc Zyngier @ 2017-03-29 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 29/03/17 15:27, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 04:38:41PM +0100, Marc Zyngier wrote:
>> On 28/03/17 15:55, Daniel Lezcano wrote:
>>> On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
>>>> On 28/03/17 15:36, Daniel Lezcano wrote:
>>>>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
>>>>>
>>>>> [ ... ]
>>>>>
>>>>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>>>> -					 const void *arg)
>>>>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
>>>>>>>>> +				  const void *arg)
>>>>>>>>>  {
>>>>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
>>>>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
>>>>>>>>
>>>>>>>> Not quite. Here, you're making all capability-based errata to be be
>>>>>>>> global (if a single CPU in the system has a capability, then by
>>>>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
>>>>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
>>>>>>>>
>>>>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
>>>>>>>> matching (since we don't have a need for a global capability erratum
>>>>>>>> handling yet).
>>>>>>>
>>>>>>> Ok, thanks.
>>>>>>
>>>>>> Quick update. I've just implemented this, and found out that getting rid
>>>>>> of local/global has an unfortunate effect:
>>>>>>
>>>>>> Since we only probe the global errata (using ACPI for example) on the
>>>>>> boot CPU path, we lose propagation of the erratum across the secondary
>>>>>> CPUs. One way of solving this is to convert the secondary boot path to
>>>>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
>>>>>> easy, since by the time we boot secondary CPUs, we don't have the
>>>>>> pointers to the various ACPI tables anymore. Also, assuming we were
>>>>>> careful and saved the pointers, the tables may have been unmapped. Fun.
>>>>>
>>>>> My proposal was supposed to prevent that. The detecion is done in the
>>>>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
>>>>> errata. The drivers get the errata and enable the workaround. The id
>>>>> association <-> errata self contains errata types (void *, char *, int). So
>>>>> everything can be done in a CPU basis without local / global dance.
>>>>
>>>> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
>>>> a fly (I'm staying away from the frozen shark metaphor here). You're
>>>> willing to add a whole list of things with private ids that need
>>>> matching to kill a flag? I don't think this buys us anything but extra
>>>> complexity and another maintenance headache.
>>>
>>> Well, it is like your approach except it is split in two steps.
>>>
>>> Can you explain where is the extra complexity ? May be I am missing the point.
>>
>> This is how I understand your approach:
>>
>> - Boot the first CPU
>> - Build a list of errata discovered at that time
>> - Apply erratum on the boot CPU if required, using a yet-to-be-invented
>> private id matching mechanism,
>> - Boot a secondary CPU
>> - Apply erratum if required, parsing the list
>> - Realise that you don't have the full list (this CPU comes with an
>> erratum that was not in the initial list)
>> - Add more to the list
>> - Apply erratum, using the same matching mechanism
>>
>> This is mine:
>>
>> - Boot the first CPU
>> - Apply global erratum to all CPUs
>> - Apply local erratum
>> - Boot a secondary CPU
>> - Apply local erratum
>>
>> In my case, everything is static, and I don't need to rematch each CPU
>> against the list of globally applicable errata.
>>
>> If my understanding is flawed, let me know.
> 
> Any of our understanding is flawed. I think that needs a maturation period.

Well, these patches have been maturing for a while, and time is running
out. If you have a better idea that is more than a concept, please post
the code, I'd be happy to review it.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-29 14:56                               ` Marc Zyngier
@ 2017-03-29 15:12                                 ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-29 15:12 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, dann frazier

On Wed, Mar 29, 2017 at 03:56:52PM +0100, Marc Zyngier wrote:
> On 29/03/17 15:27, Daniel Lezcano wrote:
> > On Tue, Mar 28, 2017 at 04:38:41PM +0100, Marc Zyngier wrote:
> >> On 28/03/17 15:55, Daniel Lezcano wrote:
> >>> On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
> >>>> On 28/03/17 15:36, Daniel Lezcano wrote:
> >>>>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> >>>>>
> >>>>> [ ... ]
> >>>>>
> >>>>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>>>> -					 const void *arg)
> >>>>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>>>> +				  const void *arg)
> >>>>>>>>>  {
> >>>>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>>>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>>>>>>>
> >>>>>>>> Not quite. Here, you're making all capability-based errata to be be
> >>>>>>>> global (if a single CPU in the system has a capability, then by
> >>>>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
> >>>>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
> >>>>>>>>
> >>>>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >>>>>>>> matching (since we don't have a need for a global capability erratum
> >>>>>>>> handling yet).
> >>>>>>>
> >>>>>>> Ok, thanks.
> >>>>>>
> >>>>>> Quick update. I've just implemented this, and found out that getting rid
> >>>>>> of local/global has an unfortunate effect:
> >>>>>>
> >>>>>> Since we only probe the global errata (using ACPI for example) on the
> >>>>>> boot CPU path, we lose propagation of the erratum across the secondary
> >>>>>> CPUs. One way of solving this is to convert the secondary boot path to
> >>>>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
> >>>>>> easy, since by the time we boot secondary CPUs, we don't have the
> >>>>>> pointers to the various ACPI tables anymore. Also, assuming we were
> >>>>>> careful and saved the pointers, the tables may have been unmapped. Fun.
> >>>>>
> >>>>> My proposal was supposed to prevent that. The detecion is done in the
> >>>>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> >>>>> errata. The drivers get the errata and enable the workaround. The id
> >>>>> association <-> errata self contains errata types (void *, char *, int). So
> >>>>> everything can be done in a CPU basis without local / global dance.
> >>>>
> >>>> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
> >>>> a fly (I'm staying away from the frozen shark metaphor here). You're
> >>>> willing to add a whole list of things with private ids that need
> >>>> matching to kill a flag? I don't think this buys us anything but extra
> >>>> complexity and another maintenance headache.
> >>>
> >>> Well, it is like your approach except it is split in two steps.
> >>>
> >>> Can you explain where is the extra complexity ? May be I am missing the point.
> >>
> >> This is how I understand your approach:
> >>
> >> - Boot the first CPU
> >> - Build a list of errata discovered at that time
> >> - Apply erratum on the boot CPU if required, using a yet-to-be-invented
> >> private id matching mechanism,
> >> - Boot a secondary CPU
> >> - Apply erratum if required, parsing the list
> >> - Realise that you don't have the full list (this CPU comes with an
> >> erratum that was not in the initial list)
> >> - Add more to the list
> >> - Apply erratum, using the same matching mechanism
> >>
> >> This is mine:
> >>
> >> - Boot the first CPU
> >> - Apply global erratum to all CPUs
> >> - Apply local erratum
> >> - Boot a secondary CPU
> >> - Apply local erratum
> >>
> >> In my case, everything is static, and I don't need to rematch each CPU
> >> against the list of globally applicable errata.
> >>
> >> If my understanding is flawed, let me know.
> > 
> > Any of our understanding is flawed. I think that needs a maturation period.
> 
> Well, these patches have been maturing for a while, and time is running
> out. If you have a better idea that is more than a concept, please post
> the code, I'd be happy to review it.

No. I had a comment regarding global/local but it is apparently not possible.
Let put the concept apart and move forward.

Thanks.

  -- Daniel

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-29 15:12                                 ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-29 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 29, 2017 at 03:56:52PM +0100, Marc Zyngier wrote:
> On 29/03/17 15:27, Daniel Lezcano wrote:
> > On Tue, Mar 28, 2017 at 04:38:41PM +0100, Marc Zyngier wrote:
> >> On 28/03/17 15:55, Daniel Lezcano wrote:
> >>> On Tue, Mar 28, 2017 at 03:48:23PM +0100, Marc Zyngier wrote:
> >>>> On 28/03/17 15:36, Daniel Lezcano wrote:
> >>>>> On Tue, Mar 28, 2017 at 03:07:52PM +0100, Marc Zyngier wrote:
> >>>>>
> >>>>> [ ... ]
> >>>>>
> >>>>>>>>> -bool arch_timer_check_global_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>>>> -					 const void *arg)
> >>>>>>>>> +bool arch_timer_check_cap_erratum(const struct arch_timer_erratum_workaround *wa,
> >>>>>>>>> +				  const void *arg)
> >>>>>>>>>  {
> >>>>>>>>> -	return cpus_have_cap((uintptr_t)wa->id);
> >>>>>>>>> +	return cpus_have_cap((uintptr_t)wa->id) | this_cpu_has_cap((uintptr_t)wa->id);
> >>>>>>>>
> >>>>>>>> Not quite. Here, you're making all capability-based errata to be be
> >>>>>>>> global (if a single CPU in the system has a capability, then by
> >>>>>>>> transitivity cpus_have_cap returns true). If that's a big-little system,
> >>>>>>>> you end-up applying the workaround to all CPUs, including those unaffected.
> >>>>>>>>
> >>>>>>>> I'd rather drop cpus_have_cap altogether and rely on individual CPU
> >>>>>>>> matching (since we don't have a need for a global capability erratum
> >>>>>>>> handling yet).
> >>>>>>>
> >>>>>>> Ok, thanks.
> >>>>>>
> >>>>>> Quick update. I've just implemented this, and found out that getting rid
> >>>>>> of local/global has an unfortunate effect:
> >>>>>>
> >>>>>> Since we only probe the global errata (using ACPI for example) on the
> >>>>>> boot CPU path, we lose propagation of the erratum across the secondary
> >>>>>> CPUs. One way of solving this is to convert the secondary boot path to
> >>>>>> be aware of DT vs ACPI vs detection method of the month. Which isn't
> >>>>>> easy, since by the time we boot secondary CPUs, we don't have the
> >>>>>> pointers to the various ACPI tables anymore. Also, assuming we were
> >>>>>> careful and saved the pointers, the tables may have been unmapped. Fun.
> >>>>>
> >>>>> My proposal was supposed to prevent that. The detecion is done in the
> >>>>> subsystems, ACPI detects ACPI errata, DT detects DT errata and CPU detects CPU
> >>>>> errata. The drivers get the errata and enable the workaround. The id
> >>>>> association <-> errata self contains errata types (void *, char *, int). So
> >>>>> everything can be done in a CPU basis without local / global dance.
> >>>>
> >>>> I'm sorry, but it feels like a Jumbo-Jet sized hammer to try and squash
> >>>> a fly (I'm staying away from the frozen shark metaphor here). You're
> >>>> willing to add a whole list of things with private ids that need
> >>>> matching to kill a flag? I don't think this buys us anything but extra
> >>>> complexity and another maintenance headache.
> >>>
> >>> Well, it is like your approach except it is split in two steps.
> >>>
> >>> Can you explain where is the extra complexity ? May be I am missing the point.
> >>
> >> This is how I understand your approach:
> >>
> >> - Boot the first CPU
> >> - Build a list of errata discovered at that time
> >> - Apply erratum on the boot CPU if required, using a yet-to-be-invented
> >> private id matching mechanism,
> >> - Boot a secondary CPU
> >> - Apply erratum if required, parsing the list
> >> - Realise that you don't have the full list (this CPU comes with an
> >> erratum that was not in the initial list)
> >> - Add more to the list
> >> - Apply erratum, using the same matching mechanism
> >>
> >> This is mine:
> >>
> >> - Boot the first CPU
> >> - Apply global erratum to all CPUs
> >> - Apply local erratum
> >> - Boot a secondary CPU
> >> - Apply local erratum
> >>
> >> In my case, everything is static, and I don't need to rematch each CPU
> >> against the list of globally applicable errata.
> >>
> >> If my understanding is flawed, let me know.
> > 
> > Any of our understanding is flawed. I think that needs a maturation period.
> 
> Well, these patches have been maturing for a while, and time is running
> out. If you have a better idea that is more than a concept, please post
> the code, I'd be happy to review it.

No. I had a comment regarding global/local but it is apparently not possible.
Let put the concept apart and move forward.

Thanks.

  -- Daniel

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
  2017-03-24 18:00       ` Marc Zyngier
@ 2017-03-30  9:28         ` Daniel Lezcano
  -1 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-30  9:28 UTC (permalink / raw)
  To: Marc Zyngier, dann frazier
  Cc: linux-arm-kernel, linux-kernel, Mark Rutland, Catalin Marinas,
	Will Deacon, Scott Wood, Hanjun Guo, Ding Tianhong, Seth Forshee

On 24/03/2017 19:00, Marc Zyngier wrote:

Hi Marc,

[ ... ]

> Sure, I can add that in the next version of this series. [ ... ]

When sending the new version, could you Cc Thomas Gleixner also.

Thanks.

  -- Daniel

-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods
@ 2017-03-30  9:28         ` Daniel Lezcano
  0 siblings, 0 replies; 88+ messages in thread
From: Daniel Lezcano @ 2017-03-30  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/03/2017 19:00, Marc Zyngier wrote:

Hi Marc,

[ ... ]

> Sure, I can add that in the next version of this series. [ ... ]

When sending the new version, could you Cc Thomas Gleixner also.

Thanks.

  -- Daniel

-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 88+ messages in thread

end of thread, other threads:[~2017-03-30  9:28 UTC | newest]

Thread overview: 88+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-20 17:48 [PATCH v2 00/18] clocksource/arch_timer: Errata workaround infrastructure rework Marc Zyngier
2017-03-20 17:48 ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 01/18] arm64: Allow checking of a CPU-local erratum Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-22  9:22   ` Daniel Lezcano
2017-03-22  9:22     ` Daniel Lezcano
2017-03-20 17:48 ` [PATCH v2 02/18] arm64: Add CNTVCT_EL0 trap handler Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 03/18] arm64: Define Cortex-A73 MIDR Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 04/18] arm64: cpu_errata: Allow an erratum to be match for all revisions of a core Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-22 14:57   ` Daniel Lezcano
2017-03-22 14:57     ` Daniel Lezcano
2017-03-20 17:48 ` [PATCH v2 05/18] arm64: cpu_errata: Add capability to advertise Cortex-A73 erratum 858921 Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-22 15:01   ` Daniel Lezcano
2017-03-22 15:01     ` Daniel Lezcano
2017-03-20 17:48 ` [PATCH v2 06/18] arm64: arch_timer: Add infrastructure for multiple erratum detection methods Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-22 15:41   ` Daniel Lezcano
2017-03-22 15:41     ` Daniel Lezcano
2017-03-22 15:53     ` Marc Zyngier
2017-03-22 15:53       ` Marc Zyngier
2017-03-22 15:59     ` Marc Zyngier
2017-03-22 15:59       ` Marc Zyngier
2017-03-22 16:52       ` Daniel Lezcano
2017-03-22 16:52         ` Daniel Lezcano
2017-03-23 17:30       ` Daniel Lezcano
2017-03-23 17:30         ` Daniel Lezcano
2017-03-24 13:51         ` Marc Zyngier
2017-03-24 13:51           ` Marc Zyngier
2017-03-27  7:56           ` Daniel Lezcano
2017-03-27  7:56             ` Daniel Lezcano
2017-03-28 13:07             ` Marc Zyngier
2017-03-28 13:07               ` Marc Zyngier
2017-03-28 13:34               ` Daniel Lezcano
2017-03-28 13:34                 ` Daniel Lezcano
2017-03-28 14:07                 ` Marc Zyngier
2017-03-28 14:07                   ` Marc Zyngier
2017-03-28 14:36                   ` Daniel Lezcano
2017-03-28 14:36                     ` Daniel Lezcano
2017-03-28 14:48                     ` Marc Zyngier
2017-03-28 14:48                       ` Marc Zyngier
2017-03-28 14:55                       ` Daniel Lezcano
2017-03-28 14:55                         ` Daniel Lezcano
2017-03-28 15:38                         ` Marc Zyngier
2017-03-28 15:38                           ` Marc Zyngier
2017-03-29 14:27                           ` Daniel Lezcano
2017-03-29 14:27                             ` Daniel Lezcano
2017-03-29 14:56                             ` Marc Zyngier
2017-03-29 14:56                               ` Marc Zyngier
2017-03-29 15:12                               ` Daniel Lezcano
2017-03-29 15:12                                 ` Daniel Lezcano
2017-03-24 17:48   ` dann frazier
2017-03-24 17:48     ` dann frazier
2017-03-24 18:00     ` Marc Zyngier
2017-03-24 18:00       ` Marc Zyngier
2017-03-30  9:28       ` Daniel Lezcano
2017-03-30  9:28         ` Daniel Lezcano
2017-03-20 17:48 ` [PATCH v2 07/18] arm64: arch_timer: Add erratum handler for globally defined capability Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 08/18] arm64: arch_timer: Add erratum handler for CPU-specific capability Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 09/18] arm64: arch_timer: Move arch_timer_reg_read/write around Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-22 15:47   ` Daniel Lezcano
2017-03-22 15:47     ` Daniel Lezcano
2017-03-20 17:48 ` [PATCH v2 10/18] arm64: arch_timer: Get rid of erratum_workaround_set_sne Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 11/18] arm64: arch_timer: Rework the set_next_event workarounds Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 12/18] arm64: arch_timer: Make workaround methods optional Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 13/18] arm64: arch_timer: Allows a CPU-specific erratum to only affect a subset of CPUs Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 14/18] arm64: arch_timer: Move clocksource_counter and co around Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 15/18] arm64: arch_timer: Enable CNTVCT_EL0 trap if workaround is enabled Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 16/18] arm64: arch_timer: Workaround for Cortex-A73 erratum 858921 Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 17/18] arm64: arch_timer: Allow erratum matching with ACPI OEM information Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-20 17:48 ` [PATCH v2 18/18] arm64: arch_timer: Add HISILICON_ERRATUM_161010101 ACPI matching data Marc Zyngier
2017-03-20 17:48   ` Marc Zyngier
2017-03-22 13:56 ` [PATCH v2 00/18] clocksource/arch_timer: Errata workaround infrastructure rework Ding Tianhong
2017-03-22 13:56   ` Ding Tianhong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.