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/vpic.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/vpic.c')
-rw-r--r-- | xen/arch/x86/hvm/vpic.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c index 81bfac5db7..fea3f68f9e 100644 --- a/xen/arch/x86/hvm/vpic.c +++ b/xen/arch/x86/hvm/vpic.c @@ -178,7 +178,7 @@ static void vpic_ioport_write( struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val) { int priority, cmd, irq; - uint8_t mask; + uint8_t mask, unmasked = 0; vpic_lock(vpic); @@ -190,6 +190,7 @@ static void vpic_ioport_write( /* Clear edge-sensing logic. */ vpic->irr &= vpic->elcr; + unmasked = vpic->imr; /* No interrupts masked or in service. */ vpic->imr = vpic->isr = 0; @@ -268,6 +269,7 @@ static void vpic_ioport_write( { case 0: /* OCW1 */ + unmasked = vpic->imr & (~val); vpic->imr = val; break; case 1: @@ -295,6 +297,9 @@ static void vpic_ioport_write( vpic_update_int_output(vpic); vpic_unlock(vpic); + + if ( unmasked ) + pt_may_unmask_irq(vpic_domain(vpic), NULL); } static uint32_t vpic_ioport_read(struct hvm_hw_vpic *vpic, uint32_t addr) |