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 @@
#define COMPAT_VDSO_SYMBOL(base, name) \
(void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
extern char compat_vdso_start[], compat_vdso_end[];
#endif /* CONFIG_COMPAT */
extern char vdso_start[], vdso_end[];
#endif /* !__ASSEMBLY__ */
#endif /* CONFIG_MMU */
......
......@@ -11,7 +11,9 @@
#include <linux/cpu.h>
#include <linux/uaccess.h>
#include <asm/alternative.h>
#include <asm/module.h>
#include <asm/sections.h>
#include <asm/vdso.h>
#include <asm/vendorid_list.h>
#include <asm/sbi.h>
#include <asm/csr.h>
......@@ -160,6 +162,31 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
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)
{
/* If called on non-boot cpu things could go wrong */
......@@ -168,6 +195,8 @@ void __init apply_boot_alternatives(void)
_apply_alternatives((struct alt_entry *)__alt_start,
(struct alt_entry *)__alt_end,
RISCV_ALTERNATIVES_BOOT);
apply_vdso_alternatives();
}
/*
......
......@@ -22,11 +22,6 @@ struct vdso_data {
};
#endif
extern char vdso_start[], vdso_end[];
#ifdef CONFIG_COMPAT
extern char compat_vdso_start[], compat_vdso_end[];
#endif
enum vvar_pages {
VVAR_DATA_PAGE_OFFSET,
VVAR_TIMENS_PAGE_OFFSET,
......
......@@ -40,6 +40,13 @@ SECTIONS
. = 0x800;
.text : { *(.text .text.*) } :text
. = ALIGN(4);
.alternative : {
__alt_start = .;
*(.alternative)
__alt_end = .;
}
.data : {
*(.got.plt) *(.got)
*(.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