1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/sched.h> 3 #include <linux/kernel.h> 4 #include <linux/errno.h> 5 #include <linux/mm.h> 6 #include <linux/nmi.h> 7 #include <linux/swap.h> 8 #include <linux/smp.h> 9 #include <linux/highmem.h> 10 #include <linux/pagemap.h> 11 #include <linux/spinlock.h> 12 13 #include <asm/cpu_entry_area.h> 14 #include <asm/pgtable.h> 15 #include <asm/pgalloc.h> 16 #include <asm/fixmap.h> 17 #include <asm/e820/api.h> 18 #include <asm/tlb.h> 19 #include <asm/tlbflush.h> 20 #include <asm/io.h> 21 #include <linux/vmalloc.h> 22 23 unsigned int __VMALLOC_RESERVE = 128 << 20; 24 25 /* 26 * Associate a virtual page frame with a given physical page frame 27 * and protection flags for that frame. 28 */ 29 void set_pte_vaddr(unsigned long vaddr, pte_t pteval) 30 { 31 pgd_t *pgd; 32 p4d_t *p4d; 33 pud_t *pud; 34 pmd_t *pmd; 35 pte_t *pte; 36 37 pgd = swapper_pg_dir + pgd_index(vaddr); 38 if (pgd_none(*pgd)) { 39 BUG(); 40 return; 41 } 42 p4d = p4d_offset(pgd, vaddr); 43 if (p4d_none(*p4d)) { 44 BUG(); 45 return; 46 } 47 pud = pud_offset(p4d, vaddr); 48 if (pud_none(*pud)) { 49 BUG(); 50 return; 51 } 52 pmd = pmd_offset(pud, vaddr); 53 if (pmd_none(*pmd)) { 54 BUG(); 55 return; 56 } 57 pte = pte_offset_kernel(pmd, vaddr); 58 if (!pte_none(pteval)) 59 set_pte_at(&init_mm, vaddr, pte, pteval); 60 else 61 pte_clear(&init_mm, vaddr, pte); 62 63 /* 64 * It's enough to flush this one mapping. 65 * (PGE mappings get flushed as well) 66 */ 67 __flush_tlb_one_kernel(vaddr); 68 } 69 70 unsigned long __FIXADDR_TOP = 0xfffff000; 71 EXPORT_SYMBOL(__FIXADDR_TOP); 72 73 /* 74 * vmalloc=size forces the vmalloc area to be exactly 'size' 75 * bytes. This can be used to increase (or decrease) the 76 * vmalloc area - the default is 128m. 77 */ 78 static int __init parse_vmalloc(char *arg) 79 { 80 if (!arg) 81 return -EINVAL; 82 83 /* Add VMALLOC_OFFSET to the parsed value due to vm area guard hole*/ 84 __VMALLOC_RESERVE = memparse(arg, &arg) + VMALLOC_OFFSET; 85 return 0; 86 } 87 early_param("vmalloc", parse_vmalloc); 88 89 /* 90 * reservetop=size reserves a hole at the top of the kernel address space which 91 * a hypervisor can load into later. Needed for dynamically loaded hypervisors, 92 * so relocating the fixmap can be done before paging initialization. 93 */ 94 static int __init parse_reservetop(char *arg) 95 { 96 unsigned long address; 97 98 if (!arg) 99 return -EINVAL; 100 101 address = memparse(arg, &arg); 102 reserve_top_address(address); 103 early_ioremap_init(); 104 return 0; 105 } 106 early_param("reservetop", parse_reservetop); 107