All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] avoid redeliver of edge interrupt before next edge
@ 2009-07-05 15:48 Gleb Natapov
  2009-07-05 15:48 ` [PATCH 2/2] Use temporary variable to shorten lines Gleb Natapov
  2009-07-05 15:58 ` [PATCH 1/2] avoid redeliver of edge interrupt before next edge Avi Kivity
  0 siblings, 2 replies; 3+ messages in thread
From: Gleb Natapov @ 2009-07-05 15:48 UTC (permalink / raw)
  To: avi; +Cc: kvm

The check for an edge is broken in current ioapic code. ioapic->irr is
cleared on each edge interrupt by ioapic_service() and this makes
old_irr != ioapic->irr condition in kvm_ioapic_set_irq() to be always
true. The patch fixes the code to properly recognise edge.

Some HW emulation calls set_irq() without level change. If each such
call is propagated to an OS it may confuse a device driver. This is the
case with keyboard device emulation and WindowsXP installer on SMP VM.
Each button stroke produce two interrupts (down/up) one interrupt is
submitted to CPU0 and another to CPU1. This confuses Windows somehow
and it ignores button strokes.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
---

Same patch as before but split in two. First one fixes bug, second
make cosmetic changes.

 virt/kvm/ioapic.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 124ecf7..8a9c6cc 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -95,8 +95,6 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
 		if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
 			pent->fields.remote_irr = 1;
 	}
-	if (!pent->fields.trig_mode)
-		ioapic->irr &= ~(1 << idx);
 
 	return injected;
 }
@@ -136,7 +134,8 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
 		mask_after = ioapic->redirtbl[index].fields.mask;
 		if (mask_before != mask_after)
 			kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after);
-		if (ioapic->irr & (1 << index))
+		if (ioapic->redirtbl[index].fields.trig_mode == IOAPIC_LEVEL_TRIG
+		    && ioapic->irr & (1 << index))
 			ioapic_service(ioapic, index);
 		break;
 	}
@@ -186,9 +185,10 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
 		if (!level)
 			ioapic->irr &= ~mask;
 		else {
+			int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG);
 			ioapic->irr |= mask;
-			if ((!entry.fields.trig_mode && old_irr != ioapic->irr)
-			    || !entry.fields.remote_irr)
+			if ((edge && old_irr != ioapic->irr) ||
+			    (!edge && !entry.fields.remote_irr))
 				ret = ioapic_service(ioapic, irq);
 		}
 	}
-- 
1.6.2.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] Use temporary variable to shorten lines.
  2009-07-05 15:48 [PATCH 1/2] avoid redeliver of edge interrupt before next edge Gleb Natapov
@ 2009-07-05 15:48 ` Gleb Natapov
  2009-07-05 15:58 ` [PATCH 1/2] avoid redeliver of edge interrupt before next edge Avi Kivity
  1 sibling, 0 replies; 3+ messages in thread
From: Gleb Natapov @ 2009-07-05 15:48 UTC (permalink / raw)
  To: avi; +Cc: kvm

Cosmetic only. No logical is changed by this patch.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
 virt/kvm/ioapic.c |   22 +++++++++++++---------
 1 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 8a9c6cc..202c405 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -116,29 +116,33 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
 	case IOAPIC_REG_ARB_ID:
 		break;
 
-	default:
+	default: {
+		union kvm_ioapic_redirect_entry *e;
+
 		index = (ioapic->ioregsel - 0x10) >> 1;
 
 		ioapic_debug("change redir index %x val %x\n", index, val);
 		if (index >= IOAPIC_NUM_PINS)
 			return;
-		mask_before = ioapic->redirtbl[index].fields.mask;
+		e = &ioapic->redirtbl[index];
+		mask_before = e->fields.mask;
 		if (ioapic->ioregsel & 1) {
-			ioapic->redirtbl[index].bits &= 0xffffffff;
-			ioapic->redirtbl[index].bits |= (u64) val << 32;
+			e->bits &= 0xffffffff;
+			e->bits |= (u64) val << 32;
 		} else {
-			ioapic->redirtbl[index].bits &= ~0xffffffffULL;
-			ioapic->redirtbl[index].bits |= (u32) val;
-			ioapic->redirtbl[index].fields.remote_irr = 0;
+			e->bits &= ~0xffffffffULL;
+			e->bits |= (u32) val;
+			e->fields.remote_irr = 0;
 		}
-		mask_after = ioapic->redirtbl[index].fields.mask;
+		mask_after = e->fields.mask;
 		if (mask_before != mask_after)
 			kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after);
-		if (ioapic->redirtbl[index].fields.trig_mode == IOAPIC_LEVEL_TRIG
+		if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG
 		    && ioapic->irr & (1 << index))
 			ioapic_service(ioapic, index);
 		break;
 	}
+	}
 }
 
 static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
-- 
1.6.2.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] avoid redeliver of edge interrupt before next edge
  2009-07-05 15:48 [PATCH 1/2] avoid redeliver of edge interrupt before next edge Gleb Natapov
  2009-07-05 15:48 ` [PATCH 2/2] Use temporary variable to shorten lines Gleb Natapov
@ 2009-07-05 15:58 ` Avi Kivity
  1 sibling, 0 replies; 3+ messages in thread
From: Avi Kivity @ 2009-07-05 15:58 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: kvm

On 07/05/2009 06:48 PM, Gleb Natapov wrote:
> The check for an edge is broken in current ioapic code. ioapic->irr is
> cleared on each edge interrupt by ioapic_service() and this makes
> old_irr != ioapic->irr condition in kvm_ioapic_set_irq() to be always
> true. The patch fixes the code to properly recognise edge.
>
> Some HW emulation calls set_irq() without level change. If each such
> call is propagated to an OS it may confuse a device driver. This is the
> case with keyboard device emulation and WindowsXP installer on SMP VM.
> Each button stroke produce two interrupts (down/up) one interrupt is
> submitted to CPU0 and another to CPU1. This confuses Windows somehow
> and it ignores button strokes.
>
> Signed-off-by: Gleb Natapov<gleb@redhat.com>
> ---
>
> Same patch as before but split in two. First one fixes bug, second
> make cosmetic changes.
>
>    

Applied both, thanks.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-07-05 15:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-05 15:48 [PATCH 1/2] avoid redeliver of edge interrupt before next edge Gleb Natapov
2009-07-05 15:48 ` [PATCH 2/2] Use temporary variable to shorten lines Gleb Natapov
2009-07-05 15:58 ` [PATCH 1/2] avoid redeliver of edge interrupt before next edge Avi Kivity

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.