aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vlapic.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/vlapic.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/vlapic.c')
-rw-r--r--xen/arch/x86/hvm/vlapic.c10
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);
}
}