@@ -130,8 +130,126 @@ SNP feature support.
130
130
131
131
More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR
132
132
133
+ Reverse Map Table (RMP)
134
+ =======================
135
+
136
+ The RMP is a structure in system memory that is used to ensure a one-to-one
137
+ mapping between system physical addresses and guest physical addresses. Each
138
+ page of memory that is potentially assignable to guests has one entry within
139
+ the RMP.
140
+
141
+ The RMP table can be either contiguous in memory or a collection of segments
142
+ in memory.
143
+
144
+ Contiguous RMP
145
+ --------------
146
+
147
+ Support for this form of the RMP is present when support for SEV-SNP is
148
+ present, which can be determined using the CPUID instruction::
149
+
150
+ 0x8000001f[eax]:
151
+ Bit[4] indicates support for SEV-SNP
152
+
153
+ The location of the RMP is identified to the hardware through two MSRs::
154
+
155
+ 0xc0010132 (RMP_BASE):
156
+ System physical address of the first byte of the RMP
157
+
158
+ 0xc0010133 (RMP_END):
159
+ System physical address of the last byte of the RMP
160
+
161
+ Hardware requires that RMP_BASE and (RPM_END + 1) be 8KB aligned, but SEV
162
+ firmware increases the alignment requirement to require a 1MB alignment.
163
+
164
+ The RMP consists of a 16KB region used for processor bookkeeping followed
165
+ by the RMP entries, which are 16 bytes in size. The size of the RMP
166
+ determines the range of physical memory that the hypervisor can assign to
167
+ SEV-SNP guests. The RMP covers the system physical address from::
168
+
169
+ 0 to ((RMP_END + 1 - RMP_BASE - 16KB) / 16B) x 4KB.
170
+
171
+ The current Linux support relies on BIOS to allocate/reserve the memory for
172
+ the RMP and to set RMP_BASE and RMP_END appropriately. Linux uses the MSR
173
+ values to locate the RMP and determine the size of the RMP. The RMP must
174
+ cover all of system memory in order for Linux to enable SEV-SNP.
175
+
176
+ Segmented RMP
177
+ -------------
178
+
179
+ Segmented RMP support is a new way of representing the layout of an RMP.
180
+ Initial RMP support required the RMP table to be contiguous in memory.
181
+ RMP accesses from a NUMA node on which the RMP doesn't reside
182
+ can take longer than accesses from a NUMA node on which the RMP resides.
183
+ Segmented RMP support allows the RMP entries to be located on the same
184
+ node as the memory the RMP is covering, potentially reducing latency
185
+ associated with accessing an RMP entry associated with the memory. Each
186
+ RMP segment covers a specific range of system physical addresses.
187
+
188
+ Support for this form of the RMP can be determined using the CPUID
189
+ instruction::
190
+
191
+ 0x8000001f[eax]:
192
+ Bit[23] indicates support for segmented RMP
193
+
194
+ If supported, segmented RMP attributes can be found using the CPUID
195
+ instruction::
196
+
197
+ 0x80000025[eax]:
198
+ Bits[5:0] minimum supported RMP segment size
199
+ Bits[11:6] maximum supported RMP segment size
200
+
201
+ 0x80000025[ebx]:
202
+ Bits[9:0] number of cacheable RMP segment definitions
203
+ Bit[10] indicates if the number of cacheable RMP segments
204
+ is a hard limit
205
+
206
+ To enable a segmented RMP, a new MSR is available::
207
+
208
+ 0xc0010136 (RMP_CFG):
209
+ Bit[0] indicates if segmented RMP is enabled
210
+ Bits[13:8] contains the size of memory covered by an RMP
211
+ segment (expressed as a power of 2)
212
+
213
+ The RMP segment size defined in the RMP_CFG MSR applies to all segments
214
+ of the RMP. Therefore each RMP segment covers a specific range of system
215
+ physical addresses. For example, if the RMP_CFG MSR value is 0x2401, then
216
+ the RMP segment coverage value is 0x24 => 36, meaning the size of memory
217
+ covered by an RMP segment is 64GB (1 << 36). So the first RMP segment
218
+ covers physical addresses from 0 to 0xF_FFFF_FFFF, the second RMP segment
219
+ covers physical addresses from 0x10_0000_0000 to 0x1F_FFFF_FFFF, etc.
220
+
221
+ When a segmented RMP is enabled, RMP_BASE points to the RMP bookkeeping
222
+ area as it does today (16K in size). However, instead of RMP entries
223
+ beginning immediately after the bookkeeping area, there is a 4K RMP
224
+ segment table (RST). Each entry in the RST is 8-bytes in size and represents
225
+ an RMP segment::
226
+
227
+ Bits[19:0] mapped size (in GB)
228
+ The mapped size can be less than the defined segment size.
229
+ A value of zero, indicates that no RMP exists for the range
230
+ of system physical addresses associated with this segment.
231
+ Bits[51:20] segment physical address
232
+ This address is left shift 20-bits (or just masked when
233
+ read) to form the physical address of the segment (1MB
234
+ alignment).
235
+
236
+ The RST can hold 512 segment entries but can be limited in size to the number
237
+ of cacheable RMP segments (CPUID 0x80000025_EBX[9:0]) if the number of cacheable
238
+ RMP segments is a hard limit (CPUID 0x80000025_EBX[10]).
239
+
240
+ The current Linux support relies on BIOS to allocate/reserve the memory for
241
+ the segmented RMP (the bookkeeping area, RST, and all segments), build the RST
242
+ and to set RMP_BASE, RMP_END, and RMP_CFG appropriately. Linux uses the MSR
243
+ values to locate the RMP and determine the size and location of the RMP
244
+ segments. The RMP must cover all of system memory in order for Linux to enable
245
+ SEV-SNP.
246
+
247
+ More details in the AMD64 APM Vol 2, section "15.36.3 Reverse Map Table",
248
+ docID: 24593.
249
+
133
250
Secure VM Service Module (SVSM)
134
251
===============================
252
+
135
253
SNP provides a feature called Virtual Machine Privilege Levels (VMPL) which
136
254
defines four privilege levels at which guest software can run. The most
137
255
privileged level is 0 and numerically higher numbers have lesser privileges.
0 commit comments