diff options
| author | Alexander Graf <[email protected]> | 2013-02-13 12:56:14 +0100 | 
|---|---|---|
| committer | Alexander Graf <[email protected]> | 2013-02-13 12:56:14 +0100 | 
| commit | dd92d6f2749c43ebab91c4762a1bc79e6523e936 (patch) | |
| tree | 6e6730bdd09284679c0861df6d0fcbec08ea7a87 /virt/kvm/ioapic.c | |
| parent | b9e3e208935e95ad62bd1b1bc4408c23a9ae3ada (diff) | |
| parent | b0da5bec30eca7ffbb2c89afa6fe503fd418d3a6 (diff) | |
Merge commit 'origin/next' into kvm-ppc-next
Diffstat (limited to 'virt/kvm/ioapic.c')
| -rw-r--r-- | virt/kvm/ioapic.c | 39 | 
1 files changed, 39 insertions, 0 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index f3abbef46c42..ce82b9401958 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -35,6 +35,7 @@  #include <linux/hrtimer.h>  #include <linux/io.h>  #include <linux/slab.h> +#include <linux/export.h>  #include <asm/processor.h>  #include <asm/page.h>  #include <asm/current.h> @@ -115,6 +116,42 @@ static void update_handled_vectors(struct kvm_ioapic *ioapic)  	smp_wmb();  } +void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu, +					u64 *eoi_exit_bitmap) +{ +	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; +	union kvm_ioapic_redirect_entry *e; +	struct kvm_lapic_irq irqe; +	int index; + +	spin_lock(&ioapic->lock); +	/* traverse ioapic entry to set eoi exit bitmap*/ +	for (index = 0; index < IOAPIC_NUM_PINS; index++) { +		e = &ioapic->redirtbl[index]; +		if (!e->fields.mask && +			(e->fields.trig_mode == IOAPIC_LEVEL_TRIG || +			 kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, +				 index))) { +			irqe.dest_id = e->fields.dest_id; +			irqe.vector = e->fields.vector; +			irqe.dest_mode = e->fields.dest_mode; +			irqe.delivery_mode = e->fields.delivery_mode << 8; +			kvm_calculate_eoi_exitmap(vcpu, &irqe, eoi_exit_bitmap); +		} +	} +	spin_unlock(&ioapic->lock); +} +EXPORT_SYMBOL_GPL(kvm_ioapic_calculate_eoi_exitmap); + +void kvm_ioapic_make_eoibitmap_request(struct kvm *kvm) +{ +	struct kvm_ioapic *ioapic = kvm->arch.vioapic; + +	if (!kvm_apic_vid_enabled(kvm) || !ioapic) +		return; +	kvm_make_update_eoibitmap_request(kvm); +} +  static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)  {  	unsigned index; @@ -156,6 +193,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)  		if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG  		    && ioapic->irr & (1 << index))  			ioapic_service(ioapic, index); +		kvm_ioapic_make_eoibitmap_request(ioapic->kvm);  		break;  	}  } @@ -455,6 +493,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)  	spin_lock(&ioapic->lock);  	memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));  	update_handled_vectors(ioapic); +	kvm_ioapic_make_eoibitmap_request(kvm);  	spin_unlock(&ioapic->lock);  	return 0;  }  |