address_spaces.h 8.02 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
/*
 * address_spaces.h
 *
 * The initial virtual and physical address spaces inside
 * an LCD.
 *
 * Copyright: University of Utah
 */
#ifndef LCD_DOMAINS_ADDRESS_SPACES_H
#define LCD_DOMAINS_ADDRESS_SPACES_H

#include <lcd-domains/types.h>
13
#include <lcd-domains/liblcd/boot_info.h>
14
15
16
17
18

/*
 * Guest Physical Memory Layout
 * ============================
 *
19
20
21
22
23
 * This is the guest physical address space layout the LCD boots
 * with. It is of course free to modify it (using the capabilities
 * to the memory).
 *
 * No gdt/tss/idt for now (easier).
24
25
26
 *
 * From bottom to top,
 *
27
28
29
30
31
32
33
34
35
36
37
38
 *   -- The bottom 1 GB is unmapped / reserved. (This could be used
 *      for BIOS memory-mapped information, low DMA, etc. in the
 *      future.) This conveniently causes EPT faults for null physical
 *      addresses.
 *
 *   -- 1 GB miscellaneous (only beginning part is mapped in guest physical):
 *
 *          -- UTCB (microkernel manages this page)
 *          -- Bootstrap info pages
 *          -- Bootstrap guest virtual address space page tables
 *
 *   -- 1 GB HOLE (unmapped)
39
 *
40
 *   -- 1 GB for initial stack region (only top part is mapped):
41
 *
42
 *          -- Stack starts at the top
43
 *
44
 *   -- 1 GB HOLE (unmapped)
45
 *
46
 *   -- 1 GB for heap region (unmapped at boot; only bottom part is used)
47
 *
48
49
50
51
52
53
54
55
56
 *   -- 2 GB HOLE (unmapped)
 *
 *   -- 256 GB for ioremap region (unmapped at boot)
 *
 *   -- 2 GB HOLE (unmapped)
 *
 *   -- 2 GB for kernel module mapping area. The kernel module itself
 *      is mapped at the correct offset into this area so that
 *      the guest virtual mapping can use huge 1 GB pages.
57
58
 *
 *   -- The upper part is unusable (see Intel SDM V3 28.2.2). The last
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
92
93
94
95
96
97
98
99
 *      usable byte is at 0x0000 FFFF FFFF FFFF. This is why we can't do
 *      a direct map of the kernel module.
 *
 *              +---------------------------+ 0xFFFF FFFF FFFF FFFF
 *              |         Unusable          |
 *              +---------------------------+ 0x0000 FFFF FFFF FFFF
 *              |                           |
 *              :           Free            :
 *              |                           |
 *              +---------------------------+ 0x0000 0080 0000 0000 (512 GB)
 *              |       Kernel Module       |
 *              |    (code, bss, rodata)    |
 *              |          (2 GB)           |
 *              +---------------------------+ 0x0000 007f 8000 0000 (510 GB)
 *              |       HOLE / Unmapped     | 
 *              |         (246 GB)          |
 *              +---------------------------+ 0x0000 0042 0000 0000 (264 GB) 
 *              |       ioremap region      |                    
 *              |         (256 GB)          |
 *              +---------------------------+ 0x0000 0002 0000 0000 (8 GB)
 *              |       HOLE / Unmapped     | 
 *              |          (2 GB)           |
 *              +---------------------------+ 0x0000 0001 8000 0000 (6 GB)
 *              |        Heap Region        | 
 *              |          (1 GB)           |
 *              +---------------------------+ 0x0000 0001 4000 0000 (5 GB)
 *              |       HOLE / Unmapped     | 
 *              |          (1 GB)           |
 *              +---------------------------+ 0x0000 0001 0000 0000 (4 GB)
 *              |     Initial Stack Region  |
 *              |          (1 GB)           |
 *              +---------------------------+ 0x0000 0000 c000 0000 (3 GB)
 *              |       HOLE / Unmapped     | 
 *              |          (1 GB)           |
 *              +---------------------------+ 0x0000 0000 8000 0000 (2 GB)
 *              |     UTCB and Bootstrap    |
 *              |          (1 GB)           |
 *              +---------------------------+ 0x0000 0000 4000 0000 (1 GB)
 *              |       Free / Unmapped     | 
 *              |          (1 GB)           |
 *              +---------------------------+ 0x0000 0000 0000 0000 (0 GB)
100
101
102
103
 *
 * Guest Virtual Memory Layout
 * ===========================
 *
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 * The layout is simple: the physical address space is mapped once in the
 * high 512 GB range. This puts the kernel module mapping area in the high
 * 2 GBs, the same as on the host (for x86_64 anyway).
 *
 *              +---------------------------+ 0xFFFF FFFF FFFF FFFF
 *              |       Kernel Module       |
 *              |    (code, bss, rodata)    |
 *              |          (2 GB)           |        \
 *              +---------------------------+        |
 *              |                           |        |
 *              |      ioremap, heap,       |        |
 *              :       stack, utcb,        :          512 GBs
 *              :           etc.            :        |
 *              |                           |        |
 *              |                           |        |
 *              +---------------------------+        /
 *              |     Unmapped in physical  |
 *              |          (1 GB)           |
 *              +---------------------------+ 0xFFFF FF7F FFFF FFFF 
 *              |                           |           
 *              |                           |
 *              :                           :
 *              :        Unmapped           :
 *              :                           :
 *              |                           |
 *              |                           |         
 *              +---------------------------+ 0x0000 0000 0000 0000
 *
 * Everything else is unmapped. We use huge 1 GB pages. This means there
 * are only two 4 KB pages needed to set up the entire guest virtual
 * address space.
 *
 * (Why don't we map everything in the high physical range so we can
 * identity map? Answer: The high part of the physical address space is
 * unusable.)
139
140
 */

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#define LCD_UTCB_SIZE (1UL << 12) /* ......................... 4  KBs   */
#define LCD_BOOTSTRAP_PAGES_SIZE \
	(ALIGN(sizeof(struct lcd_boot_info), PAGE_SIZE)) /* .. variable */
#define LCD_BOOTSTRAP_PAGE_TABLES_SIZE (2 * (1UL << 12)) /* .. 8  KBs   */
#define LCD_STACK_SIZE (2 * (1UL << 12)) /* .................. 8  KBs   */
#define LCD_HEAP_SIZE (16UL << 20) /* ........................ 16 MBs   */
#define LCD_IOREMAP_SIZE (16UL << 20) /* ..................... 16 MBs   */

#define LCD_MISC_REGION_OFFSET (1UL << 30)
#define LCD_UTCB_OFFSET LCD_MISC_REGION_OFFSET
#define LCD_BOOTSTRAP_PAGES_OFFSET (LCD_UTCB_OFFSET + LCD_UTCB_SIZE)
#define LCD_BOOTSTRAP_PAGE_TABLES_OFFSET \
	(LCD_BOOTSTRAP_PAGES_OFFSET + LCD_BOOTSTRAP_PAGES_SIZE)

/* HOLE */

#define LCD_STACK_REGION_OFFSET (3UL << 30)
#define LCD_STACK_OFFSET \
	(LCD_STACK_REGION_OFFSET + (1UL << 30) - LCD_STACK_SIZE)

/* HOLE */

#define LCD_HEAP_REGION_OFFSET (5UL << 30)
#define LCD_HEAP_OFFSET LCD_HEAP_REGION_OFFSET

/* HOLE */

#define LCD_IOREMAP_REGION_OFFSET (8UL << 30)
#define LCD_IOREMAP_OFFSET LCD_IOREMAP_REGION_OFFSET

/* HOLE */

#define LCD_KERNEL_MODULE_REGION_OFFSET (510UL << 30)
#define LCD_KERNEL_MODULE_OFFSET LCD_KERNEL_MODULE_REGION_OFFSET

/* Addresses */

#define LCD_PHYS_BASE (0UL)
#define LCD_VIRT_BASE (0xFFFFFF7FFFFFFFFFUL)

#define LCD_UTCB_GP_ADDR __gpa(LCD_PHYS_BASE + LCD_UTCB_OFFSET)
#define LCD_UTCB_GV_ADDR __gva(LCD_VIRT_BASE + LCD_UTCB_OFFSET)

#define LCD_BOOTSTRAP_PAGES_GP_ADDR \
	__gpa(LCD_PHYS_BASE + LCD_BOOTSTRAP_PAGES_OFFSET)
#define LCD_BOOTSTRAP_PAGES_GV_ADDR \
	__gpa(LCD_VIRT_BASE + LCD_BOOTSTRAP_PAGES_OFFSET)

#define LCD_BOOTSTRAP_PAGE_TABLES_GP_ADDR \
	__gpa(LCD_PHYS_BASE + LCD_BOOTSTRAP_PAGE_TABLES_OFFSET)
#define LCD_BOOTSTRAP_PAGE_TABLES_GV_ADDR \
	__gpa(LCD_VIRT_BASE + LCD_BOOTSTRAP_PAGE_TABLES_OFFSET)

#define LCD_STACK_GP_ADDR __gpa(LCD_PHYS_BASE + LCD_STACK_OFFSET)
#define LCD_STACK_GV_ADDR __gpa(LCD_VIRT_BASE + LCD_STACK_OFFSET)

#define LCD_HEAP_GP_ADDR __gpa(LCD_PHYS_BASE + LCD_HEAP_OFFSET)
#define LCD_HEAP_GV_ADDR __gpa(LCD_VIRT_BASE + LCD_HEAP_OFFSET)

#define LCD_IOREMAP_GP_ADDR __gpa(LCD_PHYS_BASE + LCD_IOREMAP_OFFSET)
#define LCD_IOREMAP_GV_ADDR __gpa(LCD_VIRT_BASE + LCD_IOREMAP_OFFSET)

#define LCD_KERNEL_MODULE_GP_ADDR \
	__gpa(LCD_PHYS_BASE + LCD_KERNEL_MODULE_OFFSET)
#define LCD_KERNEL_MODULE_GV_ADDR \
	__gpa(LCD_VIRT_BASE + LCD_KERNEL_MODULE_OFFSET)
207
208

#endif /* LCD_DOMAINS_ADDRESS_SPACES_H */