Skip to content

Commit b08c289

Browse files
chao-pbonzini
authored andcommitted
KVM: x86: Set intercept for Intel PT MSRs read/write
To save performance overhead, disable intercept Intel PT MSRs read/write when Intel PT is enabled in guest. MSR_IA32_RTIT_CTL is an exception that will always be intercepted. Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com> Signed-off-by: Luwei Kang <luwei.kang@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent bf8c55d commit b08c289

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

arch/x86/kvm/vmx/vmx.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -977,15 +977,11 @@ static void pt_guest_enter(struct vcpu_vmx *vmx)
977977
if (pt_mode == PT_MODE_SYSTEM)
978978
return;
979979

980-
/* Save host state before VM entry */
981-
rdmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
982-
983980
/*
984-
* Set guest state of MSR_IA32_RTIT_CTL MSR (PT will be disabled
985-
* on VM entry when it has been disabled in guest before).
981+
* GUEST_IA32_RTIT_CTL is already set in the VMCS.
982+
* Save host state before VM entry.
986983
*/
987-
vmcs_write64(GUEST_IA32_RTIT_CTL, vmx->pt_desc.guest.ctl);
988-
984+
rdmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
989985
if (vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) {
990986
wrmsrl(MSR_IA32_RTIT_CTL, 0);
991987
pt_save_msr(&vmx->pt_desc.host, vmx->pt_desc.addr_range);
@@ -1934,6 +1930,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
19341930
return 1;
19351931
vmcs_write64(GUEST_IA32_RTIT_CTL, data);
19361932
vmx->pt_desc.guest.ctl = data;
1933+
pt_update_intercept_for_msr(vmx);
19371934
break;
19381935
case MSR_IA32_RTIT_STATUS:
19391936
if ((pt_mode != PT_MODE_HOST_GUEST) ||
@@ -3567,6 +3564,28 @@ void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu)
35673564
vmx->msr_bitmap_mode = mode;
35683565
}
35693566

3567+
void pt_update_intercept_for_msr(struct vcpu_vmx *vmx)
3568+
{
3569+
unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap;
3570+
bool flag = !(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN);
3571+
u32 i;
3572+
3573+
vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_STATUS,
3574+
MSR_TYPE_RW, flag);
3575+
vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_OUTPUT_BASE,
3576+
MSR_TYPE_RW, flag);
3577+
vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_OUTPUT_MASK,
3578+
MSR_TYPE_RW, flag);
3579+
vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_CR3_MATCH,
3580+
MSR_TYPE_RW, flag);
3581+
for (i = 0; i < vmx->pt_desc.addr_range; i++) {
3582+
vmx_set_intercept_for_msr(msr_bitmap,
3583+
MSR_IA32_RTIT_ADDR0_A + i * 2, MSR_TYPE_RW, flag);
3584+
vmx_set_intercept_for_msr(msr_bitmap,
3585+
MSR_IA32_RTIT_ADDR0_B + i * 2, MSR_TYPE_RW, flag);
3586+
}
3587+
}
3588+
35703589
static bool vmx_get_enable_apicv(struct kvm_vcpu *vcpu)
35713590
{
35723591
return enable_apicv;

arch/x86/kvm/vmx/vmx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
316316
void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
317317
void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
318318
struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr);
319+
void pt_update_intercept_for_msr(struct vcpu_vmx *vmx);
319320

320321
#define POSTED_INTR_ON 0
321322
#define POSTED_INTR_SN 1

0 commit comments

Comments
 (0)