]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.33.2/sparc64-make-prom-entry-spinlock-nmi-safe.patch
5.0-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.33.2 / sparc64-make-prom-entry-spinlock-nmi-safe.patch
CommitLineData
df00aad9
GKH
1From 8a8187c8fbbd78bd2a2b4b1ad05838d95a4ed91a Mon Sep 17 00:00:00 2001
2From: David S. Miller <davem@davemloft.net>
3Date: Wed, 3 Mar 2010 09:06:03 -0800
4Subject: sparc64: Make prom entry spinlock NMI safe.
5
6From: David S. Miller <davem@davemloft.net>
7
8[ Upstream commit 8a4fd1e4922413cfdfa6c51a59efb720d904a5eb ]
9
10If we do something like try to print to the OF console from an NMI
11while we're already in OpenFirmware, we'll deadlock on the spinlock.
12
13Use a raw spinlock and disable NMIs when we take it.
14
15Signed-off-by: David S. Miller <davem@davemloft.net>
16Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
17
18---
19 arch/sparc/prom/p1275.c | 12 +++++++-----
20 1 file changed, 7 insertions(+), 5 deletions(-)
21
22--- a/arch/sparc/prom/p1275.c
23+++ b/arch/sparc/prom/p1275.c
24@@ -32,10 +32,9 @@ extern void prom_cif_interface(void);
25 extern void prom_cif_callback(void);
26
27 /*
28- * This provides SMP safety on the p1275buf. prom_callback() drops this lock
29- * to allow recursuve acquisition.
30+ * This provides SMP safety on the p1275buf.
31 */
32-DEFINE_SPINLOCK(prom_entry_lock);
33+DEFINE_RAW_SPINLOCK(prom_entry_lock);
34
35 long p1275_cmd(const char *service, long fmt, ...)
36 {
37@@ -47,7 +46,9 @@ long p1275_cmd(const char *service, long
38
39 p = p1275buf.prom_buffer;
40
41- spin_lock_irqsave(&prom_entry_lock, flags);
42+ raw_local_save_flags(flags);
43+ raw_local_irq_restore(PIL_NMI);
44+ raw_spin_lock(&prom_entry_lock);
45
46 p1275buf.prom_args[0] = (unsigned long)p; /* service */
47 strcpy (p, service);
48@@ -139,7 +140,8 @@ long p1275_cmd(const char *service, long
49 va_end(list);
50 x = p1275buf.prom_args [nargs + 3];
51
52- spin_unlock_irqrestore(&prom_entry_lock, flags);
53+ raw_spin_unlock(&prom_entry_lock);
54+ raw_local_irq_restore(flags);
55
56 return x;
57 }