Commit cabfd146 authored by Jisheng Zhang's avatar Jisheng Zhang Committed by Palmer Dabbelt

riscv: alternative: patch alternatives in the vDSO

Make it possible to use alternatives in the vDSO, so that better
implementations can be used if possible.
Signed-off-by: default avatarJisheng Zhang <jszhang@kernel.org>
Reviewed-by: default avatarGuo Ren <guoren@kernel.org>
Reviewed-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/20230128172856.3814-11-jszhang@kernel.orgSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 8d23e94a
...@@ -28,8 +28,12 @@ ...@@ -28,8 +28,12 @@
#define COMPAT_VDSO_SYMBOL(base, name) \ #define COMPAT_VDSO_SYMBOL(base, name) \
(void __user *)((unsigned long)(base) + compat__vdso_##name##_offset) (void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
extern char compat_vdso_start[], compat_vdso_end[];
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
extern char vdso_start[], vdso_end[];
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* CONFIG_MMU */ #endif /* CONFIG_MMU */
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/module.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/vdso.h>
#include <asm/vendorid_list.h> #include <asm/vendorid_list.h>
#include <asm/sbi.h> #include <asm/sbi.h>
#include <asm/csr.h> #include <asm/csr.h>
...@@ -160,6 +162,31 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin, ...@@ -160,6 +162,31 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
stage); stage);
} }
#ifdef CONFIG_MMU
static void __init apply_vdso_alternatives(void)
{
const Elf_Ehdr *hdr;
const Elf_Shdr *shdr;
const Elf_Shdr *alt;
struct alt_entry *begin, *end;
hdr = (Elf_Ehdr *)vdso_start;
shdr = (void *)hdr + hdr->e_shoff;
alt = find_section(hdr, shdr, ".alternative");
if (!alt)
return;
begin = (void *)hdr + alt->sh_offset,
end = (void *)hdr + alt->sh_offset + alt->sh_size,
_apply_alternatives((struct alt_entry *)begin,
(struct alt_entry *)end,
RISCV_ALTERNATIVES_BOOT);
}
#else
static void __init apply_vdso_alternatives(void) { }
#endif
void __init apply_boot_alternatives(void) void __init apply_boot_alternatives(void)
{ {
/* If called on non-boot cpu things could go wrong */ /* If called on non-boot cpu things could go wrong */
...@@ -168,6 +195,8 @@ void __init apply_boot_alternatives(void) ...@@ -168,6 +195,8 @@ void __init apply_boot_alternatives(void)
_apply_alternatives((struct alt_entry *)__alt_start, _apply_alternatives((struct alt_entry *)__alt_start,
(struct alt_entry *)__alt_end, (struct alt_entry *)__alt_end,
RISCV_ALTERNATIVES_BOOT); RISCV_ALTERNATIVES_BOOT);
apply_vdso_alternatives();
} }
/* /*
......
...@@ -22,11 +22,6 @@ struct vdso_data { ...@@ -22,11 +22,6 @@ struct vdso_data {
}; };
#endif #endif
extern char vdso_start[], vdso_end[];
#ifdef CONFIG_COMPAT
extern char compat_vdso_start[], compat_vdso_end[];
#endif
enum vvar_pages { enum vvar_pages {
VVAR_DATA_PAGE_OFFSET, VVAR_DATA_PAGE_OFFSET,
VVAR_TIMENS_PAGE_OFFSET, VVAR_TIMENS_PAGE_OFFSET,
......
...@@ -40,6 +40,13 @@ SECTIONS ...@@ -40,6 +40,13 @@ SECTIONS
. = 0x800; . = 0x800;
.text : { *(.text .text.*) } :text .text : { *(.text .text.*) } :text
. = ALIGN(4);
.alternative : {
__alt_start = .;
*(.alternative)
__alt_end = .;
}
.data : { .data : {
*(.got.plt) *(.got) *(.got.plt) *(.got)
*(.data .data.* .gnu.linkonce.d.*) *(.data .data.* .gnu.linkonce.d.*)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment