# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Date 1167323595 0
# Node ID ce83c1896accbdc3e073d7d2363d32c5d254945d
# Parent 766eec31afabc566a54749a8b5795160c8687de5
[HVM] Fix assumptions that ISA IRQ 0 connects to GSI 0.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/irq.c | 40 +++++++++++++++++++++-------------------
xen/arch/x86/hvm/vioapic.c | 4 ++--
xen/arch/x86/hvm/vpt.c | 35 +++++++++++++++++++----------------
xen/include/asm-x86/hvm/irq.h | 9 ++++++---
4 files changed, 48 insertions(+), 40 deletions(-)
diff -r 766eec31afab -r ce83c1896acc xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/arch/x86/hvm/irq.c Thu Dec 28 16:33:15 2006 +0000
@@ -85,7 +85,7 @@ void hvm_isa_irq_assert(
struct domain *d, unsigned int isa_irq)
{
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
- unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
+ unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
ASSERT(isa_irq <= 15);
@@ -105,7 +105,7 @@ void hvm_isa_irq_deassert(
struct domain *d, unsigned int isa_irq)
{
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
- unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
+ unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
ASSERT(isa_irq <= 15);
@@ -257,23 +257,25 @@ int cpu_get_interrupt(struct vcpu *v, in
return -1;
}
-int get_intr_vector(struct vcpu* v, int irq, int type)
-{
+int get_isa_irq_vector(struct vcpu *v, int isa_irq, int type)
+{
+ unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
+
if ( type == APIC_DM_EXTINT )
- return v->domain->arch.hvm_domain.irq.vpic[irq >> 3].irq_base
- + (irq & 0x7);
-
- return domain_vioapic(v->domain)->redirtbl[irq].fields.vector;
-}
-
-int is_irq_masked(struct vcpu *v, int irq)
-{
- if ( is_lvtt(v, irq) )
+ return (v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].irq_base
+ + (isa_irq & 7));
+
+ return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
+}
+
+int is_isa_irq_masked(struct vcpu *v, int isa_irq)
+{
+ unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
+
+ if ( is_lvtt(v, isa_irq) )
return !is_lvtt_enabled(v);
- if ( v->domain->arch.hvm_domain.irq.vpic[irq >> 3].imr & (1 << (irq & 7))
- && domain_vioapic(v->domain)->redirtbl[irq].fields.mask )
- return 1;
-
- return 0;
-}
+ return ((v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].imr &
+ (1 << (isa_irq & 7))) &&
+ domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
+}
diff -r 766eec31afab -r ce83c1896acc xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/arch/x86/hvm/vioapic.c Thu Dec 28 16:33:15 2006 +0000
@@ -341,7 +341,7 @@ static void vioapic_deliver(struct vioap
{
#ifdef IRQ0_SPECIAL_ROUTING
/* Force round-robin to pick VCPU 0 */
- if ( irq == 0 )
+ if ( irq == hvm_isa_irq_to_gsi(0) )
{
v = vioapic_domain(vioapic)->vcpu[0];
target = v ? vcpu_vlapic(v) : NULL;
@@ -374,7 +374,7 @@ static void vioapic_deliver(struct vioap
deliver_bitmask &= ~(1 << bit);
#ifdef IRQ0_SPECIAL_ROUTING
/* Do not deliver timer interrupts to VCPU != 0 */
- if ( (irq == 0) && (bit != 0) )
+ if ( irq == hvm_isa_irq_to_gsi(0) )
v = vioapic_domain(vioapic)->vcpu[0];
else
#endif
diff -r 766eec31afab -r ce83c1896acc xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/arch/x86/hvm/vpt.c Thu Dec 28 16:33:15 2006 +0000
@@ -108,16 +108,18 @@ void pt_update_irq(struct vcpu *v)
list_for_each( list, head )
{
pt = list_entry(list, struct periodic_time, list);
- if ( !is_irq_masked(v, pt->irq) && pt->pending_intr_nr
- && pt->last_plt_gtime + pt->period < max_lag )
- {
- max_lag = pt->last_plt_gtime + pt->period;
+ if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr &&
+ ((pt->last_plt_gtime + pt->period_cycles) < max_lag) )
+ {
+ max_lag = pt->last_plt_gtime + pt->period_cycles;
irq = pt->irq;
}
}
if ( is_lvtt(v, irq) )
+ {
vlapic_set_irq(vcpu_vlapic(v), irq, 0);
+ }
else if ( irq >= 0 )
{
hvm_isa_irq_deassert(v->domain, irq);
@@ -141,16 +143,15 @@ struct periodic_time *is_pt_irq(struct v
if ( is_lvtt(v, pt->irq) )
{
- if (pt->irq == vector)
- return pt;
- else
+ if ( pt->irq != vector )
continue;
- }
-
- vec = get_intr_vector(v, pt->irq, type);
+ return pt;
+ }
+
+ vec = get_isa_irq_vector(v, pt->irq, type);
/* RTC irq need special care */
- if ( vector != vec || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
+ if ( (vector != vec) || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
continue;
return pt;
@@ -163,14 +164,14 @@ void pt_intr_post(struct vcpu *v, int ve
{
struct periodic_time *pt = is_pt_irq(v, vector, type);
- if (pt == NULL)
+ if ( pt == NULL )
return;
pt->pending_intr_nr--;
pt->last_plt_gtime += pt->period_cycles;
hvm_set_guest_time(pt->vcpu, pt->last_plt_gtime);
- if (pt->cb)
+ if ( pt->cb != NULL )
pt->cb(pt->vcpu, pt->priv);
}
@@ -200,9 +201,11 @@ void create_periodic_time(struct periodi
destroy_periodic_time(pt);
pt->enabled = 1;
- if (period < 900000) /* < 0.9 ms */
- {
- printk("HVM_PlatformTime: program too small period %"PRIu64"\n",
period);
+ if ( period < 900000 ) /* < 0.9 ms */
+ {
+ gdprintk(XENLOG_WARNING,
+ "HVM_PlatformTime: program too small period %"PRIu64"\n",
+ period);
period = 900000; /* force to 0.9ms */
}
pt->period = period;
diff -r 766eec31afab -r ce83c1896acc xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/include/asm-x86/hvm/irq.h Thu Dec 28 16:33:15 2006 +0000
@@ -61,7 +61,8 @@ struct hvm_irq {
/*
* Number of wires asserting each GSI.
*
- * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space.
+ * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
+ * except ISA IRQ 0, which is connected to GSI 2.
* PCI links map into this space via the PCI-ISA bridge.
*
* GSIs 16+ are used only be PCI devices. The mapping from PCI device to
@@ -87,6 +88,8 @@ struct hvm_irq {
#define hvm_pci_intx_link(dev, intx) \
(((dev) + (intx)) & 3)
+#define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
+
/* Modify state of a PCI INTx wire. */
void hvm_pci_intx_assert(
struct domain *d, unsigned int device, unsigned int intx);
@@ -106,7 +109,7 @@ void hvm_set_callback_gsi(struct domain
int cpu_get_interrupt(struct vcpu *v, int *type);
int cpu_has_pending_irq(struct vcpu *v);
-int get_intr_vector(struct vcpu* vcpu, int irq, int type);
-int is_irq_masked(struct vcpu *v, int irq);
+int get_isa_irq_vector(struct vcpu *vcpu, int irq, int type);
+int is_isa_irq_masked(struct vcpu *v, int isa_irq);
#endif /* __ASM_X86_HVM_IRQ_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|