Skip to content

Commit

Permalink
lguest: allow any process to send interrupts
Browse files Browse the repository at this point in the history
We currently only allow the Launcher process to send interrupts, but it
as we already send interrupts from the hrtimer, it's a simple matter of
extracting that code into a common set_interrupt routine.

As we switch to a thread per virtqueue, this avoids a bottleneck through the
main Launcher process.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Jun 12, 2009
1 parent 92b4d8d commit 9f155a9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
19 changes: 15 additions & 4 deletions drivers/lguest/interrupts_and_traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,20 @@ void try_deliver_interrupt(struct lg_cpu *cpu, unsigned int irq, bool more)
if (!more)
put_user(0, &cpu->lg->lguest_data->irq_pending);
}

/* 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)
{
/* Next time the Guest runs, the core code will see if it can deliver
* this interrupt. */
set_bit(irq, cpu->irqs_pending);

/* 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);
}
/*:*/

/* Linux uses trap 128 for system calls. Plan9 uses 64, and Ron Minnich sent
Expand Down Expand Up @@ -528,10 +542,7 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
struct lg_cpu *cpu = container_of(timer, struct lg_cpu, hrt);

/* Remember the first interrupt is the timer interrupt. */
set_bit(0, cpu->irqs_pending);
/* Guest may be stopped or running on another CPU. */
if (!wake_up_process(cpu->tsk))
kick_process(cpu->tsk);
set_interrupt(cpu, 0);
return HRTIMER_NORESTART;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/lguest/lg.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user);
/* 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);
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);
Expand Down
10 changes: 2 additions & 8 deletions drivers/lguest/lguest_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ static int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input)
return -EFAULT;
if (irq >= LGUEST_IRQS)
return -EINVAL;
/* Next time the Guest runs, the core code will see if it can deliver
* this interrupt. */
set_bit(irq, cpu->irqs_pending);

set_interrupt(cpu, irq);
return 0;
}

Expand Down Expand Up @@ -252,11 +251,6 @@ static ssize_t write(struct file *file, const char __user *in,
/* Once the Guest is dead, you can only read() why it died. */
if (lg->dead)
return -ENOENT;

/* If you're not the task which owns the Guest, all you can do
* is break the Launcher out of running the Guest. */
if (current != cpu->tsk && req != LHREQ_BREAK)
return -EPERM;
}

switch (req) {
Expand Down

0 comments on commit 9f155a9

Please sign in to comment.