[PATCH 2/2] riscv: mm: add pgprot_dmacoherent for zicbom

Ben Dooks ben.dooks at codethink.co.uk
Wed Mar 8 01:35:14 PST 2023


On 07/03/2023 20:58, Ben Dooks wrote:
> If the system uses both ZICBOM and SVPBMT then currently SVPBMT will be
> used for DMA allocated memory even though ZICBOM gives us the cache ops
> to use cached memory and clean/flush them as needed by the DMA code.
> 
> Fix this by adding pgprot_dmacoherent() which is used by the allocator
> code to map the dma memory, thus allowing the return of suitably mapped
> memory for any use of dma_alloc_attrs() code. This s uses the added
> riscv_page_dmacoherent() which will work out the correct page flags to
> return using ALT_SVPBMT_ZICBOM() to runtime patch the right result.
> 
> Note, we can't just disable SVPBMT as it will be neede for things like
> ioremap() which don't have assoicated cache management operations.
> 
> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
> ---
>   arch/riscv/include/asm/errata_list.h | 16 ++++++++++++++++
>   arch/riscv/include/asm/pgtable-64.h  | 10 ++++++++++
>   2 files changed, 26 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
> index fb1a810f3d8c..49ed2e7984a7 100644
> --- a/arch/riscv/include/asm/errata_list.h
> +++ b/arch/riscv/include/asm/errata_list.h
> @@ -62,6 +62,22 @@ asm(ALTERNATIVE_2("li %0, 0\t\nnop",					\
>   		  "I"(ALT_SVPBMT_SHIFT),				\
>   		  "I"(ALT_THEAD_PBMT_SHIFT))
>   
> +#define ALT_SVPBMT_ZICBOM(_val, prot)					\
> +asm(ALTERNATIVE_3("li %0, 0\t\nnop",					\
> +		  "li %0, %1\t\nslli %0,%0,%3", 0,			\
> +			RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,	\
> +		  "li %0, 0\t\nnop", 0,					\
> +			RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM,	\

so, I tink this needs to be selected on CONFIG_RISCV_DMA_NONCOHERENT
as just having ZICBOM in the ISA isn't enough to actually use it, you'll
need the dma-noncoherent.o being built to do the cache management.

> +		  "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID,	\
> +			ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)	\
> +		: "=r"(_val)						\
> +		: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),		\
> +		  "I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT),		\
> +		  "I"(ALT_SVPBMT_SHIFT),				\
> +		  "I"(ALT_THEAD_PBMT_SHIFT))
> +
> +
> +
>   #ifdef CONFIG_ERRATA_THEAD_PBMT
>   /*
>    * IO/NOCACHE memory types are handled together with svpbmt,
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 42a042c0e13e..e0d2e5fda5a4 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -126,10 +126,20 @@ static inline u64 riscv_page_io(void)
>   	return val;
>   }
>   
> +static inline u64 riscv_page_dmacoherent(void)
> +{
> +	u64 val;
> +
> +	ALT_SVPBMT_ZICBOM(val, _PAGE_IO);
> +	return val;
> +}
> +
>   #define _PAGE_NOCACHE		riscv_page_nocache()
>   #define _PAGE_IO		riscv_page_io()
>   #define _PAGE_MTMASK		riscv_page_mtmask()
>   
> +#define pgprot_dmacoherent(__prot) __pgprot(pgprot_val(__prot) | riscv_page_dmacoherent())
> +
>   /* Set of bits to preserve across pte_modify() */
>   #define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
>   					  _PAGE_WRITE | _PAGE_EXEC |	\

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html




More information about the linux-riscv mailing list