Re: [PATCH v3 2/3] KVM: nVMX: Enable VMFUNC for the L1 hypervisor

From: Bandan Das
Date: Mon Jul 10 2017 - 16:35:10 EST


David Hildenbrand <david@xxxxxxxxxx> writes:

>> - kvm_queue_exception(vcpu, UD_VECTOR);
>> + struct vcpu_vmx *vmx = to_vmx(vcpu);
>> + struct vmcs12 *vmcs12;
>> + u32 function = vcpu->arch.regs[VCPU_REGS_RAX];
>> +
>> + /*
>> + * VMFUNC is only supported for nested guests, but we always enable the
>> + * secondary control for simplicity; for non-nested mode, fake that we
>> + * didn't by injecting #UD.
>> + */
>> + if (!is_guest_mode(vcpu)) {
>> + kvm_queue_exception(vcpu, UD_VECTOR);
>> + return 1;
>> + }
>> +
>> + vmcs12 = get_vmcs12(vcpu);
>> + if ((vmcs12->vm_function_control & (1 << function)) == 0)
>> + goto fail;
>> + WARN(1, "VMCS12 VM function control should have been zero");
>
> Should this be a WARN_ONCE?

Even though this line gets removed in patch 3, I agree, it's a
good idea to use WARN_ONCE.

>> +
>> +fail:
>> + nested_vmx_vmexit(vcpu, vmx->exit_reason,
>> + vmcs_read32(VM_EXIT_INTR_INFO),
>> + vmcs_readl(EXIT_QUALIFICATION));
>> return 1;
>> }
>>
>> @@ -10053,7 +10092,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
>> exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
>> SECONDARY_EXEC_RDTSCP |
>> SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
>> - SECONDARY_EXEC_APIC_REGISTER_VIRT);
>> + SECONDARY_EXEC_APIC_REGISTER_VIRT |
>> + SECONDARY_EXEC_ENABLE_VMFUNC);
>> if (nested_cpu_has(vmcs12,
>> CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)) {
>> vmcs12_exec_ctrl = vmcs12->secondary_vm_exec_control &
>> @@ -10061,6 +10101,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
>> exec_control |= vmcs12_exec_ctrl;
>> }
>>
>> + /* All VMFUNCs are currently emulated through L0 vmexits. */
>> + if (exec_control & SECONDARY_EXEC_ENABLE_VMFUNC)
>> + vmcs_write64(VM_FUNCTION_CONTROL, 0);
>> +
>> if (exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY) {
>> vmcs_write64(EOI_EXIT_BITMAP0,
>> vmcs12->eoi_exit_bitmap0);
>> @@ -10310,6 +10354,11 @@ static int check_vmentry_prereqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
>> vmx->nested.nested_vmx_entry_ctls_high))
>> return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
>>
>> + if (nested_cpu_has_vmfunc(vmcs12) &&
>> + (vmcs12->vm_function_control &
>> + ~vmx->nested.nested_vmx_vmfunc_controls))
>
> I'd prefer the second part on one line, although it will violate 80
> chars. (these variable names really start to get too lengthy to be useful)

Yeah, I had to split it up for that.

Thank you for the quick review!

Bandan

>> + return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
>> +
>> if (vmcs12->cr3_target_count > nested_cpu_vmx_misc_cr3_count(vcpu))
>> return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
>>
>>
>
> Feel free to ignore my comments.
>
> Reviewed-by: David Hildenbrand <david@xxxxxxxxxx>