riscv: Move KASAN mapping next to the kernel mapping

Now that KASAN_SHADOW_OFFSET is defined at compile time as a config,
this value must remain constant whatever the size of the virtual address
space, which is only possible by pushing this region at the end of the
address space next to the kernel mapping.

Signed-off-by: Alexandre Ghiti <alexandre.ghiti@canonical.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
Alexandre Ghiti 2021-12-06 11:46:45 +01:00 committed by Palmer Dabbelt
parent db1503d355
commit f7ae02333d
No known key found for this signature in database
GPG Key ID: 2E1319F35FBB1889
6 changed files with 38 additions and 31 deletions

View File

@ -47,12 +47,12 @@ RISC-V Linux Kernel SV39
| Kernel-space virtual memory, shared between all processes: | Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________ ____________________________________________________________|___________________________________________________________
| | | | | | | |
ffffffc000000000 | -256 GB | ffffffc7ffffffff | 32 GB | kasan ffffffc6fee00000 | -228 GB | ffffffc6feffffff | 2 MB | fixmap
ffffffcefee00000 | -196 GB | ffffffcefeffffff | 2 MB | fixmap ffffffc6ff000000 | -228 GB | ffffffc6ffffffff | 16 MB | PCI io
ffffffceff000000 | -196 GB | ffffffceffffffff | 16 MB | PCI io ffffffc700000000 | -228 GB | ffffffc7ffffffff | 4 GB | vmemmap
ffffffcf00000000 | -196 GB | ffffffcfffffffff | 4 GB | vmemmap ffffffc800000000 | -224 GB | ffffffd7ffffffff | 64 GB | vmalloc/ioremap space
ffffffd000000000 | -192 GB | ffffffdfffffffff | 64 GB | vmalloc/ioremap space ffffffd800000000 | -160 GB | fffffff6ffffffff | 124 GB | direct mapping of all physical memory
ffffffe000000000 | -128 GB | ffffffff7fffffff | 124 GB | direct mapping of all physical memory fffffff700000000 | -36 GB | fffffffeffffffff | 32 GB | kasan
__________________|____________|__________________|_________|____________________________________________________________ __________________|____________|__________________|_________|____________________________________________________________
| |
| |

View File

@ -160,12 +160,12 @@ config PAGE_OFFSET
hex hex
default 0xC0000000 if 32BIT default 0xC0000000 if 32BIT
default 0x80000000 if 64BIT && !MMU default 0x80000000 if 64BIT && !MMU
default 0xffffffe000000000 if 64BIT default 0xffffffd800000000 if 64BIT
config KASAN_SHADOW_OFFSET config KASAN_SHADOW_OFFSET
hex hex
depends on KASAN_GENERIC depends on KASAN_GENERIC
default 0xdfffffc800000000 if 64BIT default 0xdfffffff00000000 if 64BIT
default 0xffffffff if 32BIT default 0xffffffff if 32BIT
config ARCH_FLATMEM_ENABLE config ARCH_FLATMEM_ENABLE

View File

@ -28,8 +28,8 @@
#define KASAN_SHADOW_SCALE_SHIFT 3 #define KASAN_SHADOW_SCALE_SHIFT 3
#define KASAN_SHADOW_SIZE (UL(1) << ((CONFIG_VA_BITS - 1) - KASAN_SHADOW_SCALE_SHIFT)) #define KASAN_SHADOW_SIZE (UL(1) << ((CONFIG_VA_BITS - 1) - KASAN_SHADOW_SCALE_SHIFT))
#define KASAN_SHADOW_START KERN_VIRT_START #define KASAN_SHADOW_START (KASAN_SHADOW_END - KASAN_SHADOW_SIZE)
#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE) #define KASAN_SHADOW_END MODULES_LOWEST_VADDR
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
void kasan_init(void); void kasan_init(void);

View File

@ -33,8 +33,6 @@
*/ */
#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) #define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
#define KERN_VIRT_SIZE (-PAGE_OFFSET)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) #define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)

View File

@ -24,6 +24,17 @@
#define KERNEL_LINK_ADDR PAGE_OFFSET #define KERNEL_LINK_ADDR PAGE_OFFSET
#endif #endif
/* Number of entries in the page global directory */
#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t))
/* Number of entries in the page table */
#define PTRS_PER_PTE (PAGE_SIZE / sizeof(pte_t))
/*
* Half of the kernel address space (half of the entries of the page global
* directory) is for the direct mapping.
*/
#define KERN_VIRT_SIZE ((PTRS_PER_PGD / 2 * PGDIR_SIZE) / 2)
#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
#define VMALLOC_END (PAGE_OFFSET - 1) #define VMALLOC_END (PAGE_OFFSET - 1)
#define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE) #define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE)
@ -39,8 +50,10 @@
/* Modules always live before the kernel */ /* Modules always live before the kernel */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define MODULES_VADDR (PFN_ALIGN((unsigned long)&_end) - SZ_2G) /* This is used to define the end of the KASAN shadow region */
#define MODULES_END (PFN_ALIGN((unsigned long)&_start)) #define MODULES_LOWEST_VADDR (KERNEL_LINK_ADDR - SZ_2G)
#define MODULES_VADDR (PFN_ALIGN((unsigned long)&_end) - SZ_2G)
#define MODULES_END (PFN_ALIGN((unsigned long)&_start))
#endif #endif
/* /*
@ -108,11 +121,6 @@
#endif /* CONFIG_XIP_KERNEL */ #endif /* CONFIG_XIP_KERNEL */
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
/* Number of entries in the page global directory */
#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t))
/* Number of entries in the page table */
#define PTRS_PER_PTE (PAGE_SIZE / sizeof(pte_t))
/* Number of PGD entries that a user-mode program can use */ /* Number of PGD entries that a user-mode program can use */
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)

View File

@ -103,6 +103,9 @@ static void __init print_vm_layout(void)
print_mlm("lowmem", (unsigned long)PAGE_OFFSET, print_mlm("lowmem", (unsigned long)PAGE_OFFSET,
(unsigned long)high_memory); (unsigned long)high_memory);
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#ifdef CONFIG_KASAN
print_mlm("kasan", KASAN_SHADOW_START, KASAN_SHADOW_END);
#endif
print_mlm("kernel", (unsigned long)KERNEL_LINK_ADDR, print_mlm("kernel", (unsigned long)KERNEL_LINK_ADDR,
(unsigned long)ADDRESS_SPACE_END); (unsigned long)ADDRESS_SPACE_END);
#endif #endif
@ -130,18 +133,8 @@ void __init mem_init(void)
print_vm_layout(); print_vm_layout();
} }
/* /* Limit the memory size via mem. */
* The default maximal physical memory size is -PAGE_OFFSET for 32-bit kernel, static phys_addr_t memory_limit;
* whereas for 64-bit kernel, the end of the virtual address space is occupied
* by the modules/BPF/kernel mappings which reduces the available size of the
* linear mapping.
* Limit the memory size via mem.
*/
#ifdef CONFIG_64BIT
static phys_addr_t memory_limit = -PAGE_OFFSET - SZ_4G;
#else
static phys_addr_t memory_limit = -PAGE_OFFSET;
#endif
static int __init early_mem(char *p) static int __init early_mem(char *p)
{ {
@ -612,6 +605,14 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
riscv_pfn_base = PFN_DOWN(kernel_map.phys_addr); riscv_pfn_base = PFN_DOWN(kernel_map.phys_addr);
/*
* The default maximal physical memory size is KERN_VIRT_SIZE for 32-bit
* kernel, whereas for 64-bit kernel, the end of the virtual address
* space is occupied by the modules/BPF/kernel mappings which reduces
* the available size of the linear mapping.
*/
memory_limit = KERN_VIRT_SIZE - (IS_ENABLED(CONFIG_64BIT) ? SZ_4G : 0);
/* Sanity check alignment and size */ /* Sanity check alignment and size */
BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0);
BUG_ON((kernel_map.phys_addr % PMD_SIZE) != 0); BUG_ON((kernel_map.phys_addr % PMD_SIZE) != 0);