aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-03-03 12:06:03 -0500
committerDavid S. Miller <davem@davemloft.net>2010-03-03 12:06:03 -0500
commit8a4fd1e4922413cfdfa6c51a59efb720d904a5eb (patch)
tree3e46821fac9d3de604466b55345c2b267d157355
parentc7d5a0050773e98d1094eaa9f2a1a793fafac300 (diff)
sparc64: Make prom entry spinlock NMI safe.
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>
-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}