Commit b6c96c0214138186f495e3ee73737c6fc5e4efa2

Authored by Stratos Psomadakis
Committed by Rusty Russell
1 parent 07fe9977b6

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)

Showing 2 changed files with 20 additions and 11 deletions Side-by-side Diff

arch/x86/lguest/boot.c
... ... @@ -856,18 +856,23 @@
856 856 }
857 857  
858 858 /*
859   - * With CONFIG_SPARSE_IRQ, interrupt descriptors are allocated as-needed, so
860   - * rather than set them in lguest_init_IRQ we are called here every time an
861   - * lguest device needs an interrupt.
862   - *
863   - * FIXME: irq_alloc_desc_at() can fail due to lack of memory, we should
864   - * pass that up!
  859 + * Interrupt descriptors are allocated as-needed, but low-numbered ones are
  860 + * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it
  861 + * tells us the irq is already used: other errors (ie. ENOMEM) we take
  862 + * seriously.
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 873 irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
870 874 handle_level_irq, "level");
  875 + return 0;
871 876 }
872 877  
873 878 /*
drivers/lguest/lguest_device.c
... ... @@ -241,7 +241,7 @@
241 241 }
242 242  
243 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 247 * This routine finds the Nth virtqueue described in the configuration of
... ... @@ -304,7 +304,9 @@
304 304 }
305 305  
306 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 312 * Tell the interrupt for this virtqueue to go to the virtio_ring
... ... @@ -317,7 +319,7 @@
317 319 err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED,
318 320 dev_name(&vdev->dev), vq);
319 321 if (err)
320   - goto destroy_vring;
  322 + goto free_desc;
321 323  
322 324 /*
323 325 * Last of all we hook up our 'struct lguest_vq_info" to the
... ... @@ -326,6 +328,8 @@
326 328 vq->priv = lvq;
327 329 return vq;
328 330  
  331 +free_desc:
  332 + irq_free_desc(lvq->config.irq);
329 333 destroy_vring:
330 334 vring_del_virtqueue(vq);
331 335 unmap: