On 07/05/19 21:18, Sean Christopherson wrote: > KVM dynamically toggles the CPU_BASED_USE_MSR_BITMAPS execution control > for nested guests based on whether or not both L0 and L1 want to pass > through the same MSRs to L2. Preserve the last used value from vmcs02 > so as to avoid multiple VMWRITEs to (re)set/(re)clear the bit on nested > VM-Entry. > > Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx> Needs a comment in code, and also leaves you puzzled as to why it's only necessary to clear it. We can even let the compiler merge the two "exec_control &= ~FOO" so that we don't even spend a precious instruction on the AND: diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 1150831e4a9b..2e086d5ab837 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2048,10 +2048,18 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) * A vmexit (to either L1 hypervisor or L0 userspace) is always needed * for I/O port accesses. */ - exec_control &= ~CPU_BASED_USE_IO_BITMAPS; exec_control |= CPU_BASED_UNCOND_IO_EXITING; - if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS)) - exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; + exec_control &= ~CPU_BASED_USE_IO_BITMAPS; + + /* + * This bit will be computed in nested_get_vmcs12_pages, because + * we do not have access to L1's MSR bitmap yet. For now, keep + * the same bit as before, hoping to avoid multiple VMWRITEs that + * only set/clear this bit. + */ + exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; + exec_control |= exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS; + exec_controls_set(vmx, exec_control); /* Paolo