Merge branch 'parisc-for-3.10' of git://git.kernel.org/pub/scm/linux/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
This commit is contained in:
Коммит
95f4838e21
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <asm/ptrace.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/percpu.h>
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
@ -119,17 +115,20 @@
|
|||
|
||||
/* 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
|
||||
|
@ -137,10 +136,12 @@
|
|||
/* 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
|
||||
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -442,27 +464,26 @@ panic_check:
|
|||
}
|
||||
|
||||
#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.
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/signal.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
/* #define DEBUG_UNALIGNED 1 */
|
||||
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; \
|
||||
|
@ -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)); \
|
||||
|
|
Загрузка…
Ссылка в новой задаче