diff options
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/assigned-dev.c | 13 | ||||
| -rw-r--r-- | virt/kvm/eventfd.c | 15 | ||||
| -rw-r--r-- | virt/kvm/ioapic.c | 18 | ||||
| -rw-r--r-- | virt/kvm/ioapic.h | 2 | ||||
| -rw-r--r-- | virt/kvm/irq_comm.c | 19 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 3 | 
6 files changed, 41 insertions, 29 deletions
| diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 3642239252b0..f4c7f591b5d8 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -80,11 +80,12 @@ kvm_assigned_dev_raise_guest_irq(struct kvm_assigned_dev_kernel *assigned_dev,  		spin_lock(&assigned_dev->intx_mask_lock);  		if (!(assigned_dev->flags & KVM_DEV_ASSIGN_MASK_INTX))  			kvm_set_irq(assigned_dev->kvm, -				    assigned_dev->irq_source_id, vector, 1); +				    assigned_dev->irq_source_id, vector, 1, +				    false);  		spin_unlock(&assigned_dev->intx_mask_lock);  	} else  		kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, -			    vector, 1); +			    vector, 1, false);  }  static irqreturn_t kvm_assigned_dev_thread_intx(int irq, void *dev_id) @@ -165,7 +166,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)  		container_of(kian, struct kvm_assigned_dev_kernel,  			     ack_notifier); -	kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0); +	kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0, false);  	spin_lock(&dev->intx_mask_lock); @@ -188,7 +189,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)  		if (reassert)  			kvm_set_irq(dev->kvm, dev->irq_source_id, -				    dev->guest_irq, 1); +				    dev->guest_irq, 1, false);  	}  	spin_unlock(&dev->intx_mask_lock); @@ -202,7 +203,7 @@ static void deassign_guest_irq(struct kvm *kvm,  						&assigned_dev->ack_notifier);  	kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, -		    assigned_dev->guest_irq, 0); +		    assigned_dev->guest_irq, 0, false);  	if (assigned_dev->irq_source_id != -1)  		kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id); @@ -901,7 +902,7 @@ static int kvm_vm_ioctl_set_pci_irq_mask(struct kvm *kvm,  	if (match->irq_requested_type & KVM_DEV_IRQ_GUEST_INTX) {  		if (assigned_dev->flags & KVM_DEV_ASSIGN_MASK_INTX) {  			kvm_set_irq(match->kvm, match->irq_source_id, -				    match->guest_irq, 0); +				    match->guest_irq, 0, false);  			/*  			 * Masking at hardware-level is performed on demand,  			 * i.e. when an IRQ actually arrives at the host. diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 48790989f8d2..c5d43ffbf1f3 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -100,11 +100,13 @@ irqfd_inject(struct work_struct *work)  	struct kvm *kvm = irqfd->kvm;  	if (!irqfd->resampler) { -		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1); -		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0); +		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1, +				false); +		kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0, +				false);  	} else  		kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, -			    irqfd->gsi, 1); +			    irqfd->gsi, 1, false);  }  /* @@ -121,7 +123,7 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)  	resampler = container_of(kian, struct _irqfd_resampler, notifier);  	kvm_set_irq(resampler->kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, -		    resampler->notifier.gsi, 0); +		    resampler->notifier.gsi, 0, false);  	rcu_read_lock(); @@ -146,7 +148,7 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd)  		list_del(&resampler->link);  		kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier);  		kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, -			    resampler->notifier.gsi, 0); +			    resampler->notifier.gsi, 0, false);  		kfree(resampler);  	} @@ -225,7 +227,8 @@ irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)  		irq = rcu_dereference(irqfd->irq_entry);  		/* An event has been signaled, inject an interrupt */  		if (irq) -			kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1); +			kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, +					false);  		else  			schedule_work(&irqfd->inject);  		rcu_read_unlock(); diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 76528fff252d..a49fcd55b378 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -50,7 +50,8 @@  #else  #define ioapic_debug(fmt, arg...)  #endif -static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq); +static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq, +		bool line_status);  static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,  					  unsigned long addr, @@ -146,7 +147,8 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)  	    __rtc_irq_eoi_tracking_restore_one(vcpu);  } -static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) +static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx, +		bool line_status)  {  	union kvm_ioapic_redirect_entry *pent;  	int injected = -1; @@ -154,7 +156,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)  	pent = &ioapic->redirtbl[idx];  	if (!pent->fields.mask) { -		injected = ioapic_deliver(ioapic, idx); +		injected = ioapic_deliver(ioapic, idx, line_status);  		if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)  			pent->fields.remote_irr = 1;  	} @@ -248,13 +250,13 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)  			kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after);  		if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG  		    && ioapic->irr & (1 << index)) -			ioapic_service(ioapic, index); +			ioapic_service(ioapic, index, false);  		kvm_ioapic_make_eoibitmap_request(ioapic->kvm);  		break;  	}  } -static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) +static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq, bool line_status)  {  	union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];  	struct kvm_lapic_irq irqe; @@ -277,7 +279,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)  }  int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, -		       int level) +		       int level, bool line_status)  {  	u32 old_irr;  	u32 mask = 1 << irq; @@ -300,7 +302,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,  		ioapic->irr |= mask;  		if ((edge && old_irr != ioapic->irr) ||  		    (!edge && !entry.fields.remote_irr)) -			ret = ioapic_service(ioapic, irq); +			ret = ioapic_service(ioapic, irq, line_status);  		else  			ret = 0; /* report coalesced interrupt */  	} @@ -349,7 +351,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,  		ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);  		ent->fields.remote_irr = 0;  		if (!ent->fields.mask && (ioapic->irr & (1 << i))) -			ioapic_service(ioapic, i); +			ioapic_service(ioapic, i, false);  	}  } diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 313fc4ea61d9..554157bbb586 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h @@ -89,7 +89,7 @@ bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector);  int kvm_ioapic_init(struct kvm *kvm);  void kvm_ioapic_destroy(struct kvm *kvm);  int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, -		       int level); +		       int level, bool line_status);  void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id);  void kvm_ioapic_reset(struct kvm_ioapic *ioapic);  int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 2f07d2e59a2d..8efb580edfef 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -35,7 +35,8 @@  #include "ioapic.h"  static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, -			   struct kvm *kvm, int irq_source_id, int level) +			   struct kvm *kvm, int irq_source_id, int level, +			   bool line_status)  {  #ifdef CONFIG_X86  	struct kvm_pic *pic = pic_irqchip(kvm); @@ -46,10 +47,12 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,  }  static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, -			      struct kvm *kvm, int irq_source_id, int level) +			      struct kvm *kvm, int irq_source_id, int level, +			      bool line_status)  {  	struct kvm_ioapic *ioapic = kvm->arch.vioapic; -	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level); +	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level, +				line_status);  }  inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) @@ -121,7 +124,7 @@ static inline void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,  }  int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, -		struct kvm *kvm, int irq_source_id, int level) +		struct kvm *kvm, int irq_source_id, int level, bool line_status)  {  	struct kvm_lapic_irq irq; @@ -159,7 +162,7 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)  	route.msi.address_hi = msi->address_hi;  	route.msi.data = msi->data; -	return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1); +	return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false);  }  /* @@ -168,7 +171,8 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)   *  = 0   Interrupt was coalesced (previous irq is still pending)   *  > 0   Number of CPUs interrupt was delivered to   */ -int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) +int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, +		bool line_status)  {  	struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS];  	int ret = -1, i = 0; @@ -189,7 +193,8 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level)  	while(i--) {  		int r; -		r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level); +		r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level, +				line_status);  		if (r < 0)  			continue; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5cc53c907d3b..ac3182eed462 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2258,7 +2258,8 @@ static long kvm_vm_ioctl(struct file *filp,  		if (copy_from_user(&irq_event, argp, sizeof irq_event))  			goto out; -		r = kvm_vm_ioctl_irq_line(kvm, &irq_event); +		r = kvm_vm_ioctl_irq_line(kvm, &irq_event, +					ioctl == KVM_IRQ_LINE_STATUS);  		if (r)  			goto out; |