[PATCH v3] arm: Support for the PXN CPU feature on ARMv7
Jungseung Lee
js07.lee at gmail.com
Wed Nov 26 17:32:25 PST 2014
2014-11-26 22:52 GMT+09:00 Russell King - ARM Linux <linux at arm.linux.org.uk>:
> On Wed, Nov 26, 2014 at 10:34:00PM +0900, Jungseung Lee wrote:
>> +/*
>> + * Once this call has completed the variable @vmsa is set to 'VMSA support'
>> + * in case of ARMv7.
>> + */
>> +static inline bool cpu_has_classic_pxn(void)
>> +{
>> + if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE)) {
>> + static unsigned int vmsa = ~0UL;
>> +
>> + if (cpu_architecture() != CPU_ARCH_ARMv7)
>> + return false;
>> + if (vmsa == 4)
>> + return true;
>> +
>> + vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0;
>> + return vmsa == 4;
>> + } else
>> + return false;
>> +}
>
> Take a moment to consider whether this should be an inline function. It's
> rather complex, involves calling out to a function, reading a variable,
> etc...
>
>> static inline void
>> pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
>> {
>> - __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE);
>> + pmdval_t pmdval = _PAGE_USER_TABLE;
>> +
>> + if (cpu_has_classic_pxn())
>> + pmdval |= PMD_PXNTABLE;
>> + __pmd_populate(pmdp, page_to_phys(ptep), pmdval);
>> }
>> #define pmd_pgtable(pmd) pmd_page(pmd)
>
> It's also used in another inline function.
>
> Now, consider if we did this:
>
> extern pmdval_t user_pmd_table;
>
> static inline void
> pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
> {
> __pmd_populate(pmdp, page_to_phys(ptep), user_pmd_table);
> }
>
> This means that pmd_populate() only has to load the value instead, which
> is far simpler. All the setup complexity can live in build_mem_type_table()
> which means that it only happens once, and we don't have to have checks
> in these paths to see whether we've done that.
>
> What would also be acceptable is to have the constant tests here, so the
> compiler can eliminate the unnecessary load when we have no hope of ever
> supporting PXN:
>
> static inline void
> pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
> {
> pmdval_t prot;
>
> if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE))
> prot = user_pmd_table;
> else
> prot = _PAGE_USER_TABLE;
>
> __pmd_populate(pmdp, page_to_phys(ptep), prot);
> }
>
Yes, that would be solution to make any redundant overhead.
I'll prepare patch including your suggestion.
thanks for review,
> --
> FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
> according to speedtest.net.
More information about the linux-arm-kernel
mailing list