diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-09-16 09:30:41 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-09-16 09:30:41 +0100 |
commit | 71708b1966462eeac3a3a2bc1a74086b2b25b62c (patch) | |
tree | 8a87d5408a4492abd3cb55694fe20ef9c622f630 /xen/arch/x86/hvm/vlapic.c | |
parent | 057958b0ab83fe767397a7ef896b4e6ed63529d5 (diff) | |
download | xen-71708b1966462eeac3a3a2bc1a74086b2b25b62c.tar.gz xen-71708b1966462eeac3a3a2bc1a74086b2b25b62c.tar.bz2 xen-71708b1966462eeac3a3a2bc1a74086b2b25b62c.zip |
x86 hvm: suspend platform timer emulation while its IRQ is masked
This patch gets rid of a timer which IRQ is masked from vcpu's timer
list. It reduces the overhead of VM EXIT and context switch of vm.
Also fixes a potential bug.
(1) VCPU#0: mask the IRQ of a timer. (ex. vioapic.redir[2].mask=1)
(2) VCPU#1: pt_timer_fn() is invoked by expiration of the timer.
(3) VCPU#1: pt_update_irq() is called but does nothing by
pt_irq_masked()==1.
(4) VCPU#1: sleep by halt.
(5) VCPU#0: unmask the IRQ of the timer.
After that, no one wakes up the VCPU#1.
IRQ of ISA is masked by:
- PIC's IMR
- IOAPIC's redir[0]
- IOAPIC's redir[N].mask
- LAPIC's LVT0
- LAPIC enabled/disabled
IRQ of LAPIC timer is masked by:
- LAPIC's LVTT
- LAPIC disabled
When above stuffs are changed, the corresponding vcpu is kicked and
suspended timer emulation is resumed.
In addition, a small bug fix in pt_adjust_global_vcpu_target().
Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
Diffstat (limited to 'xen/arch/x86/hvm/vlapic.c')
-rw-r--r-- | xen/arch/x86/hvm/vlapic.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index b915609d36..603a9200ab 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -624,7 +624,10 @@ static int vlapic_write(struct vcpu *v, unsigned long address, } } else + { vlapic->hw.disabled &= ~VLAPIC_SW_DISABLED; + pt_may_unmask_irq(vlapic_domain(vlapic), &vlapic->pt); + } break; case APIC_ESR: @@ -654,7 +657,12 @@ static int vlapic_write(struct vcpu *v, unsigned long address, val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4]; vlapic_set_reg(vlapic, offset, val); if ( offset == APIC_LVT0 ) + { vlapic_adjust_i8259_target(v->domain); + pt_may_unmask_irq(v->domain, NULL); + } + if ( (offset == APIC_LVTT) && !(val & APIC_LVT_MASKED) ) + pt_may_unmask_irq(NULL, &vlapic->pt); break; case APIC_TMICT: @@ -719,10 +727,12 @@ void vlapic_msr_set(struct vlapic *vlapic, uint64_t value) { vlapic_reset(vlapic); vlapic->hw.disabled &= ~VLAPIC_HW_DISABLED; + pt_may_unmask_irq(vlapic_domain(vlapic), &vlapic->pt); } else { vlapic->hw.disabled |= VLAPIC_HW_DISABLED; + pt_may_unmask_irq(vlapic_domain(vlapic), NULL); } } |