riscv: add nommu support
The kernel runs in M-mode without using page tables, and thus can't run bare metal without help from additional firmware. Most of the patch is just stubbing out code not needed without page tables, but there is an interesting detail in the signals implementation: - The normal RISC-V syscall ABI only implements rt_sigreturn as VDSO entry point, but the ELF VDSO is not supported for nommu Linux. We instead copy the code to call the syscall onto the stack. In addition to enabling the nommu code a new defconfig for a small kernel image that can run in nommu mode on qemu is also provided, to run a kernel in qemu you can use the following command line: qemu-system-riscv64 -smp 2 -m 64 -machine virt -nographic \ -kernel arch/riscv/boot/loader \ -drive file=rootfs.ext2,format=raw,id=hd0 \ -device virtio-blk-device,drive=hd0 Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Anup Patel <anup@brainfault.org> [paul.walmsley@sifive.com: updated to apply; add CONFIG_MMU guards around PCI_IOBASE definition to fix build issues; fixed checkpatch issues; move the PCI_IO_* and VMEMMAP address space macros along with the others; resolve sparse warning] Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
This commit is contained in:

committed by
Paul Walmsley

parent
9e80635619
commit
6bd33e1ece
@@ -17,11 +17,16 @@
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/csr.h>
|
||||
|
||||
extern u32 __user_rt_sigreturn[2];
|
||||
|
||||
#define DEBUG_SIG 0
|
||||
|
||||
struct rt_sigframe {
|
||||
struct siginfo info;
|
||||
struct ucontext uc;
|
||||
#ifndef CONFIG_MMU
|
||||
u32 sigreturn_code[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FPU
|
||||
@@ -166,7 +171,6 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
|
||||
return (void __user *)sp;
|
||||
}
|
||||
|
||||
|
||||
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
@@ -189,8 +193,19 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
|
||||
return -EFAULT;
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
#ifdef CONFIG_MMU
|
||||
regs->ra = (unsigned long)VDSO_SYMBOL(
|
||||
current->mm->context.vdso, rt_sigreturn);
|
||||
#else
|
||||
/*
|
||||
* For the nommu case we don't have a VDSO. Instead we push two
|
||||
* instructions to call the rt_sigreturn syscall onto the user stack.
|
||||
*/
|
||||
if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
|
||||
sizeof(frame->sigreturn_code)))
|
||||
return -EFAULT;
|
||||
regs->ra = (unsigned long)&frame->sigreturn_code;
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
/*
|
||||
* Set up registers for signal handler.
|
||||
|
Reference in New Issue
Block a user