linux-arm-kernel.lists.infradead.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).