On 25/07/2018 10:37, Vitaly Kuznetsov wrote: >> Why is this needed? If it weren't for it, you could pass hv_evmcs >> directly to evmcs_needs_write, which would simplify the code a bit in >> the caller. > This is an equivalent of prepare_vmcs02()/prepare_vmcs02_full() split > for eVMCS case: when we switch from L2 guest A to L2 guest B we need to > write the whole VMCS so evmcs_needs_write() needs to return true. Right, I missed the dirty_vmcs12 assignment in patch 5. But is L0 allowed to write to hv_clean_fields? One possibility is to add a dirty_evmcs field to struct nested_vmx, and "OR" ~hv_clean_fields into it at the beginning of prepare_vmcs02. Something like if (vmx->nested.hv_evmcs) { vmx->nested.dirty_evmcs |= ~vmx->nested.hv_evmcs->hv_clean_fields; prepare_vmcs02_full(vcpu, vmcs12, vmx->nested.dirty_evmcs); } else if (vmx->nested.dirty_vmcs12) { prepare_vmcs02_full(vcpu, vmcs12, ~0); } ... vmx->nested.dirty_evmcs = 0; vmx->nested.dirty_vmcs12 = false; ? Paolo > We can, however, make an optimisation: forcefuly reset hv_clean_fields > mask on enlightened vmptrld making 'dirty_vmcs12' check redundant.