LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB
From: Christophe Leroy @ 2019-08-26 20:08 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Alastair D'Silva
  Cc: linux-kernel, stable, Paul Mackerras, alastair, Thomas Gleixner,
	linuxppc-dev, Allison Randal
In-Reply-To: <20190826165021.GB9305@kroah.com>



Le 26/08/2019 à 18:50, Greg Kroah-Hartman a écrit :
> On Wed, Aug 21, 2019 at 10:19:27AM +1000, Alastair D'Silva wrote:
>> From: Alastair D'Silva <alastair@d-silva.org>
>>
>> The upstream commit:
>> 22e9c88d486a ("powerpc/64: reuse PPC32 static inline flush_dcache_range()")
>> has a similar effect, but since it is a rewrite of the assembler to C, is
>> too invasive for stable. This patch is a minimal fix to address the issue in
>> assembler.
>>
>> This patch applies cleanly to v5.2, v4.19 & v4.14.
>>
>> When calling flush_(inval_)dcache_range with a size >4GB, we were masking
>> off the upper 32 bits, so we would incorrectly flush a range smaller
>> than intended.
>>
>> This patch replaces the 32 bit shifts with 64 bit ones, so that
>> the full size is accounted for.
>>
>> Changelog:
>> v2
>>    - Add related upstream commit
>>
>> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
>> ---
>>   arch/powerpc/kernel/misc_64.S | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
>> index 1ad4089dd110..d4d096f80f4b 100644
>> --- a/arch/powerpc/kernel/misc_64.S
>> +++ b/arch/powerpc/kernel/misc_64.S
>> @@ -130,7 +130,7 @@ _GLOBAL_TOC(flush_dcache_range)
>>   	subf	r8,r6,r4		/* compute length */
>>   	add	r8,r8,r5		/* ensure we get enough */
>>   	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of dcache block size */
>> -	srw.	r8,r8,r9		/* compute line count */
>> +	srd.	r8,r8,r9		/* compute line count */
>>   	beqlr				/* nothing to do? */
>>   	mtctr	r8
>>   0:	dcbst	0,r6
>> @@ -148,7 +148,7 @@ _GLOBAL(flush_inval_dcache_range)
>>   	subf	r8,r6,r4		/* compute length */
>>   	add	r8,r8,r5		/* ensure we get enough */
>>   	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache block size */
>> -	srw.	r8,r8,r9		/* compute line count */
>> +	srd.	r8,r8,r9		/* compute line count */
>>   	beqlr				/* nothing to do? */
>>   	sync
>>   	isync
> 
> I need an ack from the powerpc maintainer(s) before I can take this.

I think you already got an ack (on v1). See 
https://patchwork.ozlabs.org/patch/1147403/#2239663

Christophe

^ permalink raw reply

* Re: [PATCH v2] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB
From: Greg Kroah-Hartman @ 2019-08-26 16:50 UTC (permalink / raw)
  To: Alastair D'Silva
  Cc: alastair, linux-kernel, stable, Paul Mackerras, Thomas Gleixner,
	linuxppc-dev, Allison Randal
In-Reply-To: <20190821001929.4253-1-alastair@au1.ibm.com>

On Wed, Aug 21, 2019 at 10:19:27AM +1000, Alastair D'Silva wrote:
> From: Alastair D'Silva <alastair@d-silva.org>
> 
> The upstream commit:
> 22e9c88d486a ("powerpc/64: reuse PPC32 static inline flush_dcache_range()")
> has a similar effect, but since it is a rewrite of the assembler to C, is
> too invasive for stable. This patch is a minimal fix to address the issue in
> assembler.
> 
> This patch applies cleanly to v5.2, v4.19 & v4.14.
> 
> When calling flush_(inval_)dcache_range with a size >4GB, we were masking
> off the upper 32 bits, so we would incorrectly flush a range smaller
> than intended.
> 
> This patch replaces the 32 bit shifts with 64 bit ones, so that
> the full size is accounted for.
> 
> Changelog:
> v2
>   - Add related upstream commit
> 
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> ---
>  arch/powerpc/kernel/misc_64.S | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
> index 1ad4089dd110..d4d096f80f4b 100644
> --- a/arch/powerpc/kernel/misc_64.S
> +++ b/arch/powerpc/kernel/misc_64.S
> @@ -130,7 +130,7 @@ _GLOBAL_TOC(flush_dcache_range)
>  	subf	r8,r6,r4		/* compute length */
>  	add	r8,r8,r5		/* ensure we get enough */
>  	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of dcache block size */
> -	srw.	r8,r8,r9		/* compute line count */
> +	srd.	r8,r8,r9		/* compute line count */
>  	beqlr				/* nothing to do? */
>  	mtctr	r8
>  0:	dcbst	0,r6
> @@ -148,7 +148,7 @@ _GLOBAL(flush_inval_dcache_range)
>  	subf	r8,r6,r4		/* compute length */
>  	add	r8,r8,r5		/* ensure we get enough */
>  	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache block size */
> -	srw.	r8,r8,r9		/* compute line count */
> +	srd.	r8,r8,r9		/* compute line count */
>  	beqlr				/* nothing to do? */
>  	sync
>  	isync

I need an ack from the powerpc maintainer(s) before I can take this.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH v2] btrfs: fix allocation of bitmap pages.
From: David Sterba @ 2019-08-26 16:46 UTC (permalink / raw)
  To: Nikolay Borisov
  Cc: erhard_f, linux-mm, linux-kernel, Josef Bacik, stable, dsterba,
	Chris Mason, David Sterba, Andrew Morton, linuxppc-dev,
	linux-btrfs
In-Reply-To: <a096d653-8b64-be15-3e81-581536a88e8a@suse.com>

On Mon, Aug 26, 2019 at 06:40:24PM +0300, Nikolay Borisov wrote:
> >> Link: https://bugzilla.kernel.org/show_bug.cgi?id=204371
> >> Fixes: 69d2480456d1 ("btrfs: use copy_page for copying pages instead of memcpy")
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> >> ---
> >> v2: Using kmem_cache instead of get_zeroed_page() in order to benefit from SLAB debugging features like redzone.
> > 
> > I'll take this version, thanks. Though I'm not happy about the allocator
> > behaviour. The kmem cache based fix can be backported independently to
> > 4.19 regardless of the SL*B fixes.
> > 
> >> +extern struct kmem_cache *btrfs_bitmap_cachep;
> > 
> > I've renamed the cache to btrfs_free_space_bitmap_cachep
> > 
> > Reviewed-by: David Sterba <dsterba@suse.com>
> 
> Isn't this obsoleted by
> 
> '[PATCH v2 0/2] guarantee natural alignment for kmalloc()' ?

Yeah, but this would add maybe another whole dev cycle to merge and
release. The reporters of the bug seem to care enough to identify the
problem and propose the fix so I feel like adding the btrfs-specific fix
now is a little favor we can afford.

The bug is reproduced on an architecture that's not widely tested so
from practical POV I think this adds more coverage which is desirable.

^ permalink raw reply

* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Greg Kroah-Hartman @ 2019-08-26 15:57 UTC (permalink / raw)
  To: Nayna
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, Nayna Jain, linux-kernel,
	Mimi Zohar, Claudio Carvalho, Matthew Garret, linuxppc-dev,
	Paul Mackerras, Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <2c5b8ba3-e5a3-5c80-a291-ea9965db2019@linux.vnet.ibm.com>

On Mon, Aug 26, 2019 at 11:46:11AM -0400, Nayna wrote:
> 
> 
> On 08/26/2019 10:56 AM, Greg Kroah-Hartman wrote:
> > On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
> > > +static struct kobj_attribute size_attr = __ATTR_RO(size);
> > Wait, why not just normal ATTR_RO()?
> 
> Oh!! Sorry. I am not seeing this macro in sysfs.h. am I missing something ?

Ugh, no, you are right, I thought it was there as the BIN_ATTR_RO() one
was there :)

> > > +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, VARIABLE_MAX_SIZE);
> > And BIN_ATTR_RO() here?
> 
> This would have worked. I think I just thought to use the same way as
> __ATTR_RO().

Yes, that's fine to use, sorry for the noise.

greg k-h

^ permalink raw reply

* [PATCH 6/6] powerpc/32: don't use CPU_FTR_COHERENT_ICACHE
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>

Only 601 and E200 have CPU_FTR_COHERENT_ICACHE.

Just use #ifdefs instead of feature fixup.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/kernel/misc_32.S | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 3d21fb110797..82df4b09e79f 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -324,10 +324,10 @@ EXPORT_SYMBOL(flush_instruction_cache)
  * flush_icache_range(unsigned long start, unsigned long stop)
  */
 _GLOBAL(flush_icache_range)
-BEGIN_FTR_SECTION
+#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200)
 	PURGE_PREFETCHED_INS
-	blr				/* for 601, do nothing */
-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
+	blr				/* for 601 and e200, do nothing */
+#else
 	rlwinm	r3,r3,0,0,31 - L1_CACHE_SHIFT
 	subf	r4,r3,r4
 	addi	r4,r4,L1_CACHE_BYTES - 1
@@ -353,6 +353,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 	sync				/* additional sync needed on g4 */
 	isync
 	blr
+#endif
 _ASM_NOKPROBE_SYMBOL(flush_icache_range)
 EXPORT_SYMBOL(flush_icache_range)
 
@@ -360,15 +361,15 @@ EXPORT_SYMBOL(flush_icache_range)
  * Flush a particular page from the data cache to RAM.
  * Note: this is necessary because the instruction cache does *not*
  * snoop from the data cache.
- * This is a no-op on the 601 which has a unified cache.
+ * This is a no-op on the 601 and e200 which have a unified cache.
  *
  *	void __flush_dcache_icache(void *page)
  */
 _GLOBAL(__flush_dcache_icache)
-BEGIN_FTR_SECTION
+#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200)
 	PURGE_PREFETCHED_INS
 	blr
-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
+#else
 	rlwinm	r3,r3,0,0,31-PAGE_SHIFT		/* Get page base address */
 	li	r4,PAGE_SIZE/L1_CACHE_BYTES	/* Number of lines in a page */
 	mtctr	r4
@@ -396,6 +397,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
 	sync
 	isync
 	blr
+#endif
 
 #ifndef CONFIG_BOOKE
 /*
@@ -407,10 +409,10 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
  *	void __flush_dcache_icache_phys(unsigned long physaddr)
  */
 _GLOBAL(__flush_dcache_icache_phys)
-BEGIN_FTR_SECTION
+#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200)
 	PURGE_PREFETCHED_INS
-	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
+	blr					/* for 601 and e200, do nothing */
+#else
 	mfmsr	r10
 	rlwinm	r0,r10,0,28,26			/* clear DR */
 	mtmsr	r0
@@ -431,6 +433,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 	mtmsr	r10				/* restore DR */
 	isync
 	blr
+#endif
 #endif /* CONFIG_BOOKE */
 
 /*
-- 
2.13.3


^ permalink raw reply related

* [PATCH 5/6] powerpc/32: drop CPU_FTR_UNIFIED_ID_CACHE
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>

Only 601 and e200 have unified I/D cache.

Drop the feature and use CONFIG_PPC_BOOK3S_601 and CONFIG_E200.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/cputable.h | 5 ++---
 arch/powerpc/kernel/misc_32.S       | 4 ++--
 arch/powerpc/kernel/setup_32.c      | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index fac1b81bbbd9..a1ebcbc3931f 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -158,7 +158,6 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_NEED_COHERENT		ASM_CONST(0x01000000)
 #define CPU_FTR_NO_BTIC			ASM_CONST(0x02000000)
 #define CPU_FTR_PPC_LE			ASM_CONST(0x04000000)
-#define CPU_FTR_UNIFIED_ID_CACHE	ASM_CONST(0x08000000)
 #define CPU_FTR_SPE			ASM_CONST(0x10000000)
 #define CPU_FTR_NEED_PAIRED_STWCX	ASM_CONST(0x20000000)
 #define CPU_FTR_INDEXED_DCR		ASM_CONST(0x40000000)
@@ -292,7 +291,7 @@ static inline void cpu_feature_keys_init(void) { }
 #endif
 
 #define CPU_FTRS_PPC601	(CPU_FTR_COMMON | \
-	CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
+	CPU_FTR_COHERENT_ICACHE)
 #define CPU_FTRS_603	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_604	(CPU_FTR_COMMON | CPU_FTR_PPC_LE)
@@ -383,7 +382,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTRS_47X	(CPU_FTRS_440x6)
 #define CPU_FTRS_E200	(CPU_FTR_SPE_COMP | \
 	    CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
-	    CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE | \
+	    CPU_FTR_NOEXECUTE | \
 	    CPU_FTR_DEBUG_LVL_EXC)
 #define CPU_FTRS_E500	(CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index b917641cdaa6..3d21fb110797 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -292,14 +292,14 @@ _GLOBAL(flush_instruction_cache)
 	iccci	0,r3
 #endif
 #elif defined(CONFIG_FSL_BOOKE)
-BEGIN_FTR_SECTION
+#ifdef CONFIG_E200
 	mfspr   r3,SPRN_L1CSR0
 	ori     r3,r3,L1CSR0_CFI|L1CSR0_CLFC
 	/* msync; isync recommended here */
 	mtspr   SPRN_L1CSR0,r3
 	isync
 	blr
-END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
+#endif
 	mfspr	r3,SPRN_L1CSR1
 	ori	r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
 	mtspr	SPRN_L1CSR1,r3
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 94517e4a2723..a7541edf0cdb 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -206,6 +206,6 @@ __init void initialize_cache_info(void)
 	dcache_bsize = cur_cpu_spec->dcache_bsize;
 	icache_bsize = cur_cpu_spec->icache_bsize;
 	ucache_bsize = 0;
-	if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE))
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_601) || IS_ENABLED(CONFIG_E200))
 		ucache_bsize = icache_bsize = dcache_bsize;
 }
-- 
2.13.3


^ permalink raw reply related

* [PATCH 4/6] powerpc/32s: use CONFIG_PPC_BOOK3S_601 instead of reading PVR
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>

Use CONFIG_PPC_BOOK3S_601 instead of reading PVR to know if
it is a 601 or not.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/kernel/head_32.S | 49 +++++++++++++++++++------------------------
 arch/powerpc/kernel/misc_32.S |  6 ++----
 2 files changed, 24 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 9e6f01abb31e..4a24f8f026c7 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -34,7 +34,16 @@
 
 #include "head_32.h"
 
-/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
+/* 601 only have IBAT */
+#ifdef CONFIG_PPC_BOOK3S_601
+#define LOAD_BAT(n, reg, RA, RB)	\
+	li	RA,0;			\
+	mtspr	SPRN_IBAT##n##U,RA;	\
+	lwz	RA,(n*16)+0(reg);	\
+	lwz	RB,(n*16)+4(reg);	\
+	mtspr	SPRN_IBAT##n##U,RA;	\
+	mtspr	SPRN_IBAT##n##L,RB
+#else
 #define LOAD_BAT(n, reg, RA, RB)	\
 	/* see the comment for clear_bats() -- Cort */ \
 	li	RA,0;			\
@@ -44,12 +53,11 @@
 	lwz	RB,(n*16)+4(reg);	\
 	mtspr	SPRN_IBAT##n##U,RA;	\
 	mtspr	SPRN_IBAT##n##L,RB;	\
-	beq	1f;			\
 	lwz	RA,(n*16)+8(reg);	\
 	lwz	RB,(n*16)+12(reg);	\
 	mtspr	SPRN_DBAT##n##U,RA;	\
-	mtspr	SPRN_DBAT##n##L,RB;	\
-1:
+	mtspr	SPRN_DBAT##n##L,RB
+#endif
 
 	__HEAD
 	.stabs	"arch/powerpc/kernel/",N_SO,0,0,0f
@@ -820,9 +828,6 @@ load_up_mmu:
 
 /* Load the BAT registers with the values set up by MMU_init.
    MMU_init takes care of whether we're on a 601 or not. */
-	mfpvr	r3
-	srwi	r3,r3,16
-	cmpwi	r3,1
 	lis	r3,BATS@ha
 	addi	r3,r3,BATS@l
 	tophys(r3,r3)
@@ -998,11 +1003,8 @@ EXPORT_SYMBOL(switch_mmu_context)
  */
 clear_bats:
 	li	r10,0
-	mfspr	r9,SPRN_PVR
-	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
-	cmpwi	r9, 1
-	beq	1f
 
+#ifndef CONFIG_PPC_BOOK3S_601
 	mtspr	SPRN_DBAT0U,r10
 	mtspr	SPRN_DBAT0L,r10
 	mtspr	SPRN_DBAT1U,r10
@@ -1011,7 +1013,7 @@ clear_bats:
 	mtspr	SPRN_DBAT2L,r10
 	mtspr	SPRN_DBAT3U,r10
 	mtspr	SPRN_DBAT3L,r10
-1:
+#endif
 	mtspr	SPRN_IBAT0U,r10
 	mtspr	SPRN_IBAT0L,r10
 	mtspr	SPRN_IBAT1U,r10
@@ -1106,10 +1108,7 @@ mmu_off:
  */
 initial_bats:
 	lis	r11,PAGE_OFFSET@h
-	mfspr	r9,SPRN_PVR
-	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
-	cmpwi	0,r9,1
-	bne	4f
+#ifdef CONFIG_PPC_BOOK3S_601
 	ori	r11,r11,4		/* set up BAT registers for 601 */
 	li	r8,0x7f			/* valid, block length = 8MB */
 	mtspr	SPRN_IBAT0U,r11		/* N.B. 601 has valid bit in */
@@ -1122,10 +1121,8 @@ initial_bats:
 	addis	r8,r8,0x800000@h
 	mtspr	SPRN_IBAT2U,r11
 	mtspr	SPRN_IBAT2L,r8
-	isync
-	blr
-
-4:	tophys(r8,r11)
+#else
+	tophys(r8,r11)
 #ifdef CONFIG_SMP
 	ori	r8,r8,0x12		/* R/W access, M=1 */
 #else
@@ -1137,10 +1134,10 @@ initial_bats:
 	mtspr	SPRN_DBAT0U,r11		/* bit in upper BAT register */
 	mtspr	SPRN_IBAT0L,r8
 	mtspr	SPRN_IBAT0U,r11
+#endif
 	isync
 	blr
 
-
 #ifdef CONFIG_BOOTX_TEXT
 setup_disp_bat:
 	/*
@@ -1155,15 +1152,13 @@ setup_disp_bat:
 	beqlr
 	lwz	r11,0(r8)
 	lwz	r8,4(r8)
-	mfspr	r9,SPRN_PVR
-	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
-	cmpwi	0,r9,1
-	beq	1f
+#ifndef CONFIG_PPC_BOOK3S_601
 	mtspr	SPRN_DBAT3L,r8
 	mtspr	SPRN_DBAT3U,r11
-	blr
-1:	mtspr	SPRN_IBAT3L,r8
+#else
+	mtspr	SPRN_IBAT3L,r8
 	mtspr	SPRN_IBAT3U,r11
+#endif
 	blr
 #endif /* CONFIG_BOOTX_TEXT */
 
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 02d90e1ebf65..b917641cdaa6 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -303,11 +303,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
 	mfspr	r3,SPRN_L1CSR1
 	ori	r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
 	mtspr	SPRN_L1CSR1,r3
+#elif defined(CONFIG_PPC_BOOK3S_601)
+	blr			/* for 601, do nothing */
 #else
-	mfspr	r3,SPRN_PVR
-	rlwinm	r3,r3,16,16,31
-	cmpwi	0,r3,1
-	beqlr			/* for 601, do nothing */
 	/* 603/604 processor - use invalidate-all bit in HID0 */
 	mfspr	r3,SPRN_HID0
 	ori	r3,r3,HID0_ICFI
-- 
2.13.3


^ permalink raw reply related

* [PATCH 3/6] powerpc/32s: drop CPU_FTR_USE_RTC feature
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>

CPU_FTR_USE_RTC feature only applies to powerpc601.

Drop this feature and replace it with tests on CONFIG_PPC_BOOK3S_601.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/cputable.h     |  3 +--
 arch/powerpc/include/asm/time.h         |  6 +-----
 arch/powerpc/kernel/vdso.c              | 22 ----------------------
 arch/powerpc/kernel/vdso32/datapage.S   |  2 ++
 arch/powerpc/kernel/vdso32/vdso32.lds.S |  4 +++-
 5 files changed, 7 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 0aad095896d6..fac1b81bbbd9 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -149,7 +149,6 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_SPEC7450		ASM_CONST(0x00004000)
 #define CPU_FTR_TAU			ASM_CONST(0x00008000)
 #define CPU_FTR_CAN_DOZE		ASM_CONST(0x00010000)
-#define CPU_FTR_USE_RTC			ASM_CONST(0x00020000)
 #define CPU_FTR_L3CR			ASM_CONST(0x00040000)
 #define CPU_FTR_L3_DISABLE_NAP		ASM_CONST(0x00080000)
 #define CPU_FTR_NAP_DISABLE_L2_PR	ASM_CONST(0x00100000)
@@ -293,7 +292,7 @@ static inline void cpu_feature_keys_init(void) { }
 #endif
 
 #define CPU_FTRS_PPC601	(CPU_FTR_COMMON | \
-	CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC)
+	CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
 #define CPU_FTRS_603	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_604	(CPU_FTR_COMMON | CPU_FTR_PPC_LE)
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 54f4ec1f9fab..08dbe3e6831c 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -41,11 +41,7 @@ struct div_result {
 
 /* Accessor functions for the timebase (RTC on 601) registers. */
 /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
-#ifdef CONFIG_PPC_BOOK3S_32
-#define __USE_RTC()	(cpu_has_feature(CPU_FTR_USE_RTC))
-#else
-#define __USE_RTC()	0
-#endif
+#define __USE_RTC()	(IS_ENABLED(CONFIG_PPC_BOOK3S_601))
 
 #ifdef CONFIG_PPC64
 
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index d60598113a9f..eae9ddaecbcf 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -94,28 +94,6 @@ static struct vdso_patch_def vdso_patches[] = {
 		CPU_FTR_COHERENT_ICACHE, CPU_FTR_COHERENT_ICACHE,
 		"__kernel_sync_dicache", "__kernel_sync_dicache_p5"
 	},
-#ifdef CONFIG_PPC32
-	{
-		CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
-		"__kernel_gettimeofday", NULL
-	},
-	{
-		CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
-		"__kernel_clock_gettime", NULL
-	},
-	{
-		CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
-		"__kernel_clock_getres", NULL
-	},
-	{
-		CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
-		"__kernel_get_tbfreq", NULL
-	},
-	{
-		CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
-		"__kernel_time", NULL
-	},
-#endif
 };
 
 /*
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index 6984125b9fc0..6c7401bd284e 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -70,6 +70,7 @@ V_FUNCTION_END(__kernel_get_syscall_map)
  *
  * returns the timebase frequency in HZ
  */
+#ifndef CONFIG_PPC_BOOK3S_601
 V_FUNCTION_BEGIN(__kernel_get_tbfreq)
   .cfi_startproc
 	mflr	r12
@@ -82,3 +83,4 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
 	blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
+#endif
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 099a6db14e67..00c025ba4a92 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -144,10 +144,13 @@ VERSION
 		__kernel_datapage_offset;
 
 		__kernel_get_syscall_map;
+#ifndef CONFIG_PPC_BOOK3S_601
 		__kernel_gettimeofday;
 		__kernel_clock_gettime;
 		__kernel_clock_getres;
+		__kernel_time;
 		__kernel_get_tbfreq;
+#endif
 		__kernel_sync_dicache;
 		__kernel_sync_dicache_p5;
 		__kernel_sigtramp32;
@@ -155,7 +158,6 @@ VERSION
 #ifdef CONFIG_PPC64
 		__kernel_getcpu;
 #endif
-		__kernel_time;
 
 	local: *;
 	};
-- 
2.13.3


^ permalink raw reply related

* [PATCH 2/6] powerpc/32s: get rid of CPU_FTR_601 feature
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>

Now that 601 is exclusive from other 6xx, CPU_FTR_601 and
associated fixups are useless.

Drop this feature and use #ifdefs instead.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/configs/pmac32_defconfig |  1 -
 arch/powerpc/include/asm/cputable.h   | 14 ++++++++------
 arch/powerpc/include/asm/ppc_asm.h    | 28 +++++++---------------------
 arch/powerpc/include/asm/ptrace.h     |  6 +++++-
 arch/powerpc/include/asm/timex.h      | 34 +++-------------------------------
 arch/powerpc/kernel/cputable.c        |  6 ++++--
 arch/powerpc/kernel/entry_32.S        | 22 ++++++++++++++++------
 arch/powerpc/mm/book3s32/mmu.c        | 15 ++++++---------
 arch/powerpc/mm/ptdump/bats.c         |  2 +-
 arch/powerpc/platforms/Kconfig        |  3 ++-
 10 files changed, 52 insertions(+), 79 deletions(-)

diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 7e6654848531..4e6e95f92646 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -20,7 +20,6 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_PMAC=y
-CONFIG_PPC601_SYNC_FIX=y
 CONFIG_GEN_RTC=y
 CONFIG_HIGHMEM=y
 CONFIG_BINFMT_MISC=m
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index d05f0c28e515..0aad095896d6 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -145,7 +145,6 @@ static inline void cpu_feature_keys_init(void) { }
 
 /* Definitions for features that only exist on 32-bit chips */
 #ifdef CONFIG_PPC32
-#define CPU_FTR_601			ASM_CONST(0x00001000)
 #define CPU_FTR_L2CR			ASM_CONST(0x00002000)
 #define CPU_FTR_SPEC7450		ASM_CONST(0x00004000)
 #define CPU_FTR_TAU			ASM_CONST(0x00008000)
@@ -167,7 +166,6 @@ static inline void cpu_feature_keys_init(void) { }
 
 #else	/* CONFIG_PPC32 */
 /* Define these to 0 for the sake of tests in common code */
-#define CPU_FTR_601			(0)
 #define CPU_FTR_PPC_LE			(0)
 #endif
 
@@ -294,7 +292,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_MAYBE_CAN_NAP	0
 #endif
 
-#define CPU_FTRS_PPC601	(CPU_FTR_COMMON | CPU_FTR_601 | \
+#define CPU_FTRS_PPC601	(CPU_FTR_COMMON | \
 	CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC)
 #define CPU_FTRS_603	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
@@ -498,7 +496,9 @@ static inline void cpu_feature_keys_init(void) { }
 #else
 enum {
 	CPU_FTRS_POSSIBLE =
-#ifdef CONFIG_PPC_BOOK3S_32
+#ifdef CONFIG_PPC_BOOK3S_601
+	    CPU_FTRS_PPC601 |
+#elif defined(CONFIG_PPC_BOOK3S_32)
 	    CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
 	    CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
 	    CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
@@ -574,8 +574,10 @@ enum {
 #else
 enum {
 	CPU_FTRS_ALWAYS =
-#ifdef CONFIG_PPC_BOOK3S_32
-	    CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
+#ifdef CONFIG_PPC_BOOK3S_601
+	    CPU_FTRS_PPC601 &
+#elif defined(CONFIG_PPC_BOOK3S_32)
+	    CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
 	    CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
 	    CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
 	    CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 &
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index e0637730a8e7..94279e611c98 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -351,19 +351,9 @@ GLUE(.,name):
 
 /* various errata or part fixups */
 #ifdef CONFIG_PPC601_SYNC_FIX
-#define SYNC				\
-BEGIN_FTR_SECTION			\
-	sync;				\
-	isync;				\
-END_FTR_SECTION_IFSET(CPU_FTR_601)
-#define SYNC_601			\
-BEGIN_FTR_SECTION			\
-	sync;				\
-END_FTR_SECTION_IFSET(CPU_FTR_601)
-#define ISYNC_601			\
-BEGIN_FTR_SECTION			\
-	isync;				\
-END_FTR_SECTION_IFSET(CPU_FTR_601)
+#define SYNC		sync; isync
+#define SYNC_601	sync
+#define ISYNC_601	isync
 #else
 #define	SYNC
 #define SYNC_601
@@ -389,15 +379,11 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
 #define MFTBU(dest)			mfspr dest, SPRN_TBRU
 #endif
 
-#ifndef CONFIG_SMP
-#define TLBSYNC
-#else /* CONFIG_SMP */
 /* tlbsync is not implemented on 601 */
-#define TLBSYNC				\
-BEGIN_FTR_SECTION			\
-	tlbsync;			\
-	sync;				\
-END_FTR_SECTION_IFCLR(CPU_FTR_601)
+#if !defined(CONFIG_SMP) || defined(CONFIG_PPC_BOOK3S_601)
+#define TLBSYNC
+#else
+#define TLBSYNC		tlbsync; sync
 #endif
 
 #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index feee1b21bbd5..ee3ada66deb5 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -203,7 +203,11 @@ do {									      \
 #endif /* __powerpc64__ */
 
 #define arch_has_single_step()	(1)
-#define arch_has_block_step()	(!cpu_has_feature(CPU_FTR_601))
+#ifndef CONFIG_BOOK3S_601
+#define arch_has_block_step()	(true)
+#else
+#define arch_has_block_step()	(false)
+#endif
 #define ARCH_HAS_USER_SINGLE_STEP_REPORT
 
 /*
diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h
index 926b9f91a3ef..d2d2c4bd8435 100644
--- a/arch/powerpc/include/asm/timex.h
+++ b/arch/powerpc/include/asm/timex.h
@@ -17,38 +17,10 @@ typedef unsigned long cycles_t;
 
 static inline cycles_t get_cycles(void)
 {
-#ifdef __powerpc64__
+	if (IS_ENABLED(CONFIG_BOOK3S_601))
+		return 0;
+
 	return mftb();
-#else
-	cycles_t ret;
-
-	/*
-	 * For the "cycle" counter we use the timebase lower half.
-	 * Currently only used on SMP.
-	 */
-
-	ret = 0;
-
-	__asm__ __volatile__(
-#ifdef CONFIG_PPC_8xx
-		"97:	mftb %0\n"
-#else
-		"97:	mfspr %0, %2\n"
-#endif
-		"99:\n"
-		".section __ftr_fixup,\"a\"\n"
-		".align 2\n"
-		"98:\n"
-		"	.long %1\n"
-		"	.long 0\n"
-		"	.long 97b-98b\n"
-		"	.long 99b-98b\n"
-		"	.long 0\n"
-		"	.long 0\n"
-		".previous"
-		: "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
-	return ret;
-#endif
 }
 
 #endif	/* __KERNEL__ */
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index bfe5f4a2886b..e745abc5457a 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -569,7 +569,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 #endif	/* CONFIG_PPC_BOOK3S_64 */
 
 #ifdef CONFIG_PPC32
-#ifdef CONFIG_PPC_BOOK3S_32
+#ifdef CONFIG_PPC_BOOK3S_601
 	{	/* 601 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x00010000,
@@ -583,6 +583,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc601",
 	},
+#endif /* CONFIG_PPC_BOOK3S_601 */
+#ifdef CONFIG_PPC_BOOK3S_6xx
 	{	/* 603 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x00030000,
@@ -1212,7 +1214,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc603",
 	},
-#endif /* CONFIG_PPC_BOOK3S_32 */
+#endif /* CONFIG_PPC_BOOK3S_6xx */
 #ifdef CONFIG_PPC_8xx
 	{	/* 8xx */
 		.pvr_mask		= 0xffff0000,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 54fab22c9a43..0365d1afbfa5 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -777,11 +777,19 @@ fast_exception_return:
 1:	lis	r3,exc_exit_restart_end@ha
 	addi	r3,r3,exc_exit_restart_end@l
 	cmplw	r12,r3
+#if CONFIG_PPC_BOOK3S_601
+	bge	2b
+#else
 	bge	3f
+#endif
 	lis	r4,exc_exit_restart@ha
 	addi	r4,r4,exc_exit_restart@l
 	cmplw	r12,r4
+#if CONFIG_PPC_BOOK3S_601
+	blt	2b
+#else
 	blt	3f
+#endif
 	lis	r3,fee_restarts@ha
 	tophys(r3,r3)
 	lwz	r5,fee_restarts@l(r3)
@@ -800,9 +808,6 @@ fee_restarts:
 /* aargh, we don't know which trap this is */
 /* but the 601 doesn't implement the RI bit, so assume it's OK */
 3:
-BEGIN_FTR_SECTION
-	b	2b
-END_FTR_SECTION_IFSET(CPU_FTR_601)
 	li	r10,-1
 	stw	r10,_TRAP(r11)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -1270,11 +1275,19 @@ nonrecoverable:
 	lis	r10,exc_exit_restart_end@ha
 	addi	r10,r10,exc_exit_restart_end@l
 	cmplw	r12,r10
+#ifdef CONFIG_PPC_BOOK3S_601
+	bgelr
+#else
 	bge	3f
+#endif
 	lis	r11,exc_exit_restart@ha
 	addi	r11,r11,exc_exit_restart@l
 	cmplw	r12,r11
+#ifdef CONFIG_PPC_BOOK3S_601
+	bltlr
+#else
 	blt	3f
+#endif
 	lis	r10,ee_restarts@ha
 	lwz	r12,ee_restarts@l(r10)
 	addi	r12,r12,1
@@ -1283,9 +1296,6 @@ nonrecoverable:
 	blr
 3:	/* OK, we can't recover, kill this process */
 	/* but the 601 doesn't implement the RI bit, so assume it's OK */
-BEGIN_FTR_SECTION
-	blr
-END_FTR_SECTION_IFSET(CPU_FTR_601)
 	lwz	r3,_TRAP(r1)
 	andi.	r0,r3,1
 	beq	5f
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 50a1991d257f..84d5fab94f8f 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -74,7 +74,7 @@ static int find_free_bat(void)
 {
 	int b;
 
-	if (cpu_has_feature(CPU_FTR_601)) {
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) {
 		for (b = 0; b < 4; b++) {
 			struct ppc_bat *bat = BATS[b];
 
@@ -106,7 +106,7 @@ static int find_free_bat(void)
  */
 static unsigned int block_size(unsigned long base, unsigned long top)
 {
-	unsigned int max_size = (cpu_has_feature(CPU_FTR_601) ? 8 : 256) << 20;
+	unsigned int max_size = IS_ENABLED(CONFIG_PPC_BOOK3S_601) ? SZ_8M : SZ_256M;
 	unsigned int base_shift = (ffs(base) - 1) & 31;
 	unsigned int block_shift = (fls(top - base) - 1) & 31;
 
@@ -189,7 +189,7 @@ void mmu_mark_initmem_nx(void)
 	unsigned long top = (unsigned long)_etext - PAGE_OFFSET;
 	unsigned long size;
 
-	if (cpu_has_feature(CPU_FTR_601))
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
 		return;
 
 	for (i = 0; i < nb - 1 && base < top && top - base > (128 << 10);) {
@@ -227,7 +227,7 @@ void mmu_mark_rodata_ro(void)
 	int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
 	int i;
 
-	if (cpu_has_feature(CPU_FTR_601))
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
 		return;
 
 	for (i = 0; i < nb; i++) {
@@ -259,7 +259,7 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
 		flags &= ~_PAGE_COHERENT;
 
 	bl = (size >> 17) - 1;
-	if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
+	if (!IS_ENABLED(CONFIG_PPC_BOOK3S_601)) {
 		/* 603, 604, etc. */
 		/* Do DBAT first */
 		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
@@ -441,7 +441,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 	BUG_ON(first_memblock_base != 0);
 
 	/* 601 can only access 16MB at the moment */
-	if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
 		memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01000000));
 	else /* Anything else has 256M mapped */
 		memblock_set_current_limit(min_t(u64, first_memblock_size, 0x10000000));
@@ -459,9 +459,6 @@ void __init setup_kuep(bool disabled)
 {
 	pr_info("Activating Kernel Userspace Execution Prevention\n");
 
-	if (cpu_has_feature(CPU_FTR_601))
-		pr_warn("KUEP is not working on powerpc 601 (No NX bit in Seg Regs)\n");
-
 	if (disabled)
 		pr_warn("KUEP cannot be disabled yet on 6xx when compiled in\n");
 }
diff --git a/arch/powerpc/mm/ptdump/bats.c b/arch/powerpc/mm/ptdump/bats.c
index a0d23e96e841..4154feac1da3 100644
--- a/arch/powerpc/mm/ptdump/bats.c
+++ b/arch/powerpc/mm/ptdump/bats.c
@@ -149,7 +149,7 @@ static int bats_show_603(struct seq_file *m, void *v)
 
 static int bats_open(struct inode *inode, struct file *file)
 {
-	if (cpu_has_feature(CPU_FTR_601))
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
 		return single_open(file, bats_show_601, NULL);
 
 	return single_open(file, bats_show_603, NULL);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f3fb79fccc72..d82e3664ffdf 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -197,7 +197,8 @@ endmenu
 
 config PPC601_SYNC_FIX
 	bool "Workarounds for PPC601 bugs"
-	depends on PPC_BOOK3S_32 && PPC_PMAC
+	depends on PPC_BOOK3S_601 && PPC_PMAC
+	default y
 	help
 	  Some versions of the PPC601 (the first PowerPC chip) have bugs which
 	  mean that extra synchronization instructions are required near
-- 
2.13.3


^ permalink raw reply related

* [PATCH 1/6] powerpc/32s: add an option to exclusively select powerpc 601
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linuxppc-dev, linux-kernel

Powerpc 601 is rather old powerpc which as some important
limitations compared to other book3s/32 powerpcs:
- No Timebase.
- Common BATs for instruction and data.
- No execution protection in segment registers.
- No RI bit in MSR
- ...

It is starting to be difficult and cumbersome to maintain
kernels that are compatible both with 601 and other 6xx cores.

Create a compiletime option to exclusively select either powerpc 601
or other 6xx.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/platforms/Kconfig.cputype | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 56a7c814160d..68c5cc075bfc 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -6,6 +6,9 @@ config PPC64
 	  This option selects whether a 32-bit or a 64-bit kernel
 	  will be built.
 
+config PPC_BOOK3S_32
+	bool
+
 menu "Processor support"
 choice
 	prompt "Processor Type"
@@ -21,13 +24,20 @@ choice
 
 	  If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
 
-config PPC_BOOK3S_32
-	bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
+config PPC_BOOK3S_6xx
+	bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601"
+	select PPC_BOOK3S_32
 	select PPC_FPU
 	select PPC_HAVE_PMU_SUPPORT
 	select PPC_HAVE_KUEP
 	select PPC_HAVE_KUAP
 
+config PPC_BOOK3S_601
+	bool "PowerPC 601"
+	select PPC_BOOK3S_32
+	select PPC_FPU
+	select PPC_HAVE_KUAP
+
 config PPC_85xx
 	bool "Freescale 85xx"
 	select E500
-- 
2.13.3


^ permalink raw reply related

* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 15:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Nayna Jain
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
	Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
	Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <20190826145649.GA27342@kroah.com>



On 08/26/2019 10:56 AM, Greg Kroah-Hartman wrote:
> On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
>> +static struct kobj_attribute size_attr = __ATTR_RO(size);
> Wait, why not just normal ATTR_RO()?

Oh!! Sorry. I am not seeing this macro in sysfs.h. am I missing something ?

>
>> +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, VARIABLE_MAX_SIZE);
> And BIN_ATTR_RO() here?

This would have worked. I think I just thought to use the same way as 
__ATTR_RO().
I will change this to __BIN_ATTR_RO and use __BIN_ATTR_WO from your patch.

Thanks for the patch.

Thanks & Regards,
     - Nayna

^ permalink raw reply

* Re: [PATCH v2] btrfs: fix allocation of bitmap pages.
From: David Sterba @ 2019-08-26 15:37 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: erhard_f, Chris Mason, Josef Bacik, stable, linux-kernel,
	linux-mm, David Sterba, Andrew Morton, linuxppc-dev, linux-btrfs
In-Reply-To: <c3157c8e8e0e7588312b40c853f65c02fe6c957a.1566399731.git.christophe.leroy@c-s.fr>

On Wed, Aug 21, 2019 at 03:05:55PM +0000, Christophe Leroy wrote:
> Various notifications of type "BUG kmalloc-4096 () : Redzone
> overwritten" have been observed recently in various parts of
> the kernel. After some time, it has been made a relation with
> the use of BTRFS filesystem.
> 
> [   22.809700] BUG kmalloc-4096 (Tainted: G        W        ): Redzone overwritten
> [   22.809971] -----------------------------------------------------------------------------
> 
> [   22.810286] INFO: 0xbe1a5921-0xfbfc06cd. First byte 0x0 instead of 0xcc
> [   22.810866] INFO: Allocated in __load_free_space_cache+0x588/0x780 [btrfs] age=22 cpu=0 pid=224
> [   22.811193] 	__slab_alloc.constprop.26+0x44/0x70
> [   22.811345] 	kmem_cache_alloc_trace+0xf0/0x2ec
> [   22.811588] 	__load_free_space_cache+0x588/0x780 [btrfs]
> [   22.811848] 	load_free_space_cache+0xf4/0x1b0 [btrfs]
> [   22.812090] 	cache_block_group+0x1d0/0x3d0 [btrfs]
> [   22.812321] 	find_free_extent+0x680/0x12a4 [btrfs]
> [   22.812549] 	btrfs_reserve_extent+0xec/0x220 [btrfs]
> [   22.812785] 	btrfs_alloc_tree_block+0x178/0x5f4 [btrfs]
> [   22.813032] 	__btrfs_cow_block+0x150/0x5d4 [btrfs]
> [   22.813262] 	btrfs_cow_block+0x194/0x298 [btrfs]
> [   22.813484] 	commit_cowonly_roots+0x44/0x294 [btrfs]
> [   22.813718] 	btrfs_commit_transaction+0x63c/0xc0c [btrfs]
> [   22.813973] 	close_ctree+0xf8/0x2a4 [btrfs]
> [   22.814107] 	generic_shutdown_super+0x80/0x110
> [   22.814250] 	kill_anon_super+0x18/0x30
> [   22.814437] 	btrfs_kill_super+0x18/0x90 [btrfs]
> [   22.814590] INFO: Freed in proc_cgroup_show+0xc0/0x248 age=41 cpu=0 pid=83
> [   22.814841] 	proc_cgroup_show+0xc0/0x248
> [   22.814967] 	proc_single_show+0x54/0x98
> [   22.815086] 	seq_read+0x278/0x45c
> [   22.815190] 	__vfs_read+0x28/0x17c
> [   22.815289] 	vfs_read+0xa8/0x14c
> [   22.815381] 	ksys_read+0x50/0x94
> [   22.815475] 	ret_from_syscall+0x0/0x38
> 
> Commit 69d2480456d1 ("btrfs: use copy_page for copying pages instead
> of memcpy") changed the way bitmap blocks are copied. But allthough
> bitmaps have the size of a page, they were allocated with kzalloc().
> 
> Most of the time, kzalloc() allocates aligned blocks of memory, so
> copy_page() can be used. But when some debug options like SLAB_DEBUG
> are activated, kzalloc() may return unaligned pointer.
> 
> On powerpc, memcpy(), copy_page() and other copying functions use
> 'dcbz' instruction which provides an entire zeroed cacheline to avoid
> memory read when the intention is to overwrite a full line. Functions
> like memcpy() are writen to care about partial cachelines at the start
> and end of the destination, but copy_page() assumes it gets pages. As
> pages are naturally cache aligned, copy_page() doesn't care about
> partial lines. This means that when copy_page() is called with a
> misaligned pointer, a few leading bytes are zeroed.
> 
> To fix it, allocate bitmaps through kmem_cache instead of using kzalloc()
> The cache pool is created with PAGE_SIZE alignment constraint.
> 
> Reported-by: Erhard F. <erhard_f@mailbox.org>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=204371
> Fixes: 69d2480456d1 ("btrfs: use copy_page for copying pages instead of memcpy")
> Cc: stable@vger.kernel.org
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
> v2: Using kmem_cache instead of get_zeroed_page() in order to benefit from SLAB debugging features like redzone.

I'll take this version, thanks. Though I'm not happy about the allocator
behaviour. The kmem cache based fix can be backported independently to
4.19 regardless of the SL*B fixes.

> +extern struct kmem_cache *btrfs_bitmap_cachep;

I've renamed the cache to btrfs_free_space_bitmap_cachep

Reviewed-by: David Sterba <dsterba@suse.com>

^ permalink raw reply

* [PATCH] sysfs: add BIN_ATTR_WO() macro
From: Greg Kroah-Hartman @ 2019-08-26 15:01 UTC (permalink / raw)
  To: Nayna
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, Nayna Jain, linux-kernel,
	Mimi Zohar, Claudio Carvalho, Matthew Garret, linuxppc-dev,
	Paul Mackerras, Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <ff9674e1-1b27-783a-38f3-4fd725353186@linux.vnet.ibm.com>

This variant was missing from sysfs.h, I guess no one noticed it before.

Turns out the powerpc secure variable code can use it, so add it to the
tree for it, and potentially others to take advantage of, instead of
open-coding it.

Reported-by: Nayna Jain <nayna@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---

I'll queue this up to my tree for 5.4-rc1, but if you want to take this
in your tree earlier, feel free to do so.

 include/linux/sysfs.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 965236795750..5420817ed317 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -196,6 +196,12 @@ struct bin_attribute {
 	.size	= _size,						\
 }
 
+#define __BIN_ATTR_WO(_name) {						\
+	.attr	= { .name = __stringify(_name), .mode = 0200 },		\
+	.store	= _name##_store,					\
+	.size	= _size,						\
+}
+
 #define __BIN_ATTR_RW(_name, _size)					\
 	__BIN_ATTR(_name, 0644, _name##_read, _name##_write, _size)
 
@@ -208,6 +214,9 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR(_name, _mode, _read,	\
 #define BIN_ATTR_RO(_name, _size)					\
 struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size)
 
+#define BIN_ATTR_WO(_name, _size)					\
+struct bin_attribute bin_attr_##_name = __BIN_ATTR_WO(_name, _size)
+
 #define BIN_ATTR_RW(_name, _size)					\
 struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
 
-- 
2.23.0


^ permalink raw reply related

* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Greg Kroah-Hartman @ 2019-08-26 14:56 UTC (permalink / raw)
  To: Nayna Jain
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
	Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
	Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <1566825818-9731-3-git-send-email-nayna@linux.ibm.com>

On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
> +static struct kobj_attribute size_attr = __ATTR_RO(size);

Wait, why not just normal ATTR_RO()?

> +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, VARIABLE_MAX_SIZE);

And BIN_ATTR_RO() here?

Do those not work for you somehow?

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH v2 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 13:26 UTC (permalink / raw)
  To: Oliver O'Halloran, Nayna Jain, linuxppc-dev, linux-efi,
	linux-integrity
  Cc: Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
	Claudio Carvalho, Matthew Garret, Greg Kroah-Hartman,
	Paul Mackerras, Jeremy Kerr, Elaine Palmer, George Wilson
In-Reply-To: <23135466fc524a13cd76532ec59f84de51152a1c.camel@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 8538 bytes --]



On 08/22/2019 01:18 AM, Oliver O'Halloran wrote:
> On Wed, 2019-08-21 at 11:08 -0400, Nayna Jain wrote:
>> PowerNV secure variables, which store the keys used for OS kernel
>> verification, are managed by the firmware. These secure variables need to
>> be accessed by the userspace for addition/deletion of the certificates.
>>
>> This patch adds the sysfs interface to expose secure variables for PowerNV
>> secureboot. The users shall use this interface for manipulating
>> the keys stored in the secure variables.
>>
>> Signed-off-by: Nayna Jain<nayna@linux.ibm.com>
>> ---
>>   Documentation/ABI/testing/sysfs-secvar |  27 ++++
>>   arch/powerpc/Kconfig                   |   9 ++
>>   arch/powerpc/kernel/Makefile           |   1 +
>>   arch/powerpc/kernel/secvar-sysfs.c     | 210 +++++++++++++++++++++++++
>>   4 files changed, 247 insertions(+)
>>   create mode 100644 Documentation/ABI/testing/sysfs-secvar
>>   create mode 100644 arch/powerpc/kernel/secvar-sysfs.c
>>
>> diff --git a/Documentation/ABI/testing/sysfs-secvar b/Documentation/ABI/testing/sysfs-secvar
>> new file mode 100644
>> index 000000000000..68f0e03d873d
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-secvar
>> @@ -0,0 +1,27 @@
>> +What:		/sys/firmware/secvar
>> +Date:		August 2019
>> +Contact:	Nayna Jain<nayna@linux.ibm.com>
>> +Description:
>> +		This directory exposes interfaces for interacting with
>> +		the secure variables managed by OPAL firmware.
>> +
>> +		This is only for the powerpc/powernv platform.
>> +
>> +		Directory:
>> +		vars:		This directory lists all the variables that
>> +				are supported by the OPAL. The variables are
>> +				represented in the form of directories with
>> +				their variable names. The variable name is
>> +				unique and is in ASCII representation. The data
>> +				and size can be determined by reading their
>> +				respective attribute files.
>> +
>> +		Each variable directory has the following files:
>> +		name:		An ASCII representation of the variable name
>> +		data:		A read-only file containing the value of the
>> +				variable
>> +		size:		An integer representation of the size of the
>> +				content of the variable. In other works, it
>> +				represents the size of the data
>> +		update:		A write-only file that is used to submit the new
>> +				value for the variable.
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 42109682b727..b4bdf77837b2 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -925,6 +925,15 @@ config PPC_SECURE_BOOT
>>   	  allows user to enable OS Secure Boot on PowerPC systems that
>>   	  have firmware secure boot support.
>>   
>> +config SECVAR_SYSFS
>> +        tristate "Enable sysfs interface for POWER secure variables"
>> +        depends on PPC_SECURE_BOOT
>> +        help
>> +          POWER secure variables are managed and controlled by firmware.
>> +          These variables are exposed to userspace via sysfs to enable
>> +          read/write operations on these variables. Say Y if you have
>> +	  secure boot enabled and want to expose variables to userspace.
>> +
>>   endmenu
>>   
>>   config ISA_DMA_API
>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>> index 9041563f1c74..4ea7b738c3a3 100644
>> --- a/arch/powerpc/kernel/Makefile
>> +++ b/arch/powerpc/kernel/Makefile
>> @@ -158,6 +158,7 @@ obj-$(CONFIG_EPAPR_PARAVIRT)	+= epapr_paravirt.o epapr_hcalls.o
>>   obj-$(CONFIG_KVM_GUEST)		+= kvm.o kvm_emul.o
>>   
>>   obj-$(CONFIG_PPC_SECURE_BOOT)	+= secboot.o ima_arch.o secvar-ops.o
>> +obj-$(CONFIG_SECVAR_SYSFS)     += secvar-sysfs.o
>>   
>>   # Disable GCOV, KCOV & sanitizers in odd or sensitive code
>>   GCOV_PROFILE_prom_init.o := n
>> diff --git a/arch/powerpc/kernel/secvar-sysfs.c b/arch/powerpc/kernel/secvar-sysfs.c
>> new file mode 100644
>> index 000000000000..e46986bb29a0
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/secvar-sysfs.c
>> @@ -0,0 +1,210 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 IBM Corporation<nayna@linux.ibm.com>
>> + *
>> + * This code exposes secure variables to user via sysfs
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/compat.h>
>> +#include <linux/string.h>
>> +#include <asm/opal.h>
>> +#include <asm/secvar.h>
>> +
>> +//Approximating it for now, it is bound to change.
>> +#define VARIABLE_MAX_SIZE  32000
> this needs to be communicated from the secvar backend, maybe via a
> field in the ops structure?

Thanks Oliver, I have just posted v3 version which includes yours and 
Greg's feedbacks.
And giving some of the responses here.
Yes for this one,  thinking of doing it via device-tree as they will be 
fixed values for a particular platform

>> +
>> +static struct kobject *powerpc_kobj;
> Call it secvar_kobj or something.
>
>> +static struct secvar_operations *secvarops;
> Ah, the old I-can't-believe-it's-not-global trick.
>
>> +struct kset *secvar_kset;
> shouldn't that be static too?
>
>> +
>> +static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr,
>> +			 char *buf)
>> +{
>> +	return sprintf(buf, "%s", kobj->name);
>> +}
>> +
>> +static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr,
>> +			 char *buf)
>> +{
>> +	unsigned long dsize;
>> +	int rc;
>> +
>> +	rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> +				     &dsize);
>> +	if (rc) {
>> +		pr_err("Error retrieving variable size %d\n", rc);
>> +		return rc;
>> +	}
>> +
>> +	rc = sprintf(buf, "%ld", dsize);
>> +
>> +	return rc;
>> +}
>> +
>> +static ssize_t data_read(struct file *filep, struct kobject *kobj,
>> +			 struct bin_attribute *attr, char *buf, loff_t off,
>> +			 size_t count)
>> +{
>> +	unsigned long dsize;
>> +	int rc;
>> +	char *data;
>> +
>> +	rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> +				     &dsize);
>> +	if (rc) {
>> +		pr_err("Error getting variable size %d\n", rc);
>> +		return rc;
>> +	}
>> +	pr_debug("dsize is %ld\n", dsize);
>> +
>> +	data = kzalloc(dsize, GFP_KERNEL);
>> +	if (!data)
>> +		return -ENOMEM;
>> +
>> +	rc = secvarops->get_variable(kobj->name, strlen(kobj->name)+1, data,
>> +				     &dsize);
>> +	if (rc) {
>> +		pr_err("Error getting variable %d\n", rc);
>> +		goto data_fail;
>> +	}
>> +
>> +	rc = memory_read_from_buffer(buf, count, &off, data, dsize);
>> +
>> +data_fail:
>> +	kfree(data);
>> +	return rc;
>> +}
>> +
>> +static ssize_t update_write(struct file *filep, struct kobject *kobj,
>> +			    struct bin_attribute *attr, char *buf, loff_t off,
>> +			    size_t count)
>> +{
>> +	int rc;
>> +
>> +	pr_debug("count is %ld\n", count);
>> +	rc = secvarops->set_variable(kobj->name, strlen(kobj->name)+1, buf,
>> +				     count);
>> +	if (rc) {
>> +		pr_err("Error setting the variable %s\n", kobj->name);
>> +		return rc;
>> +	}
>> +
>> +	return count;
>> +}
>> +
>> +static struct kobj_attribute name_attr =
>> +__ATTR(name, 0444, name_show, NULL);
>> +
>> +static struct kobj_attribute size_attr =
>> +__ATTR(size, 0444, size_show, NULL);
>> +
>> +static struct bin_attribute data_attr = {
>> +	.attr = {.name = "data", .mode = 0444},
>> +	.size = VARIABLE_MAX_SIZE,
>> +	.read = data_read,
>> +};
> Should they be globally readable? If efivars is globally readable I'm
> happy to follow that example, but mpe might have opinions.

efivars are globally readable.


>> +
>> +
>> +static struct bin_attribute update_attr = {
>> +	.attr = {.name = "update", .mode = 0200},
>> +	.size = VARIABLE_MAX_SIZE,
>> +	.write = update_write,
>> +};
>> +
>> +static struct bin_attribute  *secvar_bin_attrs[] = {
>> +	&data_attr,
>> +	&update_attr,
>> +	NULL,
>> +};
>> +
>> +static struct attribute *secvar_attrs[] = {
>> +	&name_attr.attr,
>> +	&size_attr.attr,
>> +	NULL,
>> +};
>> +
>> +const struct attribute_group secvar_attr_group = {
>> +	.attrs = secvar_attrs,
>> +	.bin_attrs = secvar_bin_attrs,
>> +};
>> +
>> +int secvar_sysfs_load(void)
>> +{
>> +
>> +	char *name;
>> +	unsigned long namesize;
>> +	struct kobject *kobj;
>> +	int status;
>> +	int rc = 0;
>> +
>> +	name = kzalloc(1024, GFP_KERNEL);
>> +	if (!name)
>> +		return -ENOMEM;
> Where'd the 1024 restriction on the length of the variable name come
> from? is that enforced by firmware? If so, how does firmware
> communicate the limited key length?

It is not enforced by the firmware. Currently, it is sort of agreed upon 
value between the firmware and the kernel, and taken from the examples 
of efivars. Probably it can be reduced.


[-- Attachment #2: Type: text/html, Size: 9617 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 13:25 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Nayna Jain
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
	Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
	Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <20190821163018.GA28571@kroah.com>

[-- Attachment #1: Type: text/plain, Size: 9104 bytes --]



On 08/21/2019 12:30 PM, Greg Kroah-Hartman wrote:
> On Wed, Aug 21, 2019 at 11:08:21AM -0400, Nayna Jain wrote:
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-secvar
>> @@ -0,0 +1,27 @@
>> +What:		/sys/firmware/secvar
>> +Date:		August 2019
>> +Contact:	Nayna Jain<nayna@linux.ibm.com>
>> +Description:
>> +		This directory exposes interfaces for interacting with
>> +		the secure variables managed by OPAL firmware.
>> +
>> +		This is only for the powerpc/powernv platform.
>> +
>> +		Directory:
>> +		vars:		This directory lists all the variables that
>> +				are supported by the OPAL. The variables are
>> +				represented in the form of directories with
>> +				their variable names. The variable name is
>> +				unique and is in ASCII representation. The data
>> +				and size can be determined by reading their
>> +				respective attribute files.
>> +
>> +		Each variable directory has the following files:
>> +		name:		An ASCII representation of the variable name
>> +		data:		A read-only file containing the value of the
>> +				variable
>> +		size:		An integer representation of the size of the
>> +				content of the variable. In other works, it
>> +				represents the size of the data
>> +		update:		A write-only file that is used to submit the new
>> +				value for the variable.
> Can you break this out into one-entry-per-file like most other entries
> are defined?  That makes it easier for tools to parse (specifically the
> tool in the tree right now...)
>
>
>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 42109682b727..b4bdf77837b2 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -925,6 +925,15 @@ config PPC_SECURE_BOOT
>>   	  allows user to enable OS Secure Boot on PowerPC systems that
>>   	  have firmware secure boot support.
>>   
>> +config SECVAR_SYSFS
>> +        tristate "Enable sysfs interface for POWER secure variables"
>> +        depends on PPC_SECURE_BOOT
> No depends on SYSFS?
>
>> +        help
>> +          POWER secure variables are managed and controlled by firmware.
>> +          These variables are exposed to userspace via sysfs to enable
>> +          read/write operations on these variables. Say Y if you have
>> +	  secure boot enabled and want to expose variables to userspace.
> Mix of tabs and spaces :(
>
>> +
>>   endmenu
>>   
>>   config ISA_DMA_API
>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>> index 9041563f1c74..4ea7b738c3a3 100644
>> --- a/arch/powerpc/kernel/Makefile
>> +++ b/arch/powerpc/kernel/Makefile
>> @@ -158,6 +158,7 @@ obj-$(CONFIG_EPAPR_PARAVIRT)	+= epapr_paravirt.o epapr_hcalls.o
>>   obj-$(CONFIG_KVM_GUEST)		+= kvm.o kvm_emul.o
>>   
>>   obj-$(CONFIG_PPC_SECURE_BOOT)	+= secboot.o ima_arch.o secvar-ops.o
>> +obj-$(CONFIG_SECVAR_SYSFS)     += secvar-sysfs.o
> No tab?
>
>>   
>>   # Disable GCOV, KCOV & sanitizers in odd or sensitive code
>>   GCOV_PROFILE_prom_init.o := n
>> diff --git a/arch/powerpc/kernel/secvar-sysfs.c b/arch/powerpc/kernel/secvar-sysfs.c
>> new file mode 100644
>> index 000000000000..e46986bb29a0
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/secvar-sysfs.c
>> @@ -0,0 +1,210 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 IBM Corporation<nayna@linux.ibm.com>
>> + *
>> + * This code exposes secure variables to user via sysfs
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/compat.h>
>> +#include <linux/string.h>
>> +#include <asm/opal.h>
>> +#include <asm/secvar.h>
>> +
>> +//Approximating it for now, it is bound to change.
> " " before "A" here please.
>
>> +#define VARIABLE_MAX_SIZE  32000
>> +
>> +static struct kobject *powerpc_kobj;
>> +static struct secvar_operations *secvarops;
>> +struct kset *secvar_kset;
>> +
>> +static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr,
>> +			 char *buf)
>> +{
>> +	return sprintf(buf, "%s", kobj->name);
>> +}
> Why do you need this entry as it is the directory name?  Userspace
> already "knows" it if they can open this file.
>
>
>> +
>> +static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr,
>> +			 char *buf)
>> +{
>> +	unsigned long dsize;
>> +	int rc;
>> +
>> +	rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> +				     &dsize);
>> +	if (rc) {
>> +		pr_err("Error retrieving variable size %d\n", rc);
>> +		return rc;
>> +	}
>> +
>> +	rc = sprintf(buf, "%ld", dsize);
>> +
>> +	return rc;
>> +}
>> +
>> +static ssize_t data_read(struct file *filep, struct kobject *kobj,
>> +			 struct bin_attribute *attr, char *buf, loff_t off,
>> +			 size_t count)
>> +{
>> +	unsigned long dsize;
>> +	int rc;
>> +	char *data;
>> +
>> +	rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> +				     &dsize);
>> +	if (rc) {
>> +		pr_err("Error getting variable size %d\n", rc);
>> +		return rc;
>> +	}
>> +	pr_debug("dsize is %ld\n", dsize);
>> +
>> +	data = kzalloc(dsize, GFP_KERNEL);
>> +	if (!data)
>> +		return -ENOMEM;
>> +
>> +	rc = secvarops->get_variable(kobj->name, strlen(kobj->name)+1, data,
>> +				     &dsize);
>> +	if (rc) {
>> +		pr_err("Error getting variable %d\n", rc);
>> +		goto data_fail;
>> +	}
>> +
>> +	rc = memory_read_from_buffer(buf, count, &off, data, dsize);
>> +
>> +data_fail:
>> +	kfree(data);
>> +	return rc;
>> +}
>> +
>> +static ssize_t update_write(struct file *filep, struct kobject *kobj,
>> +			    struct bin_attribute *attr, char *buf, loff_t off,
>> +			    size_t count)
>> +{
>> +	int rc;
>> +
>> +	pr_debug("count is %ld\n", count);
>> +	rc = secvarops->set_variable(kobj->name, strlen(kobj->name)+1, buf,
>> +				     count);
>> +	if (rc) {
>> +		pr_err("Error setting the variable %s\n", kobj->name);
>> +		return rc;
>> +	}
>> +
>> +	return count;
>> +}
>> +
>> +static struct kobj_attribute name_attr =
>> +__ATTR(name, 0444, name_show, NULL);
> __ATTR_RO()?
>
>> +
>> +static struct kobj_attribute size_attr =
>> +__ATTR(size, 0444, size_show, NULL);
> __ATTR_RO()?
>
>> +
>> +static struct bin_attribute data_attr = {
>> +	.attr = {.name = "data", .mode = 0444},
>> +	.size = VARIABLE_MAX_SIZE,
>> +	.read = data_read,
>> +};
> __BIN_ATTR_RO()?
>
>> +
>> +
>> +static struct bin_attribute update_attr = {
>> +	.attr = {.name = "update", .mode = 0200},
>> +	.size = VARIABLE_MAX_SIZE,
>> +	.write = update_write,
>> +};
> __BIN_ATTR_RO()?
>
>
>> +
>> +static struct bin_attribute  *secvar_bin_attrs[] = {
>> +	&data_attr,
>> +	&update_attr,
>> +	NULL,
>> +};
>> +
>> +static struct attribute *secvar_attrs[] = {
>> +	&name_attr.attr,
>> +	&size_attr.attr,
>> +	NULL,
>> +};
>> +
>> +const struct attribute_group secvar_attr_group = {
>> +	.attrs = secvar_attrs,
>> +	.bin_attrs = secvar_bin_attrs,
>> +};
> static?
>
>> +
>> +int secvar_sysfs_load(void)
>> +{
>> +
>> +	char *name;
> No blank line.  You didn't run this this through checkpatch, did you :(
>
>
>> +	unsigned long namesize;
>> +	struct kobject *kobj;
>> +	int status;
>> +	int rc = 0;
>> +
>> +	name = kzalloc(1024, GFP_KERNEL);
> Why 1024?
>
>> +	if (!name)
>> +		return -ENOMEM;
>> +
>> +	do {
>> +
>> +		status = secvarops->get_next_variable(name, &namesize, 1024);
>> +		if (status != OPAL_SUCCESS)
>> +			break;
>> +
>> +		pr_info("name is %s\n", name);
> Please delete debugging messages.
>
>> +		kobj = kobject_create_and_add(name, &(secvar_kset->kobj));
>> +		if (kobj) {
>> +			rc = sysfs_create_group(kobj, &secvar_attr_group);
> You just raced userspace and lost :(
>
> If you set your kobj_type to have the attribute group you will not race
> and loose, the core will handle it for you.
>
>
>> +			if (rc)
>> +				pr_err("Error creating attributes for %s variable\n",
>> +				name);
>> +		} else {
>> +			pr_err("Error creating sysfs entry for %s variable\n",
>> +				name);
>> +			rc = -EINVAL;
>> +		}
>> +
>> +	} while ((status == OPAL_SUCCESS) && (rc == 0));
>> +
>> +	kfree(name);
>> +	return rc;
>> +}
>> +
>> +int secvar_sysfs_init(void)
>> +{
>> +	powerpc_kobj = kobject_create_and_add("secvar", firmware_kobj);
>> +	if (!powerpc_kobj) {
>> +		pr_err("secvar: Failed to create firmware kobj\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	secvar_kset = kset_create_and_add("vars", NULL, powerpc_kobj);
>> +	if (!secvar_kset) {
>> +		pr_err("secvar: sysfs kobject registration failed.\n");
> You juat leaked a kobject :(
>
>> +		return -ENODEV;
>> +	}
>> +
>> +	secvarops = get_secvar_ops();
>> +	if (!secvarops) {
>> +		kobject_put(powerpc_kobj);
>> +		pr_err("secvar: failed to retrieve secvar operations.\n");
>> +		return -ENODEV;
> You just leaked 2 things from above :(
>
>> +	}
>> +
>> +	secvar_sysfs_load();
>> +	pr_info("Secure variables sysfs initialized");
> Do not be noisy when all goes just fine.  The kernel log should be quiet
> when all goes well.
>

Thanks Greg for feedback. I just posted v3 version with the fixes 
suggested by you and Oliver.

Currently, the name length as 1024 is taken from examples of efivars. 
Probably a smaller one is fine.
In v3 version, it is still 1024 but made it #define.

Thanks & Regards,
       - Nayna


[-- Attachment #2: Type: text/html, Size: 10858 bytes --]

^ permalink raw reply

* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 14:12 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Nayna Jain
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
	Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
	Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <20190826140131.GA15270@kroah.com>



On 08/26/2019 10:01 AM, Greg Kroah-Hartman wrote:
> On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
>> +static struct bin_attribute update_attr = {
>> +	.attr = {.name = "update", .mode = 0200},
>> +	.size = VARIABLE_MAX_SIZE,
>> +	.write = update_write,
>> +};
> Ah, do we need a __BIN_ATTR_WO() macro for you?  That would make this
> more obvious, right?

Thanks Greg.  Yes, I agree it will be good to have that.

Thanks & Regards,
      - Nayna


^ permalink raw reply

* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Greg Kroah-Hartman @ 2019-08-26 14:01 UTC (permalink / raw)
  To: Nayna Jain
  Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
	Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
	Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
	linux-integrity, George Wilson
In-Reply-To: <1566825818-9731-3-git-send-email-nayna@linux.ibm.com>

On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
> +static struct bin_attribute update_attr = {
> +	.attr = {.name = "update", .mode = 0200},
> +	.size = VARIABLE_MAX_SIZE,
> +	.write = update_write,
> +};

Ah, do we need a __BIN_ATTR_WO() macro for you?  That would make this
more obvious, right?

Other than that minor thing (not a complaint at all) looks much better
to me, nice work:

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply

* Re: [PATCH] powerpc/time: use feature fixup in __USE_RTC() instead of cpu feature.
From: Christophe Leroy @ 2019-08-26 13:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Michael Ellerman, Paul Mackerras
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <60da7620a43dc29317a062f1d58dcfde8d32b258.camel@kernel.crashing.org>



Le 26/08/2019 à 15:25, Benjamin Herrenschmidt a écrit :
> On Mon, 2019-08-26 at 21:41 +1000, Michael Ellerman wrote:
>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>> sched_clock(), used by printk(), calls __USE_RTC() to know
>>> whether to use realtime clock or timebase.
>>>
>>> __USE_RTC() uses cpu_has_feature() which is initialised by
>>> machine_init(). Before machine_init(), __USE_RTC() returns true,
>>> leading to a program check exception on CPUs not having realtime
>>> clock.
>>>
>>> In order to be able to use printk() earlier, use feature fixup.
>>> Feature fixups are applies in early_init(), enabling the use of
>>> printk() earlier.
>>>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>> ---
>>>   arch/powerpc/include/asm/time.h | 9 ++++++++-
>>>   1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> The other option would be just to make this a compile time decision, eg.
>> add CONFIG_PPC_601 and use that to gate whether we use RTC.
>>
>> Given how many 601 users there are, maybe 1?, I think that would be a
>> simpler option and avoids complicating the code / binary for everyone
>> else.
> 
> Didn't we ditch 601 support years ago anyway ? We had workaround we
> threw out I think...

There are still workarounds for 601 in the kernel, for exemple (in 
arch/powerpc/include/asm/ppc_asm.h)

/* various errata or part fixups */
#ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC				\
BEGIN_FTR_SECTION			\
	sync;				\
	isync;				\
END_FTR_SECTION_IFSET(CPU_FTR_601)
#define SYNC_601			\
BEGIN_FTR_SECTION			\
	sync;				\
END_FTR_SECTION_IFSET(CPU_FTR_601)
#define ISYNC_601			\
BEGIN_FTR_SECTION			\
	isync;				\
END_FTR_SECTION_IFSET(CPU_FTR_601)
#else
#define	SYNC
#define SYNC_601
#define ISYNC_601
#endif

But if you think we can get rid of 601 completely, I'm happy with that.

Christophe


> 
> Cheers,
> Ben.
> 
>> cheers
>>
>>> diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
>>> index 54f4ec1f9fab..3455cb54c333 100644
>>> --- a/arch/powerpc/include/asm/time.h
>>> +++ b/arch/powerpc/include/asm/time.h
>>> @@ -42,7 +42,14 @@ struct div_result {
>>>   /* Accessor functions for the timebase (RTC on 601) registers. */
>>>   /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
>>>   #ifdef CONFIG_PPC_BOOK3S_32
>>> -#define __USE_RTC()	(cpu_has_feature(CPU_FTR_USE_RTC))
>>> +static inline bool __USE_RTC(void)
>>> +{
>>> +	asm_volatile_goto(ASM_FTR_IFCLR("nop;", "b %1;", %0) ::
>>> +			  "i" (CPU_FTR_USE_RTC) :: l_use_rtc);
>>> +	return false;
>>> +l_use_rtc:
>>> +	return true;
>>> +}
>>>   #else
>>>   #define __USE_RTC()	0
>>>   #endif
>>> -- 
>>> 2.13.3

^ permalink raw reply

* [PATCH 6/6] MIPS: document mixing "slightly different CCAs"
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
  To: iommu
  Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
	linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
	Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
	linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>

Based on an email from Paul Burton, quoting section 4.8 "Cacheability and
Coherency Attributes and Access Types" of "MIPS Architecture Volume 1:
Introduction to the MIPS32 Architecture" (MD00080, revision 6.01).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/mips/Kconfig | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index fc88f68ea1ee..aff1cadeea43 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,6 +1119,13 @@ config DMA_PERDEV_COHERENT
 
 config DMA_NONCOHERENT
 	bool
+	#
+	# MIPS allows mixing "slightly different" Cacheability and Coherency
+	# Attribute bits.  It is believed that the uncached access through
+	# KSEG1 and the implementation specific "uncached accelerated" used
+	# by pgprot_writcombine can be mixed, and the latter sometimes provides
+	# significant advantages.
+	#
 	select ARCH_HAS_DMA_WRITE_COMBINE
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
 	select ARCH_HAS_UNCACHED_SEGMENT
-- 
2.20.1


^ permalink raw reply related

* [PATCH 5/6] arm64: document the choice of page attributes for pgprot_dmacoherent
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
  To: iommu
  Cc: Mark Rutland, Shawn Anastasio, Will Deacon, linux-m68k,
	Guan Xuetao, linuxppc-dev, linux-kernel, Russell King, linux-mips,
	Paul Burton, Geert Uytterhoeven, Catalin Marinas, James Hogan,
	Robin Murphy, linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>

Based on an email from Will Deacon.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
 arch/arm64/include/asm/pgtable.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6700371227d1..fd40fb05eb51 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,14 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define pgprot_device(prot) \
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+/*
+ * DMA allocations for non-coherent devices use what the Arm architecture calls
+ * "Normal non-cacheable" memory, which permits speculation, unaligned accesses
+ * and merging of writes.  This is different from "Device-nGnR[nE]" memory which
+ * is intended for MMIO and thus forbids speculation, preserves access size,
+ * requires strict alignment and can also force write responses to come from the
+ * endpoint.
+ */
 #define pgprot_dmacoherent(prot) \
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
 			PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
-- 
2.20.1


^ permalink raw reply related

* [PATCH 4/6] dma-mapping: make dma_atomic_pool_init self-contained
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
  To: iommu
  Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
	linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
	Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
	linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>

The memory allocated for the atomic pool needs to have the same
mapping attributes that we use for remapping, so use
pgprot_dmacoherent instead of open coding it.  Also deduct a
suitable zone to allocate the memory from based on the presence
of the DMA zones.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arc/mm/dma.c           |  6 ------
 arch/arm64/mm/dma-mapping.c |  6 ------
 arch/csky/mm/dma-mapping.c  |  6 ------
 arch/nds32/kernel/dma.c     |  6 ------
 include/linux/dma-mapping.h |  1 -
 kernel/dma/remap.c          | 17 ++++++++++++++---
 6 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 62c210e7ee4c..ff4a5752f8cc 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -104,9 +104,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	dev_info(dev, "use %sncoherent DMA ops\n",
 		 dev->dma_coherent ? "" : "non");
 }
-
-static int __init atomic_pool_init(void)
-{
-	return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 676efcda51e6..a1d05f669f67 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -28,12 +28,6 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 	__dma_flush_area(page_address(page), size);
 }
 
-static int __init arm64_dma_init(void)
-{
-	return dma_atomic_pool_init(GFP_DMA32, __pgprot(PROT_NORMAL_NC));
-}
-arch_initcall(arm64_dma_init);
-
 #ifdef CONFIG_IOMMU_DMA
 void arch_teardown_dma_ops(struct device *dev)
 {
diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c
index 80783bb71c5c..602a60d47a94 100644
--- a/arch/csky/mm/dma-mapping.c
+++ b/arch/csky/mm/dma-mapping.c
@@ -14,12 +14,6 @@
 #include <linux/version.h>
 #include <asm/cache.h>
 
-static int __init atomic_pool_init(void)
-{
-	return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
-
 void arch_dma_prep_coherent(struct page *page, size_t size)
 {
 	if (PageHighMem(page)) {
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index 490e3720d694..4206d4b6c8ce 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -80,9 +80,3 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 {
 	cache_op(page_to_phys(page), size, cpu_dma_wbinval_range);
 }
-
-static int __init atomic_pool_init(void)
-{
-	return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..48ebe8295987 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -624,7 +624,6 @@ void *dma_common_pages_remap(struct page **pages, size_t size,
 			const void *caller);
 void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
 
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot);
 bool dma_in_atomic_pool(void *start, size_t size);
 void *dma_alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags);
 bool dma_free_from_pool(void *start, size_t size);
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c
index ffe78f0b2fe4..838123f79639 100644
--- a/kernel/dma/remap.c
+++ b/kernel/dma/remap.c
@@ -105,7 +105,16 @@ static int __init early_coherent_pool(char *p)
 }
 early_param("coherent_pool", early_coherent_pool);
 
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
+static gfp_t dma_atomic_pool_gfp(void)
+{
+	if (IS_ENABLED(CONFIG_ZONE_DMA))
+		return GFP_DMA;
+	if (IS_ENABLED(CONFIG_ZONE_DMA32))
+		return GFP_DMA32;
+	return GFP_KERNEL;
+}
+
+static int __init dma_atomic_pool_init(void)
 {
 	unsigned int pool_size_order = get_order(atomic_pool_size);
 	unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
@@ -117,7 +126,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
 		page = dma_alloc_from_contiguous(NULL, nr_pages,
 						 pool_size_order, false);
 	else
-		page = alloc_pages(gfp, pool_size_order);
+		page = alloc_pages(dma_atomic_pool_gfp(), pool_size_order);
 	if (!page)
 		goto out;
 
@@ -128,7 +137,8 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
 		goto free_page;
 
 	addr = dma_common_contiguous_remap(page, atomic_pool_size, VM_USERMAP,
-					   prot, __builtin_return_address(0));
+					   pgprot_dmacoherent(PAGE_KERNEL),
+					   __builtin_return_address(0));
 	if (!addr)
 		goto destroy_genpool;
 
@@ -155,6 +165,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
 		atomic_pool_size / 1024);
 	return -ENOMEM;
 }
+postcore_initcall(dma_atomic_pool_init);
 
 bool dma_in_atomic_pool(void *start, size_t size)
 {
-- 
2.20.1


^ permalink raw reply related

* [PATCH 3/6] dma-mapping: remove arch_dma_mmap_pgprot
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
  To: iommu
  Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
	linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
	Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
	linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>

arch_dma_mmap_pgprot is used for two things:

 1) to override the "normal" uncached page attributes for mapping
    memory coherent to devices that can't snoop the CPU caches
 2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
    arm systems and some mips platforms

Replace one with the pgprot_dmacoherent macro that is already provided
by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
handling to common code with an explicit arch opt-in.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/arm/Kconfig                   |  2 +-
 arch/arm/mm/dma-mapping.c          |  6 ------
 arch/arm64/Kconfig                 |  1 -
 arch/arm64/include/asm/pgtable.h   |  4 ++++
 arch/arm64/mm/dma-mapping.c        |  6 ------
 arch/m68k/Kconfig                  |  1 -
 arch/m68k/include/asm/pgtable_mm.h |  3 +++
 arch/m68k/kernel/dma.c             |  3 +--
 arch/mips/Kconfig                  |  2 +-
 arch/mips/mm/dma-noncoherent.c     |  8 --------
 include/linux/dma-noncoherent.h    | 13 +++++++++++--
 kernel/dma/Kconfig                 | 12 +++++++++---
 kernel/dma/mapping.c               |  8 +++++---
 13 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24360211534a..217083caeabd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,7 +8,7 @@ config ARM
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB
-	select ARCH_HAS_DMA_MMAP_PGPROT if SWIOTLB
+	select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KEEPINITRD
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..d27b12f61737 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2402,12 +2402,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
 	return dma_to_pfn(dev, dma_addr);
 }
 
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-		unsigned long attrs)
-{
-	return __get_dma_pgprot(attrs, prot);
-}
-
 void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		gfp_t gfp, unsigned long attrs)
 {
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..dab9dda34206 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -13,7 +13,6 @@ config ARM64
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_COHERENT_TO_PFN
-	select ARCH_HAS_DMA_MMAP_PGPROT
 	select ARCH_HAS_DMA_PREP_COHERENT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
 	select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index e09760ece844..6700371227d1 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,10 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define pgprot_device(prot) \
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+#define pgprot_dmacoherent(prot) \
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
+			PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index bd2b039f43a6..676efcda51e6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -11,12 +11,6 @@
 
 #include <asm/cacheflush.h>
 
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-		unsigned long attrs)
-{
-	return pgprot_writecombine(prot);
-}
-
 void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
 		size_t size, enum dma_data_direction dir)
 {
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index c518d695c376..a9e564306d3e 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,7 +4,6 @@ config M68K
 	default y
 	select ARCH_32BIT_OFF_T
 	select ARCH_HAS_BINFMT_FLAT
-	select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
 	select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
 	select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h
index fe3ddd73a0cc..fde4534b974f 100644
--- a/arch/m68k/include/asm/pgtable_mm.h
+++ b/arch/m68k/include/asm/pgtable_mm.h
@@ -169,6 +169,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
 	    ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S))	\
 	    : (prot)))
 
+pgprot_t pgprot_dmacoherent(pgprot_t prot);
+#define pgprot_dmacoherent(prot)	pgprot_dmacoherent(prot)
+
 #endif /* CONFIG_COLDFIRE */
 #include <asm-generic/pgtable.h>
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 30cd59caf037..35064150e348 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -23,8 +23,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 	cache_push(page_to_phys(page), size);
 }
 
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-		unsigned long attrs)
+pgprot_t pgprot_dmacoherent(pgprot_t prot)
 {
 	if (CPU_IS_040_OR_060) {
 		pgprot_val(prot) &= ~_PAGE_CACHE040;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d50fafd7bf3a..fc88f68ea1ee 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,7 +1119,7 @@ config DMA_PERDEV_COHERENT
 
 config DMA_NONCOHERENT
 	bool
-	select ARCH_HAS_DMA_MMAP_PGPROT
+	select ARCH_HAS_DMA_WRITE_COMBINE
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
 	select ARCH_HAS_UNCACHED_SEGMENT
 	select NEED_DMA_MAP_STATE
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index ed56c6fa7be2..1d4d57dd9acf 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -65,14 +65,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
 	return page_to_pfn(virt_to_page(cached_kernel_address(cpu_addr)));
 }
 
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-		unsigned long attrs)
-{
-	if (attrs & DMA_ATTR_WRITE_COMBINE)
-		return pgprot_writecombine(prot);
-	return pgprot_noncached(prot);
-}
-
 static inline void dma_sync_virt(void *addr, size_t size,
 		enum dma_data_direction dir)
 {
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index 0bff3d7fac92..dd3de6d88fc0 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -3,6 +3,7 @@
 #define _LINUX_DMA_NONCOHERENT_H 1
 
 #include <linux/dma-mapping.h>
+#include <asm/pgtable.h>
 
 #ifdef CONFIG_ARCH_HAS_DMA_COHERENCE_H
 #include <asm/dma-coherence.h>
@@ -42,10 +43,18 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs);
 long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
 		dma_addr_t dma_addr);
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-		unsigned long attrs);
 
 #ifdef CONFIG_MMU
+/*
+ * Page protection so that devices that can't snoop CPU caches can use the
+ * memory coherently.  We default to pgprot_noncached which is usually used
+ * for ioremap as a safe bet, but architectures can override this with less
+ * strict semantics if possible.
+ */
+#ifndef pgprot_dmacoherent
+#define pgprot_dmacoherent(prot)	pgprot_noncached(prot)
+#endif
+
 pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs);
 #else
 static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot,
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 9decbba255fc..73c5c2b8e824 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -20,6 +20,15 @@ config ARCH_HAS_DMA_COHERENCE_H
 config ARCH_HAS_DMA_SET_MASK
 	bool
 
+#
+# Select this option if the architecture needs special handling for
+# DMA_ATTR_WRITE_COMBINE.  Normally the "uncached" mapping should be what
+# people thing of when saying write combine, so very few platforms should
+# need to enable this.
+#
+config ARCH_HAS_DMA_WRITE_COMBINE
+	bool
+
 config DMA_DECLARE_COHERENT
 	bool
 
@@ -45,9 +54,6 @@ config ARCH_HAS_DMA_PREP_COHERENT
 config ARCH_HAS_DMA_COHERENT_TO_PFN
 	bool
 
-config ARCH_HAS_DMA_MMAP_PGPROT
-	bool
-
 config ARCH_HAS_FORCE_DMA_UNENCRYPTED
 	bool
 
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b0038ca3aa92..1b96616c9f20 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -161,9 +161,11 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
 	    (IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
              (attrs & DMA_ATTR_NON_CONSISTENT)))
 		return prot;
-	if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_MMAP_PGPROT))
-		return arch_dma_mmap_pgprot(dev, prot, attrs);
-	return pgprot_noncached(prot);
+#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINE
+	if (attrs & DMA_ATTR_WRITE_COMBINE)
+		return pgprot_writecombine(prot);
+#endif
+	return pgprot_dmacoherent(prot);
 }
 #endif /* CONFIG_MMU */
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH 2/6] arm-nommu: remove the unused pgprot_dmacoherent define
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
  To: iommu
  Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
	linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
	Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
	linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/include/asm/pgtable-nommu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
index 0b1f6799a32e..d0de24f06724 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -62,7 +62,6 @@ typedef pte_t *pte_addr_t;
  */
 #define pgprot_noncached(prot)	(prot)
 #define pgprot_writecombine(prot) (prot)
-#define pgprot_dmacoherent(prot) (prot)
 #define pgprot_device(prot)	(prot)
 
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH 1/6] unicore32: remove the unused pgprot_dmacoherent define
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
  To: iommu
  Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
	linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
	Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
	linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/unicore32/include/asm/pgtable.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/unicore32/include/asm/pgtable.h b/arch/unicore32/include/asm/pgtable.h
index 9492aa304f03..126e961a8cb0 100644
--- a/arch/unicore32/include/asm/pgtable.h
+++ b/arch/unicore32/include/asm/pgtable.h
@@ -198,8 +198,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 	__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
 #define pgprot_writecombine(prot)	\
 	__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
-#define pgprot_dmacoherent(prot)	\
-	__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define pmd_present(pmd)	(pmd_val(pmd) & PMD_PRESENT)
-- 
2.20.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox