[RFC PATCH 1/2] arm64: Support execute-only permissions with Enhanced PAN

Catalin Marinas catalin.marinas at arm.com
Tue Nov 17 11:47:43 EST 2020


On Fri, Nov 13, 2020 at 03:20:22PM +0000, Vladimir Murzin wrote:
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 4ff12a7..d1f68d2 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -113,8 +113,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
>  #define pte_dirty(pte)		(pte_sw_dirty(pte) || pte_hw_dirty(pte))
>  
>  #define pte_valid(pte)		(!!(pte_val(pte) & PTE_VALID))
> -#define pte_valid_not_user(pte) \
> -	((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
> +#define pte_valid_not_user(pte)										\
> +({													\
> +	int __val;											\
> +	if (cpus_have_const_cap(ARM64_HAS_EPAN))							\
> +		__val = (pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN);	\
> +	else												\
> +		__val = (pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID;				\
> +	__val;												\

Is it worth having the cap check here? I'd go with the PTE_VALID|PTE_UXN
check only.

> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index dcc165b..2033e0b 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1602,6 +1602,13 @@ static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
>  }
>  #endif /* CONFIG_ARM64_PAN */
>  
> +#ifdef CONFIG_ARM64_EPAN
> +static void cpu_enable_epan(const struct arm64_cpu_capabilities *__unused)
> +{
> +	sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_EPAN);
> +}
> +#endif /* CONFIG_ARM64_EPAN */

I checked the spec (2020 arch updates) and the EPAN bit is permitted to
be cached in the TLB. I think we get away with this because this
function is called before cnp is enabled. Maybe we should make it
explicit and move the CnP entry last with a comment.

-- 
Catalin



More information about the linux-arm-kernel mailing list