On 5/8/2023 5:30 PM, Mathias Krause wrote:
void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0,
unsigned long cr0)
{
+ /*
+ * CR0.WP is incorporated into the MMU role, but only for
non-nested,
+ * indirect shadow MMUs. If TDP is enabled, the MMU's metadata
needs
+ * to be updated, e.g. so that emulating guest translations does the
+ * right thing, but there's no need to unload the root as CR0.WP
+ * doesn't affect SPTEs.
+ */
+ if (tdp_enabled && (cr0 ^ old_cr0) == X86_CR0_WP) {
Curiously, this patch only affects tdp_enabled, why does legacy MMU also
see comparable performance gains?
Because 'tdp_enabled' just implies EPT / NPT and only 'tdp_mmu_enabled'
decides which MMU mode to use -- either legacy or TDP MMU (see
kvm_configure_mmu() and now gets invoked from vmx.c / svm.c).
Ah, get it, thanks. The name indeed confuses me (and perhaps others).
After dig into,
1. kvm modules has a param "tdp_mmu_enabled", (in the first place)
indicates KVM level's willingness on enable two dimensional paging.
However, it in the end depends on ept/npt enabled or not on vendor layer.
So, uses a "tdp_mmu_allowed" to intermediately record this willness in kvm
module init phase.
/*
* Snapshot userspace's desire to enable the TDP MMU. Whether or not the
* TDP MMU is actually enabled is determined in kvm_configure_mmu()
* when the vendor module is loaded.
*/
tdp_mmu_allowed = tdp_mmu_enabled;
2. When vendor module init --> kvm_configure_mmu()
tdp_mmu_enabled = tdp_mmu_allowed && tdp_enabled;
tdp_mmu_enabled's semantics becomes, as its name indicates, the
eventual tdp mmu enablement status.
And, tdp_enabled, is the general (ept_enabled | npt_enabled).