Commit 6db6a5f3 authored by Rusty Russell's avatar Rusty Russell

lguest: fix for CONFIG_SPARSE_IRQ=y

Impact: remove lots of lguest boot WARN_ON() when CONFIG_SPARSE_IRQ=y

We now need to call irq_to_desc_alloc_cpu() before
set_irq_chip_and_handler_name(), but we can't do that from init_IRQ (no
kmalloc available).

So do it as we use interrupts instead.  Also means we only alloc for
irqs we use, which was the intent of CONFIG_SPARSE_IRQ anyway.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@redhat.com>
parent cbd88c8e
...@@ -594,19 +594,21 @@ static void __init lguest_init_IRQ(void) ...@@ -594,19 +594,21 @@ static void __init lguest_init_IRQ(void)
/* Some systems map "vectors" to interrupts weirdly. Lguest has /* Some systems map "vectors" to interrupts weirdly. Lguest has
* a straightforward 1 to 1 mapping, so force that here. */ * a straightforward 1 to 1 mapping, so force that here. */
__get_cpu_var(vector_irq)[vector] = i; __get_cpu_var(vector_irq)[vector] = i;
if (vector != SYSCALL_VECTOR) { if (vector != SYSCALL_VECTOR)
set_intr_gate(vector, set_intr_gate(vector, interrupt[i]);
interrupt[vector-FIRST_EXTERNAL_VECTOR]);
set_irq_chip_and_handler_name(i, &lguest_irq_controller,
handle_level_irq,
"level");
}
} }
/* This call is required to set up for 4k stacks, where we have /* This call is required to set up for 4k stacks, where we have
* separate stacks for hard and soft interrupts. */ * separate stacks for hard and soft interrupts. */
irq_ctx_init(smp_processor_id()); irq_ctx_init(smp_processor_id());
} }
void lguest_setup_irq(unsigned int irq)
{
irq_to_desc_alloc_cpu(irq, 0);
set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
handle_level_irq, "level");
}
/* /*
* Time. * Time.
* *
......
...@@ -212,6 +212,9 @@ static void lg_notify(struct virtqueue *vq) ...@@ -212,6 +212,9 @@ static void lg_notify(struct virtqueue *vq)
hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0); hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
} }
/* An extern declaration inside a C file is bad form. Don't do it. */
extern void lguest_setup_irq(unsigned int irq);
/* This routine finds the first virtqueue described in the configuration of /* This routine finds the first virtqueue described in the configuration of
* this device and sets it up. * this device and sets it up.
* *
...@@ -266,6 +269,9 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, ...@@ -266,6 +269,9 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
goto unmap; goto unmap;
} }
/* Make sure the interrupt is allocated. */
lguest_setup_irq(lvq->config.irq);
/* Tell the interrupt for this virtqueue to go to the virtio_ring /* Tell the interrupt for this virtqueue to go to the virtio_ring
* interrupt handler. */ * interrupt handler. */
/* FIXME: We used to have a flag for the Host to tell us we could use /* FIXME: We used to have a flag for the Host to tell us we could use
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment