Skip to content

Commit 6bd33e1

Browse files
Christoph Hellwigpaul-walmsley-sifive
authored andcommitted
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 <[email protected]>. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Anup Patel <[email protected]> [[email protected]: 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 <[email protected]>
1 parent 9e80635 commit 6bd33e1

File tree

23 files changed

+254
-71
lines changed

23 files changed

+254
-71
lines changed

arch/riscv/Kconfig

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ config RISCV
2626
select GENERIC_IRQ_SHOW
2727
select GENERIC_PCI_IOMAP
2828
select GENERIC_SCHED_CLOCK
29-
select GENERIC_STRNCPY_FROM_USER
30-
select GENERIC_STRNLEN_USER
29+
select GENERIC_STRNCPY_FROM_USER if MMU
30+
select GENERIC_STRNLEN_USER if MMU
3131
select GENERIC_SMP_IDLE_THREAD
3232
select GENERIC_ATOMIC64 if !64BIT
3333
select HAVE_ARCH_AUDITSYSCALL
3434
select HAVE_ASM_MODVERSIONS
3535
select HAVE_MEMBLOCK_NODE_MAP
36-
select HAVE_DMA_CONTIGUOUS
36+
select HAVE_DMA_CONTIGUOUS if MMU
3737
select HAVE_FUTEX_CMPXCHG if FUTEX
3838
select HAVE_PERF_EVENTS
3939
select HAVE_PERF_REGS
@@ -50,6 +50,7 @@ config RISCV
5050
select PCI_DOMAINS_GENERIC if PCI
5151
select PCI_MSI if PCI
5252
select RISCV_TIMER
53+
select UACCESS_MEMCPY if !MMU
5354
select GENERIC_IRQ_MULTI_HANDLER
5455
select GENERIC_ARCH_TOPOLOGY if SMP
5556
select ARCH_HAS_PTE_SPECIAL
@@ -60,7 +61,7 @@ config RISCV
6061
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
6162
select SPARSEMEM_STATIC if 32BIT
6263
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
63-
select HAVE_ARCH_MMAP_RND_BITS
64+
select HAVE_ARCH_MMAP_RND_BITS if MMU
6465

6566
config ARCH_MMAP_RND_BITS_MIN
6667
default 18 if 64BIT
@@ -75,6 +76,7 @@ config ARCH_MMAP_RND_BITS_MAX
7576
# set if we run in machine mode, cleared if we run in supervisor mode
7677
config RISCV_M_MODE
7778
bool
79+
default !MMU
7880

7981
# set if we are running in S-mode and can use SBI calls
8082
config RISCV_SBI
@@ -83,7 +85,11 @@ config RISCV_SBI
8385
default y
8486

8587
config MMU
86-
def_bool y
88+
bool "MMU-based Paged Memory Management Support"
89+
default y
90+
help
91+
Select if you want MMU-based virtualised addressing space
92+
support by paged memory management. If unsure, say 'Y'.
8793

8894
config ZONE_DMA32
8995
bool
@@ -102,6 +108,7 @@ config PA_BITS
102108
config PAGE_OFFSET
103109
hex
104110
default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB
111+
default 0x80000000 if 64BIT && !MMU
105112
default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB
106113
default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
107114

@@ -145,7 +152,7 @@ config GENERIC_HWEIGHT
145152
def_bool y
146153

147154
config FIX_EARLYCON_MEM
148-
def_bool y
155+
def_bool CONFIG_MMU
149156

150157
config PGTABLE_LEVELS
151158
int
@@ -170,6 +177,7 @@ config ARCH_RV32I
170177
select GENERIC_LIB_ASHRDI3
171178
select GENERIC_LIB_LSHRDI3
172179
select GENERIC_LIB_UCMPDI2
180+
select MMU
173181

174182
config ARCH_RV64I
175183
bool "RV64I"
@@ -178,9 +186,9 @@ config ARCH_RV64I
178186
select HAVE_FUNCTION_TRACER
179187
select HAVE_FUNCTION_GRAPH_TRACER
180188
select HAVE_FTRACE_MCOUNT_RECORD
181-
select HAVE_DYNAMIC_FTRACE
182-
select HAVE_DYNAMIC_FTRACE_WITH_REGS
183-
select SWIOTLB
189+
select HAVE_DYNAMIC_FTRACE if MMU
190+
select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
191+
select SWIOTLB if MMU
184192

185193
endchoice
186194

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# CONFIG_CPU_ISOLATION is not set
2+
CONFIG_LOG_BUF_SHIFT=16
3+
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
4+
CONFIG_BLK_DEV_INITRD=y
5+
# CONFIG_RD_BZIP2 is not set
6+
# CONFIG_RD_LZMA is not set
7+
# CONFIG_RD_XZ is not set
8+
# CONFIG_RD_LZO is not set
9+
# CONFIG_RD_LZ4 is not set
10+
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
11+
CONFIG_EXPERT=y
12+
# CONFIG_SYSFS_SYSCALL is not set
13+
# CONFIG_FHANDLE is not set
14+
# CONFIG_BASE_FULL is not set
15+
# CONFIG_EPOLL is not set
16+
# CONFIG_SIGNALFD is not set
17+
# CONFIG_TIMERFD is not set
18+
# CONFIG_EVENTFD is not set
19+
# CONFIG_AIO is not set
20+
# CONFIG_IO_URING is not set
21+
# CONFIG_ADVISE_SYSCALLS is not set
22+
# CONFIG_MEMBARRIER is not set
23+
# CONFIG_KALLSYMS is not set
24+
# CONFIG_VM_EVENT_COUNTERS is not set
25+
# CONFIG_COMPAT_BRK is not set
26+
CONFIG_SLOB=y
27+
# CONFIG_SLAB_MERGE_DEFAULT is not set
28+
# CONFIG_MMU is not set
29+
CONFIG_MAXPHYSMEM_2GB=y
30+
CONFIG_SMP=y
31+
CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
32+
CONFIG_CMDLINE_FORCE=y
33+
# CONFIG_BLK_DEV_BSG is not set
34+
CONFIG_PARTITION_ADVANCED=y
35+
# CONFIG_MSDOS_PARTITION is not set
36+
# CONFIG_EFI_PARTITION is not set
37+
# CONFIG_MQ_IOSCHED_DEADLINE is not set
38+
# CONFIG_MQ_IOSCHED_KYBER is not set
39+
CONFIG_BINFMT_FLAT=y
40+
# CONFIG_COREDUMP is not set
41+
CONFIG_DEVTMPFS=y
42+
CONFIG_DEVTMPFS_MOUNT=y
43+
# CONFIG_FW_LOADER is not set
44+
# CONFIG_ALLOW_DEV_COREDUMP is not set
45+
CONFIG_VIRTIO_BLK=y
46+
# CONFIG_INPUT_KEYBOARD is not set
47+
# CONFIG_INPUT_MOUSE is not set
48+
# CONFIG_SERIO is not set
49+
# CONFIG_LEGACY_PTYS is not set
50+
# CONFIG_LDISC_AUTOLOAD is not set
51+
# CONFIG_DEVMEM is not set
52+
CONFIG_SERIAL_8250=y
53+
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
54+
CONFIG_SERIAL_8250_CONSOLE=y
55+
CONFIG_SERIAL_8250_NR_UARTS=1
56+
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
57+
CONFIG_SERIAL_OF_PLATFORM=y
58+
# CONFIG_HW_RANDOM is not set
59+
# CONFIG_HWMON is not set
60+
# CONFIG_LCD_CLASS_DEVICE is not set
61+
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
62+
# CONFIG_VGA_CONSOLE is not set
63+
# CONFIG_HID is not set
64+
# CONFIG_USB_SUPPORT is not set
65+
CONFIG_VIRTIO_MMIO=y
66+
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
67+
CONFIG_SIFIVE_PLIC=y
68+
# CONFIG_VALIDATE_FS_PARSER is not set
69+
CONFIG_EXT2_FS=y
70+
# CONFIG_DNOTIFY is not set
71+
# CONFIG_INOTIFY_USER is not set
72+
# CONFIG_MISC_FILESYSTEMS is not set
73+
CONFIG_LSM="[]"
74+
CONFIG_PRINTK_TIME=y
75+
# CONFIG_SCHED_DEBUG is not set
76+
# CONFIG_RCU_TRACE is not set
77+
# CONFIG_FTRACE is not set
78+
# CONFIG_RUNTIME_TESTING_MENU is not set

arch/riscv/include/asm/cache.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,12 @@
1111

1212
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
1313

14+
/*
15+
* RISC-V requires the stack pointer to be 16-byte aligned, so ensure that
16+
* the flat loader aligns it accordingly.
17+
*/
18+
#ifndef CONFIG_MMU
19+
#define ARCH_SLAB_MINALIGN 16
20+
#endif
21+
1422
#endif /* _ASM_RISCV_CACHE_H */

arch/riscv/include/asm/elf.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,16 @@ extern unsigned long elf_hwcap;
5656
*/
5757
#define ELF_PLATFORM (NULL)
5858

59+
#ifdef CONFIG_MMU
5960
#define ARCH_DLINFO \
6061
do { \
6162
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
6263
(elf_addr_t)current->mm->context.vdso); \
6364
} while (0)
64-
65-
6665
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
6766
struct linux_binprm;
6867
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
6968
int uses_interp);
69+
#endif /* CONFIG_MMU */
7070

7171
#endif /* _ASM_RISCV_ELF_H */

arch/riscv/include/asm/fixmap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <asm/page.h>
1212
#include <asm/pgtable.h>
1313

14+
#ifdef CONFIG_MMU
1415
/*
1516
* Here we define all the compile-time 'special' virtual addresses.
1617
* The point is to have a constant address at compile time, but to
@@ -42,4 +43,5 @@ extern void __set_fixmap(enum fixed_addresses idx,
4243

4344
#include <asm-generic/fixmap.h>
4445

46+
#endif /* CONFIG_MMU */
4547
#endif /* _ASM_RISCV_FIXMAP_H */

arch/riscv/include/asm/futex.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
#include <linux/errno.h>
1313
#include <asm/asm.h>
1414

15+
/* We don't even really need the extable code, but for now keep it simple */
16+
#ifndef CONFIG_MMU
17+
#define __enable_user_access() do { } while (0)
18+
#define __disable_user_access() do { } while (0)
19+
#endif
20+
1521
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
1622
{ \
1723
uintptr_t tmp; \

arch/riscv/include/asm/io.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
/*
2525
* I/O port access constants.
2626
*/
27+
#ifdef CONFIG_MMU
2728
#define IO_SPACE_LIMIT (PCI_IO_SIZE - 1)
2829
#define PCI_IOBASE ((void __iomem *)PCI_IO_START)
30+
#endif /* CONFIG_MMU */
2931

3032
/*
3133
* Emulation routines for the port-mapped IO space used by some PCI drivers.

arch/riscv/include/asm/mmio.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/types.h>
1515
#include <asm/mmiowb.h>
1616

17+
#ifdef CONFIG_MMU
1718
void __iomem *ioremap(phys_addr_t offset, unsigned long size);
1819

1920
/*
@@ -26,6 +27,9 @@ void __iomem *ioremap(phys_addr_t offset, unsigned long size);
2627
#define ioremap_wt(addr, size) ioremap((addr), (size))
2728

2829
void iounmap(volatile void __iomem *addr);
30+
#else
31+
#define pgprot_noncached(x) (x)
32+
#endif /* CONFIG_MMU */
2933

3034
/* Generic IO read/write. These perform native-endian accesses. */
3135
#define __raw_writeb __raw_writeb

arch/riscv/include/asm/mmu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#ifndef __ASSEMBLY__
1111

1212
typedef struct {
13+
#ifndef CONFIG_MMU
14+
unsigned long end_brk;
15+
#endif
1316
void *vdso;
1417
#ifdef CONFIG_SMP
1518
/* A local icache flush is needed before user execution can resume. */

arch/riscv/include/asm/page.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,14 @@ typedef struct page *pgtable_t;
8888
#define PTE_FMT "%08lx"
8989
#endif
9090

91+
#ifdef CONFIG_MMU
9192
extern unsigned long va_pa_offset;
9293
extern unsigned long pfn_base;
94+
#define ARCH_PFN_OFFSET (pfn_base)
95+
#else
96+
#define va_pa_offset 0
97+
#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
98+
#endif /* CONFIG_MMU */
9399

94100
extern unsigned long max_low_pfn;
95101
extern unsigned long min_low_pfn;
@@ -112,11 +118,9 @@ extern unsigned long min_low_pfn;
112118

113119
#ifdef CONFIG_FLATMEM
114120
#define pfn_valid(pfn) \
115-
(((pfn) >= pfn_base) && (((pfn)-pfn_base) < max_mapnr))
121+
(((pfn) >= ARCH_PFN_OFFSET) && (((pfn) - ARCH_PFN_OFFSET) < max_mapnr))
116122
#endif
117123

118-
#define ARCH_PFN_OFFSET (pfn_base)
119-
120124
#endif /* __ASSEMBLY__ */
121125

122126
#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))

arch/riscv/include/asm/pgalloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/mm.h>
1111
#include <asm/tlb.h>
1212

13+
#ifdef CONFIG_MMU
1314
#include <asm-generic/pgalloc.h> /* for pte_{alloc,free}_one */
1415

1516
static inline void pmd_populate_kernel(struct mm_struct *mm,
@@ -81,5 +82,6 @@ do { \
8182
pgtable_pte_page_dtor(pte); \
8283
tlb_remove_page((tlb), pte); \
8384
} while (0)
85+
#endif /* CONFIG_MMU */
8486

8587
#endif /* _ASM_RISCV_PGALLOC_H */

0 commit comments

Comments
 (0)