Skip to content

Commit 435e46f

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller: 1) Fix NULL oops in Schizo PCI controller error handler. 2) Fix race between xchg and other operations on 32-bit sparc, from Andreas Larsson. 3) swab*() helpers need a dummy memory input operand to show data flow on 64-bit sparc. 4) Fix RCU warnings due to missing irq_{enter,exit}() around generic_smp_call_function*() calls. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: sparc64: Fix constraints on swab helpers. sparc32: Implement xchg and atomic_xchg using ATOMIC_HASH locks sparc64: Do irq_{enter,exit}() around generic_smp_call_function*(). sparc64: Fix crashes in schizo_pcierr_intr_other().
2 parents 0fbae13 + 5a2b59d commit 435e46f

File tree

6 files changed

+43
-20
lines changed

6 files changed

+43
-20
lines changed

arch/sparc/include/asm/atomic_32.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
int atomic_add_return(int, atomic_t *);
2424
int atomic_cmpxchg(atomic_t *, int, int);
25-
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
25+
int atomic_xchg(atomic_t *, int);
2626
int __atomic_add_unless(atomic_t *, int, int);
2727
void atomic_set(atomic_t *, int);
2828

arch/sparc/include/asm/cmpxchg_32.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,14 @@
1111
#ifndef __ARCH_SPARC_CMPXCHG__
1212
#define __ARCH_SPARC_CMPXCHG__
1313

14-
static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
15-
{
16-
__asm__ __volatile__("swap [%2], %0"
17-
: "=&r" (val)
18-
: "0" (val), "r" (m)
19-
: "memory");
20-
return val;
21-
}
22-
14+
unsigned long __xchg_u32(volatile u32 *m, u32 new);
2315
void __xchg_called_with_bad_pointer(void);
2416

2517
static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
2618
{
2719
switch (size) {
2820
case 4:
29-
return xchg_u32(ptr, x);
21+
return __xchg_u32(ptr, x);
3022
}
3123
__xchg_called_with_bad_pointer();
3224
return x;

arch/sparc/include/uapi/asm/swab.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ static inline __u16 __arch_swab16p(const __u16 *addr)
99
{
1010
__u16 ret;
1111

12-
__asm__ __volatile__ ("lduha [%1] %2, %0"
12+
__asm__ __volatile__ ("lduha [%2] %3, %0"
1313
: "=r" (ret)
14-
: "r" (addr), "i" (ASI_PL));
14+
: "m" (*addr), "r" (addr), "i" (ASI_PL));
1515
return ret;
1616
}
1717
#define __arch_swab16p __arch_swab16p
@@ -20,9 +20,9 @@ static inline __u32 __arch_swab32p(const __u32 *addr)
2020
{
2121
__u32 ret;
2222

23-
__asm__ __volatile__ ("lduwa [%1] %2, %0"
23+
__asm__ __volatile__ ("lduwa [%2] %3, %0"
2424
: "=r" (ret)
25-
: "r" (addr), "i" (ASI_PL));
25+
: "m" (*addr), "r" (addr), "i" (ASI_PL));
2626
return ret;
2727
}
2828
#define __arch_swab32p __arch_swab32p
@@ -31,9 +31,9 @@ static inline __u64 __arch_swab64p(const __u64 *addr)
3131
{
3232
__u64 ret;
3333

34-
__asm__ __volatile__ ("ldxa [%1] %2, %0"
34+
__asm__ __volatile__ ("ldxa [%2] %3, %0"
3535
: "=r" (ret)
36-
: "r" (addr), "i" (ASI_PL));
36+
: "m" (*addr), "r" (addr), "i" (ASI_PL));
3737
return ret;
3838
}
3939
#define __arch_swab64p __arch_swab64p

arch/sparc/kernel/pci_schizo.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
581581
{
582582
unsigned long csr_reg, csr, csr_error_bits;
583583
irqreturn_t ret = IRQ_NONE;
584-
u16 stat;
584+
u32 stat;
585585

586586
csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
587587
csr = upa_readq(csr_reg);
@@ -617,15 +617,15 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
617617
pbm->name);
618618
ret = IRQ_HANDLED;
619619
}
620-
pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
620+
pbm->pci_ops->read(pbm->pci_bus, 0, PCI_STATUS, 2, &stat);
621621
if (stat & (PCI_STATUS_PARITY |
622622
PCI_STATUS_SIG_TARGET_ABORT |
623623
PCI_STATUS_REC_TARGET_ABORT |
624624
PCI_STATUS_REC_MASTER_ABORT |
625625
PCI_STATUS_SIG_SYSTEM_ERROR)) {
626626
printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
627627
pbm->name, stat);
628-
pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
628+
pbm->pci_ops->write(pbm->pci_bus, 0, PCI_STATUS, 2, 0xffff);
629629
ret = IRQ_HANDLED;
630630
}
631631
return ret;

arch/sparc/kernel/smp_64.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,13 +816,17 @@ void arch_send_call_function_single_ipi(int cpu)
816816
void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
817817
{
818818
clear_softint(1 << irq);
819+
irq_enter();
819820
generic_smp_call_function_interrupt();
821+
irq_exit();
820822
}
821823

822824
void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
823825
{
824826
clear_softint(1 << irq);
827+
irq_enter();
825828
generic_smp_call_function_single_interrupt();
829+
irq_exit();
826830
}
827831

828832
static void tsb_sync(void *info)

arch/sparc/lib/atomic32.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ ATOMIC_OP(add, +=)
4545

4646
#undef ATOMIC_OP
4747

48+
int atomic_xchg(atomic_t *v, int new)
49+
{
50+
int ret;
51+
unsigned long flags;
52+
53+
spin_lock_irqsave(ATOMIC_HASH(v), flags);
54+
ret = v->counter;
55+
v->counter = new;
56+
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
57+
return ret;
58+
}
59+
EXPORT_SYMBOL(atomic_xchg);
60+
4861
int atomic_cmpxchg(atomic_t *v, int old, int new)
4962
{
5063
int ret;
@@ -137,3 +150,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
137150
return (unsigned long)prev;
138151
}
139152
EXPORT_SYMBOL(__cmpxchg_u32);
153+
154+
unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
155+
{
156+
unsigned long flags;
157+
u32 prev;
158+
159+
spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
160+
prev = *ptr;
161+
*ptr = new;
162+
spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
163+
164+
return (unsigned long)prev;
165+
}
166+
EXPORT_SYMBOL(__xchg_u32);

0 commit comments

Comments
 (0)