Re: [PATCH 04/21] KVM: VMX: Split out guts of EPT violation to common/exposed function

From: Sean Christopherson
Date: Mon Sep 09 2024 - 12:07:47 EST


On Tue, Sep 03, 2024, Rick Edgecombe wrote:
> +static inline int __vmx_handle_ept_violation(struct kvm_vcpu *vcpu, gpa_t gpa,
> + unsigned long exit_qualification)
> +{
> + u64 error_code;
> +
> + /* Is it a read fault? */
> + error_code = (exit_qualification & EPT_VIOLATION_ACC_READ)
> + ? PFERR_USER_MASK : 0;
> + /* Is it a write fault? */
> + error_code |= (exit_qualification & EPT_VIOLATION_ACC_WRITE)
> + ? PFERR_WRITE_MASK : 0;
> + /* Is it a fetch fault? */
> + error_code |= (exit_qualification & EPT_VIOLATION_ACC_INSTR)
> + ? PFERR_FETCH_MASK : 0;
> + /* ept page table entry is present? */
> + error_code |= (exit_qualification & EPT_VIOLATION_RWX_MASK)
> + ? PFERR_PRESENT_MASK : 0;
> +
> + if (error_code & EPT_VIOLATION_GVA_IS_VALID)
> + error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) ?
> + PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK;
> +
> + return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
> +}
> +
> +#endif /* __KVM_X86_VMX_COMMON_H */
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 5e7b5732f35d..ade7666febe9 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -53,6 +53,7 @@
> #include <trace/events/ipi.h>
>
> #include "capabilities.h"
> +#include "common.h"
> #include "cpuid.h"
> #include "hyperv.h"
> #include "kvm_onhyperv.h"
> @@ -5771,11 +5772,8 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>
> static int handle_ept_violation(struct kvm_vcpu *vcpu)
> {
> - unsigned long exit_qualification;
> + unsigned long exit_qualification = vmx_get_exit_qual(vcpu);
> gpa_t gpa;
> - u64 error_code;
> -
> - exit_qualification = vmx_get_exit_qual(vcpu);
>
> /*
> * EPT violation happened while executing iret from NMI,
> @@ -5791,23 +5789,6 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
> gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
> trace_kvm_page_fault(vcpu, gpa, exit_qualification);
>
> - /* Is it a read fault? */
> - error_code = (exit_qualification & EPT_VIOLATION_ACC_READ)
> - ? PFERR_USER_MASK : 0;
> - /* Is it a write fault? */
> - error_code |= (exit_qualification & EPT_VIOLATION_ACC_WRITE)
> - ? PFERR_WRITE_MASK : 0;
> - /* Is it a fetch fault? */
> - error_code |= (exit_qualification & EPT_VIOLATION_ACC_INSTR)
> - ? PFERR_FETCH_MASK : 0;
> - /* ept page table entry is present? */
> - error_code |= (exit_qualification & EPT_VIOLATION_RWX_MASK)
> - ? PFERR_PRESENT_MASK : 0;
> -
> - if (error_code & EPT_VIOLATION_GVA_IS_VALID)
> - error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) ?
> - PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK;
> -

Paolo, are you planning on queueing these for 6.12, or for a later kernel? I ask
because this will conflict with a bug fix[*] that I am planning on taking through
kvm-x86/mmu. If you anticipate merging these in 6.12, then it'd probably be best
for you to grab that one patch directly, as I don't think it has semantic conflicts
with anything else in that series.

[*] https://lore.kernel.org/all/20240831001538.336683-2-seanjc@xxxxxxxxxx