aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vpic.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-09-16 09:30:41 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-09-16 09:30:41 +0100
commit71708b1966462eeac3a3a2bc1a74086b2b25b62c (patch)
tree8a87d5408a4492abd3cb55694fe20ef9c622f630 /xen/arch/x86/hvm/vpic.c
parent057958b0ab83fe767397a7ef896b4e6ed63529d5 (diff)
downloadxen-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.c7
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)