| From 170fce5e2cb1b88e44ca64c6f47bf58f980b99d6 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 15 Feb 2017 11:11:51 +0100 |
| Subject: [PATCH] goldfish: Sanitize the broken interrupt handler |
| |
| commit 6cf18e6927c0b224f972e3042fb85770d63cb9f8 upstream. |
| |
| This interrupt handler is broken in several ways: |
| |
| - It loops forever when the op code is not decodeable |
| |
| - It never returns IRQ_HANDLED because the only way to exit the loop |
| returns IRQ_NONE unconditionally. |
| |
| The whole concept of this is broken. Creating devices in an interrupt |
| handler is beyond any point of sanity. |
| |
| Make it at least behave halfways sane so accidental users do not have to |
| deal with a hard to debug lockup. |
| |
| Fixes: e809c22b8fb028 ("goldfish: add the goldfish virtual bus") |
| Reported-by: Gabriel C <nix.or.die@gmail.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Acked-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/platform/goldfish/pdev_bus.c b/drivers/platform/goldfish/pdev_bus.c |
| index 1f52462f4cdd..dd9ea463c2a4 100644 |
| --- a/drivers/platform/goldfish/pdev_bus.c |
| +++ b/drivers/platform/goldfish/pdev_bus.c |
| @@ -157,23 +157,26 @@ static int goldfish_new_pdev(void) |
| static irqreturn_t goldfish_pdev_bus_interrupt(int irq, void *dev_id) |
| { |
| irqreturn_t ret = IRQ_NONE; |
| + |
| while (1) { |
| u32 op = readl(pdev_bus_base + PDEV_BUS_OP); |
| - switch (op) { |
| - case PDEV_BUS_OP_DONE: |
| - return IRQ_NONE; |
| |
| + switch (op) { |
| case PDEV_BUS_OP_REMOVE_DEV: |
| goldfish_pdev_remove(); |
| + ret = IRQ_HANDLED; |
| break; |
| |
| case PDEV_BUS_OP_ADD_DEV: |
| goldfish_new_pdev(); |
| + ret = IRQ_HANDLED; |
| break; |
| + |
| + case PDEV_BUS_OP_DONE: |
| + default: |
| + return ret; |
| } |
| - ret = IRQ_HANDLED; |
| } |
| - return ret; |
| } |
| |
| static int goldfish_pdev_bus_probe(struct platform_device *pdev) |
| -- |
| 2.12.0 |
| |