1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019 Joyent, Inc. 14 * Copyright 2021 Oxide Computer Company 15 */ 16 17 #ifndef _VMM_GPT_H 18 #define _VMM_GPT_H 19 20 #include <sys/types.h> 21 22 /* 23 * Constants for the nodes in the GPT radix tree. Note 24 * that, in accordance with hardware page table descriptions, 25 * the root of the tree is referred to as "LEVEL4" while the 26 * leaf level is "LEVEL1". 27 */ 28 enum vmm_gpt_node_level { 29 LEVEL4 = 0, 30 LEVEL3, 31 LEVEL2, 32 LEVEL1, 33 MAX_GPT_LEVEL, 34 }; 35 36 /* 37 * The vmm_pte_ops structure contains function pointers for format-specific 38 * operations on page table entries. The operations are as follows: 39 * 40 * vpeo_map_table: Creates a PTE that maps an inner node in the page table. 41 * vpeo_map_page: Creates a leaf entry PTE that maps a page of physical memory. 42 * vpeo_pte_pfn: Returns the PFN contained in the given PTE. 43 * vpeo_pte_is_present: Returns true IFF the PTE maps a present page. 44 * vpeo_pte_prot: Returns a bitmask of protection bits for the PTE. 45 * The bits correspond to the standard mmap(2) bits: PROT_READ, PROT_WRITE, 46 * PROT_EXEC. 47 * vpeo_reset_dirty: Resets the dirty bit on the given PTE. If the second 48 * argument is `true`, the bit will be set, otherwise it will be cleared. 49 * Returns non-zero if the previous value of the bit was set. 50 * vpeo_reset_accessed: Resets the accessed bit on the given PTE. If the 51 * second argument is `true`, the bit will be set, otherwise it will be 52 * cleared. Returns non-zero if the previous value of the bit was set. 53 * vpeo_get_pmtp: Generate a properly formatted PML4 (EPTP/nCR3), given the root 54 * PFN for the GPT. 55 */ 56 typedef struct vmm_pte_ops vmm_pte_ops_t; 57 struct vmm_pte_ops { 58 uint64_t (*vpeo_map_table)(pfn_t); 59 uint64_t (*vpeo_map_page)(pfn_t, uint_t, uint8_t); 60 pfn_t (*vpeo_pte_pfn)(uint64_t); 61 bool (*vpeo_pte_is_present)(uint64_t); 62 uint_t (*vpeo_pte_prot)(uint64_t); 63 uint_t (*vpeo_reset_dirty)(uint64_t *, bool); 64 uint_t (*vpeo_reset_accessed)(uint64_t *, bool); 65 uint64_t (*vpeo_get_pmtp)(pfn_t); 66 }; 67 68 extern vmm_pte_ops_t ept_pte_ops; 69 extern vmm_pte_ops_t rvi_pte_ops; 70 71 struct vmm_gpt; 72 typedef struct vmm_gpt vmm_gpt_t; 73 74 vmm_gpt_t *vmm_gpt_alloc(vmm_pte_ops_t *); 75 void vmm_gpt_free(vmm_gpt_t *); 76 77 uint64_t *vmm_gpt_lookup(vmm_gpt_t *, uint64_t); 78 void vmm_gpt_walk(vmm_gpt_t *, uint64_t, uint64_t **, enum vmm_gpt_node_level); 79 void vmm_gpt_populate_region(vmm_gpt_t *, uint64_t, uint64_t); 80 bool vmm_gpt_map_at(vmm_gpt_t *, uint64_t *, pfn_t, uint_t, uint8_t); 81 void vmm_gpt_vacate_region(vmm_gpt_t *, uint64_t, uint64_t); 82 bool vmm_gpt_map(vmm_gpt_t *, uint64_t, pfn_t, uint_t, uint8_t); 83 bool vmm_gpt_unmap(vmm_gpt_t *, uint64_t); 84 size_t vmm_gpt_unmap_region(vmm_gpt_t *, uint64_t, uint64_t); 85 uint64_t vmm_gpt_get_pmtp(vmm_gpt_t *); 86 87 bool vmm_gpt_is_mapped(vmm_gpt_t *, uint64_t *, pfn_t *, uint_t *); 88 uint_t vmm_gpt_reset_accessed(vmm_gpt_t *, uint64_t *, bool); 89 uint_t vmm_gpt_reset_dirty(vmm_gpt_t *, uint64_t *, bool); 90 91 #endif /* _VMM_GPT_H */ 92