Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: Fix several kprobes bugs. [SPARC64]: Update defconfig. [SPARC64]: dma remove extra brackets [SPARC{32,64}]: Propagate ptrace_traceme() return value. [SPARC64]: Replace kmalloc+memset with kzalloc [SPARC]: Check kzalloc() return value in SUN4D irq/iommu init. [SPARC]: Replace kmalloc+memset with kzalloc [SPARC64]: Run ctrl-alt-del action for sun4v powerdown request. [SPARC64]: Unaligned accesses to userspace are hard errors. [SPARC64]: Call do_mathemu on illegal instruction traps too. [SPARC64]: Update defconfig. [SPARC64]: Add irqtrace/stacktrace/lockdep support.
This commit is contained in:
commit
edb16bec41
|
@ -317,9 +317,8 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
|
|||
if ((va = __get_free_pages(GFP_KERNEL|__GFP_COMP, order)) == 0)
|
||||
goto err_nopages;
|
||||
|
||||
if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL)
|
||||
if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL)
|
||||
goto err_nomem;
|
||||
memset((char*)res, 0, sizeof(struct resource));
|
||||
|
||||
if (allocate_resource(&_sparc_dvma, res, len_total,
|
||||
_sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
|
||||
|
@ -589,12 +588,11 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
|
||||
if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
|
||||
free_pages(va, order);
|
||||
printk("pci_alloc_consistent: no core\n");
|
||||
return NULL;
|
||||
}
|
||||
memset((char*)res, 0, sizeof(struct resource));
|
||||
|
||||
if (allocate_resource(&_sparc_dvma, res, len_total,
|
||||
_sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
|
||||
|
|
|
@ -793,10 +793,9 @@ struct of_device* of_platform_device_create(struct device_node *np,
|
|||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.bus = bus;
|
||||
|
|
|
@ -289,7 +289,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
|
|||
|
||||
if (request == PTRACE_TRACEME) {
|
||||
ret = ptrace_traceme();
|
||||
pt_succ_return(regs, 0);
|
||||
if (ret < 0)
|
||||
pt_error_return(regs, -ret);
|
||||
else
|
||||
pt_succ_return(regs, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -545,8 +545,11 @@ void __init sun4d_init_sbi_irq(void)
|
|||
nsbi = 0;
|
||||
for_each_sbus(sbus)
|
||||
nsbi++;
|
||||
sbus_actions = (struct sbus_action *)kmalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
|
||||
memset (sbus_actions, 0, (nsbi * 8 * 4 * sizeof(struct sbus_action)));
|
||||
sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
|
||||
if (!sbus_actions) {
|
||||
prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");
|
||||
prom_halt();
|
||||
}
|
||||
for_each_sbus(sbus) {
|
||||
#ifdef CONFIG_SMP
|
||||
extern unsigned char boot_cpu_id;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/oplib.h>
|
||||
|
||||
/* #define IOUNIT_DEBUG */
|
||||
#ifdef IOUNIT_DEBUG
|
||||
|
@ -41,9 +42,12 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
|
|||
struct linux_prom_registers iommu_promregs[PROMREG_MAX];
|
||||
struct resource r;
|
||||
|
||||
iounit = kmalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
|
||||
iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
|
||||
if (!iounit) {
|
||||
prom_printf("SUN4D: Cannot alloc iounit, halting.\n");
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
memset(iounit, 0, sizeof(*iounit));
|
||||
iounit->limit[0] = IOUNIT_BMAP1_START;
|
||||
iounit->limit[1] = IOUNIT_BMAP2_START;
|
||||
iounit->limit[2] = IOUNIT_BMAPM_START;
|
||||
|
|
|
@ -26,6 +26,14 @@ config MMU
|
|||
bool
|
||||
default y
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config TIME_INTERPOLATION
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
menu "Kernel hacking"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config DEBUG_STACK_USAGE
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc2
|
||||
# Tue Oct 17 19:29:20 2006
|
||||
# Linux kernel version: 2.6.19
|
||||
# Sat Dec 9 15:41:30 2006
|
||||
#
|
||||
CONFIG_SPARC=y
|
||||
CONFIG_SPARC64=y
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_STACKTRACE_SUPPORT=y
|
||||
CONFIG_LOCKDEP_SUPPORT=y
|
||||
CONFIG_TIME_INTERPOLATION=y
|
||||
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
|
||||
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
|
||||
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
|
||||
CONFIG_AUDIT_ARCH=y
|
||||
CONFIG_SPARC64_PAGE_SIZE_8KB=y
|
||||
# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
|
||||
# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
|
||||
# CONFIG_SPARC64_PAGE_SIZE_4MB is not set
|
||||
CONFIG_SECCOMP=y
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_HZ_250 is not set
|
||||
# CONFIG_HZ_300 is not set
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=250
|
||||
CONFIG_HZ=100
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
|
@ -42,13 +47,14 @@ CONFIG_POSIX_MQUEUE=y
|
|||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_SYSCTL=y
|
||||
# CONFIG_EMBEDDED is not set
|
||||
CONFIG_UID16=y
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
CONFIG_SYSCTL_SYSCALL=y
|
||||
CONFIG_KALLSYMS=y
|
||||
# CONFIG_KALLSYMS_ALL is not set
|
||||
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||
|
@ -203,6 +209,7 @@ CONFIG_INET_TCP_DIAG=y
|
|||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_CUBIC=y
|
||||
CONFIG_DEFAULT_TCP_CONG="cubic"
|
||||
# CONFIG_TCP_MD5SIG is not set
|
||||
CONFIG_IPV6=m
|
||||
CONFIG_IPV6_PRIVACY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
|
@ -219,7 +226,6 @@ CONFIG_INET6_XFRM_MODE_BEET=m
|
|||
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
# CONFIG_IPV6_SUBTREES is not set
|
||||
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
@ -238,6 +244,8 @@ CONFIG_IP_DCCP_CCID2=m
|
|||
# CONFIG_IP_DCCP_CCID2_DEBUG is not set
|
||||
CONFIG_IP_DCCP_CCID3=m
|
||||
CONFIG_IP_DCCP_TFRC_LIB=m
|
||||
# CONFIG_IP_DCCP_CCID3_DEBUG is not set
|
||||
CONFIG_IP_DCCP_CCID3_RTO=100
|
||||
|
||||
#
|
||||
# DCCP Kernel Hacking
|
||||
|
@ -405,6 +413,7 @@ CONFIG_IDEDMA_AUTO=y
|
|||
#
|
||||
CONFIG_RAID_ATTRS=m
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_TGT is not set
|
||||
CONFIG_SCSI_NETLINK=y
|
||||
CONFIG_SCSI_PROC_FS=y
|
||||
|
||||
|
@ -425,6 +434,7 @@ CONFIG_CHR_DEV_SG=m
|
|||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
# CONFIG_SCSI_LOGGING is not set
|
||||
# CONFIG_SCSI_SCAN_ASYNC is not set
|
||||
|
||||
#
|
||||
# SCSI Transports
|
||||
|
@ -468,6 +478,7 @@ CONFIG_ISCSI_TCP=m
|
|||
# CONFIG_SCSI_DC390T is not set
|
||||
# CONFIG_SCSI_DEBUG is not set
|
||||
# CONFIG_SCSI_SUNESP is not set
|
||||
# CONFIG_SCSI_SRP is not set
|
||||
|
||||
#
|
||||
# Serial ATA (prod) and Parallel ATA (experimental) drivers
|
||||
|
@ -598,6 +609,7 @@ CONFIG_BNX2=m
|
|||
# CONFIG_IXGB is not set
|
||||
# CONFIG_S2IO is not set
|
||||
# CONFIG_MYRI10GE is not set
|
||||
# CONFIG_NETXEN_NIC is not set
|
||||
|
||||
#
|
||||
# Token Ring devices
|
||||
|
@ -724,10 +736,6 @@ CONFIG_RTC=y
|
|||
# CONFIG_DTLK is not set
|
||||
# CONFIG_R3964 is not set
|
||||
# CONFIG_APPLICOM is not set
|
||||
|
||||
#
|
||||
# Ftape, the floppy tape device driver
|
||||
#
|
||||
# CONFIG_DRM is not set
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
|
||||
|
@ -1038,6 +1046,11 @@ CONFIG_SND_SUN_CS4231=m
|
|||
#
|
||||
# CONFIG_SOUND_PRIME is not set
|
||||
|
||||
#
|
||||
# HID Devices
|
||||
#
|
||||
CONFIG_HID=y
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
|
@ -1053,6 +1066,7 @@ CONFIG_USB=y
|
|||
CONFIG_USB_DEVICEFS=y
|
||||
# CONFIG_USB_BANDWIDTH is not set
|
||||
# CONFIG_USB_DYNAMIC_MINORS is not set
|
||||
# CONFIG_USB_MULTITHREAD_PROBE is not set
|
||||
# CONFIG_USB_OTG is not set
|
||||
|
||||
#
|
||||
|
@ -1089,8 +1103,7 @@ CONFIG_USB_UHCI_HCD=m
|
|||
# USB Input Devices
|
||||
#
|
||||
CONFIG_USB_HID=y
|
||||
CONFIG_USB_HIDINPUT=y
|
||||
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
|
||||
# CONFIG_USB_HID_POWERBOOK is not set
|
||||
# CONFIG_HID_FF is not set
|
||||
CONFIG_USB_HIDDEV=y
|
||||
# CONFIG_USB_AIPTEK is not set
|
||||
|
@ -1119,6 +1132,7 @@ CONFIG_USB_HIDDEV=y
|
|||
# CONFIG_USB_KAWETH is not set
|
||||
# CONFIG_USB_PEGASUS is not set
|
||||
# CONFIG_USB_RTL8150 is not set
|
||||
# CONFIG_USB_USBNET_MII is not set
|
||||
# CONFIG_USB_USBNET is not set
|
||||
# CONFIG_USB_MON is not set
|
||||
|
||||
|
@ -1363,6 +1377,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
|
|||
# CONFIG_NLS_KOI8_U is not set
|
||||
# CONFIG_NLS_UTF8 is not set
|
||||
|
||||
#
|
||||
# Distributed Lock Manager
|
||||
#
|
||||
# CONFIG_DLM is not set
|
||||
|
||||
#
|
||||
# Instrumentation Support
|
||||
#
|
||||
|
@ -1373,6 +1392,7 @@ CONFIG_KPROBES=y
|
|||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
|
@ -1387,6 +1407,8 @@ CONFIG_SCHEDSTATS=y
|
|||
# CONFIG_DEBUG_SPINLOCK is not set
|
||||
# CONFIG_DEBUG_MUTEXES is not set
|
||||
# CONFIG_DEBUG_RWSEMS is not set
|
||||
# CONFIG_DEBUG_LOCK_ALLOC is not set
|
||||
# CONFIG_PROVE_LOCKING is not set
|
||||
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
|
@ -1420,8 +1442,9 @@ CONFIG_CRYPTO=y
|
|||
CONFIG_CRYPTO_ALGAPI=y
|
||||
CONFIG_CRYPTO_BLKCIPHER=y
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_MANAGER=m
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_XCBC=y
|
||||
CONFIG_CRYPTO_NULL=m
|
||||
CONFIG_CRYPTO_MD4=y
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
|
@ -1430,8 +1453,10 @@ CONFIG_CRYPTO_SHA256=m
|
|||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_GF128MUL=m
|
||||
CONFIG_CRYPTO_ECB=m
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_DES=y
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
|
@ -1456,6 +1481,7 @@ CONFIG_CRYPTO_TEST=m
|
|||
#
|
||||
# Library routines
|
||||
#
|
||||
CONFIG_BITREVERSE=y
|
||||
CONFIG_CRC_CCITT=m
|
||||
CONFIG_CRC16=m
|
||||
CONFIG_CRC32=y
|
||||
|
|
|
@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
|
|||
power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
|
||||
visemul.o prom.o of_device.o
|
||||
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
|
||||
pci_psycho.o pci_sabre.o pci_schizo.o \
|
||||
pci_sun4v.o pci_sun4v_asm.o
|
||||
|
|
|
@ -341,7 +341,7 @@ static void fetch_decode_regs(struct mctrl_info *mp)
|
|||
|
||||
static int init_one_mctrl(struct device_node *dp)
|
||||
{
|
||||
struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL);
|
||||
struct mctrl_info *mp = kzalloc(sizeof(*mp), GFP_KERNEL);
|
||||
int portid = of_getintprop_default(dp, "portid", -1);
|
||||
struct linux_prom64_registers *regs;
|
||||
void *pval;
|
||||
|
@ -349,7 +349,6 @@ static int init_one_mctrl(struct device_node *dp)
|
|||
|
||||
if (!mp)
|
||||
return -1;
|
||||
memset(mp, 0, sizeof(*mp));
|
||||
if (portid == -1)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -597,7 +597,12 @@ __spitfire_cee_trap_continue:
|
|||
1: ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
2: mov %l4, %o1
|
||||
2:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call spitfire_access_error
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
|
@ -824,6 +829,10 @@ do_cheetah_plus_data_parity:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov 0x0, %o0
|
||||
call cheetah_plus_parity_error
|
||||
add %sp, PTREGS_OFF, %o1
|
||||
|
@ -855,6 +864,10 @@ do_cheetah_plus_insn_parity:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov 0x1, %o0
|
||||
call cheetah_plus_parity_error
|
||||
add %sp, PTREGS_OFF, %o1
|
||||
|
@ -1183,6 +1196,10 @@ c_fast_ecc:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call cheetah_fecc_handler
|
||||
|
@ -1211,6 +1228,10 @@ c_cee:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call cheetah_cee_handler
|
||||
|
@ -1239,6 +1260,10 @@ c_deferred:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call cheetah_deferred_handler
|
||||
|
|
|
@ -489,6 +489,14 @@ tlb_fixup_done:
|
|||
call __bzero
|
||||
sub %o1, %o0, %o1
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
/* We have this call this super early, as even prom_init can grab
|
||||
* spinlocks and thus call into the lockdep code.
|
||||
*/
|
||||
call lockdep_init
|
||||
nop
|
||||
#endif
|
||||
|
||||
mov %l6, %o1 ! OpenPROM stack
|
||||
call prom_init
|
||||
mov %l7, %o0 ! OpenPROM cif handler
|
||||
|
|
|
@ -72,14 +72,12 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
|
|||
struct linux_prom_registers *regs;
|
||||
struct sparc_isa_device *isa_dev;
|
||||
|
||||
isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
|
||||
isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
|
||||
if (!isa_dev) {
|
||||
fatal_err("cannot allocate child isa_dev");
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
memset(isa_dev, 0, sizeof(*isa_dev));
|
||||
|
||||
/* Link it in to parent. */
|
||||
isa_dev->next = parent_isa_dev->child;
|
||||
parent_isa_dev->child = isa_dev;
|
||||
|
@ -104,14 +102,12 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
|
|||
struct linux_prom_registers *regs;
|
||||
struct sparc_isa_device *isa_dev;
|
||||
|
||||
isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
|
||||
isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
|
||||
if (!isa_dev) {
|
||||
printk(KERN_DEBUG "ISA: cannot allocate isa_dev");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(isa_dev, 0, sizeof(*isa_dev));
|
||||
|
||||
isa_dev->ofdev.node = dp;
|
||||
isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
|
||||
isa_dev->ofdev.dev.bus = &isa_bus_type;
|
||||
|
@ -180,14 +176,12 @@ void __init isa_init(void)
|
|||
pbm = pdev_cookie->pbm;
|
||||
dp = pdev_cookie->prom_node;
|
||||
|
||||
isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
|
||||
isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL);
|
||||
if (!isa_br) {
|
||||
printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(isa_br, 0, sizeof(*isa_br));
|
||||
|
||||
isa_br->ofdev.node = dp;
|
||||
isa_br->ofdev.dev.parent = &pdev->dev;
|
||||
isa_br->ofdev.dev.bus = &isa_bus_type;
|
||||
|
|
|
@ -45,7 +45,11 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
|||
int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
||||
{
|
||||
p->ainsn.insn[0] = *p->addr;
|
||||
flushi(&p->ainsn.insn[0]);
|
||||
|
||||
p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
|
||||
flushi(&p->ainsn.insn[1]);
|
||||
|
||||
p->opcode = *p->addr;
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,16 +189,19 @@ no_kprobe:
|
|||
/* If INSN is a relative control transfer instruction,
|
||||
* return the corrected branch destination value.
|
||||
*
|
||||
* The original INSN location was REAL_PC, it actually
|
||||
* executed at PC and produced destination address NPC.
|
||||
* regs->tpc and regs->tnpc still hold the values of the
|
||||
* program counters at the time of trap due to the execution
|
||||
* of the BREAKPOINT_INSTRUCTION_2 at p->ainsn.insn[1]
|
||||
*
|
||||
*/
|
||||
static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc,
|
||||
unsigned long pc,
|
||||
unsigned long npc)
|
||||
static unsigned long __kprobes relbranch_fixup(u32 insn, struct kprobe *p,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long real_pc = (unsigned long) p->addr;
|
||||
|
||||
/* Branch not taken, no mods necessary. */
|
||||
if (npc == pc + 0x4UL)
|
||||
return real_pc + 0x4UL;
|
||||
if (regs->tnpc == regs->tpc + 0x4UL)
|
||||
return real_pc + 0x8UL;
|
||||
|
||||
/* The three cases are call, branch w/prediction,
|
||||
* and traditional branch.
|
||||
|
@ -202,14 +209,21 @@ static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc,
|
|||
if ((insn & 0xc0000000) == 0x40000000 ||
|
||||
(insn & 0xc1c00000) == 0x00400000 ||
|
||||
(insn & 0xc1c00000) == 0x00800000) {
|
||||
unsigned long ainsn_addr;
|
||||
|
||||
ainsn_addr = (unsigned long) &p->ainsn.insn[0];
|
||||
|
||||
/* The instruction did all the work for us
|
||||
* already, just apply the offset to the correct
|
||||
* instruction location.
|
||||
*/
|
||||
return (real_pc + (npc - pc));
|
||||
return (real_pc + (regs->tnpc - ainsn_addr));
|
||||
}
|
||||
|
||||
return real_pc + 0x4UL;
|
||||
/* It is jmpl or some other absolute PC modification instruction,
|
||||
* leave NPC as-is.
|
||||
*/
|
||||
return regs->tnpc;
|
||||
}
|
||||
|
||||
/* If INSN is an instruction which writes it's PC location
|
||||
|
@ -220,12 +234,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
|
|||
{
|
||||
unsigned long *slot = NULL;
|
||||
|
||||
/* Simplest cast is call, which always uses %o7 */
|
||||
/* Simplest case is 'call', which always uses %o7 */
|
||||
if ((insn & 0xc0000000) == 0x40000000) {
|
||||
slot = ®s->u_regs[UREG_I7];
|
||||
}
|
||||
|
||||
/* Jmpl encodes the register inside of the opcode */
|
||||
/* 'jmpl' encodes the register inside of the opcode */
|
||||
if ((insn & 0xc1f80000) == 0x81c00000) {
|
||||
unsigned long rd = ((insn >> 25) & 0x1f);
|
||||
|
||||
|
@ -247,11 +261,11 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
|
|||
|
||||
/*
|
||||
* Called after single-stepping. p->addr is the address of the
|
||||
* instruction whose first byte has been replaced by the breakpoint
|
||||
* instruction which has been replaced by the breakpoint
|
||||
* instruction. To avoid the SMP problems that can occur when we
|
||||
* temporarily put back the original opcode to single-step, we
|
||||
* single-stepped a copy of the instruction. The address of this
|
||||
* copy is p->ainsn.insn.
|
||||
* copy is &p->ainsn.insn[0].
|
||||
*
|
||||
* This function prepares to return from the post-single-step
|
||||
* breakpoint trap.
|
||||
|
@ -261,11 +275,11 @@ static void __kprobes resume_execution(struct kprobe *p,
|
|||
{
|
||||
u32 insn = p->ainsn.insn[0];
|
||||
|
||||
regs->tnpc = relbranch_fixup(insn, p, regs);
|
||||
|
||||
/* This assignment must occur after relbranch_fixup() */
|
||||
regs->tpc = kcb->kprobe_orig_tnpc;
|
||||
regs->tnpc = relbranch_fixup(insn,
|
||||
(unsigned long) p->addr,
|
||||
(unsigned long) &p->ainsn.insn[0],
|
||||
regs->tnpc);
|
||||
|
||||
retpc_fixup(regs, insn, (unsigned long) p->addr);
|
||||
|
||||
regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
|
||||
|
@ -430,17 +444,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs_location = regs;
|
||||
memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
|
||||
|
||||
/* Save a whole stack frame, this gets arguments
|
||||
* pushed onto the stack after using up all the
|
||||
* arg registers.
|
||||
*/
|
||||
memcpy(&(kcb->jprobe_saved_stack),
|
||||
(char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
|
||||
sizeof(kcb->jprobe_saved_stack));
|
||||
|
||||
regs->tpc = (unsigned long) jp->entry;
|
||||
regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
|
||||
regs->tstate |= TSTATE_PIL;
|
||||
|
@ -450,10 +455,19 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
|
||||
void __kprobes jprobe_return(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
".globl jprobe_return_trap_instruction\n"
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
register unsigned long orig_fp asm("g1");
|
||||
|
||||
orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP];
|
||||
__asm__ __volatile__("\n"
|
||||
"1: cmp %%sp, %0\n\t"
|
||||
"blu,a,pt %%xcc, 1b\n\t"
|
||||
" restore\n\t"
|
||||
".globl jprobe_return_trap_instruction\n"
|
||||
"jprobe_return_trap_instruction:\n\t"
|
||||
"ta 0x70");
|
||||
"ta 0x70"
|
||||
: /* no outputs */
|
||||
: "r" (orig_fp));
|
||||
}
|
||||
|
||||
extern void jprobe_return_trap_instruction(void);
|
||||
|
@ -466,26 +480,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
if (addr == (u32 *) jprobe_return_trap_instruction) {
|
||||
if (kcb->jprobe_saved_regs_location != regs) {
|
||||
printk("JPROBE: Current regs (%p) does not match "
|
||||
"saved regs (%p).\n",
|
||||
regs, kcb->jprobe_saved_regs_location);
|
||||
printk("JPROBE: Saved registers\n");
|
||||
__show_regs(kcb->jprobe_saved_regs_location);
|
||||
printk("JPROBE: Current registers\n");
|
||||
__show_regs(regs);
|
||||
BUG();
|
||||
}
|
||||
/* Restore old register state. Do pt_regs
|
||||
* first so that UREG_FP is the original one for
|
||||
* the stack frame restore.
|
||||
*/
|
||||
memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
|
||||
|
||||
memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
|
||||
&(kcb->jprobe_saved_stack),
|
||||
sizeof(kcb->jprobe_saved_stack));
|
||||
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1007,10 +1007,9 @@ struct of_device* of_platform_device_create(struct device_node *np,
|
|||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.bus = bus;
|
||||
|
|
|
@ -798,7 +798,7 @@ static struct pci_ops pci_sun4v_ops = {
|
|||
static void pbm_scan_bus(struct pci_controller_info *p,
|
||||
struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
|
||||
struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
|
||||
|
||||
if (!cookie) {
|
||||
prom_printf("%s: Critical allocation failure.\n", pbm->name);
|
||||
|
@ -806,7 +806,6 @@ static void pbm_scan_bus(struct pci_controller_info *p,
|
|||
}
|
||||
|
||||
/* All we care about is the PBM. */
|
||||
memset(cookie, 0, sizeof(*cookie));
|
||||
cookie->pbm = pbm;
|
||||
|
||||
pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm);
|
||||
|
@ -1048,12 +1047,11 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
|
|||
/* Allocate and initialize the free area map. */
|
||||
sz = num_tsb_entries / 8;
|
||||
sz = (sz + 7UL) & ~7UL;
|
||||
iommu->arena.map = kmalloc(sz, GFP_KERNEL);
|
||||
iommu->arena.map = kzalloc(sz, GFP_KERNEL);
|
||||
if (!iommu->arena.map) {
|
||||
prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n");
|
||||
prom_halt();
|
||||
}
|
||||
memset(iommu->arena.map, 0, sz);
|
||||
iommu->arena.limit = num_tsb_entries;
|
||||
|
||||
sz = probe_existing_entries(pbm, iommu);
|
||||
|
@ -1164,24 +1162,20 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
|
|||
per_cpu(pci_iommu_batch, i).pglist = (u64 *) page;
|
||||
}
|
||||
|
||||
p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
|
||||
p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
|
||||
if (!p)
|
||||
goto fatal_memory_error;
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
|
||||
iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
|
||||
if (!iommu)
|
||||
goto fatal_memory_error;
|
||||
|
||||
memset(iommu, 0, sizeof(*iommu));
|
||||
p->pbm_A.iommu = iommu;
|
||||
|
||||
iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
|
||||
iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC);
|
||||
if (!iommu)
|
||||
goto fatal_memory_error;
|
||||
|
||||
memset(iommu, 0, sizeof(*iommu));
|
||||
p->pbm_B.iommu = iommu;
|
||||
|
||||
p->next = pci_controller_root;
|
||||
|
|
|
@ -202,7 +202,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
|
|||
#endif
|
||||
if (request == PTRACE_TRACEME) {
|
||||
ret = ptrace_traceme();
|
||||
pt_succ_return(regs, 0);
|
||||
if (ret < 0)
|
||||
pt_error_return(regs, -ret);
|
||||
else
|
||||
pt_succ_return(regs, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,14 +165,26 @@ rtrap:
|
|||
__handle_softirq_continue:
|
||||
rtrap_xcall:
|
||||
sethi %hi(0xf << 20), %l4
|
||||
andcc %l1, TSTATE_PRIV, %l3
|
||||
and %l1, %l4, %l4
|
||||
andn %l1, %l4, %l1
|
||||
srl %l4, 20, %l4
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
brnz,pn %l4, rtrap_no_irq_enable
|
||||
nop
|
||||
call trace_hardirqs_on
|
||||
nop
|
||||
wrpr %l4, %pil
|
||||
rtrap_no_irq_enable:
|
||||
#endif
|
||||
andcc %l1, TSTATE_PRIV, %l3
|
||||
bne,pn %icc, to_kernel
|
||||
andn %l1, %l4, %l1
|
||||
nop
|
||||
|
||||
/* We must hold IRQs off and atomically test schedule+signal
|
||||
* state, then hold them off all the way back to userspace.
|
||||
* If we are returning to kernel, none of this matters.
|
||||
* If we are returning to kernel, none of this matters. Note
|
||||
* that we are disabling interrupts via PSTATE_IE, not using
|
||||
* %pil.
|
||||
*
|
||||
* If we do not do this, there is a window where we would do
|
||||
* the tests, later the signal/resched event arrives but we do
|
||||
|
@ -256,7 +268,6 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
|
|||
|
||||
ld [%sp + PTREGS_OFF + PT_V9_Y], %o3
|
||||
wr %o3, %g0, %y
|
||||
srl %l4, 20, %l4
|
||||
wrpr %l4, 0x0, %pil
|
||||
wrpr %g0, 0x1, %tl
|
||||
wrpr %l1, %g0, %tstate
|
||||
|
@ -374,8 +385,8 @@ to_kernel:
|
|||
ldx [%g6 + TI_FLAGS], %l5
|
||||
andcc %l5, _TIF_NEED_RESCHED, %g0
|
||||
be,pt %xcc, kern_fpucheck
|
||||
srl %l4, 20, %l5
|
||||
cmp %l5, 0
|
||||
nop
|
||||
cmp %l4, 0
|
||||
bne,pn %xcc, kern_fpucheck
|
||||
sethi %hi(PREEMPT_ACTIVE), %l6
|
||||
stw %l6, [%g6 + TI_PRE_COUNT]
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
|
||||
{
|
||||
unsigned long ksp, fp, thread_base;
|
||||
struct thread_info *tp;
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
tp = task_thread_info(task);
|
||||
if (task == current) {
|
||||
flushw_all();
|
||||
__asm__ __volatile__(
|
||||
"mov %%fp, %0"
|
||||
: "=r" (ksp)
|
||||
);
|
||||
} else
|
||||
ksp = tp->ksp;
|
||||
|
||||
fp = ksp + STACK_BIAS;
|
||||
thread_base = (unsigned long) tp;
|
||||
do {
|
||||
struct reg_window *rw;
|
||||
|
||||
/* Bogus frame pointer? */
|
||||
if (fp < (thread_base + sizeof(struct thread_info)) ||
|
||||
fp >= (thread_base + THREAD_SIZE))
|
||||
break;
|
||||
|
||||
rw = (struct reg_window *) fp;
|
||||
if (trace->skip > 0)
|
||||
trace->skip--;
|
||||
else
|
||||
trace->entries[trace->nr_entries++] = rw->ins[7];
|
||||
|
||||
fp = rw->ins[6] + STACK_BIAS;
|
||||
} while (trace->nr_entries < trace->max_entries);
|
||||
}
|
|
@ -190,7 +190,10 @@ sun4v_res_mondo:
|
|||
mov %g1, %g4
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
/* Log the event. */
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
call sun4v_resum_error
|
||||
|
@ -216,7 +219,10 @@ sun4v_res_mondo_queue_full:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
call sun4v_resum_overflow
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
|
||||
|
@ -295,7 +301,10 @@ sun4v_nonres_mondo:
|
|||
mov %g1, %g4
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
/* Log the event. */
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
call sun4v_nonresum_error
|
||||
|
@ -321,7 +330,10 @@ sun4v_nonres_mondo_queue_full:
|
|||
wrpr %g0, 15, %pil
|
||||
ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
call trace_hardirqs_off
|
||||
nop
|
||||
#endif
|
||||
call sun4v_nonresum_overflow
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h> /* for jiffies */
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/signal.h>
|
||||
|
@ -1873,6 +1873,16 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)
|
|||
|
||||
put_cpu();
|
||||
|
||||
if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) {
|
||||
/* If err_type is 0x4, it's a powerdown request. Do
|
||||
* not do the usual resumable error log because that
|
||||
* makes it look like some abnormal error.
|
||||
*/
|
||||
printk(KERN_INFO "Power down request...\n");
|
||||
kill_cad_pid(SIGINT, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
sun4v_log_error(regs, &local_copy, cpu,
|
||||
KERN_ERR "RESUMABLE ERROR",
|
||||
&sun4v_resum_oflow_cnt);
|
||||
|
@ -2261,8 +2271,12 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19))
|
||||
#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19))
|
||||
|
||||
extern int handle_popc(u32 insn, struct pt_regs *regs);
|
||||
extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);
|
||||
extern int vis_emul(struct pt_regs *, unsigned int);
|
||||
|
||||
void do_illegal_instruction(struct pt_regs *regs)
|
||||
{
|
||||
|
@ -2287,10 +2301,18 @@ void do_illegal_instruction(struct pt_regs *regs)
|
|||
if (handle_ldf_stq(insn, regs))
|
||||
return;
|
||||
} else if (tlb_type == hypervisor) {
|
||||
extern int vis_emul(struct pt_regs *, unsigned int);
|
||||
if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) {
|
||||
if (!vis_emul(regs, insn))
|
||||
return;
|
||||
} else {
|
||||
struct fpustate *f = FPUSTATE;
|
||||
|
||||
if (!vis_emul(regs, insn))
|
||||
return;
|
||||
/* XXX maybe verify XFSR bits like
|
||||
* XXX do_fpother() does?
|
||||
*/
|
||||
if (do_mathemu(regs, f))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
info.si_signo = SIGILL;
|
||||
|
|
|
@ -243,7 +243,7 @@ static inline int ok_for_kernel(unsigned int insn)
|
|||
return !floating_point_load_or_store_p(insn);
|
||||
}
|
||||
|
||||
static void kernel_mna_trap_fault(void)
|
||||
static void kernel_mna_trap_fault(int fixup_tstate_asi)
|
||||
{
|
||||
struct pt_regs *regs = current_thread_info()->kern_una_regs;
|
||||
unsigned int insn = current_thread_info()->kern_una_insn;
|
||||
|
@ -274,18 +274,15 @@ static void kernel_mna_trap_fault(void)
|
|||
regs->tpc = entry->fixup;
|
||||
regs->tnpc = regs->tpc + 4;
|
||||
|
||||
regs->tstate &= ~TSTATE_ASI;
|
||||
regs->tstate |= (ASI_AIUS << 24UL);
|
||||
if (fixup_tstate_asi) {
|
||||
regs->tstate &= ~TSTATE_ASI;
|
||||
regs->tstate |= (ASI_AIUS << 24UL);
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
||||
static void log_unaligned(struct pt_regs *regs)
|
||||
{
|
||||
static unsigned long count, last_time;
|
||||
enum direction dir = decode_direction(insn);
|
||||
int size = decode_access_size(insn);
|
||||
|
||||
current_thread_info()->kern_una_regs = regs;
|
||||
current_thread_info()->kern_una_insn = insn;
|
||||
|
||||
if (jiffies - last_time > 5 * HZ)
|
||||
count = 0;
|
||||
|
@ -295,6 +292,28 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
|||
printk("Kernel unaligned access at TPC[%lx] ", regs->tpc);
|
||||
print_symbol("%s\n", regs->tpc);
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
||||
{
|
||||
enum direction dir = decode_direction(insn);
|
||||
int size = decode_access_size(insn);
|
||||
int orig_asi, asi;
|
||||
|
||||
current_thread_info()->kern_una_regs = regs;
|
||||
current_thread_info()->kern_una_insn = insn;
|
||||
|
||||
orig_asi = asi = decode_asi(insn, regs);
|
||||
|
||||
/* If this is a {get,put}_user() on an unaligned userspace pointer,
|
||||
* just signal a fault and do not log the event.
|
||||
*/
|
||||
if (asi == ASI_AIUS) {
|
||||
kernel_mna_trap_fault(0);
|
||||
return;
|
||||
}
|
||||
|
||||
log_unaligned(regs);
|
||||
|
||||
if (!ok_for_kernel(insn) || dir == both) {
|
||||
printk("Unsupported unaligned load/store trap for kernel "
|
||||
|
@ -302,10 +321,10 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
|||
unaligned_panic("Kernel does fpu/atomic "
|
||||
"unaligned load/store.", regs);
|
||||
|
||||
kernel_mna_trap_fault();
|
||||
kernel_mna_trap_fault(0);
|
||||
} else {
|
||||
unsigned long addr, *reg_addr;
|
||||
int orig_asi, asi, err;
|
||||
int err;
|
||||
|
||||
addr = compute_effective_address(regs, insn,
|
||||
((insn >> 25) & 0x1f));
|
||||
|
@ -315,7 +334,6 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
|||
regs->tpc, dirstrings[dir], addr, size,
|
||||
regs->u_regs[UREG_RETPC]);
|
||||
#endif
|
||||
orig_asi = asi = decode_asi(insn, regs);
|
||||
switch (asi) {
|
||||
case ASI_NL:
|
||||
case ASI_AIUPL:
|
||||
|
@ -365,7 +383,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
|||
/* Not reached... */
|
||||
}
|
||||
if (unlikely(err))
|
||||
kernel_mna_trap_fault();
|
||||
kernel_mna_trap_fault(1);
|
||||
else
|
||||
advance(regs);
|
||||
}
|
||||
|
|
|
@ -128,9 +128,6 @@
|
|||
/* 001001100 - Permute bytes as specified by GSR.MASK */
|
||||
#define BSHUFFLE_OPF 0x04c
|
||||
|
||||
#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19))
|
||||
#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19))
|
||||
|
||||
#define VIS_OPF_SHIFT 5
|
||||
#define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT)
|
||||
|
||||
|
@ -810,9 +807,6 @@ int vis_emul(struct pt_regs *regs, unsigned int insn)
|
|||
if (get_user(insn, (u32 __user *) pc))
|
||||
return -EFAULT;
|
||||
|
||||
if ((insn & VIS_OPCODE_MASK) != VIS_OPCODE_VAL)
|
||||
return -EINVAL;
|
||||
|
||||
opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT;
|
||||
switch (opf) {
|
||||
default:
|
||||
|
|
|
@ -477,6 +477,10 @@ xcall_sync_tick:
|
|||
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 smp_synchronize_tick_client
|
||||
nop
|
||||
clr %l6
|
||||
|
@ -508,6 +512,10 @@ xcall_report_regs:
|
|||
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
|
||||
clr %l6
|
||||
|
|
|
@ -152,9 +152,9 @@ extern void dvma_init(struct sbus_bus *);
|
|||
#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
|
||||
|
||||
/* Yes, I hack a lot of elisp in my spare time... */
|
||||
#define DMA_ERROR_P(regs) (((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR))
|
||||
#define DMA_IRQ_P(regs) (((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
|
||||
#define DMA_WRITE_P(regs) (((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE))
|
||||
#define DMA_ERROR_P(regs) ((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR))
|
||||
#define DMA_IRQ_P(regs) ((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
|
||||
#define DMA_WRITE_P(regs) ((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE))
|
||||
#define DMA_OFF(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp &= ~DMA_ENABLE; \
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* include/asm-sparc64/irqflags.h
|
||||
*
|
||||
* IRQ flags handling
|
||||
*
|
||||
* This file gets included from lowlevel asm headers too, to provide
|
||||
* wrapped versions of the local_irq_*() APIs, based on the
|
||||
* raw_local_irq_*() functions from the lowlevel headers.
|
||||
*/
|
||||
#ifndef _ASM_IRQFLAGS_H
|
||||
#define _ASM_IRQFLAGS_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
static inline unsigned long __raw_local_save_flags(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"rdpr %%pil, %0"
|
||||
: "=r" (flags)
|
||||
);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define raw_local_save_flags(flags) \
|
||||
do { (flags) = __raw_local_save_flags(); } while (0)
|
||||
|
||||
static inline void raw_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wrpr %0, %%pil"
|
||||
: /* no output */
|
||||
: "r" (flags)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void raw_local_irq_disable(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wrpr 15, %%pil"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void raw_local_irq_enable(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wrpr 0, %%pil"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return (flags > 0);
|
||||
}
|
||||
|
||||
static inline int raw_irqs_disabled(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
|
||||
return raw_irqs_disabled_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* For spinlocks, etc:
|
||||
*/
|
||||
static inline unsigned long __raw_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
|
||||
raw_local_irq_disable();
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define raw_local_irq_save(flags) \
|
||||
do { (flags) = __raw_local_irq_save(); } while (0)
|
||||
|
||||
#endif /* (__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(_ASM_IRQFLAGS_H) */
|
|
@ -13,7 +13,11 @@ typedef u32 kprobe_opcode_t;
|
|||
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
|
||||
#define arch_remove_kprobe(p) do {} while (0)
|
||||
#define ARCH_INACTIVE_KPROBE_COUNT 0
|
||||
#define flush_insn_slot(p) do { } while (0)
|
||||
|
||||
#define flush_insn_slot(p) \
|
||||
do { flushi(&(p)->ainsn.insn[0]); \
|
||||
flushi(&(p)->ainsn.insn[1]); \
|
||||
} while (0)
|
||||
|
||||
/* Architecture specific copy of original instruction*/
|
||||
struct arch_specific_insn {
|
||||
|
@ -23,7 +27,7 @@ struct arch_specific_insn {
|
|||
|
||||
struct prev_kprobe {
|
||||
struct kprobe *kp;
|
||||
unsigned int status;
|
||||
unsigned long status;
|
||||
unsigned long orig_tnpc;
|
||||
unsigned long orig_tstate_pil;
|
||||
};
|
||||
|
@ -33,10 +37,7 @@ struct kprobe_ctlblk {
|
|||
unsigned long kprobe_status;
|
||||
unsigned long kprobe_orig_tnpc;
|
||||
unsigned long kprobe_orig_tstate_pil;
|
||||
long *jprobe_saved_esp;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
struct pt_regs *jprobe_saved_regs_location;
|
||||
struct sparc_stackf jprobe_saved_stack;
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,20 +23,33 @@ struct rw_semaphore {
|
|||
signed int count;
|
||||
spinlock_t wait_lock;
|
||||
struct list_head wait_list;
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
struct lockdep_map dep_map;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
|
||||
#else
|
||||
# define __RWSEM_DEP_MAP_INIT(lockname)
|
||||
#endif
|
||||
|
||||
#define __RWSEM_INITIALIZER(name) \
|
||||
{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) }
|
||||
{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
|
||||
__RWSEM_DEP_MAP_INIT(name) }
|
||||
|
||||
#define DECLARE_RWSEM(name) \
|
||||
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
|
||||
|
||||
static __inline__ void init_rwsem(struct rw_semaphore *sem)
|
||||
{
|
||||
sem->count = RWSEM_UNLOCKED_VALUE;
|
||||
spin_lock_init(&sem->wait_lock);
|
||||
INIT_LIST_HEAD(&sem->wait_list);
|
||||
}
|
||||
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
|
||||
struct lock_class_key *key);
|
||||
|
||||
#define init_rwsem(sem) \
|
||||
do { \
|
||||
static struct lock_class_key __key; \
|
||||
\
|
||||
__init_rwsem((sem), #sem, &__key); \
|
||||
} while (0)
|
||||
|
||||
extern void __down_read(struct rw_semaphore *sem);
|
||||
extern int __down_read_trylock(struct rw_semaphore *sem);
|
||||
|
@ -46,6 +59,11 @@ extern void __up_read(struct rw_semaphore *sem);
|
|||
extern void __up_write(struct rw_semaphore *sem);
|
||||
extern void __downgrade_write(struct rw_semaphore *sem);
|
||||
|
||||
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
|
||||
{
|
||||
__down_write(sem);
|
||||
}
|
||||
|
||||
static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
|
||||
{
|
||||
return atomic_add_return(delta, (atomic_t *)(&sem->count));
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include <asm/visasm.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
/*
|
||||
* Sparc (general) CPU types
|
||||
*/
|
||||
|
@ -72,52 +75,6 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
|
|||
|
||||
#endif
|
||||
|
||||
#define setipl(__new_ipl) \
|
||||
__asm__ __volatile__("wrpr %0, %%pil" : : "r" (__new_ipl) : "memory")
|
||||
|
||||
#define local_irq_disable() \
|
||||
__asm__ __volatile__("wrpr 15, %%pil" : : : "memory")
|
||||
|
||||
#define local_irq_enable() \
|
||||
__asm__ __volatile__("wrpr 0, %%pil" : : : "memory")
|
||||
|
||||
#define getipl() \
|
||||
({ unsigned long retval; __asm__ __volatile__("rdpr %%pil, %0" : "=r" (retval)); retval; })
|
||||
|
||||
#define swap_pil(__new_pil) \
|
||||
({ unsigned long retval; \
|
||||
__asm__ __volatile__("rdpr %%pil, %0\n\t" \
|
||||
"wrpr %1, %%pil" \
|
||||
: "=&r" (retval) \
|
||||
: "r" (__new_pil) \
|
||||
: "memory"); \
|
||||
retval; \
|
||||
})
|
||||
|
||||
#define read_pil_and_cli() \
|
||||
({ unsigned long retval; \
|
||||
__asm__ __volatile__("rdpr %%pil, %0\n\t" \
|
||||
"wrpr 15, %%pil" \
|
||||
: "=r" (retval) \
|
||||
: : "memory"); \
|
||||
retval; \
|
||||
})
|
||||
|
||||
#define local_save_flags(flags) ((flags) = getipl())
|
||||
#define local_irq_save(flags) ((flags) = read_pil_and_cli())
|
||||
#define local_irq_restore(flags) setipl((flags))
|
||||
|
||||
/* On sparc64 IRQ flags are the PIL register. A value of zero
|
||||
* means all interrupt levels are enabled, any other value means
|
||||
* only IRQ levels greater than that value will be received.
|
||||
* Consequently this means that the lowest IRQ level is one.
|
||||
*/
|
||||
#define irqs_disabled() \
|
||||
({ unsigned long flags; \
|
||||
local_save_flags(flags);\
|
||||
(flags > 0); \
|
||||
})
|
||||
|
||||
#define nop() __asm__ __volatile__ ("nop")
|
||||
|
||||
#define read_barrier_depends() do { } while(0)
|
||||
|
|
|
@ -137,10 +137,49 @@
|
|||
#endif
|
||||
#define BREAKPOINT_TRAP TRAP(breakpoint_trap)
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
|
||||
#define TRAP_IRQ(routine, level) \
|
||||
rdpr %pil, %g2; \
|
||||
wrpr %g0, 15, %pil; \
|
||||
b,pt %xcc, etrap_irq; \
|
||||
sethi %hi(1f-4), %g7; \
|
||||
ba,pt %xcc, etrap_irq; \
|
||||
or %g7, %lo(1f-4), %g7; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop; \
|
||||
.subsection 2; \
|
||||
1: call trace_hardirqs_off; \
|
||||
nop; \
|
||||
mov level, %o0; \
|
||||
call routine; \
|
||||
add %sp, PTREGS_OFF, %o1; \
|
||||
ba,a,pt %xcc, rtrap_irq; \
|
||||
.previous;
|
||||
|
||||
#define TICK_SMP_IRQ \
|
||||
rdpr %pil, %g2; \
|
||||
wrpr %g0, 15, %pil; \
|
||||
sethi %hi(1f-4), %g7; \
|
||||
ba,pt %xcc, etrap_irq; \
|
||||
or %g7, %lo(1f-4), %g7; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop; \
|
||||
.subsection 2; \
|
||||
1: call trace_hardirqs_off; \
|
||||
nop; \
|
||||
call smp_percpu_timer_interrupt; \
|
||||
add %sp, PTREGS_OFF, %o0; \
|
||||
ba,a,pt %xcc, rtrap_irq; \
|
||||
.previous;
|
||||
|
||||
#else
|
||||
|
||||
#define TRAP_IRQ(routine, level) \
|
||||
rdpr %pil, %g2; \
|
||||
wrpr %g0, 15, %pil; \
|
||||
ba,pt %xcc, etrap_irq; \
|
||||
rd %pc, %g7; \
|
||||
mov level, %o0; \
|
||||
call routine; \
|
||||
|
@ -151,12 +190,14 @@
|
|||
rdpr %pil, %g2; \
|
||||
wrpr %g0, 15, %pil; \
|
||||
sethi %hi(109f), %g7; \
|
||||
b,pt %xcc, etrap_irq; \
|
||||
ba,pt %xcc, etrap_irq; \
|
||||
109: or %g7, %lo(109b), %g7; \
|
||||
call smp_percpu_timer_interrupt; \
|
||||
add %sp, PTREGS_OFF, %o0; \
|
||||
ba,a,pt %xcc, rtrap_irq;
|
||||
|
||||
#endif
|
||||
|
||||
#define TRAP_IVEC TRAP_NOSAVE(do_ivec)
|
||||
|
||||
#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
|
||||
|
|
Loading…
Reference in New Issue