Home | History | Annotate | Line # | Download | only in include
pmap_private.h revision 1.1
      1 /*	$NetBSD: pmap_private.h,v 1.1 2022/08/20 23:48:50 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997 Charles D. Cranor and Washington University.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /*
     29  * Copyright (c) 2001 Wasabi Systems, Inc.
     30  * All rights reserved.
     31  *
     32  * Written by Frank van der Linden for Wasabi Systems, Inc.
     33  *
     34  * Redistribution and use in source and binary forms, with or without
     35  * modification, are permitted provided that the following conditions
     36  * are met:
     37  * 1. Redistributions of source code must retain the above copyright
     38  *    notice, this list of conditions and the following disclaimer.
     39  * 2. Redistributions in binary form must reproduce the above copyright
     40  *    notice, this list of conditions and the following disclaimer in the
     41  *    documentation and/or other materials provided with the distribution.
     42  * 3. All advertising materials mentioning features or use of this software
     43  *    must display the following acknowledgement:
     44  *      This product includes software developed for the NetBSD Project by
     45  *      Wasabi Systems, Inc.
     46  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     47  *    or promote products derived from this software without specific prior
     48  *    written permission.
     49  *
     50  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     52  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     53  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     54  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     55  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     56  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     58  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     60  * POSSIBILITY OF SUCH DAMAGE.
     61  */
     62 
     63 #ifndef	_X86_PMAP_PRIVATE_H_
     64 #define	_X86_PMAP_PRIVATE_H_
     65 
     66 #ifndef	_MACHINE_PMAP_PRIVATE_H_X86
     67 #error Include machine/pmap_private.h, not x86/pmap_private.h.
     68 #endif
     69 
     70 #ifdef _KERNEL_OPT
     71 #include "opt_svs.h"
     72 #endif
     73 
     74 #include <sys/param.h>
     75 #include <sys/types.h>
     76 
     77 #include <sys/mutex.h>
     78 #include <sys/pool.h>
     79 #include <sys/queue.h>
     80 
     81 #include <machine/pte.h>
     82 #include <machine/vmparam.h>
     83 
     84 #include <uvm/uvm_pmap.h>
     85 
     86 struct pmap;
     87 
     88 #define SLAREA_USER	0
     89 #define SLAREA_PTE	1
     90 #define SLAREA_MAIN	2
     91 #define SLAREA_PCPU	3
     92 #define SLAREA_DMAP	4
     93 #define SLAREA_HYPV	5
     94 #define SLAREA_ASAN	6
     95 #define SLAREA_MSAN	7
     96 #define SLAREA_KERN	8
     97 #define SLSPACE_NAREAS	9
     98 
     99 struct slotspace {
    100 	struct {
    101 		size_t sslot; /* start slot */
    102 		size_t nslot; /* # of slots */
    103 		bool active;  /* area is active */
    104 	} area[SLSPACE_NAREAS];
    105 };
    106 
    107 extern struct slotspace slotspace;
    108 
    109 #include <x86/gdt.h>
    110 
    111 struct pcpu_entry {
    112 	uint8_t gdt[MAXGDTSIZ];
    113 	uint8_t ldt[MAX_USERLDT_SIZE];
    114 	uint8_t idt[PAGE_SIZE];
    115 	uint8_t tss[PAGE_SIZE];
    116 	uint8_t ist0[PAGE_SIZE];
    117 	uint8_t ist1[PAGE_SIZE];
    118 	uint8_t ist2[PAGE_SIZE];
    119 	uint8_t ist3[PAGE_SIZE];
    120 	uint8_t rsp0[2 * PAGE_SIZE];
    121 } __packed;
    122 
    123 struct pcpu_area {
    124 #ifdef SVS
    125 	uint8_t utls[PAGE_SIZE];
    126 #endif
    127 	uint8_t ldt[PAGE_SIZE];
    128 	struct pcpu_entry ent[MAXCPUS];
    129 } __packed;
    130 
    131 extern struct pcpu_area *pcpuarea;
    132 
    133 #define PMAP_PCID_KERN	0
    134 #define PMAP_PCID_USER	1
    135 
    136 /*
    137  * pmap data structures: see pmap.c for details of locking.
    138  */
    139 
    140 /*
    141  * we maintain a list of all non-kernel pmaps
    142  */
    143 
    144 LIST_HEAD(pmap_head, pmap); /* struct pmap_head: head of a pmap list */
    145 
    146 /*
    147  * linked list of all non-kernel pmaps
    148  */
    149 extern struct pmap_head pmaps;
    150 extern kmutex_t pmaps_lock;    /* protects pmaps */
    151 
    152 /*
    153  * pool_cache(9) that pmaps are allocated from
    154  */
    155 extern struct pool_cache pmap_cache;
    156 
    157 /* macro to access pm_pdirpa slots */
    158 #ifdef PAE
    159 #define pmap_pdirpa(pmap, index) \
    160 	((pmap)->pm_pdirpa[l2tol3(index)] + l2tol2(index) * sizeof(pd_entry_t))
    161 #else
    162 #define pmap_pdirpa(pmap, index) \
    163 	((pmap)->pm_pdirpa[0] + (index) * sizeof(pd_entry_t))
    164 #endif
    165 
    166 /*
    167  * global kernel variables
    168  */
    169 
    170 /*
    171  * PDPpaddr is the physical address of the kernel's PDP.
    172  * - i386 non-PAE and amd64: PDPpaddr corresponds directly to the %cr3
    173  * value associated to the kernel process, proc0.
    174  * - i386 PAE: it still represents the PA of the kernel's PDP (L2). Due to
    175  * the L3 PD, it cannot be considered as the equivalent of a %cr3 any more.
    176  * - Xen: it corresponds to the PFN of the kernel's PDP.
    177  */
    178 extern u_long PDPpaddr;
    179 
    180 extern pd_entry_t pmap_pg_g;			/* do we support PTE_G? */
    181 extern pd_entry_t pmap_pg_nx;			/* do we support PTE_NX? */
    182 extern int pmap_largepages;
    183 extern long nkptp[PTP_LEVELS];
    184 
    185 #define pmap_valid_entry(E) 		((E) & PTE_P) /* is PDE or PTE valid? */
    186 
    187 void		pmap_map_ptes(struct pmap *, struct pmap **, pd_entry_t **,
    188 		    pd_entry_t * const **);
    189 void		pmap_unmap_ptes(struct pmap *, struct pmap *);
    190 
    191 bool		pmap_pdes_valid(vaddr_t, pd_entry_t * const *, pd_entry_t *,
    192 		    int *lastlvl);
    193 
    194 bool		pmap_is_curpmap(struct pmap *);
    195 
    196 void		pmap_ept_transform(struct pmap *);
    197 
    198 #ifndef __HAVE_DIRECT_MAP
    199 void		pmap_vpage_cpu_init(struct cpu_info *);
    200 #endif
    201 vaddr_t		slotspace_rand(int, size_t, size_t, size_t, vaddr_t);
    202 
    203 vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
    204 
    205 typedef enum tlbwhy {
    206 	TLBSHOOT_REMOVE_ALL,
    207 	TLBSHOOT_KENTER,
    208 	TLBSHOOT_KREMOVE,
    209 	TLBSHOOT_FREE_PTP,
    210 	TLBSHOOT_REMOVE_PTE,
    211 	TLBSHOOT_SYNC_PV,
    212 	TLBSHOOT_WRITE_PROTECT,
    213 	TLBSHOOT_ENTER,
    214 	TLBSHOOT_NVMM,
    215 	TLBSHOOT_BUS_DMA,
    216 	TLBSHOOT_BUS_SPACE,
    217 	TLBSHOOT__MAX,
    218 } tlbwhy_t;
    219 
    220 void		pmap_tlb_init(void);
    221 void		pmap_tlb_cpu_init(struct cpu_info *);
    222 void		pmap_tlb_shootdown(pmap_t, vaddr_t, pt_entry_t, tlbwhy_t);
    223 void		pmap_tlb_shootnow(void);
    224 void		pmap_tlb_intr(void);
    225 
    226 /*
    227  * inline functions
    228  */
    229 
    230 /*
    231  * pmap_update_pg: flush one page from the TLB (or flush the whole thing
    232  *	if hardware doesn't support one-page flushing)
    233  */
    234 
    235 __inline static void __unused
    236 pmap_update_pg(vaddr_t va)
    237 {
    238 	invlpg(va);
    239 }
    240 
    241 /*
    242  * various address inlines
    243  *
    244  *  vtopte: return a pointer to the PTE mapping a VA, works only for
    245  *  user and PT addresses
    246  *
    247  *  kvtopte: return a pointer to the PTE mapping a kernel VA
    248  */
    249 
    250 #include <lib/libkern/libkern.h>
    251 
    252 static __inline pt_entry_t * __unused
    253 vtopte(vaddr_t va)
    254 {
    255 
    256 	KASSERT(va < VM_MIN_KERNEL_ADDRESS);
    257 
    258 	return (PTE_BASE + pl1_i(va));
    259 }
    260 
    261 static __inline pt_entry_t * __unused
    262 kvtopte(vaddr_t va)
    263 {
    264 	pd_entry_t *pde;
    265 
    266 	KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
    267 
    268 	pde = L2_BASE + pl2_i(va);
    269 	if (*pde & PTE_PS)
    270 		return ((pt_entry_t *)pde);
    271 
    272 	return (PTE_BASE + pl1_i(va));
    273 }
    274 
    275 #ifdef XENPV
    276 #include <sys/bitops.h>
    277 
    278 #define XPTE_MASK	L1_FRAME
    279 /* Selects the index of a PTE in (A)PTE_BASE */
    280 #define XPTE_SHIFT	(L1_SHIFT - ilog2(sizeof(pt_entry_t)))
    281 
    282 /* PTE access inline functions */
    283 
    284 /*
    285  * Get the machine address of the pointed pte
    286  * We use hardware MMU to get value so works only for levels 1-3
    287  */
    288 
    289 static __inline paddr_t
    290 xpmap_ptetomach(pt_entry_t *pte)
    291 {
    292 	pt_entry_t *up_pte;
    293 	vaddr_t va = (vaddr_t) pte;
    294 
    295 	va = ((va & XPTE_MASK) >> XPTE_SHIFT) | (vaddr_t) PTE_BASE;
    296 	up_pte = (pt_entry_t *) va;
    297 
    298 	return (paddr_t) (((*up_pte) & PTE_FRAME) + (((vaddr_t) pte) & (~PTE_FRAME & ~VA_SIGN_MASK)));
    299 }
    300 
    301 /* Xen helpers to change bits of a pte */
    302 #define XPMAP_UPDATE_DIRECT	1	/* Update direct map entry flags too */
    303 
    304 paddr_t	vtomach(vaddr_t);
    305 #define vtomfn(va) (vtomach(va) >> PAGE_SHIFT)
    306 #endif	/* XENPV */
    307 
    308 #ifdef __HAVE_PCPU_AREA
    309 extern struct pcpu_area *pcpuarea;
    310 #define PDIR_SLOT_PCPU		510
    311 #define PMAP_PCPU_BASE		(VA_SIGN_NEG((PDIR_SLOT_PCPU * NBPD_L4)))
    312 #endif
    313 
    314 void	svs_quad_copy(void *, void *, long);
    315 
    316 #endif	/* _X86_PMAP_PRIVATE_H_ */
    317