Skip to content

Commit 2bc46f7

Browse files
authored
Merge pull request #551 from rodionov/mmu_rc
LKL MMU support
2 parents 7682a9e + 1ee079e commit 2bc46f7

25 files changed

+966
-12
lines changed

Diff for: .github/workflows/ci.yml

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ jobs:
2222
runs_on: ubuntu-22.04
2323
shell: bash
2424
build_options: "kasan=yes kasan_test=yes"
25+
- displayTargetName: mmu_kasan
26+
os: unix
27+
runs_on: ubuntu-22.04
28+
shell: bash
29+
build_options: "MMU=1 MMU_KUNIT=1 kasan=yes"
2530
- displayTargetName: windows-2019
2631
os: windows
2732
runs_on: windows-2019

Diff for: arch/lkl/Kconfig

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
config LKL
22
def_bool y
3-
depends on !SMP && !MMU && !COREDUMP && !SECCOMP && !UPROBES && !COMPAT && !USER_RETURN_NOTIFIER
3+
depends on !SMP && !COREDUMP && !SECCOMP && !UPROBES && !COMPAT && !USER_RETURN_NOTIFIER
44
select ARCH_THREAD_STACK_ALLOCATOR
55
select RWSEM_GENERIC_SPINLOCK
66
select GENERIC_ATOMIC64
@@ -77,6 +77,43 @@ config 64BIT
7777
bool "64bit kernel"
7878
default n
7979

80+
config MMU
81+
bool "LKL MMU implementation"
82+
depends on 64BIT
83+
default n
84+
85+
if MMU
86+
config PGTABLE_LEVELS
87+
int
88+
default 3
89+
90+
config LKL_MEMORY_START
91+
hex
92+
default 0x50000000
93+
help
94+
Base address of kernel virtual address space for LKL. No particular
95+
reason for picking this specific value. It is assumed that the host
96+
mmap is able to map requested amount of memory at this address.
97+
STACK_TOP and VMALLOC_START values depend on it.
98+
99+
100+
config LKL_TASK_UNMAPPED_BASE
101+
hex
102+
default 0x100000
103+
help
104+
Starting virtual address for LKL user-space mmap. It is assumed that
105+
the host mmap is able to map requested amount of memory starting from
106+
this address.
107+
108+
config LKL_MMU_KUNIT_TEST
109+
bool "Kunit tests for LKL MMU"
110+
default n
111+
depends on KUNIT
112+
help
113+
Kunit tests to test correctness of MMU-related kernel interfaces (such
114+
as vmalloc, for example) which are difficult to test in user-space.
115+
endif
116+
80117
config COREDUMP
81118
def_bool n
82119

Diff for: arch/lkl/include/asm/Kbuild

+1
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,4 @@ generic-y += vga.h
7575
generic-y += word-at-a-time.h
7676
generic-y += kprobes.h
7777
generic-y += uaccess.h
78+
generic-y += mman.h

Diff for: arch/lkl/include/asm/elf.h

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
#define ELF_CLASS ELFCLASS32
1010
#endif
1111

12+
#ifdef CONFIG_MMU
13+
#define ELF_EXEC_PAGESIZE 4096
14+
#define ELF_PLATFORM "i586"
15+
#define ELF_HWCAP 0L
16+
#define ELF_ET_DYN_BASE (TASK_SIZE)
17+
#endif // CONFIG_MMU
18+
1219
#define elf_gregset_t long
1320
#define elf_fpregset_t double
1421
#endif

Diff for: arch/lkl/include/asm/io.h

+8
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
9898
return (void __iomem *)lkl_ops->ioremap(offset, size);
9999
}
100100

101+
#ifdef CONFIG_MMU
102+
static inline void __iounmap(void __iomem *addr)
103+
{
104+
// No-op according to ioremap implementation.
105+
}
106+
#define iounmap __iounmap
107+
#endif
108+
101109
#include <asm-generic/io.h>
102110

103111
#endif /* _ASM_LKL_IO_H */

Diff for: arch/lkl/include/asm/mmu_context.h

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22
#ifndef _ASM_LKL_MMU_CONTEXT_H
33
#define _ASM_LKL_MMU_CONTEXT_H
44

5+
#ifdef CONFIG_MMU
6+
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
7+
struct task_struct *tsk) {
8+
// No-op for LKL as it doesn't support multiple user-mode address spaces.
9+
}
10+
11+
/* Generic hooks for arch_dup_mmap and arch_exit_mmap */
12+
#include <asm-generic/mm_hooks.h>
13+
#include <asm-generic/mmu_context.h>
14+
15+
#else
516
#include <asm-generic/nommu_context.h>
17+
#endif
618

719
#endif /* _ASM_LKL_MMU_CONTEXT_H */

Diff for: arch/lkl/include/asm/page-mmu.h

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _ASM_LKL_PAGE_MMU_H
3+
#define _ASM_LKL_PAGE_MMU_H
4+
5+
#include <linux/const.h>
6+
7+
/* PAGE_SHIFT determines the page size */
8+
#define PAGE_SHIFT 12
9+
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
10+
#define PAGE_MASK (~(PAGE_SIZE-1))
11+
#define PFN_PTE_SHIFT PAGE_SHIFT
12+
13+
#ifndef __ASSEMBLY__
14+
15+
struct page;
16+
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
17+
#define copy_page(to, from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
18+
#define clear_user_page(page, vaddr, pg) clear_page(page)
19+
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
20+
21+
typedef struct {unsigned long pte; } pte_t;
22+
typedef struct {unsigned long pmd; } pmd_t;
23+
typedef struct {unsigned long pgd; } pgd_t;
24+
typedef struct {unsigned long pgprot; } pgprot_t;
25+
typedef struct page *pgtable_t;
26+
27+
#define pte_val(p) ((p).pte)
28+
#define pgd_val(x) ((x).pgd)
29+
#define pgprot_val(x) ((x).pgprot)
30+
31+
#define pmd_val(x) ((x).pmd)
32+
#define __pmd(x) ((pmd_t) { (x) })
33+
34+
#define __pte(x) ((pte_t) { (x) })
35+
#define __pgd(x) ((pgd_t) { (x) })
36+
#define __pgprot(x) ((pgprot_t) { (x) })
37+
38+
#define pte_get_bits(p, bits) ((p).pte & (bits))
39+
#define pte_set_bits(p, bits) ((p).pte |= (bits))
40+
#define pte_clear_bits(p, bits) ((p).pte &= ~(bits))
41+
#define pte_copy(to, from) ({ (to).pte = (from).pte; })
42+
#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE))
43+
#define pte_set_val(p, phys, prot) ({ (p).pte = (phys) | pgprot_val(prot); })
44+
45+
extern unsigned long memory_start;
46+
extern unsigned long memory_end;
47+
48+
#define PAGE_OFFSET (memory_start)
49+
// Define ARCH_PFN_OFFSET so that kernel virtual addresses are the same as
50+
// the corresponding physical addresses (i.e. 1-to-1 mapping).
51+
#define ARCH_PFN_OFFSET (memory_start >> PAGE_SHIFT)
52+
53+
#define __pa(virt) ((unsigned long) (virt))
54+
#define __va(phys) ((void *)(phys))
55+
56+
#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
57+
58+
#define phys_to_pfn(p) PHYS_PFN(p)
59+
#define pfn_to_phys(pfn) PFN_PHYS(pfn)
60+
61+
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
62+
63+
#endif // __ASSEMBLY__
64+
65+
#include <asm-generic/memory_model.h>
66+
#include <asm-generic/getorder.h>
67+
68+
#endif // _ASM_LKL_PAGE_MMU_H

Diff for: arch/lkl/include/asm/page.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
12
#ifndef _ASM_LKL_PAGE_H
23
#define _ASM_LKL_PAGE_H
34

5+
#ifndef CONFIG_MMU
46
#define ARCH_PFN_OFFSET (memory_start >> PAGE_SHIFT)
7+
#include <asm-generic/page.h>
8+
#else // CONFIG_MMU
9+
#include <asm/page-mmu.h>
10+
#endif // CONFIG_MMU
511

612
#ifndef __ASSEMBLY__
713
void free_mem(void);
814
void bootmem_init(unsigned long mem_size);
915
#endif
1016

11-
#include <asm-generic/page.h>
12-
1317
#undef PAGE_OFFSET
1418
#define PAGE_OFFSET memory_start
1519

Diff for: arch/lkl/include/asm/pgalloc.h

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _LKL_PGALLOC_H
3+
#define _LKL_PGALLOC_H
4+
5+
#include <linux/mm.h>
6+
#include <linux/mmzone.h>
7+
8+
#include <asm-generic/pgalloc.h>
9+
10+
#ifdef CONFIG_MMU
11+
12+
static inline void pmd_populate_kernel(struct mm_struct *mm,
13+
pmd_t *pmd, pte_t *pte)
14+
{
15+
set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte)));
16+
}
17+
18+
static inline void pmd_populate(struct mm_struct *mm,
19+
pmd_t *pmd, pgtable_t pte)
20+
{
21+
set_pmd(pmd, __pmd(_PAGE_TABLE + (page_to_pfn(pte) << PAGE_SHIFT)));
22+
}
23+
24+
#define pmd_pgtable(pmd) pmd_page(pmd)
25+
26+
extern pgd_t *pgd_alloc(struct mm_struct *mm);
27+
28+
#define __pte_free_tlb(tlb, pte, address) tlb_remove_page((tlb), (pte))
29+
30+
#define __pmd_free_tlb(tlb, pmd, address) \
31+
do { \
32+
pagetable_pmd_dtor(virt_to_ptdesc(pmd)); \
33+
tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pmd)); \
34+
} while (0)
35+
36+
#endif // CONFIG_MMU
37+
38+
#endif /* _LKL_PGALLOC_H */

0 commit comments

Comments
 (0)