diff options
Diffstat (limited to 'arch/sparc64')
49 files changed, 450 insertions, 405 deletions
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index 9cb75c852b4..4b8f2b084c2 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.52 2002/02/09 19:49:31 davem Exp $ # sparc64/Makefile # # Makefile for the architecture dependent flags and dependencies on the diff --git a/arch/sparc64/boot/Makefile b/arch/sparc64/boot/Makefile index 6968a6da57d..0458b5244f0 100644 --- a/arch/sparc64/boot/Makefile +++ b/arch/sparc64/boot/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.4 1997/12/15 20:08:56 ecd Exp $ # Makefile for the Sparc64 boot stuff. # # Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/boot/piggyback.c b/arch/sparc64/boot/piggyback.c index 36f907408c6..de364bfed0b 100644 --- a/arch/sparc64/boot/piggyback.c +++ b/arch/sparc64/boot/piggyback.c @@ -1,4 +1,4 @@ -/* $Id: piggyback.c,v 1.2 2000/09/19 14:34:39 anton Exp $ +/* Simple utility to make a single-image install kernel with initial ramdisk for Sparc64 tftpbooting without need to set up nfs. diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index aff93c9d13f..76eb832527f 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25 -# Sat Apr 26 03:11:06 2008 +# Linux kernel version: 2.6.26-rc2 +# Fri May 16 13:36:07 2008 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -74,6 +74,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -103,12 +104,14 @@ CONFIG_KPROBES=y CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y @@ -170,6 +173,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y @@ -402,7 +406,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_AEC62XX is not set CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_BLK_DEV_CMD64X is not set # CONFIG_BLK_DEV_TRIFLEX is not set @@ -609,6 +612,7 @@ CONFIG_NIU=m # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_SFC is not set # CONFIG_TR is not set # @@ -717,6 +721,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -793,12 +798,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y @@ -873,8 +873,17 @@ CONFIG_SSB_POSSIBLE=y # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -893,8 +902,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -1100,6 +1109,10 @@ CONFIG_SND_SUN_CS4231=m # # +# SoC Audio for the Texas Instruments OMAP +# + +# # Open Sound System # # CONFIG_SOUND_PRIME is not set @@ -1135,10 +1148,12 @@ CONFIG_USB_DEVICEFS=y # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set @@ -1173,6 +1188,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1214,6 +1230,7 @@ CONFIG_USB_STORAGE=m # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set # CONFIG_UIO is not set @@ -1367,6 +1384,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y @@ -1377,6 +1395,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHED_DEBUG is not set CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set @@ -1402,6 +1421,8 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_DCFLUSH is not set # CONFIG_STACK_DEBUG is not set @@ -1503,6 +1524,7 @@ CONFIG_CRYPTO_HW=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m # CONFIG_CRC_ITU_T is not set diff --git a/arch/sparc64/kernel/dtlb_prot.S b/arch/sparc64/kernel/dtlb_prot.S index e0a92016260..b2c2c5be281 100644 --- a/arch/sparc64/kernel/dtlb_prot.S +++ b/arch/sparc64/kernel/dtlb_prot.S @@ -1,4 +1,4 @@ -/* $Id: dtlb_prot.S,v 1.22 2001/04/11 23:40:32 davem Exp $ +/* * dtlb_prot.S: DTLB protection trap strategy. * This is included directly into the trap table. * diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index bc263227484..c49d0388b79 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.64 2001/11/08 04:41:33 davem Exp $ +/* * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index b49d3b60bc0..29ce489bc18 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.46 2002/02/09 19:49:30 davem Exp $ +/* * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -27,11 +27,12 @@ .text .align 64 - .globl etrap, etrap_irq, etraptl1 + .globl etrap_syscall, etrap, etrap_irq, etraptl1 etrap: rdpr %pil, %g2 -etrap_irq: - TRAP_LOAD_THREAD_REG(%g6, %g1) +etrap_irq: clr %g3 +etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1) rdpr %tstate, %g1 + or %g1, %g3, %g1 sllx %g2, 20, %g3 andcc %g1, TSTATE_PRIV, %g0 or %g1, %g3, %g1 diff --git a/arch/sparc64/kernel/idprom.c b/arch/sparc64/kernel/idprom.c index 3b6789e09a7..5b45a808c62 100644 --- a/arch/sparc64/kernel/idprom.c +++ b/arch/sparc64/kernel/idprom.c @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.3 1999/08/31 06:54:53 davem Exp $ +/* * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * diff --git a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c index 90007cf88ba..d2b312381c1 100644 --- a/arch/sparc64/kernel/init_task.c +++ b/arch/sparc64/kernel/init_task.c @@ -10,7 +10,6 @@ #include <asm/processor.h> static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index dbf2fc2f4d8..112b09f16f3 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -350,8 +350,7 @@ static void pci_parse_of_addrs(struct of_device *op, struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct device_node *node, - struct pci_bus *bus, int devfn, - int host_controller) + struct pci_bus *bus, int devfn) { struct dev_archdata *sd; struct pci_dev *dev; @@ -390,43 +389,28 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ - if (host_controller) { - if (tlb_type != hypervisor) { - pci_read_config_word(dev, PCI_VENDOR_ID, - &dev->vendor); - pci_read_config_word(dev, PCI_DEVICE_ID, - &dev->device); - } else { - dev->vendor = PCI_VENDOR_ID_SUN; - dev->device = 0x80f0; - } - dev->cfg_size = 256; - dev->class = PCI_CLASS_BRIDGE_HOST << 8; - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), - 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn)); - } else { - dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); - dev->device = of_getintprop_default(node, "device-id", 0xffff); - dev->subsystem_vendor = - of_getintprop_default(node, "subsystem-vendor-id", 0); - dev->subsystem_device = - of_getintprop_default(node, "subsystem-id", 0); - - dev->cfg_size = pci_cfg_space_size(dev); - - /* We can't actually use the firmware value, we have - * to read what is in the register right now. One - * reason is that in the case of IDE interfaces the - * firmware can sample the value before the the IDE - * interface is programmed into native mode. - */ - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); - dev->class = class >> 8; - dev->revision = class & 0xff; + dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); + dev->device = of_getintprop_default(node, "device-id", 0xffff); + dev->subsystem_vendor = + of_getintprop_default(node, "subsystem-vendor-id", 0); + dev->subsystem_device = + of_getintprop_default(node, "subsystem-id", 0); + + dev->cfg_size = pci_cfg_space_size(dev); + + /* We can't actually use the firmware value, we have + * to read what is in the register right now. One + * reason is that in the case of IDE interfaces the + * firmware can sample the value before the the IDE + * interface is programmed into native mode. + */ + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); + dev->class = class >> 8; + dev->revision = class & 0xff; + + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), - dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - } if (ofpci_verbose) printk(" class: 0x%x device name: %s\n", dev->class, pci_name(dev)); @@ -441,26 +425,21 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; - if (host_controller) { + if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; - dev->irq = PCI_IRQ_NONE; + } else if (!strcmp(type, "cardbus")) { + dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; } else { - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { - /* a PCI-PCI bridge */ - dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; - dev->rom_base_reg = PCI_ROM_ADDRESS1; - } else if (!strcmp(type, "cardbus")) { - dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; - } else { - dev->hdr_type = PCI_HEADER_TYPE_NORMAL; - dev->rom_base_reg = PCI_ROM_ADDRESS; + dev->hdr_type = PCI_HEADER_TYPE_NORMAL; + dev->rom_base_reg = PCI_ROM_ADDRESS; - dev->irq = sd->op->irqs[0]; - if (dev->irq == 0xffffffff) - dev->irq = PCI_IRQ_NONE; - } + dev->irq = sd->op->irqs[0]; + if (dev->irq == 0xffffffff) + dev->irq = PCI_IRQ_NONE; } + pci_parse_of_addrs(sd->op, node, dev); if (ofpci_verbose) @@ -749,7 +728,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, prev_devfn = devfn; /* create a new pci_dev for this device */ - dev = of_create_pci_dev(pbm, child, bus, devfn, 0); + dev = of_create_pci_dev(pbm, child, bus, devfn); if (!dev) continue; if (ofpci_verbose) @@ -796,48 +775,9 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } -int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 *value) -{ - static u8 fake_pci_config[] = { - 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ - 0xf0, 0x80, /* Device: 0x80f0 (Fire) */ - 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ - 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ - 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ - 0x00, /* Cacheline: 0x00 */ - 0x40, /* Latency: 0x40 */ - 0x00, /* Header-Type: 0x00 normal */ - }; - - *value = 0; - if (where >= 0 && where < sizeof(fake_pci_config) && - (where + size) >= 0 && - (where + size) < sizeof(fake_pci_config) && - size <= sizeof(u32)) { - while (size--) { - *value <<= 8; - *value |= fake_pci_config[where + size]; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 value) -{ - return PCIBIOS_SUCCESSFUL; -} - struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct device_node *node = pbm->prom_node; - struct pci_dev *host_pdev; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -855,10 +795,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) bus->resource[0] = &pbm->io_space; bus->resource[1] = &pbm->mem_space; - /* Create the dummy host bridge and link it in. */ - host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); - bus->self = host_pdev; - pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 923e0bcc3bf..19fa621d6a6 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -264,9 +264,6 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; - if (!bus && devfn == 0x00) - return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, - size, value); if (config_out_of_range(pbm, bus, devfn, where)) { ret = ~0UL; } else { @@ -300,9 +297,6 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; - if (!bus && devfn == 0x00) - return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, - size, value); if (config_out_of_range(pbm, bus, devfn, where)) { /* Do nothing. */ } else { diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 218bac4ff79..c385d126be1 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -167,15 +167,6 @@ extern void pci_get_pbm_props(struct pci_pbm_info *pbm); extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); -extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 *value); -extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 value); - /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 05601374915..2084f81a76e 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -1,6 +1,6 @@ /* arch/sparc64/kernel/process.c * - * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995, 1996, 2008 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1997, 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ @@ -30,6 +30,7 @@ #include <linux/init.h> #include <linux/cpu.h> #include <linux/elfcore.h> +#include <linux/sysrq.h> #include <asm/oplib.h> #include <asm/uaccess.h> @@ -49,6 +50,8 @@ #include <asm/sstate.h> #include <asm/reboot.h> #include <asm/syscalls.h> +#include <asm/irq_regs.h> +#include <asm/smp.h> /* #define VERBOSE_SHOWREGS */ @@ -298,6 +301,118 @@ void show_regs(struct pt_regs *regs) #endif } +#ifdef CONFIG_MAGIC_SYSRQ +struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; +static DEFINE_SPINLOCK(global_reg_snapshot_lock); + +static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, + int this_cpu) +{ + flushw_all(); + + global_reg_snapshot[this_cpu].tstate = regs->tstate; + global_reg_snapshot[this_cpu].tpc = regs->tpc; + global_reg_snapshot[this_cpu].tnpc = regs->tnpc; + global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7]; + + if (regs->tstate & TSTATE_PRIV) { + 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 + global_reg_snapshot[this_cpu].i7 = 0; + + global_reg_snapshot[this_cpu].thread = tp; +} + +/* In order to avoid hangs we do not try to synchronize with the + * global register dump client cpus. The last store they make is to + * the thread pointer, so do a short poll waiting for that to become + * non-NULL. + */ +static void __global_reg_poll(struct global_reg_snapshot *gp) +{ + int limit = 0; + + while (!gp->thread && ++limit < 100) { + barrier(); + udelay(1); + } +} + +static void sysrq_handle_globreg(int key, struct tty_struct *tty) +{ + struct thread_info *tp = current_thread_info(); + struct pt_regs *regs = get_irq_regs(); +#ifdef CONFIG_KALLSYMS + char buffer[KSYM_SYMBOL_LEN]; +#endif + unsigned long flags; + int this_cpu, cpu; + + if (!regs) + regs = tp->kregs; + + spin_lock_irqsave(&global_reg_snapshot_lock, flags); + + memset(global_reg_snapshot, 0, sizeof(global_reg_snapshot)); + + this_cpu = raw_smp_processor_id(); + + __global_reg_self(tp, regs, this_cpu); + + smp_fetch_global_regs(); + + for_each_online_cpu(cpu) { + struct global_reg_snapshot *gp = &global_reg_snapshot[cpu]; + struct thread_info *tp; + + __global_reg_poll(gp); + + tp = gp->thread; + printk("%c CPU[%3d]: TSTATE[%016lx] TPC[%016lx] TNPC[%016lx] TASK[%s:%d]\n", + (cpu == this_cpu ? '*' : ' '), cpu, + gp->tstate, gp->tpc, gp->tnpc, + ((tp && tp->task) ? tp->task->comm : "NULL"), + ((tp && tp->task) ? tp->task->pid : -1)); +#ifdef CONFIG_KALLSYMS + if (gp->tstate & TSTATE_PRIV) { + sprint_symbol(buffer, gp->tpc); + printk(" TPC[%s] ", buffer); + sprint_symbol(buffer, gp->o7); + printk("O7[%s] ", buffer); + sprint_symbol(buffer, gp->i7); + printk("I7[%s]\n", buffer); + } else +#endif + { + printk(" TPC[%lx] O7[%lx] I7[%lx]\n", + gp->tpc, gp->o7, gp->i7); + } + } + + memset(global_reg_snapshot, 0, sizeof(global_reg_snapshot)); + + spin_unlock_irqrestore(&global_reg_snapshot_lock, flags); +} + +static struct sysrq_key_op sparc_globalreg_op = { + .handler = sysrq_handle_globreg, + .help_msg = "Globalregs", + .action_msg = "Show Global CPU Regs", +}; + +static int __init sparc_globreg_init(void) +{ + return register_sysrq_key('y', &sparc_globalreg_op); +} + +core_initcall(sparc_globreg_init); + +#endif + unsigned long thread_saved_pc(struct task_struct *tsk) { struct thread_info *ti = task_thread_info(tsk); @@ -503,6 +618,8 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, unsigned long stack_size) { int __user *parent_tid_ptr, *child_tid_ptr; + unsigned long orig_i1 = regs->u_regs[UREG_I1]; + long ret; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { @@ -515,9 +632,19 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; } - return do_fork(clone_flags, stack_start, - regs, stack_size, - parent_tid_ptr, child_tid_ptr); + ret = do_fork(clone_flags, stack_start, + regs, stack_size, + parent_tid_ptr, child_tid_ptr); + + /* If we get an error and potentially restart the system + * call, we're screwed because copy_thread() clobbered + * the parent's %o1. So detect that case and restore it + * here. + */ + if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) + regs->u_regs[UREG_I1] = orig_i1; + + return ret; } /* Copy a Sparc thread. The fork() return value conventions @@ -530,20 +657,39 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, struct task_struct *p, struct pt_regs *regs) { struct thread_info *t = task_thread_info(p); + struct sparc_stackf *parent_sf; + unsigned long child_stack_sz; char *child_trap_frame; + int kernel_thread; - /* Calculate offset to stack_frame & pt_regs */ - child_trap_frame = task_stack_page(p) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); - memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); + kernel_thread = (regs->tstate & TSTATE_PRIV) ? 1 : 0; + parent_sf = ((struct sparc_stackf *) regs) - 1; - t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | + /* Calculate offset to stack_frame & pt_regs */ + child_stack_sz = ((STACKFRAME_SZ + TRACEREG_SZ) + + (kernel_thread ? STACKFRAME_SZ : 0)); + child_trap_frame = (task_stack_page(p) + + (THREAD_SIZE - child_stack_sz)); + memcpy(child_trap_frame, parent_sf, child_stack_sz); + + t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | + (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); t->new_child = 1; t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; - t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf)); + t->kregs = (struct pt_regs *) (child_trap_frame + + sizeof(struct sparc_stackf)); t->fpsaved[0] = 0; - if (regs->tstate & TSTATE_PRIV) { + if (kernel_thread) { + struct sparc_stackf *child_sf = (struct sparc_stackf *) + (child_trap_frame + (STACKFRAME_SZ + TRACEREG_SZ)); + + /* Zero terminate the stack backtrace. */ + child_sf->fp = NULL; + t->kregs->u_regs[UREG_FP] = + ((unsigned long) child_sf) - STACK_BIAS; + /* Special case, if we are spawning a kernel thread from * a userspace task (via KMOD, NFS, or similar) we must * disable performance counters in the child because the @@ -554,12 +700,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, t->pcr_reg = 0; t->flags &= ~_TIF_PERFCTR; } - t->kregs->u_regs[UREG_FP] = t->ksp; t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); - flush_register_windows(); - memcpy((void *)(t->ksp + STACK_BIAS), - (void *)(regs->u_regs[UREG_FP] + STACK_BIAS), - sizeof(struct sparc_stackf)); t->kregs->u_regs[UREG_G6] = (unsigned long) t; t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; } else { @@ -591,12 +732,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, if (clone_flags & CLONE_SETTLS) t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; - /* We do not want to accidently trigger system call restart - * handling in the new thread. Therefore, clear out the trap - * type, which will make pt_regs_regs_is_syscall() return false. - */ - pt_regs_clear_trap_type(t->kregs); - return 0; } diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index e9fc0aa2da3..f6c9fc92921 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target, 32 * sizeof(u64), 33 * sizeof(u64)); if (!ret) { - /* Only the condition codes can be modified - * in the %tstate register. + /* Only the condition codes and the "in syscall" + * state can be modified in the %tstate register. */ - tstate &= (TSTATE_ICC | TSTATE_XCC); - regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); + tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); + regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); regs->tstate |= tstate; } } @@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target, switch (pos) { case 32: /* PSR */ tstate = regs->tstate; - tstate &= ~(TSTATE_ICC | TSTATE_XCC); + tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); tstate |= psr_to_tstate_icc(reg); + if (reg & PSR_SYSCALL) + tstate |= TSTATE_SYSCALL; regs->tstate = tstate; break; case 33: /* PC */ @@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = compat_ptrace_request(child, request, addr, data); break; } @@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = ptrace_request(child, request, addr, data); break; } diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index ecf6753b204..c6fc695fe1f 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.61 2002/02/09 19:49:31 davem Exp $ +/* * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -46,7 +46,7 @@ __handle_user_windows: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate ldx [%g6 + TI_FLAGS], %l0 -1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 +1: andcc %l0, _TIF_SIGPENDING, %g0 be,pt %xcc, __handle_user_windows_continue nop mov %l5, %o1 @@ -86,7 +86,7 @@ __handle_perfctrs: wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate ldx [%g6 + TI_FLAGS], %l0 -1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 +1: andcc %l0, _TIF_SIGPENDING, %g0 be,pt %xcc, __handle_perfctrs_continue sethi %hi(TSTATE_PEF), %o0 @@ -195,7 +195,7 @@ __handle_preemption_continue: andcc %l1, %o0, %g0 andcc %l0, _TIF_NEED_RESCHED, %g0 bne,pn %xcc, __handle_preemption - andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 + andcc %l0, _TIF_SIGPENDING, %g0 bne,pn %xcc, __handle_signal __handle_signal_continue: ldub [%g6 + TI_WSAVED], %o2 @@ -257,6 +257,7 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 wr %o3, %g0, %y wrpr %l4, 0x0, %pil wrpr %g0, 0x1, %tl + andn %l1, TSTATE_SYSCALL, %l1 wrpr %l1, %g0, %tstate wrpr %l2, %g0, %tpc wrpr %o2, %g0, %tnpc @@ -362,6 +363,7 @@ kern_rtt: rdpr %canrestore, %g1 brz,pn %g1, kern_rtt_fill nop kern_rtt_restore: + stw %g0, [%sp + PTREGS_OFF + PT_V9_MAGIC] restore retry diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index fa2827c4a3a..e33a8a660e9 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.19 2002/01/23 11:27:32 davem Exp $ +/* * sbus.c: UltraSparc SBUS controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index da5e6ee0c66..c8b03a4f68b 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.72 2002/02/09 19:49:30 davem Exp $ +/* * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index f2d88d8f7a4..9667e96fd51 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.60 2002/02/09 19:49:31 davem Exp $ +/* * arch/sparc64/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set) current->state = TASK_INTERRUPTIBLE; schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); + + set_restore_sigmask(); + return -ERESTARTNOHAND; } @@ -332,6 +334,9 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tpc = tpc; regs->tnpc = tnpc; + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; @@ -373,16 +378,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { - unsigned long sp; + unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; - sp = regs->u_regs[UREG_FP] + STACK_BIAS; + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) + return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp) && - !((current->sas_ss_sp + current->sas_ss_size) & 7)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &= ~7UL; + return (void __user *)(sp - framesize); } @@ -483,7 +501,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, - struct sigaction *sa) + struct sigaction *sa) { switch (regs->u_regs[UREG_I0]) { case ERESTART_RESTARTBLOCK: @@ -509,20 +527,19 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { - struct signal_deliver_cookie cookie; struct k_sigaction ka; + int restart_syscall; sigset_t *oldset; siginfo_t info; int signr; - if (pt_regs_is_syscall(regs)) { - pt_regs_clear_trap_type(regs); - cookie.restart_syscall = 1; + if (pt_regs_is_syscall(regs) && + (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { + restart_syscall = 1; } else - cookie.restart_syscall = 0; - cookie.orig_i0 = orig_i0; + restart_syscall = 0; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) + if (current_thread_info()->status & TS_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; @@ -530,77 +547,62 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *, - struct signal_deliver_cookie *); - do_signal32(oldset, regs, &cookie); + int restart_syscall, + unsigned long orig_i0); + do_signal32(oldset, regs, restart_syscall, orig_i0); return; } #endif - signr = get_signal_to_deliver(&info, &ka, regs, &cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the software "in syscall" bit, directing us to not perform + * a syscall restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie.restart_syscall) - syscall_restart(cookie.orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); - /* a signal was successfully delivered; the saved + /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. + * clear the TS_RESTORE_SIGMASK flag. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; return; } - if (cookie.restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie.orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (cookie.restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; } - /* if there's no signal to deliver, we just put the saved sigmask + /* If there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); } - -void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) -{ - struct signal_deliver_cookie *cp = cookie; - - if (cp->restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cp->orig_i0; - regs->tpc -= 4; - regs->tnpc -= 4; - cp->restart_syscall = 0; - } - if (cp->restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->tpc -= 4; - regs->tnpc -= 4; - cp->restart_syscall = 0; - } -} diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 91f8d0826db..97cdd1bf4a1 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -268,6 +268,9 @@ void do_sigreturn32(struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); @@ -351,6 +354,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); @@ -400,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; sp = regs->u_regs[UREG_FP]; + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) + return (void __user *) -1L; + /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &= ~7UL; + return (void __user *)(sp - framesize); } @@ -746,48 +768,55 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs * mistake. */ void do_signal32(sigset_t *oldset, struct pt_regs * regs, - struct signal_deliver_cookie *cookie) + int restart_syscall, unsigned long orig_i0) { struct k_sigaction ka; siginfo_t info; int signr; - signr = get_signal_to_deliver(&info, &ka, regs, cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the "in syscall" bit, directing us to not perform a syscall + * restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie->restart_syscall) - syscall_restart32(cookie->orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); - /* a signal was successfully delivered; the saved + /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. + * clear the TS_RESTORE_SIGMASK flag. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; return; } - if (cookie->restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie->orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (cookie->restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; } - /* if there's no signal to deliver, we just put the saved sigmask + /* If there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 3aba47624df..fa63c68a181 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -865,21 +865,14 @@ void smp_call_function_client(int irq, struct pt_regs *regs) void *info = call_data->info; clear_softint(1 << irq); - - irq_enter(); - - if (!call_data->wait) { - /* let initiator proceed after getting data */ - atomic_inc(&call_data->finished); - } - - func(info); - - irq_exit(); - if (call_data->wait) { /* let initiator proceed only after completion */ + func(info); + atomic_inc(&call_data->finished); + } else { + /* let initiator proceed after getting data */ atomic_inc(&call_data->finished); + func(info); } } @@ -907,6 +900,9 @@ 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 extern unsigned long xcall_receive_signal; extern unsigned long xcall_new_mmu_context_version; #ifdef CONFIG_KGDB @@ -1041,9 +1037,7 @@ void smp_receive_signal(int cpu) void smp_receive_signal_client(int irq, struct pt_regs *regs) { - irq_enter(); clear_softint(1 << irq); - irq_exit(); } void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) @@ -1051,8 +1045,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) struct mm_struct *mm; unsigned long flags; - irq_enter(); - clear_softint(1 << irq); /* See if we need to allocate a new TLB context because @@ -1072,8 +1064,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); - - irq_exit(); } void smp_new_mmu_context_version(void) @@ -1093,6 +1083,13 @@ void smp_report_regs(void) smp_cross_call(&xcall_report_regs, 0, 0, 0); } +#ifdef CONFIG_MAGIC_SYSRQ +void smp_fetch_global_regs(void) +{ + smp_cross_call(&xcall_fetch_glob_regs, 0, 0, 0); +} +#endif + /* We know that the window frames of the user have been flushed * to the stack before we get here because all callers of us * are flush_tlb_*() routines, and these run after flush_cache_*() @@ -1239,8 +1236,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) { clear_softint(1 << irq); - irq_enter(); - preempt_disable(); __asm__ __volatile__("flushw"); @@ -1253,8 +1248,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) prom_world(0); preempt_enable(); - - irq_exit(); } /* /proc/profile writes can call this, don't __init it please. */ diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index 01b52f561af..c73ce3f4197 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c @@ -19,7 +19,7 @@ void save_stack_trace(struct stack_trace *trace) fp = ksp + STACK_BIAS; thread_base = (unsigned long) tp; do { - struct reg_window *rw; + struct sparc_stackf *sf; struct pt_regs *regs; unsigned long pc; @@ -28,15 +28,17 @@ void save_stack_trace(struct stack_trace *trace) fp >= (thread_base + THREAD_SIZE)) break; - rw = (struct reg_window *) fp; - regs = (struct pt_regs *) (rw + 1); + sf = (struct sparc_stackf *) fp; + regs = (struct pt_regs *) (sf + 1); if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { + if (!(regs->tstate & TSTATE_PRIV)) + break; pc = regs->tpc; fp = regs->u_regs[UREG_I6] + STACK_BIAS; } else { - pc = rw->ins[7]; - fp = rw->ins[6] + STACK_BIAS; + pc = sf->callers_pc; + fp = (unsigned long)sf->fp + STACK_BIAS; } if (trace->skip > 0) diff --git a/arch/sparc64/kernel/starfire.c b/arch/sparc64/kernel/starfire.c index b930fee7708..7461581b3bb 100644 --- a/arch/sparc64/kernel/starfire.c +++ b/arch/sparc64/kernel/starfire.c @@ -1,4 +1,4 @@ -/* $Id: starfire.c,v 1.10 2001/04/14 21:13:45 davem Exp $ +/* * starfire.c: Starfire/E10000 support. * * Copyright (C) 1998 David S. Miller (davem@redhat.com) diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 010a737908e..ade18ba0c68 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -1,4 +1,4 @@ -/* $Id: sys32.S,v 1.12 2000/03/24 04:17:37 davem Exp $ +/* * sys32.S: I-cache tricks for 32-bit compatibility layer simple * conversions. * diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 8d4761f15fa..ac1bff58c1a 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -542,20 +542,19 @@ asmlinkage long sparc64_personality(unsigned long personality) return ret; } -int sparc64_mmap_check(unsigned long addr, unsigned long len, - unsigned long flags) +int sparc64_mmap_check(unsigned long addr, unsigned long len) { if (test_thread_flag(TIF_32BIT)) { if (len >= STACK_TOP32) return -EINVAL; - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) + if (addr > STACK_TOP32 - len) return -EINVAL; } else { if (len >= VA_EXCLUDE_START) return -EINVAL; - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) + if (invalid_64bit_range(addr, len)) return -EINVAL; } @@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { - struct vm_area_struct *vma; unsigned long ret = -EINVAL; if (test_thread_flag(TIF_32BIT)) goto out; if (unlikely(new_len >= VA_EXCLUDE_START)) goto out; - if (unlikely(invalid_64bit_range(addr, old_len))) + if (unlikely(sparc64_mmap_check(addr, old_len))) + goto out; + if (unlikely(sparc64_mmap_check(new_addr, new_len))) goto out; down_write(¤t->mm->mmap_sem); - if (flags & MREMAP_FIXED) { - if (invalid_64bit_range(new_addr, new_len)) - goto out_sem; - } else if (invalid_64bit_range(addr, new_len)) { - unsigned long map_flags = 0; - struct file *file = NULL; - - ret = -ENOMEM; - if (!(flags & MREMAP_MAYMOVE)) - goto out_sem; - - vma = find_vma(current->mm, addr); - if (vma) { - if (vma->vm_flags & VM_SHARED) - map_flags |= MAP_SHARED; - file = vma->vm_file; - } - - /* MREMAP_FIXED checked above. */ - new_addr = get_unmapped_area(file, addr, new_len, - vma ? vma->vm_pgoff : 0, - map_flags); - ret = new_addr; - if (new_addr & ~PAGE_MASK) - goto out_sem; - flags |= MREMAP_FIXED; - } ret = do_mremap(addr, old_len, new_len, flags, new_addr); -out_sem: up_write(¤t->mm->mmap_sem); out: return ret; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 161ce4710fe..ba5bd626b39 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -236,13 +236,6 @@ asmlinkage long sys32_getegid16(void) /* 32-bit timeval and related flotsam. */ -static long get_tv32(struct timeval *o, struct compat_timeval __user *i) -{ - return (!access_ok(VERIFY_READ, i, sizeof(*i)) || - (__get_user(o->tv_sec, &i->tv_sec) | - __get_user(o->tv_usec, &i->tv_usec))); -} - static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) { return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || @@ -757,30 +750,6 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } -asmlinkage long sys32_utimes(char __user *filename, - struct compat_timeval __user *tvs) -{ - struct timespec tv[2]; - - if (tvs) { - struct timeval ktvs[2]; - if (get_tv32(&ktvs[0], tvs) || - get_tv32(&ktvs[1], 1+tvs)) - return -EFAULT; - - if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 || - ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000) - return -EINVAL; - - tv[0].tv_sec = ktvs[0].tv_sec; - tv[0].tv_nsec = 1000 * ktvs[0].tv_usec; - tv[1].tv_sec = ktvs[1].tv_sec; - tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; - } - - return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0); -} - /* These are here just in case some old sparc32 binary calls it. */ asmlinkage long sys32_pause(void) { @@ -898,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, u32 __new_addr) { - struct vm_area_struct *vma; unsigned long ret = -EINVAL; unsigned long new_addr = __new_addr; - if (old_len > STACK_TOP32 || new_len > STACK_TOP32) + if (unlikely(sparc64_mmap_check(addr, old_len))) goto out; - if (addr > STACK_TOP32 - old_len) + if (unlikely(sparc64_mmap_check(new_addr, new_len))) goto out; down_write(¤t->mm->mmap_sem); - if (flags & MREMAP_FIXED) { - if (new_addr > STACK_TOP32 - new_len) - goto out_sem; - } else if (addr > STACK_TOP32 - new_len) { - unsigned long map_flags = 0; - struct file *file = NULL; - - ret = -ENOMEM; - if (!(flags & MREMAP_MAYMOVE)) - goto out_sem; - - vma = find_vma(current->mm, addr); - if (vma) { - if (vma->vm_flags & VM_SHARED) - map_flags |= MAP_SHARED; - file = vma->vm_file; - } - - /* MREMAP_FIXED checked above. */ - new_addr = get_unmapped_area(file, addr, new_len, - vma ? vma->vm_pgoff : 0, - map_flags); - ret = new_addr; - if (new_addr & ~PAGE_MASK) - goto out_sem; - flags |= MREMAP_FIXED; - } ret = do_mremap(addr, old_len, new_len, flags, new_addr); -out_sem: up_write(¤t->mm->mmap_sem); out: return ret; diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index a4fef2ba1ae..8b5282d433c 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -45,7 +45,7 @@ sys_call_table32: /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate /*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall - .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64 + .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write /*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 56ff5521134..704a3afcfd0 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -1,4 +1,4 @@ -/* $Id: trampoline.S,v 1.26 2002/02/09 19:49:30 davem Exp $ +/* * trampoline.S: Jump start slave processors on sparc64. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index d9b8d46707d..36974926265 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -2116,7 +2116,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) printk("\n"); #endif do { - struct reg_window *rw; + struct sparc_stackf *sf; struct pt_regs *regs; unsigned long pc; @@ -2124,15 +2124,17 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) if (fp < (thread_base + sizeof(struct thread_info)) || fp >= (thread_base + THREAD_SIZE)) break; - rw = (struct reg_window *)fp; - regs = (struct pt_regs *) (rw + 1); + sf = (struct sparc_stackf *) fp; + regs = (struct pt_regs *) (sf + 1); if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { + if (!(regs->tstate & TSTATE_PRIV)) + break; pc = regs->tpc; fp = regs->u_regs[UREG_I6] + STACK_BIAS; } else { - pc = rw->ins[7]; - fp = rw->ins[6] + STACK_BIAS; + pc = sf->callers_pc; + fp = (unsigned long)sf->fp + STACK_BIAS; } printk(" [%016lx] ", pc); diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index 1a511e9f0d3..afa7fc4f519 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.24 2002/02/09 19:49:31 davem Exp $ +/* * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * diff --git a/arch/sparc64/lib/PeeCeeI.c b/arch/sparc64/lib/PeeCeeI.c index 3c6cfbb2036..8b313f11bc8 100644 --- a/arch/sparc64/lib/PeeCeeI.c +++ b/arch/sparc64/lib/PeeCeeI.c @@ -1,4 +1,4 @@ -/* $Id: PeeCeeI.c,v 1.4 1999/09/06 01:17:35 davem Exp $ +/* * PeeCeeI.c: The emerging standard... * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index a0ded5c5aa5..b320ae9e2e2 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S @@ -1,4 +1,4 @@ -/* $Id: VISsave.S,v 1.6 2002/02/09 19:49:30 davem Exp $ +/* * VISsave.S: Code for saving FPU register state for * VIS routines. One should not call this directly, * but use macros provided in <asm/visasm.h>. diff --git a/arch/sparc64/lib/memcmp.S b/arch/sparc64/lib/memcmp.S index c90ad96c51b..d3fdaa89856 100644 --- a/arch/sparc64/lib/memcmp.S +++ b/arch/sparc64/lib/memcmp.S @@ -1,4 +1,4 @@ -/* $Id: memcmp.S,v 1.3 2000/03/23 07:51:08 davem Exp $ +/* * Sparc64 optimized memcmp code. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc64/lib/memscan.S b/arch/sparc64/lib/memscan.S index 5e72d491141..5686dfa5dc1 100644 --- a/arch/sparc64/lib/memscan.S +++ b/arch/sparc64/lib/memscan.S @@ -1,4 +1,4 @@ -/* $Id: memscan.S,v 1.3 2000/01/31 04:59:10 davem Exp $ +/* * memscan.S: Optimized memscan for Sparc64. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz) diff --git a/arch/sparc64/lib/strncmp.S b/arch/sparc64/lib/strncmp.S index 6f14f53dbab..980e8375155 100644 --- a/arch/sparc64/lib/strncmp.S +++ b/arch/sparc64/lib/strncmp.S @@ -1,4 +1,4 @@ -/* $Id: strncmp.S,v 1.2 1997/03/11 17:51:44 jj Exp $ +/* * Sparc64 optimized strncmp code. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc64/lib/strncpy_from_user.S b/arch/sparc64/lib/strncpy_from_user.S index b2f499f7942..511c8f136f9 100644 --- a/arch/sparc64/lib/strncpy_from_user.S +++ b/arch/sparc64/lib/strncpy_from_user.S @@ -1,4 +1,4 @@ -/* $Id: strncpy_from_user.S,v 1.6 1999/05/25 16:53:05 jj Exp $ +/* * strncpy_from_user.S: Sparc64 strncpy from userspace. * * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) diff --git a/arch/sparc64/math-emu/math.c b/arch/sparc64/math-emu/math.c index 6ee496c2864..add053e0f3b 100644 --- a/arch/sparc64/math-emu/math.c +++ b/arch/sparc64/math-emu/math.c @@ -1,4 +1,4 @@ -/* $Id: math.c,v 1.11 1999/12/20 05:02:25 davem Exp $ +/* * arch/sparc64/math-emu/math.c * * Copyright (C) 1997,1999 Jakub Jelinek (jj@ultra.linux.cz) diff --git a/arch/sparc64/math-emu/sfp-util.h b/arch/sparc64/math-emu/sfp-util.h index 31e474738cf..425d3cf01af 100644 --- a/arch/sparc64/math-emu/sfp-util.h +++ b/arch/sparc64/math-emu/sfp-util.h @@ -1,4 +1,4 @@ -/* $Id: sfp-util.h,v 1.5 2001/06/10 06:48:46 davem Exp $ +/* * arch/sparc64/math-emu/sfp-util.h * * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile index e415bf942bc..68d04c0370f 100644 --- a/arch/sparc64/mm/Makefile +++ b/arch/sparc64/mm/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.8 2000/12/14 22:57:25 davem Exp $ # Makefile for the linux Sparc64-specific parts of the memory manager. # diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 2650d0d33ac..236f4d228d2 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.59 2002/02/09 19:49:31 davem Exp $ +/* * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index af9d81db0b3..f362c203701 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c @@ -1,4 +1,4 @@ -/* $Id: generic.c,v 1.18 2001/12/21 04:56:15 davem Exp $ +/* * generic.c: Generic Sparc mm routines that are not dependent upon * MMU type but are Sparc specific. * diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 4cad0b32b0a..84898c44dd4 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.209 2002/02/09 19:49:31 davem Exp $ +/* * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -610,8 +610,6 @@ static void __init remap_kernel(void) static void __init inherit_prom_mappings(void) { - read_obp_translations(); - /* Now fixup OBP's idea about where we really are mapped. */ printk("Remapping the kernel... "); remap_kernel(); @@ -770,7 +768,10 @@ static void __init find_ramdisk(unsigned long phys_base) initrd_start = ramdisk_image; initrd_end = ramdisk_image + sparc_ramdisk_size; - lmb_reserve(initrd_start, initrd_end); + lmb_reserve(initrd_start, sparc_ramdisk_size); + + initrd_start += PAGE_OFFSET; + initrd_end += PAGE_OFFSET; } #endif } @@ -1744,7 +1745,17 @@ void __init paging_init(void) lmb_init(); - /* Find available physical memory... */ + /* Find available physical memory... + * + * Read it twice in order to work around a bug in openfirmware. + * The call to grab this table itself can cause openfirmware to + * allocate memory, which in turn can take away some space from + * the list of available memory. Reading it twice makes sure + * we really do get the final value. + */ + read_obp_translations(); + read_obp_memory("reg", &pall[0], &pall_ents); + read_obp_memory("available", &pavail[0], &pavail_ents); read_obp_memory("available", &pavail[0], &pavail_ents); phys_base = 0xffffffffffffffffUL; @@ -1785,8 +1796,6 @@ void __init paging_init(void) inherit_prom_mappings(); - read_obp_memory("reg", &pall[0], &pall_ents); - init_kpte_bitmap(); /* Ok, we can use our TLB miss and window trap handlers safely. */ @@ -2362,16 +2371,3 @@ void __flush_tlb_all(void) __asm__ __volatile__("wrpr %0, 0, %%pstate" : : "r" (pstate)); } - -#ifdef CONFIG_MEMORY_HOTPLUG - -void online_page(struct page *page) -{ - ClearPageReserved(page); - init_page_count(page); - __free_page(page); - totalram_pages++; - num_physpages++; -} - -#endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 796e005dad8..9bb2d90a9df 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -1,7 +1,7 @@ -/* $Id: ultra.S,v 1.72 2002/02/09 19:49:31 davem Exp $ +/* * ultra.S: Don't expand these all over the place... * - * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) + * Copyright (C) 1997, 2000, 2008 David S. Miller (davem@davemloft.net) */ #include <asm/asi.h> @@ -15,6 +15,7 @@ #include <asm/thread_info.h> #include <asm/cacheflush.h> #include <asm/hypervisor.h> +#include <asm/cpudata.h> /* Basically, most of the Spitfire vs. Cheetah madness * has to do with the fact that Cheetah does not support @@ -514,6 +515,32 @@ xcall_report_regs: b rtrap_xcall ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 +#ifdef CONFIG_MAGIC_SYSRQ + .globl xcall_fetch_glob_regs +xcall_fetch_glob_regs: + sethi %hi(global_reg_snapshot), %g1 + or %g1, %lo(global_reg_snapshot), %g1 + __GET_CPUID(%g2) + sllx %g2, 6, %g3 + add %g1, %g3, %g1 + rdpr %tstate, %g7 + stx %g7, [%g1 + GR_SNAP_TSTATE] + rdpr %tpc, %g7 + stx %g7, [%g1 + GR_SNAP_TPC] + rdpr %tnpc, %g7 + stx %g7, [%g1 + GR_SNAP_TNPC] + stx %o7, [%g1 + GR_SNAP_O7] + stx %i7, [%g1 + GR_SNAP_I7] + sethi %hi(trap_block), %g7 + or %g7, %lo(trap_block), %g7 + sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2 + add %g7, %g2, %g7 + ldx [%g7 + TRAP_PER_CPU_THREAD], %g3 + membar #StoreStore + stx %g3, [%g1 + GR_SNAP_THREAD] + retry +#endif /* CONFIG_MAGIC_SYSRQ */ + #ifdef DCACHE_ALIASING_POSSIBLE .align 32 .globl xcall_flush_dcache_page_cheetah diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile index 3d33ed27bc2..8c94483ca54 100644 --- a/arch/sparc64/prom/Makefile +++ b/arch/sparc64/prom/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.7 2000/12/14 22:57:25 davem Exp $ # Makefile for the Sun Boot PROM interface library under # Linux. # diff --git a/arch/sparc64/prom/bootstr.c b/arch/sparc64/prom/bootstr.c index a7278614e99..ab9ccc63b38 100644 --- a/arch/sparc64/prom/bootstr.c +++ b/arch/sparc64/prom/bootstr.c @@ -1,4 +1,4 @@ -/* $Id: bootstr.c,v 1.6 1999/08/31 06:55:01 davem Exp $ +/* * bootstr.c: Boot string/argument acquisition from the PROM. * * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/prom/devops.c b/arch/sparc64/prom/devops.c index 4641839eb39..9dbd803e46e 100644 --- a/arch/sparc64/prom/devops.c +++ b/arch/sparc64/prom/devops.c @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.3 1997/10/29 07:43:28 ecd Exp $ +/* * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c index 87e7c7ea0ee..7b00f89490a 100644 --- a/arch/sparc64/prom/init.c +++ b/arch/sparc64/prom/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.10 1999/09/21 14:35:59 davem Exp $ +/* * init.c: Initialize internal variables used by the PROM * library functions. * diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 47a877a15ab..9b0c0760901 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.20 2001/09/21 03:17:07 kanoj Exp $ +/* * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * diff --git a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c index 7fcccc0e19c..4b7c937bba6 100644 --- a/arch/sparc64/prom/p1275.c +++ b/arch/sparc64/prom/p1275.c @@ -1,4 +1,4 @@ -/* $Id: p1275.c,v 1.22 2001/10/18 09:40:00 davem Exp $ +/* * p1275.c: Sun IEEE 1275 PROM low level interface routines * * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index a99ccd7fb1b..281aea44790 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.10 1998/01/10 22:39:00 ecd Exp $ +/* * tree.c: Basic device tree traversal/scanning for the Linux * prom library. * |