]>
Commit | Line | Data |
---|---|---|
df00aad9 GKH |
1 | From 8a8187c8fbbd78bd2a2b4b1ad05838d95a4ed91a Mon Sep 17 00:00:00 2001 |
2 | From: David S. Miller <davem@davemloft.net> | |
3 | Date: Wed, 3 Mar 2010 09:06:03 -0800 | |
4 | Subject: sparc64: Make prom entry spinlock NMI safe. | |
5 | ||
6 | From: David S. Miller <davem@davemloft.net> | |
7 | ||
8 | [ Upstream commit 8a4fd1e4922413cfdfa6c51a59efb720d904a5eb ] | |
9 | ||
10 | If we do something like try to print to the OF console from an NMI | |
11 | while we're already in OpenFirmware, we'll deadlock on the spinlock. | |
12 | ||
13 | Use a raw spinlock and disable NMIs when we take it. | |
14 | ||
15 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
16 | Signed-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 | } |