Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/sched.h>
0003 #include <linux/kernel.h>
0004 #include <linux/errno.h>
0005 #include <linux/mm.h>
0006 #include <linux/nmi.h>
0007 #include <linux/swap.h>
0008 #include <linux/smp.h>
0009 #include <linux/highmem.h>
0010 #include <linux/pagemap.h>
0011 #include <linux/spinlock.h>
0012 
0013 #include <asm/cpu_entry_area.h>
0014 #include <asm/fixmap.h>
0015 #include <asm/e820/api.h>
0016 #include <asm/tlb.h>
0017 #include <asm/tlbflush.h>
0018 #include <asm/io.h>
0019 #include <linux/vmalloc.h>
0020 
0021 unsigned int __VMALLOC_RESERVE = 128 << 20;
0022 
0023 /*
0024  * Associate a virtual page frame with a given physical page frame 
0025  * and protection flags for that frame.
0026  */ 
0027 void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
0028 {
0029     pgd_t *pgd;
0030     p4d_t *p4d;
0031     pud_t *pud;
0032     pmd_t *pmd;
0033     pte_t *pte;
0034 
0035     pgd = swapper_pg_dir + pgd_index(vaddr);
0036     if (pgd_none(*pgd)) {
0037         BUG();
0038         return;
0039     }
0040     p4d = p4d_offset(pgd, vaddr);
0041     if (p4d_none(*p4d)) {
0042         BUG();
0043         return;
0044     }
0045     pud = pud_offset(p4d, vaddr);
0046     if (pud_none(*pud)) {
0047         BUG();
0048         return;
0049     }
0050     pmd = pmd_offset(pud, vaddr);
0051     if (pmd_none(*pmd)) {
0052         BUG();
0053         return;
0054     }
0055     pte = pte_offset_kernel(pmd, vaddr);
0056     if (!pte_none(pteval))
0057         set_pte_at(&init_mm, vaddr, pte, pteval);
0058     else
0059         pte_clear(&init_mm, vaddr, pte);
0060 
0061     /*
0062      * It's enough to flush this one mapping.
0063      * (PGE mappings get flushed as well)
0064      */
0065     flush_tlb_one_kernel(vaddr);
0066 }
0067 
0068 unsigned long __FIXADDR_TOP = 0xfffff000;
0069 EXPORT_SYMBOL(__FIXADDR_TOP);
0070 
0071 /*
0072  * vmalloc=size forces the vmalloc area to be exactly 'size'
0073  * bytes. This can be used to increase (or decrease) the
0074  * vmalloc area - the default is 128m.
0075  */
0076 static int __init parse_vmalloc(char *arg)
0077 {
0078     if (!arg)
0079         return -EINVAL;
0080 
0081     /* Add VMALLOC_OFFSET to the parsed value due to vm area guard hole*/
0082     __VMALLOC_RESERVE = memparse(arg, &arg) + VMALLOC_OFFSET;
0083     return 0;
0084 }
0085 early_param("vmalloc", parse_vmalloc);
0086 
0087 /*
0088  * reservetop=size reserves a hole at the top of the kernel address space which
0089  * a hypervisor can load into later.  Needed for dynamically loaded hypervisors,
0090  * so relocating the fixmap can be done before paging initialization.
0091  */
0092 static int __init parse_reservetop(char *arg)
0093 {
0094     unsigned long address;
0095 
0096     if (!arg)
0097         return -EINVAL;
0098 
0099     address = memparse(arg, &arg);
0100     reserve_top_address(address);
0101     early_ioremap_init();
0102     return 0;
0103 }
0104 early_param("reservetop", parse_reservetop);