This source file includes following definitions.
- alloc_pgt_page
- initialize_identity_maps
- add_identity_map
- finalize_identity_maps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #define __pa(x) ((unsigned long)(x))
17 #define __va(x) ((void *)((unsigned long)(x)))
18
19
20 #undef CONFIG_PAGE_TABLE_ISOLATION
21
22 #include "misc.h"
23
24
25 #include <asm/init.h>
26 #include <asm/pgtable.h>
27
28 #undef __PAGE_OFFSET
29 #define __PAGE_OFFSET __PAGE_OFFSET_BASE
30 #include "../../mm/ident_map.c"
31
32
33 struct alloc_pgt_data {
34 unsigned char *pgt_buf;
35 unsigned long pgt_buf_size;
36 unsigned long pgt_buf_offset;
37 };
38
39
40
41
42
43
44 static void *alloc_pgt_page(void *context)
45 {
46 struct alloc_pgt_data *pages = (struct alloc_pgt_data *)context;
47 unsigned char *entry;
48
49
50 if (pages->pgt_buf_offset >= pages->pgt_buf_size) {
51 debug_putstr("out of pgt_buf in " __FILE__ "!?\n");
52 debug_putaddr(pages->pgt_buf_offset);
53 debug_putaddr(pages->pgt_buf_size);
54 return NULL;
55 }
56
57 entry = pages->pgt_buf + pages->pgt_buf_offset;
58 pages->pgt_buf_offset += PAGE_SIZE;
59
60 return entry;
61 }
62
63
64 static struct alloc_pgt_data pgt_data;
65
66
67 static unsigned long top_level_pgt;
68
69 phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
70
71
72
73
74
75 static struct x86_mapping_info mapping_info;
76
77
78 void initialize_identity_maps(void)
79 {
80
81 set_sev_encryption_mask();
82
83
84 physical_mask &= ~sme_me_mask;
85
86
87 mapping_info.alloc_pgt_page = alloc_pgt_page;
88 mapping_info.context = &pgt_data;
89 mapping_info.page_flag = __PAGE_KERNEL_LARGE_EXEC | sme_me_mask;
90 mapping_info.kernpg_flag = _KERNPG_TABLE;
91
92
93
94
95
96
97 pgt_data.pgt_buf_offset = 0;
98
99
100
101
102
103
104
105
106
107
108
109
110 top_level_pgt = read_cr3_pa();
111 if (p4d_offset((pgd_t *)top_level_pgt, 0) == (p4d_t *)_pgtable) {
112 debug_putstr("booted via startup_32()\n");
113 pgt_data.pgt_buf = _pgtable + BOOT_INIT_PGT_SIZE;
114 pgt_data.pgt_buf_size = BOOT_PGT_SIZE - BOOT_INIT_PGT_SIZE;
115 memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size);
116 } else {
117 debug_putstr("booted via startup_64()\n");
118 pgt_data.pgt_buf = _pgtable;
119 pgt_data.pgt_buf_size = BOOT_PGT_SIZE;
120 memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size);
121 top_level_pgt = (unsigned long)alloc_pgt_page(&pgt_data);
122 }
123 }
124
125
126
127
128
129
130 void add_identity_map(unsigned long start, unsigned long size)
131 {
132 unsigned long end = start + size;
133
134
135 start = round_down(start, PMD_SIZE);
136 end = round_up(end, PMD_SIZE);
137 if (start >= end)
138 return;
139
140
141 kernel_ident_mapping_init(&mapping_info, (pgd_t *)top_level_pgt,
142 start, end);
143 }
144
145
146
147
148
149
150 void finalize_identity_maps(void)
151 {
152 write_cr3(top_level_pgt);
153 }