From 3f22ab276b931b72ea04b184c155b34d0362bfc3 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 23 Jun 2005 00:07:43 -0700 Subject: [PATCH] make each arch use mm/Kconfig For all architectures, this just means that you'll see a "Memory Model" choice in your architecture menu. For those that implement DISCONTIGMEM, you may eventually want to make your ARCH_DISCONTIGMEM_ENABLE a "def_bool y" and make your users select DISCONTIGMEM right out of the new choice menu. The only disadvantage might be if you have some specific things that you need in your help option to explain something about DISCONTIGMEM. Signed-off-by: Dave Hansen Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sparc64') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index a72fd15d5ea..e2b050eb3b9 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -484,6 +484,8 @@ config CMDLINE NOTE: This option WILL override the PROM bootargs setting! +source "mm/Kconfig" + endmenu source "drivers/base/Kconfig" -- cgit v1.2.3-70-g09d2 From 7e1048b11c5afe79aac46a42e3ccec86b8365c6d Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Thu, 23 Jun 2005 00:09:25 -0700 Subject: [PATCH] Move kprobe [dis]arming into arch specific code The architecture independent code of the current kprobes implementation is arming and disarming kprobes at registration time. The problem is that the code is assuming that arming and disarming is a just done by a simple write of some magic value to an address. This is problematic for ia64 where our instructions look more like structures, and we can not insert break points by just doing something like: *p->addr = BREAKPOINT_INSTRUCTION; The following patch to 2.6.12-rc4-mm2 adds two new architecture dependent functions: * void arch_arm_kprobe(struct kprobe *p) * void arch_disarm_kprobe(struct kprobe *p) and then adds the new functions for each of the architectures that already implement kprobes (spar64/ppc64/i386/x86_64). I thought arch_[dis]arm_kprobe was the most descriptive of what was really happening, but each of the architectures already had a disarm_kprobe() function that was really a "disarm and do some other clean-up items as needed when you stumble across a recursive kprobe." So... I took the liberty of changing the code that was calling disarm_kprobe() to call arch_disarm_kprobe(), and then do the cleanup in the block of code dealing with the recursive kprobe case. So far this patch as been tested on i386, x86_64, and ppc64, but still needs to be tested in sparc64. Signed-off-by: Rusty Lynch Signed-off-by: Anil S Keshavamurthy Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 19 +++++++++++++++---- arch/ppc64/kernel/kprobes.c | 19 +++++++++++++++---- arch/sparc64/kernel/kprobes.c | 31 ++++++++++++++++++------------- arch/x86_64/kernel/kprobes.c | 26 ++++++++++++++++++-------- include/linux/kprobes.h | 2 ++ kernel/kprobes.c | 12 ++++-------- 6 files changed, 72 insertions(+), 37 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 048f754bbe2..2314d8d306f 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -71,16 +72,25 @@ int arch_prepare_kprobe(struct kprobe *p) void arch_copy_kprobe(struct kprobe *p) { memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + p->opcode = *p->addr; } -void arch_remove_kprobe(struct kprobe *p) +void arch_arm_kprobe(struct kprobe *p) { + *p->addr = BREAKPOINT_INSTRUCTION; + flush_icache_range((unsigned long) p->addr, + (unsigned long) p->addr + sizeof(kprobe_opcode_t)); } -static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) +void arch_disarm_kprobe(struct kprobe *p) { *p->addr = p->opcode; - regs->eip = (unsigned long)p->addr; + flush_icache_range((unsigned long) p->addr, + (unsigned long) p->addr + sizeof(kprobe_opcode_t)); +} + +void arch_remove_kprobe(struct kprobe *p) +{ } static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) @@ -177,7 +187,8 @@ static int kprobe_handler(struct pt_regs *regs) unlock_kprobes(); goto no_kprobe; } - disarm_kprobe(p, regs); + arch_disarm_kprobe(p); + regs->eip = (unsigned long)p->addr; ret = 1; } else { p = current_kprobe; diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index e950a2058a1..8c0920a6d03 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -61,16 +62,25 @@ int arch_prepare_kprobe(struct kprobe *p) void arch_copy_kprobe(struct kprobe *p) { memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + p->opcode = *p->addr; } -void arch_remove_kprobe(struct kprobe *p) +void arch_arm_kprobe(struct kprobe *p) { + *p->addr = BREAKPOINT_INSTRUCTION; + flush_icache_range((unsigned long) p->addr, + (unsigned long) p->addr + sizeof(kprobe_opcode_t)); } -static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) +void arch_disarm_kprobe(struct kprobe *p) { *p->addr = p->opcode; - regs->nip = (unsigned long)p->addr; + flush_icache_range((unsigned long) p->addr, + (unsigned long) p->addr + sizeof(kprobe_opcode_t)); +} + +void arch_remove_kprobe(struct kprobe *p) +{ } static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) @@ -101,7 +111,8 @@ static inline int kprobe_handler(struct pt_regs *regs) unlock_kprobes(); goto no_kprobe; } - disarm_kprobe(p, regs); + arch_disarm_kprobe(p); + regs->nip = (unsigned long)p->addr; ret = 1; } else { p = current_kprobe; diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 7066d7ba667..d67195ba3fa 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -6,7 +6,6 @@ #include #include #include - #include #include @@ -47,6 +46,19 @@ void arch_copy_kprobe(struct kprobe *p) { p->ainsn.insn[0] = *p->addr; p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; + p->opcode = *p->addr; +} + +void arch_arm_kprobe(struct kprobe *p) +{ + *p->addr = BREAKPOINT_INSTRUCTION; + flushi(p->addr); +} + +void arch_disarm_kprobe(struct kprobe *p) +{ + *p->addr = p->opcode; + flushi(p->addr); } void arch_remove_kprobe(struct kprobe *p) @@ -78,17 +90,6 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) } } -static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) -{ - *p->addr = p->opcode; - flushi(p->addr); - - regs->tpc = (unsigned long) p->addr; - regs->tnpc = current_kprobe_orig_tnpc; - regs->tstate = ((regs->tstate & ~TSTATE_PIL) | - current_kprobe_orig_tstate_pil); -} - static int kprobe_handler(struct pt_regs *regs) { struct kprobe *p; @@ -109,7 +110,11 @@ static int kprobe_handler(struct pt_regs *regs) unlock_kprobes(); goto no_kprobe; } - disarm_kprobe(p, regs); + arch_disarm_kprobe(p); + regs->tpc = (unsigned long) p->addr; + regs->tnpc = current_kprobe_orig_tnpc; + regs->tstate = ((regs->tstate & ~TSTATE_PIL) | + current_kprobe_orig_tstate_pil); ret = 1; } else { p = current_kprobe; diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 203672ca740..324bf57925a 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -39,7 +39,7 @@ #include #include #include - +#include #include #include @@ -216,19 +216,28 @@ void arch_copy_kprobe(struct kprobe *p) BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ *ripdisp = disp; } + p->opcode = *p->addr; } -void arch_remove_kprobe(struct kprobe *p) +void arch_arm_kprobe(struct kprobe *p) { - up(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); - down(&kprobe_mutex); + *p->addr = BREAKPOINT_INSTRUCTION; + flush_icache_range((unsigned long) p->addr, + (unsigned long) p->addr + sizeof(kprobe_opcode_t)); } -static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) +void arch_disarm_kprobe(struct kprobe *p) { *p->addr = p->opcode; - regs->rip = (unsigned long)p->addr; + flush_icache_range((unsigned long) p->addr, + (unsigned long) p->addr + sizeof(kprobe_opcode_t)); +} + +void arch_remove_kprobe(struct kprobe *p) +{ + up(&kprobe_mutex); + free_insn_slot(p->ainsn.insn); + down(&kprobe_mutex); } static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) @@ -311,7 +320,8 @@ int kprobe_handler(struct pt_regs *regs) unlock_kprobes(); goto no_kprobe; } - disarm_kprobe(p, regs); + arch_disarm_kprobe(p); + regs->rip = (unsigned long)p->addr; ret = 1; } else { p = current_kprobe; diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index fba39f87efe..0f90466fb8b 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -165,6 +165,8 @@ static inline int kprobe_running(void) extern int arch_prepare_kprobe(struct kprobe *p); extern void arch_copy_kprobe(struct kprobe *p); +extern void arch_arm_kprobe(struct kprobe *p); +extern void arch_disarm_kprobe(struct kprobe *p); extern void arch_remove_kprobe(struct kprobe *p); extern void show_registers(struct pt_regs *regs); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 692fbf75ab4..e8e0ae8a6e1 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -261,7 +261,7 @@ static inline void free_rp_inst(struct kretprobe *rp) static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p) { ap->addr = p->addr; - ap->opcode = p->opcode; + memcpy(&ap->opcode, &p->opcode, sizeof(kprobe_opcode_t)); memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn)); ap->pre_handler = aggr_pre_handler; @@ -304,10 +304,8 @@ static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p) /* kprobe removal house-keeping routines */ static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags) { - *p->addr = p->opcode; + arch_disarm_kprobe(p); hlist_del(&p->hlist); - flush_icache_range((unsigned long) p->addr, - (unsigned long) p->addr + sizeof(kprobe_opcode_t)); spin_unlock_irqrestore(&kprobe_lock, flags); arch_remove_kprobe(p); } @@ -344,10 +342,8 @@ int register_kprobe(struct kprobe *p) hlist_add_head(&p->hlist, &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); - p->opcode = *p->addr; - *p->addr = BREAKPOINT_INSTRUCTION; - flush_icache_range((unsigned long) p->addr, - (unsigned long) p->addr + sizeof(kprobe_opcode_t)); + arch_arm_kprobe(p); + out: spin_unlock_irqrestore(&kprobe_lock, flags); rm_kprobe: -- cgit v1.2.3-70-g09d2 From e539c2331414e73a5a1b79fb57369d79447c1cf8 Mon Sep 17 00:00:00 2001 From: Prasanna S Panchamukhi Date: Thu, 23 Jun 2005 00:09:39 -0700 Subject: [PATCH] kprobes: Temporary disarming of reentrant probe for sparc64 This patch includes sparc64 architecture specific changes to support temporary disarming on reentrancy of probes. Signed-of-by: Prasanna S Panchamukhi Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/kprobes.c | 62 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index d67195ba3fa..bdac631cf01 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -65,19 +65,40 @@ void arch_remove_kprobe(struct kprobe *p) { } -/* kprobe_status settings */ -#define KPROBE_HIT_ACTIVE 0x00000001 -#define KPROBE_HIT_SS 0x00000002 - static struct kprobe *current_kprobe; static unsigned long current_kprobe_orig_tnpc; static unsigned long current_kprobe_orig_tstate_pil; static unsigned int kprobe_status; +static struct kprobe *kprobe_prev; +static unsigned long kprobe_orig_tnpc_prev; +static unsigned long kprobe_orig_tstate_pil_prev; +static unsigned int kprobe_status_prev; -static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) +static inline void save_previous_kprobe(void) +{ + kprobe_status_prev = kprobe_status; + kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc; + kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil; + kprobe_prev = current_kprobe; +} + +static inline void restore_previous_kprobe(void) +{ + kprobe_status = kprobe_status_prev; + current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev; + current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev; + current_kprobe = kprobe_prev; +} + +static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs) { current_kprobe_orig_tnpc = regs->tnpc; current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); + current_kprobe = p; +} + +static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) +{ regs->tstate |= TSTATE_PIL; /*single step inline, if it a breakpoint instruction*/ @@ -110,12 +131,18 @@ static int kprobe_handler(struct pt_regs *regs) unlock_kprobes(); goto no_kprobe; } - arch_disarm_kprobe(p); - regs->tpc = (unsigned long) p->addr; - regs->tnpc = current_kprobe_orig_tnpc; - regs->tstate = ((regs->tstate & ~TSTATE_PIL) | - current_kprobe_orig_tstate_pil); - ret = 1; + /* We have reentered the kprobe_handler(), since + * another probe was hit while within the handler. + * We here save the original kprobes variables and + * just single step on the instruction of the new probe + * without calling any user handlers. + */ + save_previous_kprobe(); + set_current_kprobe(p, regs); + p->nmissed++; + kprobe_status = KPROBE_REENTER; + prepare_singlestep(p, regs); + return 1; } else { p = current_kprobe; if (p->break_handler && p->break_handler(p, regs)) @@ -143,8 +170,8 @@ static int kprobe_handler(struct pt_regs *regs) goto no_kprobe; } + set_current_kprobe(p, regs); kprobe_status = KPROBE_HIT_ACTIVE; - current_kprobe = p; if (p->pre_handler && p->pre_handler(p, regs)) return 1; @@ -250,12 +277,20 @@ static inline int post_kprobe_handler(struct pt_regs *regs) if (!kprobe_running()) return 0; - if (current_kprobe->post_handler) + if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { + kprobe_status = KPROBE_HIT_SSDONE; current_kprobe->post_handler(current_kprobe, regs, 0); + } resume_execution(current_kprobe, regs); + /*Restore back the original saved kprobes variables and continue. */ + if (kprobe_status == KPROBE_REENTER) { + restore_previous_kprobe(); + goto out; + } unlock_kprobes(); +out: preempt_enable_no_resched(); return 1; @@ -397,3 +432,4 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) } return 0; } + -- cgit v1.2.3-70-g09d2 From 0d77e5a2c23da734f5a7925f64afa1c2ed92e0f9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 23 Jun 2005 00:10:14 -0700 Subject: [PATCH] compat: introduce compat_time_t This patch is based on work by Carlos O'Donell and Matthew Wilcox. It introduces/updates the compat_time_t type and uses it for compat siginfo structures. I have built this on ppc64 and x86_64. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/ia32/ia32priv.h | 2 +- arch/s390/kernel/compat_linux.h | 2 +- arch/sparc64/kernel/signal32.c | 2 +- include/asm-ia64/compat.h | 1 + include/asm-mips/compat.h | 1 + include/asm-parisc/compat.h | 2 +- include/asm-ppc64/compat.h | 1 + include/asm-ppc64/ppc32.h | 2 +- include/asm-sparc64/compat.h | 1 + include/asm-x86_64/ia32.h | 2 +- 10 files changed, 10 insertions(+), 6 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h index b2de948bdae..e3e9290e3ff 100644 --- a/arch/ia64/ia32/ia32priv.h +++ b/arch/ia64/ia32/ia32priv.h @@ -241,7 +241,7 @@ typedef struct compat_siginfo { /* POSIX.1b timers */ struct { - timer_t _tid; /* timer id */ + compat_timer_t _tid; /* timer id */ int _overrun; /* overrun count */ char _pad[sizeof(unsigned int) - sizeof(int)]; compat_sigval_t _sigval; /* same as below */ diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index bf33dcfec7d..3898f66d0b2 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -45,7 +45,7 @@ typedef struct compat_siginfo { /* POSIX.1b timers */ struct { - timer_t _tid; /* timer id */ + compat_timer_t _tid; /* timer id */ int _overrun; /* overrun count */ compat_sigval_t _sigval; /* same as below */ int _sys_private; /* not to be passed to user */ diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 9a375e975cf..f28428f4170 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -102,7 +102,7 @@ typedef struct compat_siginfo{ /* POSIX.1b timers */ struct { - timer_t _tid; /* timer id */ + compat_timer_t _tid; /* timer id */ int _overrun; /* overrun count */ compat_sigval_t _sigval; /* same as below */ int _sys_private; /* not to be passed to user */ diff --git a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h index cc0ff0a4bdd..0c05e5bad8a 100644 --- a/include/asm-ia64/compat.h +++ b/include/asm-ia64/compat.h @@ -27,6 +27,7 @@ typedef u16 compat_ipc_pid_t; typedef s32 compat_daddr_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; +typedef s32 compat_timer_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h index dce92079e7f..d78002afb1e 100644 --- a/include/asm-mips/compat.h +++ b/include/asm-mips/compat.h @@ -29,6 +29,7 @@ typedef s32 compat_caddr_t; typedef struct { s32 val[2]; } compat_fsid_t; +typedef s32 compat_timer_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h index ca0eac647a0..7630d1ad239 100644 --- a/include/asm-parisc/compat.h +++ b/include/asm-parisc/compat.h @@ -24,7 +24,7 @@ typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef s32 compat_daddr_t; typedef u32 compat_caddr_t; -typedef u32 compat_timer_t; +typedef s32 compat_timer_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h index 09c28d28ce6..12414f5fc66 100644 --- a/include/asm-ppc64/compat.h +++ b/include/asm-ppc64/compat.h @@ -26,6 +26,7 @@ typedef s32 compat_daddr_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; typedef s32 compat_key_t; +typedef s32 compat_timer_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h index 1d040489755..6b44a8caf39 100644 --- a/include/asm-ppc64/ppc32.h +++ b/include/asm-ppc64/ppc32.h @@ -32,7 +32,7 @@ typedef struct compat_siginfo { /* POSIX.1b timers */ struct { - timer_t _tid; /* timer id */ + compat_timer_t _tid; /* timer id */ int _overrun; /* overrun count */ compat_sigval_t _sigval; /* same as below */ int _sys_private; /* not to be passed to user */ diff --git a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h index 22f58055b8a..b59122dd176 100644 --- a/include/asm-sparc64/compat.h +++ b/include/asm-sparc64/compat.h @@ -25,6 +25,7 @@ typedef s32 compat_daddr_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; typedef s32 compat_key_t; +typedef s32 compat_timer_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h index c0a7717923e..6efa00fe4e7 100644 --- a/include/asm-x86_64/ia32.h +++ b/include/asm-x86_64/ia32.h @@ -94,7 +94,7 @@ typedef struct compat_siginfo{ /* POSIX.1b timers */ struct { - int _tid; /* timer id */ + compat_timer_t _tid; /* timer id */ int _overrun; /* overrun count */ compat_sigval_t _sigval; /* same as below */ int _sys_private; /* not to be passed to user */ -- cgit v1.2.3-70-g09d2 From b445e26cbf784cdba10f2b6c3e2cd3ee7bab360a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 27 Jun 2005 15:42:04 -0700 Subject: [SPARC64]: Avoid membar instructions in delay slots. In particular, avoid membar instructions in the delay slot of a jmpl instruction. UltraSPARC-I, II, IIi, and IIe have a bug, documented in the UltraSPARC-IIi User's Manual, Appendix K, Erratum 51 The long and short of it is that if the IMU unit misses on a branch or jmpl, and there is a store buffer synchronizing membar in the delay slot, the chip can stop fetching instructions. If interrupts are enabled or some other trap is enabled, the chip will unwedge itself, but performance will suffer. We already had a workaround for this bug in a few spots, but it's better to have the entire tree sanitized for this rule. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 6 ++- arch/sparc64/kernel/semaphore.c | 12 +++-- arch/sparc64/kernel/trampoline.S | 3 +- arch/sparc64/lib/U1memcpy.S | 103 ++++++++++++++++++++------------------- arch/sparc64/lib/VISsave.S | 15 +++++- arch/sparc64/lib/atomic.S | 42 ++++++++++------ arch/sparc64/lib/bitops.S | 31 +++++++----- arch/sparc64/lib/debuglocks.c | 6 ++- arch/sparc64/lib/dec_and_lock.S | 6 ++- arch/sparc64/lib/rwsem.S | 15 ++++-- arch/sparc64/mm/init.c | 6 ++- arch/sparc64/mm/ultra.S | 3 +- include/asm-sparc64/rwsem.h | 3 +- include/asm-sparc64/spinlock.h | 29 +++++++---- include/asm-sparc64/spitfire.h | 1 - 15 files changed, 171 insertions(+), 110 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index a47f2d0b1a2..ffe717ab7f8 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -271,8 +271,9 @@ cplus_fptrap_insn_1: fmuld %f0, %f2, %f26 faddd %f0, %f2, %f28 fmuld %f0, %f2, %f30 + membar #Sync b,pt %xcc, fpdis_exit - membar #Sync + nop 2: andcc %g5, FPRS_DU, %g0 bne,pt %icc, 3f fzero %f32 @@ -301,8 +302,9 @@ cplus_fptrap_insn_2: fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 + membar #Sync ba,pt %xcc, fpdis_exit - membar #Sync + nop 3: mov SECONDARY_CONTEXT, %g3 add %g6, TI_FPREGS, %g1 ldxa [%g3] ASI_DMMU, %g5 diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index 63496c43fe1..a809e63f03e 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -32,8 +32,9 @@ static __inline__ int __sem_update_count(struct semaphore *sem, int incr) " add %1, %4, %1\n" " cas [%3], %0, %1\n" " cmp %0, %1\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%icc, 1b\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) : "r" (&sem->count), "r" (incr), "m" (sem->count) : "cc"); @@ -71,8 +72,9 @@ void up(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " addcc %%g7, 1, %%g0\n" +" membar #StoreLoad | #StoreStore\n" " ble,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %0, %%g1\n" @@ -128,8 +130,9 @@ void __sched down(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " cmp %%g7, 1\n" +" membar #StoreLoad | #StoreStore\n" " bl,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %0, %%g1\n" @@ -233,8 +236,9 @@ int __sched down_interruptible(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " cmp %%g7, 1\n" +" membar #StoreLoad | #StoreStore\n" " bl,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %2, %%g1\n" diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 2c8f9344b4e..3a145fc39cf 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -98,8 +98,9 @@ startup_continue: sethi %hi(prom_entry_lock), %g2 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 + membar #StoreLoad | #StoreStore brnz,pn %g1, 1b - membar #StoreLoad | #StoreStore + nop sethi %hi(p1275buf), %g2 or %g2, %lo(p1275buf), %g2 diff --git a/arch/sparc64/lib/U1memcpy.S b/arch/sparc64/lib/U1memcpy.S index da9b520c718..bafd2fc07ac 100644 --- a/arch/sparc64/lib/U1memcpy.S +++ b/arch/sparc64/lib/U1memcpy.S @@ -87,14 +87,17 @@ #define LOOP_CHUNK3(src, dest, len, branch_dest) \ MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest) +#define DO_SYNC membar #Sync; #define STORE_SYNC(dest, fsrc) \ EX_ST(STORE_BLK(%fsrc, %dest)); \ - add %dest, 0x40, %dest; + add %dest, 0x40, %dest; \ + DO_SYNC #define STORE_JUMP(dest, fsrc, target) \ EX_ST(STORE_BLK(%fsrc, %dest)); \ add %dest, 0x40, %dest; \ - ba,pt %xcc, target; + ba,pt %xcc, target; \ + nop; #define FINISH_VISCHUNK(dest, f0, f1, left) \ subcc %left, 8, %left;\ @@ -239,17 +242,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f0, %f2, %f48 1: FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) - STORE_JUMP(o0, f48, 40f) membar #Sync + STORE_JUMP(o0, f48, 40f) 2: FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) - STORE_JUMP(o0, f48, 48f) membar #Sync + STORE_JUMP(o0, f48, 48f) 3: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) - STORE_JUMP(o0, f48, 56f) membar #Sync + STORE_JUMP(o0, f48, 56f) 1: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -260,17 +263,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f2, %f4, %f48 1: FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) - STORE_JUMP(o0, f48, 41f) membar #Sync + STORE_JUMP(o0, f48, 41f) 2: FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) - STORE_JUMP(o0, f48, 49f) membar #Sync + STORE_JUMP(o0, f48, 49f) 3: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) - STORE_JUMP(o0, f48, 57f) membar #Sync + STORE_JUMP(o0, f48, 57f) 1: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -281,17 +284,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f4, %f6, %f48 1: FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) - STORE_JUMP(o0, f48, 42f) membar #Sync + STORE_JUMP(o0, f48, 42f) 2: FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) - STORE_JUMP(o0, f48, 50f) membar #Sync + STORE_JUMP(o0, f48, 50f) 3: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) - STORE_JUMP(o0, f48, 58f) membar #Sync + STORE_JUMP(o0, f48, 58f) 1: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -302,17 +305,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f6, %f8, %f48 1: FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) - STORE_JUMP(o0, f48, 43f) membar #Sync + STORE_JUMP(o0, f48, 43f) 2: FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) - STORE_JUMP(o0, f48, 51f) membar #Sync + STORE_JUMP(o0, f48, 51f) 3: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) - STORE_JUMP(o0, f48, 59f) membar #Sync + STORE_JUMP(o0, f48, 59f) 1: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -323,17 +326,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f8, %f10, %f48 1: FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) - STORE_JUMP(o0, f48, 44f) membar #Sync + STORE_JUMP(o0, f48, 44f) 2: FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) - STORE_JUMP(o0, f48, 52f) membar #Sync + STORE_JUMP(o0, f48, 52f) 3: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) - STORE_JUMP(o0, f48, 60f) membar #Sync + STORE_JUMP(o0, f48, 60f) 1: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -344,17 +347,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f10, %f12, %f48 1: FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) - STORE_JUMP(o0, f48, 45f) membar #Sync + STORE_JUMP(o0, f48, 45f) 2: FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) - STORE_JUMP(o0, f48, 53f) membar #Sync + STORE_JUMP(o0, f48, 53f) 3: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) - STORE_JUMP(o0, f48, 61f) membar #Sync + STORE_JUMP(o0, f48, 61f) 1: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -365,17 +368,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f12, %f14, %f48 1: FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) - STORE_JUMP(o0, f48, 46f) membar #Sync + STORE_JUMP(o0, f48, 46f) 2: FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) - STORE_JUMP(o0, f48, 54f) membar #Sync + STORE_JUMP(o0, f48, 54f) 3: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) - STORE_JUMP(o0, f48, 62f) membar #Sync + STORE_JUMP(o0, f48, 62f) 1: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -386,17 +389,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f14, %f16, %f48 1: FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) - STORE_JUMP(o0, f48, 47f) membar #Sync + STORE_JUMP(o0, f48, 47f) 2: FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) - STORE_JUMP(o0, f48, 55f) membar #Sync + STORE_JUMP(o0, f48, 55f) 3: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) - STORE_JUMP(o0, f48, 63f) membar #Sync + STORE_JUMP(o0, f48, 63f) 40: FINISH_VISCHUNK(o0, f0, f2, g3) 41: FINISH_VISCHUNK(o0, f2, f4, g3) diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index 65e328d600a..4e18989bd60 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S @@ -72,7 +72,11 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 stda %f48, [%g3 + %g1] ASI_BLK_P 5: membar #Sync - jmpl %g7 + %g0, %g0 + ba,pt %xcc, 80f + nop + + .align 32 +80: jmpl %g7 + %g0, %g0 nop 6: ldub [%g3 + TI_FPSAVED], %o5 @@ -87,8 +91,11 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 stda %f32, [%g2 + %g1] ASI_BLK_P stda %f48, [%g3 + %g1] ASI_BLK_P membar #Sync - jmpl %g7 + %g0, %g0 + ba,pt %xcc, 80f + nop + .align 32 +80: jmpl %g7 + %g0, %g0 nop .align 32 @@ -126,6 +133,10 @@ VISenterhalf: stda %f0, [%g2 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P membar #Sync + ba,pt %xcc, 4f + nop + + .align 32 4: and %o5, FPRS_DU, %o5 jmpl %g7 + %g0, %g0 wr %o5, FPRS_FEF, %fprs diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S index e528b8d1a3e..faf87c31598 100644 --- a/arch/sparc64/lib/atomic.S +++ b/arch/sparc64/lib/atomic.S @@ -7,18 +7,6 @@ #include #include - /* On SMP we need to use memory barriers to ensure - * correct memory operation ordering, nop these out - * for uniprocessor. - */ -#ifdef CONFIG_SMP -#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad -#define ATOMIC_POST_BARRIER membar #StoreLoad | #StoreStore -#else -#define ATOMIC_PRE_BARRIER nop -#define ATOMIC_POST_BARRIER nop -#endif - .text /* Two versions of the atomic routines, one that @@ -52,6 +40,24 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ nop .size atomic_sub, .-atomic_sub + /* On SMP we need to use memory barriers to ensure + * correct memory operation ordering, nop these out + * for uniprocessor. + */ +#ifdef CONFIG_SMP + +#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad; +#define ATOMIC_POST_BARRIER \ + ba,pt %xcc, 80b; \ + membar #StoreLoad | #StoreStore + +80: retl + nop +#else +#define ATOMIC_PRE_BARRIER +#define ATOMIC_POST_BARRIER +#endif + .globl atomic_add_ret .type atomic_add_ret,#function atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ @@ -62,9 +68,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %icc, 1b add %g7, %o0, %g7 + sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl - sra %g7, 0, %o0 + nop .size atomic_add_ret, .-atomic_add_ret .globl atomic_sub_ret @@ -77,9 +84,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %icc, 1b sub %g7, %o0, %g7 + sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl - sra %g7, 0, %o0 + nop .size atomic_sub_ret, .-atomic_sub_ret .globl atomic64_add @@ -118,9 +126,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %xcc, 1b add %g7, %o0, %g7 + mov %g7, %o0 ATOMIC_POST_BARRIER retl - mov %g7, %o0 + nop .size atomic64_add_ret, .-atomic64_add_ret .globl atomic64_sub_ret @@ -133,7 +142,8 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %xcc, 1b sub %g7, %o0, %g7 + mov %g7, %o0 ATOMIC_POST_BARRIER retl - mov %g7, %o0 + nop .size atomic64_sub_ret, .-atomic64_sub_ret diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S index 886dcd2b376..31afbfe6c1e 100644 --- a/arch/sparc64/lib/bitops.S +++ b/arch/sparc64/lib/bitops.S @@ -7,20 +7,26 @@ #include #include + .text + /* On SMP we need to use memory barriers to ensure * correct memory operation ordering, nop these out * for uniprocessor. */ + #ifdef CONFIG_SMP #define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad -#define BITOP_POST_BARRIER membar #StoreLoad | #StoreStore +#define BITOP_POST_BARRIER \ + ba,pt %xcc, 80b; \ + membar #StoreLoad | #StoreStore + +80: retl + nop #else -#define BITOP_PRE_BARRIER nop -#define BITOP_POST_BARRIER nop +#define BITOP_PRE_BARRIER +#define BITOP_POST_BARRIER #endif - .text - .globl test_and_set_bit .type test_and_set_bit,#function test_and_set_bit: /* %o0=nr, %o1=addr */ @@ -37,10 +43,11 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_set_bit, .-test_and_set_bit .globl test_and_clear_bit @@ -59,10 +66,11 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_clear_bit, .-test_and_clear_bit .globl test_and_change_bit @@ -81,10 +89,11 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_change_bit, .-test_and_change_bit .globl set_bit diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c index c421e0c6532..f03344cf784 100644 --- a/arch/sparc64/lib/debuglocks.c +++ b/arch/sparc64/lib/debuglocks.c @@ -252,8 +252,9 @@ wlock_again: " andn %%g1, %%g3, %%g7\n" " casx [%0], %%g1, %%g7\n" " cmp %%g1, %%g7\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%xcc, 1b\n" -" membar #StoreLoad | #StoreStore" +" nop" : /* no outputs */ : "r" (&(rw->lock)) : "g3", "g1", "g7", "cc", "memory"); @@ -351,8 +352,9 @@ int _do_write_trylock (rwlock_t *rw, char *str) " andn %%g1, %%g3, %%g7\n" " casx [%0], %%g1, %%g7\n" " cmp %%g1, %%g7\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%xcc, 1b\n" -" membar #StoreLoad | #StoreStore" +" nop" : /* no outputs */ : "r" (&(rw->lock)) : "g3", "g1", "g7", "cc", "memory"); diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S index 7e6fdaebedb..8ee288dd0af 100644 --- a/arch/sparc64/lib/dec_and_lock.S +++ b/arch/sparc64/lib/dec_and_lock.S @@ -48,8 +48,9 @@ start_to_zero: #endif to_zero: ldstub [%o1], %g3 + membar #StoreLoad | #StoreStore brnz,pn %g3, spin_on_lock - membar #StoreLoad | #StoreStore + nop loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ cmp %g2, %g7 @@ -71,8 +72,9 @@ loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ nop spin_on_lock: ldub [%o1], %g3 + membar #LoadLoad brnz,pt %g3, spin_on_lock - membar #LoadLoad + nop ba,pt %xcc, to_zero nop nop diff --git a/arch/sparc64/lib/rwsem.S b/arch/sparc64/lib/rwsem.S index 174ff7b9164..75f0e6b951d 100644 --- a/arch/sparc64/lib/rwsem.S +++ b/arch/sparc64/lib/rwsem.S @@ -17,8 +17,9 @@ __down_read: bne,pn %icc, 1b add %g7, 1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop @@ -57,8 +58,9 @@ __down_write: cmp %g3, %g7 bne,pn %icc, 1b cmp %g7, 0 + membar #StoreLoad | #StoreStore bne,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop 3: @@ -97,8 +99,9 @@ __up_read: cmp %g1, %g7 bne,pn %icc, 1b cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1 @@ -126,8 +129,9 @@ __up_write: bne,pn %icc, 1b sub %g7, %g1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop @@ -151,8 +155,9 @@ __downgrade_write: bne,pn %icc, 1b sub %g7, %g1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 9c5222075da..8fc413cb6ac 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -136,8 +136,9 @@ static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) "or %%g1, %0, %%g1\n\t" "casx [%2], %%g7, %%g1\n\t" "cmp %%g7, %%g1\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%xcc, 1b\n\t" - " membar #StoreLoad | #StoreStore" + " nop" : /* no outputs */ : "r" (mask), "r" (non_cpu_bits), "r" (&page->flags) : "g1", "g7"); @@ -157,8 +158,9 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c " andn %%g7, %1, %%g1\n\t" "casx [%2], %%g7, %%g1\n\t" "cmp %%g7, %%g1\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%xcc, 1b\n\t" - " membar #StoreLoad | #StoreStore\n" + " nop\n" "2:" : /* no outputs */ : "r" (cpu), "r" (mask), "r" (&page->flags), diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 7a093432101..7a2431d3abc 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -266,8 +266,9 @@ __cheetah_flush_tlb_pending: /* 22 insns */ andn %o3, 1, %o3 stxa %g0, [%o3] ASI_IMMU_DEMAP 2: stxa %g0, [%o3] ASI_DMMU_DEMAP + membar #Sync brnz,pt %o1, 1b - membar #Sync + nop stxa %g2, [%o4] ASI_DMMU flush %g6 wrpr %g0, 0, %tl diff --git a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h index bf2ae90ed3d..a1cc94f9598 100644 --- a/include/asm-sparc64/rwsem.h +++ b/include/asm-sparc64/rwsem.h @@ -55,8 +55,9 @@ static __inline__ int rwsem_atomic_update(int delta, struct rw_semaphore *sem) "add %%g1, %1, %%g7\n\t" "cas [%2], %%g1, %%g7\n\t" "cmp %%g1, %%g7\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%icc, 1b\n\t" - " membar #StoreLoad | #StoreStore\n\t" + " nop\n\t" "mov %%g7, %0\n\t" : "=&r" (tmp) : "0" (tmp), "r" (sem) diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h index db7581bdb53..9cb93a5c2b4 100644 --- a/include/asm-sparc64/spinlock.h +++ b/include/asm-sparc64/spinlock.h @@ -52,12 +52,14 @@ static inline void _raw_spin_lock(spinlock_t *lock) __asm__ __volatile__( "1: ldstub [%1], %0\n" +" membar #StoreLoad | #StoreStore\n" " brnz,pn %0, 2f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" " .subsection 2\n" "2: ldub [%1], %0\n" +" membar #LoadLoad\n" " brnz,pt %0, 2b\n" -" membar #LoadLoad\n" +" nop\n" " ba,a,pt %%xcc, 1b\n" " .previous" : "=&r" (tmp) @@ -95,16 +97,18 @@ static inline void _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags) __asm__ __volatile__( "1: ldstub [%2], %0\n" -" brnz,pn %0, 2f\n" " membar #StoreLoad | #StoreStore\n" +" brnz,pn %0, 2f\n" +" nop\n" " .subsection 2\n" "2: rdpr %%pil, %1\n" " wrpr %3, %%pil\n" "3: ldub [%2], %0\n" -" brnz,pt %0, 3b\n" " membar #LoadLoad\n" +" brnz,pt %0, 3b\n" +" nop\n" " ba,pt %%xcc, 1b\n" -" wrpr %1, %%pil\n" +" wrpr %1, %%pil\n" " .previous" : "=&r" (tmp1), "=&r" (tmp2) : "r"(lock), "r"(flags) @@ -162,12 +166,14 @@ static void inline __read_lock(rwlock_t *lock) "4: add %0, 1, %1\n" " cas [%2], %0, %1\n" " cmp %0, %1\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%icc, 1b\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" " .subsection 2\n" "2: ldsw [%2], %0\n" +" membar #LoadLoad\n" " brlz,pt %0, 2b\n" -" membar #LoadLoad\n" +" nop\n" " ba,a,pt %%xcc, 4b\n" " .previous" : "=&r" (tmp1), "=&r" (tmp2) @@ -204,12 +210,14 @@ static void inline __write_lock(rwlock_t *lock) "4: or %0, %3, %1\n" " cas [%2], %0, %1\n" " cmp %0, %1\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%icc, 1b\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" " .subsection 2\n" "2: lduw [%2], %0\n" +" membar #LoadLoad\n" " brnz,pt %0, 2b\n" -" membar #LoadLoad\n" +" nop\n" " ba,a,pt %%xcc, 4b\n" " .previous" : "=&r" (tmp1), "=&r" (tmp2) @@ -240,8 +248,9 @@ static int inline __write_trylock(rwlock_t *lock) " or %0, %4, %1\n" " cas [%3], %0, %1\n" " cmp %0, %1\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%icc, 1b\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" " mov 1, %2\n" "2:" : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result) diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h index 9d7613eea81..1aa932773af 100644 --- a/include/asm-sparc64/spitfire.h +++ b/include/asm-sparc64/spitfire.h @@ -111,7 +111,6 @@ static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long "membar #Sync" : /* No outputs */ : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG)); - __asm__ __volatile__ ("membar #Sync" : : : "memory"); } /* The instruction cache lines are flushed with this, but note that -- cgit v1.2.3-70-g09d2 From 63b614522cba5a015923c0e8f284be6e01c13f1a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 27 Jun 2005 17:04:45 -0700 Subject: [SPARC64]: Get rid of fast IRQ feature. The only real user was the assembler floppy interrupt handler, which does not need to be in assembly. This makes it so that there are less pieces of code which know about the internal layout of ivector_table[] and friends. Signed-off-by: David S. Miller --- arch/sparc64/kernel/auxio.c | 2 +- arch/sparc64/kernel/entry.S | 110 ----------------------- arch/sparc64/kernel/irq.c | 171 +++++++++++------------------------- arch/sparc64/kernel/sparc64_ksyms.c | 1 - include/asm-sparc64/auxio.h | 2 + include/asm-sparc64/floppy.h | 16 ++-- include/asm-sparc64/irq.h | 7 +- 7 files changed, 62 insertions(+), 247 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index a0716ccc2f4..8852c20c8d9 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -16,7 +16,7 @@ #include #include -/* This cannot be static, as it is referenced in entry.S */ +/* This cannot be static, as it is referenced in irq.c */ void __iomem *auxio_register = NULL; enum auxio_type { diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index ffe717ab7f8..eee516a71c1 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -701,116 +701,6 @@ utrap_ill: ba,pt %xcc, rtrap clr %l6 -#ifdef CONFIG_BLK_DEV_FD - .globl floppy_hardint -floppy_hardint: - wr %g0, (1 << 11), %clear_softint - sethi %hi(doing_pdma), %g1 - ld [%g1 + %lo(doing_pdma)], %g2 - brz,pn %g2, floppy_dosoftint - sethi %hi(fdc_status), %g3 - ldx [%g3 + %lo(fdc_status)], %g3 - sethi %hi(pdma_vaddr), %g5 - ldx [%g5 + %lo(pdma_vaddr)], %g4 - sethi %hi(pdma_size), %g5 - ldx [%g5 + %lo(pdma_size)], %g5 - -next_byte: - lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 - andcc %g7, 0x80, %g0 - be,pn %icc, floppy_fifo_emptied - andcc %g7, 0x20, %g0 - be,pn %icc, floppy_overrun - andcc %g7, 0x40, %g0 - be,pn %icc, floppy_write - sub %g5, 1, %g5 - - inc %g3 - lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 - dec %g3 - orcc %g0, %g5, %g0 - stb %g7, [%g4] - bne,pn %xcc, next_byte - add %g4, 1, %g4 - - b,pt %xcc, floppy_tdone - nop - -floppy_write: - ldub [%g4], %g7 - orcc %g0, %g5, %g0 - inc %g3 - stba %g7, [%g3] ASI_PHYS_BYPASS_EC_E - dec %g3 - bne,pn %xcc, next_byte - add %g4, 1, %g4 - -floppy_tdone: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(auxio_register), %g1 - ldx [%g1 + %lo(auxio_register)], %g7 - lduba [%g7] ASI_PHYS_BYPASS_EC_E, %g5 - or %g5, AUXIO_AUX1_FTCNT, %g5 -/* andn %g5, AUXIO_AUX1_MASK, %g5 */ - stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E - andn %g5, AUXIO_AUX1_FTCNT, %g5 -/* andn %g5, AUXIO_AUX1_MASK, %g5 */ - - nop; nop; nop; nop; nop; nop; - nop; nop; nop; nop; nop; nop; - - stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E - sethi %hi(doing_pdma), %g1 - b,pt %xcc, floppy_dosoftint - st %g0, [%g1 + %lo(doing_pdma)] - -floppy_fifo_emptied: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(irq_action), %g1 - or %g1, %lo(irq_action), %g1 - ldx [%g1 + (11 << 3)], %g3 ! irqaction[floppy_irq] - ldx [%g3 + 0x08], %g4 ! action->flags>>48==ino - sethi %hi(ivector_table), %g3 - srlx %g4, 48, %g4 - or %g3, %lo(ivector_table), %g3 - sllx %g4, 5, %g4 - ldx [%g3 + %g4], %g4 ! &ivector_table[ino] - ldx [%g4 + 0x10], %g4 ! bucket->iclr - stwa %g0, [%g4] ASI_PHYS_BYPASS_EC_E ! ICLR_IDLE - membar #Sync ! probably not needed... - retry - -floppy_overrun: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(doing_pdma), %g1 - st %g0, [%g1 + %lo(doing_pdma)] - -floppy_dosoftint: - rdpr %pil, %g2 - wrpr %g0, 15, %pil - sethi %hi(109f), %g7 - b,pt %xcc, etrap_irq -109: or %g7, %lo(109b), %g7 - - mov 11, %o0 - mov 0, %o1 - call sparc_floppy_irq - add %sp, PTREGS_OFF, %o2 - - b,pt %xcc, rtrap_irq - nop - -#endif /* CONFIG_BLK_DEV_FD */ - /* XXX Here is stuff we still need to write... -DaveM XXX */ .globl netbsd_syscall netbsd_syscall: diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 4dcb8af9409..42471257730 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef CONFIG_SMP static void distribute_irqs(void); @@ -834,137 +835,65 @@ void handler_irq(int irq, struct pt_regs *regs) } #ifdef CONFIG_BLK_DEV_FD -extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs); +extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);; -void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) -{ - struct irqaction *action = *(irq + irq_action); - struct ino_bucket *bucket; - int cpu = smp_processor_id(); - - irq_enter(); - kstat_this_cpu.irqs[irq]++; - - *(irq_work(cpu, irq)) = 0; - bucket = get_ino_in_irqaction(action) + ivector_table; - - bucket->flags |= IBF_INPROGRESS; - - floppy_interrupt(irq, dev_cookie, regs); - upa_writel(ICLR_IDLE, bucket->iclr); - - bucket->flags &= ~IBF_INPROGRESS; - - irq_exit(); -} -#endif - -/* The following assumes that the branch lies before the place we - * are branching to. This is the case for a trap vector... - * You have been warned. - */ -#define SPARC_BRANCH(dest_addr, inst_addr) \ - (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff)) - -#define SPARC_NOP (0x01000000) +/* XXX No easy way to include asm/floppy.h XXX */ +extern unsigned char *pdma_vaddr; +extern unsigned long pdma_size; +extern volatile int doing_pdma; +extern unsigned long fdc_status; -static void install_fast_irq(unsigned int cpu_irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *)) +irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) { - extern unsigned long sparc64_ttable_tl0; - unsigned long ttent = (unsigned long) &sparc64_ttable_tl0; - unsigned int *insns; - - ttent += 0x820; - ttent += (cpu_irq - 1) << 5; - insns = (unsigned int *) ttent; - insns[0] = SPARC_BRANCH(((unsigned long) handler), - ((unsigned long)&insns[0])); - insns[1] = SPARC_NOP; - __asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent)); -} - -int request_fast_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char *name, void *dev_id) -{ - struct irqaction *action; - struct ino_bucket *bucket = __bucket(irq); - unsigned long flags; - - /* No pil0 dummy buckets allowed here. */ - if (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS]) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); - return -EINVAL; - } - - if (!handler) - return -EINVAL; + if (likely(doing_pdma)) { + void __iomem *stat = (void __iomem *) fdc_status; + unsigned char *vaddr = pdma_vaddr; + unsigned long size = pdma_size; + u8 val; + + while (size) { + val = readb(stat); + if (unlikely(!(val & 0x80))) { + pdma_vaddr = vaddr; + pdma_size = size; + return IRQ_HANDLED; + } + if (unlikely(!(val & 0x20))) { + pdma_vaddr = vaddr; + pdma_size = size; + doing_pdma = 0; + goto main_interrupt; + } + if (val & 0x40) { + /* read */ + *vaddr++ = readb(stat + 1); + } else { + unsigned char data = *vaddr++; - if ((bucket->pil == 0) || (bucket->pil == 14)) { - printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n"); - return -EBUSY; - } + /* write */ + writeb(data, stat + 1); + } + size--; + } - spin_lock_irqsave(&irq_action_lock, flags); + pdma_vaddr = vaddr; + pdma_size = size; - action = *(bucket->pil + irq_action); - if (action) { - if (action->flags & SA_SHIRQ) - panic("Trying to register fast irq when already shared.\n"); - if (irqflags & SA_SHIRQ) - panic("Trying to register fast irq as shared.\n"); - printk("request_fast_irq: Trying to register yet already owned.\n"); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } + /* Send Terminal Count pulse to floppy controller. */ + val = readb(auxio_register); + val |= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); + val &= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); - /* - * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we - * support smp intr affinity in this path. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", bucket->pil, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - if (!action) { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; + doing_pdma = 0; } - install_fast_irq(bucket->pil, handler); - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - - action->handler = handler; - action->flags = irqflags; - action->dev_id = NULL; - action->name = name; - action->next = NULL; - put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, CPU_MASK_NONE); - - *(bucket->pil + irq_action) = action; - enable_irq(irq); - - spin_unlock_irqrestore(&irq_action_lock, flags); - -#ifdef CONFIG_SMP - distribute_irqs(); -#endif - return 0; +main_interrupt: + return floppy_interrupt(irq, dev_cookie, regs); } +EXPORT_SYMBOL(sparc_floppy_irq); +#endif /* We really don't need these at all on the Sparc. We only have * stubs here because they are exported to modules. diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index e78cc53594f..56cd96f4a5c 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -227,7 +227,6 @@ EXPORT_SYMBOL(__flush_dcache_range); EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); -EXPORT_SYMBOL(request_fast_irq); #ifdef CONFIG_SUN_AUXIO EXPORT_SYMBOL(auxio_set_led); EXPORT_SYMBOL(auxio_set_lte); diff --git a/include/asm-sparc64/auxio.h b/include/asm-sparc64/auxio.h index 5eb01dd4715..81a590a50a1 100644 --- a/include/asm-sparc64/auxio.h +++ b/include/asm-sparc64/auxio.h @@ -75,6 +75,8 @@ #ifndef __ASSEMBLY__ +extern void __iomem *auxio_register; + #define AUXIO_LTE_ON 1 #define AUXIO_LTE_OFF 0 diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h index e071b4b4edf..49d49a28594 100644 --- a/include/asm-sparc64/floppy.h +++ b/include/asm-sparc64/floppy.h @@ -159,7 +159,7 @@ static void sun_82077_fd_outb(unsigned char value, unsigned long port) * underruns. If non-zero, doing_pdma encodes the direction of * the transfer for debugging. 1=read 2=write */ -char *pdma_vaddr; +unsigned char *pdma_vaddr; unsigned long pdma_size; volatile int doing_pdma = 0; @@ -209,8 +209,7 @@ static void sun_fd_enable_dma(void) pdma_areasize = pdma_size; } -/* Our low-level entry point in arch/sparc/kernel/entry.S */ -extern irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs); +extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *); static int sun_fd_request_irq(void) { @@ -220,8 +219,8 @@ static int sun_fd_request_irq(void) if(!once) { once = 1; - error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, - SA_INTERRUPT, "floppy", NULL); + error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, + SA_INTERRUPT, "floppy", NULL); return ((error == 0) ? 0 : -1); } @@ -615,7 +614,7 @@ static unsigned long __init sun_floppy_init(void) struct linux_ebus *ebus; struct linux_ebus_device *edev = NULL; unsigned long config = 0; - unsigned long auxio_reg; + void __iomem *auxio_reg; for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { @@ -642,7 +641,7 @@ static unsigned long __init sun_floppy_init(void) /* Make sure the high density bit is set, some systems * (most notably Ultra5/Ultra10) come up with it clear. */ - auxio_reg = edev->resource[2].start; + auxio_reg = (void __iomem *) edev->resource[2].start; writel(readl(auxio_reg)|0x2, auxio_reg); sun_pci_ebus_dev = ebus->self; @@ -650,7 +649,8 @@ static unsigned long __init sun_floppy_init(void) spin_lock_init(&sun_pci_fd_ebus_dma.lock); /* XXX ioremap */ - sun_pci_fd_ebus_dma.regs = edev->resource[1].start; + sun_pci_fd_ebus_dma.regs = (void __iomem *) + edev->resource[1].start; if (!sun_pci_fd_ebus_dma.regs) return 0; diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 3aef0ca6775..018e2e46082 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -19,7 +19,7 @@ /* You should not mess with this directly. That's the job of irq.c. * * If you make changes here, please update hand coded assembler of - * SBUS/floppy interrupt handler in entry.S -DaveM + * the vectored interrupt trap handler in entry.S -DaveM * * This is currently one DCACHE line, two buckets per L2 cache * line. Keep this in mind please. @@ -122,11 +122,6 @@ extern void enable_irq(unsigned int); extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); -extern int request_fast_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long flags, __const__ char *devname, - void *dev_id); - static __inline__ void set_softint(unsigned long bits) { __asm__ __volatile__("wr %0, 0x0, %%set_softint" -- cgit v1.2.3-70-g09d2 From e7270dec080002d8aa18256c756af6c32331ef48 Mon Sep 17 00:00:00 2001 From: Raphael Assenat Date: Mon, 4 Jul 2005 13:23:45 -0700 Subject: [SPARC64/COMPAT]: Add some compat ioctl for ppdev The following patch adds some ioctls to include/linux/compat_ioctl.h to allow using ppdev from the 32 bit user space on sparc64. This patch also adds the PPDEV option in the sparc64 menu, near Parallel printer support in the 'General machine setup' submenu. All those ioctls seem to be compatible, since (correct me if I'm wrong) they dont use the 'long' type. See include/linux/ppdev.h. The application I used to test the new ioctls only used the following: PPEXCL PPCLAIM PPNEGOT PPGETMODES PPRCONTROL PPWCONTROL PPDATADIR PPWDATA PPRDATA But I beleive that the other ioctls will work fine. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 18 ++++++++++++++++++ include/linux/compat_ioctl.h | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index e2b050eb3b9..d78bc13ebbb 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -444,6 +444,24 @@ config PRINTER If you have more than 8 printers, you need to increase the LP_NO macro in lp.c and the PARPORT_MAX macro in parport.h. +config PPDEV + tristate "Support for user-space parallel port device drivers" + depends on PARPORT + ---help--- + Saying Y to this adds support for /dev/parport device nodes. This + is needed for programs that want portable access to the parallel + port, for instance deviceid (which displays Plug-and-Play device + IDs). + + This is the parallel port equivalent of SCSI generic support (sg). + It is safe to say N to this -- it is not needed for normal printing + or parallel port CD-ROM/disk support. + + To compile this driver as a module, choose M here: the + module will be called ppdev. + + If unsure, say N. + config ENVCTRL tristate "SUNW, envctrl support" depends on PCI diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index 70a4ebb5d96..ecb0d39c079 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -346,10 +346,27 @@ COMPATIBLE_IOCTL(PPPOEIOCDFWD) /* LP */ COMPATIBLE_IOCTL(LPGETSTATUS) /* ppdev */ +COMPATIBLE_IOCTL(PPSETMODE) +COMPATIBLE_IOCTL(PPRSTATUS) +COMPATIBLE_IOCTL(PPRCONTROL) +COMPATIBLE_IOCTL(PPWCONTROL) +COMPATIBLE_IOCTL(PPFCONTROL) +COMPATIBLE_IOCTL(PPRDATA) +COMPATIBLE_IOCTL(PPWDATA) COMPATIBLE_IOCTL(PPCLAIM) COMPATIBLE_IOCTL(PPRELEASE) -COMPATIBLE_IOCTL(PPEXCL) COMPATIBLE_IOCTL(PPYIELD) +COMPATIBLE_IOCTL(PPEXCL) +COMPATIBLE_IOCTL(PPDATADIR) +COMPATIBLE_IOCTL(PPNEGOT) +COMPATIBLE_IOCTL(PPWCTLONIRQ) +COMPATIBLE_IOCTL(PPCLRIRQ) +COMPATIBLE_IOCTL(PPSETPHASE) +COMPATIBLE_IOCTL(PPGETMODES) +COMPATIBLE_IOCTL(PPGETMODE) +COMPATIBLE_IOCTL(PPGETPHASE) +COMPATIBLE_IOCTL(PPGETFLAGS) +COMPATIBLE_IOCTL(PPSETFLAGS) /* CDROM stuff */ COMPATIBLE_IOCTL(CDROMPAUSE) COMPATIBLE_IOCTL(CDROMRESUME) -- cgit v1.2.3-70-g09d2 From 088dd1f81b3577c17c4c4381696bf2105ea0e43a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 13:24:38 -0700 Subject: [SPARC64]: Add support for IRQ pre-handlers. This allows a PCI controller to shim into IRQ delivery so that DMA queues can be drained, if necessary. If some bus specific code needs to run before an IRQ handler is invoked, the bus driver simply needs to setup the function pointer in bucket->irq_info->pre_handler and the two args bucket->irq_info->pre_handler_arg[12]. The Schizo PCI driver is converted over to use a pre-handler for the DMA write-sync processing it needs when a device is behind a PCI->PCI bus deeper than the top-level APB bridges. While we're here, clean up all of the action allocation and handling. Now, we allocate the irqaction as part of the bucket->irq_info area. There is an array of 4 irqaction (for PCI irq sharing) and a bitmask saying which entries are active. The bucket->irq_info is allocated at build_irq() time, not at request_irq() time. This simplifies request_irq() and free_irq() tremendously. The SMP dynamic IRQ retargetting code got removed in this change too. It was disabled for a few months now, and we can resurrect it in the future if we want. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 21 +- arch/sparc64/kernel/irq.c | 581 ++++++++++++++-------------------------- arch/sparc64/kernel/pci_sabre.c | 46 ++-- arch/sparc64/kernel/time.c | 2 +- include/asm-sparc64/irq.h | 49 ++-- include/asm-sparc64/signal.h | 15 -- 6 files changed, 247 insertions(+), 467 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index eee516a71c1..d3973d8a719 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -553,13 +553,11 @@ do_ivec: sllx %g3, 5, %g3 or %g2, %lo(ivector_table), %g2 add %g2, %g3, %g3 - ldx [%g3 + 0x08], %g2 /* irq_info */ ldub [%g3 + 0x04], %g4 /* pil */ - brz,pn %g2, do_ivec_spurious - mov 1, %g2 - + mov 1, %g2 sllx %g2, %g4, %g2 sllx %g4, 2, %g4 + lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ @@ -567,9 +565,9 @@ do_ivec: retry do_ivec_xcall: mov 0x50, %g1 - ldxa [%g1 + %g0] ASI_INTR_R, %g1 srl %g3, 0, %g3 + mov 0x60, %g7 ldxa [%g7 + %g0] ASI_INTR_R, %g7 stxa %g0, [%g0] ASI_INTR_RECEIVE @@ -581,19 +579,6 @@ do_ivec_xcall: 1: jmpl %g3, %g0 nop -do_ivec_spurious: - stw %g3, [%g6 + 0x00] /* irq_work(cpu, 0) = bucket */ - rdpr %pstate, %g5 - - wrpr %g5, PSTATE_IG | PSTATE_AG, %pstate - sethi %hi(109f), %g7 - ba,pt %xcc, etrap -109: or %g7, %lo(109b), %g7 - call catch_disabled_ivec - add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - clr %l6 - .globl save_alternate_globals save_alternate_globals: /* %o0 = save_area */ rdpr %pstate, %o5 diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 42471257730..74a2e0808cb 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -71,31 +71,7 @@ struct irq_work_struct { struct irq_work_struct __irq_work[NR_CPUS]; #define irq_work(__cpu, __pil) &(__irq_work[(__cpu)].irq_worklists[(__pil)]) -#ifdef CONFIG_PCI -/* This is a table of physical addresses used to deal with IBF_DMA_SYNC. - * It is used for PCI only to synchronize DMA transfers with IRQ delivery - * for devices behind busses other than APB on Sabre systems. - * - * Currently these physical addresses are just config space accesses - * to the command register for that device. - */ -unsigned long pci_dma_wsync; -unsigned long dma_sync_reg_table[256]; -unsigned char dma_sync_reg_table_entry = 0; -#endif - -/* This is based upon code in the 32-bit Sparc kernel written mostly by - * David Redman (djhr@tadpole.co.uk). - */ -#define MAX_STATIC_ALLOC 4 -static struct irqaction static_irqaction[MAX_STATIC_ALLOC]; -static int static_irq_count; - -/* This is exported so that fast IRQ handlers can get at it... -DaveM */ -struct irqaction *irq_action[NR_IRQS+1] = { - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL -}; +static struct irqaction *irq_action[NR_IRQS+1]; /* This only synchronizes entities which modify IRQ handler * state and some selected user-level spots that want to @@ -241,17 +217,22 @@ void disable_irq(unsigned int irq) * the CPU %tick register and not by some normal vectored interrupt * source. To handle this special case, we use this dummy INO bucket. */ +static struct irq_desc pil0_dummy_desc; static struct ino_bucket pil0_dummy_bucket = { - 0, /* irq_chain */ - 0, /* pil */ - 0, /* pending */ - 0, /* flags */ - 0, /* __unused */ - NULL, /* irq_info */ - 0UL, /* iclr */ - 0UL, /* imap */ + .irq_info = &pil0_dummy_desc, }; +static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, + unsigned long iclr, unsigned long imap, + struct ino_bucket *bucket) +{ + prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> " + "(%d:%d:%016lx:%016lx), halting...\n", + ino, bucket->pil, bucket->iclr, bucket->imap, + pil, inofixup, iclr, imap); + prom_halt(); +} + unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; @@ -280,28 +261,35 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long prom_halt(); } - /* Ok, looks good, set it up. Don't touch the irq_chain or - * the pending flag. - */ bucket = &ivector_table[ino]; - if ((bucket->flags & IBF_ACTIVE) || - (bucket->irq_info != NULL)) { - /* This is a gross fatal error if it happens here. */ - prom_printf("IRQ: Trying to reinit INO bucket, fatal error.\n"); - prom_printf("IRQ: Request INO %04x (%d:%d:%016lx:%016lx)\n", - ino, pil, inofixup, iclr, imap); - prom_printf("IRQ: Existing (%d:%016lx:%016lx)\n", - bucket->pil, bucket->iclr, bucket->imap); - prom_printf("IRQ: Cannot continue, halting...\n"); + if (bucket->flags & IBF_ACTIVE) + build_irq_error("IRQ: Trying to build active INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + if (bucket->irq_info) { + if (bucket->imap != imap || bucket->iclr != iclr) + build_irq_error("IRQ: Trying to reinit INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + goto out; + } + + bucket->irq_info = kmalloc(sizeof(struct irq_desc), GFP_ATOMIC); + if (!bucket->irq_info) { + prom_printf("IRQ: Error, kmalloc(irq_desc) failed.\n"); prom_halt(); } + memset(bucket->irq_info, 0, sizeof(struct irq_desc)); + + /* Ok, looks good, set it up. Don't touch the irq_chain or + * the pending flag. + */ bucket->imap = imap; bucket->iclr = iclr; bucket->pil = pil; bucket->flags = 0; - bucket->irq_info = NULL; - +out: return __irq(bucket); } @@ -319,26 +307,65 @@ static void atomic_bucket_insert(struct ino_bucket *bucket) __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); } +static int check_irq_sharing(int pil, unsigned long irqflags) +{ + struct irqaction *action, *tmp; + + action = *(irq_action + pil); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next) + ; + } else { + return -EBUSY; + } + } + return 0; +} + +static void append_irq_action(int pil, struct irqaction *action) +{ + struct irqaction **pp = irq_action + pil; + + while (*pp) + pp = &((*pp)->next); + *pp = action; +} + +static struct irqaction *get_action_slot(struct ino_bucket *bucket) +{ + struct irq_desc *desc = bucket->irq_info; + int max_irq, i; + + max_irq = 1; + if (bucket->flags & IBF_PCI) + max_irq = MAX_IRQ_DESC_ACTION; + for (i = 0; i < max_irq; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); + + if (desc->action_active_mask & mask) + continue; + + desc->action_active_mask |= mask; + return p; + } + return NULL; +} + int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *name, void *dev_id) { - struct irqaction *action, *tmp = NULL; + struct irqaction *action; struct ino_bucket *bucket = __bucket(irq); unsigned long flags; int pending = 0; - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); + if (unlikely(!handler)) return -EINVAL; - } - if (!handler) - return -EINVAL; + + if (unlikely(!bucket->irq_info)) + return -ENODEV; if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) { /* @@ -356,93 +383,20 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ spin_lock_irqsave(&irq_action_lock, flags); - action = *(bucket->pil + irq_action); - if (action) { - if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) - for (tmp = action; tmp->next; tmp = tmp->next) - ; - else { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } - action = NULL; /* Or else! */ + if (check_irq_sharing(bucket->pil, irqflags)) { + spin_unlock_irqrestore(&irq_action_lock, flags); + return -EBUSY; } - /* If this is flagged as statically allocated then we use our - * private struct which is never freed. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", irq, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - + action = get_action_slot(bucket); if (!action) { spin_unlock_irqrestore(&irq_action_lock, flags); return -ENOMEM; } - if (bucket == &pil0_dummy_bucket) { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } else { - if ((bucket->flags & IBF_ACTIVE) != 0) { - void *orig = bucket->irq_info; - void **vector = NULL; - - if ((bucket->flags & IBF_PCI) == 0) { - printk("IRQ: Trying to share non-PCI bucket.\n"); - goto free_and_ebusy; - } - if ((bucket->flags & IBF_MULTI) == 0) { - vector = kmalloc(sizeof(void *) * 4, GFP_ATOMIC); - if (vector == NULL) - goto free_and_enomem; - - /* We might have slept. */ - if ((bucket->flags & IBF_MULTI) != 0) { - int ent; - - kfree(vector); - vector = (void **)bucket->irq_info; - for(ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } else { - vector[0] = orig; - vector[1] = action; - vector[2] = NULL; - vector[3] = NULL; - bucket->irq_info = vector; - bucket->flags |= IBF_MULTI; - } - } else { - int ent; - - vector = (void **)orig; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } - } else { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } + bucket->flags |= IBF_ACTIVE; + pending = 0; + if (bucket != &pil0_dummy_bucket) { pending = bucket->pending; if (pending) bucket->pending = 0; @@ -456,10 +410,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ put_ino_in_irqaction(action, irq); put_smpaff_in_irqaction(action, CPU_MASK_NONE); - if (tmp) - tmp->next = action; - else - *(bucket->pil + irq_action) = action; + append_irq_action(bucket->pil, action); enable_irq(irq); @@ -468,147 +419,103 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ atomic_bucket_insert(bucket); set_softint(1 << bucket->pil); } + spin_unlock_irqrestore(&irq_action_lock, flags); - if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC))) + + if (bucket != &pil0_dummy_bucket) register_irq_proc(__irq_ino(irq)); #ifdef CONFIG_SMP distribute_irqs(); #endif return 0; - -free_and_ebusy: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - -free_and_enomem: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; } EXPORT_SYMBOL(request_irq); -void free_irq(unsigned int irq, void *dev_id) +static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) { - struct irqaction *action; - struct irqaction *tmp = NULL; - unsigned long flags; - struct ino_bucket *bucket = __bucket(irq), *bp; - - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; + struct ino_bucket *bucket = __bucket(irq); + struct irqaction *action, **pp; - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "free_irq: Old style IRQ removal attempt " - "from %p, irq %08x.\n", caller, irq); - return; - } - - spin_lock_irqsave(&irq_action_lock, flags); + pp = irq_action + bucket->pil; + action = *pp; + if (unlikely(!action)) + return NULL; - action = *(bucket->pil + irq_action); - if (!action->handler) { + if (unlikely(!action->handler)) { printk("Freeing free IRQ %d\n", bucket->pil); - return; - } - if (dev_id) { - for ( ; action; action = action->next) { - if (action->dev_id == dev_id) - break; - tmp = action; - } - if (!action) { - printk("Trying to free free shared IRQ %d\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; - } - } else if (action->flags & SA_SHIRQ) { - printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + return NULL; } - if (action->flags & SA_STATIC_ALLOC) { - printk("Attempt to free statically allocated IRQ %d (%s)\n", - bucket->pil, action->name); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + while (action && action->dev_id != dev_id) { + pp = &action->next; + action = *pp; } - if (action && tmp) - tmp->next = action->next; - else - *(bucket->pil + irq_action) = action->next; + if (likely(action)) + *pp = action->next; + + return action; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction *action; + struct ino_bucket *bucket; + unsigned long flags; + + spin_lock_irqsave(&irq_action_lock, flags); + + action = unlink_irq_action(irq, dev_id); spin_unlock_irqrestore(&irq_action_lock, flags); + if (unlikely(!action)) + return; + synchronize_irq(irq); spin_lock_irqsave(&irq_action_lock, flags); + bucket = __bucket(irq); if (bucket != &pil0_dummy_bucket) { + struct irq_desc *desc = bucket->irq_info; unsigned long imap = bucket->imap; - void **vector, *orig; - int ent; - - orig = bucket->irq_info; - vector = (void **)orig; - - if ((bucket->flags & IBF_MULTI) != 0) { - int other = 0; - void *orphan = NULL; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == action) - vector[ent] = NULL; - else if (vector[ent] != NULL) { - orphan = vector[ent]; - other++; - } - } + int ent, i; - /* Only free when no other shared irq - * uses this bucket. - */ - if (other) { - if (other == 1) { - /* Convert back to non-shared bucket. */ - bucket->irq_info = orphan; - bucket->flags &= ~(IBF_MULTI); - kfree(vector); - } - goto out; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + + if (p == action) { + desc->action_active_mask &= ~(1 << i); + break; } - } else { - bucket->irq_info = NULL; } - /* This unique interrupt source is now inactive. */ - bucket->flags &= ~IBF_ACTIVE; + if (!desc->action_active_mask) { + /* This unique interrupt source is now inactive. */ + bucket->flags &= ~IBF_ACTIVE; - /* See if any other buckets share this bucket's IMAP - * and are still active. - */ - for (ent = 0; ent < NUM_IVECS; ent++) { - bp = &ivector_table[ent]; - if (bp != bucket && - bp->imap == imap && - (bp->flags & IBF_ACTIVE) != 0) - break; - } + /* See if any other buckets share this bucket's IMAP + * and are still active. + */ + for (ent = 0; ent < NUM_IVECS; ent++) { + struct ino_bucket *bp = &ivector_table[ent]; + if (bp != bucket && + bp->imap == imap && + (bp->flags & IBF_ACTIVE) != 0) + break; + } - /* Only disable when no other sub-irq levels of - * the same IMAP are active. - */ - if (ent == NUM_IVECS) - disable_irq(irq); + /* Only disable when no other sub-irq levels of + * the same IMAP are active. + */ + if (ent == NUM_IVECS) + disable_irq(irq); + } } -out: - kfree(action); spin_unlock_irqrestore(&irq_action_lock, flags); } @@ -647,99 +554,55 @@ void synchronize_irq(unsigned int irq) } #endif /* CONFIG_SMP */ -void catch_disabled_ivec(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - struct ino_bucket *bucket = __bucket(*irq_work(cpu, 0)); - - /* We can actually see this on Ultra/PCI PCI cards, which are bridges - * to other devices. Here a single IMAP enabled potentially multiple - * unique interrupt sources (which each do have a unique ICLR register. - * - * So what we do is just register that the IVEC arrived, when registered - * for real the request_irq() code will check the bit and signal - * a local CPU interrupt for it. - */ -#if 0 - printk("IVEC: Spurious interrupt vector (%x) received at (%016lx)\n", - bucket - &ivector_table[0], regs->tpc); -#endif - *irq_work(cpu, 0) = 0; - bucket->pending = 1; -} - -/* Tune this... */ -#define FORWARD_VOLUME 12 - -#ifdef CONFIG_SMP - -static inline void redirect_intr(int cpu, struct ino_bucket *bp) +static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs) { - /* Ok, here is what is going on: - * 1) Retargeting IRQs on Starfire is very - * expensive so just forget about it on them. - * 2) Moving around very high priority interrupts - * is a losing game. - * 3) If the current cpu is idle, interrupts are - * useful work, so keep them here. But do not - * pass to our neighbour if he is not very idle. - * 4) If sysadmin explicitly asks for directed intrs, - * Just Do It. - */ - struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask; - unsigned int buddy, ticks; + struct irq_desc *desc = bp->irq_info; + unsigned char flags = bp->flags; + u32 action_mask, i; + int random; - cpu_mask = get_smpaff_in_irqaction(ap); - cpus_and(cpu_mask, cpu_mask, cpu_online_map); - if (cpus_empty(cpu_mask)) - cpu_mask = cpu_online_map; + bp->flags |= IBF_INPROGRESS; - if (this_is_starfire != 0 || - bp->pil >= 10 || current->pid == 0) + if (unlikely(!(flags & IBF_ACTIVE))) { + bp->pending = 1; goto out; - - /* 'cpu' is the MID (ie. UPAID), calculate the MID - * of our buddy. - */ - buddy = cpu + 1; - if (buddy >= NR_CPUS) - buddy = 0; - - ticks = 0; - while (!cpu_isset(buddy, cpu_mask)) { - if (++buddy >= NR_CPUS) - buddy = 0; - if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, CPU_MASK_NONE); - goto out; - } } - if (buddy == cpu) - goto out; + if (desc->pre_handler) + desc->pre_handler(bp, + desc->pre_handler_arg1, + desc->pre_handler_arg2); - /* Voo-doo programming. */ - if (cpu_data(buddy).idle_volume < FORWARD_VOLUME) - goto out; + action_mask = desc->action_active_mask; + random = 0; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); - /* This just so happens to be correct on Cheetah - * at the moment. - */ - buddy <<= 26; + if (!(action_mask & mask)) + continue; + + action_mask &= ~mask; - /* Push it to our buddy. */ - upa_writel(buddy | IMAP_VALID, bp->imap); + if (p->handler(__irq(bp), p->dev_id, regs) == IRQ_HANDLED) + random |= p->flags; + if (!action_mask) + break; + } + if (bp->pil != 0) { + upa_writel(ICLR_IDLE, bp->iclr); + /* Test and add entropy */ + if (random & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + } out: - return; + bp->flags &= ~IBF_INPROGRESS; } -#endif - void handler_irq(int irq, struct pt_regs *regs) { - struct ino_bucket *bp, *nbp; + struct ino_bucket *bp; int cpu = smp_processor_id(); #ifndef CONFIG_SMP @@ -757,8 +620,6 @@ void handler_irq(int irq, struct pt_regs *regs) clear_softint(clr_mask); } #else - int should_forward = 0; - clear_softint(1 << irq); #endif @@ -773,63 +634,12 @@ void handler_irq(int irq, struct pt_regs *regs) #else bp = __bucket(xchg32(irq_work(cpu, irq), 0)); #endif - for ( ; bp != NULL; bp = nbp) { - unsigned char flags = bp->flags; - unsigned char random = 0; + while (bp) { + struct ino_bucket *nbp = __bucket(bp->irq_chain); - nbp = __bucket(bp->irq_chain); bp->irq_chain = 0; - - bp->flags |= IBF_INPROGRESS; - - if ((flags & IBF_ACTIVE) != 0) { -#ifdef CONFIG_PCI - if ((flags & IBF_DMA_SYNC) != 0) { - upa_readl(dma_sync_reg_table[bp->synctab_ent]); - upa_readq(pci_dma_wsync); - } -#endif - if ((flags & IBF_MULTI) == 0) { - struct irqaction *ap = bp->irq_info; - int ret; - - ret = ap->handler(__irq(bp), ap->dev_id, regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } else { - void **vector = (void **)bp->irq_info; - int ent; - for (ent = 0; ent < 4; ent++) { - struct irqaction *ap = vector[ent]; - if (ap != NULL) { - int ret; - - ret = ap->handler(__irq(bp), - ap->dev_id, - regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } - } - } - /* Only the dummy bucket lacks IMAP/ICLR. */ - if (bp->pil != 0) { -#ifdef CONFIG_SMP - if (should_forward) { - redirect_intr(cpu, bp); - should_forward = 0; - } -#endif - upa_writel(ICLR_IDLE, bp->iclr); - - /* Test and add entropy */ - if (random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - } - } else - bp->pending = 1; - - bp->flags &= ~IBF_INPROGRESS; + process_bucket(irq, bp, regs); + bp = nbp; } irq_exit(); } @@ -959,7 +769,10 @@ static void distribute_irqs(void) */ for (level = 1; level < NR_IRQS; level++) { struct irqaction *p = irq_action[level]; - if (level == 12) continue; + + if (level == 12) + continue; + while(p) { cpu = retarget_one_irq(p, cpu); p = p->next; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 53d333b4a4e..52bf3431a42 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -595,6 +595,23 @@ static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +/* When a device lives behind a bridge deeper in the PCI bus topology + * than APB, a special sequence must run to make sure all pending DMA + * transfers at the time of IRQ delivery are visible in the coherency + * domain by the cpu. This sequence is to perform a read on the far + * side of the non-APB bridge, then perform a read of Sabre's DMA + * write-sync register. + */ +static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + struct pci_dev *pdev = _arg1; + unsigned long sync_reg = (unsigned long) _arg2; + u16 _unused; + + pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused); + sabre_read(sync_reg); +} + static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -639,24 +656,14 @@ static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, if (pdev) { struct pcidev_cookie *pcp = pdev->sysdata; - /* When a device lives behind a bridge deeper in the - * PCI bus topology than APB, a special sequence must - * run to make sure all pending DMA transfers at the - * time of IRQ delivery are visible in the coherency - * domain by the cpu. This sequence is to perform - * a read on the far side of the non-APB bridge, then - * perform a read of Sabre's DMA write-sync register. - * - * Currently, the PCI_CONFIG register for the device - * is used for this read from the far side of the bridge. - */ if (pdev->bus->number != pcp->pbm->pci_first_busno) { - bucket->flags |= IBF_DMA_SYNC; - bucket->synctab_ent = dma_sync_reg_table_entry++; - dma_sync_reg_table[bucket->synctab_ent] = - (unsigned long) sabre_pci_config_mkaddr( - pcp->pbm, - pdev->bus->number, pdev->devfn, PCI_COMMAND); + struct pci_controller_info *p = pcp->pbm->parent; + struct irq_desc *d = bucket->irq_info; + + d->pre_handler = sabre_wsync_handler; + d->pre_handler_arg1 = pdev; + d->pre_handler_arg2 = (void *) + p->pbm_A.controller_regs + SABRE_WRSYNC; } } return __irq(bucket); @@ -1626,10 +1633,9 @@ void __init sabre_init(int pnode, char *model_name) */ p->pbm_A.controller_regs = pr_regs[0].phys_addr; p->pbm_B.controller_regs = pr_regs[0].phys_addr; - pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC; - printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", - p->pbm_A.controller_regs, pci_dma_wsync); + printk("PCI: Found SABRE, main regs at %016lx\n", + p->pbm_A.controller_regs); /* Clear interrupts */ diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 71b4e380769..b40db389f90 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -973,7 +973,7 @@ static void sparc64_start_timers(irqreturn_t (*cfunc)(int, void *, struct pt_reg int err; /* Register IRQ handler. */ - err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC, + err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, 0, "timer", NULL); if (err) { diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 018e2e46082..8b70edcb80d 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -16,6 +16,18 @@ #include #include +struct ino_bucket; + +#define MAX_IRQ_DESC_ACTION 4 + +struct irq_desc { + void (*pre_handler)(struct ino_bucket *, void *, void *); + void *pre_handler_arg1; + void *pre_handler_arg2; + u32 action_active_mask; + struct irqaction action[MAX_IRQ_DESC_ACTION]; +}; + /* You should not mess with this directly. That's the job of irq.c. * * If you make changes here, please update hand coded assembler of @@ -42,24 +54,11 @@ struct ino_bucket { /* Miscellaneous flags. */ /*0x06*/unsigned char flags; - /* This is used to deal with IBF_DMA_SYNC on - * Sabre systems. - */ -/*0x07*/unsigned char synctab_ent; - - /* Reference to handler for this IRQ. If this is - * non-NULL this means it is active and should be - * serviced. Else the pending member is set to one - * and later registry of the interrupt checks for - * this condition. - * - * Normally this is just an irq_action structure. - * But, on PCI, if multiple interrupt sources behind - * a bridge have multiple interrupt sources that share - * the same INO bucket, this points to an array of - * pointers to four IRQ action structures. - */ -/*0x08*/void *irq_info; + /* Currently unused. */ +/*0x07*/unsigned char __pad; + + /* Reference to IRQ descriptor for this bucket. */ +/*0x08*/struct irq_desc *irq_info; /* Sun5 Interrupt Clear Register. */ /*0x10*/unsigned long iclr; @@ -69,12 +68,6 @@ struct ino_bucket { }; -#ifdef CONFIG_PCI -extern unsigned long pci_dma_wsync; -extern unsigned long dma_sync_reg_table[256]; -extern unsigned char dma_sync_reg_table_entry; -#endif - /* IMAP/ICLR register defines */ #define IMAP_VALID 0x80000000 /* IRQ Enabled */ #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ @@ -90,11 +83,9 @@ extern unsigned char dma_sync_reg_table_entry; #define ICLR_PENDING 0x00000003 /* Pending state */ /* Only 8-bits are available, be careful. -DaveM */ -#define IBF_DMA_SYNC 0x01 /* DMA synchronization behind PCI bridge needed. */ -#define IBF_PCI 0x02 /* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt. */ -#define IBF_ACTIVE 0x04 /* This interrupt is active and has a handler. */ -#define IBF_MULTI 0x08 /* On PCI, indicates shared bucket. */ -#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ +#define IBF_PCI 0x02 /* PSYCHO/SABRE/SCHIZO PCI interrupt. */ +#define IBF_ACTIVE 0x04 /* Interrupt is active and has a handler.*/ +#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ #define NUM_IVECS (IMAP_INR + 1) extern struct ino_bucket ivector_table[NUM_IVECS]; diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index becdf1bc592..e3059bb4a46 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h @@ -162,21 +162,6 @@ struct sigstack { #define MINSIGSTKSZ 4096 #define SIGSTKSZ 16384 -#ifdef __KERNEL__ -/* - * DJHR - * SA_STATIC_ALLOC is used for the SPARC system to indicate that this - * interrupt handler's irq structure should be statically allocated - * by the request_irq routine. - * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge - * of interrupt usage and that sucks. Also without a flag like this - * it may be possible for the free_irq routine to attempt to free - * statically allocated data.. which is NOT GOOD. - * - */ -#define SA_STATIC_ALLOC 0x80 -#endif - #include struct __new_sigaction { -- cgit v1.2.3-70-g09d2 From bb6743f4f0aed5c1f09fa77cd8d3973c31792f4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 13:26:04 -0700 Subject: [SPARC64]: Do proper DMA IRQ syncing on Tomatillo This was the main impetus behind adding the PCI IRQ shim. In order to properly order DMA writes wrt. interrupts, you have to write to a PCI controller register, then poll for that bit clearing. There is one bit for each interrupt source, and setting this register bit tells Tomatillo to drain all pending DMA from that device. Furthermore, Tomatillo's with revision less than 4 require us to do a block store due to some memory transaction ordering issues it has on JBUS. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_schizo.c | 51 ++++++++++++++++++++++++++++++++++++++++ include/asm-sparc64/pbm.h | 3 +++ 2 files changed, 54 insertions(+) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 5753175b94e..68b1a63a178 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "pci_impl.h" #include "iommu_common.h" @@ -326,6 +327,44 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + unsigned long sync_reg = (unsigned long) _arg2; + u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); + u64 val; + int limit; + + schizo_write(sync_reg, mask); + + limit = 100000; + val = 0; + while (--limit) { + val = schizo_read(sync_reg); + if (!(val & mask)) + break; + } + if (limit <= 0) { + printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", + val, mask); + } + + if (_arg1) { + static unsigned char cacheline[64] + __attribute__ ((aligned (64))); + + __asm__ __volatile__("rd %%fprs, %0\n\t" + "or %0, %4, %1\n\t" + "wr %1, 0x0, %%fprs\n\t" + "stda %%f0, [%5] %6\n\t" + "wr %0, 0x0, %%fprs\n\t" + "membar #Sync" + : "=&r" (mask), "=&r" (val) + : "0" (mask), "1" (val), + "i" (FPRS_FEF), "r" (&cacheline[0]), + "i" (ASI_BLK_COMMIT_P)); + } +} + static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -369,6 +408,15 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); bucket->flags |= IBF_PCI; + if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + struct irq_desc *p = bucket->irq_info; + + p->pre_handler = tomatillo_wsync_handler; + p->pre_handler_arg1 = ((pbm->chip_version <= 4) ? + (void *) 1 : (void *) 0); + p->pre_handler_arg2 = (void *) pbm->sync_reg; + } + return __irq(bucket); } @@ -2015,6 +2063,9 @@ static void __init schizo_pbm_init(struct pci_controller_info *p, pbm->pbm_regs = pr_regs[0].phys_addr; pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; + if (chip_type == PBM_CHIP_TYPE_TOMATILLO) + pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; + sprintf(pbm->name, (chip_type == PBM_CHIP_TYPE_TOMATILLO ? "TOMATILLO%d PBM%c" : diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 4c15610a2ba..38bbbccb406 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -145,6 +145,9 @@ struct pci_pbm_info { /* Physical address base of PBM registers. */ unsigned long pbm_regs; + /* Physical address of DMA sync register, if any. */ + unsigned long sync_reg; + /* Opaque 32-bit system bus Port ID. */ u32 portid; -- cgit v1.2.3-70-g09d2 From 9fba62a59cf1407cd5495f6c61d22d169ca1553f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 14:53:33 -0700 Subject: [SPARC64]: Small Schizo PCI controller programming tweaks. Use macro instead of magic value for Tomatillo discard- timeout interrupt enable register bit. Leave OBP programming PTO value unless Tomatillo and version >= 0x2. If no-bus-parking property is present, explicitly clear PCICTRL_PARK bit. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_schizo.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 68b1a63a178..f4f68e150d7 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -933,6 +933,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) #define SCHIZO_PCI_CTRL (0x2000UL) #define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ +#define SCHIZO_PCICTRL_DTO_INT (1UL << 61UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ @@ -1939,33 +1940,25 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, SCHIZO_IRQ_RETRY_INF); - /* Enable arbiter for all PCI slots. Also, disable PCI interval - * timer so that DTO (Discard TimeOuts) are not reported because - * some Schizo revisions report them erroneously. - */ tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); - if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS && - pbm->chip_version == 0x5 && - pbm->chip_revision == 0x1) - tmp |= 0x0f; - else - tmp |= 0xff; - tmp &= ~SCHIZO_PCICTRL_PTO; + /* Enable arbiter for all PCI slots. */ + tmp |= 0xff; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - else - tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; if (!prom_getbool(pbm->prom_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; + else + tmp &= ~SCHIZO_PCICTRL_PARK; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version <= 0x1) - tmp |= (1UL << 61); + tmp |= SCHIZO_PCICTRL_DTO_INT; else - tmp &= ~(1UL << 61); + tmp &= ~SCHIZO_PCICTRL_DTO_INT; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) tmp |= (SCHIZO_PCICTRL_MRM_PREF | -- cgit v1.2.3-70-g09d2 From 864ae180074931f3a28c84ea85aa8cfeca18bc4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 15:58:19 -0700 Subject: [SPARC64]: Fix IRQ retry interval timer value on sparc64 PCI controllers. Use '5' instead of 'infinity'. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_psycho.c | 3 +-- arch/sparc64/kernel/pci_schizo.c | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 534320ef0db..91ab466d6c6 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1303,8 +1303,7 @@ static void psycho_controller_hwinit(struct pci_controller_info *p) { u64 tmp; - /* PROM sets the IRQ retry value too low, increase it. */ - psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); /* Enable arbiter for all PCI slots. */ tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index f4f68e150d7..6a182bb6628 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1936,9 +1936,7 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) { u64 tmp; - /* Set IRQ retry to infinity. */ - schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, - SCHIZO_IRQ_RETRY_INF); + schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); -- cgit v1.2.3-70-g09d2 From 6772926bef3c9f0ec761b39e5702535471fff70b Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Tue, 5 Jul 2005 18:54:50 -0700 Subject: [PATCH] kprobes: fix namespace problem and sparc64 build The following renames arch_init, a kprobes function for performing any architecture specific initialization, to arch_init_kprobes in order to cleanup the namespace. Also, this patch adds arch_init_kprobes to sparc64 to fix the sparc64 kprobes build from the last return probe patch. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 2 +- arch/ia64/kernel/kprobes.c | 2 +- arch/ppc64/kernel/kprobes.c | 2 +- arch/sparc64/kernel/kprobes.c | 5 +++++ arch/x86_64/kernel/kprobes.c | 2 +- include/linux/kprobes.h | 2 +- kernel/kprobes.c | 2 +- 7 files changed, 11 insertions(+), 6 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index fc8b1752176..a6d8c45961d 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -537,7 +537,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 3aa3167edbe..884f5cd27d8 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -713,7 +713,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { trampoline_p.addr = (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 1d2ff6d6b0b..a3d519518fb 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -444,7 +444,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index bdac631cf01..bbf11f85dab 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -433,3 +433,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +/* architecture specific initialization */ +int arch_init_kprobes(void) +{ + return 0; +} diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index acd2a778ebe..5c6dc705148 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -682,7 +682,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index b7a194c4362..e050fc2d4c2 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -155,7 +155,7 @@ extern void arch_copy_kprobe(struct kprobe *p); extern void arch_arm_kprobe(struct kprobe *p); extern void arch_disarm_kprobe(struct kprobe *p); extern void arch_remove_kprobe(struct kprobe *p); -extern int arch_init(void); +extern int arch_init_kprobes(void); extern void show_registers(struct pt_regs *regs); extern kprobe_opcode_t *get_insn_slot(void); extern void free_insn_slot(kprobe_opcode_t *slot); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 90c0e82b650..b0237122b24 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -574,7 +574,7 @@ static int __init init_kprobes(void) INIT_HLIST_HEAD(&kretprobe_inst_table[i]); } - err = arch_init(); + err = arch_init_kprobes(); if (!err) err = register_die_notifier(&kprobe_exceptions_nb); -- cgit v1.2.3-70-g09d2 From fef43da4e4341697a682f5aae1d5d428e840bc61 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 19:45:24 -0700 Subject: [SPARC64]: Fix UltraSPARC-III fallout from membar changes. The membar changes made the size of __cheetah_flush_tlb_pending grow by one instruction, but the boot-time code patching was not updated to match. Signed-off-by: David S. Miller --- arch/sparc64/mm/ultra.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 7a2431d3abc..36377089379 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -72,6 +72,7 @@ __flush_tlb_pending: flush %g6 retl wrpr %g7, 0x0, %pstate + nop .align 32 .globl __flush_tlb_kernel_range @@ -249,7 +250,7 @@ __cheetah_flush_tlb_mm: /* 15 insns */ retl wrpr %g7, 0x0, %pstate -__cheetah_flush_tlb_pending: /* 22 insns */ +__cheetah_flush_tlb_pending: /* 23 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 sllx %o1, 3, %o1 @@ -317,7 +318,7 @@ cheetah_patch_cachetlbops: sethi %hi(__cheetah_flush_tlb_pending), %o1 or %o1, %lo(__cheetah_flush_tlb_pending), %o1 call cheetah_patch_one - mov 22, %o2 + mov 23, %o2 #ifdef DCACHE_ALIASING_POSSIBLE sethi %hi(__flush_dcache_page), %o0 -- cgit v1.2.3-70-g09d2 From 12cf649f417c68b6bdd2a3b4ed97113159c6029e Mon Sep 17 00:00:00 2001 From: "Eddie C. Dost" Date: Wed, 6 Jul 2005 15:40:21 -0700 Subject: [SPARC64]: Fix set_intr_affinity() Do not cat bucket->irq_info to struct irqaction * directly, but go through struct irq_desc *. Signed-off-by: David S. Miller --- arch/sparc64/kernel/irq.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 74a2e0808cb..daa2fb93052 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -917,7 +917,8 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { struct ino_bucket *bp = ivector_table + (long)data; - struct irqaction *ap = bp->irq_info; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; cpumask_t mask; int len; @@ -935,11 +936,13 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; /* Users specify affinity in terms of hw cpu ids. * As soon as we do this, handler_irq() might see and take action. */ - put_smpaff_in_irqaction((struct irqaction *)bp->irq_info, hw_aff); + put_smpaff_in_irqaction(ap, hw_aff); /* Migration is simply done by the next cpu to service this * interrupt. -- cgit v1.2.3-70-g09d2 From dcc83a028552ac34538db52d82446d1da6ea8c22 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 8 Jul 2005 13:33:10 -0700 Subject: [SPARC64]: Typo in dtlb_backend.S, _PAGE_SZ4M --> _PAGE_SZ4MB Noticed by Eddie C. Dost Signed-off-by: David S. Miller --- arch/sparc64/kernel/dtlb_backend.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S index b73a3c85877..538522848ad 100644 --- a/arch/sparc64/kernel/dtlb_backend.S +++ b/arch/sparc64/kernel/dtlb_backend.S @@ -16,7 +16,7 @@ #elif PAGE_SHIFT == 19 #define SZ_BITS _PAGE_SZ512K #elif PAGE_SHIFT == 22 -#define SZ_BITS _PAGE_SZ4M +#define SZ_BITS _PAGE_SZ4MB #endif #define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS) -- cgit v1.2.3-70-g09d2 From a6524813e032fb33bd1de807a98f8453414335e4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 8 Jul 2005 15:21:51 -0700 Subject: [SPARC64]: Support CONFIG_HZ Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 2 ++ include/asm-sparc64/param.h | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index d78bc13ebbb..4b132928624 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -43,6 +43,8 @@ config SPARC64_PAGE_SIZE_4MB endchoice +source kernel/Kconfig.hz + source "init/Kconfig" config SYSVIPC_COMPAT diff --git a/include/asm-sparc64/param.h b/include/asm-sparc64/param.h index 6a12f3ac035..a1cd4974630 100644 --- a/include/asm-sparc64/param.h +++ b/include/asm-sparc64/param.h @@ -1,9 +1,10 @@ -/* $Id: param.h,v 1.2 2000/10/30 21:01:41 davem Exp $ */ #ifndef _ASMSPARC64_PARAM_H #define _ASMSPARC64_PARAM_H +#include + #ifdef __KERNEL__ -# define HZ 1000 /* Internal kernel timer frequency */ +# define HZ CONFIG_HZ /* Internal kernel timer frequency */ # define USER_HZ 100 /* .. some user interfaces are in "ticks" */ # define CLOCKS_PER_SEC (USER_HZ) #endif -- cgit v1.2.3-70-g09d2 From 9126dfde9e5efd76f9d4246819bdc7ea66de3af0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jul 2005 15:11:45 -0700 Subject: [SPARC]: Add ioprio system call support. Signed-off-by: David S. Miller --- arch/sparc/kernel/systbls.S | 4 ++-- arch/sparc64/kernel/sys32.S | 2 ++ arch/sparc64/kernel/systbls.S | 8 ++++---- include/asm-sparc/unistd.h | 4 ++-- include/asm-sparc64/unistd.h | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 928ffeb0fab..025f4516e65 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -57,11 +57,11 @@ sys_call_table: /*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_ni_syscall /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl -/*195*/ .long sys_epoll_wait, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask +/*195*/ .long sys_epoll_wait, sys_ioprio_set, sys_getppid, sparc_sigaction, sys_sgetmask /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo -/*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex +/*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 /*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64 diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 5a95e98c531..5f9e4fae612 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -135,6 +135,8 @@ SIGN2(sys32_shutdown, sys_shutdown, %o0, %o1) SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2) SIGN1(sys32_getpeername, sys_getpeername, %o0) SIGN1(sys32_getsockname, sys_getsockname, %o0) +SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) +SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) .globl sys32_mmap2 sys32_mmap2: diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index a5e36a4c892..bceb91a8a2b 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -59,11 +59,11 @@ sys_call_table32: /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname /*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl - .word sys32_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask + .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo - .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex + .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, sys32_adjtimex /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 /*230*/ .word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64 @@ -125,11 +125,11 @@ sys_call_table: /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname /*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl - .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask + .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo - .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex + .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid /*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64 diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 84670840390..aee17d7e2e4 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -212,7 +212,7 @@ #define __NR_epoll_create 193 /* Linux Specific */ #define __NR_epoll_ctl 194 /* Linux Specific */ #define __NR_epoll_wait 195 /* Linux Specific */ -/* #define __NR_ulimit 196 Linux Specific */ +#define __NR_ioprio_set 196 /* Linux Specific */ #define __NR_getppid 197 /* Linux Specific */ #define __NR_sigaction 198 /* Linux Specific */ #define __NR_sgetmask 199 /* Linux Specific */ @@ -234,7 +234,7 @@ #define __NR_ipc 215 /* Linux Specific */ #define __NR_sigreturn 216 /* Linux Specific */ #define __NR_clone 217 /* Linux Specific */ -/* #define __NR_modify_ldt 218 Linux Specific - i386 specific, unused */ +#define __NR_ioprio_get 218 /* Linux Specific */ #define __NR_adjtimex 219 /* Linux Specific */ #define __NR_sigprocmask 220 /* Linux Specific */ #define __NR_create_module 221 /* Linux Specific */ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 5b8dcf5786a..f59144c6b76 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -212,7 +212,7 @@ #define __NR_epoll_create 193 /* Linux Specific */ #define __NR_epoll_ctl 194 /* Linux Specific */ #define __NR_epoll_wait 195 /* Linux Specific */ -/* #define __NR_ulimit 196 Linux Specific */ +#define __NR_ioprio_set 196 /* Linux Specific */ #define __NR_getppid 197 /* Linux Specific */ #define __NR_sigaction 198 /* Linux Specific */ #define __NR_sgetmask 199 /* Linux Specific */ @@ -234,7 +234,7 @@ #define __NR_ipc 215 /* Linux Specific */ #define __NR_sigreturn 216 /* Linux Specific */ #define __NR_clone 217 /* Linux Specific */ -/* #define __NR_modify_ldt 218 Linux Specific - i386 specific, unused */ +#define __NR_ioprio_get 218 /* Linux Specific */ #define __NR_adjtimex 219 /* Linux Specific */ #define __NR_sigprocmask 220 /* Linux Specific */ #define __NR_create_module 221 /* Linux Specific */ -- cgit v1.2.3-70-g09d2 From d369ddd2fc00fc3f46e9052d1017cbf407e3cdf7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jul 2005 15:45:11 -0700 Subject: [SPARC64]: Add __read_mostly support. Signed-off-by: David S. Miller --- arch/sparc64/kernel/smp.c | 10 +++++----- arch/sparc64/kernel/time.c | 24 +++++++++--------------- arch/sparc64/kernel/vmlinux.lds.S | 2 ++ include/linux/cache.h | 2 +- 4 files changed, 17 insertions(+), 21 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index e5b9c7a2778..441fc2e52ce 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -45,8 +45,8 @@ extern void calibrate_delay(void); /* Please don't make this stuff initdata!!! --DaveM */ static unsigned char boot_cpu_id; -cpumask_t cpu_online_map = CPU_MASK_NONE; -cpumask_t phys_cpu_present_map = CPU_MASK_NONE; +cpumask_t cpu_online_map = CPU_MASK_NONE __read_mostly; +cpumask_t phys_cpu_present_map = CPU_MASK_NONE __read_mostly; static cpumask_t smp_commenced_mask; static cpumask_t cpu_callout_map; @@ -155,7 +155,7 @@ void cpu_panic(void) panic("SMP bolixed\n"); } -static unsigned long current_tick_offset; +static unsigned long current_tick_offset __read_mostly; /* This tick register synchronization scheme is taken entirely from * the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit. @@ -1193,8 +1193,8 @@ void smp_send_stop(void) { } -unsigned long __per_cpu_base; -unsigned long __per_cpu_shift; +unsigned long __per_cpu_base __read_mostly; +unsigned long __per_cpu_shift __read_mostly; EXPORT_SYMBOL(__per_cpu_base); EXPORT_SYMBOL(__per_cpu_shift); diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index b40db389f90..362b9c26871 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -73,7 +73,7 @@ static __initdata struct sparc64_tick_ops dummy_tick_ops = { .get_tick = dummy_get_tick, }; -struct sparc64_tick_ops *tick_ops = &dummy_tick_ops; +struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops; #define TICK_PRIV_BIT (1UL << 63) @@ -195,7 +195,7 @@ static unsigned long tick_add_tick(unsigned long adj, unsigned long offset) return new_tick; } -static struct sparc64_tick_ops tick_operations = { +static struct sparc64_tick_ops tick_operations __read_mostly = { .init_tick = tick_init_tick, .get_tick = tick_get_tick, .get_compare = tick_get_compare, @@ -276,7 +276,7 @@ static unsigned long stick_add_compare(unsigned long adj) return new_compare; } -static struct sparc64_tick_ops stick_operations = { +static struct sparc64_tick_ops stick_operations __read_mostly = { .init_tick = stick_init_tick, .get_tick = stick_get_tick, .get_compare = stick_get_compare, @@ -422,7 +422,7 @@ static unsigned long hbtick_add_compare(unsigned long adj) return val; } -static struct sparc64_tick_ops hbtick_operations = { +static struct sparc64_tick_ops hbtick_operations __read_mostly = { .init_tick = hbtick_init_tick, .get_tick = hbtick_get_tick, .get_compare = hbtick_get_compare, @@ -437,10 +437,9 @@ static struct sparc64_tick_ops hbtick_operations = { * NOTE: On SUN5 systems the ticker interrupt comes in using 2 * interrupts, one at level14 and one with softint bit 0. */ -unsigned long timer_tick_offset; -unsigned long timer_tick_compare; +unsigned long timer_tick_offset __read_mostly; -static unsigned long timer_ticks_per_nsec_quotient; +static unsigned long timer_ticks_per_nsec_quotient __read_mostly; #define TICK_SIZE (tick_nsec / 1000) @@ -464,7 +463,7 @@ static inline void timer_check_rtc(void) static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - unsigned long ticks, pstate; + unsigned long ticks, compare, pstate; write_seqlock(&xtime_lock); @@ -483,14 +482,14 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) : "=r" (pstate) : "i" (PSTATE_IE)); - timer_tick_compare = tick_ops->add_compare(timer_tick_offset); + compare = tick_ops->add_compare(timer_tick_offset); ticks = tick_ops->get_tick(); /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : /* no outputs */ : "r" (pstate)); - } while (time_after_eq(ticks, timer_tick_compare)); + } while (time_after_eq(ticks, compare)); timer_check_rtc(); @@ -506,11 +505,6 @@ void timer_tick_interrupt(struct pt_regs *regs) do_timer(regs); - /* - * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR. - */ - timer_tick_compare = tick_ops->get_compare() + timer_tick_offset; - timer_check_rtc(); write_sequnlock(&xtime_lock); diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index 382fd6798bb..950423da8a6 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S @@ -32,6 +32,8 @@ SECTIONS .data1 : { *(.data1) } . = ALIGN(64); .data.cacheline_aligned : { *(.data.cacheline_aligned) } + . = ALIGN(64); + .data.read_mostly : { *(.data.read_mostly) } _edata = .; PROVIDE (edata = .); .fixup : { *(.fixup) } diff --git a/include/linux/cache.h b/include/linux/cache.h index 2b66a36d85f..f6b5a46c5f8 100644 --- a/include/linux/cache.h +++ b/include/linux/cache.h @@ -13,7 +13,7 @@ #define SMP_CACHE_BYTES L1_CACHE_BYTES #endif -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) #define __read_mostly __attribute__((__section__(".data.read_mostly"))) #else #define __read_mostly -- cgit v1.2.3-70-g09d2 From af166d15c3ad4d501a0c4fb5b4547bb2ba205918 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jul 2005 15:56:40 -0700 Subject: [SPARC64]: Kill ancient and unused SYSCALL_TRACING debugging code. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 18 ------------------ arch/sparc64/mm/fault.c | 16 ---------------- 2 files changed, 34 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index d3973d8a719..b51bd14cde4 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -22,8 +22,6 @@ #include #include -/* #define SYSCALL_TRACING 1 */ - #define curptr g6 #define NR_SYSCALLS 284 /* Each OS is different... */ @@ -1671,11 +1669,6 @@ linux_sparc_syscall32: bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI srl %i0, 0, %o0 ! IEU0 sll %g1, 2, %l4 ! IEU0 Group -#ifdef SYSCALL_TRACING - call syscall_trace_entry - add %sp, PTREGS_OFF, %o0 - srl %i0, 0, %o0 -#endif srl %i4, 0, %o4 ! IEU1 lduw [%l7 + %l4], %l7 ! Load srl %i1, 0, %o1 ! IEU0 Group @@ -1699,11 +1692,6 @@ linux_sparc_syscall: bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI mov %i0, %o0 ! IEU0 sll %g1, 2, %l4 ! IEU0 Group -#ifdef SYSCALL_TRACING - call syscall_trace_entry - add %sp, PTREGS_OFF, %o0 - mov %i0, %o0 -#endif mov %i1, %o1 ! IEU1 lduw [%l7 + %l4], %l7 ! Load 4: mov %i2, %o2 ! IEU0 Group @@ -1720,12 +1708,6 @@ linux_sparc_syscall: 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ret_sys_call: -#ifdef SYSCALL_TRACING - mov %o0, %o1 - call syscall_trace_exit - add %sp, PTREGS_OFF, %o0 - mov %o1, %o0 -#endif ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc sra %o0, 0, %o0 diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 3ffee7b51ae..52e9375288a 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -33,22 +33,6 @@ extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; -/* - * To debug kernel during syscall entry. - */ -void syscall_trace_entry(struct pt_regs *regs) -{ - printk("scall entry: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]); -} - -/* - * To debug kernel during syscall exit. - */ -void syscall_trace_exit(struct pt_regs *regs) -{ - printk("scall exit: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]); -} - /* * To debug kernel to catch accesses to certain virtual/physical addresses. * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. -- cgit v1.2.3-70-g09d2 From bb49bcda15f1bc1a52c7f887db278447f332eaa7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jul 2005 16:49:28 -0700 Subject: [SPARC64]: Add SECCOMP support. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 17 +++++++++++++++++ arch/sparc64/kernel/entry.S | 10 +++++----- arch/sparc64/kernel/power.c | 3 ++- arch/sparc64/kernel/ptrace.c | 12 ++++-------- include/asm-sparc64/thread_info.h | 3 ++- 5 files changed, 30 insertions(+), 15 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 4b132928624..6a4733683f0 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -43,6 +43,23 @@ config SPARC64_PAGE_SIZE_4MB endchoice +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc//seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + source kernel/Kconfig.hz source "init/Kconfig" diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index b51bd14cde4..acc323eef53 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1552,7 +1552,7 @@ sys_ptrace: add %sp, PTREGS_OFF, %o0 nop .align 32 1: ldx [%curptr + TI_FLAGS], %l5 - andcc %l5, _TIF_SYSCALL_TRACE, %g0 + andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 be,pt %icc, rtrap clr %l6 call syscall_trace @@ -1676,7 +1676,7 @@ linux_sparc_syscall32: srl %i5, 0, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU0 Group + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 ! IEU0 Group bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 call %l7 ! CTI Group brk forced @@ -1699,7 +1699,7 @@ linux_sparc_syscall: mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU1 Group+1 bubble + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 ! IEU1 Group+1 bubble bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -1727,7 +1727,7 @@ ret_sys_call: 1: cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, _TIF_SYSCALL_TRACE, %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %l6 80: /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 @@ -1742,7 +1742,7 @@ ret_sys_call: /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ - andcc %l0, _TIF_SYSCALL_TRACE, %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %l6 sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 52f14e399b1..533104c7907 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -4,6 +4,8 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ +#define __KERNEL_SYSCALLS__ + #include #include #include @@ -17,7 +19,6 @@ #include #include -#define __KERNEL_SYSCALLS__ #include /* diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 80a76e2ad73..5abf596f596 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -630,9 +630,9 @@ out: asmlinkage void syscall_trace(void) { -#ifdef DEBUG_PTRACE - printk("%s [%d]: syscall_trace\n", current->comm, current->pid); -#endif + /* do the secure computing check first */ + secure_computing(current_thread_info()->kregs->u_regs[UREG_G1]); + if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; if (!(current->ptrace & PT_PTRACED)) @@ -645,12 +645,8 @@ asmlinkage void syscall_trace(void) * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ -#ifdef DEBUG_PTRACE - printk("%s [%d]: syscall_trace exit= %x\n", current->comm, - current->pid, current->exit_code); -#endif if (current->exit_code) { - send_sig (current->exit_code, current, 1); + send_sig(current->exit_code, current, 1); current->exit_code = 0; } } diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index 0cd65295692..6b2fbb89bb6 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h @@ -220,7 +220,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define TIF_NEWSIGNALS 6 /* wants new-style signals */ #define TIF_32BIT 7 /* 32-bit binary */ #define TIF_NEWCHILD 8 /* just-spawned child process */ -/* TIF_* value 9 is available */ +#define TIF_SECCOMP 9 /* secure computing */ #define TIF_POLLING_NRFLAG 10 #define TIF_SYSCALL_SUCCESS 11 /* NOTE: Thread flags >= 12 should be ones we have no interest @@ -239,6 +239,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_NEWSIGNALS (1< Date: Sun, 10 Jul 2005 16:55:48 -0700 Subject: [SPARC64]: Pass regs and entry/exit boolean to syscall_trace() Also fix a bug in 32-bit syscall tracing. We forgot to update this code when we moved over to the convention that all 32-bit syscall arguments are zero extended by default. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 14 +++++++++----- arch/sparc64/kernel/ptrace.c | 4 ++-- arch/sparc64/kernel/sparc64_ksyms.c | 2 +- arch/sparc64/solaris/entry64.S | 7 +++++-- 4 files changed, 17 insertions(+), 10 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index acc323eef53..8b7ed760c50 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1555,8 +1555,9 @@ sys_ptrace: add %sp, PTREGS_OFF, %o0 andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 be,pt %icc, rtrap clr %l6 + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + mov 1, %o1 ba,pt %xcc, rtrap clr %l6 @@ -1640,18 +1641,20 @@ linux_sparc_ni_syscall: or %l7, %lo(sys_ni_syscall), %l7 linux_syscall_trace32: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + clr %o1 srl %i0, 0, %o0 - mov %i4, %o4 + srl %i4, 0, %o4 srl %i1, 0, %o1 srl %i2, 0, %o2 b,pt %xcc, 2f srl %i3, 0, %o3 linux_syscall_trace: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + clr %o1 mov %i0, %o0 mov %i1, %o1 mov %i2, %o2 @@ -1755,8 +1758,9 @@ ret_sys_call: b,pt %xcc, rtrap stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] linux_syscall_trace2: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + mov 1, %o1 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ba,pt %xcc, rtrap stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 5abf596f596..c57dc9ea731 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -628,10 +628,10 @@ out: unlock_kernel(); } -asmlinkage void syscall_trace(void) +asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) { /* do the secure computing check first */ - secure_computing(current_thread_info()->kregs->u_regs[UREG_G1]); + secure_computing(regs->u_regs[UREG_G1]); if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 56cd96f4a5c..9202d925a9c 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -79,7 +79,7 @@ extern void linux_sparc_syscall(void); extern void rtrap(void); extern void show_regs(struct pt_regs *); extern void solaris_syscall(void); -extern void syscall_trace(void); +extern void syscall_trace(struct pt_regs *, int); extern u32 sunos_sys_table[], sys_call_table32[]; extern void tl0_solaris(void); extern void sys_sigsuspend(void); diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S index 0cc9dad75c5..4b6ae583c0a 100644 --- a/arch/sparc64/solaris/entry64.S +++ b/arch/sparc64/solaris/entry64.S @@ -24,8 +24,9 @@ .text solaris_syscall_trace: + add %sp, PTREGS_OFF, %o0 call syscall_trace - nop + mov 0, %o1 srl %i0, 0, %o0 mov %i4, %o4 srl %i1, 0, %o1 @@ -159,8 +160,10 @@ ret_from_solaris: stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 solaris_syscall_trace2: + add %sp, PTREGS_OFF, %o0 call syscall_trace - add %l1, 0x4, %l2 /* npc = npc+4 */ + mov 1, %o1 + add %l1, 0x4, %l2 /* npc = npc+4 */ andcc %l1, 1, %g0 bne,pn %icc, 2b nop -- cgit v1.2.3-70-g09d2 From f7ceba360cce9af3fbc4e5a5b1bd40b570b7021c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jul 2005 19:29:45 -0700 Subject: [SPARC64]: Add syscall auditing support. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 10 +++++----- arch/sparc64/kernel/ptrace.c | 32 +++++++++++++++++++++++++++++--- include/asm-sparc64/thread_info.h | 8 +++++--- include/linux/audit.h | 2 +- init/Kconfig | 2 +- 5 files changed, 41 insertions(+), 13 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 8b7ed760c50..d781f10adc5 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1552,7 +1552,7 @@ sys_ptrace: add %sp, PTREGS_OFF, %o0 nop .align 32 1: ldx [%curptr + TI_FLAGS], %l5 - andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 + andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 be,pt %icc, rtrap clr %l6 add %sp, PTREGS_OFF, %o0 @@ -1679,7 +1679,7 @@ linux_sparc_syscall32: srl %i5, 0, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 ! IEU0 Group + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 call %l7 ! CTI Group brk forced @@ -1702,7 +1702,7 @@ linux_sparc_syscall: mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %g0 ! IEU1 Group+1 bubble + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -1730,7 +1730,7 @@ ret_sys_call: 1: cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 80: /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 @@ -1745,7 +1745,7 @@ ret_sys_call: /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP), %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index c57dc9ea731..23ad839d113 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -633,10 +635,22 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) /* do the secure computing check first */ secure_computing(regs->u_regs[UREG_G1]); - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; + if (unlikely(current->audit_context) && syscall_exit_p) { + unsigned long tstate = regs->tstate; + int result = AUDITSC_SUCCESS; + + if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) + result = AUDITSC_FAILURE; + + audit_syscall_exit(current, result, regs->u_regs[UREG_I0]); + } + if (!(current->ptrace & PT_PTRACED)) - return; + goto out; + + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + goto out; + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); @@ -649,4 +663,16 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) send_sig(current->exit_code, current, 1); current->exit_code = 0; } + +out: + if (unlikely(current->audit_context) && !syscall_exit_p) + audit_syscall_entry(current, + (test_thread_flag(TIF_32BIT) ? + AUDIT_ARCH_SPARC : + AUDIT_ARCH_SPARC64), + regs->u_regs[UREG_G1], + regs->u_regs[UREG_I0], + regs->u_regs[UREG_I1], + regs->u_regs[UREG_I2], + regs->u_regs[UREG_I3]); } diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index 6b2fbb89bb6..a1d25c06f92 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h @@ -221,7 +221,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define TIF_32BIT 7 /* 32-bit binary */ #define TIF_NEWCHILD 8 /* just-spawned child process */ #define TIF_SECCOMP 9 /* secure computing */ -#define TIF_POLLING_NRFLAG 10 +#define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */ #define TIF_SYSCALL_SUCCESS 11 /* NOTE: Thread flags >= 12 should be ones we have no interest * in using in assembly, else we can't use the mask as @@ -229,6 +229,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); */ #define TIF_ABI_PENDING 12 #define TIF_MEMDIE 13 +#define TIF_POLLING_NRFLAG 14 #define _TIF_SYSCALL_TRACE (1< Date: Sat, 2 Jul 2005 18:15:49 +0200 Subject: [PATCH] I2C: Move hwmon drivers (1/3) Part 1: Configuration files and Makefiles. From: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig | 2 + arch/h8300/Kconfig | 2 + arch/sparc64/Kconfig | 2 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/hwmon/Kconfig | 420 +++++++++++++++++++++++++++++++++++++++++++++ drivers/hwmon/Makefile | 44 +++++ drivers/i2c/chips/Kconfig | 402 +------------------------------------------ drivers/i2c/chips/Makefile | 38 +--- 9 files changed, 476 insertions(+), 437 deletions(-) create mode 100644 drivers/hwmon/Kconfig create mode 100644 drivers/hwmon/Makefile (limited to 'arch/sparc64') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8752751f998..0fb8a04c311 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -744,6 +744,8 @@ source "drivers/char/Kconfig" source "drivers/i2c/Kconfig" +source "drivers/hwmon/Kconfig" + #source "drivers/l3/Kconfig" source "drivers/misc/Kconfig" diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 62a89e812e3..917286087c5 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -179,6 +179,8 @@ source "drivers/serial/Kconfig" source "drivers/i2c/Kconfig" +source "drivers/hwmon/Kconfig" + source "drivers/usb/Kconfig" endmenu diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 6a4733683f0..5e8591c427f 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -647,6 +647,8 @@ source "drivers/input/Kconfig" source "drivers/i2c/Kconfig" +source "drivers/hwmon/Kconfig" + source "fs/Kconfig" source "drivers/media/Kconfig" diff --git a/drivers/Kconfig b/drivers/Kconfig index aed4a9b97c1..cf087de3b3a 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -44,6 +44,8 @@ source "drivers/i2c/Kconfig" source "drivers/w1/Kconfig" +source "drivers/hwmon/Kconfig" + source "drivers/misc/Kconfig" source "drivers/media/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 3167be54fed..126a851d565 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_W1) += w1/ +obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_MD) += md/ obj-$(CONFIG_BT) += bluetooth/ diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig new file mode 100644 index 00000000000..140d5f851a5 --- /dev/null +++ b/drivers/hwmon/Kconfig @@ -0,0 +1,420 @@ +# +# I2C Sensor chip drivers configuration +# + +menu "Hardware Monitoring support" + +config HWMON + tristate "Hardware Monitoring support" + default y + help + Hardware monitoring devices let you monitor the hardware health + of a system. Most modern motherboards include such a device. It + can include temperature sensors, voltage sensors, fan speed + sensors and various additional features such as the ability to + control the speed of the fans. + +config SENSORS_ADM1021 + tristate "Analog Devices ADM1021 and compatibles" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for Analog Devices ADM1021 + and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, + Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10, + and the XEON processor built-in sensor. + + This driver can also be built as a module. If so, the module + will be called adm1021. + +config SENSORS_ADM1025 + tristate "Analog Devices ADM1025 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Analog Devices ADM1025 + and Philips NE1619 sensor chips. + + This driver can also be built as a module. If so, the module + will be called adm1025. + +config SENSORS_ADM1026 + tristate "Analog Devices ADM1026 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Analog Devices ADM1026 + sensor chip. + + This driver can also be built as a module. If so, the module + will be called adm1026. + +config SENSORS_ADM1031 + tristate "Analog Devices ADM1031 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Analog Devices ADM1031 + and ADM1030 sensor chips. + + This driver can also be built as a module. If so, the module + will be called adm1031. + +config SENSORS_ADM9240 + tristate "Analog Devices ADM9240 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Analog Devices ADM9240, + Dallas DS1780, National Semiconductor LM81 sensor chips. + + This driver can also be built as a module. If so, the module + will be called adm9240. + +config SENSORS_ASB100 + tristate "Asus ASB100 Bach" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for the ASB100 Bach sensor + chip found on some Asus mainboards. + + This driver can also be built as a module. If so, the module + will be called asb100. + +config SENSORS_ATXP1 + tristate "Attansic ATXP1 VID controller" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for the Attansic ATXP1 VID + controller. + + If your board have such a chip, you are able to control your CPU + core and other voltages. + + This driver can also be built as a module. If so, the module + will be called atxp1. + +config SENSORS_DS1621 + tristate "Dallas Semiconductor DS1621 and DS1625" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Dallas Semiconductor + DS1621 and DS1625 sensor chips. + + This driver can also be built as a module. If so, the module + will be called ds1621. + +config SENSORS_FSCHER + tristate "FSC Hermes" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Fujitsu Siemens + Computers Hermes sensor chips. + + This driver can also be built as a module. If so, the module + will be called fscher. + +config SENSORS_FSCPOS + tristate "FSC Poseidon" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Fujitsu Siemens + Computers Poseidon sensor chips. + + This driver can also be built as a module. If so, the module + will be called fscpos. + +config SENSORS_GL518SM + tristate "Genesys Logic GL518SM" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for Genesys Logic GL518SM + sensor chips. + + This driver can also be built as a module. If so, the module + will be called gl518sm. + +config SENSORS_GL520SM + tristate "Genesys Logic GL520SM" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Genesys Logic GL520SM + sensor chips. + + This driver can also be built as a module. If so, the module + will be called gl520sm. + +config SENSORS_IT87 + tristate "ITE IT87xx and compatibles" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for ITE IT87xx sensor chips + and clones: SiS960. + + This driver can also be built as a module. If so, the module + will be called it87. + +config SENSORS_LM63 + tristate "National Semiconductor LM63" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for the National Semiconductor + LM63 remote diode digital temperature sensor with integrated fan + control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro) + motherboard, among others. + + This driver can also be built as a module. If so, the module + will be called lm63. + +config SENSORS_LM75 + tristate "National Semiconductor LM75 and compatibles" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM75 + sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in + 9-bit precision mode), and TelCom (now Microchip) TCN75. + + The DS75 and DS1775 in 10- to 12-bit precision modes will require + a force module parameter. The driver will not handle the extra + precision anyhow. + + This driver can also be built as a module. If so, the module + will be called lm75. + +config SENSORS_LM77 + tristate "National Semiconductor LM77" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM77 + sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm77. + +config SENSORS_LM78 + tristate "National Semiconductor LM78 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM78, + LM78-J and LM79. + + This driver can also be built as a module. If so, the module + will be called lm78. + +config SENSORS_LM80 + tristate "National Semiconductor LM80" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor + LM80 sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm80. + +config SENSORS_LM83 + tristate "National Semiconductor LM83" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor + LM83 sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm83. + +config SENSORS_LM85 + tristate "National Semiconductor LM85 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM85 + sensor chips and clones: ADT7463, EMC6D100, EMC6D102 and ADM1027. + + This driver can also be built as a module. If so, the module + will be called lm85. + +config SENSORS_LM87 + tristate "National Semiconductor LM87" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM87 + sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm87. + +config SENSORS_LM90 + tristate "National Semiconductor LM90 and compatibles" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM90, + LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and + MAX6658 sensor chips. + + The Analog Devices ADT7461 sensor chip is also supported, but only + if found in ADM1032 compatibility mode. + + This driver can also be built as a module. If so, the module + will be called lm90. + +config SENSORS_LM92 + tristate "National Semiconductor LM92 and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor LM92 + and Maxim MAX6635 sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm92. + +config SENSORS_MAX1619 + tristate "Maxim MAX1619 sensor chip" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for MAX1619 sensor chip. + + This driver can also be built as a module. If so, the module + will be called max1619. + +config SENSORS_PC87360 + tristate "National Semiconductor PC87360 family" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get access to the hardware monitoring + functions of the National Semiconductor PC8736x Super-I/O chips. + The PC87360, PC87363 and PC87364 only have fan monitoring and + control. The PC87365 and PC87366 additionally have voltage and + temperature monitoring. + + This driver can also be built as a module. If so, the module + will be called pc87360. + +config SENSORS_SIS5595 + tristate "Silicon Integrated Systems Corp. SiS5595" + depends on HWMON && I2C && PCI && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get support for the integrated sensors in + SiS5595 South Bridges. + + This driver can also be built as a module. If so, the module + will be called sis5595. + +config SENSORS_SMSC47M1 + tristate "SMSC LPC47M10x and compatibles" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get support for the integrated fan + monitoring and control capabilities of the SMSC LPC47B27x, + LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips. + + This driver can also be built as a module. If so, the module + will be called smsc47m1. + +config SENSORS_SMSC47B397 + tristate "SMSC LPC47B397-NC" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get support for the SMSC LPC47B397-NC + sensor chip. + + This driver can also be built as a module. If so, the module + will be called smsc47b397. + +config SENSORS_VIA686A + tristate "VIA686A" + depends on HWMON && I2C && PCI + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get support for the integrated sensors in + Via 686A/B South Bridges. + + This driver can also be built as a module. If so, the module + will be called via686a. + +config SENSORS_W83781D + tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" + depends on HWMON && I2C + select I2C_SENSOR + help + If you say yes here you get support for the Winbond W8378x series + of sensor chips: the W83781D, W83782D, W83783S and W83627HF, + and the similar Asus AS99127F. + + This driver can also be built as a module. If so, the module + will be called w83781d. + +config SENSORS_W83L785TS + tristate "Winbond W83L785TS-S" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for the Winbond W83L785TS-S + sensor chip, which is used on the Asus A7N8X, among other + motherboards. + + This driver can also be built as a module. If so, the module + will be called w83l785ts. + +config SENSORS_W83627HF + tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get support for the Winbond W836X7 series + of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF + + This driver can also be built as a module. If so, the module + will be called w83627hf. + +config SENSORS_W83627EHF + tristate "Winbond W83627EHF" + depends on HWMON && I2C && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get preliminary support for the hardware + monitoring functionality of the Winbond W83627EHF Super-I/O chip. + Only fan and temperature inputs are supported at the moment, while + the chip does much more than that. + + This driver can also be built as a module. If so, the module + will be called w83627ehf. + +config HWMON_DEBUG_CHIP + bool "Hardware Monitoring Chip debugging messages" + depends on HWMON + default n + help + Say Y here if you want the I2C chip drivers to produce a bunch of + debug messages to the system log. Select this if you are having + a problem with I2C support and want to see more of what is going + on. + +endmenu diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile new file mode 100644 index 00000000000..2781403a023 --- /dev/null +++ b/drivers/hwmon/Makefile @@ -0,0 +1,44 @@ +# +# Makefile for sensor chip drivers. +# + +# asb100, then w83781d go first, as they can override other drivers' addresses. +obj-$(CONFIG_SENSORS_ASB100) += asb100.o +obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o +obj-$(CONFIG_SENSORS_W83781D) += w83781d.o + +obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o +obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o +obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o +obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o +obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o +obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o +obj-$(CONFIG_SENSORS_DS1621) += ds1621.o +obj-$(CONFIG_SENSORS_FSCHER) += fscher.o +obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o +obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o +obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o +obj-$(CONFIG_SENSORS_IT87) += it87.o +obj-$(CONFIG_SENSORS_LM63) += lm63.o +obj-$(CONFIG_SENSORS_LM75) += lm75.o +obj-$(CONFIG_SENSORS_LM77) += lm77.o +obj-$(CONFIG_SENSORS_LM78) += lm78.o +obj-$(CONFIG_SENSORS_LM80) += lm80.o +obj-$(CONFIG_SENSORS_LM83) += lm83.o +obj-$(CONFIG_SENSORS_LM85) += lm85.o +obj-$(CONFIG_SENSORS_LM87) += lm87.o +obj-$(CONFIG_SENSORS_LM90) += lm90.o +obj-$(CONFIG_SENSORS_LM92) += lm92.o +obj-$(CONFIG_SENSORS_MAX1619) += max1619.o +obj-$(CONFIG_SENSORS_PC87360) += pc87360.o +obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o +obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o +obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o +obj-$(CONFIG_SENSORS_VIA686A) += via686a.o +obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o +obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o + +ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) +EXTRA_CFLAGS += -DDEBUG +endif + diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index fddfc11b297..43f70dbfc03 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -1,410 +1,12 @@ # -# I2C Sensor and "other" chip configuration +# Miscellaneous I2C chip drivers configuration # -menu "Hardware Sensors Chip support" - depends on I2C - config I2C_SENSOR tristate default n -config SENSORS_ADM1021 - tristate "Analog Devices ADM1021 and compatibles" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for Analog Devices ADM1021 - and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, - Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10, - and the XEON processor built-in sensor. - - This driver can also be built as a module. If so, the module - will be called adm1021. - -config SENSORS_ADM1025 - tristate "Analog Devices ADM1025 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Analog Devices ADM1025 - and Philips NE1619 sensor chips. - - This driver can also be built as a module. If so, the module - will be called adm1025. - -config SENSORS_ADM1026 - tristate "Analog Devices ADM1026 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Analog Devices ADM1026 - sensor chip. - - This driver can also be built as a module. If so, the module - will be called adm1026. - -config SENSORS_ADM1031 - tristate "Analog Devices ADM1031 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Analog Devices ADM1031 - and ADM1030 sensor chips. - - This driver can also be built as a module. If so, the module - will be called adm1031. - -config SENSORS_ADM9240 - tristate "Analog Devices ADM9240 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Analog Devices ADM9240, - Dallas DS1780, National Semiconductor LM81 sensor chips. - - This driver can also be built as a module. If so, the module - will be called adm9240. - -config SENSORS_ASB100 - tristate "Asus ASB100 Bach" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for the ASB100 Bach sensor - chip found on some Asus mainboards. - - This driver can also be built as a module. If so, the module - will be called asb100. - -config SENSORS_ATXP1 - tristate "Attansic ATXP1 VID controller" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for the Attansic ATXP1 VID - controller. - - If your board have such a chip, you are able to control your CPU - core and other voltages. - - This driver can also be built as a module. If so, the module - will be called atxp1. - -config SENSORS_DS1621 - tristate "Dallas Semiconductor DS1621 and DS1625" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Dallas Semiconductor - DS1621 and DS1625 sensor chips. - - This driver can also be built as a module. If so, the module - will be called ds1621. - -config SENSORS_FSCHER - tristate "FSC Hermes" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Fujitsu Siemens - Computers Hermes sensor chips. - - This driver can also be built as a module. If so, the module - will be called fscher. - -config SENSORS_FSCPOS - tristate "FSC Poseidon" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Fujitsu Siemens - Computers Poseidon sensor chips. - - This driver can also be built as a module. If so, the module - will be called fscpos. - -config SENSORS_GL518SM - tristate "Genesys Logic GL518SM" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for Genesys Logic GL518SM - sensor chips. - - This driver can also be built as a module. If so, the module - will be called gl518sm. - -config SENSORS_GL520SM - tristate "Genesys Logic GL520SM" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for Genesys Logic GL520SM - sensor chips. - - This driver can also be built as a module. If so, the module - will be called gl520sm. - -config SENSORS_IT87 - tristate "ITE IT87xx and compatibles" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for ITE IT87xx sensor chips - and clones: SiS960. - - This driver can also be built as a module. If so, the module - will be called it87. - -config SENSORS_LM63 - tristate "National Semiconductor LM63" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for the National Semiconductor - LM63 remote diode digital temperature sensor with integrated fan - control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro) - motherboard, among others. - - This driver can also be built as a module. If so, the module - will be called lm63. - -config SENSORS_LM75 - tristate "National Semiconductor LM75 and compatibles" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM75 - sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in - 9-bit precision mode), and TelCom (now Microchip) TCN75. - - The DS75 and DS1775 in 10- to 12-bit precision modes will require - a force module parameter. The driver will not handle the extra - precision anyhow. - - This driver can also be built as a module. If so, the module - will be called lm75. - -config SENSORS_LM77 - tristate "National Semiconductor LM77" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM77 - sensor chips. - - This driver can also be built as a module. If so, the module - will be called lm77. - -config SENSORS_LM78 - tristate "National Semiconductor LM78 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM78, - LM78-J and LM79. - - This driver can also be built as a module. If so, the module - will be called lm78. - -config SENSORS_LM80 - tristate "National Semiconductor LM80" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor - LM80 sensor chips. - - This driver can also be built as a module. If so, the module - will be called lm80. - -config SENSORS_LM83 - tristate "National Semiconductor LM83" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor - LM83 sensor chips. - - This driver can also be built as a module. If so, the module - will be called lm83. - -config SENSORS_LM85 - tristate "National Semiconductor LM85 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM85 - sensor chips and clones: ADT7463, EMC6D100, EMC6D102 and ADM1027. - - This driver can also be built as a module. If so, the module - will be called lm85. - -config SENSORS_LM87 - tristate "National Semiconductor LM87" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM87 - sensor chips. - - This driver can also be built as a module. If so, the module - will be called lm87. - -config SENSORS_LM90 - tristate "National Semiconductor LM90 and compatibles" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM90, - LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and - MAX6658 sensor chips. - - The Analog Devices ADT7461 sensor chip is also supported, but only - if found in ADM1032 compatibility mode. - - This driver can also be built as a module. If so, the module - will be called lm90. - -config SENSORS_LM92 - tristate "National Semiconductor LM92 and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for National Semiconductor LM92 - and Maxim MAX6635 sensor chips. - - This driver can also be built as a module. If so, the module - will be called lm92. - -config SENSORS_MAX1619 - tristate "Maxim MAX1619 sensor chip" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for MAX1619 sensor chip. - - This driver can also be built as a module. If so, the module - will be called max1619. - -config SENSORS_PC87360 - tristate "National Semiconductor PC87360 family" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get access to the hardware monitoring - functions of the National Semiconductor PC8736x Super-I/O chips. - The PC87360, PC87363 and PC87364 only have fan monitoring and - control. The PC87365 and PC87366 additionally have voltage and - temperature monitoring. - - This driver can also be built as a module. If so, the module - will be called pc87360. - -config SENSORS_SMSC47B397 - tristate "SMSC LPC47B397-NC" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get support for the SMSC LPC47B397-NC - sensor chip. - - This driver can also be built as a module. If so, the module - will be called smsc47b397. - -config SENSORS_SIS5595 - tristate "Silicon Integrated Systems Corp. SiS5595" - depends on I2C && PCI && EXPERIMENTAL - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get support for the integrated sensors in - SiS5595 South Bridges. - - This driver can also be built as a module. If so, the module - will be called sis5595. - -config SENSORS_SMSC47M1 - tristate "SMSC LPC47M10x and compatibles" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get support for the integrated fan - monitoring and control capabilities of the SMSC LPC47B27x, - LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips. - - This driver can also be built as a module. If so, the module - will be called smsc47m1. - -config SENSORS_VIA686A - tristate "VIA686A" - depends on I2C && PCI - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get support for the integrated sensors in - Via 686A/B South Bridges. - - This driver can also be built as a module. If so, the module - will be called via686a. - -config SENSORS_W83781D - tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" - depends on I2C - select I2C_SENSOR - help - If you say yes here you get support for the Winbond W8378x series - of sensor chips: the W83781D, W83782D, W83783S and W83627HF, - and the similar Asus AS99127F. - - This driver can also be built as a module. If so, the module - will be called w83781d. - -config SENSORS_W83L785TS - tristate "Winbond W83L785TS-S" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - help - If you say yes here you get support for the Winbond W83L785TS-S - sensor chip, which is used on the Asus A7N8X, among other - motherboards. - - This driver can also be built as a module. If so, the module - will be called w83l785ts. - -config SENSORS_W83627HF - tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get support for the Winbond W836X7 series - of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF - - This driver can also be built as a module. If so, the module - will be called w83627hf. - -config SENSORS_W83627EHF - tristate "Winbond W83627EHF" - depends on I2C && EXPERIMENTAL - select I2C_SENSOR - select I2C_ISA - help - If you say yes here you get preliminary support for the hardware - monitoring functionality of the Winbond W83627EHF Super-I/O chip. - Only fan and temperature inputs are supported at the moment, while - the chip does much more than that. - - This driver can also be built as a module. If so, the module - will be called w83627ehf. - -endmenu - -menu "Other I2C Chip support" +menu "Miscellaneous I2C Chip support" depends on I2C config SENSORS_DS1337 diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index b5e6d2f84f9..a876dd42b86 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -1,52 +1,16 @@ # -# Makefile for sensor and "other" I2C chip drivers. +# Makefile for miscellaneous I2C chip drivers. # -# asb100, then w83781d go first, as they can override other drivers' addresses. -obj-$(CONFIG_SENSORS_ASB100) += asb100.o -obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o -obj-$(CONFIG_SENSORS_W83781D) += w83781d.o - -obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o -obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o -obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o -obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o -obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o -obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_DS1337) += ds1337.o obj-$(CONFIG_SENSORS_DS1374) += ds1374.o -obj-$(CONFIG_SENSORS_DS1621) += ds1621.o obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o -obj-$(CONFIG_SENSORS_FSCHER) += fscher.o -obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o -obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o -obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o -obj-$(CONFIG_SENSORS_IT87) += it87.o -obj-$(CONFIG_SENSORS_LM63) += lm63.o -obj-$(CONFIG_SENSORS_LM75) += lm75.o -obj-$(CONFIG_SENSORS_LM77) += lm77.o -obj-$(CONFIG_SENSORS_LM78) += lm78.o -obj-$(CONFIG_SENSORS_LM80) += lm80.o -obj-$(CONFIG_SENSORS_LM83) += lm83.o -obj-$(CONFIG_SENSORS_LM85) += lm85.o -obj-$(CONFIG_SENSORS_LM87) += lm87.o -obj-$(CONFIG_SENSORS_LM90) += lm90.o -obj-$(CONFIG_SENSORS_LM92) += lm92.o -obj-$(CONFIG_SENSORS_MAX1619) += max1619.o obj-$(CONFIG_SENSORS_MAX6875) += max6875.o obj-$(CONFIG_SENSORS_M41T00) += m41t00.o -obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o -obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o -obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o -obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o -obj-$(CONFIG_SENSORS_VIA686A) += via686a.o -obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o -obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o - obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TPS65010) += tps65010.o -- cgit v1.2.3-70-g09d2 From d5950b4355049092739bea97d1bdc14433126cc5 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 11 Jul 2005 21:03:49 -0700 Subject: [NET]: add a top-level Networking menu to *config Create a new top-level menu named "Networking" thus moving net related options and protocol selection way from the drivers menu and up on the top-level where they belong. To implement this all architectures has to source "net/Kconfig" before drivers/*/Kconfig in their Kconfig file. This change has been implemented for all architectures. Device drivers for ordinary NIC's are still to be found in the Device Drivers section, but Bluetooth, IrDA and ax25 are located with their corresponding menu entries under the new networking menu item. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/alpha/Kconfig | 2 ++ arch/arm/Kconfig | 4 +++- arch/arm26/Kconfig | 4 +++- arch/cris/Kconfig | 4 +++- arch/frv/Kconfig | 2 ++ arch/h8300/Kconfig | 4 +++- arch/i386/Kconfig | 2 ++ arch/ia64/Kconfig | 2 ++ arch/m32r/Kconfig | 2 ++ arch/m68k/Kconfig | 2 ++ arch/m68knommu/Kconfig | 2 ++ arch/mips/Kconfig | 2 ++ arch/parisc/Kconfig | 2 ++ arch/ppc/Kconfig | 2 ++ arch/ppc64/Kconfig | 2 ++ arch/s390/Kconfig | 4 +++- arch/sh/Kconfig | 2 ++ arch/sh64/Kconfig | 2 ++ arch/sparc/Kconfig | 2 ++ arch/sparc64/Kconfig | 4 +++- arch/um/Kconfig | 4 +++- arch/v850/Kconfig | 4 +++- arch/x86_64/Kconfig | 2 ++ arch/xtensa/Kconfig | 2 ++ drivers/Kconfig | 2 +- drivers/net/Kconfig | 3 +++ net/Kconfig | 10 +++++----- 27 files changed, 65 insertions(+), 14 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index c5739d6309d..083c5df42d3 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -596,6 +596,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8752751f998..45462714caf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -700,6 +700,8 @@ config APM endmenu +source "net/Kconfig" + menu "Device Drivers" source "drivers/base/Kconfig" @@ -732,7 +734,7 @@ source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index dc0c1936969..1f037326730 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -183,6 +183,8 @@ source "mm/Kconfig" endmenu +source "net/Kconfig" + source "drivers/base/Kconfig" source "drivers/parport/Kconfig" @@ -193,7 +195,7 @@ source "drivers/block/Kconfig" source "drivers/md/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/ide/Kconfig" diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index f848e376149..e5979d68e35 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -122,6 +122,8 @@ source arch/cris/arch-v10/Kconfig endmenu +source "net/Kconfig" + # bring in ETRAX built-in drivers menu "Drivers for built-in interfaces" source arch/cris/arch-v10/drivers/Kconfig @@ -149,7 +151,7 @@ source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index c93f95146cc..ec85c0d6c6d 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -346,6 +346,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 62a89e812e3..375f2a8ff3b 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -55,6 +55,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/base/Kconfig" source "drivers/mtd/Kconfig" @@ -65,7 +67,7 @@ source "drivers/ide/Kconfig" source "arch/h8300/Kconfig.ide" -source "net/Kconfig" +source "drivers/net/Kconfig" # # input - input/joystick depends on it. As does USB. diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 6c02336fe2e..a801d9d4860 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1285,6 +1285,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 01b78e7f992..2e08942339a 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -423,6 +423,8 @@ endmenu endif +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 42ca8a39798..7772951df31 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -359,6 +359,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 691a2469ff3..178c4a3fbb7 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -450,6 +450,8 @@ source "drivers/zorro/Kconfig" endmenu +source "net/Kconfig" + source "drivers/Kconfig" menu "Character devices" diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index dbfcdc8e608..117f183f0b4 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -575,6 +575,8 @@ config PM endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index bd9de7b00c0..b578239146b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1640,6 +1640,8 @@ config PM endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index ce327c799b4..1c2d8743523 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -190,6 +190,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 23b0d2f662c..b833cbcd77f 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -1355,6 +1355,8 @@ config PIN_TLB depends on ADVANCED_OPTIONS && 8xx endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index f804f25232a..fdd8afba715 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -429,6 +429,8 @@ config CMDLINE endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 6600ee87f89..477ac2758bd 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -465,6 +465,8 @@ config KEXEC endmenu +source "net/Kconfig" + config PCMCIA bool default n @@ -475,7 +477,7 @@ source "drivers/scsi/Kconfig" source "drivers/s390/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "fs/Kconfig" diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index a7c8bfc1160..adc8109f8b7 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -784,6 +784,8 @@ config EMBEDDED_RAMDISK_IMAGE endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig index 708e59736a4..4c3e5334adb 100644 --- a/arch/sh64/Kconfig +++ b/arch/sh64/Kconfig @@ -268,6 +268,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 7a117ef473c..aca028aa29b 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -268,6 +268,8 @@ source "mm/Kconfig" endmenu +source "net/Kconfig" + source "drivers/Kconfig" if !SUN4 diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 6a4733683f0..140607870f1 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -525,6 +525,8 @@ source "mm/Kconfig" endmenu +source "net/Kconfig" + source "drivers/base/Kconfig" source "drivers/video/Kconfig" @@ -551,7 +553,7 @@ endif source "drivers/ieee1394/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 6682c788364..f945444df49 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -275,6 +275,8 @@ endmenu source "init/Kconfig" +source "net/Kconfig" + source "drivers/base/Kconfig" source "arch/um/Kconfig_char" @@ -287,7 +289,7 @@ config NETDEVICES source "arch/um/Kconfig_net" -source "net/Kconfig" +source "drivers/net/Kconfig" source "fs/Kconfig" diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig index 27febd6ffa8..89c053b6c2c 100644 --- a/arch/v850/Kconfig +++ b/arch/v850/Kconfig @@ -250,6 +250,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + ############################################################################# source "drivers/base/Kconfig" @@ -283,7 +285,7 @@ source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index d09437b5c48..4b8326177c5 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -515,6 +515,8 @@ config UID16 endmenu +source "net/Kconfig" + source drivers/Kconfig source "drivers/firmware/Kconfig" diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index c9b5d298e3c..2b6257bec4c 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -228,6 +228,8 @@ source "fs/Kconfig.binfmt" endmenu +source "net/Kconfig" + source "drivers/Kconfig" source "fs/Kconfig" diff --git a/drivers/Kconfig b/drivers/Kconfig index aed4a9b97c1..34efb2150e6 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -28,7 +28,7 @@ source "drivers/message/i2o/Kconfig" source "drivers/macintosh/Kconfig" -source "net/Kconfig" +source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2b55687f6ee..9a07ff7a777 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -3,6 +3,8 @@ # Network device configuration # +menu "Network device support" + config NETDEVICES depends on NET bool "Network device support" @@ -2547,3 +2549,4 @@ config NETCONSOLE If you want to log kernel messages over the network, enable this. See for details. +endmenu diff --git a/net/Kconfig b/net/Kconfig index b9ca0a581bd..f46fc326c00 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -2,7 +2,7 @@ # Network configuration # -menu "Networking support" +menu "Networking" config NET bool "Networking support" @@ -10,7 +10,9 @@ config NET Unless you really know what you are doing, you should say Y here. The reason is that some programs need kernel networking support even when running on a stand-alone machine that isn't connected to any - other computer. If you are upgrading from an older kernel, you + other computer. + + If you are upgrading from an older kernel, you should consider updating your networking tools too because changes in the kernel and the tools often go hand in hand. The tools are contained in the package net-tools, the location and version number @@ -640,7 +642,5 @@ source "net/irda/Kconfig" source "net/bluetooth/Kconfig" -source "drivers/net/Kconfig" - -endmenu +endmenu # Networking -- cgit v1.2.3-70-g09d2 From c12a828982ee27e0d9f742177016896d6c3a5acb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 12 Jul 2005 12:09:43 -0700 Subject: [SPARC64]: Fix SMP build failure. arch/sparc64/kernel/smp.c:48: error: parse error before "__attribute__" arch/sparc64/kernel/smp.c:49: error: parse error before "__attribute__" Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- arch/sparc64/kernel/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 441fc2e52ce..7e8e2919e18 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -45,8 +45,8 @@ extern void calibrate_delay(void); /* Please don't make this stuff initdata!!! --DaveM */ static unsigned char boot_cpu_id; -cpumask_t cpu_online_map = CPU_MASK_NONE __read_mostly; -cpumask_t phys_cpu_present_map = CPU_MASK_NONE __read_mostly; +cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; +cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; static cpumask_t smp_commenced_mask; static cpumask_t cpu_callout_map; -- cgit v1.2.3-70-g09d2 From cdd5186f753b23ab51f86679bdc4cc698ab0b893 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 24 Jul 2005 19:36:13 -0700 Subject: [SPARC64]: Privatize sun5_timer. It is only used by some localized code in irq.c, and also delete enable_prom_timer() as that is totally unused. Signed-off-by: David S. Miller --- arch/sparc64/kernel/irq.c | 20 +++++++------------- include/asm-sparc64/timer.h | 41 ----------------------------------------- 2 files changed, 7 insertions(+), 54 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index daa2fb93052..c9b69167632 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -782,8 +782,14 @@ static void distribute_irqs(void) } #endif +struct sun5_timer { + u64 count0; + u64 limit0; + u64 count1; + u64 limit1; +}; -struct sun5_timer *prom_timers; +static struct sun5_timer *prom_timers; static u64 prom_limit0, prom_limit1; static void map_prom_timers(void) @@ -839,18 +845,6 @@ static void kill_prom_timer(void) : "g1", "g2"); } -void enable_prom_timer(void) -{ - if (!prom_timers) - return; - - /* Set it to whatever was there before. */ - prom_timers->limit1 = prom_limit1; - prom_timers->count1 = 0; - prom_timers->limit0 = prom_limit0; - prom_timers->count0 = 0; -} - void init_irqwork_curcpu(void) { register struct irq_work_struct *workp asm("o2"); diff --git a/include/asm-sparc64/timer.h b/include/asm-sparc64/timer.h index ba33a2b6b7b..edc8e08c3a3 100644 --- a/include/asm-sparc64/timer.h +++ b/include/asm-sparc64/timer.h @@ -9,49 +9,8 @@ #include -/* How timers work: - * - * On uniprocessors we just use counter zero for the system wide - * ticker, this performs thread scheduling, clock book keeping, - * and runs timer based events. Previously we used the Ultra - * %tick interrupt for this purpose. - * - * On multiprocessors we pick one cpu as the master level 10 tick - * processor. Here this counter zero tick handles clock book - * keeping and timer events only. Each Ultra has it's level - * 14 %tick interrupt set to fire off as well, even the master - * tick cpu runs this locally. This ticker performs thread - * scheduling, system/user tick counting for the current thread, - * and also profiling if enabled. - */ - #include -/* Two timers, traditionally steered to PIL's 10 and 14 respectively. - * But since INO packets are used on sun5, we could use any PIL level - * we like, however for now we use the normal ones. - * - * The 'reg' and 'interrupts' properties for these live in nodes named - * 'counter-timer'. The first of three 'reg' properties describe where - * the sun5_timer registers are. The other two I have no idea. (XXX) - */ -struct sun5_timer { - u64 count0; - u64 limit0; - u64 count1; - u64 limit1; -}; - -#define SUN5_LIMIT_ENABLE 0x80000000 -#define SUN5_LIMIT_TOZERO 0x40000000 -#define SUN5_LIMIT_ZRESTART 0x20000000 -#define SUN5_LIMIT_CMASK 0x1fffffff - -/* Given a HZ value, set the limit register to so that the timer IRQ - * gets delivered that often. - */ -#define SUN5_HZ_TO_LIMIT(__hz) (1000000/(__hz)) - struct sparc64_tick_ops { void (*init_tick)(unsigned long); unsigned long (*get_tick)(void); -- cgit v1.2.3-70-g09d2 From db7d9a4eb700be766cc9f29241483dbb1e748832 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 24 Jul 2005 19:36:26 -0700 Subject: [SPARC64]: Move syscall success and newchild state out of thread flags. These two bits were accesses non-atomically from assembler code. So, in order to eliminate any potential races resulting from that, move these pieces of state into two bytes elsewhere in struct thread_info. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 17 ++++++++--------- arch/sparc64/kernel/process.c | 2 +- arch/sparc64/kernel/smp.c | 2 +- arch/sparc64/kernel/traps.c | 2 ++ include/asm-sparc64/ptrace.h | 5 +++-- include/asm-sparc64/system.h | 11 +++++------ include/asm-sparc64/thread_info.h | 12 +++++++----- 7 files changed, 27 insertions(+), 24 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index d781f10adc5..88332f00094 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1600,11 +1600,11 @@ sys_clone: flushw ba,pt %xcc, sparc_do_fork add %sp, PTREGS_OFF, %o2 ret_from_syscall: - /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in - * %o7 for us. Check performance counter stuff too. + /* Clear current_thread_info()->new_child, and + * check performance counter stuff too. */ - andn %o7, _TIF_NEWCHILD, %l0 - stx %l0, [%g6 + TI_FLAGS] + stb %g0, [%g6 + TI_NEW_CHILD] + ldx [%g6 + TI_FLAGS], %l0 call schedule_tail mov %g7, %o0 andcc %l0, _TIF_PERFCTR, %g0 @@ -1720,12 +1720,11 @@ ret_sys_call: /* Check if force_successful_syscall_return() * was invoked. */ - ldx [%curptr + TI_FLAGS], %l0 - andcc %l0, _TIF_SYSCALL_SUCCESS, %g0 - be,pt %icc, 1f - andn %l0, _TIF_SYSCALL_SUCCESS, %l0 + ldub [%curptr + TI_SYS_NOERROR], %l0 + brz,pt %l0, 1f + nop ba,pt %xcc, 80f - stx %l0, [%curptr + TI_FLAGS] + stb %g0, [%curptr + TI_SYS_NOERROR] 1: cmp %o0, -ERESTART_RESTARTBLOCK diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index a0cd2b2494d..cffb1c8ab4f 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -621,8 +621,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | - _TIF_NEWCHILD | (((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->fpsaved[0] = 0; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 7e8e2919e18..b9b42491e11 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -137,7 +137,7 @@ void __init smp_callin(void) /* Clear this or we will die instantly when we * schedule back to this idler... */ - clear_thread_flag(TIF_NEWCHILD); + current_thread_info()->new_child = 0; /* Attach to the address space of init_task. */ atomic_inc(&init_mm.mm_count); diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index a9f4596d7c2..100b0107c4b 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -2125,6 +2125,8 @@ void __init trap_init(void) TI_PCR != offsetof(struct thread_info, pcr_reg) || TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) || TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || + TI_NEW_CHILD != offsetof(struct thread_info, new_child) || + TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || TI_FPREGS != offsetof(struct thread_info, fpregs) || (TI_FPREGS & (64 - 1))) thread_info_offsets_are_bolixed_dave(); diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index 2d2b5a113d2..6194f771e9f 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -94,8 +94,9 @@ struct sparc_trapf { #define STACKFRAME32_SZ sizeof(struct sparc_stackf32) #ifdef __KERNEL__ -#define force_successful_syscall_return() \ - set_thread_flag(TIF_SYSCALL_SUCCESS) +#define force_successful_syscall_return() \ +do { current_thread_info()->syscall_noerror = 1; \ +} while (0) #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) #define instruction_pointer(regs) ((regs)->tpc) #ifdef CONFIG_SMP diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index f9be2c5b4dc..ee4bdfc6b88 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -190,24 +190,23 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ "wrpr %%g1, %%cwp\n\t" \ "ldx [%%g6 + %3], %%o6\n\t" \ "ldub [%%g6 + %2], %%o5\n\t" \ - "ldx [%%g6 + %4], %%o7\n\t" \ + "ldub [%%g6 + %4], %%o7\n\t" \ "mov %%g6, %%l2\n\t" \ "wrpr %%o5, 0x0, %%wstate\n\t" \ "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ "wrpr %%g0, 0x94, %%pstate\n\t" \ "mov %%l2, %%g6\n\t" \ - "ldx [%%g6 + %7], %%g4\n\t" \ + "ldx [%%g6 + %6], %%g4\n\t" \ "wrpr %%g0, 0x96, %%pstate\n\t" \ - "andcc %%o7, %6, %%g0\n\t" \ - "beq,pt %%icc, 1f\n\t" \ + "brz,pt %%o7, 1f\n\t" \ " mov %%g7, %0\n\t" \ "b,a ret_from_syscall\n\t" \ "1:\n\t" \ : "=&r" (last) \ : "0" (next->thread_info), \ - "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_FLAGS), "i" (TI_CWP), \ - "i" (_TIF_NEWCHILD), "i" (TI_TASK) \ + "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \ + "i" (TI_CWP), "i" (TI_TASK) \ : "cc", \ "g1", "g2", "g3", "g7", \ "l2", "l3", "l4", "l5", "l6", "l7", \ diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index a1d25c06f92..352d9943661 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h @@ -47,7 +47,9 @@ struct thread_info { struct pt_regs *kregs; struct exec_domain *exec_domain; int preempt_count; /* 0 => preemptable, <0 => BUG */ - int __pad; + __u8 new_child; + __u8 syscall_noerror; + __u16 __pad; unsigned long *utraps; @@ -87,6 +89,8 @@ struct thread_info { #define TI_KREGS 0x00000028 #define TI_EXEC_DOMAIN 0x00000030 #define TI_PRE_COUNT 0x00000038 +#define TI_NEW_CHILD 0x0000003c +#define TI_SYS_NOERROR 0x0000003d #define TI_UTRAPS 0x00000040 #define TI_REG_WINDOW 0x00000048 #define TI_RWIN_SPTRS 0x000003c8 @@ -219,10 +223,10 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ #define TIF_NEWSIGNALS 6 /* wants new-style signals */ #define TIF_32BIT 7 /* 32-bit binary */ -#define TIF_NEWCHILD 8 /* just-spawned child process */ +/* flag bit 8 is available */ #define TIF_SECCOMP 9 /* secure computing */ #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */ -#define TIF_SYSCALL_SUCCESS 11 +/* flag bit 11 is available */ /* NOTE: Thread flags >= 12 should be ones we have no interest * in using in assembly, else we can't use the mask as * an immediate value in instructions such as andcc. @@ -239,10 +243,8 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_UNALIGNED (1< Date: Tue, 26 Jul 2005 11:36:01 -0600 Subject: [PATCH] Don't export machine_restart, machine_halt, or machine_power_off. machine_restart, machine_halt and machine_power_off are machine specific hooks deep into the reboot logic, that modules have no business messing with. Usually code should be calling kernel_restart, kernel_halt, kernel_power_off, or emergency_restart. So don't export machine_restart, machine_halt, and machine_power_off so we can catch buggy users. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/alpha/kernel/process.c | 3 --- arch/arm/kernel/process.c | 4 ---- arch/arm26/kernel/process.c | 5 ----- arch/cris/kernel/process.c | 6 ------ arch/h8300/kernel/process.c | 6 ------ arch/i386/kernel/reboot.c | 5 ----- arch/i386/mach-visws/reboot.c | 5 ----- arch/i386/mach-voyager/voyager_basic.c | 5 ----- arch/ia64/kernel/process.c | 5 ----- arch/m32r/kernel/process.c | 6 ------ arch/m68k/kernel/process.c | 6 ------ arch/m68knommu/kernel/process.c | 6 ------ arch/mips/kernel/reset.c | 5 ----- arch/parisc/kernel/process.c | 6 ------ arch/ppc/kernel/setup.c | 6 ------ arch/ppc64/kernel/setup.c | 3 --- arch/s390/kernel/setup.c | 6 ------ arch/sh/kernel/process.c | 6 ------ arch/sparc/kernel/process.c | 6 ------ arch/sparc64/kernel/power.c | 2 -- arch/sparc64/kernel/process.c | 4 ---- arch/um/kernel/reboot.c | 6 ------ arch/v850/kernel/anna.c | 6 ------ arch/v850/kernel/as85ep1.c | 6 ------ arch/v850/kernel/fpga85e2c.c | 6 ------ arch/v850/kernel/rte_cb.c | 6 ------ arch/v850/kernel/sim.c | 6 ------ arch/v850/kernel/sim85e2.c | 5 ----- arch/x86_64/kernel/reboot.c | 5 ----- 29 files changed, 152 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 4933f3ce583..fa98dae3cd9 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -165,7 +165,6 @@ machine_restart(char *restart_cmd) common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd); } -EXPORT_SYMBOL(machine_restart); void machine_halt(void) @@ -173,7 +172,6 @@ machine_halt(void) common_shutdown(LINUX_REBOOT_CMD_HALT, NULL); } -EXPORT_SYMBOL(machine_halt); void machine_power_off(void) @@ -181,7 +179,6 @@ machine_power_off(void) common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL); } -EXPORT_SYMBOL(machine_power_off); /* Used by sysrq-p, among others. I don't believe r9-r15 are ever saved in the context it's used. */ diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index bbea636ff68..409db6d5ec9 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -131,7 +131,6 @@ void machine_halt(void) { } -EXPORT_SYMBOL(machine_halt); void machine_power_off(void) { @@ -139,7 +138,6 @@ void machine_power_off(void) pm_power_off(); } -EXPORT_SYMBOL(machine_power_off); void machine_restart(char * __unused) { @@ -169,8 +167,6 @@ void machine_restart(char * __unused) while (1); } -EXPORT_SYMBOL(machine_restart); - void __show_regs(struct pt_regs *regs) { unsigned long flags = condition_codes(regs); diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c index 46aea6ac194..9eb9964d32a 100644 --- a/arch/arm26/kernel/process.c +++ b/arch/arm26/kernel/process.c @@ -103,9 +103,6 @@ void machine_power_off(void) { } -EXPORT_SYMBOL(machine_halt); -EXPORT_SYMBOL(machine_power_off); - void machine_restart(char * __unused) { /* @@ -136,8 +133,6 @@ void machine_restart(char * __unused) while (1); } -EXPORT_SYMBOL(machine_restart); - void show_regs(struct pt_regs * regs) { unsigned long flags; diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 7645c4d4de6..a5ad2b67585 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -214,8 +214,6 @@ void machine_restart(char *cmd) hard_reset_now(); } -EXPORT_SYMBOL(machine_restart); - /* * Similar to machine_power_off, but don't shut off power. Add code * here to freeze the system for e.g. post-mortem debug purpose when @@ -226,16 +224,12 @@ void machine_halt(void) { } -EXPORT_SYMBOL(machine_halt); - /* If or when software power-off is implemented, add code here. */ void machine_power_off(void) { } -EXPORT_SYMBOL(machine_power_off); - /* * When a process does an "exec", machine state like FPU and debug * registers need to be reset. This is a hook function for that. diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index b5f83e9f04d..27f1fce64ce 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -90,8 +90,6 @@ void machine_restart(char * __unused) __asm__("jmp @@0"); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { local_irq_disable(); @@ -99,8 +97,6 @@ void machine_halt(void) for (;;); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { local_irq_disable(); @@ -108,8 +104,6 @@ void machine_power_off(void) for (;;); } -EXPORT_SYMBOL(machine_power_off); - void show_regs(struct pt_regs * regs) { printk("\nPC: %08lx Status: %02x", diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index b3e58484996..1b24bc7271a 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -337,14 +337,10 @@ void machine_restart(char * __unused) machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { lapic_shutdown(); @@ -355,5 +351,4 @@ void machine_power_off(void) pm_power_off(); } -EXPORT_SYMBOL(machine_power_off); diff --git a/arch/i386/mach-visws/reboot.c b/arch/i386/mach-visws/reboot.c index 95e4676594e..9e9296676f9 100644 --- a/arch/i386/mach-visws/reboot.c +++ b/arch/i386/mach-visws/reboot.c @@ -22,8 +22,6 @@ void machine_restart(char * __unused) outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); } -EXPORT_SYMBOL(machine_restart); - void machine_power_off(void) { unsigned short pm_status; @@ -43,10 +41,7 @@ void machine_power_off(void) outl(PIIX_SPECIAL_STOP, 0xCFC); } -EXPORT_SYMBOL(machine_power_off); - void machine_halt(void) { } -EXPORT_SYMBOL(machine_halt); diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index 8680080a6a8..b3eda46e0fe 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c @@ -278,8 +278,6 @@ machine_restart(char *cmd) } } -EXPORT_SYMBOL(machine_restart); - void mca_nmi_hook(void) { @@ -315,12 +313,9 @@ machine_halt(void) machine_power_off(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { if (pm_power_off) pm_power_off(); } -EXPORT_SYMBOL(machine_power_off); diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index e484910246a..66e84060980 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -807,16 +807,12 @@ machine_restart (char *restart_cmd) (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); } -EXPORT_SYMBOL(machine_restart); - void machine_halt (void) { cpu_halt(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off (void) { @@ -825,4 +821,3 @@ machine_power_off (void) machine_halt(); } -EXPORT_SYMBOL(machine_power_off); diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index b556c3cf649..ea13a8f4d8b 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -115,8 +115,6 @@ void machine_restart(char *__unused) cpu_relax(); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { printk("Please push reset button!\n"); @@ -124,15 +122,11 @@ void machine_halt(void) cpu_relax(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { /* M32R_FIXME */ } -EXPORT_SYMBOL(machine_power_off); - static int __init idle_setup (char *str) { if (!strncmp(str, "poll", 4)) { diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 93b043e2a43..11b1b90ba6b 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -113,8 +113,6 @@ void machine_restart(char * __unused) for (;;); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { if (mach_halt) @@ -122,8 +120,6 @@ void machine_halt(void) for (;;); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { if (mach_power_off) @@ -131,8 +127,6 @@ void machine_power_off(void) for (;;); } -EXPORT_SYMBOL(machine_power_off); - void show_regs(struct pt_regs * regs) { printk("\n"); diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index c4a33f265dc..82e7ec88880 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -80,8 +80,6 @@ void machine_restart(char * __unused) for (;;); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { if (mach_halt) @@ -89,8 +87,6 @@ void machine_halt(void) for (;;); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { if (mach_power_off) @@ -98,8 +94,6 @@ void machine_power_off(void) for (;;); } -EXPORT_SYMBOL(machine_power_off); - void show_regs(struct pt_regs * regs) { printk(KERN_NOTICE "\n"); diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index 7e0a9821931..ae2ba67b7ef 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c @@ -26,18 +26,13 @@ void machine_restart(char *command) _machine_restart(command); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { _machine_halt(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { _machine_power_off(); } -EXPORT_SYMBOL(machine_power_off); diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 46e4a6881f1..4fc04501d5e 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -150,8 +150,6 @@ void machine_restart(char *cmd) } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { /* @@ -160,8 +158,6 @@ void machine_halt(void) */ } -EXPORT_SYMBOL(machine_halt); - /* * This routine is called from sys_reboot to actually turn off the @@ -187,8 +183,6 @@ void machine_power_off(void) KERN_EMERG "Please power this system off now."); } -EXPORT_SYMBOL(machine_power_off); - /* * Create a kernel thread diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index c42f7532693..929e5d1cc7f 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -121,8 +121,6 @@ void machine_restart(char *cmd) ppc_md.restart(cmd); } -EXPORT_SYMBOL(machine_restart); - void machine_power_off(void) { #ifdef CONFIG_NVRAM @@ -131,8 +129,6 @@ void machine_power_off(void) ppc_md.power_off(); } -EXPORT_SYMBOL(machine_power_off); - void machine_halt(void) { #ifdef CONFIG_NVRAM @@ -141,8 +137,6 @@ void machine_halt(void) ppc_md.halt(); } -EXPORT_SYMBOL(machine_halt); - void (*pm_power_off)(void) = machine_power_off; #ifdef CONFIG_TAU diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index d1b33f0b26c..e80f10c8982 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -694,7 +694,6 @@ void machine_restart(char *cmd) local_irq_disable(); while (1) ; } -EXPORT_SYMBOL(machine_restart); void machine_power_off(void) { @@ -707,7 +706,6 @@ void machine_power_off(void) local_irq_disable(); while (1) ; } -EXPORT_SYMBOL(machine_power_off); void machine_halt(void) { @@ -720,7 +718,6 @@ void machine_halt(void) local_irq_disable(); while (1) ; } -EXPORT_SYMBOL(machine_halt); static int ppc64_panic_event(struct notifier_block *this, unsigned long event, void *ptr) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b6d740ac0e6..a12183989a7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -299,24 +299,18 @@ void machine_restart(char *command) _machine_restart(command); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { console_unblank(); _machine_halt(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { console_unblank(); _machine_power_off(); } -EXPORT_SYMBOL(machine_power_off); - static void __init add_memory_hole(unsigned long start, unsigned long end) { diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 3d024590c24..6dce9d0b81f 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -80,8 +80,6 @@ void machine_restart(char * __unused) "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { #if defined(CONFIG_SH_HS7751RVOIP) @@ -96,8 +94,6 @@ void machine_halt(void) cpu_sleep(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { #if defined(CONFIG_SH_HS7751RVOIP) @@ -110,8 +106,6 @@ void machine_power_off(void) #endif } -EXPORT_SYMBOL(machine_power_off); - void show_regs(struct pt_regs * regs) { printk("\n"); diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 2c216ffeea9..29e72b57d4f 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -158,8 +158,6 @@ void machine_halt(void) panic("Halt failed!"); } -EXPORT_SYMBOL(machine_halt); - void machine_restart(char * cmd) { char *p; @@ -180,8 +178,6 @@ void machine_restart(char * cmd) panic("Reboot failed!"); } -EXPORT_SYMBOL(machine_restart); - void machine_power_off(void) { #ifdef CONFIG_SUN_AUXIO @@ -191,8 +187,6 @@ void machine_power_off(void) machine_halt(); } -EXPORT_SYMBOL(machine_power_off); - static DEFINE_SPINLOCK(sparc_backtrace_lock); void __show_backtrace(unsigned long fp) diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 533104c7907..946cee0257e 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -69,8 +69,6 @@ void machine_power_off(void) machine_halt(); } -EXPORT_SYMBOL(machine_power_off); - #ifdef CONFIG_PCI static int powerd(void *__unused) { diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index cffb1c8ab4f..07424b07593 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -124,8 +124,6 @@ void machine_halt(void) panic("Halt failed!"); } -EXPORT_SYMBOL(machine_halt); - void machine_alt_power_off(void) { if (!serial_console && prom_palette) @@ -154,8 +152,6 @@ void machine_restart(char * cmd) panic("Reboot failed!"); } -EXPORT_SYMBOL(machine_restart); - static void show_regwindow32(struct pt_regs *regs) { struct reg_window32 __user *rw; diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index fcec51da1d3..a637e885c58 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -49,23 +49,17 @@ void machine_restart(char * __unused) CHOOSE_MODE(reboot_tt(), reboot_skas()); } -EXPORT_SYMBOL(machine_restart); - void machine_power_off(void) { uml_cleanup(); CHOOSE_MODE(halt_tt(), halt_skas()); } -EXPORT_SYMBOL(machine_power_off); - void machine_halt(void) { machine_power_off(); } -EXPORT_SYMBOL(machine_halt); - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/arch/v850/kernel/anna.c b/arch/v850/kernel/anna.c index 6aaeab5e8a4..d0502e14243 100644 --- a/arch/v850/kernel/anna.c +++ b/arch/v850/kernel/anna.c @@ -132,8 +132,6 @@ void machine_restart (char *__unused) asm ("jmp r0"); /* Jump to the reset vector. */ } -EXPORT_SYMBOL(machine_restart); - void machine_halt (void) { #ifdef CONFIG_RESET_GUARD @@ -145,15 +143,11 @@ void machine_halt (void) asm ("halt; nop; nop; nop; nop; nop"); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off (void) { machine_halt (); } -EXPORT_SYMBOL(machine_power_off); - /* Called before configuring an on-chip UART. */ void anna_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud) { diff --git a/arch/v850/kernel/as85ep1.c b/arch/v850/kernel/as85ep1.c index 4059b1df11b..d78c5e4ea9b 100644 --- a/arch/v850/kernel/as85ep1.c +++ b/arch/v850/kernel/as85ep1.c @@ -160,8 +160,6 @@ void machine_restart (char *__unused) asm ("jmp r0"); /* Jump to the reset vector. */ } -EXPORT_SYMBOL(machine_restart); - void machine_halt (void) { #ifdef CONFIG_RESET_GUARD @@ -173,15 +171,11 @@ void machine_halt (void) asm ("halt; nop; nop; nop; nop; nop"); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off (void) { machine_halt (); } -EXPORT_SYMBOL(machine_power_off); - /* Called before configuring an on-chip UART. */ void as85ep1_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud) { diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c index 4bac5149b3c..d8094519ad8 100644 --- a/arch/v850/kernel/fpga85e2c.c +++ b/arch/v850/kernel/fpga85e2c.c @@ -121,22 +121,16 @@ void machine_halt (void) } } -EXPORT_SYMBOL(machine_halt); - void machine_restart (char *__unused) { machine_halt (); } -EXPORT_SYMBOL(machine_restart); - void machine_power_off (void) { machine_halt (); } -EXPORT_SYMBOL(machine_power_off); - /* Interrupts */ diff --git a/arch/v850/kernel/rte_cb.c b/arch/v850/kernel/rte_cb.c index 7ba397f77ac..0c794b9e0f9 100644 --- a/arch/v850/kernel/rte_cb.c +++ b/arch/v850/kernel/rte_cb.c @@ -67,8 +67,6 @@ void machine_restart (char *__unused) asm ("jmp r0"); /* Jump to the reset vector. */ } -EXPORT_SYMBOL(machine_restart); - /* This says `HALt.' in LEDese. */ static unsigned char halt_leds_msg[] = { 0x76, 0x77, 0x38, 0xF8 }; @@ -89,15 +87,11 @@ void machine_halt (void) asm ("halt; nop; nop; nop; nop; nop"); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off (void) { machine_halt (); } -EXPORT_SYMBOL(machine_power_off); - /* Animated LED display for timer tick. */ diff --git a/arch/v850/kernel/sim.c b/arch/v850/kernel/sim.c index 4f31da96263..e2cc5580fa2 100644 --- a/arch/v850/kernel/sim.c +++ b/arch/v850/kernel/sim.c @@ -104,24 +104,18 @@ void machine_restart (char *__unused) V850_SIM_SYSCALL (exit, 0); } -EXPORT_SYMBOL(machine_restart); - void machine_halt (void) { V850_SIM_SYSCALL (write, 1, "HALT\n", 5); V850_SIM_SYSCALL (exit, 0); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off (void) { V850_SIM_SYSCALL (write, 1, "POWER OFF\n", 10); V850_SIM_SYSCALL (exit, 0); } -EXPORT_SYMBOL(machine_power_off); - /* Load data from a file called NAME into ram. The address and length of the data image are returned in ADDR and LEN. */ diff --git a/arch/v850/kernel/sim85e2.c b/arch/v850/kernel/sim85e2.c index 93a722b516b..9111613fb53 100644 --- a/arch/v850/kernel/sim85e2.c +++ b/arch/v850/kernel/sim85e2.c @@ -184,18 +184,13 @@ void machine_halt (void) for (;;) {} } -EXPORT_SYMBOL(machine_halt); - void machine_restart (char *__unused) { machine_halt (); } -EXPORT_SYMBOL(machine_restart); - void machine_power_off (void) { machine_halt (); } -EXPORT_SYMBOL(machine_power_off); diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c index 57e71dbdfd6..0515d326663 100644 --- a/arch/x86_64/kernel/reboot.c +++ b/arch/x86_64/kernel/reboot.c @@ -150,18 +150,13 @@ void machine_restart(char * __unused) } } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { if (pm_power_off) pm_power_off(); } -EXPORT_SYMBOL(machine_power_off); -- cgit v1.2.3-70-g09d2 From 40a085c41dc3d5991fdf90ed2557cc06cce0590a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Jul 2005 14:14:39 -0700 Subject: [SPARC]: Add inotify syscall entries. Signed-off-by: David S. Miller --- arch/sparc/kernel/systbls.S | 4 ++-- arch/sparc64/kernel/systbls.S | 8 ++++---- include/asm-sparc/unistd.h | 6 +++--- include/asm-sparc64/unistd.h | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 025f4516e65..e457a40838f 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -48,8 +48,8 @@ sys_call_table: /*135*/ .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64 /*140*/ .long sys_sendfile64, sys_nis_syscall, sys_futex, sys_gettid, sys_getrlimit /*145*/ .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write -/*150*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 -/*155*/ .long sys_fcntl64, sys_ni_syscall, sys_statfs, sys_fstatfs, sys_oldumount +/*150*/ .long sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 +/*155*/ .long sys_fcntl64, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount /*160*/ .long sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall /*165*/ .long sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr /*170*/ .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index bceb91a8a2b..53eaf2345fe 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -50,8 +50,8 @@ sys_call_table32: .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_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_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 - .word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount +/*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 + .word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount /*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr /*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents @@ -116,8 +116,8 @@ sys_call_table: .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64 /*140*/ .word sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write -/*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 - .word sys_nis_syscall, sys_ni_syscall, sys_statfs, sys_fstatfs, sys_oldumount +/*150*/ .word sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 + .word sys_nis_syscall, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount /*160*/ .word sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_utrap_install .word sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index aee17d7e2e4..58dba518239 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -167,12 +167,12 @@ #define __NR_pciconfig_read 148 /* ENOSYS under SunOS */ #define __NR_pciconfig_write 149 /* ENOSYS under SunOS */ #define __NR_getsockname 150 /* Common */ -/* #define __NR_getmsg 151 SunOS Specific */ -/* #define __NR_putmsg 152 SunOS Specific */ +#define __NR_inotify_init 151 /* Linux specific */ +#define __NR_inotify_add_watch 152 /* Linux specific */ #define __NR_poll 153 /* Common */ #define __NR_getdents64 154 /* Linux specific */ #define __NR_fcntl64 155 /* Linux sparc32 Specific */ -/* #define __NR_getdirentires 156 SunOS Specific */ +#define __NR_inotify_rm_watch 156 /* Linux specific */ #define __NR_statfs 157 /* Common */ #define __NR_fstatfs 158 /* Common */ #define __NR_umount 159 /* Common */ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index f59144c6b76..51ec2879b88 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -167,12 +167,12 @@ #define __NR_pciconfig_read 148 /* ENOSYS under SunOS */ #define __NR_pciconfig_write 149 /* ENOSYS under SunOS */ #define __NR_getsockname 150 /* Common */ -/* #define __NR_getmsg 151 SunOS Specific */ -/* #define __NR_putmsg 152 SunOS Specific */ +#define __NR_inotify_init 151 /* Linux specific */ +#define __NR_inotify_add_watch 152 /* Linux specific */ #define __NR_poll 153 /* Common */ #define __NR_getdents64 154 /* Linux specific */ /* #define __NR_fcntl64 155 Linux sparc32 Specific */ -/* #define __NR_getdirentries 156 SunOS Specific */ +#define __NR_inotify_rm_watch 156 /* Linux specific */ #define __NR_statfs 157 /* Common */ #define __NR_fstatfs 158 /* Common */ #define __NR_umount 159 /* Common */ -- cgit v1.2.3-70-g09d2 From 48b0e5487fcdcb3421bda67666277348b2bd2661 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Jul 2005 16:08:44 -0700 Subject: [SPARC64]: Fix ugly dependency on NR_CPUS being a power-of-2. The page->flags D-cache dirty state tracking depended upon NR_CPUS being a power-of-2 via it's "NR_CPUS - 1" masking. Fix that to use a fixed (256 - 1) mask as that is the limit imposed by thread_info->cpu which is a "u8". Finally, add a compile time check that NR_CPUS is not greater than 256. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 8fc413cb6ac..3fbaf342a45 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -121,15 +121,24 @@ __inline__ void flush_dcache_page_impl(struct page *page) } #define PG_dcache_dirty PG_arch_1 +#define PG_dcache_cpu_shift 24 +#define PG_dcache_cpu_mask (256 - 1) + +#if NR_CPUS > 256 +#error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus +#endif #define dcache_dirty_cpu(page) \ - (((page)->flags >> 24) & (NR_CPUS - 1UL)) + (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask) static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) { unsigned long mask = this_cpu; - unsigned long non_cpu_bits = ~((NR_CPUS - 1UL) << 24UL); - mask = (mask << 24) | (1UL << PG_dcache_dirty); + unsigned long non_cpu_bits; + + non_cpu_bits = ~(PG_dcache_cpu_mask << PG_dcache_cpu_shift); + mask = (mask << PG_dcache_cpu_shift) | (1UL << PG_dcache_dirty); + __asm__ __volatile__("1:\n\t" "ldx [%2], %%g7\n\t" "and %%g7, %1, %%g1\n\t" @@ -151,7 +160,7 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c __asm__ __volatile__("! test_and_clear_dcache_dirty\n" "1:\n\t" "ldx [%2], %%g7\n\t" - "srlx %%g7, 24, %%g1\n\t" + "srlx %%g7, %4, %%g1\n\t" "and %%g1, %3, %%g1\n\t" "cmp %%g1, %0\n\t" "bne,pn %%icc, 2f\n\t" @@ -164,7 +173,8 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c "2:" : /* no outputs */ : "r" (cpu), "r" (mask), "r" (&page->flags), - "i" (NR_CPUS - 1UL) + "i" (PG_dcache_cpu_mask), + "i" (PG_dcache_cpu_shift) : "g1", "g7"); } @@ -180,7 +190,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { - int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL)); + int cpu = ((pg_flags >> PG_dcache_cpu_shift) & + PG_dcache_cpu_mask); int this_cpu = get_cpu(); /* This is just to optimize away some function calls -- cgit v1.2.3-70-g09d2 From fec59a711eef002d4ef9eb8de09dd0a26986eb77 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 4 Aug 2005 18:06:10 -0700 Subject: [PATCH] PCI: restore BAR values after D3hot->D0 for devices that need it Some PCI devices (e.g. 3c905B, 3c556B) lose all configuration (including BARs) when transitioning from D3hot->D0. This leaves such a device in an inaccessible state. The patch below causes the BARs to be restored when enabling such a device, so that its driver will be able to access it. The patch also adds pci_restore_bars as a new global symbol, and adds a correpsonding EXPORT_SYMBOL_GPL for that. Some firmware (e.g. Thinkpad T21) leaves devices in D3hot after a (re)boot. Most drivers call pci_enable_device very early, so devices left in D3hot that lose configuration during the D3hot->D0 transition will be inaccessible to their drivers. Drivers could be modified to account for this, but it would be difficult to know which drivers need modification. This is especially true since often many devices are covered by the same driver. It likely would be necessary to replicate code across dozens of drivers. The patch below should trigger only when transitioning from D3hot->D0 (or at boot), and only for devices that have the "no soft reset" bit cleared in the PM control register. I believe it is safe to include this patch as part of the PCI infrastructure. The cleanest implementation of pci_restore_bars was to call pci_update_resource. Unfortunately, that does not currently exist for the sparc64 architecture. The patch below includes a null implemenation of pci_update_resource for sparc64. Some have expressed interest in making general use of the the pci_restore_bars function, so that has been exported to GPL licensed modules. Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/pci.c | 6 +++++ drivers/pci/pci.c | 59 +++++++++++++++++++++++++++++++++++++++++++---- drivers/pci/setup-res.c | 2 +- include/linux/pci.h | 3 +++ 4 files changed, 65 insertions(+), 5 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index bba140d98b1..914e125d397 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -413,6 +413,12 @@ static int pci_assign_bus_resource(const struct pci_bus *bus, return -EBUSY; } +void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) +{ + /* Not implemented for sparc64... */ + BUG(); +} + int pci_assign_resource(struct pci_dev *pdev, int resource) { struct pcidev_cookie *pcp = pdev->sysdata; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b34fc56067..65ea7d25f69 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -221,6 +221,37 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) return best; } +/** + * pci_restore_bars - restore a devices BAR values (e.g. after wake-up) + * @dev: PCI device to have its BARs restored + * + * Restore the BAR values for a given device, so as to make it + * accessible by its driver. + */ +void +pci_restore_bars(struct pci_dev *dev) +{ + int i, numres; + + switch (dev->hdr_type) { + case PCI_HEADER_TYPE_NORMAL: + numres = 6; + break; + case PCI_HEADER_TYPE_BRIDGE: + numres = 2; + break; + case PCI_HEADER_TYPE_CARDBUS: + numres = 1; + break; + default: + /* Should never get here, but just in case... */ + return; + } + + for (i = 0; i < numres; i ++) + pci_update_resource(dev, &dev->resource[i], i); +} + /** * pci_set_power_state - Set the power state of a PCI device * @dev: PCI device to be suspended @@ -239,7 +270,7 @@ int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { - int pm; + int pm, need_restore = 0; u16 pmcsr, pmc; /* bound the state we're entering */ @@ -278,14 +309,17 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) return -EIO; } + pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + /* If we're in D3, force entire word to 0. * This doesn't affect PME_Status, disables PME_En, and * sets PowerState to 0. */ - if (dev->current_state >= PCI_D3hot) + if (dev->current_state >= PCI_D3hot) { + if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) + need_restore = 1; pmcsr = 0; - else { - pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + } else { pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= state; } @@ -308,6 +342,22 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) platform_pci_set_power_state(dev, state); dev->current_state = state; + + /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT + * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning + * from D3hot to D0 _may_ perform an internal reset, thereby + * going to "D0 Uninitialized" rather than "D0 Initialized". + * For example, at least some versions of the 3c905B and the + * 3c556B exhibit this behaviour. + * + * At least some laptop BIOSen (e.g. the Thinkpad T21) leave + * devices in a D3hot state at boot. Consequently, we need to + * restore at least the BARs so that the device will be + * accessible to its driver. + */ + if (need_restore) + pci_restore_bars(dev); + return 0; } @@ -805,6 +855,7 @@ struct pci_dev *isa_bridge; EXPORT_SYMBOL(isa_bridge); #endif +EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_disable_device); diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1ca21d2ba11..878fd0a65c0 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -26,7 +26,7 @@ #include "pci.h" -static void +void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) { struct pci_bus_region region; diff --git a/include/linux/pci.h b/include/linux/pci.h index 8621cf42b46..98bdd95fcee 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -225,6 +225,7 @@ #define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ #define PCI_PM_CTRL 4 /* PM control and status register */ #define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ +#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */ #define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ #define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ #define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ @@ -816,7 +817,9 @@ int pci_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); int pci_set_dma_mask(struct pci_dev *dev, u64 mask); int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); +void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int pci_assign_resource(struct pci_dev *dev, int i); +void pci_restore_bars(struct pci_dev *dev); /* ROM control related routines */ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size); -- cgit v1.2.3-70-g09d2 From dc836b5b6fcde95f750a4790d8200fabaf563dc9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 8 Aug 2005 18:46:09 -0700 Subject: Revert "[PATCH] PCI: restore BAR values..." Revert commit fec59a711eef002d4ef9eb8de09dd0a26986eb77, which is breaking sparc64 that doesn't have a working pci_update_resource. We'll re-do this after 2.6.13 when we'll do it all properly. --- arch/sparc64/kernel/pci.c | 6 ----- drivers/pci/pci.c | 59 ++++------------------------------------------- drivers/pci/setup-res.c | 2 +- include/linux/pci.h | 3 --- 4 files changed, 5 insertions(+), 65 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 914e125d397..bba140d98b1 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -413,12 +413,6 @@ static int pci_assign_bus_resource(const struct pci_bus *bus, return -EBUSY; } -void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) -{ - /* Not implemented for sparc64... */ - BUG(); -} - int pci_assign_resource(struct pci_dev *pdev, int resource) { struct pcidev_cookie *pcp = pdev->sysdata; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 65ea7d25f69..1b34fc56067 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -221,37 +221,6 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) return best; } -/** - * pci_restore_bars - restore a devices BAR values (e.g. after wake-up) - * @dev: PCI device to have its BARs restored - * - * Restore the BAR values for a given device, so as to make it - * accessible by its driver. - */ -void -pci_restore_bars(struct pci_dev *dev) -{ - int i, numres; - - switch (dev->hdr_type) { - case PCI_HEADER_TYPE_NORMAL: - numres = 6; - break; - case PCI_HEADER_TYPE_BRIDGE: - numres = 2; - break; - case PCI_HEADER_TYPE_CARDBUS: - numres = 1; - break; - default: - /* Should never get here, but just in case... */ - return; - } - - for (i = 0; i < numres; i ++) - pci_update_resource(dev, &dev->resource[i], i); -} - /** * pci_set_power_state - Set the power state of a PCI device * @dev: PCI device to be suspended @@ -270,7 +239,7 @@ int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { - int pm, need_restore = 0; + int pm; u16 pmcsr, pmc; /* bound the state we're entering */ @@ -309,17 +278,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) return -EIO; } - pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); - /* If we're in D3, force entire word to 0. * This doesn't affect PME_Status, disables PME_En, and * sets PowerState to 0. */ - if (dev->current_state >= PCI_D3hot) { - if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) - need_restore = 1; + if (dev->current_state >= PCI_D3hot) pmcsr = 0; - } else { + else { + pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= state; } @@ -342,22 +308,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) platform_pci_set_power_state(dev, state); dev->current_state = state; - - /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT - * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning - * from D3hot to D0 _may_ perform an internal reset, thereby - * going to "D0 Uninitialized" rather than "D0 Initialized". - * For example, at least some versions of the 3c905B and the - * 3c556B exhibit this behaviour. - * - * At least some laptop BIOSen (e.g. the Thinkpad T21) leave - * devices in a D3hot state at boot. Consequently, we need to - * restore at least the BARs so that the device will be - * accessible to its driver. - */ - if (need_restore) - pci_restore_bars(dev); - return 0; } @@ -855,7 +805,6 @@ struct pci_dev *isa_bridge; EXPORT_SYMBOL(isa_bridge); #endif -EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_disable_device); diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 589486704ce..84eedc96568 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -26,7 +26,7 @@ #include "pci.h" -void +static void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) { struct pci_bus_region region; diff --git a/include/linux/pci.h b/include/linux/pci.h index 98bdd95fcee..8621cf42b46 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -225,7 +225,6 @@ #define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ #define PCI_PM_CTRL 4 /* PM control and status register */ #define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ -#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */ #define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ #define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ #define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ @@ -817,9 +816,7 @@ int pci_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); int pci_set_dma_mask(struct pci_dev *dev, u64 mask); int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); -void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int pci_assign_resource(struct pci_dev *dev, int i); -void pci_restore_bars(struct pci_dev *dev); /* ROM control related routines */ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size); -- cgit v1.2.3-70-g09d2 From d64d3873721cfe870d49d73c3744f06260779ce7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 9 Aug 2005 15:29:19 -0700 Subject: [NET]: Fix memory leak in sys_{send,recv}msg() w/compat From: Dave Johnson sendmsg()/recvmsg() syscalls from o32/n32 apps to a 64bit kernel will cause a kernel memory leak if iov_len > UIO_FASTIOV for each syscall! This is because both sys_sendmsg() and verify_compat_iovec() kmalloc a new iovec structure. Only the one from sys_sendmsg() is free'ed. I wrote a simple test program to confirm this after identifying the problem: http://davej.org/programs/testsendmsg.c Note that the below fix will break solaris_sendmsg()/solaris_recvmsg() as it also calls verify_compat_iovec() but expects it to malloc internally. [ I fixed that. -DaveM ] Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- arch/sparc64/solaris/socket.c | 193 ++++++++++++++++++++++++++---------------- net/compat.c | 9 -- 2 files changed, 119 insertions(+), 83 deletions(-) (limited to 'arch/sparc64') diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c index 06740582717..d3a66ea74a7 100644 --- a/arch/sparc64/solaris/socket.c +++ b/arch/sparc64/solaris/socket.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -297,121 +298,165 @@ asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsi { struct socket *sock; char address[MAX_SOCK_ADDR]; - struct iovec iov[UIO_FASTIOV]; + struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; unsigned char ctl[sizeof(struct cmsghdr) + 20]; unsigned char *ctl_buf = ctl; - struct msghdr kern_msg; - int err, total_len; + struct msghdr msg_sys; + int err, ctl_len, iov_size, total_len; - if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) - return -EFAULT; - if(kern_msg.msg_iovlen > UIO_MAXIOV) - return -EINVAL; - err = verify_compat_iovec(&kern_msg, iov, address, VERIFY_READ); - if (err < 0) + err = -EFAULT; + if (msghdr_from_user32_to_kern(&msg_sys, user_msg)) + goto out; + + sock = sockfd_lookup(fd, &err); + if (!sock) goto out; + + /* do not move before msg_sys is valid */ + err = -EMSGSIZE; + if (msg_sys.msg_iovlen > UIO_MAXIOV) + goto out_put; + + /* Check whether to allocate the iovec area*/ + err = -ENOMEM; + iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); + if (msg_sys.msg_iovlen > UIO_FASTIOV) { + iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); + if (!iov) + goto out_put; + } + + err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ); + if (err < 0) + goto out_freeiov; total_len = err; - if(kern_msg.msg_controllen) { - struct sol_cmsghdr __user *ucmsg = kern_msg.msg_control; + err = -ENOBUFS; + if (msg_sys.msg_controllen > INT_MAX) + goto out_freeiov; + + ctl_len = msg_sys.msg_controllen; + if (ctl_len) { + struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control; unsigned long *kcmsg; compat_size_t cmlen; - if (kern_msg.msg_controllen <= sizeof(compat_size_t)) - return -EINVAL; + err = -EINVAL; + if (ctl_len <= sizeof(compat_size_t)) + goto out_freeiov; - if(kern_msg.msg_controllen > sizeof(ctl)) { + if (ctl_len > sizeof(ctl)) { err = -ENOBUFS; - ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL); - if(!ctl_buf) + ctl_buf = kmalloc(ctl_len, GFP_KERNEL); + if (!ctl_buf) goto out_freeiov; } __get_user(cmlen, &ucmsg->cmsg_len); kcmsg = (unsigned long *) ctl_buf; *kcmsg++ = (unsigned long)cmlen; err = -EFAULT; - if(copy_from_user(kcmsg, &ucmsg->cmsg_level, - kern_msg.msg_controllen - sizeof(compat_size_t))) + if (copy_from_user(kcmsg, &ucmsg->cmsg_level, + ctl_len - sizeof(compat_size_t))) goto out_freectl; - kern_msg.msg_control = ctl_buf; + msg_sys.msg_control = ctl_buf; } - kern_msg.msg_flags = solaris_to_linux_msgflags(user_flags); + msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags); - lock_kernel(); - sock = sockfd_lookup(fd, &err); - if (sock != NULL) { - if (sock->file->f_flags & O_NONBLOCK) - kern_msg.msg_flags |= MSG_DONTWAIT; - err = sock_sendmsg(sock, &kern_msg, total_len); - sockfd_put(sock); - } - unlock_kernel(); + if (sock->file->f_flags & O_NONBLOCK) + msg_sys.msg_flags |= MSG_DONTWAIT; + err = sock_sendmsg(sock, &msg_sys, total_len); out_freectl: - /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */ - if(ctl_buf != ctl) - kfree(ctl_buf); + if (ctl_buf != ctl) + sock_kfree_s(sock->sk, ctl_buf, ctl_len); out_freeiov: - if(kern_msg.msg_iov != iov) - kfree(kern_msg.msg_iov); -out: + if (iov != iovstack) + sock_kfree_s(sock->sk, iov, iov_size); +out_put: + sockfd_put(sock); +out: return err; } asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags) { - struct iovec iovstack[UIO_FASTIOV]; - struct msghdr kern_msg; - char addr[MAX_SOCK_ADDR]; struct socket *sock; + struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; + struct msghdr msg_sys; + unsigned long cmsg_ptr; + int err, iov_size, total_len, len; + + /* kernel mode address */ + char addr[MAX_SOCK_ADDR]; + + /* user mode address pointers */ struct sockaddr __user *uaddr; int __user *uaddr_len; - unsigned long cmsg_ptr; - int err, total_len, len = 0; - if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + if (msghdr_from_user32_to_kern(&msg_sys, user_msg)) return -EFAULT; - if(kern_msg.msg_iovlen > UIO_MAXIOV) - return -EINVAL; - uaddr = kern_msg.msg_name; + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + + err = -EMSGSIZE; + if (msg_sys.msg_iovlen > UIO_MAXIOV) + goto out_put; + + /* Check whether to allocate the iovec area*/ + err = -ENOMEM; + iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); + if (msg_sys.msg_iovlen > UIO_FASTIOV) { + iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); + if (!iov) + goto out_put; + } + + /* + * Save the user-mode address (verify_iovec will change the + * kernel msghdr to use the kernel address space) + */ + + uaddr = (void __user *) msg_sys.msg_name; uaddr_len = &user_msg->msg_namelen; - err = verify_compat_iovec(&kern_msg, iov, addr, VERIFY_WRITE); + err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE); if (err < 0) - goto out; + goto out_freeiov; total_len = err; - cmsg_ptr = (unsigned long) kern_msg.msg_control; - kern_msg.msg_flags = 0; + cmsg_ptr = (unsigned long) msg_sys.msg_control; + msg_sys.msg_flags = MSG_CMSG_COMPAT; - lock_kernel(); - sock = sockfd_lookup(fd, &err); - if (sock != NULL) { - if (sock->file->f_flags & O_NONBLOCK) - user_flags |= MSG_DONTWAIT; - err = sock_recvmsg(sock, &kern_msg, total_len, user_flags); - if(err >= 0) - len = err; - sockfd_put(sock); - } - unlock_kernel(); - - if(uaddr != NULL && err >= 0) - err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len); - if(err >= 0) { - err = __put_user(linux_to_solaris_msgflags(kern_msg.msg_flags), &user_msg->msg_flags); - if(!err) { - /* XXX Convert cmsg back into userspace 32-bit format... */ - err = __put_user((unsigned long)kern_msg.msg_control - cmsg_ptr, - &user_msg->msg_controllen); - } + if (sock->file->f_flags & O_NONBLOCK) + user_flags |= MSG_DONTWAIT; + + err = sock_recvmsg(sock, &msg_sys, total_len, user_flags); + if(err < 0) + goto out_freeiov; + + len = err; + + if (uaddr != NULL) { + err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); + if (err < 0) + goto out_freeiov; } + err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags); + if (err) + goto out_freeiov; + err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr, + &user_msg->msg_controllen); + if (err) + goto out_freeiov; + err = len; - if(kern_msg.msg_iov != iov) - kfree(kern_msg.msg_iov); +out_freeiov: + if (iov != iovstack) + sock_kfree_s(sock->sk, iov, iov_size); +out_put: + sockfd_put(sock); out: - if(err < 0) - return err; - return len; + return err; } diff --git a/net/compat.c b/net/compat.c index be5d936dc42..d99ab969589 100644 --- a/net/compat.c +++ b/net/compat.c @@ -91,20 +91,11 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, } else kern_msg->msg_name = NULL; - if(kern_msg->msg_iovlen > UIO_FASTIOV) { - kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec), - GFP_KERNEL); - if(!kern_iov) - return -ENOMEM; - } - tot_len = iov_from_user_compat_to_kern(kern_iov, (struct compat_iovec __user *)kern_msg->msg_iov, kern_msg->msg_iovlen); if(tot_len >= 0) kern_msg->msg_iov = kern_iov; - else if(kern_msg->msg_iovlen > UIO_FASTIOV) - kfree(kern_iov); return tot_len; } -- cgit v1.2.3-70-g09d2