Skip to content

Commit f4b395e

Browse files
guoren83palmer-dabbelt
authored andcommitted
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>
1 parent 87309e1 commit f4b395e

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

arch/riscv/include/asm/elf.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@
3333
/*
3434
* This is used to ensure we don't load something for the wrong architecture.
3535
*/
36-
#define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
36+
#define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
37+
((x)->e_ident[EI_CLASS] == ELF_CLASS))
3738

38-
#define compat_elf_check_arch(x) ((x)->e_machine == EM_RISCV)
39+
extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
40+
#define compat_elf_check_arch compat_elf_check_arch
3941

4042
#define CORE_DUMP_USE_REGSET
4143
#define ELF_EXEC_PAGESIZE (PAGE_SIZE)

arch/riscv/kernel/process.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,34 @@ void show_regs(struct pt_regs *regs)
8484
dump_backtrace(regs, NULL, KERN_DEFAULT);
8585
}
8686

87+
#ifdef CONFIG_COMPAT
88+
static bool compat_mode_supported __read_mostly;
89+
90+
bool compat_elf_check_arch(Elf32_Ehdr *hdr)
91+
{
92+
return compat_mode_supported &&
93+
hdr->e_machine == EM_RISCV &&
94+
hdr->e_ident[EI_CLASS] == ELFCLASS32;
95+
}
96+
97+
static int __init compat_mode_detect(void)
98+
{
99+
unsigned long tmp = csr_read(CSR_STATUS);
100+
101+
csr_write(CSR_STATUS, (tmp & ~SR_UXL) | SR_UXL_32);
102+
compat_mode_supported =
103+
(csr_read(CSR_STATUS) & SR_UXL) == SR_UXL_32;
104+
105+
csr_write(CSR_STATUS, tmp);
106+
107+
pr_info("riscv: ELF compat mode %s",
108+
compat_mode_supported ? "supported" : "failed");
109+
110+
return 0;
111+
}
112+
early_initcall(compat_mode_detect);
113+
#endif
114+
87115
void start_thread(struct pt_regs *regs, unsigned long pc,
88116
unsigned long sp)
89117
{

0 commit comments

Comments
 (0)