* Bootstrap the system enough to run with virtual memory. * * On amd64 this is called after mapping has already been enabled * and just syncs the pmap module with what has already been done. * [We can't call it easily with mapping off since the kernel is not * mapped with PA == VA, hence we would have to relocate every address * from the linked base (virtual) address "KERNBASE" to the actual
| 1777 | * (physical) address starting relative to 0] |
| 1778 | */ |
| 1779 | void |
| 1780 | pmap_bootstrap(vm_paddr_t *firstaddr) |
| 1781 | { |
| 1782 | vm_offset_t va; |
| 1783 | pt_entry_t *pte, *pcpu_pte; |
| 1784 | struct region_descriptor r_gdt; |
| 1785 | uint64_t cr4, pcpu_phys; |
| 1786 | u_long res; |
| 1787 | int i; |
| 1788 | |
| 1789 | KERNend = *firstaddr; |
| 1790 | res = atop(KERNend - (vm_paddr_t)kernphys); |
| 1791 | |
| 1792 | if (!pti) |
| 1793 | pg_g = X86_PG_G; |
| 1794 | |
| 1795 | /* |
| 1796 | * Create an initial set of page tables to run the kernel in. |
| 1797 | */ |
| 1798 | create_pagetables(firstaddr); |
| 1799 | |
| 1800 | pcpu_phys = allocpages(firstaddr, MAXCPU); |
| 1801 | |
| 1802 | /* |
| 1803 | * Add a physical memory segment (vm_phys_seg) corresponding to the |
| 1804 | * preallocated kernel page table pages so that vm_page structures |
| 1805 | * representing these pages will be created. The vm_page structures |
| 1806 | * are required for promotion of the corresponding kernel virtual |
| 1807 | * addresses to superpage mappings. |
| 1808 | */ |
| 1809 | vm_phys_early_add_seg(KPTphys, KPTphys + ptoa(nkpt)); |
| 1810 | |
| 1811 | /* |
| 1812 | * Account for the virtual addresses mapped by create_pagetables(). |
| 1813 | */ |
| 1814 | virtual_avail = (vm_offset_t)KERNBASE + round_2mpage(KERNend); |
| 1815 | virtual_end = VM_MAX_KERNEL_ADDRESS; |
| 1816 | |
| 1817 | /* |
| 1818 | * Enable PG_G global pages, then switch to the kernel page |
| 1819 | * table from the bootstrap page table. After the switch, it |
| 1820 | * is possible to enable SMEP and SMAP since PG_U bits are |
| 1821 | * correct now. |
| 1822 | */ |
| 1823 | cr4 = rcr4(); |
| 1824 | cr4 |= CR4_PGE; |
| 1825 | load_cr4(cr4); |
| 1826 | load_cr3(KPML4phys); |
| 1827 | if (cpu_stdext_feature & CPUID_STDEXT_SMEP) |
| 1828 | cr4 |= CR4_SMEP; |
| 1829 | if (cpu_stdext_feature & CPUID_STDEXT_SMAP) |
| 1830 | cr4 |= CR4_SMAP; |
| 1831 | load_cr4(cr4); |
| 1832 | |
| 1833 | /* |
| 1834 | * Initialize the kernel pmap (which is statically allocated). |
| 1835 | * Count bootstrap data as being resident in case any of this data is |
| 1836 | * later unmapped (using pmap_remove()) and freed. |
no test coverage detected