Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6: sparc64: Do not clobber %g7 in setcontext() trap. sparc64: Kill __show_regs(). sparc: Add __KERNEL__ ifdef protection to pt_regs helpers. sparc64: Kill smp_report_regs(). sparc64: Kill VERBOSE_SHOWREGS code. sparc64: Hook up trigger_all_cpu_backtrace(). sparc64: Make global reg dumping even more useful. sparc: Ignore drivers/video/console/promcon_tbl.c conmakehash generated file sparc64: FUTEX_OP_ANDN fix sparc: merge of_platform_{32,64}.h sparc64: Kill isa_bus_type. sparc64: Fix global reg snapshotting on self-cpu.
This commit is contained in:
Коммит
d9c566198b
|
@ -59,7 +59,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
|||
__futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
__futex_cas_op("andn\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
|
|
|
@ -90,4 +90,7 @@ static inline unsigned long get_softint(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
void __trigger_all_cpu_backtrace(void);
|
||||
#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace()
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
#ifndef ___ASM_SPARC_OF_PLATFORM_H
|
||||
#define ___ASM_SPARC_OF_PLATFORM_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/of_platform_64.h>
|
||||
#else
|
||||
#include <asm/of_platform_32.h>
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef _ASM_SPARC_OF_PLATFORM_H
|
||||
#define _ASM_SPARC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif /* _ASM_SPARC_OF_PLATFORM_H */
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef _ASM_SPARC64_OF_PLATFORM_H
|
||||
#define _ASM_SPARC64_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type isa_bus_type;
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif /* _ASM_SPARC64_OF_PLATFORM_H */
|
|
@ -40,16 +40,6 @@ struct pt_regs {
|
|||
#define UREG_FP UREG_I6
|
||||
#define UREG_RETPC UREG_I7
|
||||
|
||||
static inline bool pt_regs_is_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->psr & PSR_SYSCALL);
|
||||
}
|
||||
|
||||
static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->psr &= ~PSR_SYSCALL);
|
||||
}
|
||||
|
||||
/* A register window */
|
||||
struct reg_window {
|
||||
unsigned long locals[8];
|
||||
|
@ -72,6 +62,16 @@ struct sparc_stackf {
|
|||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
static inline bool pt_regs_is_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->psr & PSR_SYSCALL);
|
||||
}
|
||||
|
||||
static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->psr &= ~PSR_SYSCALL);
|
||||
}
|
||||
|
||||
#define user_mode(regs) (!((regs)->psr & PSR_PS))
|
||||
#define instruction_pointer(regs) ((regs)->pc)
|
||||
#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
|
||||
|
|
|
@ -37,21 +37,6 @@ struct pt_regs {
|
|||
unsigned int magic;
|
||||
};
|
||||
|
||||
static inline int pt_regs_trap_type(struct pt_regs *regs)
|
||||
{
|
||||
return regs->magic & 0x1ff;
|
||||
}
|
||||
|
||||
static inline bool pt_regs_is_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->tstate & TSTATE_SYSCALL);
|
||||
}
|
||||
|
||||
static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->tstate &= ~TSTATE_SYSCALL);
|
||||
}
|
||||
|
||||
struct pt_regs32 {
|
||||
unsigned int psr;
|
||||
unsigned int pc;
|
||||
|
@ -128,15 +113,30 @@ struct sparc_trapf {
|
|||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
static inline int pt_regs_trap_type(struct pt_regs *regs)
|
||||
{
|
||||
return regs->magic & 0x1ff;
|
||||
}
|
||||
|
||||
static inline bool pt_regs_is_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->tstate & TSTATE_SYSCALL);
|
||||
}
|
||||
|
||||
static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->tstate &= ~TSTATE_SYSCALL);
|
||||
}
|
||||
|
||||
struct global_reg_snapshot {
|
||||
unsigned long tstate;
|
||||
unsigned long tpc;
|
||||
unsigned long tnpc;
|
||||
unsigned long o7;
|
||||
unsigned long i7;
|
||||
unsigned long rpc;
|
||||
struct thread_info *thread;
|
||||
unsigned long pad1;
|
||||
unsigned long pad2;
|
||||
};
|
||||
|
||||
#define __ARCH_WANT_COMPAT_SYS_PTRACE
|
||||
|
@ -154,7 +154,6 @@ extern unsigned long profile_pc(struct pt_regs *);
|
|||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
#endif
|
||||
extern void show_regs(struct pt_regs *);
|
||||
extern void __show_regs(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
@ -315,9 +314,9 @@ extern void __show_regs(struct pt_regs *);
|
|||
#define GR_SNAP_TNPC 0x10
|
||||
#define GR_SNAP_O7 0x18
|
||||
#define GR_SNAP_I7 0x20
|
||||
#define GR_SNAP_THREAD 0x28
|
||||
#define GR_SNAP_PAD1 0x30
|
||||
#define GR_SNAP_PAD2 0x38
|
||||
#define GR_SNAP_RPC 0x28
|
||||
#define GR_SNAP_THREAD 0x30
|
||||
#define GR_SNAP_PAD1 0x38
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -56,9 +56,6 @@ struct of_device *of_find_device_by_node(struct device_node *dp)
|
|||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct bus_type isa_bus_type;
|
||||
EXPORT_SYMBOL(isa_bus_type);
|
||||
|
||||
struct bus_type ebus_bus_type;
|
||||
EXPORT_SYMBOL(ebus_bus_type);
|
||||
#endif
|
||||
|
@ -841,8 +838,6 @@ static int __init of_bus_driver_init(void)
|
|||
|
||||
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||
#ifdef CONFIG_PCI
|
||||
if (!err)
|
||||
err = of_bus_type_init(&isa_bus_type, "isa");
|
||||
if (!err)
|
||||
err = of_bus_type_init(&ebus_bus_type, "ebus");
|
||||
#endif
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
#include <asm/irq_regs.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
/* #define VERBOSE_SHOWREGS */
|
||||
|
||||
static void sparc64_yield(int cpu)
|
||||
{
|
||||
if (tlb_type != hypervisor)
|
||||
|
@ -213,22 +211,8 @@ static void show_regwindow(struct pt_regs *regs)
|
|||
printk("I7: <%pS>\n", (void *) rwk->ins[7]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static DEFINE_SPINLOCK(regdump_lock);
|
||||
#endif
|
||||
|
||||
void __show_regs(struct pt_regs * regs)
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long flags;
|
||||
|
||||
/* Protect against xcall ipis which might lead to livelock on the lock */
|
||||
__asm__ __volatile__("rdpr %%pstate, %0\n\t"
|
||||
"wrpr %0, %1, %%pstate"
|
||||
: "=r" (flags)
|
||||
: "i" (PSTATE_IE));
|
||||
spin_lock(®dump_lock);
|
||||
#endif
|
||||
printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate,
|
||||
regs->tpc, regs->tnpc, regs->y, print_tainted());
|
||||
printk("TPC: <%pS>\n", (void *) regs->tpc);
|
||||
|
@ -246,64 +230,24 @@ void __show_regs(struct pt_regs * regs)
|
|||
regs->u_regs[15]);
|
||||
printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
|
||||
show_regwindow(regs);
|
||||
#ifdef CONFIG_SMP
|
||||
spin_unlock(®dump_lock);
|
||||
__asm__ __volatile__("wrpr %0, 0, %%pstate"
|
||||
: : "r" (flags));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VERBOSE_SHOWREGS
|
||||
static void idump_from_user (unsigned int *pc)
|
||||
{
|
||||
int i;
|
||||
int code;
|
||||
|
||||
if((((unsigned long) pc) & 3))
|
||||
return;
|
||||
|
||||
pc -= 3;
|
||||
for(i = -3; i < 6; i++) {
|
||||
get_user(code, pc);
|
||||
printk("%c%08x%c",i?' ':'<',code,i?' ':'>');
|
||||
pc++;
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef VERBOSE_SHOWREGS
|
||||
extern long etrap, etraptl1;
|
||||
#endif
|
||||
__show_regs(regs);
|
||||
#if 0
|
||||
#ifdef CONFIG_SMP
|
||||
{
|
||||
extern void smp_report_regs(void);
|
||||
|
||||
smp_report_regs();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VERBOSE_SHOWREGS
|
||||
if (regs->tpc >= &etrap && regs->tpc < &etraptl1 &&
|
||||
regs->u_regs[14] >= (long)current - PAGE_SIZE &&
|
||||
regs->u_regs[14] < (long)current + 6 * PAGE_SIZE) {
|
||||
printk ("*********parent**********\n");
|
||||
__show_regs((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF));
|
||||
idump_from_user(((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF))->tpc);
|
||||
printk ("*********endpar**********\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
|
||||
static DEFINE_SPINLOCK(global_reg_snapshot_lock);
|
||||
|
||||
static bool kstack_valid(struct thread_info *tp, struct reg_window *rw)
|
||||
{
|
||||
unsigned long thread_base, fp;
|
||||
|
||||
thread_base = (unsigned long) tp;
|
||||
fp = (unsigned long) rw;
|
||||
|
||||
if (fp < (thread_base + sizeof(struct thread_info)) ||
|
||||
fp >= (thread_base + THREAD_SIZE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
|
||||
int this_cpu)
|
||||
{
|
||||
|
@ -315,14 +259,22 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
|
|||
global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7];
|
||||
|
||||
if (regs->tstate & TSTATE_PRIV) {
|
||||
struct thread_info *tp = current_thread_info();
|
||||
struct reg_window *rw;
|
||||
|
||||
rw = (struct reg_window *)
|
||||
(regs->u_regs[UREG_FP] + STACK_BIAS);
|
||||
global_reg_snapshot[this_cpu].i7 = rw->ins[6];
|
||||
} else
|
||||
if (kstack_valid(tp, rw)) {
|
||||
global_reg_snapshot[this_cpu].i7 = rw->ins[7];
|
||||
rw = (struct reg_window *)
|
||||
(rw->ins[6] + STACK_BIAS);
|
||||
if (kstack_valid(tp, rw))
|
||||
global_reg_snapshot[this_cpu].rpc = rw->ins[7];
|
||||
}
|
||||
} else {
|
||||
global_reg_snapshot[this_cpu].i7 = 0;
|
||||
|
||||
global_reg_snapshot[this_cpu].rpc = 0;
|
||||
}
|
||||
global_reg_snapshot[this_cpu].thread = tp;
|
||||
}
|
||||
|
||||
|
@ -341,7 +293,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp)
|
|||
}
|
||||
}
|
||||
|
||||
static void sysrq_handle_globreg(int key, struct tty_struct *tty)
|
||||
void __trigger_all_cpu_backtrace(void)
|
||||
{
|
||||
struct thread_info *tp = current_thread_info();
|
||||
struct pt_regs *regs = get_irq_regs();
|
||||
|
@ -375,13 +327,14 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
|
|||
((tp && tp->task) ? tp->task->pid : -1));
|
||||
|
||||
if (gp->tstate & TSTATE_PRIV) {
|
||||
printk(" TPC[%pS] O7[%pS] I7[%pS]\n",
|
||||
printk(" TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n",
|
||||
(void *) gp->tpc,
|
||||
(void *) gp->o7,
|
||||
(void *) gp->i7);
|
||||
(void *) gp->i7,
|
||||
(void *) gp->rpc);
|
||||
} else {
|
||||
printk(" TPC[%lx] O7[%lx] I7[%lx]\n",
|
||||
gp->tpc, gp->o7, gp->i7);
|
||||
printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
|
||||
gp->tpc, gp->o7, gp->i7, gp->rpc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,6 +343,13 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
|
|||
spin_unlock_irqrestore(&global_reg_snapshot_lock, flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
|
||||
static void sysrq_handle_globreg(int key, struct tty_struct *tty)
|
||||
{
|
||||
__trigger_all_cpu_backtrace();
|
||||
}
|
||||
|
||||
static struct sysrq_key_op sparc_globalreg_op = {
|
||||
.handler = sysrq_handle_globreg,
|
||||
.help_msg = "Globalregs",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* arch/sparc64/kernel/signal.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
|
||||
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
|
@ -91,7 +91,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
|
|||
err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
|
||||
err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
|
||||
err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
|
||||
err |= __get_user(regs->u_regs[UREG_G7], (&(*grp)[MC_G7]));
|
||||
|
||||
/* Skip %g7 as that's the thread register in userspace. */
|
||||
|
||||
err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
|
||||
err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
|
||||
err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
|
||||
|
|
|
@ -843,7 +843,6 @@ void smp_tsb_sync(struct mm_struct *mm)
|
|||
extern unsigned long xcall_flush_tlb_mm;
|
||||
extern unsigned long xcall_flush_tlb_pending;
|
||||
extern unsigned long xcall_flush_tlb_kernel_range;
|
||||
extern unsigned long xcall_report_regs;
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
extern unsigned long xcall_fetch_glob_regs;
|
||||
#endif
|
||||
|
@ -1022,11 +1021,6 @@ void kgdb_roundup_cpus(unsigned long flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
void smp_report_regs(void)
|
||||
{
|
||||
smp_cross_call(&xcall_report_regs, 0, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
void smp_fetch_global_regs(void)
|
||||
{
|
||||
|
|
|
@ -68,7 +68,6 @@ extern void *__memscan_zero(void *, size_t);
|
|||
extern void *__memscan_generic(void *, int, size_t);
|
||||
extern int __memcmp(const void *, const void *, __kernel_size_t);
|
||||
extern __kernel_size_t strlen(const char *);
|
||||
extern void show_regs(struct pt_regs *);
|
||||
extern void syscall_trace(struct pt_regs *, int);
|
||||
extern void sys_sigsuspend(void);
|
||||
extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
|
||||
|
|
|
@ -1777,7 +1777,7 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent,
|
|||
pfx,
|
||||
ent->err_raddr, ent->err_size, ent->err_cpu);
|
||||
|
||||
__show_regs(regs);
|
||||
show_regs(regs);
|
||||
|
||||
if ((cnt = atomic_read(ocnt)) != 0) {
|
||||
atomic_set(ocnt, 0);
|
||||
|
@ -2177,7 +2177,6 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
|
|||
void die_if_kernel(char *str, struct pt_regs *regs)
|
||||
{
|
||||
static int die_counter;
|
||||
extern void smp_report_regs(void);
|
||||
int count = 0;
|
||||
|
||||
/* Amuse the user. */
|
||||
|
@ -2190,7 +2189,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
|
||||
notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
|
||||
__asm__ __volatile__("flushw");
|
||||
__show_regs(regs);
|
||||
show_regs(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
if (regs->tstate & TSTATE_PRIV) {
|
||||
struct reg_window *rw = (struct reg_window *)
|
||||
|
@ -2215,11 +2214,6 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
}
|
||||
user_instruction_dump ((unsigned int __user *) regs->tpc);
|
||||
}
|
||||
#if 0
|
||||
#ifdef CONFIG_SMP
|
||||
smp_report_regs();
|
||||
#endif
|
||||
#endif
|
||||
if (regs->tstate & TSTATE_PRIV)
|
||||
do_exit(SIGKILL);
|
||||
do_exit(SIGSEGV);
|
||||
|
|
|
@ -480,41 +480,6 @@ xcall_sync_tick:
|
|||
b rtrap_xcall
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
|
||||
|
||||
/* NOTE: This is SPECIAL!! We do etrap/rtrap however
|
||||
* we choose to deal with the "BH's run with
|
||||
* %pil==15" problem (described in asm/pil.h)
|
||||
* by just invoking rtrap directly past where
|
||||
* BH's are checked for.
|
||||
*
|
||||
* We do it like this because we do not want %pil==15
|
||||
* lockups to prevent regs being reported.
|
||||
*/
|
||||
.globl xcall_report_regs
|
||||
xcall_report_regs:
|
||||
|
||||
661: rdpr %pstate, %g2
|
||||
wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
|
||||
.section .sun4v_2insn_patch, "ax"
|
||||
.word 661b
|
||||
nop
|
||||
nop
|
||||
.previous
|
||||
|
||||
rdpr %pil, %g2
|
||||
wrpr %g0, 15, %pil
|
||||
sethi %hi(109f), %g7
|
||||
b,pt %xcc, etrap_irq
|
||||
109: or %g7, %lo(109b), %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
call __show_regs
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
/* Has to be a non-v9 branch due to the large distance. */
|
||||
b rtrap_xcall
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
.globl xcall_fetch_glob_regs
|
||||
xcall_fetch_glob_regs:
|
||||
|
@ -531,6 +496,13 @@ xcall_fetch_glob_regs:
|
|||
stx %g7, [%g1 + GR_SNAP_TNPC]
|
||||
stx %o7, [%g1 + GR_SNAP_O7]
|
||||
stx %i7, [%g1 + GR_SNAP_I7]
|
||||
/* Don't try this at home kids... */
|
||||
rdpr %cwp, %g2
|
||||
sub %g2, 1, %g7
|
||||
wrpr %g7, %cwp
|
||||
mov %i7, %g7
|
||||
wrpr %g2, %cwp
|
||||
stx %g7, [%g1 + GR_SNAP_RPC]
|
||||
sethi %hi(trap_block), %g7
|
||||
or %g7, %lo(trap_block), %g7
|
||||
sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# conmakehash generated file
|
||||
promcon_tbl.c
|
Загрузка…
Ссылка в новой задаче