lguest: Return -EEXIST from LHREQ_IRQ if interrupt already pending

Allows for more stats in the Launcher, as it can tell it's triggering
redundant irqs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 Documentation/lguest/lguest.c         |    2 +-
 drivers/lguest/interrupts_and_traps.c |    6 ++++--
 drivers/lguest/lg.h                   |    2 +-
 drivers/lguest/lguest_user.c          |    3 +--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -552,7 +552,7 @@ static void trigger_irq(struct virtqueue
 		return;
 
 	/* Send the Guest an interrupt tell them we used something up. */
-	if (write(lguest_fd, buf, sizeof(buf)) != 0)
+	if (write(lguest_fd, buf, sizeof(buf)) != 0 && errno != EEXIST)
 		err(1, "Triggering irq %i", vq->config.irq);
 }
 
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -237,17 +237,19 @@ void try_deliver_interrupt(struct lg_cpu
 }
 
 /* And this is the routine when we want to set an interrupt for the Guest. */
-void set_interrupt(struct lg_cpu *cpu, unsigned int irq)
+int set_interrupt(struct lg_cpu *cpu, unsigned int irq)
 {
 	/* Next time the Guest runs, the core code will see if it can deliver
 	 * this interrupt. */
-	set_bit(irq, cpu->irqs_pending);
+	if (test_and_set_bit(irq, cpu->irqs_pending))
+		return -EEXIST;
 
 	/* Make sure it sees it; it might be asleep (eg. halted), or
 	 * running the Guest right now, in which case kick_process()
 	 * will knock it out. */
 	if (!wake_up_process(cpu->tsk))
 		kick_process(cpu->tsk);
+	return 0;
 }
 /*:*/
 
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -149,7 +149,7 @@ int run_guest(struct lg_cpu *cpu, unsign
 /* interrupts_and_traps.c: */
 unsigned int interrupt_pending(struct lg_cpu *cpu, bool *more);
 void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq, bool more);
-void set_interrupt(struct lg_cpu *cpu, unsigned int irq);
+int set_interrupt(struct lg_cpu *cpu, unsigned int irq);
 bool deliver_trap(struct lg_cpu *cpu, unsigned int num);
 void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i,
 			  u32 low, u32 hi);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -116,8 +116,7 @@ static int user_send_irq(struct lg_cpu *
 	if (irq >= LGUEST_IRQS)
 		return -EINVAL;
 
-	set_interrupt(cpu, irq);
-	return 0;
+	return set_interrupt(cpu, irq);
 }
 
 /*L:040 Once our Guest is initialized, the Launcher makes it run by reading
