diff options
author | Avi Kivity <avi@qumranet.com> | 2007-10-22 10:50:39 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 11:01:20 -0500 |
commit | b209749f528488c4c0d20a42c0fbcbf49e6933b3 (patch) | |
tree | 0e0a24225a5c6bca1c1986cc0daaf8753424cfe6 /arch/x86/kvm/lapic.c | |
parent | 565f1fbd9d2f766dcfed5db90b89ef80afe8b49a (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.c | 21 |
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 | ||
554 | static 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 | |||
565 | static 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 | |||
554 | static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) | 571 | static 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 | ||