aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-03-03 12:06:03 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 19:01:19 -0400
commit6b485cd307ba56876d20b6d443a02f3cc5bbb7a2 (patch)
tree2b158efc315b22ea2212fb71ce8c0405d72a8ab9 /arch
parent38b5c1269e7c1582d25a2ffd71d9289d8520d9b8 (diff)
sparc64: Make prom entry spinlock NMI safe.
[ Upstream commit 8a4fd1e4922413cfdfa6c51a59efb720d904a5eb ] If we do something like try to print to the OF console from an NMI while we're already in OpenFirmware, we'll deadlock on the spinlock. Use a raw spinlock and disable NMIs when we take it. Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/prom/p1275.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c
index 4b7c937bba61..2d8b70d397f1 100644
--- a/arch/sparc/prom/p1275.c
+++ b/arch/sparc/prom/p1275.c
@@ -32,10 +32,9 @@ extern void prom_cif_interface(void);
32extern void prom_cif_callback(void); 32extern void prom_cif_callback(void);
33 33
34/* 34/*
35 * This provides SMP safety on the p1275buf. prom_callback() drops this lock 35 * This provides SMP safety on the p1275buf.
36 * to allow recursuve acquisition.
37 */ 36 */
38DEFINE_SPINLOCK(prom_entry_lock); 37DEFINE_RAW_SPINLOCK(prom_entry_lock);
39 38
40long p1275_cmd(const char *service, long fmt, ...) 39long p1275_cmd(const char *service, long fmt, ...)
41{ 40{
@@ -47,7 +46,9 @@ long p1275_cmd(const char *service, long fmt, ...)
47 46
48 p = p1275buf.prom_buffer; 47 p = p1275buf.prom_buffer;
49 48
50 spin_lock_irqsave(&prom_entry_lock, flags); 49 raw_local_save_flags(flags);
50 raw_local_irq_restore(PIL_NMI);
51 raw_spin_lock(&prom_entry_lock);
51 52
52 p1275buf.prom_args[0] = (unsigned long)p; /* service */ 53 p1275buf.prom_args[0] = (unsigned long)p; /* service */
53 strcpy (p, service); 54 strcpy (p, service);
@@ -139,7 +140,8 @@ long p1275_cmd(const char *service, long fmt, ...)
139 va_end(list); 140 va_end(list);
140 x = p1275buf.prom_args [nargs + 3]; 141 x = p1275buf.prom_args [nargs + 3];
141 142
142 spin_unlock_irqrestore(&prom_entry_lock, flags); 143 raw_spin_unlock(&prom_entry_lock);
144 raw_local_irq_restore(flags);
143 145
144 return x; 146 return x;
145} 147}