Skip to content

Commit

Permalink
riscv: alternative: patch alternatives in the vDSO
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jisheng Zhang authored and Palmer Dabbelt committed Feb 1, 2023
1 parent 8d23e94 commit cabfd14
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
4 changes: 4 additions & 0 deletions arch/riscv/include/asm/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
29 changes: 29 additions & 0 deletions arch/riscv/kernel/alternative.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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 */
Expand All @@ -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();
}

/*
Expand Down
5 changes: 0 additions & 5 deletions arch/riscv/kernel/vdso.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions arch/riscv/kernel/vdso/vdso.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down

0 comments on commit cabfd14

Please sign in to comment.