KVM: VMX: Add helper to consolidate up PT/RTIT WRMSR fault logic

Add a helper to consolidate the common checks for writing PT MSRs,
and opportunistically clean up the formatting of the affected code.

No functional change intended.

Cc: Chao Peng <chao.p.peng@linux.intel.com>
Cc: Luwei Kang <luwei.kang@intel.com>
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Sean Christopherson 2019-12-10 15:24:33 -08:00 committed by Paolo Bonzini
parent fe6ed369fc
commit e348ac7c9e

View File

@ -1057,6 +1057,12 @@ static unsigned long segment_base(u16 selector)
} }
#endif #endif
static inline bool pt_can_write_msr(struct vcpu_vmx *vmx)
{
return (pt_mode == PT_MODE_HOST_GUEST) &&
!(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN);
}
static inline void pt_load_msr(struct pt_ctx *ctx, u32 addr_range) static inline void pt_load_msr(struct pt_ctx *ctx, u32 addr_range)
{ {
u32 i; u32 i;
@ -2102,47 +2108,48 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
pt_update_intercept_for_msr(vmx); pt_update_intercept_for_msr(vmx);
break; break;
case MSR_IA32_RTIT_STATUS: case MSR_IA32_RTIT_STATUS:
if ((pt_mode != PT_MODE_HOST_GUEST) || if (!pt_can_write_msr(vmx))
(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) || return 1;
(data & MSR_IA32_RTIT_STATUS_MASK)) if (data & MSR_IA32_RTIT_STATUS_MASK)
return 1; return 1;
vmx->pt_desc.guest.status = data; vmx->pt_desc.guest.status = data;
break; break;
case MSR_IA32_RTIT_CR3_MATCH: case MSR_IA32_RTIT_CR3_MATCH:
if ((pt_mode != PT_MODE_HOST_GUEST) || if (!pt_can_write_msr(vmx))
(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) || return 1;
!intel_pt_validate_cap(vmx->pt_desc.caps, if (!intel_pt_validate_cap(vmx->pt_desc.caps,
PT_CAP_cr3_filtering)) PT_CAP_cr3_filtering))
return 1; return 1;
vmx->pt_desc.guest.cr3_match = data; vmx->pt_desc.guest.cr3_match = data;
break; break;
case MSR_IA32_RTIT_OUTPUT_BASE: case MSR_IA32_RTIT_OUTPUT_BASE:
if ((pt_mode != PT_MODE_HOST_GUEST) || if (!pt_can_write_msr(vmx))
(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) || return 1;
(!intel_pt_validate_cap(vmx->pt_desc.caps, if (!intel_pt_validate_cap(vmx->pt_desc.caps,
PT_CAP_topa_output) && PT_CAP_topa_output) &&
!intel_pt_validate_cap(vmx->pt_desc.caps, !intel_pt_validate_cap(vmx->pt_desc.caps,
PT_CAP_single_range_output)) || PT_CAP_single_range_output))
(data & MSR_IA32_RTIT_OUTPUT_BASE_MASK)) return 1;
if (data & MSR_IA32_RTIT_OUTPUT_BASE_MASK)
return 1; return 1;
vmx->pt_desc.guest.output_base = data; vmx->pt_desc.guest.output_base = data;
break; break;
case MSR_IA32_RTIT_OUTPUT_MASK: case MSR_IA32_RTIT_OUTPUT_MASK:
if ((pt_mode != PT_MODE_HOST_GUEST) || if (!pt_can_write_msr(vmx))
(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) || return 1;
(!intel_pt_validate_cap(vmx->pt_desc.caps, if (!intel_pt_validate_cap(vmx->pt_desc.caps,
PT_CAP_topa_output) && PT_CAP_topa_output) &&
!intel_pt_validate_cap(vmx->pt_desc.caps, !intel_pt_validate_cap(vmx->pt_desc.caps,
PT_CAP_single_range_output))) PT_CAP_single_range_output))
return 1; return 1;
vmx->pt_desc.guest.output_mask = data; vmx->pt_desc.guest.output_mask = data;
break; break;
case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B:
if (!pt_can_write_msr(vmx))
return 1;
index = msr_info->index - MSR_IA32_RTIT_ADDR0_A; index = msr_info->index - MSR_IA32_RTIT_ADDR0_A;
if ((pt_mode != PT_MODE_HOST_GUEST) || if (index >= 2 * intel_pt_validate_cap(vmx->pt_desc.caps,
(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) || PT_CAP_num_address_ranges))
(index >= 2 * intel_pt_validate_cap(vmx->pt_desc.caps,
PT_CAP_num_address_ranges)))
return 1; return 1;
if (is_noncanonical_address(data, vcpu)) if (is_noncanonical_address(data, vcpu))
return 1; return 1;