@@ -219,7 +219,7 @@ OperateOnNestedPageTables (
219
219
}
220
220
}
221
221
pageDirectoryPointerTable = reinterpret_cast <PPDP_ENTRY_4KB>(GetVaFromPfn (
222
- pml4Entry->Fields .PageFrameNumber ));
222
+ pml4Entry->Fields .PageFrameNumber ));
223
223
224
224
//
225
225
// PDPT (1 GB)
@@ -239,7 +239,7 @@ OperateOnNestedPageTables (
239
239
}
240
240
}
241
241
pageDirectoryTable = reinterpret_cast <PPD_ENTRY_4KB>(GetVaFromPfn (
242
- pdptEntry->Fields .PageFrameNumber ));
242
+ pdptEntry->Fields .PageFrameNumber ));
243
243
244
244
//
245
245
// PDT (2 MB)
@@ -259,7 +259,7 @@ OperateOnNestedPageTables (
259
259
}
260
260
}
261
261
pageTable = reinterpret_cast <PPT_ENTRY_4KB>(GetVaFromPfn (
262
- pdtEntry->Fields .PageFrameNumber ));
262
+ pdtEntry->Fields .PageFrameNumber ));
263
263
264
264
//
265
265
// PT (4 KB)
@@ -279,29 +279,34 @@ OperateOnNestedPageTables (
279
279
(VOID)BuildNestedPageTableEntry (ptEntry, PhysicalAddress, HookData);
280
280
281
281
//
282
- // FIXME: Set the correct memory type. Do not make it WB unconditionally.
282
+ // We do not explicitly configure PAT in the NPT entry. The consequences
283
+ // of this are: 1) pages whose PAT (Page Attribute Table) type is the
284
+ // Write-Combining (WC) memory type could be treated as the
285
+ // Write-Combining Plus (WC+) while it should be WC when the MTRR type is
286
+ // either Write Protect (WP), Writethrough (WT) or Writeback (WB), and
287
+ // 2) pages whose PAT type is Uncacheable Minus (UC-) could be treated
288
+ // as Cache Disabled (CD) while it should be WC, when MTRR type is WC.
283
289
//
284
- // The host PAT type is set to WB because all PAT, PCD, and PWT bits in
285
- // the NPT entries are cleared. See "PAT-Register PA-Field Indexing" for
286
- // this determination.
290
+ // While those are not desirable, this is acceptable given that 1) only
291
+ // introduces additional cache snooping and associated performance
292
+ // penalty, which would not be significant since WC+ still lets
293
+ // processors combine multiple writes into one and avoid large
294
+ // performance penalty due to frequent writes to memory without caching.
295
+ // 2) might be worse but I have not seen MTRR ranges configured as WC
296
+ // on testing, hence the unintentional UC- will just results in the same
297
+ // effective memory type as what would be with UC.
287
298
//
288
- // This introduces the following changes in the combined PAT type when
289
- // the guest PAT type is:
290
- // UC-, it will be UC
291
- // WC, it will be WC+
292
- // See "Combining Guest and Host PAT Types" for this determination .
299
+ // See "Memory Types" (7.4), for details of memory types,
300
+ // "PAT-Register PA-Field Indexing", "Combining Guest and Host PAT Types",
301
+ // and "Combining PAT and MTRR Types" for how the effective memory type
302
+ // is determined based on Guest PAT type, Host PAT type, and the MTRR
303
+ // type .
293
304
//
294
- // This introduces the following changes in the effective PAT type when
295
- // the MTRR type is:
296
- // WC, it will be WC while it could have been CD
297
- // WP,WT,WB, it will be WC+ while it could have been WC
298
- // See "Combining Memory Types, MTRRs" for this determination.
299
- //
300
- // This will be unwanted to change, especially for MMIO regions where the
301
- // guest PAT type can be one of those affected types (UC- or WC). The
302
- // correct fix is probably to look up the guest PTE and copy the caching
303
- // related bits (PAT, PCD, and PWT) when constructing NTP entries, so
304
- // the combined PAT will always be the same as the guest PAT type.
305
+ // The correct approach may be to look up the guest PTE and copy the
306
+ // caching related bits (PAT, PCD, and PWT) when constructing NTP
307
+ // entries for non RAM regions, so the combined PAT will always be the
308
+ // same as the guest PAT type. This may be done when any issue manifests
309
+ // with the current implementation.
305
310
//
306
311
}
307
312
else
0 commit comments