# HG changeset patch
# User Paul Durrant <paul.durrant@xxxxxxxxxx>
# Date 1278948846 -3600
# Node ID 2dbd30d4027eeafc41fa46638679eb7e3e1bc951
# Parent f12837d7a50e3e5f843bd1a7113bb329661c7dd0
Dont' round-robin the callback interrupt.
Arrange that the event channel callback interrupt always goes to the
lowest vcpu with a matching local apic. This should, in most cases,
be VCPU0 (to which all event channels are bound for HVM guests) but
this cannot be guaranteed.
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
CC: Tim Deegan <tim.deegan@xxxxxxxxxx>
diff -r f12837d7a50e -r 2dbd30d4027e xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Mon Jul 12 10:48:34 2010 +0100
+++ b/xen/arch/x86/hvm/vioapic.c Mon Jul 12 16:34:06 2010 +0100
@@ -276,6 +276,29 @@
return pt_active(&pit->pt0);
}
+static int is_callback_via(struct domain *d, int irq)
+{
+ struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+
+ switch ( hvm_irq->callback_via_type )
+ {
+ case HVMIRQ_callback_gsi: {
+ unsigned int gsi = hvm_irq->callback_via.gsi;
+
+ return irq == gsi;
+ }
+ case HVMIRQ_callback_pci_intx: {
+ unsigned int pdev = hvm_irq->callback_via.pci.dev;
+ unsigned int pintx = hvm_irq->callback_via.pci.intx;
+
+ return irq == hvm_pci_intx_gsi(pdev, pintx);
+ }
+ case HVMIRQ_callback_vector:
+ default:
+ return 0;
+ }
+}
+
static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq)
{
uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
@@ -307,7 +330,11 @@
}
else
#endif
+ if ( is_callback_via(d, irq) )
+ target = vlapic_lowest_vcpu(d, NULL, 0, dest, dest_mode);
+ else
target = vlapic_lowest_prio(d, NULL, 0, dest, dest_mode);
+
if ( target != NULL )
{
ioapic_inj_irq(vioapic, target, vector, trig_mode, delivery_mode);
diff -r f12837d7a50e -r 2dbd30d4027e xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Mon Jul 12 10:48:34 2010 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Mon Jul 12 16:34:06 2010 +0100
@@ -354,6 +354,27 @@
if ( target != NULL )
d->arch.hvm_domain.irq.round_robin_prev_vcpu =
vlapic_vcpu(target)->vcpu_id;
+
+ return target;
+}
+
+struct vlapic *vlapic_lowest_vcpu(
+ struct domain *d, struct vlapic *source,
+ int short_hand, uint8_t dest, uint8_t dest_mode)
+{
+ struct vlapic *vlapic, *target = NULL;
+ struct vcpu *v;
+
+ if ( unlikely(!d->vcpu) )
+ return NULL;
+
+ for ( v = d->vcpu[0]; v; v = v->next_in_list ) {
+ vlapic = vcpu_vlapic(v);
+ if ( vlapic_match_dest(vlapic, source, short_hand, dest, dest_mode) &&
+ vlapic_enabled(vlapic) ) {
+ target = vlapic;
+ }
+ }
return target;
}
diff -r f12837d7a50e -r 2dbd30d4027e xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h Mon Jul 12 10:48:34 2010 +0100
+++ b/xen/include/asm-x86/hvm/vlapic.h Mon Jul 12 16:34:06 2010 +0100
@@ -100,6 +100,10 @@
struct domain *d, struct vlapic *source,
int short_hand, uint8_t dest, uint8_t dest_mode);
+struct vlapic *vlapic_lowest_vcpu(
+ struct domain *d, struct vlapic *source,
+ int short_hand, uint8_t dest, uint8_t dest_mode);
+
bool_t vlapic_match_dest(
struct vlapic *target, struct vlapic *source,
int short_hand, uint8_t dest, uint8_t dest_mode);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|