| From: Nicholas Piggin <npiggin@gmail.com> |
| Date: Tue, 15 May 2018 01:59:47 +1000 |
| Subject: powerpc/powernv: Fix NVRAM sleep in invalid context when crashing |
| |
| commit c1d2a31397ec51f0370f6bd17b19b39152c263cb upstream. |
| |
| Similarly to opal_event_shutdown, opal_nvram_write can be called in |
| the crash path with irqs disabled. Special case the delay to avoid |
| sleeping in invalid context. |
| |
| Fixes: 3b8070335f75 ("powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops") |
| Signed-off-by: Nicholas Piggin <npiggin@gmail.com> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| arch/powerpc/platforms/powernv/opal-nvram.c | 14 ++++++++++++-- |
| 1 file changed, 12 insertions(+), 2 deletions(-) |
| |
| --- a/arch/powerpc/platforms/powernv/opal-nvram.c |
| +++ b/arch/powerpc/platforms/powernv/opal-nvram.c |
| @@ -43,6 +43,10 @@ static ssize_t opal_nvram_read(char *buf |
| return count; |
| } |
| |
| +/* |
| + * This can be called in the panic path with interrupts off, so use |
| + * mdelay in that case. |
| + */ |
| static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) |
| { |
| s64 rc = OPAL_BUSY; |
| @@ -57,10 +61,16 @@ static ssize_t opal_nvram_write(char *bu |
| while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
| rc = opal_write_nvram(__pa(buf), count, off); |
| if (rc == OPAL_BUSY_EVENT) { |
| - msleep(OPAL_BUSY_DELAY_MS); |
| + if (in_interrupt() || irqs_disabled()) |
| + mdelay(OPAL_BUSY_DELAY_MS); |
| + else |
| + msleep(OPAL_BUSY_DELAY_MS); |
| opal_poll_events(NULL); |
| } else if (rc == OPAL_BUSY) { |
| - msleep(OPAL_BUSY_DELAY_MS); |
| + if (in_interrupt() || irqs_disabled()) |
| + mdelay(OPAL_BUSY_DELAY_MS); |
| + else |
| + msleep(OPAL_BUSY_DELAY_MS); |
| } |
| } |
| |