All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes
@ 2014-08-06 15:46 Ard Biesheuvel
  2014-08-06 15:46 ` [PATCH v3 2/2] arm64: don't flag non-aliasing VIPT I-caches as aliasing Ard Biesheuvel
  2014-08-07 17:27 ` [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes Will Deacon
  0 siblings, 2 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2014-08-06 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

This adds helper functions and #defines to <asm/cachetype.h> to read the
line size and the number of sets from the level 1 instruction cache.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
v3: add WARN_ON(preemptible()), move icache_get_ccsidr() to cpuinfo.c to
    prevent #include header recursion hell
v2: put () around macro args, use 64-bit types for asm() mrs/msr calls

 arch/arm64/include/asm/cachetype.h | 20 ++++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c        | 14 ++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h
index 7a2e0762cb40..4c631a0a3609 100644
--- a/arch/arm64/include/asm/cachetype.h
+++ b/arch/arm64/include/asm/cachetype.h
@@ -39,6 +39,26 @@
 
 extern unsigned long __icache_flags;
 
+#define CCSIDR_EL1_LINESIZE_MASK	0x7
+#define CCSIDR_EL1_LINESIZE(x)		((x) & CCSIDR_EL1_LINESIZE_MASK)
+
+#define CCSIDR_EL1_NUMSETS_SHIFT	13
+#define CCSIDR_EL1_NUMSETS_MASK		(0x7fff << CCSIDR_EL1_NUMSETS_SHIFT)
+#define CCSIDR_EL1_NUMSETS(x) \
+	(((x) & CCSIDR_EL1_NUMSETS_MASK) >> CCSIDR_EL1_NUMSETS_SHIFT)
+
+extern u64 __attribute_const__ icache_get_ccsidr(void);
+
+static inline int icache_get_linesize(void)
+{
+	return 16 << CCSIDR_EL1_LINESIZE(icache_get_ccsidr());
+}
+
+static inline int icache_get_numsets(void)
+{
+	return 1 + CCSIDR_EL1_NUMSETS(icache_get_ccsidr());
+}
+
 /*
  * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
  * permitted in the I-cache.
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index f798f66634af..319255ff536d 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -20,8 +20,10 @@
 #include <asm/cputype.h>
 
 #include <linux/bitops.h>
+#include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/preempt.h>
 #include <linux/printk.h>
 #include <linux/smp.h>
 
@@ -190,3 +192,15 @@ void __init cpuinfo_store_boot_cpu(void)
 
 	boot_cpu_data = *info;
 }
+
+u64 __attribute_const__ icache_get_ccsidr(void)
+{
+	u64 ccsidr;
+
+	WARN_ON(preemptible());
+
+	/* Select L1 I-cache and read its size ID register */
+	asm("msr csselr_el1, %1; isb; mrs %0, ccsidr_el1"
+	    : "=r"(ccsidr) : "r"(1L));
+	return ccsidr;
+}
-- 
1.8.3.2

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

* [PATCH v3 2/2] arm64: don't flag non-aliasing VIPT I-caches as aliasing
  2014-08-06 15:46 [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes Ard Biesheuvel
@ 2014-08-06 15:46 ` Ard Biesheuvel
  2014-08-07 17:28   ` Will Deacon
  2014-08-07 17:27 ` [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes Will Deacon
  1 sibling, 1 reply; 4+ messages in thread
From: Ard Biesheuvel @ 2014-08-06 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

VIPT caches are non-aliasing if the index is derived from address bits that
are always equal between VA and PA. Classifying these as aliasing results in
unnecessary flushing which may hurt performance.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
v2, v3: no changes

 arch/arm64/kernel/cpuinfo.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 319255ff536d..a5b6dce48094 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -49,7 +49,13 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
 	unsigned int cpu = smp_processor_id();
 	u32 l1ip = CTR_L1IP(info->reg_ctr);
 
-	if (l1ip != ICACHE_POLICY_PIPT)
+	/*
+	 * VIPT caches are non-aliasing if the VA always equals the PA in all
+	 * bit positions that are covered by the index, i.e., if num_sets_shift
+	 * is less than or equal to PAGE_SHIFT minus line_size_shift.
+	 */
+	if (l1ip != ICACHE_POLICY_PIPT && !(l1ip == ICACHE_POLICY_VIPT &&
+	    icache_get_linesize() * icache_get_numsets() <= PAGE_SIZE))
 		set_bit(ICACHEF_ALIASING, &__icache_flags);
 	if (l1ip == ICACHE_POLICY_AIVIVT);
 		set_bit(ICACHEF_AIVIVT, &__icache_flags);
-- 
1.8.3.2

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

* [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes
  2014-08-06 15:46 [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes Ard Biesheuvel
  2014-08-06 15:46 ` [PATCH v3 2/2] arm64: don't flag non-aliasing VIPT I-caches as aliasing Ard Biesheuvel
@ 2014-08-07 17:27 ` Will Deacon
  1 sibling, 0 replies; 4+ messages in thread
From: Will Deacon @ 2014-08-07 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 06, 2014 at 04:46:05PM +0100, Ard Biesheuvel wrote:
> This adds helper functions and #defines to <asm/cachetype.h> to read the
> line size and the number of sets from the level 1 instruction cache.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> v3: add WARN_ON(preemptible()), move icache_get_ccsidr() to cpuinfo.c to
>     prevent #include header recursion hell
> v2: put () around macro args, use 64-bit types for asm() mrs/msr calls
> 
>  arch/arm64/include/asm/cachetype.h | 20 ++++++++++++++++++++
>  arch/arm64/kernel/cpuinfo.c        | 14 ++++++++++++++
>  2 files changed, 34 insertions(+)

  Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

* [PATCH v3 2/2] arm64: don't flag non-aliasing VIPT I-caches as aliasing
  2014-08-06 15:46 ` [PATCH v3 2/2] arm64: don't flag non-aliasing VIPT I-caches as aliasing Ard Biesheuvel
@ 2014-08-07 17:28   ` Will Deacon
  0 siblings, 0 replies; 4+ messages in thread
From: Will Deacon @ 2014-08-07 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 06, 2014 at 04:46:06PM +0100, Ard Biesheuvel wrote:
> VIPT caches are non-aliasing if the index is derived from address bits that
> are always equal between VA and PA. Classifying these as aliasing results in
> unnecessary flushing which may hurt performance.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> v2, v3: no changes
> 
>  arch/arm64/kernel/cpuinfo.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index 319255ff536d..a5b6dce48094 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -49,7 +49,13 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
>  	unsigned int cpu = smp_processor_id();
>  	u32 l1ip = CTR_L1IP(info->reg_ctr);
>  
> -	if (l1ip != ICACHE_POLICY_PIPT)
> +	/*
> +	 * VIPT caches are non-aliasing if the VA always equals the PA in all
> +	 * bit positions that are covered by the index, i.e., if num_sets_shift
> +	 * is less than or equal to PAGE_SHIFT minus line_size_shift.
> +	 */
> +	if (l1ip != ICACHE_POLICY_PIPT && !(l1ip == ICACHE_POLICY_VIPT &&
> +	    icache_get_linesize() * icache_get_numsets() <= PAGE_SIZE))

Might just be me, but I'd find this a lot easier to understand if you had a
local `way_size' variable and set it to linesize * num_sets.

Either way:

  Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

end of thread, other threads:[~2014-08-07 17:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-06 15:46 [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes Ard Biesheuvel
2014-08-06 15:46 ` [PATCH v3 2/2] arm64: don't flag non-aliasing VIPT I-caches as aliasing Ard Biesheuvel
2014-08-07 17:28   ` Will Deacon
2014-08-07 17:27 ` [PATCH v3 1/2] arm64: add helper functions to read I-cache attributes Will Deacon

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.