Fix a race in pmap_emulate_accessed_dirty() that could trigger a EPT
misconfiguration VM-exit. An EPT misconfiguration is triggered when the processor encounters a PTE that is writable but not readable (WR=10). On processors that require A/D bit emulation PG_M and PG_A map to EPT_PG_WRITE and EPT_PG_READ respectively. If the PTE is updated as in the following code snippet: *pte |= PG_M; *pte |= PG_A; then it is possible for another processor to observe the PTE after the PG_M (aka EPT_PG_WRITE) bit is set but before PG_A (aka EPT_PG_READ) bit is set. This will trigger an EPT misconfiguration VM-exit on the other processor. Reported by: rodrigc Reviewed by: grehan MFC after: 3 days
This commit is contained in:
parent
75254491e5
commit
fb464d4f98
@ -6810,9 +6810,19 @@ pmap_emulate_accessed_dirty(pmap_t pmap, vm_offset_t va, int ftype)
|
||||
if (ftype == VM_PROT_WRITE) {
|
||||
if ((*pte & PG_RW) == 0)
|
||||
goto done;
|
||||
*pte |= PG_M;
|
||||
/*
|
||||
* Set the modified and accessed bits simultaneously.
|
||||
*
|
||||
* Intel EPT PTEs that do software emulation of A/D bits map
|
||||
* PG_A and PG_M to EPT_PG_READ and EPT_PG_WRITE respectively.
|
||||
* An EPT misconfiguration is triggered if the PTE is writable
|
||||
* but not readable (WR=10). This is avoided by setting PG_A
|
||||
* and PG_M simultaneously.
|
||||
*/
|
||||
*pte |= PG_M | PG_A;
|
||||
} else {
|
||||
*pte |= PG_A;
|
||||
}
|
||||
*pte |= PG_A;
|
||||
|
||||
/* try to promote the mapping */
|
||||
if (va < VM_MAXUSER_ADDRESS)
|
||||
|
Loading…
Reference in New Issue
Block a user