[PATCH OLK-5.10 0/5] use SYS_CNTVCTSS_EL0 for gettimeofday
Jisheng Zhang (1): arm64: vdso: remove two .altinstructions related symbols Joey Gouly (3): arm64: module: move find_section to header arm64: alternative: patch alternatives in the vDSO arm64: vdso: use SYS_CNTVCTSS_EL0 for gettimeofday Yang Yingliang (1): vdso: do cntvct workaround in the VDSO arch/arm64/include/asm/module.h | 15 ++++++++ arch/arm64/include/asm/vdso.h | 3 ++ arch/arm64/include/asm/vdso/gettimeofday.h | 42 ++++++++++++++++++---- arch/arm64/kernel/alternative.c | 28 +++++++++++++++ arch/arm64/kernel/module.c | 15 -------- arch/arm64/kernel/vdso.c | 2 -- arch/arm64/kernel/vdso/vdso.lds.S | 5 +++ 7 files changed, 87 insertions(+), 23 deletions(-) -- 2.34.1
From: Joey Gouly <joey.gouly@arm.com> mainline inclusion from mainline-v6.1-rc1 commit b3adc3844e1dedd05fa8d09633eaa8ddc5ddcece category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8301 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Move it to the header so that the implementation can be shared by the alternatives code. Signed-off-by: Joey Gouly <joey.gouly@arm.com> Cc: Will Deacon <will@kernel.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20220830104833.34636-2-joey.gouly@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Xinyu Zheng <zhengxinyu6@huawei.com> --- arch/arm64/include/asm/module.h | 15 +++++++++++++++ arch/arm64/kernel/module.c | 15 --------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h index 4e7fa2623896..22f1be47cc92 100644 --- a/arch/arm64/include/asm/module.h +++ b/arch/arm64/include/asm/module.h @@ -65,4 +65,19 @@ static inline bool plt_entry_is_initialized(const struct plt_entry *e) return e->adrp || e->add || e->br; } +static inline const Elf_Shdr *find_section(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + const char *name) +{ + const Elf_Shdr *s, *se; + const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) { + if (strcmp(name, secstrs + s->sh_name) == 0) + return s; + } + + return NULL; +} + #endif /* __ASM_MODULE_H */ diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c index acd557c83b6f..fb5d2eb73cf5 100644 --- a/arch/arm64/kernel/module.c +++ b/arch/arm64/kernel/module.c @@ -472,21 +472,6 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return -ENOEXEC; } -static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *name) -{ - const Elf_Shdr *s, *se; - const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - - for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) { - if (strcmp(name, secstrs + s->sh_name) == 0) - return s; - } - - return NULL; -} - static inline void __init_plt(struct plt_entry *plt, unsigned long addr) { *plt = get_plt_entry(addr, plt); -- 2.34.1
From: Joey Gouly <joey.gouly@arm.com> mainline inclusion from mainline-v6.1-rc1 commit 4e3bca8f7cdd3b658ee7ad700fdce95b5e13a441 category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8301 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Make it possible to use alternatives in the vDSO, so that better implementations can be used if possible. Signed-off-by: Joey Gouly <joey.gouly@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20220830104833.34636-3-joey.gouly@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Conflicts: arch/arm64/kernel/vdso/vdso.lds.S arch/arm64/kernel/vdso.c arch/arm64/include/asm/vdso.h [context conflict] Signed-off-by: Xinyu Zheng <zhengxinyu6@huawei.com> --- arch/arm64/include/asm/vdso.h | 3 +++ arch/arm64/kernel/alternative.c | 28 ++++++++++++++++++++++++++++ arch/arm64/kernel/vdso.c | 2 -- arch/arm64/kernel/vdso/vdso.lds.S | 7 +++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 872e01b18957..64305ec3073c 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -32,6 +32,9 @@ (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ }) +extern char vdso_start[], vdso_end[]; +extern char vdso32_start[], vdso32_end[]; + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_VDSO_H */ diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c index 5f8e4c2df53c..8436e432afe5 100644 --- a/arch/arm64/kernel/alternative.c +++ b/arch/arm64/kernel/alternative.c @@ -10,11 +10,14 @@ #include <linux/init.h> #include <linux/cpu.h> +#include <linux/elf.h> #include <asm/cacheflush.h> #include <asm/alternative.h> #include <asm/cpufeature.h> #include <asm/insn.h> +#include <asm/module.h> #include <asm/sections.h> +#include <asm/vdso.h> #include <linux/stop_machine.h> #define __ALT_PTR(a,f) ((void *)&(a)->f + (a)->f) @@ -192,6 +195,30 @@ static void __apply_alternatives(void *alt_region, bool is_module, } } +void apply_alternatives_vdso(void) +{ + struct alt_region region; + const struct elf64_hdr *hdr; + const struct elf64_shdr *shdr; + const struct elf64_shdr *alt; + DECLARE_BITMAP(all_capabilities, ARM64_NPATCHABLE); + + bitmap_fill(all_capabilities, ARM64_NPATCHABLE); + + hdr = (struct elf64_hdr *)vdso_start; + shdr = (void *)hdr + hdr->e_shoff; + alt = find_section(hdr, shdr, ".altinstructions"); + if (!alt) + return; + + region = (struct alt_region){ + .begin = (void *)hdr + alt->sh_offset, + .end = (void *)hdr + alt->sh_offset + alt->sh_size, + }; + + __apply_alternatives(®ion, false, &all_capabilities[0]); +} + /* * We might be patching the stop_machine state machine, so implement a * really simple polling protocol here. @@ -225,6 +252,7 @@ static int __apply_alternatives_multi_stop(void *unused) void __init apply_alternatives_all(void) { + apply_alternatives_vdso(); /* better not try code patching on a live SMP system */ stop_machine(__apply_alternatives_multi_stop, NULL, cpu_online_mask); } diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 0dc216e2d7ac..324a59974585 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -29,8 +29,6 @@ #include <asm/signal32.h> #include <asm/vdso.h> -extern char vdso_start[], vdso_end[]; -extern char vdso32_start[], vdso32_end[]; #ifdef CONFIG_ARM64_ILP32 extern char vdso_ilp32_start[], vdso_ilp32_end[]; #endif diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index b840ab1b705c..f60ec7b51ee4 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -47,6 +47,13 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); + . = ALIGN(4); + .altinstructions : { + __alt_instructions = .; + *(.altinstructions) + __alt_instructions_end = .; + } + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr .eh_frame : { KEEP (*(.eh_frame)) } :text -- 2.34.1
From: Joey Gouly <joey.gouly@arm.com> mainline inclusion from mainline-v6.1-rc1 commit 9025cebf12d1763de36d5e09e2b0a1e4f9b13b28 category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8301 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- If FEAT_ECV is implemented, the self-synchronized counter CNTVCTSS_EL0 can be used, removing the need for an ISB. Signed-off-by: Joey Gouly <joey.gouly@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Andre Przywara <andre.przywara@arm.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20220830104833.34636-4-joey.gouly@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Xinyu Zheng <zhengxinyu6@huawei.com> --- arch/arm64/include/asm/vdso/gettimeofday.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h index e35cda0f09a3..b5cf4581ea18 100644 --- a/arch/arm64/include/asm/vdso/gettimeofday.h +++ b/arch/arm64/include/asm/vdso/gettimeofday.h @@ -7,8 +7,10 @@ #ifndef __ASSEMBLY__ +#include <asm/alternative.h> #include <asm/barrier.h> #include <asm/unistd.h> +#include <asm/sysreg.h> #define VDSO_HAS_CLOCK_GETRES 1 @@ -78,11 +80,20 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, return 0; /* - * This isb() is required to prevent that the counter value + * If FEAT_ECV is available, use the self-synchronizing counter. + * Otherwise the isb is required to prevent that the counter value * is speculated. */ - isb(); - asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); + asm volatile( + ALTERNATIVE("isb\n" + "mrs %0, cntvct_el0", + "nop\n" + __mrs_s("%0", SYS_CNTVCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (res) + : + : "memory"); + if (vd->vdso_fix) { u64 new; int retries = 50; -- 2.34.1
From: Jisheng Zhang <jszhang@kernel.org> mainline inclusion from mainline-v6.6-rc1 commit a96a7a7ddf9559eb20e608c0de30d1867d755a33 category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8301 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- The two symbols __alt_instructions and __alt_instructions_end are not used, since the vDSO patching code looks for the '.altinstructions' ELF section directly. Remove the unused linker symbols. Fixes: 4e3bca8f7cdd ("arm64: alternative: patch alternatives in the vDSO") Signed-off-by: Jisheng Zhang <jszhang@kernel.org> Link: https://lore.kernel.org/r/20230726173619.3732-1-jszhang@kernel.org Signed-off-by: Will Deacon <will@kernel.org> Signed-off-by: Xinyu Zheng <zhengxinyu6@huawei.com> --- arch/arm64/kernel/vdso/vdso.lds.S | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index f60ec7b51ee4..17adf7c75584 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -49,9 +49,7 @@ SECTIONS . = ALIGN(4); .altinstructions : { - __alt_instructions = .; *(.altinstructions) - __alt_instructions_end = .; } .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr -- 2.34.1
From: Yang Yingliang <yangyingliang@huawei.com> hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8301 CVE: NA -------------------------------------------------- If a cntvct workaround is enabled, read CNTVCT_EL0 twice in VDSO to avoid the clock bug. Without this patch on Kunpeng916: ./gettimeofday -E -C 200 -L -S -W -N "gettimeofday" Running: gettimeofday# ./gettimeofday -E -C 200 -L -S -W -N gettimeofday prc thr usecs/call samples errors cnt/samp gettimeofday 1 1 0.31753 198 0 20000 With this patch on Kunpeng916: ./gettimeofday -E -C 200 -L -S -W -N "gettimeofday" Running: gettimeofday# ./gettimeofday -E -C 200 -L -S -W -N gettimeofday prc thr usecs/call samples errors cnt/samp gettimeofday 1 1 0.05244 198 0 20000 This patch was backported from OLK-6.6 partially before, since we already backported 9025cebf12d1 ("arm64: vdso: use SYS_CNTVCTSS_EL0 for gettimeofday"). Now we backport the whole patch. Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: Xinyu Zheng <zhengxinyu6@huawei.com> --- arch/arm64/include/asm/vdso/gettimeofday.h | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h index b5cf4581ea18..cf5b6db57cc2 100644 --- a/arch/arm64/include/asm/vdso/gettimeofday.h +++ b/arch/arm64/include/asm/vdso/gettimeofday.h @@ -98,10 +98,29 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, u64 new; int retries = 50; - asm volatile("mrs %0, cntvct_el0" : "=r" (new) :: "memory"); + asm volatile( + ALTERNATIVE("mrs %0, cntvct_el0", + __mrs_s("%0", SYS_CNTVCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (new) + : + : "memory"); while (unlikely((new - res) >> vd->vdso_shift) && retries) { - asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); - asm volatile("mrs %0, cntvct_el0" : "=r" (new) :: "memory"); + asm volatile( + ALTERNATIVE("mrs %0, cntvct_el0", + __mrs_s("%0", SYS_CNTVCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (res) + : + : "memory"); + + asm volatile( + ALTERNATIVE("mrs %0, cntvct_el0", + __mrs_s("%0", SYS_CNTVCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (new) + : + : "memory"); retries--; } } -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/20423 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/EV5... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/20423 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/EV5...
participants (2)
-
patchwork bot -
Xinyu Zheng