lkml.org 
[lkml]   [2022]   [Sep]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v8 048/103] KVM: VMX: Split out guts of EPT violation to common/exposed function
    On Sun, Aug 07, 2022 at 03:01:33PM -0700, isaku.yamahata@intel.com wrote:
    > From: Sean Christopherson <sean.j.christopherson@intel.com>
    >
    > The difference of TDX EPT violation is how to retrieve information, GPA,
    > and exit qualification. To share the code to handle EPT violation, split
    > out the guts of EPT violation handler so that VMX/TDX exit handler can call
    > it after retrieving GPA and exit qualification.
    >
    > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
    > Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
    > Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
    > Reviewed-by: Kai Huang <kai.huang@intel.com>

    Reviewed-by: Yuan Yao <yuan.yao@intel.com>

    > ---
    > arch/x86/kvm/vmx/common.h | 33 +++++++++++++++++++++++++++++++++
    > arch/x86/kvm/vmx/vmx.c | 29 +++++------------------------
    > 2 files changed, 38 insertions(+), 24 deletions(-)
    > create mode 100644 arch/x86/kvm/vmx/common.h
    >
    > diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h
    > new file mode 100644
    > index 000000000000..235908f3e044
    > --- /dev/null
    > +++ b/arch/x86/kvm/vmx/common.h
    > @@ -0,0 +1,33 @@
    > +/* SPDX-License-Identifier: GPL-2.0-only */
    > +#ifndef __KVM_X86_VMX_COMMON_H
    > +#define __KVM_X86_VMX_COMMON_H
    > +
    > +#include <linux/kvm_host.h>
    > +
    > +#include "mmu.h"
    > +
    > +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;
    > +
    > + error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) != 0 ?
    > + 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 4a3b3dc5d4d2..3af8cd164274 100644
    > --- a/arch/x86/kvm/vmx/vmx.c
    > +++ b/arch/x86/kvm/vmx/vmx.c
    > @@ -50,6 +50,7 @@
    > #include <asm/vmx.h>
    >
    > #include "capabilities.h"
    > +#include "common.h"
    > #include "cpuid.h"
    > #include "evmcs.h"
    > #include "hyperv.h"
    > @@ -5646,11 +5647,10 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
    >
    > static int handle_ept_violation(struct kvm_vcpu *vcpu)
    > {
    > - unsigned long exit_qualification;
    > - gpa_t gpa;
    > - u64 error_code;
    > + unsigned long exit_qualification = vmx_get_exit_qual(vcpu);
    > + gpa_t gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
    >
    > - exit_qualification = vmx_get_exit_qual(vcpu);
    > + trace_kvm_page_fault(gpa, exit_qualification);
    >
    > /*
    > * EPT violation happened while executing iret from NMI,
    > @@ -5663,25 +5663,6 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
    > (exit_qualification & INTR_INFO_UNBLOCK_NMI))
    > vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, GUEST_INTR_STATE_NMI);
    >
    > - gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
    > - trace_kvm_page_fault(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;
    > -
    > - error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) != 0 ?
    > - PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK;
    > -
    > vcpu->arch.exit_qualification = exit_qualification;
    >
    > /*
    > @@ -5695,7 +5676,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
    > if (unlikely(allow_smaller_maxphyaddr && kvm_vcpu_is_illegal_gpa(vcpu, gpa)))
    > return kvm_emulate_instruction(vcpu, 0);
    >
    > - return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
    > + return __vmx_handle_ept_violation(vcpu, gpa, exit_qualification);
    > }
    >
    > static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
    > --
    > 2.25.1
    >

    \
     
     \ /
      Last update: 2022-09-02 09:08    [W:4.692 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site