On Tue, Oct 10, 2023 at 2:37 PM David Woodhouse <dwmw2@xxxxxxxxxxxxx> wrote: > > If I understand things correctly, the point of the TDP MMU is to use > page tables such as EPT for GPA → HPA translations, but let the > virtualization support in the CPU handle all of the *virtual* > addressing and page tables, including the non-root mode %cr3/%cr4. > > I have a guest which loves to flip the SMEP bit on and off in %cr4 all > the time. The guest is actually Xen, in its 'PV shim' mode which > enables it to support a single PV guest, while running in a true > hardware virtual machine: > https://lists.xenproject.org/archives/html/xen-devel/2018-01/msg00497.html > > The performance is *awful*, since as far as I can tell, on every flip > KVM flushes the entire EPT. I understand why that might be necessary > for the mode where KVM is building up a set of shadow page tables to > directly map GVA → HPA and be loaded into %cr3 of a CPU that doesn't > support native EPT translations. But I don't understand why the TDP MMU > would need to do it. Surely we don't have to change anything in the EPT > just because the stuff in the non-root-mode %cr3/%cr4 changes? > > So I tried this, and it went faster and nothing appears to have blown > up. > > Am I missing something? Is this stupidly wrong? The TDP MMU is essentially a virtual TLB of guest-physical mappings, so it's oblivious to %cr4 changes. However, the hardware TLBs of the current logical processor contain combined mappings, which may have to be flushed, depending on how %cr4 has changed. Since kvm has emulated the instruction, it is responsible for flushing the hardware TLBs as required (see the SDM, volume 3, section 4.10.4: Operations that Invalidate TLBs and Paging-Structure Caches). Some of the logic in kvm_post_set_cr4() seems to deal with that. Not your fault, of course, but can't we come up with a better name than "kvm_post_set_cr4"?