diff options
author | Stratos Psomadakis <psomas@cslab.ece.ntua.gr> | 2012-01-12 00:14:47 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-01-12 00:14:47 -0500 |
commit | b6c96c0214138186f495e3ee73737c6fc5e4efa2 (patch) | |
tree | 991ed5cd8c219543fb32f2b919556d5634859c90 | |
parent | 07fe9977b6234ede1bd29e10e0323e478860c871 (diff) |
lguest: Make sure interrupt is allocated ok by lguest_setup_irq
Make sure the interrupt is allocated correctly by lguest_setup_irq (check the
return value of irq_alloc_desc_at for -ENOMEM)
Signed-off-by: Stratos Psomadakis <psomas@cslab.ece.ntua.gr>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (cleanups and commentry)
-rw-r--r-- | arch/x86/lguest/boot.c | 21 | ||||
-rw-r--r-- | drivers/lguest/lguest_device.c | 10 |
2 files changed, 20 insertions, 11 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index cf4603ba866f..642d8805bc1b 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -856,18 +856,23 @@ static void __init lguest_init_IRQ(void) | |||
856 | } | 856 | } |
857 | 857 | ||
858 | /* | 858 | /* |
859 | * With CONFIG_SPARSE_IRQ, interrupt descriptors are allocated as-needed, so | 859 | * Interrupt descriptors are allocated as-needed, but low-numbered ones are |
860 | * rather than set them in lguest_init_IRQ we are called here every time an | 860 | * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it |
861 | * lguest device needs an interrupt. | 861 | * tells us the irq is already used: other errors (ie. ENOMEM) we take |
862 | * | 862 | * seriously. |
863 | * FIXME: irq_alloc_desc_at() can fail due to lack of memory, we should | ||
864 | * pass that up! | ||
865 | */ | 863 | */ |
866 | void lguest_setup_irq(unsigned int irq) | 864 | int lguest_setup_irq(unsigned int irq) |
867 | { | 865 | { |
868 | irq_alloc_desc_at(irq, 0); | 866 | int err; |
867 | |||
868 | /* Returns -ve error or vector number. */ | ||
869 | err = irq_alloc_desc_at(irq, 0); | ||
870 | if (err < 0 && err != -EEXIST) | ||
871 | return err; | ||
872 | |||
869 | irq_set_chip_and_handler_name(irq, &lguest_irq_controller, | 873 | irq_set_chip_and_handler_name(irq, &lguest_irq_controller, |
870 | handle_level_irq, "level"); | 874 | handle_level_irq, "level"); |
875 | return 0; | ||
871 | } | 876 | } |
872 | 877 | ||
873 | /* | 878 | /* |
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 6a1d6447b864..9e8388efd88e 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -241,7 +241,7 @@ static void lg_notify(struct virtqueue *vq) | |||
241 | } | 241 | } |
242 | 242 | ||
243 | /* An extern declaration inside a C file is bad form. Don't do it. */ | 243 | /* An extern declaration inside a C file is bad form. Don't do it. */ |
244 | extern void lguest_setup_irq(unsigned int irq); | 244 | extern int lguest_setup_irq(unsigned int irq); |
245 | 245 | ||
246 | /* | 246 | /* |
247 | * This routine finds the Nth virtqueue described in the configuration of | 247 | * This routine finds the Nth virtqueue described in the configuration of |
@@ -304,7 +304,9 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
304 | } | 304 | } |
305 | 305 | ||
306 | /* Make sure the interrupt is allocated. */ | 306 | /* Make sure the interrupt is allocated. */ |
307 | lguest_setup_irq(lvq->config.irq); | 307 | err = lguest_setup_irq(lvq->config.irq); |
308 | if (err) | ||
309 | goto destroy_vring; | ||
308 | 310 | ||
309 | /* | 311 | /* |
310 | * Tell the interrupt for this virtqueue to go to the virtio_ring | 312 | * Tell the interrupt for this virtqueue to go to the virtio_ring |
@@ -317,7 +319,7 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
317 | err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED, | 319 | err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED, |
318 | dev_name(&vdev->dev), vq); | 320 | dev_name(&vdev->dev), vq); |
319 | if (err) | 321 | if (err) |
320 | goto destroy_vring; | 322 | goto free_desc; |
321 | 323 | ||
322 | /* | 324 | /* |
323 | * Last of all we hook up our 'struct lguest_vq_info" to the | 325 | * Last of all we hook up our 'struct lguest_vq_info" to the |
@@ -326,6 +328,8 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
326 | vq->priv = lvq; | 328 | vq->priv = lvq; |
327 | return vq; | 329 | return vq; |
328 | 330 | ||
331 | free_desc: | ||
332 | irq_free_desc(lvq->config.irq); | ||
329 | destroy_vring: | 333 | destroy_vring: |
330 | vring_del_virtqueue(vq); | 334 | vring_del_virtqueue(vq); |
331 | unmap: | 335 | unmap: |