forked from Minki/linux
riscv: compat: Add hw capability check for elf
Detect hardware COMPAT (32bit U-mode) capability in rv64. If not support COMPAT mode in hw, compat_elf_check_arch would return false by compat_binfmt_elf.c Add CLASS to enhance (compat_)elf_check_arch to distinguish 32BIT/64BIT elf. Signed-off-by: Guo Ren <guoren@linux.alibaba.com> Signed-off-by: Guo Ren <guoren@kernel.org> Tested-by: Heiko Stuebner <heiko@sntech.de> Link: https://lore.kernel.org/r/20220405071314.3225832-16-guoren@kernel.org Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
87309e1082
commit
f4b395e6f1
@ -33,9 +33,11 @@
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
|
||||
#define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
|
||||
((x)->e_ident[EI_CLASS] == ELF_CLASS))
|
||||
|
||||
#define compat_elf_check_arch(x) ((x)->e_machine == EM_RISCV)
|
||||
extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
|
||||
#define compat_elf_check_arch compat_elf_check_arch
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
#define ELF_EXEC_PAGESIZE (PAGE_SIZE)
|
||||
|
@ -84,6 +84,34 @@ void show_regs(struct pt_regs *regs)
|
||||
dump_backtrace(regs, NULL, KERN_DEFAULT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static bool compat_mode_supported __read_mostly;
|
||||
|
||||
bool compat_elf_check_arch(Elf32_Ehdr *hdr)
|
||||
{
|
||||
return compat_mode_supported &&
|
||||
hdr->e_machine == EM_RISCV &&
|
||||
hdr->e_ident[EI_CLASS] == ELFCLASS32;
|
||||
}
|
||||
|
||||
static int __init compat_mode_detect(void)
|
||||
{
|
||||
unsigned long tmp = csr_read(CSR_STATUS);
|
||||
|
||||
csr_write(CSR_STATUS, (tmp & ~SR_UXL) | SR_UXL_32);
|
||||
compat_mode_supported =
|
||||
(csr_read(CSR_STATUS) & SR_UXL) == SR_UXL_32;
|
||||
|
||||
csr_write(CSR_STATUS, tmp);
|
||||
|
||||
pr_info("riscv: ELF compat mode %s",
|
||||
compat_mode_supported ? "supported" : "failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_initcall(compat_mode_detect);
|
||||
#endif
|
||||
|
||||
void start_thread(struct pt_regs *regs, unsigned long pc,
|
||||
unsigned long sp)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user