summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/vmm/sys/vmm_gpt.h
blob: a425fb53ec1e1ae49f9eaf8acd850d5d6ea37a77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2019 Joyent, Inc.
 * Copyright 2021 Oxide Computer Company
 */

#ifndef _VMM_GPT_H
#define	_VMM_GPT_H

#include <sys/types.h>

/*
 * Constants for the nodes in the GPT radix tree.  Note
 * that, in accordance with hardware page table descriptions,
 * the root of the tree is referred to as "LEVEL4" while the
 * leaf level is "LEVEL1".
 */
enum vmm_gpt_node_level {
	LEVEL4 = 0,
	LEVEL3,
	LEVEL2,
	LEVEL1,
	MAX_GPT_LEVEL,
};

/*
 * The vmm_pte_ops structure contains function pointers for format-specific
 * operations on page table entries.  The operations are as follows:
 *
 * vpeo_map_table: Creates a PTE that maps an inner node in the page table.
 * vpeo_map_page: Creates a leaf entry PTE that maps a page of physical memory.
 * vpeo_pte_pfn: Returns the PFN contained in the given PTE.
 * vpeo_pte_is_present: Returns true IFF the PTE maps a present page.
 * vpeo_pte_prot: Returns a bitmask of protection bits for the PTE.
 *   The bits correspond to the standard mmap(2) bits: PROT_READ, PROT_WRITE,
 *   PROT_EXEC.
 * vpeo_reset_dirty: Resets the dirty bit on the given PTE.  If the second
 *   argument is `true`, the bit will be set, otherwise it will be cleared.
 *   Returns non-zero if the previous value of the bit was set.
 * vpeo_reset_accessed: Resets the accessed bit on the given PTE.  If the
 *   second argument is `true`, the bit will be set, otherwise it will be
 *   cleared.  Returns non-zero if the previous value of the bit was set.
 * vpeo_get_pmtp: Generate a properly formatted PML4 (EPTP/nCR3), given the root
 *   PFN for the GPT.
 */
typedef struct vmm_pte_ops vmm_pte_ops_t;
struct vmm_pte_ops {
	uint64_t	(*vpeo_map_table)(pfn_t);
	uint64_t	(*vpeo_map_page)(pfn_t, uint_t, uint8_t);
	pfn_t		(*vpeo_pte_pfn)(uint64_t);
	bool		(*vpeo_pte_is_present)(uint64_t);
	uint_t		(*vpeo_pte_prot)(uint64_t);
	uint_t		(*vpeo_reset_dirty)(uint64_t *, bool);
	uint_t		(*vpeo_reset_accessed)(uint64_t *, bool);
	uint64_t	(*vpeo_get_pmtp)(pfn_t);
};

extern vmm_pte_ops_t ept_pte_ops;
extern vmm_pte_ops_t rvi_pte_ops;

struct vmm_gpt;
typedef struct vmm_gpt vmm_gpt_t;

vmm_gpt_t *vmm_gpt_alloc(vmm_pte_ops_t *);
void vmm_gpt_free(vmm_gpt_t *);

uint64_t *vmm_gpt_lookup(vmm_gpt_t *, uint64_t);
void vmm_gpt_walk(vmm_gpt_t *, uint64_t, uint64_t **, enum vmm_gpt_node_level);
void vmm_gpt_populate_region(vmm_gpt_t *, uint64_t, uint64_t);
bool vmm_gpt_map_at(vmm_gpt_t *, uint64_t *, pfn_t, uint_t, uint8_t);
void vmm_gpt_vacate_region(vmm_gpt_t *, uint64_t, uint64_t);
bool vmm_gpt_map(vmm_gpt_t *, uint64_t, pfn_t, uint_t, uint8_t);
bool vmm_gpt_unmap(vmm_gpt_t *, uint64_t);
size_t vmm_gpt_unmap_region(vmm_gpt_t *, uint64_t, uint64_t);
uint64_t vmm_gpt_get_pmtp(vmm_gpt_t *);

bool vmm_gpt_is_mapped(vmm_gpt_t *, uint64_t *, pfn_t *, uint_t *);
uint_t vmm_gpt_reset_accessed(vmm_gpt_t *, uint64_t *, bool);
uint_t vmm_gpt_reset_dirty(vmm_gpt_t *, uint64_t *, bool);

#endif /* _VMM_GPT_H */