aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/lapic.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-10-22 10:50:39 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 11:01:20 -0500
commitb209749f528488c4c0d20a42c0fbcbf49e6933b3 (patch)
tree0e0a24225a5c6bca1c1986cc0daaf8753424cfe6 /arch/x86/kvm/lapic.c
parent565f1fbd9d2f766dcfed5db90b89ef80afe8b49a (diff)
KVM: local APIC TPR access reporting facility
Add a facility to report on accesses to the local apic tpr even if the local apic is emulated in the kernel. This is basically a hack that allows userspace to patch Windows which tends to bang on the tpr a lot. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r--arch/x86/kvm/lapic.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 4076331b01ee..50c3f3a8dd3d 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -551,6 +551,23 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
551 return tmcct; 551 return tmcct;
552} 552}
553 553
554static void __report_tpr_access(struct kvm_lapic *apic, bool write)
555{
556 struct kvm_vcpu *vcpu = apic->vcpu;
557 struct kvm_run *run = vcpu->run;
558
559 set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests);
560 kvm_x86_ops->cache_regs(vcpu);
561 run->tpr_access.rip = vcpu->arch.rip;
562 run->tpr_access.is_write = write;
563}
564
565static inline void report_tpr_access(struct kvm_lapic *apic, bool write)
566{
567 if (apic->vcpu->arch.tpr_access_reporting)
568 __report_tpr_access(apic, write);
569}
570
554static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) 571static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
555{ 572{
556 u32 val = 0; 573 u32 val = 0;
@@ -568,6 +585,9 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
568 val = apic_get_tmcct(apic); 585 val = apic_get_tmcct(apic);
569 break; 586 break;
570 587
588 case APIC_TASKPRI:
589 report_tpr_access(apic, false);
590 /* fall thru */
571 default: 591 default:
572 apic_update_ppr(apic); 592 apic_update_ppr(apic);
573 val = apic_get_reg(apic, offset); 593 val = apic_get_reg(apic, offset);
@@ -677,6 +697,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
677 break; 697 break;
678 698
679 case APIC_TASKPRI: 699 case APIC_TASKPRI:
700 report_tpr_access(apic, true);
680 apic_set_tpr(apic, val & 0xff); 701 apic_set_tpr(apic, val & 0xff);
681 break; 702 break;
682 703