Minor improvements to the compat vdso and sigpage
Subsystems (2)
Will Deacon
maintainercover Minor improvements to the compat vdso and sigpage
Hi all,
Here are a few small improvements to the compat vDSO and sigpage implementation for arm64 which I cooked up when comparing the code with the native 32-bit counterpart.
Cheers,
Will
--->8
Will Deacon (5):
arm64: vdso: Use GFP_KERNEL for allocating compat vdso and signal
pages
arm64: vdso: Remove redundant calls to flush_dcache_page()
arm64: compat: Allow signal page to be remapped
arm64: vdso: Avoid ISB after reading from cntvct_el0
arm64: compat: Poison the compat sigpage
arch/arm64/include/asm/arch_timer.h | 21 --------------------- arch/arm64/include/asm/barrier.h | 19 +++++++++++++++++++ arch/arm64/include/asm/vdso/gettimeofday.h | 6 +----- arch/arm64/kernel/vdso.c | 22 ++++++++++++++++------ 4 files changed, 36 insertions(+), 32 deletions(-)
Signature · 7 lines
2.31.0.rc2.261.g7f71774620-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 1/5 arm64: vdso: Use GFP_KERNEL for allocating compat vdso and signal pages
There's no need to allocate the compat vDSO and signal pages using GFP_ATOMIC allocations, so use GFP_KERNEL instead.
--- arch/arm64/kernel/vdso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/vdso.c +2 -2
@@ -299,7 +299,7 @@ static int aarch32_alloc_kuser_vdso_page(void)if (!IS_ENABLED (CONFIG_KUSER_HELPERS ))return 0 ; - vdso_page =get_zeroed_page (GFP_ATOMIC ); + vdso_page =get_zeroed_page (GFP_KERNEL );if (!vdso_page)return -ENOMEM ;
@@ -316,7 +316,7 @@ static int aarch32_alloc_sigpage(void)int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;unsigned long sigpage; - sigpage =get_zeroed_page (GFP_ATOMIC ); + sigpage =get_zeroed_page (GFP_KERNEL );if (!sigpage)return -ENOMEM ;
Signature · 7 lines
2.31.0.rc2.261.g7f71774620-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 1/5] arm64: vdso: Use GFP_KERNEL for allocating compat vdso and signal pages
Quoted 4 lines · Will Deacon
There's no need to allocate the compat vDSO and signal pages using
GFP_ATOMICallocations, so useGFP_KERNELinstead.Signed-off-by Will Deacon <[email protected]>
Nit: We could explain why GFP_KERNEL is sufficient in the commit message.
Otherwise:
Quoted 27 lines
--- arch/arm64/kernel/vdso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)arch/arm64/kernel/vdso.c +2
-2@@ -299,7 +299,7 @@ static int aarch32_alloc_kuser_vdso_page(void)if (!IS_ENABLED (CONFIG_KUSER_HELPERS ))return 0 ; - vdso_page =get_zeroed_page (GFP_ATOMIC ); + vdso_page =get_zeroed_page (GFP_KERNEL );if (!vdso_page)return -ENOMEM ;@@ -316,7 +316,7 @@ static int aarch32_alloc_sigpage(void)int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;unsigned long sigpage; - sigpage =get_zeroed_page (GFP_ATOMIC ); + sigpage =get_zeroed_page (GFP_KERNEL );if (!sigpage)return -ENOMEM ;
Signature · 7 lines
Regards, Vincenzo _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Catalin Marinas
maintainerRe: [PATCH 1/5] arm64: vdso: Use GFP_KERNEL for allocating compat vdso and signal pages
Quoted 7 lines · Vincenzo Frascino
Quoted 4 lines · Will Deacon
There's no need to allocate the compat vDSO and signal pages using
GFP_ATOMICallocations, so useGFP_KERNELinstead.Signed-off-by Will Deacon <[email protected]>Nit: We could explain why
GFP_KERNELis sufficient in the commit message.
Usually it's the other way around, document why GFP_ATOMIC is needed ;).
Signature · 6 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 2/5 arm64: vdso: Remove redundant calls to flush_dcache_page()
In reply to Will Deaconflush_dcache_page() ensures that the 'PG_dcache_clean' flag for its 'page' argument is clear so that cache maintenance will be performed if the page is mapped into userspace with execute permissions.
Newly allocated pages have this flag clear, so there is no need to call flush_dcache_page() for the compat vdso or signal pages. Remove the redundant calls.
--- arch/arm64/kernel/vdso.c | 2 -- 1 file changed, 2 deletions(-)
arch/arm64/kernel/vdso.c +0 -2
@@ -306,7 +306,6 @@ static int aarch32_alloc_kuser_vdso_page(void)memcpy ((void *)(vdso_page +0x1000 - kuser_sz), __kuser_helper_start, kuser_sz); aarch32_vectors_page =virt_to_page (vdso_page); -flush_dcache_page (aarch32_vectors_page);return 0 ; }
@@ -322,7 +321,6 @@ static int aarch32_alloc_sigpage(void)memcpy ((void *)sigpage, __aarch32_sigret_code_start, sigret_sz); aarch32_sig_page =virt_to_page (sigpage); -flush_dcache_page (aarch32_sig_page);return 0 ; }
Signature · 7 lines
2.31.0.rc2.261.g7f71774620-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 2/5] arm64: vdso: Remove redundant calls to flush_dcache_page()
Quoted 9 lines · Will Deacon
flush_dcache_page()ensures that the 'PG_dcache_clean' flag for its 'page' argument is clear so that cache maintenance will be performed if the page is mapped into userspace with execute permissions.Newly allocated pages have this flag clear, so there is no need to call
flush_dcache_page()for the compat vdso or signal pages. Remove the redundant calls.Signed-off-by Will Deacon <[email protected]>
Quoted 25 lines
--- arch/arm64/kernel/vdso.c | 2 -- 1 file changed, 2 deletions(-)arch/arm64/kernel/vdso.c +0
-2@@ -306,7 +306,6 @@ static int aarch32_alloc_kuser_vdso_page(void)memcpy ((void *)(vdso_page +0x1000 - kuser_sz), __kuser_helper_start, kuser_sz); aarch32_vectors_page =virt_to_page (vdso_page); -flush_dcache_page (aarch32_vectors_page);return 0 ; }@@ -322,7 +321,6 @@ static int aarch32_alloc_sigpage(void)memcpy ((void *)sigpage, __aarch32_sigret_code_start, sigret_sz); aarch32_sig_page =virt_to_page (sigpage); -flush_dcache_page (aarch32_sig_page);return 0 ; }
Signature · 7 lines
Regards, Vincenzo _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 3/5 arm64: compat: Allow signal page to be remapped
In reply to Will DeaconFor compatability with 32-bit Arm, allow the compat signal page to be remapped via mremap().
--- arch/arm64/kernel/vdso.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/arm64/kernel/vdso.c +9 -0
@@ -271,6 +271,14 @@ enum aarch32_map {static struct page *aarch32_vectors_page__ro_after_init ;static struct page *aarch32_sig_page__ro_after_init ; +static int aarch32_sigpage_mremap (const struct vm_special_mapping *sm, +struct vm_area_struct *new_vma) +{ + current->mm->context.sigpage = (void *)new_vma->vm_start; + +return 0 ; +} +static struct vm_special_mapping aarch32_vdso_maps[] = { [AA32_MAP_VECTORS ] = { .name ="[vectors]" ,/* ABI */
@@ -279,6 +287,7 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { [AA32_MAP_SIGPAGE] = { .name = "[sigpage]", /* ABI */ .pages = &aarch32_sig_page, + .mremap = aarch32_sigpage_mremap, }, [AA32_MAP_VVAR] = { .name = "[vvar]",
Signature · 7 lines
2.31.0.rc2.261.g7f71774620-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 3/5] arm64: compat: Allow signal page to be remapped
Quoted 4 lines · Will Deacon
For compatability with 32-bit Arm, allow the compat signal page to be remapped via
mremap().Signed-off-by Will Deacon <[email protected]>
Quoted 32 lines
--- arch/arm64/kernel/vdso.c | 9 +++++++++ 1 file changed, 9 insertions(+)arch/arm64/kernel/vdso.c +9
-0@@ -271,6 +271,14 @@ enum aarch32_map {static struct page *aarch32_vectors_page__ro_after_init ;static struct page *aarch32_sig_page__ro_after_init ; +static int aarch32_sigpage_mremap (const struct vm_special_mapping *sm, +struct vm_area_struct *new_vma) +{ + current->mm->context.sigpage = (void *)new_vma->vm_start; + +return 0 ; +} +static struct vm_special_mapping aarch32_vdso_maps[] = { [AA32_MAP_VECTORS ] = { .name ="[vectors]" ,/* ABI */ @@ -279,6 +287,7 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { [AA32_MAP_SIGPAGE] = { .name = "[sigpage]", /* ABI */ .pages = &aarch32_sig_page, + .mremap = aarch32_sigpage_mremap, }, [AA32_MAP_VVAR] = { .name = "[vvar]",
Signature · 7 lines
Regards, Vincenzo _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 4/5 arm64: vdso: Avoid ISB after reading from cntvct_el0
In reply to Will DeaconWe can avoid the expensive ISB instruction after reading the counter in the vDSO gettime functions by creating a fake address hazard against a dummy stack read, just like we do inside the kernel.
--- arch/arm64/include/asm/arch_timer.h | 21 --------------------- arch/arm64/include/asm/barrier.h | 19 +++++++++++++++++++ arch/arm64/include/asm/vdso/gettimeofday.h | 6 +----- 3 files changed, 20 insertions(+), 26 deletions(-)
arch/arm64/include/asm/arch_timer.h +0 -21
@@ -165,25 +165,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)isb (); } -/* -* Ensure that reads of the counter are treated the same as memory reads -* for the purposes of ordering by subsequent memory barriers. -* -* This insanity brought to you by speculative system register reads, -* out-of-order memory accesses, sequence locks and Thomas Gleixner. -* -* http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html -*/ -#define arch_counter_enforce_ordering (val) do { \ - u64 tmp, _val = (val); \ - \ - asm volatile( \ - " eor %0, %1, %1\n" \ - " add %0, sp, %0\n" \ - " ldr xzr, [%0]" \ - : "=r" (tmp) : "r" (_val)); \ -} while (0) - static __always_inline u64 __arch_counter_get_cntpct_stable(void) {u64 cnt;
@@ -224,8 +205,6 @@ static __always_inline u64 __arch_counter_get_cntvct(void)return cnt; } -#undef arch_counter_enforce_ordering -static inline int arch_timer_arch_init (void ) {return 0 ;
arch/arm64/include/asm/barrier.h +19 -0
@@ -70,6 +70,25 @@ static inline unsigned long array_index_mask_nospec(unsigned long idx,return mask; } +/* +* Ensure that reads of the counter are treated the same as memory reads +* for the purposes of ordering by subsequent memory barriers. +* +* This insanity brought to you by speculative system register reads, +* out-of-order memory accesses, sequence locks and Thomas Gleixner. +* +* http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html +*/ +#define arch_counter_enforce_ordering (val) do { \ + u64 tmp, _val = (val); \ + \ + asm volatile( \ + " eor %0, %1, %1\n" \ + " add %0, sp, %0\n" \ + " ldr xzr, [%0]" \ + : "=r" (tmp) : "r" (_val)); \ +} while (0) +#define __smp_mb () dmb(ish)#define __smp_rmb () dmb(ishld)#define __smp_wmb () dmb(ishst)
arch/arm64/include/asm/vdso/gettimeofday.h +1 -5
@@ -83,11 +83,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,*/ isb (); asmvolatile ("mrs %0, cntvct_el0" :"=r" (res) ::"memory" ); -/* -* This isb() is required to prevent that the seq lock is -* speculated.# -*/ -isb (); +arch_counter_enforce_ordering (res);return res; }
Signature · 7 lines
2.31.0.rc2.261.g7f71774620-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 4/5] arm64: vdso: Avoid ISB after reading from cntvct_el0
Quoted 5 lines · Will Deacon
We can avoid the expensive ISB instruction after reading the counter in the vDSO gettime functions by creating a fake address hazard against a dummy stack read, just like we do inside the kernel.
Signed-off-by Will Deacon <[email protected]>
Quoted 93 lines
--- arch/arm64/include/asm/arch_timer.h | 21 --------------------- arch/arm64/include/asm/barrier.h | 19 +++++++++++++++++++ arch/arm64/include/asm/vdso/gettimeofday.h | 6 +----- 3 files changed, 20 insertions(+), 26 deletions(-)arch/arm64/include/asm/arch_timer.h +0
-21@@ -165,25 +165,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)isb (); } -/* -* Ensure that reads of the counter are treated the same as memory reads -* for the purposes of ordering by subsequent memory barriers. -* -* This insanity brought to you by speculative system register reads, -* out-of-order memory accesses, sequence locks and Thomas Gleixner. -* -* http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html -*/ -#define arch_counter_enforce_ordering (val) do { \ - u64 tmp, _val = (val); \ - \ - asm volatile( \ - " eor %0, %1, %1\n" \ - " add %0, sp, %0\n" \ - " ldr xzr, [%0]" \ - : "=r" (tmp) : "r" (_val)); \ -} while (0) - static __always_inline u64 __arch_counter_get_cntpct_stable(void) {u64 cnt;@@ -224,8 +205,6 @@ static __always_inline u64 __arch_counter_get_cntvct(void)return cnt; } -#undef arch_counter_enforce_ordering -static inline int arch_timer_arch_init (void ) {return 0 ;arch/arm64/include/asm/barrier.h +19
-0@@ -70,6 +70,25 @@ static inline unsigned long array_index_mask_nospec(unsigned long idx,return mask; } +/* +* Ensure that reads of the counter are treated the same as memory reads +* for the purposes of ordering by subsequent memory barriers. +* +* This insanity brought to you by speculative system register reads, +* out-of-order memory accesses, sequence locks and Thomas Gleixner. +* +* http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html +*/ +#define arch_counter_enforce_ordering (val) do { \ + u64 tmp, _val = (val); \ + \ + asm volatile( \ + " eor %0, %1, %1\n" \ + " add %0, sp, %0\n" \ + " ldr xzr, [%0]" \ + : "=r" (tmp) : "r" (_val)); \ +} while (0) +#define __smp_mb () dmb(ish)#define __smp_rmb () dmb(ishld)#define __smp_wmb () dmb(ishst)arch/arm64/include/asm/vdso/gettimeofday.h +1
-5@@ -83,11 +83,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,*/ isb (); asmvolatile ("mrs %0, cntvct_el0" :"=r" (res) ::"memory" ); -/* -* This isb() is required to prevent that the seq lock is -* speculated.# -*/ -isb (); +arch_counter_enforce_ordering (res);return res; }
Signature · 7 lines
Regards, Vincenzo _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 5/5 arm64: compat: Poison the compat sigpage
In reply to Will DeaconCommit 9c698bff66ab ("ARM: ensure the signal page contains defined contents") poisoned the unused portions of the signal page for 32-bit Arm.
Implement the same poisoning for the compat signal page on arm64 rather than using __GFP_ZERO.
--- arch/arm64/kernel/vdso.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/arm64/kernel/vdso.c +6 -3
@@ -318,17 +318,20 @@ static int aarch32_alloc_kuser_vdso_page(void)return 0 ; } +#define COMPAT_SIGPAGE_POISON_WORD 0xe7fddef1static int aarch32_alloc_sigpage (void ) {extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start; -unsigned long sigpage; +__le32 poison =cpu_to_le32 (COMPAT_SIGPAGE_POISON_WORD ); +void *sigpage; - sigpage =get_zeroed_page (GFP_KERNEL ); + sigpage = (void *)__get_free_page (GFP_KERNEL );if (!sigpage)return -ENOMEM ; -memcpy ((void *)sigpage, __aarch32_sigret_code_start, sigret_sz); +memset32 (sigpage, (__force u32 )poison,PAGE_SIZE /sizeof (poison)); +memcpy (sigpage, __aarch32_sigret_code_start, sigret_sz); aarch32_sig_page =virt_to_page (sigpage);return 0 ; }
Signature · 7 lines
2.31.0.rc2.261.g7f71774620-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 5/5] arm64: compat: Poison the compat sigpage
Quoted 7 lines · Will Deacon
Commit
9c698bff66ab("ARM: ensure the signal page contains defined contents") poisoned the unused portions of the signal page for 32-bit Arm.Implement the same poisoning for the compat signal page on arm64 rather than using
__GFP_ZERO.Signed-off-by Will Deacon <[email protected]>
Quoted 33 lines
--- arch/arm64/kernel/vdso.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)arch/arm64/kernel/vdso.c +6
-3@@ -318,17 +318,20 @@ static int aarch32_alloc_kuser_vdso_page(void)return 0 ; } +#define COMPAT_SIGPAGE_POISON_WORD 0xe7fddef1static int aarch32_alloc_sigpage (void ) {extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start; -unsigned long sigpage; +__le32 poison =cpu_to_le32 (COMPAT_SIGPAGE_POISON_WORD ); +void *sigpage; - sigpage =get_zeroed_page (GFP_KERNEL ); + sigpage = (void *)__get_free_page (GFP_KERNEL );if (!sigpage)return -ENOMEM ; -memcpy ((void *)sigpage, __aarch32_sigret_code_start, sigret_sz); +memset32 (sigpage, (__force u32 )poison,PAGE_SIZE /sizeof (poison)); +memcpy (sigpage, __aarch32_sigret_code_start, sigret_sz); aarch32_sig_page =virt_to_page (sigpage);return 0 ; }
Signature · 7 lines
Regards, Vincenzo _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 9 lines · Will Deacon
Here are a few small improvements to the compat vDSO and sigpage implementation for arm64 which I cooked up when comparing the code with the native 32-bit counterpart.
Cheers,
Will
[...]
Applied to arm64 (for-next/vdso), thanks!
[1/5] arm64: vdso: Use GFP_KERNEL for allocating compat vdso and signal pages
https://git.kernel.org/arm64/c/7cd6ca1d7902 [2/5] arm64: vdso: Remove redundant calls to flush_dcache_page() https://git.kernel.org/arm64/c/e9be47eab1cd [3/5] arm64: compat: Allow signal page to be remapped https://git.kernel.org/arm64/c/7adbf10e29c2 [4/5] arm64: vdso: Avoid ISB after reading from cntvct_el0 https://git.kernel.org/arm64/c/77ec462536a1 [5/5] arm64: compat: Poison the compat sigpage https://git.kernel.org/arm64/c/6e554abd0700
Signature · 7 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel