On 02/09/20 20:32, Jim Mattson wrote: > > /* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ > if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) > vmcs_write64(GUEST_BNDCFGS, 0); > > BTW, where does the L2 value propagate to L1 if not VM_EXIT_CLEAR_BNDCFGS? Hmm, nowhere. :/ Probably something like this (not really thought through): diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 1e903d51912b..aba76aa99465 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3317,7 +3317,8 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); if (kvm_mpx_supported() && - !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)) + (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS) || + !(vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS))) vmx->nested.vmcs01_guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS); /* @@ -4186,9 +4187,12 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, vmcs_write32(GUEST_IDTR_LIMIT, 0xFFFF); vmcs_write32(GUEST_GDTR_LIMIT, 0xFFFF); - /* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ - if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) - vmcs_write64(GUEST_BNDCFGS, 0); + if (kvm_mpx_supported()) { + if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) + vmcs_write64(GUEST_BNDCFGS, 0); + else + vmcs_write64(GUEST_BNDCFGS, vmx->nested.vmcs01_guest_bndcfgs); + } if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) { vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat); @@ -4466,6 +4470,10 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, vmx_set_virtual_apic_mode(vcpu); } + /* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ + if (!(vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS)) + vmx->nested.vmcs01_guest_bndcfgs = vmcs12->guest_bndcfgs; + /* Unpin physical memory we referred to in vmcs02 */ if (vmx->nested.apic_access_page) { kvm_release_page_clean(vmx->nested.apic_access_page); which will also work in the failed vmentry case. Paolo