Paolo Bonzini <pbonzini@xxxxxxxxxx> writes: > On 03/05/21 17:08, Vitaly Kuznetsov wrote: >> It now looks like a bad idea to not restore eVMCS mapping directly from >> vmx_set_nested_state(). The restoration path now depends on whether KVM >> will continue executing L2 (vmx_get_nested_state_pages()) or will have to >> exit to L1 (nested_vmx_vmexit()), this complicates error propagation and >> diverges too much from the 'native' path when 'nested.current_vmptr' is >> set directly from vmx_get_nested_state_pages(). >> >> The existing solution postponing eVMCS mapping also seems to be fragile. >> In multiple places the code checks whether 'vmx->nested.hv_evmcs' is not >> NULL to distinguish between eVMCS and non-eVMCS cases. All these checks >> are 'incomplete' as we have a weird 'eVMCS is in use but not yet mapped' >> state. >> >> Also, in case vmx_get_nested_state() is called right after >> vmx_set_nested_state() without executing the guest first, the resulting >> state is going to be incorrect as 'KVM_STATE_NESTED_EVMCS' flag will be >> missing. >> >> Fix all these issues by making eVMCS restoration path closer to its >> 'native' sibling by putting eVMCS GPA to 'struct kvm_vmx_nested_state_hdr'. >> To avoid ABI incompatibility, do not introduce a new flag and keep the > > I'm not sure what is the disadvantage of not having a new flag. > Adding a new flag would make us backwards-incompatible both ways: 1) Migrating 'new' state to an older KVM will fail the if (kvm_state->hdr.vmx.flags & ~KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE) return -EINVAL; check. 2) Migrating 'old' state to 'new' KVM would make us support the old path ('KVM_REQ_GET_NESTED_STATE_PAGES') so the flag will still be 'optional'. > Having two different paths with subtly different side effects however > seems really worse for maintenance. We are already discussing in > another thread how to get rid of the check_nested_events side effects; > that might possibly even remove the need for patch 1, so it's at least > worth pursuing more than adding this second path. I have to admit I don't fully like this solution either :-( In case we make sure KVM_REQ_GET_NESTED_STATE_PAGES always gets handled the fix can be omitted indeed, however, I still dislike the divergence and the fact that 'if (vmx->nested.hv_evmcs)' checks scattered across the code are not fully valid. E.g. how do we fix immediate KVM_GET_NESTED_STATE after KVM_SET_NESTED_STATE without executing the vCPU problem? > > I have queued patch 1, but I'd rather have a kvm selftest for it. It > doesn't seem impossible to have one... Thank you, the band-aid solves a real problem. Let me try to come up with a selftest for it. > > Paolo > >> original eVMCS mapping path through KVM_REQ_GET_NESTED_STATE_PAGES in >> place. To distinguish between 'new' and 'old' formats consider eVMCS >> GPA == 0 as an unset GPA (thus forcing KVM_REQ_GET_NESTED_STATE_PAGES >> path). While technically possible, it seems to be an extremely unlikely >> case. > > >> Signed-off-by: Vitaly Kuznetsov<vkuznets@xxxxxxxxxx> > -- Vitaly