From 726c334223180e3c0197cc980a432681370d4baf Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 23 Jun 2006 02:02:58 -0700 Subject: [PATCH] VFS: Permit filesystem to perform statfs with a known root dentry Give the statfs superblock operation a dentry pointer rather than a superblock pointer. This complements the get_sb() patch. That reduced the significance of sb->s_root, allowing NFS to place a fake root there. However, NFS does require a dentry to use as a target for the statfs operation. This permits the root in the vfsmount to be used instead. linux/mount.h has been added where necessary to make allyesconfig build successfully. Interest has also been expressed for use with the FUSE and XFS filesystems. Signed-off-by: David Howells Acked-by: Al Viro Cc: Nathan Scott Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/hpux/sys_hpux.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c index 05273ccced0e..cb69727027ae 100644 --- a/arch/parisc/hpux/sys_hpux.c +++ b/arch/parisc/hpux/sys_hpux.c @@ -145,7 +145,7 @@ static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf) s = user_get_super(dev); if (s == NULL) goto out; - err = vfs_statfs(s, &sbuf); + err = vfs_statfs(s->s_root, &sbuf); drop_super(s); if (err) goto out; @@ -186,12 +186,12 @@ struct hpux_statfs { int16_t f_pad; }; -static int vfs_statfs_hpux(struct super_block *sb, struct hpux_statfs *buf) +static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(sb, &st); + retval = vfs_statfs(dentry, &st); if (retval) return retval; @@ -219,7 +219,7 @@ asmlinkage long hpux_statfs(const char __user *path, error = user_path_walk(path, &nd); if (!error) { struct hpux_statfs tmp; - error = vfs_statfs_hpux(nd.dentry->d_inode->i_sb, &tmp); + error = vfs_statfs_hpux(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_release(&nd); @@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf) file = fget(fd); if (!file) goto out; - error = vfs_statfs_hpux(file->f_dentry->d_inode->i_sb, &tmp); + error = vfs_statfs_hpux(file->f_dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); -- cgit v1.2.1 From d09042da7284a86ffbdd18695f517a71514ed598 Mon Sep 17 00:00:00 2001 From: Laurent MEYER Date: Fri, 23 Jun 2006 02:05:36 -0700 Subject: [PATCH] fix incorrect SA_ONSTACK behaviour for 64-bit processes - When setting a sighandler using sigaction() call, if the flag SA_ONSTACK is set and no alternate stack is provided via sigaltstack(), the kernel still try to install the alternate stack. This behavior is the opposite of the one which is documented in Single Unix Specifications V3. - Also when setting an alternate stack using sigaltstack() with the flag SS_DISABLE, the kernel try to install the alternate stack on signal delivery. These two use cases makes the process crash at signal delivery. Signed-off-by: Laurent Meyer Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: David Howells Cc: Yoshinori Sato Cc: Geert Uytterhoeven Cc: Roman Zippel Cc: Kyle McMartin Cc: Paul Mundt Cc: Kazumoto Kojima Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 05767e83cf2d..cc38edfd90c5 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -248,7 +248,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n", (unsigned long)ka, sp, frame_size); - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) sp = current->sas_ss_sp; /* Stacks grow up! */ DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp); -- cgit v1.2.1 From e31dd6e4520439ceae4753f32dd2da2c345e929a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 12 Jun 2006 17:06:02 -0700 Subject: [PATCH] 64bit resource: change pci core and arch code to use resource_size_t Based on a patch series originally from Vivek Goyal Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/parisc/kernel/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 79c7db2705fd..7d6967ee367c 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * than res->start. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long alignment) + resource_size_t size, resource_size_t alignment) { unsigned long mask, align; -- cgit v1.2.1 From 64f495323c9a902b3e59fe0a588585102bb3b13e Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sat, 22 Apr 2006 00:48:22 -0600 Subject: [PARISC] Ensure all ldcw uses are ldcw,co on pa2.0 ldcw,co should always be used on pa2.0, otherwise the strict cache width alignment requirement is not relaxed. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/entry.S | 6 +++--- arch/parisc/kernel/syscall.S | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index d9e53cf0372b..630730c32a5a 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1638,7 +1638,7 @@ dbit_trap_20w: load32 PA(pa_dbit_lock),t0 dbit_spin_20w: - ldcw 0(t0),t1 + LDCW 0(t0),t1 cmpib,= 0,t1,dbit_spin_20w nop @@ -1674,7 +1674,7 @@ dbit_trap_11: load32 PA(pa_dbit_lock),t0 dbit_spin_11: - ldcw 0(t0),t1 + LDCW 0(t0),t1 cmpib,= 0,t1,dbit_spin_11 nop @@ -1714,7 +1714,7 @@ dbit_trap_20: load32 PA(pa_dbit_lock),t0 dbit_spin_20: - ldcw 0(t0),t1 + LDCW 0(t0),t1 cmpib,= 0,t1,dbit_spin_20 nop diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 479d9a017cd1..a028c990cbff 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -541,7 +541,7 @@ cas_nocontend: # endif /* ENABLE_LWS_DEBUG */ - ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */ + LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ cas_wouldblock: ldo 2(%r0), %r28 /* 2nd case */ -- cgit v1.2.1 From 3fd3a74f45c935f7d6d5c2fb48f06324b18826b7 Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Sat, 22 Apr 2006 14:47:21 -0600 Subject: [PARISC] Use FIXUP_BRANCH_CLOBBER to asm clobber list Joel Soete noticed correctly that the fixup's clobbers must be listed as the ASM clobbers. FIXUP_BRANCH in unaligned.c has a new macro which lists all the clobbers in the fixup, we use this throughout the file to simplify the process of listing clobbers in the future. A missing "r1" clobber is added to our uaccess.h for the 64-bit __put_kernel_asm. Interestingly this is a pretty serious bug since gcc generates pretty good use of r1 as a temporary and the uses of __put_kernel_asm are varied and dangerous if r1 is scratched during an invalid write. Signed-off-by: Joel Soete Signed-off-by: Carlos O'Donell Signed-off-by: Kyle McMartin --- arch/parisc/kernel/unaligned.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index de0a1b21cb40..92328fbddb3e 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -43,6 +43,8 @@ "\tldil L%%" #lbl ", %%r1\n" \ "\tldo R%%" #lbl "(%%r1), %%r1\n" \ "\tbv,n %%r0(%%r1)\n" +/* If you use FIXUP_BRANCH, then you must list this clobber */ +#define FIXUP_BRANCH_CLOBBER "r1" /* 1111 1100 0000 0000 0001 0011 1100 0000 */ #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) @@ -157,7 +159,7 @@ static int emulate_ldh(struct pt_regs *regs, int toreg) " .previous\n" : "=r" (val), "=r" (ret) : "0" (val), "r" (saddr), "r" (regs->isr) - : "r20" ); + : "r20", FIXUP_BRANCH_CLOBBER ); DPRINTF("val = 0x" RFMT "\n", val); @@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) " .previous\n" : "=r" (val), "=r" (ret) : "0" (val), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "r19", "r20", FIXUP_BRANCH_CLOBBER ); DPRINTF("val = 0x" RFMT "\n", val); @@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) " .previous\n" : "=r" (val), "=r" (ret) : "0" (val), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "r19", "r20", FIXUP_BRANCH_CLOBBER ); #else { unsigned long valh=0,vall=0; @@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) " .previous\n" : "=r" (valh), "=r" (vall), "=r" (ret) : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "r19", "r20", FIXUP_BRANCH_CLOBBER ); val=((__u64)valh<<32)|(__u64)vall; } #endif @@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg) " .previous\n" : "=r" (ret) : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19" ); + : "r19", FIXUP_BRANCH_CLOBBER ); return ret; } @@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) " .previous\n" : "=r" (ret) : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1" ); + : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); return 0; } @@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) " .previous\n" : "=r" (ret) : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1" ); + : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); #else { unsigned long valh=(val>>32),vall=(val&0xffffffffl); @@ -495,7 +497,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) " .previous\n" : "=r" (ret) : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r1" ); + : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER ); } #endif -- cgit v1.2.1 From 7514b7a500411faa1c2ff1d5dc3198b855f5cdcc Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 25 May 2006 16:22:30 +0000 Subject: [PARISC] Remove dead function pc_in_user_space This code has been crufting up the file without any use for quite a long time, so let's kill it. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/real2.S | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 8c2859cca77e..453d01a9f971 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -276,15 +276,6 @@ r64_ret: #endif - .export pc_in_user_space - .text - /* Doesn't belong here but I couldn't find a nicer spot. */ - /* Should never get called, only used by profile stuff in time.c */ -pc_in_user_space: - bv,n 0(%rp) - nop - - .export __canonicalize_funcptr_for_compare .text /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html -- cgit v1.2.1 From 8ffaeaf42e91930888df09d696a8a6ebe056d0e0 Mon Sep 17 00:00:00 2001 From: Thibaut Varene Date: Wed, 3 May 2006 17:27:35 -0600 Subject: [PARISC] PDC_CHASSIS is implemented on all machines This patch removes a limitation of the original code, so that CHASSIS codes can be sent to all machines. On machines with a LCD panel, this code displays "INI" during bootup, "RUN" when the system is booted and running, "FLT" when a panic occurs, etc. This part of the code can be enabled/disabled through CONFIG_PDC_CHASSIS This patch also adds minimalistic support for Chassis warnings, through a proc entry '/proc/chassis', which will reflect the warnings status (PSU or fans failure when they happen, NVRAM battery level and temperature thresholds overflows). This part of the code can be enabled/disabled through CONFIG_PDC_CHASSIS_WARN Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- arch/parisc/kernel/firmware.c | 22 +++++++++--- arch/parisc/kernel/pdc_chassis.c | 73 ++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 15 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 2dc06b8e1817..0596f27340cc 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -11,7 +11,7 @@ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) * Copyright 2003 Grant Grundler * Copyright 2003,2004 Ryan Bradetich - * Copyright 2004 Thibaut VARENE + * Copyright 2004,2006 Thibaut VARENE * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -252,10 +252,8 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) #endif /** - * pdc_chassis_disp - Updates display + * pdc_chassis_disp - Updates chassis code * @retval: -1 on error, 0 on success - * - * Works on old PDC only (E class, others?) */ int pdc_chassis_disp(unsigned long disp) { @@ -268,6 +266,22 @@ int pdc_chassis_disp(unsigned long disp) return retval; } +/** + * pdc_chassis_warn - Fetches chassis warnings + * @retval: -1 on error, 0 on success + */ +int pdc_chassis_warn(unsigned long *warn) +{ + int retval = 0; + + spin_lock_irq(&pdc_lock); + retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result)); + *warn = pdc_result[0]; + spin_unlock_irq(&pdc_lock); + + return retval; +} + /** * pdc_coproc_cfg - To identify coprocessors attached to the processor. * @pdc_coproc_info: Return buffer address. diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..51e86c0365c1 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c @@ -1,8 +1,8 @@ /* - * interfaces to log Chassis Codes via PDC (firmware) + * interfaces to Chassis Codes via PDC (firmware) * * Copyright (C) 2002 Laurent Canet - * Copyright (C) 2002-2004 Thibaut VARENE + * Copyright (C) 2002-2006 Thibaut VARENE * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -16,6 +16,9 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * TODO: poll chassis warns, trigger (configurable) machine shutdown when + * needed. */ #undef PDC_CHASSIS_DEBUG @@ -30,6 +33,7 @@ #include #include #include +#include #include #include @@ -38,7 +42,6 @@ #ifdef CONFIG_PDC_CHASSIS -static int pdc_chassis_old __read_mostly = 0; static unsigned int pdc_chassis_enabled __read_mostly = 1; @@ -64,7 +67,7 @@ __setup("pdcchassis=", pdc_chassis_setup); * Currently, only E class and A180 are known to work with this. * Inspired by Christoph Plattner */ - +#if 0 static void __init pdc_chassis_checkold(void) { switch(CPU_HVERSION) { @@ -73,7 +76,6 @@ static void __init pdc_chassis_checkold(void) case 0x482: /* E45 */ case 0x483: /* E55 */ case 0x516: /* A180 */ - pdc_chassis_old = 1; break; default: @@ -81,7 +83,7 @@ static void __init pdc_chassis_checkold(void) } DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); } - +#endif /** * pdc_chassis_panic_event() - Called by the panic handler. @@ -136,14 +138,13 @@ void __init parisc_pdc_chassis_init(void) DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); /* Let see if we have something to handle... */ - /* Check for PDC_PAT or old LED Panel */ - pdc_chassis_checkold(); + /* Check for PDC_PAT */ if (is_pdc_pat()) { printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); handle = 1; } - else if (unlikely(pdc_chassis_old)) { - printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); + else { + printk(KERN_INFO "Enabling regular chassis codes support.\n"); handle = 1; } @@ -215,9 +216,12 @@ int pdc_chassis_send_status(int message) } } else retval = -1; #else - if (unlikely(pdc_chassis_old)) { + if (1) { switch (message) { case PDC_CHASSIS_DIRECT_BSTART: + retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT)); + break; + case PDC_CHASSIS_DIRECT_BCOMPLETE: retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); break; @@ -244,3 +248,50 @@ int pdc_chassis_send_status(int message) #endif /* CONFIG_PDC_CHASSIS */ return retval; } + +#ifdef CONFIG_PDC_CHASSIS_WARN +#ifdef CONFIG_PROC_FS +static int pdc_chassis_warn_pread(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *out = page; + int len, ret; + unsigned long warn; + u32 warnreg; + + ret = pdc_chassis_warn(&warn); + if (ret != PDC_OK) + return -EIO; + + warnreg = (warn & 0xFFFFFFFF); + + if ((warnreg >> 24) & 0xFF) + out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF)); + + out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); + out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); + out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); + + len = out - page - off; + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else { + len = count; + } + *start = page + off; + return len; +} + +static int __init pdc_chassis_create_procfs(void) +{ + printk(KERN_INFO "Enabling PDC chassis warnings support.\n"); + create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, + NULL); + return 0; +} + +__initcall(pdc_chassis_create_procfs); + +#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_PDC_CHASSIS_WARN */ -- cgit v1.2.1 From 9b0703fed7ca1af95d4454f45e2f25733f0afa76 Mon Sep 17 00:00:00 2001 From: Thibaut Varene Date: Thu, 4 May 2006 09:29:32 -0600 Subject: [PARISC] Work around machines which do not support chassis warnings pdc_chassis v0.05: Some machines seems not to implement Chassis warn support. Work around these. Also cleanup a bit of the code. Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pdc_chassis.c | 44 ++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index 51e86c0365c1..d47ba1aa8253 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c @@ -19,6 +19,7 @@ * * TODO: poll chassis warns, trigger (configurable) machine shutdown when * needed. + * Find out how to get Chassis warnings out of PAT boxes? */ #undef PDC_CHASSIS_DEBUG @@ -40,6 +41,7 @@ #include #include +#define PDC_CHASSIS_VER "0.05" #ifdef CONFIG_PDC_CHASSIS static unsigned int pdc_chassis_enabled __read_mostly = 1; @@ -133,29 +135,20 @@ static struct notifier_block pdc_chassis_reboot_block = { void __init parisc_pdc_chassis_init(void) { #ifdef CONFIG_PDC_CHASSIS - int handle = 0; if (likely(pdc_chassis_enabled)) { DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); /* Let see if we have something to handle... */ - /* Check for PDC_PAT */ - if (is_pdc_pat()) { - printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); - handle = 1; - } - else { - printk(KERN_INFO "Enabling regular chassis codes support.\n"); - handle = 1; - } - - if (handle) { - /* initialize panic notifier chain */ - atomic_notifier_chain_register(&panic_notifier_list, - &pdc_chassis_panic_block); - - /* initialize reboot notifier chain */ - register_reboot_notifier(&pdc_chassis_reboot_block); - } + printk(KERN_INFO "Enabling %s chassis codes support v%s\n", + is_pdc_pat() ? "PDC_PAT" : "regular", + PDC_CHASSIS_VER); + + /* initialize panic notifier chain */ + atomic_notifier_chain_register(&panic_notifier_list, + &pdc_chassis_panic_block); + + /* initialize reboot notifier chain */ + register_reboot_notifier(&pdc_chassis_reboot_block); } #endif /* CONFIG_PDC_CHASSIS */ } @@ -285,7 +278,18 @@ static int pdc_chassis_warn_pread(char *page, char **start, off_t off, static int __init pdc_chassis_create_procfs(void) { - printk(KERN_INFO "Enabling PDC chassis warnings support.\n"); + unsigned long test; + int ret; + + ret = pdc_chassis_warn(&test); + if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) { + /* seems that some boxes (eg L1000) do not implement this */ + printk(KERN_INFO "Chassis warnings not supported.\n"); + return 0; + } + + printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n", + PDC_CHASSIS_VER); create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, NULL); return 0; -- cgit v1.2.1 From 3f9edb53f74b4e18f92783da7b6f5ad1d36e05b2 Mon Sep 17 00:00:00 2001 From: Thibaut Varene Date: Thu, 4 May 2006 18:43:34 -0600 Subject: [PARISC] pdc_stable version 0.30 pdc_stable v0.30: This patch introduces 3 more files to the /sys/firmware/stable tree: - diagnostic, which contains a cryptic hex string - osdep1, a 16 bytes os-dependent storage area always available - osdep2, another os-dependent storage area which existence/size depends on hversion. This patch also adds code to setup the "Linux" signature in stable storage. That is to say that starting with this patch, the kernel will now sign its OSID (0x0006, thx LaMont) in Stable Storage upon boot, whether pdc_stable is enabled or not. Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- arch/parisc/kernel/setup.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 4a36ec3f6ac1..8471486a7565 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -303,6 +303,8 @@ extern void eisa_init(void); static int __init parisc_init(void) { + u32 osid = (0x0006 << 16); + parisc_proc_mkdir(); parisc_init_resources(); do_device_inventory(); /* probe for hardware */ @@ -311,6 +313,9 @@ static int __init parisc_init(void) /* set up a new led state on systems shipped LED State panel */ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); + + /* tell PDC we're Linux. Nevermind failure. */ + pdc_stable_write(0x40, &osid, sizeof(osid)); processor_init(); printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", -- cgit v1.2.1 From a3ea84fabacd9cc5bcc3fda67c35e692ca10dc8c Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 16 Jun 2006 19:10:02 +0000 Subject: [PARISC] Add is_compat_task() helper ... And convert signal.c and ptrace.c to use it instead of open coded equivalents. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/ptrace.c | 8 ++++---- arch/parisc/kernel/signal.c | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 413292f1a4a3..3f28de974556 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int copied; #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { unsigned int tmp; addr &= 0xffffffffL; @@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_POKEDATA: ret = 0; #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { unsigned int tmp = (unsigned int)data; DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", request == PTRACE_POKETEXT ? "TEXT" : "DATA", @@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_PEEKUSR: { ret = -EIO; #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { unsigned int tmp; if (addr & (sizeof(int)-1)) @@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) goto out_tsk; } #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { if (addr & (sizeof(int)-1)) goto out_tsk; if ((addr = translate_usr_offset(addr)) < 0) diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index cc38edfd90c5..bb83880c5ee3 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r #ifdef __LP64__ compat_sigset_t newset32; - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; @@ -153,7 +153,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) compat_sigset_t compat_set; struct compat_rt_sigframe __user * compat_frame; - if(personality(current->personality) == PER_LINUX32) + if (is_compat_task()) sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif @@ -166,7 +166,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) #ifdef __LP64__ compat_frame = (struct compat_rt_sigframe __user *)frame; - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) goto give_sigsegv; @@ -186,7 +186,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) /* Good thing we saved the old gr[30], eh? */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", &compat_frame->uc.uc_mcontext); // FIXME: Load upper half from register file @@ -315,7 +315,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, compat_frame = (struct compat_rt_sigframe __user *)frame; - if(personality(current->personality) == PER_LINUX32) { + if (is_compat_task()) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); err |= copy_siginfo_to_user32(&compat_frame->info, info); DBG(1,"SETUP_RT_FRAME: 1\n"); @@ -392,7 +392,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, haddr = A(ka->sa.sa_handler); /* The sa_handler may be a pointer to a function descriptor */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32) { + if (is_compat_task()) { #endif if (haddr & PA_PLABEL_FDESC) { Elf32_Fdesc fdesc; @@ -427,19 +427,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, */ sigframe_size = PARISC_RT_SIGFRAME_SIZE; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32) + if (is_compat_task()) sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif if (in_syscall) { regs->gr[31] = haddr; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX) + if (personality(current->personality) == PER_LINUX) sigframe_size |= 1; #endif } else { unsigned long psw = USER_PSW; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX) + if (personality(current->personality) == PER_LINUX) psw |= PSW_W; #endif @@ -464,7 +464,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gr[26] = sig; /* signal number */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ } else -- cgit v1.2.1 From 667baef53fcd5b839ca8e74ed65811d9df22bd7b Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sat, 17 Jun 2006 17:53:43 +0000 Subject: [PARISC] Remove unused macro fixup_branch in syscall.S Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall.S | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index a028c990cbff..9670a89c77fe 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -29,18 +29,6 @@ .level 1.1 #endif -#ifndef CONFIG_64BIT - .macro fixup_branch,lbl - b \lbl - .endm -#else - .macro fixup_branch,lbl - ldil L%\lbl, %r1 - ldo R%\lbl(%r1), %r1 - bv,n %r0(%r1) - .endm -#endif - .text .import syscall_exit,code -- cgit v1.2.1 From e5a2e7fdb53028ce187c0ce0ae0d45ca7546fd5e Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 14 Jun 2006 20:26:25 +0000 Subject: [PARISC] Match show_cache_info with reality show_cache_info and struct pdc_cache_cf were out of sync with published documentation. Fix the reporting of cache associativity and update the pdc_cache_cf bitfields to match documentation. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index c057ad7605ba..851519cbad6f 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) void show_cache_info(struct seq_file *m) { + char buf[32]; + seq_printf(m, "I-cache\t\t: %ld KB\n", cache_info.ic_size/1024 ); - seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n", + if (cache_info.dc_loop == 1) + snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop); + seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n", cache_info.dc_size/1024, (cache_info.dc_conf.cc_wt ? "WT":"WB"), (cache_info.dc_conf.cc_sh ? ", shared I/D":""), - (cache_info.dc_conf.cc_assoc) - ); - + ((cache_info.dc_loop == 1) ? "direct mapped" : buf)); seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", cache_info.it_size, cache_info.dt_size, @@ -158,11 +160,11 @@ parisc_cache_init(void) cache_info.dc_conf.cc_block, cache_info.dc_conf.cc_line, cache_info.dc_conf.cc_shift); - printk(" wt %d sh %d cst %d assoc %d\n", + printk(" wt %d sh %d cst %d hv %d\n", cache_info.dc_conf.cc_wt, cache_info.dc_conf.cc_sh, cache_info.dc_conf.cc_cst, - cache_info.dc_conf.cc_assoc); + cache_info.dc_conf.cc_hv); printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n", cache_info.ic_base, @@ -176,11 +178,11 @@ parisc_cache_init(void) cache_info.ic_conf.cc_block, cache_info.ic_conf.cc_line, cache_info.ic_conf.cc_shift); - printk(" wt %d sh %d cst %d assoc %d\n", + printk(" wt %d sh %d cst %d hv %d\n", cache_info.ic_conf.cc_wt, cache_info.ic_conf.cc_sh, cache_info.ic_conf.cc_cst, - cache_info.ic_conf.cc_assoc); + cache_info.ic_conf.cc_hv); printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", cache_info.dt_conf.tc_sh, -- cgit v1.2.1 From a9d2d386c42b816a81eb1d02dfb7b502ba8cea82 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 16 Jun 2006 18:20:00 -0400 Subject: [PARISC] Ensure Space ID hashing is turned off Check PDC_CACHE to see if spaceid hashing is turned on, and fail to boot if that is the case. However, some old machines do not implement the PDC_CACHE_RET_SPID firmware call, so continue to boot if the call fails because of PDC_BAD_OPTION (but fail in all other error returns). Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 10 +++++++++- arch/parisc/kernel/firmware.c | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 851519cbad6f..bc7c4a4e26a1 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -236,7 +236,8 @@ parisc_cache_init(void) void disable_sr_hashing(void) { - int srhash_type; + int srhash_type, retval; + unsigned long space_bits; switch (boot_cpu_data.cpu_type) { case pcx: /* We shouldn't get this far. setup.c should prevent it. */ @@ -262,6 +263,13 @@ void disable_sr_hashing(void) } disable_sr_hashing_asm(srhash_type); + + retval = pdc_spaceid_bits(&space_bits); + /* If this procedure isn't implemented, don't panic. */ + if (retval < 0 && retval != PDC_BAD_OPTION) + panic("pdc_spaceid_bits call failed.\n"); + if (space_bits != 0) + panic("SpaceID hashing is still on!\n"); } void flush_dcache_page(struct page *page) diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 0596f27340cc..c80c277454f3 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -512,6 +512,26 @@ int pdc_cache_info(struct pdc_cache_info *cache_info) return retval; } +/** + * pdc_spaceid_bits - Return whether Space ID hashing is turned on. + * @space_bits: Should be 0, if not, bad mojo! + * + * Returns information about Space ID hashing. + */ +int pdc_spaceid_bits(unsigned long *space_bits) +{ + int retval; + + spin_lock_irq(&pdc_lock); + pdc_result[0] = 0; + retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0); + convert_to_wide(pdc_result); + *space_bits = pdc_result[0]; + spin_unlock_irq(&pdc_lock); + + return retval; +} + #ifndef CONFIG_PA20 /** * pdc_btlb_info - Return block TLB information. -- cgit v1.2.1 From ec1fdc24c2ae012b078ba0187ceef208e08a3aec Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 21 Jun 2006 19:27:29 +0000 Subject: [PARISC] OS_ID_LINUX == 0x0006 We were assigned an OS_ID of 0x0006. Consistently use OS_ID_LINUX instead of using the magic number. Also update the OS_ID_ defines in asm/pdc.h to reflect this. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/firmware.c | 4 +++- arch/parisc/kernel/setup.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index c80c277454f3..4398d2a95789 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -407,7 +407,9 @@ int pdc_model_info(struct pdc_model *model) * pdc_model_sysmodel - Get the system model name. * @name: A char array of at least 81 characters. * - * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) + * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L). + * Using OS_ID_HPUX will return the equivalent of the 'modelname' command + * on HP/UX. */ int pdc_model_sysmodel(char *name) { diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 8471486a7565..278f4b9f6a38 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -303,7 +303,7 @@ extern void eisa_init(void); static int __init parisc_init(void) { - u32 osid = (0x0006 << 16); + u32 osid = (OS_ID_LINUX << 16); parisc_proc_mkdir(); parisc_init_resources(); -- cgit v1.2.1 From 1c63b4b8474700f3fb5e3442a78897766f153437 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 21 Jun 2006 16:49:38 +0000 Subject: [PARISC] Refactor show_regs in traps.c show_regs() was one bloaty function. Split it into a few cleaner functions and define a clean macro to print a line of registers. [And from Thibaut, only print fprs on a usermode trap.] Signed-off-by: Kyle McMartin --- arch/parisc/kernel/traps.c | 84 ++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 44 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index ff200608c851..348344a84bf7 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -66,57 +66,42 @@ int printbinary(char *buf, unsigned long x, int nbits) #else #define RFMT "%08lx" #endif +#define FFMT "%016llx" /* fpregs are 64-bit always */ -void show_regs(struct pt_regs *regs) +#define PRINTREGS(lvl,r,f,fmt,x) \ + printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \ + lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \ + (r)[(x)+2], (r)[(x)+3]) + +static void print_gr(char *level, struct pt_regs *regs) { int i; - char buf[128], *p; - char *level; - unsigned long cr30; - unsigned long cr31; - /* carlos says that gcc understands better memory in a struct, - * and it makes our life easier with fpregs -- T-Bone */ - struct { u32 sw[2]; } s; - - level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; - - printk("%s\n", level); /* don't want to have that pretty register dump messed up */ + char buf[64]; + printk("%s\n", level); printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); printbinary(buf, regs->gr[0], 32); printk("%sPSW: %s %s\n", level, buf, print_tainted()); - for (i = 0; i < 32; i += 4) { - int j; - p = buf; - p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3); - for (j = 0; j < 4; j++) { - p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]); - } - printk("%s\n", buf); - } + for (i = 0; i < 32; i += 4) + PRINTREGS(level, regs->gr, "r", RFMT, i); +} - for (i = 0; i < 8; i += 4) { - int j; - p = buf; - p += sprintf(p, "%ssr%d-%d ", level, i, i + 3); - for (j = 0; j < 4; j++) { - p += sprintf(p, " " RFMT, regs->sr[i + j]); - } - printk("%s\n", buf); - } +static void print_fr(char *level, struct pt_regs *regs) +{ + int i; + char buf[64]; + struct { u32 sw[2]; } s; /* FR are 64bit everywhere. Need to use asm to get the content * of fpsr/fper1, and we assume that we won't have a FP Identify * in our way, otherwise we're screwed. * The fldd is used to restore the T-bit if there was one, as the * store clears it anyway. - * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */ - __asm__ ( - "fstd %%fr0,0(%1) \n\t" - "fldd 0(%1),%%fr0 \n\t" - : "=m" (s) : "r" (&s) : "%r0" - ); + * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */ + asm volatile ("fstd %%fr0,0(%1) \n\t" + "fldd 0(%1),%%fr0 \n\t" + : "=m" (s) : "r" (&s) : "r0"); printk("%s\n", level); printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); @@ -125,14 +110,25 @@ void show_regs(struct pt_regs *regs) printk("%sFPER1: %08x\n", level, s.sw[1]); /* here we'll print fr0 again, tho it'll be meaningless */ - for (i = 0; i < 32; i += 4) { - int j; - p = buf; - p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3); - for (j = 0; j < 4; j++) - p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]); - printk("%s\n", buf); - } + for (i = 0; i < 32; i += 4) + PRINTREGS(level, regs->fr, "fr", FFMT, i); +} + +void show_regs(struct pt_regs *regs) +{ + int i; + char *level; + unsigned long cr30, cr31; + + level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; + + print_gr(level, regs); + + for (i = 0; i < 8; i += 4) + PRINTREGS(level, regs->sr, "sr", RFMT, i); + + if (user_mode(regs)) + print_fr(level, regs); cr30 = mfctl(30); cr31 = mfctl(31); -- cgit v1.2.1 From 6e1b9585aaae2fa4f9590f363b32c5d3b6339ba6 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 23 Jun 2006 14:15:20 -0600 Subject: [PARISC] Fix PCREL22F relocation problem for most modules The new problem, which has been affecting many more modules was that our new ioremap really takes chunks out of our vmalloc space. The net result being that any two kernel vmalloc's now have to slot into the chunked up space. So the vmallocs for a modules init and core sectons are no longer necessarily contiguous. Unfortunately, the module loader thinks that any internal symbol references should be satisfiable using the jump instruction, which isn't true if the symbol is referenced from init to core and vmalloc placed them a long way apart. Fix this by introducing a new stub type for intra module inter sectional jumps and using it. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- arch/parisc/kernel/module.c | 63 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 13 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index f27cfe4771b8..aee311884f3f 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -89,6 +89,12 @@ static inline int is_local(struct module *me, void *loc) return is_init(me, loc) || is_core(me, loc); } +static inline int is_local_section(struct module *me, void *loc, void *dot) +{ + return (is_init(me, loc) && is_init(me, dot)) || + (is_core(me, loc) && is_core(me, dot)); +} + #ifndef __LP64__ struct got_entry { @@ -364,8 +370,14 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) } #endif /* __LP64__ */ +enum elf_stub_type { + ELF_STUB_GOT, + ELF_STUB_MILLI, + ELF_STUB_DIRECT, +}; + static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, - int millicode, int init_section) + enum elf_stub_type stub_type, int init_section) { unsigned long i; struct stub_entry *stub; @@ -396,7 +408,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); #else -/* for 64-bit we have two kinds of stubs: +/* for 64-bit we have three kinds of stubs: * for normal function calls: * ldd 0(%dp),%dp * ldd 10(%dp), %r1 @@ -408,18 +420,23 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, * ldo 0(%r1), %r1 * ldd 10(%r1), %r1 * bve,n (%r1) + * + * for direct branches (jumps between different section of the + * same module): + * ldil 0, %r1 + * ldo 0(%r1), %r1 + * bve,n (%r1) */ - if (!millicode) - { + switch (stub_type) { + case ELF_STUB_GOT: stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ stub->insns[2] = 0xe820d000; /* bve (%r1) */ stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); - } - else - { + break; + case ELF_STUB_MILLI: stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ @@ -427,7 +444,17 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[0] |= reassemble_21(lrsel(value, addend)); stub->insns[1] |= reassemble_14(rrsel(value, addend)); + break; + case ELF_STUB_DIRECT: + stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ + stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ + stub->insns[2] = 0xe820d002; /* bve,n (%r1) */ + + stub->insns[0] |= reassemble_21(lrsel(value, addend)); + stub->insns[1] |= reassemble_14(rrsel(value, addend)); + break; } + #endif return (Elf_Addr)stub; @@ -539,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - val = get_stub(me, val, addend, 0, is_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); val = (val - dot - 8)/4; CHECK_RELOC(val, 17) *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: /* 22-bit PC relative address; only defined for pa20 */ - val = get_stub(me, val, addend, 0, is_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", strtab + sym->st_name, (unsigned long)loc, addend, val) @@ -643,13 +670,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs, strtab + sym->st_name, loc, val); /* can we reach it locally? */ - if(!is_local(me, (void *)val)) { - if (strncmp(strtab + sym->st_name, "$$", 2) + if(!is_local_section(me, (void *)val, (void *)dot)) { + + if (is_local(me, (void *)val)) + /* this is the case where the + * symbol is local to the + * module, but in a different + * section, so stub the jump + * in case it's more than 22 + * bits away */ + val = get_stub(me, val, addend, ELF_STUB_DIRECT, + is_init(me, loc)); + else if (strncmp(strtab + sym->st_name, "$$", 2) == 0) - val = get_stub(me, val, addend, 1, + val = get_stub(me, val, addend, ELF_STUB_MILLI, is_init(me, loc)); else - val = get_stub(me, val, addend, 0, + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); } DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", -- cgit v1.2.1 From 61c340166d8c62086b6de00afc7670eea27eb2ab Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 24 Jun 2006 16:05:18 +0000 Subject: [PARISC] Fix do_gettimeofday() hang Apparently gettimeoffset can return small negative values (usually in the 100us range). If xtime.tv_nsec is accidentally less than this, though (a fortunately unlikely event) it triggers the loop forever. I've added a test and correct adjustment for this case. It has a warning printk in there which I'd like to leave for the time being just in case this problem implicates some other part of the kernel. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- arch/parisc/kernel/time.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 594930bc4bcf..eb35e1c0bb53 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv) usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - while (usec >= 1000000) { - usec -= 1000000; + if (unlikely(usec > LONG_MAX)) { + /* This can happen if the gettimeoffset adjustment is + * negative and xtime.tv_nsec is smaller than the + * adjustment */ + printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec); + usec += USEC_PER_SEC; + --sec; + /* This should never happen, it means the negative + * time adjustment was more than a second, so there's + * something seriously wrong */ + BUG_ON(usec > LONG_MAX); + } + + + while (usec >= USEC_PER_SEC) { + usec -= USEC_PER_SEC; ++sec; } -- cgit v1.2.1 From 76b67ed9dce69a6a329cdd66f94af1787f417b62 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Tue, 27 Jun 2006 02:53:41 -0700 Subject: [PATCH] node hotplug: register cpu: remove node struct With Goto-san's patch, we can add new pgdat/node at runtime. I'm now considering node-hot-add with cpu + memory on ACPI. I found acpi container, which describes node, could evaluate cpu before memory. This means cpu-hot-add occurs before memory hot add. In most part, cpu-hot-add doesn't depend on node hot add. But register_cpu(), which creates symbolic link from node to cpu, requires that node should be onlined before register_cpu(). When a node is onlined, its pgdat should be there. This patch-set holds off creating symbolic link from node to cpu until node is onlined. This removes node arguments from register_cpu(). Now, register_cpu() requires 'struct node' as its argument. But the array of struct node is now unified in driver/base/node.c now (By Goto's node hotplug patch). We can get struct node in generic way. So, this argument is not necessary now. This patch also guarantees add cpu under node only when node is onlined. It is necessary for node-hot-add vs. cpu-hot-add patch following this. Moreover, register_cpu calculates cpu->node_id by cpu_to_node() without regard to its 'struct node *root' argument. This patch removes it. Also modify callers of register_cpu()/unregister_cpu, whose args are changed by register-cpu-remove-node-struct patch. [Brice.Goglin@ens-lyon.org: fix it] Signed-off-by: KAMEZAWA Hiroyuki Cc: Yasunori Goto Cc: Ashok Raj Cc: Dave Hansen Signed-off-by: Brice Goglin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/kernel/topology.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c index 3ba040050e4c..068b20d822e7 100644 --- a/arch/parisc/kernel/topology.c +++ b/arch/parisc/kernel/topology.c @@ -26,11 +26,10 @@ static struct cpu cpu_devices[NR_CPUS] __read_mostly; static int __init topology_init(void) { - struct node *parent = NULL; int num; for_each_present_cpu(num) { - register_cpu(&cpu_devices[num], num, parent); + register_cpu(&cpu_devices[num], num); } return 0; } -- cgit v1.2.1 From d1bef4ed5faf7d9872337b33c4269e45ae1bf960 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 29 Jun 2006 02:24:36 -0700 Subject: [PATCH] genirq: rename desc->handler to desc->chip This patch-queue improves the generic IRQ layer to be truly generic, by adding various abstractions and features to it, without impacting existing functionality. While the queue can be best described as "fix and improve everything in the generic IRQ layer that we could think of", and thus it consists of many smaller features and lots of cleanups, the one feature that stands out most is the new 'irq chip' abstraction. The irq-chip abstraction is about describing and coding and IRQ controller driver by mapping its raw hardware capabilities [and quirks, if needed] in a straightforward way, without having to think about "IRQ flow" (level/edge/etc.) type of details. This stands in contrast with the current 'irq-type' model of genirq architectures, which 'mixes' raw hardware capabilities with 'flow' details. The patchset supports both types of irq controller designs at once, and converts i386 and x86_64 to the new irq-chip design. As a bonus side-effect of the irq-chip approach, chained interrupt controllers (master/slave PIC constructs, etc.) are now supported by design as well. The end result of this patchset intends to be simpler architecture-level code and more consolidation between architectures. We reused many bits of code and many concepts from Russell King's ARM IRQ layer, the merging of which was one of the motivations for this patchset. This patch: rename desc->handler to desc->chip. Originally i did not want to do this, because it's a big patch. But having both "desc->handler", "desc->handle_irq" and "action->handler" caused a large degree of confusion and made the code appear alot less clean than it truly is. I have also attempted a dual approach as well by introducing a desc->chip alias - but that just wasnt robust enough and broke frequently. So lets get over with this quickly. The conversion was done automatically via scripts and converts all the code in the kernel. This renaming patch is the first one amongst the patches, so that the remaining patches can stay flexible and can be merged and split up without having some big monolithic patch act as a merge barrier. [akpm@osdl.org: build fix] [akpm@osdl.org: another build fix] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/kernel/irq.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 197936d9359a..26e69f73fdb0 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -158,7 +158,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_irqs(i)); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); #ifndef PARISC_IRQ_CR16_COUNTS seq_printf(p, " %s", action->name); @@ -210,12 +210,12 @@ int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data) { if (irq_desc[irq].action) return -EBUSY; - if (irq_desc[irq].handler != &cpu_interrupt_type) + if (irq_desc[irq].chip != &cpu_interrupt_type) return -EBUSY; if (type) { - irq_desc[irq].handler = type; - irq_desc[irq].handler_data = data; + irq_desc[irq].chip = type; + irq_desc[irq].chip_data = data; cpu_interrupt_type.enable(irq); } return 0; @@ -378,7 +378,7 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - irq_desc[i].handler = &cpu_interrupt_type; + irq_desc[i].chip = &cpu_interrupt_type; } irq_desc[TIMER_IRQ].action = &timer_action; -- cgit v1.2.1 From a53da52fd743fd637637572838c0a7af23a2d038 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 29 Jun 2006 02:24:38 -0700 Subject: [PATCH] genirq: cleanup: merge irq_affinity[] into irq_desc[] Consolidation: remove the irq_affinity[NR_IRQS] array and move it into the irq_desc[NR_IRQS].affinity field. [akpm@osdl.org: sparc64 build fix] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/kernel/irq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 26e69f73fdb0..ea6a55e1a0c5 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -94,7 +94,7 @@ int cpu_check_affinity(unsigned int irq, cpumask_t *dest) if (irq == TIMER_IRQ || irq == IPI_IRQ) { /* Bad linux design decision. The mask has already * been set; we must reset it */ - irq_affinity[irq] = CPU_MASK_ALL; + irq_desc[irq].affinity = CPU_MASK_ALL; return -EINVAL; } @@ -110,7 +110,7 @@ static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest) if (cpu_check_affinity(irq, &dest)) return; - irq_affinity[irq] = dest; + irq_desc[irq].affinity = dest; } #endif @@ -265,7 +265,7 @@ int txn_alloc_irq(unsigned int bits_wide) unsigned long txn_affinity_addr(unsigned int irq, int cpu) { #ifdef CONFIG_SMP - irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].affinity = cpumask_of_cpu(cpu); #endif return cpu_data[cpu].txn_addr; @@ -326,7 +326,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) /* Work our way from MSb to LSb...same order we alloc EIRs */ for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { #ifdef CONFIG_SMP - cpumask_t dest = irq_affinity[irq]; + cpumask_t dest = irq_desc[irq].affinity; #endif if (!(bit & eirr_val)) continue; -- cgit v1.2.1 From 0d7012a968d006e277eb0fe20edd7a9b5563c2b7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 29 Jun 2006 02:24:43 -0700 Subject: [PATCH] genirq: cleanup: turn ARCH_HAS_IRQ_PER_CPU into CONFIG_IRQ_PER_CPU Cleanup: change ARCH_HAS_IRQ_PER_CPU into a Kconfig method. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/parisc') diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 910fb3afc0b5..6dd0ea8f88e0 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -51,6 +51,10 @@ config GENERIC_HARDIRQS config GENERIC_IRQ_PROBE def_bool y +config IRQ_PER_CPU + bool + default y + # unless you want to implement ACPI on PA-RISC ... ;-) config PM bool -- cgit v1.2.1 From c0ad90a32fb60f4129d0e24dfd5fd7128e2e09f2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 29 Jun 2006 02:24:44 -0700 Subject: [PATCH] genirq: add ->retrigger() irq op to consolidate hw_irq_resend() Add ->retrigger() irq op to consolidate hw_irq_resend() implementations. (Most architectures had it defined to NOP anyway.) NOTE: ia64 needs testing. i386 and x86_64 tested. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/kernel/irq.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'arch/parisc') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index ea6a55e1a0c5..82fe6ba29727 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -125,6 +125,10 @@ static struct hw_interrupt_type cpu_interrupt_type = { #ifdef CONFIG_SMP .set_affinity = cpu_set_affinity_irq, #endif + /* XXX: Needs to be written. We managed without it so far, but + * we really ought to write it. + */ + .retrigger = NULL, }; int show_interrupts(struct seq_file *p, void *v) @@ -404,13 +408,6 @@ void __init init_IRQ(void) } -void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq) -{ - /* XXX: Needs to be written. We managed without it so far, but - * we really ought to write it. - */ -} - void ack_bad_irq(unsigned int irq) { printk("unexpected IRQ %d\n", irq); -- cgit v1.2.1