From e5a5e889ffd988f132daf488c69dec2eb438fcfc Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 28 Dec 2009 14:08:30 +0200 Subject: [PATCH] --- yaml --- r: 185975 b: refs/heads/master c: 46a929bc15fcd48e1e0e770a44040a6949cae133 h: refs/heads/master i: 185973: be1e2a90740f63c6d651553573c6fb6de9a2f81a 185971: 1131d0c4e12a6ab3f480902256a1762ff620a312 185967: cc44ebdc2ee5d9bbc356e3226fe006efa12b024e v: v3 --- [refs] | 2 +- trunk/virt/kvm/ioapic.c | 19 +++++++++++++++++++ trunk/virt/kvm/ioapic.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 1696be8dae3e..8f6849f4b04e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f4c9e87c83a9f5bc1800db27dbb39e5cd1254c0a +refs/heads/master: 46a929bc15fcd48e1e0e770a44040a6949cae133 diff --git a/trunk/virt/kvm/ioapic.c b/trunk/virt/kvm/ioapic.c index f01392f51e86..a2edfd177faf 100644 --- a/trunk/virt/kvm/ioapic.c +++ b/trunk/virt/kvm/ioapic.c @@ -100,6 +100,19 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) return injected; } +static void update_handled_vectors(struct kvm_ioapic *ioapic) +{ + DECLARE_BITMAP(handled_vectors, 256); + int i; + + memset(handled_vectors, 0, sizeof(handled_vectors)); + for (i = 0; i < IOAPIC_NUM_PINS; ++i) + __set_bit(ioapic->redirtbl[i].fields.vector, handled_vectors); + memcpy(ioapic->handled_vectors, handled_vectors, + sizeof(handled_vectors)); + smp_wmb(); +} + static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) { unsigned index; @@ -134,6 +147,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) e->bits |= (u32) val; e->fields.remote_irr = 0; } + update_handled_vectors(ioapic); mask_after = e->fields.mask; if (mask_before != mask_after) kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after); @@ -241,6 +255,9 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode) { struct kvm_ioapic *ioapic = kvm->arch.vioapic; + smp_rmb(); + if (!test_bit(vector, ioapic->handled_vectors)) + return; mutex_lock(&ioapic->lock); __kvm_ioapic_update_eoi(ioapic, vector, trigger_mode); mutex_unlock(&ioapic->lock); @@ -352,6 +369,7 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic) ioapic->ioregsel = 0; ioapic->irr = 0; ioapic->id = 0; + update_handled_vectors(ioapic); } static const struct kvm_io_device_ops ioapic_mmio_ops = { @@ -401,6 +419,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) mutex_lock(&ioapic->lock); memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); + update_handled_vectors(ioapic); mutex_unlock(&ioapic->lock); return 0; } diff --git a/trunk/virt/kvm/ioapic.h b/trunk/virt/kvm/ioapic.h index 419c43b667ab..a505ce9054f3 100644 --- a/trunk/virt/kvm/ioapic.h +++ b/trunk/virt/kvm/ioapic.h @@ -46,6 +46,7 @@ struct kvm_ioapic { struct kvm *kvm; void (*ack_notifier)(void *opaque, int irq); struct mutex lock; + DECLARE_BITMAP(handled_vectors, 256); }; #ifdef DEBUG