Skip to content

Commit

Permalink
Merge branch 'parisc-for-3.10' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/deller/parisc-linux

Pull parisc fixes from Helge Deller:
 "This time we made the kernel- and interruption stack allocation
  reentrant which fixed some strange kernel crashes (specifically
  protection ID traps).

  Furthemore this patchset fixes the interrupt stack in UP and SMP
  configurations by using native locking instructions.  And finally
  usage of floating point calculations on parisc were disabled in the
  MPILIB."

* 'parisc-for-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: fix irq stack on UP and SMP
  parisc/superio: Use module_pci_driver to register driver
  parisc: make interrupt and interruption stack allocation reentrant
  parisc: show number of FPE and unaligned access handler calls in /proc/interrupts
  parisc: add additional parisc git tree to MAINTAINERS file
  parisc: use PAGE_SHIFT instead of hardcoded value 12 in pacache.S
  parisc: add rp5470 entry to machine database
  MPILIB: disable usage of floating point registers on parisc
  • Loading branch information
Linus Torvalds committed May 26, 2013
2 parents 088d812 + d96b51e commit 95f4838
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 71 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -6084,6 +6084,7 @@ L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/
Q: http://patchwork.kernel.org/project/linux-parisc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
S: Maintained
F: arch/parisc/
F: drivers/parisc/
Expand Down
1 change: 0 additions & 1 deletion arch/parisc/include/asm/assembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@
SAVE_SP (%sr4, PT_SR4 (\regs))
SAVE_SP (%sr5, PT_SR5 (\regs))
SAVE_SP (%sr6, PT_SR6 (\regs))
SAVE_SP (%sr7, PT_SR7 (\regs))

SAVE_CR (%cr17, PT_IASQ0(\regs))
mtctl %r0, %cr17
Expand Down
7 changes: 2 additions & 5 deletions arch/parisc/include/asm/hardirq.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@

typedef struct {
unsigned int __softirq_pending;
#ifdef CONFIG_DEBUG_STACKOVERFLOW
unsigned int kernel_stack_usage;
#ifdef CONFIG_IRQSTACKS
unsigned int irq_stack_usage;
unsigned int irq_stack_counter;
#endif
#endif
#ifdef CONFIG_SMP
unsigned int irq_resched_count;
unsigned int irq_call_count;
#endif
unsigned int irq_unaligned_count;
unsigned int irq_fpassist_count;
unsigned int irq_tlb_count;
} ____cacheline_aligned irq_cpustat_t;

Expand Down
21 changes: 0 additions & 21 deletions arch/parisc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <asm/ptrace.h>
#include <asm/types.h>
#include <asm/percpu.h>

#endif /* __ASSEMBLY__ */

/*
Expand Down Expand Up @@ -58,26 +57,6 @@

#ifndef __ASSEMBLY__

/*
* IRQ STACK - used for irq handler
*/
#ifdef __KERNEL__

#include <linux/spinlock_types.h>

#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */

union irq_stack_union {
unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
raw_spinlock_t lock;
};

DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);

void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);

#endif /* __KERNEL__ */

/*
* Data detected about CPUs at boot time which is the same for all CPU's.
* HP boxes are SMP - ie identical processors.
Expand Down
19 changes: 10 additions & 9 deletions arch/parisc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,11 @@
rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */
mtsp %r0, %sr4
mtsp %r0, %sr5
mfsp %sr7, %r1
or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
mtsp %r1, %sr3
mtsp %r0, %sr6
tovirt_r1 %r29
load32 KERNEL_PSW, %r1

rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */
mtsp %r0, %sr6
mtsp %r0, %sr7
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
mtctl %r1, %ipsw
Expand Down Expand Up @@ -119,28 +115,33 @@

/* we save the registers in the task struct */

copy %r30, %r17
mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30
mtsp %r0,%sr7
mtsp %r16,%sr3
tophys %r1,%r9
LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */
tophys %r1,%r9
ldo TASK_REGS(%r9),%r9
STREG %r30, PT_GR30(%r9)
STREG %r17,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9)
STREG %r26,PT_GR26(%r9)
STREG %r16,PT_SR7(%r9)
copy %r9,%r29
mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30
.endm

.macro get_stack_use_r30

/* we put a struct pt_regs on the stack and save the registers there */

tophys %r30,%r9
STREG %r30,PT_GR30(%r9)
copy %r30,%r1
ldo PT_SZ_ALGN(%r30),%r30
STREG %r1,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9)
STREG %r26,PT_GR26(%r9)
STREG %r16,PT_SR7(%r9)
copy %r9,%r29
.endm

Expand Down
1 change: 1 addition & 0 deletions arch/parisc/kernel/hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_list[] = {
{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
{HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
Expand Down
49 changes: 34 additions & 15 deletions arch/parisc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <asm/io.h>

#include <asm/smp.h>
#include <asm/ldcw.h>

#undef PARISC_IRQ_CR16_COUNTS

Expand Down Expand Up @@ -172,10 +172,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
seq_puts(p, " Interrupt stack usage\n");
seq_printf(p, "%*s: ", prec, "ISC");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter);
seq_puts(p, " Interrupt stack usage counter\n");
# endif
#endif
#ifdef CONFIG_SMP
Expand All @@ -188,6 +184,14 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
seq_puts(p, " Function call interrupts\n");
#endif
seq_printf(p, "%*s: ", prec, "UAH");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count);
seq_puts(p, " Unaligned access handler traps\n");
seq_printf(p, "%*s: ", prec, "FPA");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count);
seq_puts(p, " Floating point assist traps\n");
seq_printf(p, "%*s: ", prec, "TLB");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
Expand Down Expand Up @@ -376,6 +380,24 @@ static inline int eirr_to_irq(unsigned long eirr)
return (BITS_PER_LONG - bit) + TIMER_IRQ;
}

#ifdef CONFIG_IRQSTACKS
/*
* IRQ STACK - used for irq handler
*/
#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */

union irq_stack_union {
unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
volatile unsigned int slock[4];
volatile unsigned int lock[1];
};

DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
.slock = { 1,1,1,1 },
};
#endif


int sysctl_panic_on_stackoverflow = 1;

static inline void stack_overflow_check(struct pt_regs *regs)
Expand Down Expand Up @@ -442,27 +464,26 @@ static inline void stack_overflow_check(struct pt_regs *regs)
}

#ifdef CONFIG_IRQSTACKS
DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
.lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock)
};
/* in entry.S: */
void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);

static void execute_on_irq_stack(void *func, unsigned long param1)
{
union irq_stack_union *union_ptr;
unsigned long irq_stack;
raw_spinlock_t *irq_stack_in_use;
volatile unsigned int *irq_stack_in_use;

union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
irq_stack = (unsigned long) &union_ptr->stack;
irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock),
irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
64); /* align for stack frame usage */

/* We may be called recursive. If we are already using the irq stack,
* just continue to use it. Use spinlocks to serialize
* the irq stack usage.
*/
irq_stack_in_use = &union_ptr->lock;
if (!raw_spin_trylock(irq_stack_in_use)) {
irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr);
if (!__ldcw(irq_stack_in_use)) {
void (*direct_call)(unsigned long p1) = func;

/* We are using the IRQ stack already.
Expand All @@ -474,10 +495,8 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
/* This is where we switch to the IRQ stack. */
call_on_stack(param1, func, irq_stack);

__inc_irq_stat(irq_stack_counter);

/* free up irq stack usage. */
do_raw_spin_unlock(irq_stack_in_use);
*irq_stack_in_use = 1;
}

asmlinkage void do_softirq(void)
Expand Down
12 changes: 6 additions & 6 deletions arch/parisc/kernel/pacache.S
Original file line number Diff line number Diff line change
Expand Up @@ -605,14 +605,14 @@ ENTRY(copy_user_page_asm)
convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */
convert_phys_for_tlb_insert20 %r23 /* convert phys addr to tlb insert format */
depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */
depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */
depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */
copy %r28, %r29
depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */
#else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */
depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */
depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
copy %r28, %r29
depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */
#endif
Expand Down Expand Up @@ -762,7 +762,7 @@ ENTRY(clear_user_page_asm)
#else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */
depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
#endif

/* Purge any old translation */
Expand Down Expand Up @@ -846,7 +846,7 @@ ENTRY(flush_dcache_page_asm)
#else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */
depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
#endif

/* Purge any old translation */
Expand Down Expand Up @@ -918,11 +918,11 @@ ENTRY(flush_icache_page_asm)
#endif
convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */
depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */
depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */
#else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */
depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
#endif

/* Purge any old translation */
Expand Down
1 change: 1 addition & 0 deletions arch/parisc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
case 14:
/* Assist Exception Trap, i.e. floating point exception. */
die_if_kernel("Floating point exception", regs, 0); /* quiet */
__inc_irq_stat(irq_fpassist_count);
handle_fpe(regs);
return;

Expand Down
3 changes: 3 additions & 0 deletions arch/parisc/kernel/unaligned.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/signal.h>
#include <linux/ratelimit.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>

/* #define DEBUG_UNALIGNED 1 */

Expand Down Expand Up @@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *regs)
struct siginfo si;
register int flop=0; /* true if this is a flop */

__inc_irq_stat(irq_unaligned_count);

/* log a message with pacing */
if (user_mode(regs)) {
if (current->thread.flags & PARISC_UAC_SIGBUS) {
Expand Down
13 changes: 1 addition & 12 deletions drivers/parisc/superio.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,15 +494,4 @@ static struct pci_driver superio_driver = {
.probe = superio_probe,
};

static int __init superio_modinit(void)
{
return pci_register_driver(&superio_driver);
}

static void __exit superio_exit(void)
{
pci_unregister_driver(&superio_driver);
}

module_init(superio_modinit);
module_exit(superio_exit);
module_pci_driver(superio_driver);
5 changes: 3 additions & 2 deletions lib/mpi/longlong.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,8 @@ extern UDItype __udiv_qrnnd();
"rM" ((USItype)(bh)), \
"rM" ((USItype)(al)), \
"rM" ((USItype)(bl)))
#if defined(_PA_RISC1_1)
#if 0 && defined(_PA_RISC1_1)
/* xmpyu uses floating point register which is not allowed in Linux kernel. */
#define umul_ppmm(wh, wl, u, v) \
do { \
union {UDItype __ll; \
Expand All @@ -337,7 +338,7 @@ do { \
#define UMUL_TIME 40
#define UDIV_TIME 80
#endif
#ifndef LONGLONG_STANDALONE
#if 0 /* #ifndef LONGLONG_STANDALONE */
#define udiv_qrnnd(q, r, n1, n0, d) \
do { USItype __r; \
(q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
Expand Down

0 comments on commit 95f4838

Please sign in to comment.