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: Jisheng Zhang <jszhang@kernel.org> Reviewed-by: Guo Ren <guoren@kernel.org> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/20230128172856.3814-11-jszhang@kernel.org Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
8d23e94a44
commit
cabfd146b3
@ -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.*)
|
||||
|
Loading…
x
Reference in New Issue
Block a user