Bitdefender Hypervisor Memory Introspection
pgtable.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef _PGTABLE_H_
6 #define _PGTABLE_H_
7 
8 #include "intro_types.h"
9 
10 #define PAGE_SIZE_4K 4096u
11 #define PAGE_OFFSET_MASK_4K (PAGE_SIZE_4K - 1)
12 #define PAGE_MAX_OFFSET_4K PAGE_OFFSET_MASK_4K
13 #define PAGE_BASE_MASK_4K (0xFFFFFFFFFFFFFFFFULL - PAGE_MAX_OFFSET_4K)
14 
15 #define PAGE_SIZE_2M (2 * ONE_MEGABYTE)
16 #define PAGE_OFFSET_MASK_2M (PAGE_SIZE_2M - 1)
17 #define PAGE_MAX_OFFSET_2M PAGE_OFFSET_MASK_2M
18 #define PAGE_BASE_MASK_2M (0xFFFFFFFFFFFFFFFFULL - PAGE_MAX_OFFSET_2M)
19 
20 #define PAGE_SIZE_4M (4 * ONE_MEGABYTE)
21 #define PAGE_OFFSET_MASK_4M (PAGE_SIZE_4M - 1)
22 #define PAGE_MAX_OFFSET_4M PAGE_OFFSET_MASK_4M
23 #define PAGE_BASE_MASK_4M (0xFFFFFFFFFFFFFFFFULL - PAGE_MAX_OFFSET_4M)
24 
25 #define PAGE_SIZE_1G (ONE_GIGABYTE)
26 #define PAGE_OFFSET_MASK_1G (PAGE_SIZE_1G - 1)
27 #define PAGE_MAX_OFFSET_1G PAGE_OFFSET_MASK_1G
28 #define PAGE_BASE_MASK_1G (0xFFFFFFFFFFFFFFFFULL - PAGE_MAX_OFFSET_1G)
29 
30 #define PAGE_SIZE PAGE_SIZE_4K
31 #define PAGE_OFFSET_MASK PAGE_OFFSET_MASK_4K
32 #define PAGE_OFFSET PAGE_OFFSET_MASK
33 #define PAGE_MAX_OFFSET PAGE_MAX_OFFSET_4K
34 #define PAGE_BASE_MASK PAGE_BASE_MASK_4K
35 #define PAGE_MASK PAGE_BASE_MASK
36 
37 // Intel tells us that MAXPHYADDR is 52 bit wide; it will never be larger (in this Universe at least...)
38 #define PHYS_PAGE_MASK 0x000FFFFFFFFFF000ULL
39 
40 // These are the page access bits defined by Intel
41 #define PML5_P BIT(0)
42 #define PML5_RW BIT(1)
43 #define PML5_US BIT(2)
44 #define PML5_PWT BIT(3)
45 #define PML5_PCD BIT(4)
46 #define PML5_A BIT(5)
47 #define PML5_PS BIT(7)
48 #define PML5_LNK BIT(9)
49 #define PML5_USED BIT(10)
50 
51 #define PML4_P BIT(0)
52 #define PML4_RW BIT(1)
53 #define PML4_US BIT(2)
54 #define PML4_PWT BIT(3)
55 #define PML4_PCD BIT(4)
56 #define PML4_A BIT(5)
57 #define PML4_PS BIT(7)
58 #define PML4_LNK BIT(9)
59 #define PML4_USED BIT(10)
60 
61 #define PDP_P BIT(0)
62 #define PDP_RW BIT(1)
63 #define PDP_US BIT(2)
64 #define PDP_PWT BIT(3)
65 #define PDP_PCD BIT(4)
66 #define PDP_A BIT(5)
67 #define PDP_PS BIT(7)
68 #define PDP_LNK BIT(9)
69 #define PDP_USED BIT(10)
70 
71 #define PD_P BIT(0)
72 #define PD_RW BIT(1)
73 #define PD_US BIT(2)
74 #define PD_PWT BIT(3)
75 #define PD_PCD BIT(4)
76 #define PD_A BIT(5)
77 #define PD_D BIT(6)
78 #define PD_PS BIT(7)
79 #define PD_G BIT(8)
80 #define PD_LNK BIT(9)
81 #define PD_USED BIT(10)
82 
83 #define PT_P BIT(0)
84 #define PT_RW BIT(1)
85 #define PT_US BIT(2)
86 #define PT_PWT BIT(3)
87 #define PT_PCD BIT(4)
88 #define PT_A BIT(5)
89 #define PT_D BIT(6)
90 #define PT_PAT BIT(7)
91 #define PT_G BIT(8)
92 #define PT_XD BIT(63)
93 
94 #define PML5_INDEX(a) (DWORD)(((a) & 0x01ff000000000000) >> 48)
95 #define PML4_INDEX(a) (DWORD)(((a) & 0x0000ff8000000000) >> 39)
96 #define PDP_INDEX(a) (DWORD)(((a) & 0x0000007fc0000000) >> 30)
97 #define PD_INDEX(a) (DWORD)(((a) & 0x000000003fe00000) >> 21)
98 #define PT_INDEX(a) (DWORD)(((a) & 0x00000000001ff000) >> 12)
99 
100 // Paging structure indexes definitions - for 32 bit mode
101 // legacy PAE
102 #define PDPPAE_INDEX(a) (DWORD)(((a) & 0x00000000c0000000) >> 30)
103 #define PDPAE_INDEX(a) (DWORD)(((a) & 0x000000003fe00000) >> 21)
104 #define PTPAE_INDEX(a) (DWORD)(((a) & 0x00000000001ff000) >> 12)
105 
106 // legacy NON-PAE
107 #define PD32_INDEX(a) (DWORD)(((a) & 0x00000000ffc00000) >> 22)
108 #define PT32_INDEX(a) (DWORD)(((a) & 0x00000000003ff000) >> 12)
109 
110 #define CR3_LEGACY_PAE_MASK 0x00000000FFFFFFE0
111 #define CR3_LEGACY_NON_PAE_MASK 0x00000000FFFFF000
112 #define CR3_LONG_MODE_MASK PHYS_PAGE_MASK
113 
119 #define CLEAN_PHYS_ADDRESS64(x) ((x) & CR3_LONG_MODE_MASK)
120 
126 #define CLEAN_PHYS_ADDRESS32(x) ((x) & CR3_LEGACY_NON_PAE_MASK)
127 
133 #define CLEAN_PHYS_ADDRESS32PAE(x) ((x) & CR3_LONG_MODE_MASK)
134 
140 #define CLEAN_PHYS_ADDRESS32PAE_ROOT(x) ((x) & CR3_LEGACY_PAE_MASK)
141 
147 #define PAGE_SX(addr) (((addr) & 0x800000000000) ? ((addr) | 0xFFFF000000000000) : (addr))
148 
155 #define PAGE_SPLIT(p, s) (((p) & PAGE_OFFSET) > (((p) + (s) - 1) & PAGE_OFFSET))
156 
163 #define PAGE_REMAINING(addr) (PAGE_SIZE_4K - ((addr) & PAGE_OFFSET_MASK_4K))
164 
165 #define PAGE_OFFSET_4K(addr) ((addr) & PAGE_OFFSET_MASK_4K)
166 #define PAGE_FRAME_NUMBER_4K(addr) ((addr) >> 12ULL)
167 
174 #define PAGE_COUNT_4K(addr, bytes) (PAGE_FRAME_NUMBER_4K(PAGE_OFFSET_4K(addr) + (bytes) + PAGE_MAX_OFFSET_4K))
175 
181 #define PAGE_FRAME_NUMBER(addr) PAGE_FRAME_NUMBER_4K(addr)
182 
189 #define PAGE_COUNT(addr, bytes) PAGE_COUNT_4K(addr, bytes)
190 
191 #endif // _PGTABLE_H_
Exposes the types and constants used by various Introcore APIs defined in glueiface.h.