From 7d01c880856bae31502095bc68784c1518a680cb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 4 Apr 2006 14:49:48 +1000 Subject: powerpc: iSeries has only 256 IRQs The iSeries Hypervisor only allows us to specify IRQ numbers up to 255 (it has a u8 field to pass it in). This patch allows platforms to specify a maximum to the virtual IRQ numbers we will use and has iSeries set that to 255. If not set, the maximum is NR_IRQS - 1 (as before). Signed-off-by: Stephen Rothwell --- include/asm-powerpc/irq.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index 51f87d9993b..7bc6d73b282 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h @@ -54,6 +54,13 @@ */ extern unsigned int virt_irq_to_real_map[NR_IRQS]; +/* The maximum virtual IRQ number that we support. This + * can be set by the platform and will be reduced by the + * value of __irq_offset_value. It defaults to and is + * capped by (NR_IRQS - 1). + */ +extern unsigned int virt_irq_max; + /* Create a mapping for a real_irq if it doesn't already exist. * Return the virtual irq as a convenience. */ -- cgit v1.2.3 From 0b7018aae7e1798f55f736b9a77c201708aa0e33 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 11 Apr 2006 23:42:03 -0400 Subject: Input: ads7846 - debouncing and rudimentary sample filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some touchscreens seem to oscillate heavily for a while after touching the screen.  Implement support for sampling the screen until we get two consecutive values that are close enough. Signed-off-by: Imre Deak Signed-off-by: Juha Yrjola Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- include/linux/spi/ads7846.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 72261e0f2ac..3f766495125 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -14,5 +14,8 @@ struct ads7846_platform_data { u16 x_min, x_max; u16 y_min, y_max; u16 pressure_min, pressure_max; + + u16 debounce_max; /* max number of readings per sample */ + u16 debounce_tol; /* tolerance used for filtering */ }; -- cgit v1.2.3 From c9e617a563ad646239270fa2222cdb06966cf1fa Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 11 Apr 2006 23:44:05 -0400 Subject: Input: ads7846 - handle IRQs that were latched during disabled IRQs The pen down IRQ will toggle during each X,Y,Z measurement cycle. Even though the IRQ is disabled it will be latched and delivered when after enable_irq. Thus in the IRQ handler we must avoid starting a new measurement cycle when such an "unwanted" IRQ happens. Add a get_pendown_state platform function, which will probably determine this by reading the current GPIO level of the pen IRQ pin. Move the IRQ reenabling from the SPI RX function to the timer. After the last power down message the pen IRQ pin is still active for a while and get_pendown_state would report incorrectly a pen down state. When suspending we should check the ts->pending flag instead of ts->pendown, since the timer can be pending regardless of ts->pendown. Also if ts->pending is set we can be sure that the timer is running, so no need to rearm it. Similarly if ts->pending is not set we can be sure that the IRQ is enabled (and the timer is not). Signed-off-by: Imre Deak Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- include/linux/spi/ads7846.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 3f766495125..d8823e237e0 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -17,5 +17,7 @@ struct ads7846_platform_data { u16 debounce_max; /* max number of readings per sample */ u16 debounce_tol; /* tolerance used for filtering */ + + int (*get_pendown_state)(void); }; -- cgit v1.2.3 From f39224a8c1828bdd327539da72a53d8a13595838 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 18 Apr 2006 21:49:11 +1000 Subject: powerpc: Use correct sequence for putting CPU into nap mode We weren't using the recommended sequence for putting the CPU into nap mode. When I changed the idle loop, for some reason 7447A cpus started hanging when we put them into nap mode. Changing to the recommended sequence fixes that. The complexity here is that the recommended sequence is a loop that keeps putting the cpu back into nap mode. Clearly we need some way to break out of the loop when an interrupt (external interrupt, decrementer, performance monitor) occurs. Here we use a bit in the thread_info struct to indicate that we need this, and the exception entry code notices this and arranges for the exception to return to the value in the link register, thus breaking out of the loop. We use a new `local_flags' field in the thread_info which we can alter without needing to use an atomic update sequence. The PPC970 has the same recommended sequence, so we do the same thing there too. This also fixes a bug in the kernel stack overflow handling code on 32-bit, since it was causing a value that we needed in a register to get trashed. Signed-off-by: Paul Mackerras --- include/asm-powerpc/thread_info.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index ffc7462d77b..88b553c6b26 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -37,6 +37,8 @@ struct thread_info { int preempt_count; /* 0 => preemptable, <0 => BUG */ struct restart_block restart_block; + unsigned long local_flags; /* private flags for thread */ + /* low level flags - has atomic operations done on it */ unsigned long flags ____cacheline_aligned_in_smp; }; @@ -143,6 +145,12 @@ static inline struct thread_info *current_thread_info(void) _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) +/* Bits in local_flags */ +/* Don't move TLF_NAPPING without adjusting the code in entry_32.S */ +#define TLF_NAPPING 0 /* idle thread enabled NAP mode */ + +#define _TLF_NAPPING (1 << TLF_NAPPING) + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_THREAD_INFO_H */ -- cgit v1.2.3 From 6fa679fdea22cd96287d4aa11ee771bcd46c6dfb Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 18 Apr 2006 12:35:16 +0200 Subject: [PATCH] x86_64: Increase NUMA hash function nodemap Needed for some big Opteron systems to compute a numa hash function They have more than 12 bits significant address. TBD switch this over to dynamic allocation or use better hash Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- include/asm-x86_64/mmzone.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h index 6b18cd8f293..6944e7122df 100644 --- a/include/asm-x86_64/mmzone.h +++ b/include/asm-x86_64/mmzone.h @@ -12,7 +12,8 @@ #include -#define NODEMAPSIZE 0xfff +/* Should really switch to dynamic allocation at some point */ +#define NODEMAPSIZE 0x4fff /* Simple perfect hash to map physical addresses to node numbers */ struct memnode { -- cgit v1.2.3 From f1233ab2cebb22a98df55de206a33a6693e3a78b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 18 Apr 2006 12:35:19 +0200 Subject: [PATCH] x86_64: Add tee and sync_file_range tee was already there for some reason for native 64bit, but sys_sync_file_range was missing. Also add it to the compat layer. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- include/asm-x86_64/unistd.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index d86494e23b6..98c36eae567 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -613,8 +613,10 @@ __SYSCALL(__NR_get_robust_list, sys_get_robust_list) __SYSCALL(__NR_splice, sys_splice) #define __NR_tee 276 __SYSCALL(__NR_tee, sys_tee) +#define __NR_sync_file_range 277 +__SYSCALL(__NR_sync_file_range, sys_sync_file_range) -#define __NR_syscall_max __NR_tee +#define __NR_syscall_max __NR_sync_file_range #ifndef __NO_STUBS -- cgit v1.2.3 From b809739a1b455396c21de13bcbf6669faf82f747 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 18 Apr 2006 14:48:45 -0700 Subject: [IPV6]: Clean up hop-by-hop options handler. - Removed unused argument (nhoff) for ipv6_parse_hopopts(). - Make ipv6_parse_hopopts() to align with other extension header handlers. - Removed pointless assignment (hdr), which is not used afterwards. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/net/ipv6.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 6d6f0634ae4..4abedb8eaec 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -230,7 +230,7 @@ extern int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)); -extern int ipv6_parse_hopopts(struct sk_buff *skb, int); +extern int ipv6_parse_hopopts(struct sk_buff *skb); extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, -- cgit v1.2.3 From b4d05cb9cbbf206ab0dc2c1740938b87b3d3ee44 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 29 Mar 2006 14:09:14 +0100 Subject: [MIPS] Make set_vi_srs_handler static. Signed-off-by: Ralf Baechle --- include/asm-mips/system.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 4097fac5ac3..29c55e7ab31 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -440,7 +440,6 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, extern void set_handler (unsigned long offset, void *addr, unsigned long len); extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len); extern void *set_vi_handler (int n, void *addr); -extern void *set_vi_srs_handler (int n, void *addr, int regset); extern void *set_except_vector(int n, void *addr); extern void per_cpu_trap_init(void); -- cgit v1.2.3 From 15c4f67ab81b07d3b579a11fc4a30da84c0d4858 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 29 Mar 2006 18:51:06 +0100 Subject: [MIPS] Provide access functions for c0_badvaddr. Signed-off-by: Ralf Baechle --- include/asm-mips/mipsregs.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 035ba0a9b0d..e85a42e2ea0 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -836,6 +836,9 @@ do { \ #define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ #define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + #define read_c0_count() __read_32bit_c0_register($9, 0) #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) -- cgit v1.2.3 From 91b05e6776e173da5ce7c96d67b3ad186c4fa49f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 29 Mar 2006 18:53:00 +0100 Subject: [MIPS] Fix vectored interrupt support in TLB exception handler generator. Signed-off-by: Ralf Baechle --- include/asm-mips/system.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 29c55e7ab31..39026690d9e 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -441,6 +441,7 @@ extern void set_handler (unsigned long offset, void *addr, unsigned long len); extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len); extern void *set_vi_handler (int n, void *addr); extern void *set_except_vector(int n, void *addr); +extern unsigned long ebase; extern void per_cpu_trap_init(void); extern NORET_TYPE void die(const char *, struct pt_regs *); -- cgit v1.2.3 From 84ada9f85686a6bfdbd65c24fd23ef5d641b0776 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Mar 2006 21:27:47 +0100 Subject: [MIPS] More SHT_* and SHF_* ELF definitions. Signed-off-by: Ralf Baechle --- include/asm-mips/elf.h | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index 851f013adad..bdc9de2df1e 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h @@ -119,8 +119,49 @@ #define SHT_MIPS_CONFLICT 0x70000002 #define SHT_MIPS_GPTAB 0x70000003 #define SHT_MIPS_UCODE 0x70000004 - -#define SHF_MIPS_GPREL 0x10000000 +#define SHT_MIPS_DEBUG 0x70000005 +#define SHT_MIPS_REGINFO 0x70000006 +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +#define SHF_MIPS_GPREL 0x10000000 +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRING 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPES 0x01000000 #ifndef ELF_ARCH /* ELF register definitions */ -- cgit v1.2.3 From f115da9cd60ccd5f27941dcf9fe8038ae9486a77 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 31 Mar 2006 09:27:20 +0100 Subject: [MIPS] Wire splice syscall. Signed-off-by: Ralf Baechle --- include/asm-mips/unistd.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index b5c78a4a019..2998795fa25 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -324,16 +324,17 @@ #define __NR_pselect6 (__NR_Linux + 301) #define __NR_ppoll (__NR_Linux + 302) #define __NR_unshare (__NR_Linux + 303) +#define __NR_splice (__NR_Linux + 304) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 303 +#define __NR_Linux_syscalls 304 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 303 +#define __NR_O32_Linux_syscalls 304 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -604,16 +605,17 @@ #define __NR_pselect6 (__NR_Linux + 260) #define __NR_ppoll (__NR_Linux + 261) #define __NR_unshare (__NR_Linux + 262) +#define __NR_splice (__NR_Linux + 263) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 262 +#define __NR_Linux_syscalls 263 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 262 +#define __NR_64_Linux_syscalls 263 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -888,16 +890,17 @@ #define __NR_pselect6 (__NR_Linux + 264) #define __NR_ppoll (__NR_Linux + 265) #define __NR_unshare (__NR_Linux + 266) +#define __NR_splice (__NR_Linux + 267) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 266 +#define __NR_Linux_syscalls 267 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 266 +#define __NR_N32_Linux_syscalls 267 #ifndef __ASSEMBLY__ -- cgit v1.2.3 From a8d587a71b76328447de165b12495650721b9286 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 1 Apr 2006 07:49:21 +0100 Subject: [MIPS] Wire up sync_file_range(2). Signed-off-by: Ralf Baechle --- include/asm-mips/unistd.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 2998795fa25..1068fe9a0a5 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -325,16 +325,17 @@ #define __NR_ppoll (__NR_Linux + 302) #define __NR_unshare (__NR_Linux + 303) #define __NR_splice (__NR_Linux + 304) +#define __NR_sync_file_range (__NR_Linux + 305) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 304 +#define __NR_Linux_syscalls 305 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 304 +#define __NR_O32_Linux_syscalls 305 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -606,16 +607,17 @@ #define __NR_ppoll (__NR_Linux + 261) #define __NR_unshare (__NR_Linux + 262) #define __NR_splice (__NR_Linux + 263) +#define __NR_sync_file_range (__NR_Linux + 264) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 263 +#define __NR_Linux_syscalls 264 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 263 +#define __NR_64_Linux_syscalls 264 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -891,16 +893,17 @@ #define __NR_ppoll (__NR_Linux + 265) #define __NR_unshare (__NR_Linux + 266) #define __NR_splice (__NR_Linux + 267) +#define __NR_sync_file_range (__NR_Linux + 268) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 267 +#define __NR_Linux_syscalls 268 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 267 +#define __NR_N32_Linux_syscalls 268 #ifndef __ASSEMBLY__ -- cgit v1.2.3 From 93373ed4d87fb02554ce020d929388ac16913664 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 1 Apr 2006 21:17:45 +0100 Subject: [MIPS] Rewrite spurious_interrupt from assembler to C. Signed-off-by: Ralf Baechle --- include/asm-mips/irq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index 8a342ccb34a..d7aecca3b95 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -46,5 +46,6 @@ do { \ #endif extern void arch_init_irq(void); +extern void spurious_interrupt(struct pt_regs *regs); #endif /* _ASM_IRQ_H */ -- cgit v1.2.3 From 13626a887fad4220bc7ca85f4b42ca8cfb805e11 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 2 Apr 2006 13:17:58 +0100 Subject: [MIPS] MV6434x: The name of the CPP symbol is __mips__, not __MIPS__. Signed-off-by: Ralf Baechle --- include/linux/mv643xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h index 955d3069d72..edfa012fad3 100644 --- a/include/linux/mv643xx.h +++ b/include/linux/mv643xx.h @@ -13,7 +13,7 @@ #ifndef __ASM_MV643XX_H #define __ASM_MV643XX_H -#ifdef __MIPS__ +#ifdef __mips__ #include #include #endif -- cgit v1.2.3 From ac2384a855c94e1d5467afe20bcb8ca23f0f3853 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 2 Apr 2006 13:48:57 +0100 Subject: [MIPS] it8172: Fix build of serial driver. Signed-off-by: Ralf Baechle --- include/asm-mips/serial.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 7b236641220..7196ceb0e94 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -77,15 +77,15 @@ #include #define ITE_SERIAL_PORT_DEFNS \ { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ - .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ + .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ - .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .type = 0x3 }, \ + .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ /* Smart Card Reader 0 */ \ { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ - .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ + .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ /* Smart Card Reader 1 */ \ { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ - .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, + .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, #else #define ITE_SERIAL_PORT_DEFNS #endif @@ -95,10 +95,10 @@ #include #define IVR_SERIAL_PORT_DEFNS \ { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ - .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ + .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ /* Smart Card Reader 1 */ \ { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ - .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, + .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, #else #define IVR_SERIAL_PORT_DEFNS #endif -- cgit v1.2.3 From 088cf96a692a0369973aa19dcbf36134d9e6a529 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 2 Apr 2006 18:06:43 +0100 Subject: [MIPS] MV6434x: Add prototype of interrupt dispatch function. Signed-off-by: Ralf Baechle --- include/asm-mips/marvell.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-mips/marvell.h b/include/asm-mips/marvell.h index 9225b3397a4..6bb2125bb05 100644 --- a/include/asm-mips/marvell.h +++ b/include/asm-mips/marvell.h @@ -53,4 +53,6 @@ struct mv_pci_controller { unsigned long config_vreg; }; +extern void ll_mv64340_irq(struct pt_regs *regs); + #endif /* __ASM_MIPS_MARVELL_H */ -- cgit v1.2.3 From ba8990f2aec85b5b62643aa82a1e71c738efc487 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 3 Apr 2006 00:21:30 +0100 Subject: [MIPS] JMR3927 build fixes for the RTC code. Signed-off-by: Ralf Baechle --- include/asm-mips/ds1742.h | 13 +++++++++++++ include/asm-mips/mach-jmr3927/ds1742.h | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 include/asm-mips/ds1742.h (limited to 'include') diff --git a/include/asm-mips/ds1742.h b/include/asm-mips/ds1742.h new file mode 100644 index 00000000000..c2f2c32da63 --- /dev/null +++ b/include/asm-mips/ds1742.h @@ -0,0 +1,13 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org) + */ +#ifndef _ASM_DS1742_H +#define _ASM_DS1742_H + +#include + +#endif /* _ASM_DS1742_H */ diff --git a/include/asm-mips/mach-jmr3927/ds1742.h b/include/asm-mips/mach-jmr3927/ds1742.h index cff6192d4bd..8a8fef6d07f 100644 --- a/include/asm-mips/mach-jmr3927/ds1742.h +++ b/include/asm-mips/mach-jmr3927/ds1742.h @@ -3,14 +3,14 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003 by Ralf Baechle + * Copyright (C) 2003, 06 by Ralf Baechle */ #ifndef __ASM_MACH_JMR3927_DS1742_H #define __ASM_MACH_JMR3927_DS1742_H #include -#define rtc_read(reg) (jmr3927_nvram_in(addr)) +#define rtc_read(reg) (jmr3927_nvram_in(reg)) #define rtc_write(data, reg) (jmr3927_nvram_out((data),(reg))) #endif /* __ASM_MACH_JMR3927_DS1742_H */ -- cgit v1.2.3 From d35d473c25d43d7db3e5e18b66d558d2a631cca8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 3 Apr 2006 13:17:41 +0100 Subject: [MIPS] Fix the crime against humanity that mipsIRQ.S is. Signed-off-by: Ralf Baechle --- include/asm-mips/mips-boards/atlas.h | 18 +++++++++++++++++- include/asm-mips/mips-boards/atlasint.h | 19 ------------------- 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/asm-mips/mips-boards/atlas.h b/include/asm-mips/mips-boards/atlas.h index 0998151fb3a..a8ae12d120e 100644 --- a/include/asm-mips/mips-boards/atlas.h +++ b/include/asm-mips/mips-boards/atlas.h @@ -33,12 +33,28 @@ #define ATLAS_RTC_ADR_REG 0x1f000800 #define ATLAS_RTC_DAT_REG 0x1f000808 - /* * Atlas interrupt controller register base. */ #define ATLAS_ICTRL_REGS_BASE 0x1f000000 +/* + * Atlas registers are memory mapped on 64-bit aligned boundaries and + * only word access are allowed. + */ +struct atlas_ictrl_regs { + volatile unsigned int intraw; + int dummy1; + volatile unsigned int intseten; + int dummy2; + volatile unsigned int intrsten; + int dummy3; + volatile unsigned int intenable; + int dummy4; + volatile unsigned int intstatus; + int dummy5; +}; + /* * Atlas UART register base. */ diff --git a/include/asm-mips/mips-boards/atlasint.h b/include/asm-mips/mips-boards/atlasint.h index bba35c183d0..fd7ebc54fa9 100644 --- a/include/asm-mips/mips-boards/atlasint.h +++ b/include/asm-mips/mips-boards/atlasint.h @@ -62,23 +62,4 @@ #define ATLASINT_RES31 (ATLASINT_BASE+31) #define ATLASINT_END (ATLASINT_BASE+31) -/* - * Atlas registers are memory mapped on 64-bit aligned boundaries and - * only word access are allowed. - */ -struct atlas_ictrl_regs { - volatile unsigned int intraw; - int dummy1; - volatile unsigned int intseten; - int dummy2; - volatile unsigned int intrsten; - int dummy3; - volatile unsigned int intenable; - int dummy4; - volatile unsigned int intstatus; - int dummy5; -}; - -extern void atlasint_init(void); - #endif /* !(_MIPS_ATLASINT_H) */ -- cgit v1.2.3 From 675055bfb5f99be56a20a6a214439adf23591786 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 3 Apr 2006 23:32:39 +0100 Subject: [MIPS] Use "R" constraint for cache_op. Gcc might emit an absolute address for the the "m" constraint which gas unfortunately does not permit. Signed-off-by: Ralf Baechle --- include/asm-mips/r4kcache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index 90c37470097..2f2eb95387f 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -37,7 +37,7 @@ " cache %0, %1 \n" \ " .set pop \n" \ : \ - : "i" (op), "m" (*(unsigned char *)(addr))) + : "i" (op), "R" (*(unsigned char *)(addr))) static inline void flush_icache_line_indexed(unsigned long addr) { -- cgit v1.2.3 From a682a2417007ad6265cd71b97b751753fd10e2fb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 4 Apr 2006 16:59:37 +0100 Subject: [MIPS] Fix genrtc compilation. Signed-off-by: Ralf Roesch Signed-off-by: Ralf Baechle --- include/asm-mips/rtc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h index a2abc4572b6..82ad401c7dc 100644 --- a/include/asm-mips/rtc.h +++ b/include/asm-mips/rtc.h @@ -32,7 +32,7 @@ static inline unsigned int get_rtc_time(struct rtc_time *time) { unsigned long nowtime; - nowtime = rtc_get_time(); + nowtime = rtc_mips_get_time(); to_tm(nowtime, time); time->tm_year -= 1900; @@ -47,7 +47,7 @@ static inline int set_rtc_time(struct rtc_time *time) nowtime = mktime(time->tm_year+1900, time->tm_mon+1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec); - ret = rtc_set_time(nowtime); + ret = rtc_mips_set_time(nowtime); return ret; } -- cgit v1.2.3 From 2600990e640e3bef29ed89d565864cf16ee83833 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 5 Apr 2006 09:45:45 +0100 Subject: [MIPS] kpsd and other AP/SP improvements. Signed-off-by: Ralf Baechle --- include/asm-mips/kspd.h | 36 ++++++++++++++++++++++++++++++++++++ include/asm-mips/mipsmtregs.h | 5 ++++- include/asm-mips/rtlx.h | 38 +++++++++++++++++++++++++------------- include/asm-mips/vpe.h | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 14 deletions(-) create mode 100644 include/asm-mips/kspd.h create mode 100644 include/asm-mips/vpe.h (limited to 'include') diff --git a/include/asm-mips/kspd.h b/include/asm-mips/kspd.h new file mode 100644 index 00000000000..4e9e724c893 --- /dev/null +++ b/include/asm-mips/kspd.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ + +#ifndef _ASM_KSPD_H +#define _ASM_KSPD_H + +struct kspd_notifications { + void (*kspd_sp_exit)(int sp_id); + + struct list_head list; +}; + +#ifdef CONFIG_MIPS_APSP_KSPD +extern void kspd_notify(struct kspd_notifications *notify); +#else +static inline void kspd_notify(struct kspd_notifications *notify) +{ +} +#endif + +#endif diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h index a669c0702c6..a5ac1a62f4f 100644 --- a/include/asm-mips/mipsmtregs.h +++ b/include/asm-mips/mipsmtregs.h @@ -234,7 +234,7 @@ static inline void __raw_emt(void) __asm__ __volatile__( " .set noreorder \n" " .set mips32r2 \n" - " emt \n" + " .word 0x41600be1 # emt \n" " ehb \n" " .set mips0 \n" " .set reorder"); @@ -364,6 +364,9 @@ do { \ #define read_vpe_c0_ebase() mftc0(15,1) #define write_vpe_c0_ebase(val) mttc0(15, 1, val) #define write_vpe_c0_compare(val) mttc0(11, 0, val) +#define read_vpe_c0_badvaddr() mftc0(8, 0) +#define read_vpe_c0_epc() mftc0(14, 0) +#define write_vpe_c0_epc(val) mttc0(14, 0, val) /* TC */ diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h index 1298c3fdf6c..76cd51c6be3 100644 --- a/include/asm-mips/rtlx.h +++ b/include/asm-mips/rtlx.h @@ -3,32 +3,46 @@ * */ -#ifndef _RTLX_H -#define _RTLX_H_ +#ifndef __ASM_RTLX_H +#define __ASM_RTLX_H_ #define LX_NODE_BASE 10 #define MIPSCPU_INT_BASE 16 #define MIPS_CPU_RTLX_IRQ 0 -#define RTLX_VERSION 1 +#define RTLX_VERSION 2 #define RTLX_xID 0x12345600 #define RTLX_ID (RTLX_xID | RTLX_VERSION) #define RTLX_CHANNELS 8 -#define RTLX_BUFFER_SIZE 1024 +#define RTLX_CHANNEL_STDIO 0 +#define RTLX_CHANNEL_DBG 1 +#define RTLX_CHANNEL_SYSIO 2 -/* - * lx_state bits - */ -#define RTLX_STATE_OPENED 1UL +extern int rtlx_open(int index, int can_sleep); +extern int rtlx_release(int index); +extern ssize_t rtlx_read(int index, void *buff, size_t count, int user); +extern ssize_t rtlx_write(int index, void *buffer, size_t count, int user); +extern unsigned int rtlx_read_poll(int index, int can_sleep); +extern unsigned int rtlx_write_poll(int index); + +enum rtlx_state { + RTLX_STATE_UNUSED, + RTLX_STATE_INITIALISED, + RTLX_STATE_REMOTE_READY, + RTLX_STATE_OPENED +}; + +#define RTLX_BUFFER_SIZE 1024 /* each channel supports read and write. linux (vpe0) reads lx_buffer and writes rt_buffer SP (vpe1) reads rt_buffer and writes lx_buffer */ struct rtlx_channel { - unsigned long lx_state; + enum rtlx_state rt_state; + enum rtlx_state lx_state; int buffer_size; @@ -38,15 +52,13 @@ struct rtlx_channel { int lx_write, lx_read; char *lx_buffer; - - void *queues; - }; struct rtlx_info { unsigned long id; + enum rtlx_state state; struct rtlx_channel channel[RTLX_CHANNELS]; }; -#endif /* _RTLX_H_ */ +#endif /* __ASM_RTLX_H_ */ diff --git a/include/asm-mips/vpe.h b/include/asm-mips/vpe.h new file mode 100644 index 00000000000..c6e1b961537 --- /dev/null +++ b/include/asm-mips/vpe.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ + +#ifndef _ASM_VPE_H +#define _ASM_VPE_H + +struct vpe_notifications { + void (*start)(int vpe); + void (*stop)(int vpe); + + struct list_head list; +}; + + +extern int vpe_notify(int index, struct vpe_notifications *notify); + +extern void *vpe_get_shared(int index); +extern int vpe_getuid(int index); +extern int vpe_getgid(int index); +extern char *vpe_getcwd(int index); + +#endif /* _ASM_VPE_H */ -- cgit v1.2.3 From 41c594ab65fc89573af296d192aa5235d09717ab Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 5 Apr 2006 09:45:45 +0100 Subject: [MIPS] MT: Improved multithreading support. Signed-off-by: Ralf Baechle --- include/asm-mips/asmmacro.h | 47 +++++++++++ include/asm-mips/cpu-info.h | 10 +++ include/asm-mips/hazards.h | 2 + include/asm-mips/interrupt.h | 65 +++++++++++--- include/asm-mips/irq.h | 29 +++++++ include/asm-mips/mips_mt.h | 15 ++++ include/asm-mips/mipsmtregs.h | 11 +-- include/asm-mips/mipsregs.h | 133 +++++++++++++++++++++++++++++ include/asm-mips/mmu_context.h | 112 +++++++++++++++++++++++- include/asm-mips/processor.h | 6 ++ include/asm-mips/ptrace.h | 4 + include/asm-mips/r4kcache.h | 128 ++++++++++++++++++++++++++++ include/asm-mips/smtc.h | 55 ++++++++++++ include/asm-mips/smtc_ipi.h | 118 ++++++++++++++++++++++++++ include/asm-mips/smtc_proc.h | 23 +++++ include/asm-mips/stackframe.h | 187 ++++++++++++++++++++++++++++++++++++++++- 16 files changed, 924 insertions(+), 21 deletions(-) create mode 100644 include/asm-mips/mips_mt.h create mode 100644 include/asm-mips/smtc.h create mode 100644 include/asm-mips/smtc_ipi.h create mode 100644 include/asm-mips/smtc_proc.h (limited to 'include') diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h index 30b18ea6cb1..f54aa147ec1 100644 --- a/include/asm-mips/asmmacro.h +++ b/include/asm-mips/asmmacro.h @@ -17,7 +17,26 @@ #ifdef CONFIG_64BIT #include #endif +#ifdef CONFIG_MIPS_MT_SMTC +#include +#endif +#ifdef CONFIG_MIPS_MT_SMTC + .macro local_irq_enable reg=t0 + mfc0 \reg, CP0_TCSTATUS + ori \reg, \reg, TCSTATUS_IXMT + xori \reg, \reg, TCSTATUS_IXMT + mtc0 \reg, CP0_TCSTATUS + ehb + .endm + + .macro local_irq_disable reg=t0 + mfc0 \reg, CP0_TCSTATUS + ori \reg, \reg, TCSTATUS_IXMT + mtc0 \reg, CP0_TCSTATUS + ehb + .endm +#else .macro local_irq_enable reg=t0 mfc0 \reg, CP0_STATUS ori \reg, \reg, 1 @@ -32,6 +51,7 @@ mtc0 \reg, CP0_STATUS irq_disable_hazard .endm +#endif /* CONFIG_MIPS_MT_SMTC */ #ifdef CONFIG_CPU_SB1 .macro fpu_enable_hazard @@ -48,4 +68,31 @@ .endm #endif +/* + * Temporary until all gas have MT ASE support + */ + .macro DMT reg=0 + .word (0x41600bc1 | (\reg << 16)) + .endm + + .macro EMT reg=0 + .word (0x41600be1 | (\reg << 16)) + .endm + + .macro DVPE reg=0 + .word (0x41600001 | (\reg << 16)) + .endm + + .macro EVPE reg=0 + .word (0x41600021 | (\reg << 16)) + .endm + + .macro MFTR rt=0, rd=0, u=0, sel=0 + .word (0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)) + .endm + + .macro MTTR rt=0, rd=0, u=0, sel=0 + .word (0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)) + .endm + #endif /* _ASM_ASMMACRO_H */ diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h index 140be1c67da..6572ac70366 100644 --- a/include/asm-mips/cpu-info.h +++ b/include/asm-mips/cpu-info.h @@ -73,6 +73,16 @@ struct cpuinfo_mips { struct cache_desc dcache; /* Primary D or combined I/D cache */ struct cache_desc scache; /* Secondary cache */ struct cache_desc tcache; /* Tertiary/split secondary cache */ +#if defined(CONFIG_MIPS_MT_SMTC) + /* + * In the MIPS MT "SMTC" model, each TC is considered + * to be a "CPU" for the purposes of scheduling, but + * exception resources, ASID spaces, etc, are common + * to all TCs within the same VPE. + */ + int vpe_id; /* Virtual Processor number */ + int tc_id; /* Thread Context number */ +#endif /* CONFIG_MIPS_MT */ void *data; /* Additional data */ } __attribute__((aligned(SMP_CACHE_BYTES))); diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index feb29a79388..dadc05188db 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h @@ -284,6 +284,8 @@ do { \ #define instruction_hazard() do { } while (0) #endif +extern void mips_ihb(void); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_HAZARDS_H */ diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h index 774348734fa..4bb9c06f441 100644 --- a/include/asm-mips/interrupt.h +++ b/include/asm-mips/interrupt.h @@ -19,7 +19,12 @@ __asm__ ( " .set push \n" " .set reorder \n" " .set noat \n" -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" + " ori $1, 0x400 \n" + " xori $1, 0x400 \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) " ei \n" #else " mfc0 $1,$12 \n" @@ -62,7 +67,12 @@ __asm__ ( " .macro local_irq_disable\n" " .set push \n" " .set noat \n" -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 \n" + " ori $1, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) " di \n" #else " mfc0 $1,$12 \n" @@ -88,7 +98,11 @@ __asm__ ( " .macro local_save_flags flags \n" " .set push \n" " .set reorder \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\flags, $2, 1 \n" +#else " mfc0 \\flags, $12 \n" +#endif " .set pop \n" " .endm \n"); @@ -102,7 +116,13 @@ __asm__ ( " .set push \n" " .set reorder \n" " .set noat \n" -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\result, $2, 1 \n" + " ori $1, \\result, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" + " andi \\result, \\result, 0x400 \n" +#elif defined(CONFIG_CPU_MIPSR2) " di \\result \n" " andi \\result, 1 \n" #else @@ -128,7 +148,14 @@ __asm__ ( " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) +#ifdef CONFIG_MIPS_MT_SMTC + "mfc0 $1, $2, 1 \n" + "andi \\flags, 0x400 \n" + "ori $1, 0x400 \n" + "xori $1, 0x400 \n" + "or \\flags, $1 \n" + "mtc0 \\flags, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) /* * Slow, but doesn't suffer from a relativly unlikely race * condition we're having since days 1. @@ -167,11 +194,29 @@ do { \ : "memory"); \ } while(0) -#define irqs_disabled() \ -({ \ - unsigned long flags; \ - local_save_flags(flags); \ - !(flags & 1); \ -}) +static inline int irqs_disabled(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU + */ + unsigned long __result; + + __asm__ __volatile__( + " .set noreorder \n" + " mfc0 %0, $2, 1 \n" + " andi %0, 0x400 \n" + " slt %0, $0, %0 \n" + " .set reorder \n" + : "=r" (__result)); + + return __result; +#else + unsigned long flags; + local_save_flags(flags); + + return !(flags & 1); +#endif +} #endif /* _ASM_INTERRUPT_H */ diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index d7aecca3b95..dde677f02bc 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -11,6 +11,9 @@ #include #include + +#include + #include #ifdef CONFIG_I8259 @@ -26,6 +29,23 @@ struct pt_regs; extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs); +#ifdef CONFIG_MIPS_MT_SMTC +/* + * Clear interrupt mask handling "backstop" if irq_hwmask + * entry so indicates. This implies that the ack() or end() + * functions will take over re-enabling the low-level mask. + * Otherwise it will be done on return from exception. + */ +#define __DO_IRQ_SMTC_HOOK() \ +do { \ + if (irq_hwmask[irq] & 0x0000ff00) \ + write_c0_tccontext(read_c0_tccontext() & \ + ~(irq_hwmask[irq] & 0x0000ff00)); \ +} while (0) +#else +#define __DO_IRQ_SMTC_HOOK() do { } while (0) +#endif + #ifdef CONFIG_PREEMPT /* @@ -39,6 +59,7 @@ extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs); #define do_IRQ(irq, regs) \ do { \ irq_enter(); \ + __DO_IRQ_SMTC_HOOK(); \ __do_IRQ((irq), (regs)); \ irq_exit(); \ } while (0) @@ -48,4 +69,12 @@ do { \ extern void arch_init_irq(void); extern void spurious_interrupt(struct pt_regs *regs); +#ifdef CONFIG_MIPS_MT_SMTC +struct irqaction; + +extern unsigned long irq_hwmask[]; +extern int setup_irq_smtc(unsigned int irq, struct irqaction * new, + unsigned long hwmask); +#endif /* CONFIG_MIPS_MT_SMTC */ + #endif /* _ASM_IRQ_H */ diff --git a/include/asm-mips/mips_mt.h b/include/asm-mips/mips_mt.h new file mode 100644 index 00000000000..c31a312b978 --- /dev/null +++ b/include/asm-mips/mips_mt.h @@ -0,0 +1,15 @@ +/* + * Definitions and decalrations for MIPS MT support + * that are common between SMTC, VSMP, and/or AP/SP + * kernel models. + */ +#ifndef __ASM_MIPS_MT_H +#define __ASM_MIPS_MT_H + +extern cpumask_t mt_fpu_cpumask; +extern unsigned long mt_fpemul_threshold; + +extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value); +extern void mips_mt_set_cpuoptions(void); + +#endif /* __ASM_MIPS_MT_H */ diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h index a5ac1a62f4f..f637ce70758 100644 --- a/include/asm-mips/mipsmtregs.h +++ b/include/asm-mips/mipsmtregs.h @@ -165,7 +165,7 @@ #ifndef __ASSEMBLY__ -extern void mips_mt_regdump(void); +extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value); static inline unsigned int dvpe(void) { @@ -282,8 +282,11 @@ static inline void ehb(void) \ __asm__ __volatile__( \ " .set push \n" \ + " .set noat \n" \ " .set mips32r2 \n" \ - " mftgpr %0," #rt " \n" \ + " # mftgpr $1," #rt " \n" \ + " .word 0x41000820 | (" #rt " << 16) \n" \ + " move %0, $1 \n" \ " .set pop \n" \ : "=r" (__res)); \ \ @@ -295,9 +298,7 @@ static inline void ehb(void) unsigned long __res; \ \ __asm__ __volatile__( \ - ".set noat\n\t" \ - "mftr\t%0, " #rt ", " #u ", " #sel "\n\t" \ - ".set at\n\t" \ + " mftr %0, " #rt ", " #u ", " #sel " \n" \ : "=r" (__res)); \ \ __res; \ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index e85a42e2ea0..a2ef579f6b1 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -861,7 +861,19 @@ do { \ #define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) #define read_c0_status() __read_32bit_c0_register($12, 0) +#ifdef CONFIG_MIPS_MT_SMTC +#define write_c0_status(val) \ +do { \ + __write_32bit_c0_register($12, 0, val); \ + __ehb(); \ +} while (0) +#else +/* + * Legacy non-SMTC code, which may be hazardous + * but which might not support EHB + */ #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) +#endif /* CONFIG_MIPS_MT_SMTC */ #define read_c0_cause() __read_32bit_c0_register($13, 0) #define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) @@ -1004,6 +1016,9 @@ do { \ #define read_c0_taglo() __read_32bit_c0_register($28, 0) #define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) +#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) +#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) + #define read_c0_taghi() __read_32bit_c0_register($29, 0) #define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) @@ -1357,6 +1372,11 @@ static inline void tlb_write_random(void) /* * Manipulate bits in a c0 register. */ +#ifndef CONFIG_MIPS_MT_SMTC +/* + * SMTC Linux requires shutting-down microthread scheduling + * during CP0 register read-modify-write sequences. + */ #define __BUILD_SET_C0(name) \ static inline unsigned int \ set_c0_##name(unsigned int set) \ @@ -1395,6 +1415,119 @@ change_c0_##name(unsigned int change, unsigned int new) \ return res; \ } +#else /* SMTC versions that manage MT scheduling */ + +#include + +/* + * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with + * header file recursion. + */ +static inline unsigned int __dmt(void) +{ + int res; + + __asm__ __volatile__( + " .set push \n" + " .set mips32r2 \n" + " .set noat \n" + " .word 0x41610BC1 # dmt $1 \n" + " ehb \n" + " move %0, $1 \n" + " .set pop \n" + : "=r" (res)); + + instruction_hazard(); + + return res; +} + +#define __VPECONTROL_TE_SHIFT 15 +#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT) + +#define __EMT_ENABLE __VPECONTROL_TE + +static inline void __emt(unsigned int previous) +{ + if ((previous & __EMT_ENABLE)) + __asm__ __volatile__( + " .set noreorder \n" + " .set mips32r2 \n" + " .word 0x41600be1 # emt \n" + " ehb \n" + " .set mips0 \n" + " .set reorder \n"); +} + +static inline void __ehb(void) +{ + __asm__ __volatile__( + " ehb \n"); +} + +/* + * Note that local_irq_save/restore affect TC-specific IXMT state, + * not Status.IE as in non-SMTC kernel. + */ + +#define __BUILD_SET_C0(name) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + unsigned int omt; \ + unsigned int flags; \ + \ + local_irq_save(flags); \ + omt = __dmt(); \ + res = read_c0_##name(); \ + res |= set; \ + write_c0_##name(res); \ + __emt(omt); \ + local_irq_restore(flags); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + unsigned int omt; \ + unsigned int flags; \ + \ + local_irq_save(flags); \ + omt = __dmt(); \ + res = read_c0_##name(); \ + res &= ~clear; \ + write_c0_##name(res); \ + __emt(omt); \ + local_irq_restore(flags); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + unsigned int omt; \ + unsigned int flags; \ + \ + local_irq_save(flags); \ + \ + omt = __dmt(); \ + res = read_c0_##name(); \ + res &= ~change; \ + res |= (new & change); \ + write_c0_##name(res); \ + __emt(omt); \ + local_irq_restore(flags); \ + \ + return res; \ +} +#endif + __BUILD_SET_C0(status) __BUILD_SET_C0(cause) __BUILD_SET_C0(config) diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index 61cf2258813..6e09f4c8721 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -17,6 +17,10 @@ #include #include #include +#ifdef CONFIG_MIPS_MT_SMTC +#include +#include +#endif /* SMTC */ /* * For the fast tlb miss handlers, we keep a per cpu array of pointers @@ -54,6 +58,14 @@ extern unsigned long pgd_current[]; #define ASID_INC 0x1 #define ASID_MASK 0xfff +/* SMTC/34K debug hack - but maybe we'll keep it */ +#elif defined(CONFIG_MIPS_MT_SMTC) + +#define ASID_INC 0x1 +extern unsigned long smtc_asid_mask; +#define ASID_MASK (smtc_asid_mask) +#define HW_ASID_MASK 0xff +/* End SMTC/34K debug hack */ #else /* FIXME: not correct for R6000 */ #define ASID_INC 0x1 @@ -76,6 +88,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) +#ifndef CONFIG_MIPS_MT_SMTC +/* Normal, classic MIPS get_new_mmu_context */ static inline void get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) { @@ -91,6 +105,12 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) cpu_context(cpu, mm) = asid_cache(cpu) = asid; } +#else /* CONFIG_MIPS_MT_SMTC */ + +#define get_new_mmu_context(mm,cpu) smtc_get_new_mmu_context((mm),(cpu)) + +#endif /* CONFIG_MIPS_MT_SMTC */ + /* * Initialize the context related info for a new mm_struct * instance. @@ -111,14 +131,46 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, { unsigned int cpu = smp_processor_id(); unsigned long flags; - +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long oldasid; + unsigned long mtflags; + int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id; local_irq_save(flags); + mtflags = dvpe(); +#else /* Not SMTC */ + local_irq_save(flags); +#endif /* CONFIG_MIPS_MT_SMTC */ /* Check if our ASID is of an older version and thus invalid */ if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) get_new_mmu_context(next, cpu); - +#ifdef CONFIG_MIPS_MT_SMTC + /* + * If the EntryHi ASID being replaced happens to be + * the value flagged at ASID recycling time as having + * an extended life, clear the bit showing it being + * in use by this "CPU", and if that's the last bit, + * free up the ASID value for use and flush any old + * instances of it from the TLB. + */ + oldasid = (read_c0_entryhi() & ASID_MASK); + if(smtc_live_asid[mytlb][oldasid]) { + smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); + if(smtc_live_asid[mytlb][oldasid] == 0) + smtc_flush_tlb_asid(oldasid); + } + /* + * Tread softly on EntryHi, and so long as we support + * having ASID_MASK smaller than the hardware maximum, + * make sure no "soft" bits become "hard"... + */ + write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) + | (cpu_context(cpu, next) & ASID_MASK)); + ehb(); /* Make sure it propagates to TCStatus */ + evpe(mtflags); +#else write_c0_entryhi(cpu_context(cpu, next)); +#endif /* CONFIG_MIPS_MT_SMTC */ TLBMISS_HANDLER_SETUP_PGD(next->pgd); /* @@ -151,12 +203,34 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) unsigned long flags; unsigned int cpu = smp_processor_id(); +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long oldasid; + unsigned long mtflags; + int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id; +#endif /* CONFIG_MIPS_MT_SMTC */ + local_irq_save(flags); /* Unconditionally get a new ASID. */ get_new_mmu_context(next, cpu); +#ifdef CONFIG_MIPS_MT_SMTC + /* See comments for similar code above */ + mtflags = dvpe(); + oldasid = read_c0_entryhi() & ASID_MASK; + if(smtc_live_asid[mytlb][oldasid]) { + smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); + if(smtc_live_asid[mytlb][oldasid] == 0) + smtc_flush_tlb_asid(oldasid); + } + /* See comments for similar code above */ + write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | + (cpu_context(cpu, next) & ASID_MASK)); + ehb(); /* Make sure it propagates to TCStatus */ + evpe(mtflags); +#else write_c0_entryhi(cpu_context(cpu, next)); +#endif /* CONFIG_MIPS_MT_SMTC */ TLBMISS_HANDLER_SETUP_PGD(next->pgd); /* mark mmu ownership change */ @@ -174,17 +248,49 @@ static inline void drop_mmu_context(struct mm_struct *mm, unsigned cpu) { unsigned long flags; +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long oldasid; + /* Can't use spinlock because called from TLB flush within DVPE */ + unsigned int prevvpe; + int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id; +#endif /* CONFIG_MIPS_MT_SMTC */ local_irq_save(flags); if (cpu_isset(cpu, mm->cpu_vm_mask)) { get_new_mmu_context(mm, cpu); +#ifdef CONFIG_MIPS_MT_SMTC + /* See comments for similar code above */ + prevvpe = dvpe(); + oldasid = (read_c0_entryhi() & ASID_MASK); + if(smtc_live_asid[mytlb][oldasid]) { + smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); + if(smtc_live_asid[mytlb][oldasid] == 0) + smtc_flush_tlb_asid(oldasid); + } + /* See comments for similar code above */ + write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) + | cpu_asid(cpu, mm)); + ehb(); /* Make sure it propagates to TCStatus */ + evpe(prevvpe); +#else /* not CONFIG_MIPS_MT_SMTC */ write_c0_entryhi(cpu_asid(cpu, mm)); +#endif /* CONFIG_MIPS_MT_SMTC */ } else { /* will get a new context next time */ +#ifndef CONFIG_MIPS_MT_SMTC cpu_context(cpu, mm) = 0; +#else /* SMTC */ + int i; + + /* SMTC shares the TLB (and ASIDs) across VPEs */ + for (i = 0; i < num_online_cpus(); i++) { + if((smtc_status & SMTC_TLB_SHARED) + || (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id)) + cpu_context(i, mm) = 0; + } +#endif /* CONFIG_MIPS_MT_SMTC */ } - local_irq_restore(flags); } diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 39d2bd50fec..786651340de 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -12,6 +12,7 @@ #define _ASM_PROCESSOR_H #include +#include #include #include @@ -107,6 +108,10 @@ struct mips_dsp_state { #define INIT_DSP {{0,},} +#define INIT_CPUMASK { \ + {0,} \ +} + typedef struct { unsigned long seg; } mm_segment_t; @@ -142,6 +147,7 @@ struct thread_struct { #define MF_LOGADE 2 /* Log address errors to syslog */ #define MF_32BIT_REGS 4 /* also implies 16/32 fprs */ #define MF_32BIT_ADDR 8 /* 32-bit address space (o32/n32) */ +#define MF_FPUBOUND 0x10 /* thread bound to FPU-full CPU set */ unsigned long mflags; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 95c5839ac46..fa9d8713c12 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -45,6 +45,10 @@ struct pt_regs { unsigned long cp0_badvaddr; unsigned long cp0_cause; unsigned long cp0_epc; +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long cp0_tcstatus; + unsigned long smtc_pad; +#endif /* CONFIG_MIPS_MT_SMTC */ }; /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index 2f2eb95387f..3c8e3c8d1a9 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -15,6 +15,7 @@ #include #include #include +#include /* * This macro return a properly sign-extended address suitable as base address @@ -39,14 +40,118 @@ : \ : "i" (op), "R" (*(unsigned char *)(addr))) +#ifdef CONFIG_MIPS_MT +/* + * Temporary hacks for SMTC debug. Optionally force single-threaded + * execution during I-cache flushes. + */ + +#define PROTECT_CACHE_FLUSHES 1 + +#ifdef PROTECT_CACHE_FLUSHES + +extern int mt_protiflush; +extern int mt_protdflush; +extern void mt_cflush_lockdown(void); +extern void mt_cflush_release(void); + +#define BEGIN_MT_IPROT \ + unsigned long flags = 0; \ + unsigned long mtflags = 0; \ + if(mt_protiflush) { \ + local_irq_save(flags); \ + ehb(); \ + mtflags = dvpe(); \ + mt_cflush_lockdown(); \ + } + +#define END_MT_IPROT \ + if(mt_protiflush) { \ + mt_cflush_release(); \ + evpe(mtflags); \ + local_irq_restore(flags); \ + } + +#define BEGIN_MT_DPROT \ + unsigned long flags = 0; \ + unsigned long mtflags = 0; \ + if(mt_protdflush) { \ + local_irq_save(flags); \ + ehb(); \ + mtflags = dvpe(); \ + mt_cflush_lockdown(); \ + } + +#define END_MT_DPROT \ + if(mt_protdflush) { \ + mt_cflush_release(); \ + evpe(mtflags); \ + local_irq_restore(flags); \ + } + +#else + +#define BEGIN_MT_IPROT +#define BEGIN_MT_DPROT +#define END_MT_IPROT +#define END_MT_DPROT + +#endif /* PROTECT_CACHE_FLUSHES */ + +#define __iflush_prologue \ + unsigned long redundance; \ + extern int mt_n_iflushes; \ + BEGIN_MT_IPROT \ + for (redundance = 0; redundance < mt_n_iflushes; redundance++) { + +#define __iflush_epilogue \ + END_MT_IPROT \ + } + +#define __dflush_prologue \ + unsigned long redundance; \ + extern int mt_n_dflushes; \ + BEGIN_MT_DPROT \ + for (redundance = 0; redundance < mt_n_dflushes; redundance++) { + +#define __dflush_epilogue \ + END_MT_DPROT \ + } + +#define __inv_dflush_prologue __dflush_prologue +#define __inv_dflush_epilogue __dflush_epilogue +#define __sflush_prologue { +#define __sflush_epilogue } +#define __inv_sflush_prologue __sflush_prologue +#define __inv_sflush_epilogue __sflush_epilogue + +#else /* CONFIG_MIPS_MT */ + +#define __iflush_prologue { +#define __iflush_epilogue } +#define __dflush_prologue { +#define __dflush_epilogue } +#define __inv_dflush_prologue { +#define __inv_dflush_epilogue } +#define __sflush_prologue { +#define __sflush_epilogue } +#define __inv_sflush_prologue { +#define __inv_sflush_epilogue } + +#endif /* CONFIG_MIPS_MT */ + static inline void flush_icache_line_indexed(unsigned long addr) { + __iflush_prologue cache_op(Index_Invalidate_I, addr); + __iflush_epilogue } static inline void flush_dcache_line_indexed(unsigned long addr) { + __dflush_prologue cache_op(Index_Writeback_Inv_D, addr); + __dflush_epilogue } static inline void flush_scache_line_indexed(unsigned long addr) @@ -56,17 +161,23 @@ static inline void flush_scache_line_indexed(unsigned long addr) static inline void flush_icache_line(unsigned long addr) { + __iflush_prologue cache_op(Hit_Invalidate_I, addr); + __iflush_epilogue } static inline void flush_dcache_line(unsigned long addr) { + __dflush_prologue cache_op(Hit_Writeback_Inv_D, addr); + __dflush_epilogue } static inline void invalidate_dcache_line(unsigned long addr) { + __dflush_prologue cache_op(Hit_Invalidate_D, addr); + __dflush_epilogue } static inline void invalidate_scache_line(unsigned long addr) @@ -239,9 +350,13 @@ static inline void blast_##pfx##cache##lsize(void) \ current_cpu_data.desc.waybit; \ unsigned long ws, addr; \ \ + __##pfx##flush_prologue \ + \ for (ws = 0; ws < ws_end; ws += ws_inc) \ for (addr = start; addr < end; addr += lsize * 32) \ cache##lsize##_unroll32(addr|ws,indexop); \ + \ + __##pfx##flush_epilogue \ } \ \ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ @@ -249,10 +364,14 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ unsigned long start = page; \ unsigned long end = page + PAGE_SIZE; \ \ + __##pfx##flush_prologue \ + \ do { \ cache##lsize##_unroll32(start,hitop); \ start += lsize * 32; \ } while (start < end); \ + \ + __##pfx##flush_epilogue \ } \ \ static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ @@ -265,9 +384,13 @@ static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) current_cpu_data.desc.waybit; \ unsigned long ws, addr; \ \ + __##pfx##flush_prologue \ + \ for (ws = 0; ws < ws_end; ws += ws_inc) \ for (addr = start; addr < end; addr += lsize * 32) \ cache##lsize##_unroll32(addr|ws,indexop); \ + \ + __##pfx##flush_epilogue \ } __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) @@ -288,12 +411,17 @@ static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ unsigned long lsize = cpu_##desc##_line_size(); \ unsigned long addr = start & ~(lsize - 1); \ unsigned long aend = (end - 1) & ~(lsize - 1); \ + \ + __##pfx##flush_prologue \ + \ while (1) { \ prot##cache_op(hitop, addr); \ if (addr == aend) \ break; \ addr += lsize; \ } \ + \ + __##pfx##flush_epilogue \ } __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) diff --git a/include/asm-mips/smtc.h b/include/asm-mips/smtc.h new file mode 100644 index 00000000000..e1941d1b872 --- /dev/null +++ b/include/asm-mips/smtc.h @@ -0,0 +1,55 @@ +#ifndef _ASM_SMTC_MT_H +#define _ASM_SMTC_MT_H + +/* + * Definitions for SMTC multitasking on MIPS MT cores + */ + +#include + +/* + * System-wide SMTC status information + */ + +extern unsigned int smtc_status; + +#define SMTC_TLB_SHARED 0x00000001 +#define SMTC_MTC_ACTIVE 0x00000002 + +/* + * TLB/ASID Management information + */ + +#define MAX_SMTC_TLBS 2 +#define MAX_SMTC_ASIDS 256 +#if NR_CPUS <= 8 +typedef char asiduse; +#else +#if NR_CPUS <= 16 +typedef short asiduse; +#else +typedef long asiduse; +#endif +#endif + +extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; + +void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu); + +void smtc_flush_tlb_asid(unsigned long asid); +extern int mipsmt_build_cpu_map(int startslot); +extern void mipsmt_prepare_cpus(void); +extern void smtc_smp_finish(void); +extern void smtc_boot_secondary(int cpu, struct task_struct *t); + +/* + * Sharing the TLB between multiple VPEs means that the + * "random" index selection function is not allowed to + * select the current value of the Index register. To + * avoid additional TLB pressure, the Index registers + * are "parked" with an non-Valid value. + */ + +#define PARKED_INDEX ((unsigned int)0x80000000) + +#endif /* _ASM_SMTC_MT_H */ diff --git a/include/asm-mips/smtc_ipi.h b/include/asm-mips/smtc_ipi.h new file mode 100644 index 00000000000..f22c3e2f993 --- /dev/null +++ b/include/asm-mips/smtc_ipi.h @@ -0,0 +1,118 @@ +/* + * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code. + */ +#ifndef __ASM_SMTC_IPI_H +#define __ASM_SMTC_IPI_H + +//#define SMTC_IPI_DEBUG + +#ifdef SMTC_IPI_DEBUG +#include +#include +#endif /* SMTC_IPI_DEBUG */ + +/* + * An IPI "message" + */ + +struct smtc_ipi { + struct smtc_ipi *flink; + int type; + void *arg; + int dest; +#ifdef SMTC_IPI_DEBUG + int sender; + long stamp; +#endif /* SMTC_IPI_DEBUG */ +}; + +/* + * Defined IPI Types + */ + +#define LINUX_SMP_IPI 1 +#define SMTC_CLOCK_TICK 2 + +/* + * A queue of IPI messages + */ + +struct smtc_ipi_q { + struct smtc_ipi *head; + spinlock_t lock; + struct smtc_ipi *tail; + int depth; +}; + +extern struct smtc_ipi_q IPIQ[NR_CPUS]; +extern struct smtc_ipi_q freeIPIq; + +static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p) +{ + long flags; + + spin_lock_irqsave(&q->lock, flags); + if (q->head == NULL) + q->head = q->tail = p; + else + q->tail->flink = p; + p->flink = NULL; + q->tail = p; + q->depth++; +#ifdef SMTC_IPI_DEBUG + p->sender = read_c0_tcbind(); + p->stamp = read_c0_count(); +#endif /* SMTC_IPI_DEBUG */ + spin_unlock_irqrestore(&q->lock, flags); +} + +static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q) +{ + struct smtc_ipi *p; + long flags; + + spin_lock_irqsave(&q->lock, flags); + if (q->head == NULL) + p = NULL; + else { + p = q->head; + q->head = q->head->flink; + q->depth--; + /* Arguably unnecessary, but leaves queue cleaner */ + if (q->head == NULL) + q->tail = NULL; + } + spin_unlock_irqrestore(&q->lock, flags); + return p; +} + +static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) +{ + long flags; + + spin_lock_irqsave(&q->lock, flags); + if (q->head == NULL) { + q->head = q->tail = p; + p->flink = NULL; + } else { + p->flink = q->head; + q->head = p; + } + q->depth++; + spin_unlock_irqrestore(&q->lock, flags); +} + +static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q) +{ + long flags; + int retval; + + spin_lock_irqsave(&q->lock, flags); + retval = q->depth; + spin_unlock_irqrestore(&q->lock, flags); + return retval; +} + +extern void smtc_send_ipi(int cpu, int type, unsigned int action); + +#endif /* __ASM_SMTC_IPI_H */ diff --git a/include/asm-mips/smtc_proc.h b/include/asm-mips/smtc_proc.h new file mode 100644 index 00000000000..25da651f1f5 --- /dev/null +++ b/include/asm-mips/smtc_proc.h @@ -0,0 +1,23 @@ +/* + * Definitions for SMTC /proc entries + * Copyright(C) 2005 MIPS Technologies Inc. + */ +#ifndef __ASM_SMTC_PROC_H +#define __ASM_SMTC_PROC_H + +/* + * per-"CPU" statistics + */ + +struct smtc_cpu_proc { + unsigned long timerints; + unsigned long selfipis; +}; + +extern struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS]; + +/* Count of number of recoveries of "stolen" FPU access rights on 34K */ + +extern atomic_t smtc_fpu_recoveries; + +#endif /* __ASM_SMTC_PROC_H */ diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 2acf3e844f0..c4856a87496 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -14,9 +14,14 @@ #include #include +#include #include #include +#ifdef CONFIG_MIPS_MT_SMTC +#include +#endif /* CONFIG_MIPS_MT_SMTC */ + .macro SAVE_AT .set push .set noat @@ -57,13 +62,30 @@ #ifdef CONFIG_SMP .macro get_saved_sp /* SMP variation */ #ifdef CONFIG_32BIT +#ifdef CONFIG_MIPS_MT_SMTC + .set mips32 + mfc0 k0, CP0_TCBIND; + .set mips0 + lui k1, %hi(kernelsp) + srl k0, k0, 19 + /* No need to shift down and up to clear bits 0-1 */ +#else mfc0 k0, CP0_CONTEXT lui k1, %hi(kernelsp) srl k0, k0, 23 +#endif addu k1, k0 LONG_L k1, %lo(kernelsp)(k1) #endif #ifdef CONFIG_64BIT +#ifdef CONFIG_MIPS_MT_SMTC + .set mips64 + mfc0 k0, CP0_TCBIND; + .set mips0 + lui k0, %highest(kernelsp) + dsrl k1, 19 + /* No need to shift down and up to clear bits 0-2 */ +#else MFC0 k1, CP0_CONTEXT lui k0, %highest(kernelsp) dsrl k1, 23 @@ -71,19 +93,30 @@ dsll k0, k0, 16 daddiu k0, %hi(kernelsp) dsll k0, k0, 16 +#endif /* CONFIG_MIPS_MT_SMTC */ daddu k1, k1, k0 LONG_L k1, %lo(kernelsp)(k1) -#endif +#endif /* CONFIG_64BIT */ .endm .macro set_saved_sp stackp temp temp2 #ifdef CONFIG_32BIT +#ifdef CONFIG_MIPS_MT_SMTC + mfc0 \temp, CP0_TCBIND + srl \temp, 19 +#else mfc0 \temp, CP0_CONTEXT srl \temp, 23 #endif +#endif #ifdef CONFIG_64BIT +#ifdef CONFIG_MIPS_MT_SMTC + mfc0 \temp, CP0_TCBIND + dsrl \temp, 19 +#else MFC0 \temp, CP0_CONTEXT dsrl \temp, 23 +#endif #endif LONG_S \stackp, kernelsp(\temp) .endm @@ -122,10 +155,25 @@ PTR_SUBU sp, k1, PT_SIZE LONG_S k0, PT_R29(sp) LONG_S $3, PT_R3(sp) + /* + * You might think that you don't need to save $0, + * but the FPU emulator and gdb remote debug stub + * need it to operate correctly + */ LONG_S $0, PT_R0(sp) mfc0 v1, CP0_STATUS LONG_S $2, PT_R2(sp) LONG_S v1, PT_STATUS(sp) +#ifdef CONFIG_MIPS_MT_SMTC + /* + * Ideally, these instructions would be shuffled in + * to cover the pipeline delay. + */ + .set mips32 + mfc0 v1, CP0_TCSTATUS + .set mips0 + LONG_S v1, PT_TCSTATUS(sp) +#endif /* CONFIG_MIPS_MT_SMTC */ LONG_S $4, PT_R4(sp) mfc0 v1, CP0_CAUSE LONG_S $5, PT_R5(sp) @@ -234,14 +282,36 @@ .endm #else +/* + * For SMTC kernel, global IE should be left set, and interrupts + * controlled exclusively via IXMT. + */ +#ifdef CONFIG_MIPS_MT_SMTC +#define STATMASK 0x1e +#else +#define STATMASK 0x1f +#endif .macro RESTORE_SOME .set push .set reorder .set noat +#ifdef CONFIG_MIPS_MT_SMTC + .set mips32r2 + /* + * This may not really be necessary if ints are already + * inhibited here. + */ + mfc0 v0, CP0_TCSTATUS + ori v0, TCSTATUS_IXMT + mtc0 v0, CP0_TCSTATUS + ehb + DMT 5 # dmt a1 + jal mips_ihb +#endif /* CONFIG_MIPS_MT_SMTC */ mfc0 a0, CP0_STATUS - ori a0, 0x1f - xori a0, 0x1f + ori a0, STATMASK + xori a0, STATMASK mtc0 a0, CP0_STATUS li v1, 0xff00 and a0, v1 @@ -250,6 +320,26 @@ and v0, v1 or v0, a0 mtc0 v0, CP0_STATUS +#ifdef CONFIG_MIPS_MT_SMTC +/* + * Only after EXL/ERL have been restored to status can we + * restore TCStatus.IXMT. + */ + LONG_L v1, PT_TCSTATUS(sp) + ehb + mfc0 v0, CP0_TCSTATUS + andi v1, TCSTATUS_IXMT + /* We know that TCStatua.IXMT should be set from above */ + xori v0, v0, TCSTATUS_IXMT + or v0, v0, v1 + mtc0 v0, CP0_TCSTATUS + ehb + andi a1, a1, VPECONTROL_TE + beqz a1, 1f + emt +1: + .set mips0 +#endif /* CONFIG_MIPS_MT_SMTC */ LONG_L v1, PT_EPC(sp) MTC0 v1, CP0_EPC LONG_L $31, PT_R31(sp) @@ -302,11 +392,33 @@ * Set cp0 enable bit as sign that we're running on the kernel stack */ .macro CLI +#if !defined(CONFIG_MIPS_MT_SMTC) mfc0 t0, CP0_STATUS li t1, ST0_CU0 | 0x1f or t0, t1 xori t0, 0x1f mtc0 t0, CP0_STATUS +#else /* CONFIG_MIPS_MT_SMTC */ + /* + * For SMTC, we need to set privilege + * and disable interrupts only for the + * current TC, using the TCStatus register. + */ + mfc0 t0,CP0_TCSTATUS + /* Fortunately CU 0 is in the same place in both registers */ + /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ + li t1, ST0_CU0 | 0x08001c00 + or t0,t1 + /* Clear TKSU, leave IXMT */ + xori t0, 0x00001800 + mtc0 t0, CP0_TCSTATUS + ehb + /* We need to leave the global IE bit set, but clear EXL...*/ + mfc0 t0, CP0_STATUS + ori t0, ST0_EXL | ST0_ERL + xori t0, ST0_EXL | ST0_ERL + mtc0 t0, CP0_STATUS +#endif /* CONFIG_MIPS_MT_SMTC */ irq_disable_hazard .endm @@ -315,11 +427,35 @@ * Set cp0 enable bit as sign that we're running on the kernel stack */ .macro STI +#if !defined(CONFIG_MIPS_MT_SMTC) mfc0 t0, CP0_STATUS li t1, ST0_CU0 | 0x1f or t0, t1 xori t0, 0x1e mtc0 t0, CP0_STATUS +#else /* CONFIG_MIPS_MT_SMTC */ + /* + * For SMTC, we need to set privilege + * and enable interrupts only for the + * current TC, using the TCStatus register. + */ + ehb + mfc0 t0,CP0_TCSTATUS + /* Fortunately CU 0 is in the same place in both registers */ + /* Set TCU0, TKSU (for later inversion) and IXMT */ + li t1, ST0_CU0 | 0x08001c00 + or t0,t1 + /* Clear TKSU *and* IXMT */ + xori t0, 0x00001c00 + mtc0 t0, CP0_TCSTATUS + ehb + /* We need to leave the global IE bit set, but clear EXL...*/ + mfc0 t0, CP0_STATUS + ori t0, ST0_EXL + xori t0, ST0_EXL + mtc0 t0, CP0_STATUS + /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */ +#endif /* CONFIG_MIPS_MT_SMTC */ irq_enable_hazard .endm @@ -328,11 +464,56 @@ * Set cp0 enable bit as sign that we're running on the kernel stack */ .macro KMODE +#ifdef CONFIG_MIPS_MT_SMTC + /* + * This gets baroque in SMTC. We want to + * protect the non-atomic clearing of EXL + * with DMT/EMT, but we don't want to take + * an interrupt while DMT is still in effect. + */ + + /* KMODE gets invoked from both reorder and noreorder code */ + .set push + .set mips32r2 + .set noreorder + mfc0 v0, CP0_TCSTATUS + andi v1, v0, TCSTATUS_IXMT + ori v0, TCSTATUS_IXMT + mtc0 v0, CP0_TCSTATUS + ehb + DMT 2 # dmt v0 + /* + * We don't know a priori if ra is "live" + */ + move t0, ra + jal mips_ihb + nop /* delay slot */ + move ra, t0 +#endif /* CONFIG_MIPS_MT_SMTC */ mfc0 t0, CP0_STATUS li t1, ST0_CU0 | 0x1e or t0, t1 xori t0, 0x1e mtc0 t0, CP0_STATUS +#ifdef CONFIG_MIPS_MT_SMTC + ehb + andi v0, v0, VPECONTROL_TE + beqz v0, 2f + nop /* delay slot */ + emt +2: + mfc0 v0, CP0_TCSTATUS + /* Clear IXMT, then OR in previous value */ + ori v0, TCSTATUS_IXMT + xori v0, TCSTATUS_IXMT + or v0, v1, v0 + mtc0 v0, CP0_TCSTATUS + /* + * irq_disable_hazard below should expand to EHB + * on 24K/34K CPUS + */ + .set pop +#endif /* CONFIG_MIPS_MT_SMTC */ irq_disable_hazard .endm -- cgit v1.2.3 From f088fc84f94c1a36943e28ad704a9a740a35f877 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 5 Apr 2006 09:45:47 +0100 Subject: [MIPS] FPU affinity for MT ASE. Signed-off-by: Ralf Baechle --- include/asm-mips/cpu-features.h | 2 +- include/asm-mips/fpu.h | 4 ++++ include/asm-mips/processor.h | 16 ++++++++++++++++ include/asm-mips/system.h | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h index 3f2b6d9ac45..254e11ed247 100644 --- a/include/asm-mips/cpu-features.h +++ b/include/asm-mips/cpu-features.h @@ -40,7 +40,7 @@ #define cpu_has_sb1_cache (cpu_data[0].options & MIPS_CPU_SB1_CACHE) #endif #ifndef cpu_has_fpu -#define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU) +#define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU) #endif #ifndef cpu_has_32fpr #define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h index 9c828b1f821..b0f50015e25 100644 --- a/include/asm-mips/fpu.h +++ b/include/asm-mips/fpu.h @@ -21,6 +21,10 @@ #include #include +#ifdef CONFIG_MIPS_MT_FPAFF +#include +#endif + struct sigcontext; struct sigcontext32; diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 786651340de..0fb75f0762e 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -134,6 +134,12 @@ struct thread_struct { /* Saved fpu/fpu emulator stuff. */ union mips_fpu_union fpu; +#ifdef CONFIG_MIPS_MT_FPAFF + /* Emulated instruction count */ + unsigned long emulated_fp; + /* Saved per-thread scheduler affinity mask */ + cpumask_t user_cpus_allowed; +#endif /* CONFIG_MIPS_MT_FPAFF */ /* Saved state of the DSP ASE, if available. */ struct mips_dsp_state dsp; @@ -159,6 +165,12 @@ struct thread_struct { #define MF_N32 MF_32BIT_ADDR #define MF_N64 0 +#ifdef CONFIG_MIPS_MT_FPAFF +#define FPAFF_INIT 0, INIT_CPUMASK, +#else +#define FPAFF_INIT +#endif /* CONFIG_MIPS_MT_FPAFF */ + #define INIT_THREAD { \ /* \ * saved main processor registers \ @@ -173,6 +185,10 @@ struct thread_struct { * saved fpu/fpu emulator stuff \ */ \ INIT_FPU, \ + /* \ + * fpu affinity state (null if not FPAFF) \ + */ \ + FPAFF_INIT \ /* \ * saved dsp/dsp emulator stuff \ */ \ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 39026690d9e..261f71d16a0 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -155,6 +155,37 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti); struct task_struct; +#ifdef CONFIG_MIPS_MT_FPAFF + +/* + * Handle the scheduler resume end of FPU affinity management. We do this + * inline to try to keep the overhead down. If we have been forced to run on + * a "CPU" with an FPU because of a previous high level of FP computation, + * but did not actually use the FPU during the most recent time-slice (CU1 + * isn't set), we undo the restriction on cpus_allowed. + * + * We're not calling set_cpus_allowed() here, because we have no need to + * force prompt migration - we're already switching the current CPU to a + * different thread. + */ + +#define switch_to(prev,next,last) \ +do { \ + if (cpu_has_fpu && \ + (prev->thread.mflags & MF_FPUBOUND) && \ + (!(KSTK_STATUS(prev) & ST0_CU1))) { \ + prev->thread.mflags &= ~MF_FPUBOUND; \ + prev->cpus_allowed = prev->thread.user_cpus_allowed; \ + } \ + if (cpu_has_dsp) \ + __save_dsp(prev); \ + next->thread.emulated_fp = 0; \ + (last) = resume(prev, next, next->thread_info); \ + if (cpu_has_dsp) \ + __restore_dsp(current); \ +} while(0) + +#else #define switch_to(prev,next,last) \ do { \ if (cpu_has_dsp) \ @@ -163,6 +194,7 @@ do { \ if (cpu_has_dsp) \ __restore_dsp(current); \ } while(0) +#endif /* * On SMP systems, when the scheduler does migration-cost autodetection, -- cgit v1.2.3 From b4ade4bf8811c7267b9f32b4a5d8fcfde714adac Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 5 Apr 2006 09:45:48 +0100 Subject: [MIPS] MIPS boards: Set HZ to 100. 1000Hz will bring an FPGA CPU down on it's knees and it's even worse on multithreaded cores. Signed-off-by: Ralf Baechle --- include/asm-mips/mach-mips/param.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 include/asm-mips/mach-mips/param.h (limited to 'include') diff --git a/include/asm-mips/mach-mips/param.h b/include/asm-mips/mach-mips/param.h new file mode 100644 index 00000000000..805ef6d27d3 --- /dev/null +++ b/include/asm-mips/mach-mips/param.h @@ -0,0 +1,13 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 by Ralf Baechle + */ +#ifndef __ASM_MACH_MIPS_PARAM_H +#define __ASM_MACH_MIPS_PARAM_H + +#define HZ 100 /* Internal kernel timer frequency */ + +#endif /* __ASM_MACH_MIPS_PARAM_H */ -- cgit v1.2.3 From 7e3bfc7cfc402458b0386086ab650ce811720927 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 5 Apr 2006 20:42:04 +0100 Subject: [MIPS] Handle IDE PIO cache aliases on SMP. Signed-off-by: Ralf Baechle --- include/asm-mips/cacheflush.h | 1 + include/asm-mips/mach-generic/ide.h | 46 +++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h index aeae9fabf4a..47bc8f6c20d 100644 --- a/include/asm-mips/cacheflush.h +++ b/include/asm-mips/cacheflush.h @@ -74,6 +74,7 @@ static inline void copy_from_user_page(struct vm_area_struct *vma, extern void (*flush_cache_sigtramp)(unsigned long addr); extern void (*flush_icache_all)(void); +extern void (*local_flush_data_cache_page)(void * addr); extern void (*flush_data_cache_page)(unsigned long addr); /* diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h index 550979a9ea9..e3315359500 100644 --- a/include/asm-mips/mach-generic/ide.h +++ b/include/asm-mips/mach-generic/ide.h @@ -104,65 +104,107 @@ static __inline__ unsigned long ide_default_io_base(int index) #endif /* MIPS port and memory-mapped I/O string operations. */ +static inline void __ide_flush_prologue(void) +{ +#ifdef CONFIG_SMP + if (cpu_has_dc_aliases) + preempt_disable(); +#endif +} + +static inline void __ide_flush_epilogue(void) +{ +#ifdef CONFIG_SMP + if (cpu_has_dc_aliases) + preempt_enable(); +#endif +} static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size) { if (cpu_has_dc_aliases) { unsigned long end = addr + size; - for (; addr < end; addr += PAGE_SIZE) - flush_dcache_page(virt_to_page(addr)); + + while (addr < end) { + local_flush_data_cache_page((void *)addr); + addr += PAGE_SIZE; + } } } +/* + * insw() and gang might be called with interrupts disabled, so we can't + * send IPIs for flushing due to the potencial of deadlocks, see the comment + * above smp_call_function() in arch/mips/kernel/smp.c. We work around the + * problem by disabling preemption so we know we actually perform the flush + * on the processor that actually has the lines to be flushed which hopefully + * is even better for performance anyway. + */ static inline void __ide_insw(unsigned long port, void *addr, unsigned int count) { + __ide_flush_prologue(); insw(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 2); + __ide_flush_epilogue(); } static inline void __ide_insl(unsigned long port, void *addr, unsigned int count) { + __ide_flush_prologue(); insl(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 4); + __ide_flush_epilogue(); } static inline void __ide_outsw(unsigned long port, const void *addr, unsigned long count) { + __ide_flush_prologue(); outsw(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 2); + __ide_flush_epilogue(); } static inline void __ide_outsl(unsigned long port, const void *addr, unsigned long count) { + __ide_flush_prologue(); outsl(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 4); + __ide_flush_epilogue(); } static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count) { + __ide_flush_prologue(); readsw(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 2); + __ide_flush_epilogue(); } static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count) { + __ide_flush_prologue(); readsl(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 4); + __ide_flush_epilogue(); } static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count) { + __ide_flush_prologue(); writesw(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 2); + __ide_flush_epilogue(); } static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count) { + __ide_flush_prologue(); writesl(port, addr, count); __ide_flush_dcache_range((unsigned long)addr, count * 4); + __ide_flush_epilogue(); } /* ide_insw calls insw, not __ide_insw. Why? */ -- cgit v1.2.3 From 5e85d4abe3f43bb5362f384bab0e20ef082ce0b5 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 18 Apr 2006 22:20:16 -0700 Subject: [PATCH] task: Make task list manipulations RCU safe While we can currently walk through thread groups, process groups, and sessions with just the rcu_read_lock, this opens the door to walking the entire task list. We already have all of the other RCU guarantees so there is no cost in doing this, this should be enough so that proc can stop taking the tasklist lock during readdir. prev_task was killed because it has no users, and using it will miss new tasks when doing an rcu traversal. Signed-off-by: Eric W. Biederman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/sched.h b/include/linux/sched.h index b7d31e2e172..29b7d4f87d2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1192,8 +1192,7 @@ extern void wait_task_inactive(task_t * p); #define remove_parent(p) list_del_init(&(p)->sibling) #define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) -#define next_task(p) list_entry((p)->tasks.next, struct task_struct, tasks) -#define prev_task(p) list_entry((p)->tasks.prev, struct task_struct, tasks) +#define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) #define for_each_process(p) \ for (p = &init_task ; (p = next_task(p)) != &init_task ; ) -- cgit v1.2.3 From 676ff453e58c5ff7ddbfebf5a11142e3e4add161 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Tue, 18 Apr 2006 22:20:21 -0700 Subject: [PATCH] for_each_possible_cpu: x86_64 for_each_cpu() actually iterates across all possible CPUs. We've had mistakes in the past where people were using for_each_cpu() where they should have been iterating across only online or present CPUs. This is inefficient and possibly buggy. We're renaming for_each_cpu() to for_each_possible_cpu() to avoid this in the future. This patch replaces for_each_cpu with for_each_possible_cpu. Signed-off-by: KAMEZAWA Hiroyuki Acked-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86_64/percpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h index 4405b4adeab..7f33aaf9f7b 100644 --- a/include/asm-x86_64/percpu.h +++ b/include/asm-x86_64/percpu.h @@ -26,7 +26,7 @@ #define percpu_modcopy(pcpudst, src, size) \ do { \ unsigned int __i; \ - for_each_cpu(__i) \ + for_each_possible_cpu(__i) \ memcpy((pcpudst)+__per_cpu_offset(__i), \ (src), (size)); \ } while (0) -- cgit v1.2.3 From 1bb858f27eadc54e24dfa351fcae724cff426de2 Mon Sep 17 00:00:00 2001 From: lepton Date: Tue, 18 Apr 2006 22:21:10 -0700 Subject: [PATCH] asm-i386/atomic.h: local_irq_save should be used instead of local_irq_disable atomic_add_return() if CONFIG_M386 can accidentally enable local interrupts. Signed-off-by: Lepton Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-i386/atomic.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h index 22d80ece95c..4ddce5296a7 100644 --- a/include/asm-i386/atomic.h +++ b/include/asm-i386/atomic.h @@ -183,6 +183,7 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) { int __i; #ifdef CONFIG_M386 + unsigned long flags; if(unlikely(boot_cpu_data.x86==3)) goto no_xadd; #endif @@ -196,10 +197,10 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) #ifdef CONFIG_M386 no_xadd: /* Legacy 386 processor */ - local_irq_disable(); + local_irq_save(flags); __i = atomic_read(v); atomic_set(v, i + __i); - local_irq_enable(); + local_irq_restore(flags); return i + __i; #endif } -- cgit v1.2.3 From 8e8ff02c0b61d9b7c15c7996a2eddbedf51a105b Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 18 Apr 2006 22:21:20 -0700 Subject: [PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target This modification is required to fix debugging function for m32r targets with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct sigcontext' size for all M32R ISA. Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1. This means there are two variations of thread context. So far, we reduced and changed stackframe size at a syscall for their context size. However, this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2 cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2. From the viewpoint of GDB support, we should reduce such variation of stackframe size for simplicity. In this patch, dummy members are added to 'struct pt_regs' and 'struct sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2. This modification is also a one step for a GDB update in future. Currently, on the m32r, GDB can access process's context by using ptrace functions in a simple way of register by register access. By unifying stackframe size, we have a possibility to make use of ptrace functions of not only a single register access but also block register access, PTRACE_{GETREGS,PUTREGS}. However, for this purpose, we might have to modify stackframe structure some more; for example, PSW (processor status word) register should be pre-processed before pushing to stack at a syscall, and so on. In this case, we must update carefully both kernel and GDB at a time... Signed-off-by: Hayato Fujiwara Signed-off-by: Hirokazu Takata Cc: Kei Sakamoto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-m32r/assembler.h | 5 +++++ include/asm-m32r/ptrace.h | 25 ++++++++++--------------- include/asm-m32r/sigcontext.h | 2 ++ 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/asm-m32r/assembler.h b/include/asm-m32r/assembler.h index b7f4d8aaeb4..1a1aa17edd3 100644 --- a/include/asm-m32r/assembler.h +++ b/include/asm-m32r/assembler.h @@ -109,6 +109,9 @@ push r13 mvfachi r13 push r13 + ldi r13, #0 + push r13 ; dummy push acc1h + push r13 ; dummy push acc1l #else #error unknown isa configuration #endif @@ -156,6 +159,8 @@ pop r13 mvtaclo r13, a1 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) + pop r13 ; dummy pop acc1h + pop r13 ; dummy pop acc1l pop r13 mvtachi r13 pop r13 diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h index 0d058b2d844..53c792452df 100644 --- a/include/asm-m32r/ptrace.h +++ b/include/asm-m32r/ptrace.h @@ -43,6 +43,14 @@ #define PT_ACC1L 18 #define PT_ACCH PT_ACC0H #define PT_ACCL PT_ACC0L +#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) +#define PT_ACCH 15 +#define PT_ACCL 16 +#define PT_DUMMY_ACC1H 17 +#define PT_DUMMY_ACC1L 18 +#else +#error unknown isa conifiguration +#endif #define PT_PSW 19 #define PT_BPC 20 #define PT_BBPSW 21 @@ -52,21 +60,6 @@ #define PT_LR 25 #define PT_SPI 26 #define PT_ORIGR0 27 -#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) -#define PT_ACCH 15 -#define PT_ACCL 16 -#define PT_PSW 17 -#define PT_BPC 18 -#define PT_BBPSW 19 -#define PT_BBPC 20 -#define PT_SPU 21 -#define PT_FP 22 -#define PT_LR 23 -#define PT_SPI 24 -#define PT_ORIGR0 25 -#else -#error unknown isa conifiguration -#endif /* virtual pt_reg entry for gdb */ #define PT_PC 30 @@ -121,6 +114,8 @@ struct pt_regs { #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) unsigned long acch; unsigned long accl; + unsigned long dummy_acc1h; + unsigned long dummy_acc1l; #else #error unknown isa configuration #endif diff --git a/include/asm-m32r/sigcontext.h b/include/asm-m32r/sigcontext.h index c233e2def2a..942b8a30937 100644 --- a/include/asm-m32r/sigcontext.h +++ b/include/asm-m32r/sigcontext.h @@ -32,6 +32,8 @@ struct sigcontext { #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) unsigned long sc_acch; unsigned long sc_accl; + unsigned long sc_dummy_acc1h; + unsigned long sc_dummy_acc1l; #else #error unknown isa configuration #endif -- cgit v1.2.3 From fa372810e51979c5044e036a34015845e9c6aedd Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 18 Apr 2006 22:21:25 -0700 Subject: [PATCH] m32r: update include/asm-m32r/semaphore.h This patch updates include/asm-m32r/semaphore.h for good readability and maintainability. Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-m32r/semaphore.h | 64 +++----------------------------------------- 1 file changed, 4 insertions(+), 60 deletions(-) (limited to 'include') diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h index bf447c52a0a..81750edc891 100644 --- a/include/asm-m32r/semaphore.h +++ b/include/asm-m32r/semaphore.h @@ -9,7 +9,7 @@ * SMP- and interrupt-safe semaphores.. * * Copyright (C) 1996 Linus Torvalds - * Copyright (C) 2004 Hirokazu Takata + * Copyright (C) 2004, 2006 Hirokazu Takata */ #include @@ -77,27 +77,8 @@ asmlinkage void __up(struct semaphore * sem); */ static inline void down(struct semaphore * sem) { - unsigned long flags; - long count; - might_sleep(); - local_irq_save(flags); - __asm__ __volatile__ ( - "# down \n\t" - DCACHE_CLEAR("%0", "r4", "%1") - M32R_LOCK" %0, @%1; \n\t" - "addi %0, #-1; \n\t" - M32R_UNLOCK" %0, @%1; \n\t" - : "=&r" (count) - : "r" (&sem->count) - : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ - ); - local_irq_restore(flags); - - if (unlikely(count < 0)) + if (unlikely(atomic_dec_return(&sem->count) < 0)) __down(sem); } @@ -107,28 +88,10 @@ static inline void down(struct semaphore * sem) */ static inline int down_interruptible(struct semaphore * sem) { - unsigned long flags; - long count; int result = 0; might_sleep(); - local_irq_save(flags); - __asm__ __volatile__ ( - "# down_interruptible \n\t" - DCACHE_CLEAR("%0", "r4", "%1") - M32R_LOCK" %0, @%1; \n\t" - "addi %0, #-1; \n\t" - M32R_UNLOCK" %0, @%1; \n\t" - : "=&r" (count) - : "r" (&sem->count) - : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ - ); - local_irq_restore(flags); - - if (unlikely(count < 0)) + if (unlikely(atomic_dec_return(&sem->count) < 0)) result = __down_interruptible(sem); return result; @@ -174,26 +137,7 @@ static inline int down_trylock(struct semaphore * sem) */ static inline void up(struct semaphore * sem) { - unsigned long flags; - long count; - - local_irq_save(flags); - __asm__ __volatile__ ( - "# up \n\t" - DCACHE_CLEAR("%0", "r4", "%1") - M32R_LOCK" %0, @%1; \n\t" - "addi %0, #1; \n\t" - M32R_UNLOCK" %0, @%1; \n\t" - : "=&r" (count) - : "r" (&sem->count) - : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ - ); - local_irq_restore(flags); - - if (unlikely(count <= 0)) + if (unlikely(atomic_inc_return(&sem->count) <= 0)) __up(sem); } -- cgit v1.2.3 From 0d34c86c3b75e5fd7cde15c965349b0104e06e53 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 18 Apr 2006 22:21:30 -0700 Subject: [PATCH] m32r: mappi3 reboot support Here is a patch to support a reboot function for M3A-2170(Mappi-III) evaluation board. Signed-off-by: Hayato Fujiwara Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-m32r/mappi3/mappi3_pld.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h index 1d3c25d61bc..031369a7afc 100644 --- a/include/asm-m32r/mappi3/mappi3_pld.h +++ b/include/asm-m32r/mappi3/mappi3_pld.h @@ -53,16 +53,14 @@ /* Power Control of MMC and CF */ #define PLD_CPCR __reg16(PLD_BASE + 0x14000) - -/*==== ICU ====*/ -#define M32R_IRQ_PC104 (5) /* INT4(PC/104) */ -#define M32R_IRQ_I2C (28) /* I2C-BUS */ -#define PLD_IRQ_CFIREQ (6) /* INT5 CFC Card Interrupt */ -#define PLD_IRQ_CFC_INSERT (7) /* INT6 CFC Card Insert */ -#define PLD_IRQ_IDEIREQ (8) /* INT7 IDE Interrupt */ -#define PLD_IRQ_MMCCARD (43) /* MMC Card Insert */ -#define PLD_IRQ_MMCIRQ (44) /* MMC Transfer Done */ - +/* ICU */ +#define M32R_IRQ_PC104 (5) /* INT4(PC/104) */ +#define M32R_IRQ_I2C (28) /* I2C-BUS */ +#define PLD_IRQ_CFIREQ (6) /* INT5 CFC Card Interrupt */ +#define PLD_IRQ_CFC_INSERT (7) /* INT6 CFC Card Insert & Eject */ +#define PLD_IRQ_IDEIREQ (8) /* INT7 IDE Interrupt */ +#define PLD_IRQ_MMCCARD (43) /* MMC Card Insert */ +#define PLD_IRQ_MMCIRQ (44) /* MMC Transfer Done */ #if 0 /* LED Control @@ -97,7 +95,6 @@ #define PLD_CRC16ADATA __reg16(PLD_BASE + 0x18008) #define PLD_CRC16AINDATA __reg16(PLD_BASE + 0x1800a) - #if 0 /* RTC */ #define PLD_RTCCR __reg16(PLD_BASE + 0x1c000) @@ -140,4 +137,7 @@ #endif +/* Reset Control */ +#define PLD_REBOOT __reg16(PLD_BASE + 0x38000) + #endif /* _MAPPI3_PLD.H */ -- cgit v1.2.3 From 4127272c38619c56f0c1aa01d01c7bd757db70a1 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 18 Apr 2006 22:21:38 -0700 Subject: [PATCH] m32r: update switch_to macro for tuning - Remove unnecessary push/pop's of the switch_to() macro for performance tuning. - Cosmetic updates: change __inline__ to inline, etc. Signed-off-by: Hirokazu Takata Cc: NIIBE Yutaka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-m32r/system.h | 67 ++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h index c5ab5da56d2..e55013f378e 100644 --- a/include/asm-m32r/system.h +++ b/include/asm-m32r/system.h @@ -6,8 +6,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 by Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto - * Copyright (C) 2004 Hirokazu Takata + * Copyright (C) 2001 Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto + * Copyright (C) 2004, 2006 Hirokazu Takata */ #include @@ -19,49 +19,28 @@ * switch_to(prev, next) should switch from task `prev' to `next' * `prev' will never be the same as `next'. * - * `next' and `prev' should be struct task_struct, but it isn't always defined + * `next' and `prev' should be task_t, but it isn't always defined */ #define switch_to(prev, next, last) do { \ - register unsigned long arg0 __asm__ ("r0") = (unsigned long)prev; \ - register unsigned long arg1 __asm__ ("r1") = (unsigned long)next; \ - register unsigned long *oldsp __asm__ ("r2") = &(prev->thread.sp); \ - register unsigned long *newsp __asm__ ("r3") = &(next->thread.sp); \ - register unsigned long *oldlr __asm__ ("r4") = &(prev->thread.lr); \ - register unsigned long *newlr __asm__ ("r5") = &(next->thread.lr); \ - register struct task_struct *__last __asm__ ("r6"); \ __asm__ __volatile__ ( \ - "st r8, @-r15 \n\t" \ - "st r9, @-r15 \n\t" \ - "st r10, @-r15 \n\t" \ - "st r11, @-r15 \n\t" \ - "st r12, @-r15 \n\t" \ - "st r13, @-r15 \n\t" \ - "st r14, @-r15 \n\t" \ - "seth r14, #high(1f) \n\t" \ - "or3 r14, r14, #low(1f) \n\t" \ - "st r14, @r4 ; store old LR \n\t" \ - "st r15, @r2 ; store old SP \n\t" \ - "ld r15, @r3 ; load new SP \n\t" \ - "st r0, @-r15 ; store 'prev' onto new stack \n\t" \ - "ld r14, @r5 ; load new LR \n\t" \ - "jmp r14 \n\t" \ - ".fillinsn \n " \ - "1: \n\t" \ - "ld r6, @r15+ ; load 'prev' from new stack \n\t" \ - "ld r14, @r15+ \n\t" \ - "ld r13, @r15+ \n\t" \ - "ld r12, @r15+ \n\t" \ - "ld r11, @r15+ \n\t" \ - "ld r10, @r15+ \n\t" \ - "ld r9, @r15+ \n\t" \ - "ld r8, @r15+ \n\t" \ - : "=&r" (__last) \ - : "r" (arg0), "r" (arg1), "r" (oldsp), "r" (newsp), \ - "r" (oldlr), "r" (newlr) \ - : "memory" \ + " seth lr, #high(1f) \n" \ + " or3 lr, lr, #low(1f) \n" \ + " st lr, @%4 ; store old LR \n" \ + " ld lr, @%5 ; load new LR \n" \ + " st sp, @%2 ; store old SP \n" \ + " ld sp, @%3 ; load new SP \n" \ + " push %1 ; store `prev' on new stack \n" \ + " jmp lr \n" \ + " .fillinsn \n" \ + "1: \n" \ + " pop %0 ; restore `__last' from new stack \n" \ + : "=r" (last) \ + : "0" (prev), \ + "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \ + "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \ + : "memory", "lr" \ ); \ - last = __last; \ } while(0) /* @@ -167,8 +146,8 @@ extern void __xchg_called_with_bad_pointer(void); #define DCACHE_CLEAR(reg0, reg1, addr) #endif /* CONFIG_CHIP_M32700_TS1 */ -static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, - int size) +static inline unsigned long +__xchg(unsigned long x, volatile void * ptr, int size) { unsigned long flags; unsigned long tmp = 0; @@ -220,7 +199,7 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, #define __HAVE_ARCH_CMPXCHG 1 -static __inline__ unsigned long +static inline unsigned long __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new) { unsigned long flags; @@ -254,7 +233,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new) if something tries to do an invalid cmpxchg(). */ extern void __cmpxchg_called_with_bad_pointer(void); -static __inline__ unsigned long +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { switch (size) { -- cgit v1.2.3 From 6e89280184e4990f5ea80d2504af89b6099523c4 Mon Sep 17 00:00:00 2001 From: Anatoli Antonovitch Date: Tue, 18 Apr 2006 22:22:05 -0700 Subject: [PATCH] ide: ATI SB600 IDE support Add support for the IDE device on ATI SB600 Signed-off-by: Felix Kuehling Acked-by: Bartlomiej Zolnierkiewicz Cc: Alan Cox Acked-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci_ids.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8d03e10212f..d6fe048376a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -356,6 +356,10 @@ #define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e #define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 +#define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a +#define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 +#define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381 +#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c #define PCI_VENDOR_ID_VLSI 0x1004 #define PCI_DEVICE_ID_VLSI_82C592 0x0005 -- cgit v1.2.3 From d3a7b202995421631f486313aacf9ab2ad48b2c8 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 18 Apr 2006 22:22:07 -0700 Subject: [PATCH] remove the obsolete IDEPCI_FLAG_FORCE_PDC Noted by Sergei Shtylylov Signed-off-by: Adrian Bunk Acked-by: Bartlomiej Zolnierkiewicz Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 8d2db412ba9..a8bef1d1371 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1220,7 +1220,6 @@ typedef struct ide_pci_enablebit_s { enum { /* Uses ISA control ports not PCI ones. */ IDEPCI_FLAG_ISA_PORTS = (1 << 0), - IDEPCI_FLAG_FORCE_PDC = (1 << 1), }; typedef struct ide_pci_device_s { -- cgit v1.2.3 From 7866babad542bb5e1dc95deb5800b577abef58dd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 18 Apr 2006 13:14:13 -0400 Subject: NFS: fix PROC_FS=n compile error fs/built-in.o: In function `nfs_show_stats':inode.c:(.text+0x15481a): undefined reference to `rpc_print_iostats' net/built-in.o: In function `rpc_destroy_client': undefined reference to `rpc_free_iostats' net/built-in.o: In function `rpc_clone_client': undefined reference to `rpc_alloc_iostats' net/built-in.o: In function `rpc_new_client': undefined reference to `rpc_alloc_iostats' net/built-in.o: In function `xprt_release': undefined reference to `rpc_count_iostats' make: *** [.tmp_vmlinux1] Error 1 Signed-off-by: Adrian Bunk Cc: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Trond Myklebust --- include/linux/sunrpc/metrics.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/linux/sunrpc/metrics.h b/include/linux/sunrpc/metrics.h index 8f96e9dc369..77f78e56c48 100644 --- a/include/linux/sunrpc/metrics.h +++ b/include/linux/sunrpc/metrics.h @@ -69,9 +69,21 @@ struct rpc_clnt; /* * EXPORTed functions for managing rpc_iostats structures */ + +#ifdef CONFIG_PROC_FS + struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *); void rpc_count_iostats(struct rpc_task *); void rpc_print_iostats(struct seq_file *, struct rpc_clnt *); void rpc_free_iostats(struct rpc_iostats *); +#else /* CONFIG_PROC_FS */ + +static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } +static inline void rpc_count_iostats(struct rpc_task *task) {} +static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} +static inline void rpc_free_iostats(struct rpc_iostats *stats) {} + +#endif /* CONFIG_PROC_FS */ + #endif /* _LINUX_SUNRPC_METRICS_H */ -- cgit v1.2.3 From e99170ff3b799a9fd43d538932a9231fac1de9d4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 18 Apr 2006 13:21:42 -0400 Subject: NFS,SUNRPC: Fix compiler warnings if CONFIG_PROC_FS & CONFIG_SYSCTL are unset Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprt.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 7eebbab7160..e8bbe8118de 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -53,6 +53,7 @@ struct rpc_timeout { struct rpc_task; struct rpc_xprt; +struct seq_file; /* * This describes a complete RPC request -- cgit v1.2.3 From feeeaa87e8e6702f57ed3be7904ffd87cc044b82 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 13 Apr 2006 02:42:42 +0200 Subject: [PATCH] softmac: fix event sending Softmac is sending custom events to userspace already, but it should _really_ be sending the right WEXT events instead. This patch fixes that. Signed-off-by: Dan Williams Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/ieee80211softmac.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h index b971d8c82bd..6b3693f05ca 100644 --- a/include/net/ieee80211softmac.h +++ b/include/net/ieee80211softmac.h @@ -267,8 +267,9 @@ extern void ieee80211softmac_stop(struct net_device *dev); #define IEEE80211SOFTMAC_EVENT_AUTH_FAILED 5 #define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT 6 #define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND 7 +#define IEEE80211SOFTMAC_EVENT_DISASSOCIATED 8 /* keep this updated! */ -#define IEEE80211SOFTMAC_EVENT_LAST 7 +#define IEEE80211SOFTMAC_EVENT_LAST 8 /* * If you want to be notified of certain events, you can call * ieee80211softmac_notify[_atomic] with -- cgit v1.2.3 From 2784f40e2774b61d68d232bcf92a9484e99f22b8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 19 Apr 2006 15:00:01 -0700 Subject: [SPARC]: __NR_sys_splice --> __NR_splice Signed-off-by: David S. Miller --- include/asm-sparc/unistd.h | 2 +- include/asm-sparc64/unistd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 2a911aa4cae..45feff893b8 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -248,7 +248,7 @@ #define __NR_setfsgid 229 /* Linux Specific */ #define __NR__newselect 230 /* Linux Specific */ #define __NR_time 231 /* Linux Specific */ -#define __NR_sys_splice 232 /* Linux Specific */ +#define __NR_splice 232 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */ #define __NR_statfs64 234 /* Linux Specific */ #define __NR_fstatfs64 235 /* Linux Specific */ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 6ada6a871cc..597f6923a46 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -250,7 +250,7 @@ #ifdef __KERNEL__ #define __NR_time 231 /* Linux sparc32 */ #endif -#define __NR_sys_splice 232 /* Linux Specific */ +#define __NR_splice 232 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */ #define __NR_statfs64 234 /* Linux Specific */ #define __NR_fstatfs64 235 /* Linux Specific */ -- cgit v1.2.3 From dc6de33674608f978ec29f5c2f7e3af458c06f78 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Apr 2006 00:10:50 -0700 Subject: [NET]: Add skb->truesize assertion checking. Add some sanity checking. truesize should be at least sizeof(struct sk_buff) plus the current packet length. If not, then truesize is seriously mangled and deserves a kernel log message. Currently we'll do the check for release of stream socket buffers. But we can add checks to more spots over time. Incorporating ideas from Herbert Xu. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 7 +++++++ include/net/sock.h | 1 + 2 files changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index c4619a428d9..f8f234708b9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -344,6 +344,13 @@ extern void skb_over_panic(struct sk_buff *skb, int len, void *here); extern void skb_under_panic(struct sk_buff *skb, int len, void *here); +extern void skb_truesize_bug(struct sk_buff *skb); + +static inline void skb_truesize_check(struct sk_buff *skb) +{ + if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len)) + skb_truesize_bug(skb); +} extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, int getfrag(void *from, char *to, int offset, diff --git a/include/net/sock.h b/include/net/sock.h index af2b0544586..ff8b0dad7b0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -454,6 +454,7 @@ static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk) static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) { + skb_truesize_check(skb); sock_set_flag(sk, SOCK_QUEUE_SHRUNK); sk->sk_wmem_queued -= skb->truesize; sk->sk_forward_alloc += skb->truesize; -- cgit v1.2.3 From 68876baf5e713ef711b6e19a279385e14c9921e3 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 20 Apr 2006 02:43:15 -0700 Subject: [PATCH] xtensa: Fix TIOCGICOUNT macro Remove the dependence on the async_icount structure in the TIOCGICOUNT macro for Xtensa. (Thanks Russell and Adrian for pointing this out) Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-xtensa/ioctls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-xtensa/ioctls.h b/include/asm-xtensa/ioctls.h index 10c443435c1..3b89a772d0a 100644 --- a/include/asm-xtensa/ioctls.h +++ b/include/asm-xtensa/ioctls.h @@ -107,6 +107,6 @@ #define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */ #define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT _IOR('T', 93, struct async_icount) /* read serial port inline interrupt counts */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #endif /* _XTENSA_IOCTLS_H */ -- cgit v1.2.3 From 72b38d436e4cd18185de11f4b48a6e62eb104644 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 20 Apr 2006 02:43:23 -0700 Subject: [PATCH] memory_hotplug.h cleanup We don't have to #if guard prototypes. This also fixes a bug observed by Randy Dunlap due to a misspelled option in the #if. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memory_hotplug.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 4ca3e6ad03e..91120638617 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -99,10 +99,7 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, return -ENOSYS; } -#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ - || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) extern int add_memory(u64 start, u64 size); extern int remove_memory(u64 start, u64 size); -#endif #endif /* __LINUX_MEMORY_HOTPLUG_H */ -- cgit v1.2.3 From 18bd057b1408cd110ed23281533430cfc2d52091 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 20 Apr 2006 02:36:45 +0200 Subject: [PATCH] i386/x86-64: Fix x87 information leak between processes AMD K7/K8 CPUs only save/restore the FOP/FIP/FDP x87 registers in FXSAVE when an exception is pending. This means the value leak through context switches and allow processes to observe some x87 instruction state of other processes. This was actually documented by AMD, but nobody recognized it as being different from Intel before. The fix first adds an optimization: instead of unconditionally calling FNCLEX after each FXSAVE test if ES is pending and skip it when not needed. Then do a x87 load from a kernel variable to clear FOP/FIP/FDP. This means other processes always will only see a constant value defined by the kernel in their FP state. I took some pain to make sure to chose a variable that's already in L1 during context switch to make the overhead of this low. Also alternative() is used to patch away the new code on CPUs who don't need it. Patch for both i386/x86-64. The problem was discovered originally by Jan Beulich. Richard Brunner provided the basic code for the workarounds, with contribution from Jan. This is CVE-2006-1056 Cc: richard.brunner@amd.com Cc: jbeulich@novell.com Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- include/asm-i386/cpufeature.h | 1 + include/asm-i386/i387.h | 30 ++++++++++++++++++++++++++---- include/asm-x86_64/cpufeature.h | 1 + include/asm-x86_64/i387.h | 20 +++++++++++++++++++- 4 files changed, 47 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index 5c0b5876b93..b44bfc6239c 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -71,6 +71,7 @@ #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ #define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ +#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index 152d0baa576..7b1f01191e7 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -38,17 +39,38 @@ extern void init_fpu(struct task_struct *); extern void kernel_fpu_begin(void); #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) +/* We need a safe address that is cheap to find and that is already + in L1 during context switch. The best choices are unfortunately + different for UP and SMP */ +#ifdef CONFIG_SMP +#define safe_address (__per_cpu_offset[0]) +#else +#define safe_address (kstat_cpu(0).cpustat.user) +#endif + /* * These must be called with preempt disabled */ static inline void __save_init_fpu( struct task_struct *tsk ) { + /* Use more nops than strictly needed in case the compiler + varies code */ alternative_input( - "fnsave %1 ; fwait ;" GENERIC_NOP2, - "fxsave %1 ; fnclex", + "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, + "fxsave %[fx]\n" + "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", X86_FEATURE_FXSR, - "m" (tsk->thread.i387.fxsave) - :"memory"); + [fx] "m" (tsk->thread.i387.fxsave), + [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. __per_cpu_offset[0] is a random variable that should be in L1 */ + alternative_input( + GENERIC_NOP8 GENERIC_NOP2, + "emms\n\t" /* clear stack tags */ + "fildl %[addr]", /* set F?P to defined value */ + X86_FEATURE_FXSAVE_LEAK, + [addr] "m" (safe_address)); task_thread_info(tsk)->status &= ~TS_USEDFPU; } diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index 76bb6193ae9..662964b74e3 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h @@ -64,6 +64,7 @@ #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ +#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h index 876eb9a2fe7..cba8a3b0cde 100644 --- a/include/asm-x86_64/i387.h +++ b/include/asm-x86_64/i387.h @@ -72,6 +72,23 @@ extern int set_fpregs(struct task_struct *tsk, #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) +#define X87_FSW_ES (1 << 7) /* Exception Summary */ + +/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. The kernel data segment can be sometimes 0 and sometimes + new user value. Both should be ok. + Use the PDA as safe address because it should be already in L1. */ +static inline void clear_fpu_state(struct i387_fxsave_struct *fx) +{ + if (unlikely(fx->swd & X87_FSW_ES)) + asm volatile("fnclex"); + alternative_input(ASM_NOP8 ASM_NOP2, + " emms\n" /* clear stack tags */ + " fildl %%gs:0", /* load to clear state */ + X86_FEATURE_FXSAVE_LEAK); +} + static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) { int err; @@ -119,6 +136,7 @@ static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) #endif if (unlikely(err)) __clear_user(fx, sizeof(struct i387_fxsave_struct)); + /* No need to clear here because the caller clears USED_MATH */ return err; } @@ -149,7 +167,7 @@ static inline void __fxsave_clear(struct task_struct *tsk) "i" (offsetof(__typeof__(*tsk), thread.i387.fxsave))); #endif - __asm__ __volatile__("fnclex"); + clear_fpu_state(&tsk->thread.i387.fxsave); } static inline void kernel_fpu_begin(void) -- cgit v1.2.3 From 0b699e36b2d43c1b4288992683e5913d347b5b78 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 20 Apr 2006 02:36:48 +0200 Subject: [PATCH] x86_64: bring back __read_mostly support to linux-2.6.17-rc2 It seems latest kernel has a wrong/missing __read_mostly implementation for x86_64 __read_mostly macro should be declared outside of #if CONFIG_X86_VSMP block Signed-off-by: Eric Dumazet Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- include/asm-x86_64/cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h index c8043a16152..f8dff1c6753 100644 --- a/include/asm-x86_64/cache.h +++ b/include/asm-x86_64/cache.h @@ -20,8 +20,8 @@ __attribute__((__section__(".data.page_aligned"))) #endif -#define __read_mostly __attribute__((__section__(".data.read_mostly"))) - #endif +#define __read_mostly __attribute__((__section__(".data.read_mostly"))) + #endif -- cgit v1.2.3 From 308a878210cde6ab19df9f392c24db53ad6f56bf Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Tue, 18 Apr 2006 11:26:34 -0500 Subject: [IA64] Remove unused variable in sn_sal.h cnodeid was being set but not used. The dead code was left over from a previous version that grabbed a per node lock. Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- include/asm-ia64/sn/sn_sal.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index bf4cc867a69..7ddce80e191 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -8,7 +8,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2005 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. All rights reserved. */ @@ -705,10 +705,8 @@ static inline int sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array) { struct ia64_sal_retval ret_stuff; - int cnodeid; unsigned long irq_flags; - cnodeid = nasid_to_cnodeid(get_node_number(paddr)); local_irq_save(irq_flags); ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len, (u64)nasid_array, perms, 0, 0, 0); -- cgit v1.2.3 From 0d9adec525b87d8ab7e64efeabffb5b3f293056e Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 18 Apr 2006 15:00:45 -0500 Subject: [IA64] - Fix MAX_PXM_DOMAINS for systems with > 256 nodes Correctly size the PXM-related arrays for systems that have more than 256 nodes. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- include/asm-ia64/acpi.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h index d734585a23c..09a5dd0e44a 100644 --- a/include/asm-ia64/acpi.h +++ b/include/asm-ia64/acpi.h @@ -110,9 +110,8 @@ extern void prefill_possible_map(void); extern int additional_cpus; #ifdef CONFIG_ACPI_NUMA -/* Proximity bitmap length; _PXM is at most 255 (8 bit)*/ -#ifdef CONFIG_IA64_NR_NODES -#define MAX_PXM_DOMAINS CONFIG_IA64_NR_NODES +#if MAX_NUMNODES > 256 +#define MAX_PXM_DOMAINS MAX_NUMNODES #else #define MAX_PXM_DOMAINS (256) #endif -- cgit v1.2.3 From 86db2f4239e2556cd37b853c2307aa9d43041458 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Thu, 20 Apr 2006 17:05:43 -0700 Subject: [IA64-SGI] SN SAL call to inject memory errors The SGI Altix SAL provides an interface for modifying the ECC on memory to create memory errors. The SAL call can be used to inject memory errors for testing MCA recovery code. Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- include/asm-ia64/sn/sn_sal.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index 7ddce80e191..51aca022cf3 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -85,6 +85,7 @@ #define SN_SAL_GET_PROM_FEATURE_SET 0x02000065 #define SN_SAL_SET_OS_FEATURE_SET 0x02000066 +#define SN_SAL_INJECT_ERROR 0x02000067 /* * Service-specific constants @@ -1138,4 +1139,16 @@ ia64_sn_set_os_feature(int feature) return rv.status; } +static inline int +sn_inject_error(u64 paddr, u64 *data, u64 *ecc) +{ + struct ia64_sal_retval ret_stuff; + unsigned long irq_flags; + + local_irq_save(irq_flags); + ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_INJECT_ERROR, paddr, (u64)data, + (u64)ecc, 0, 0, 0, 0); + local_irq_restore(irq_flags); + return ret_stuff.status; +} #endif /* _ASM_IA64_SN_SN_SAL_H */ -- cgit v1.2.3 From a72391e42f0a13116995045b3d492d660f96697d Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Thu, 20 Apr 2006 18:49:48 +0900 Subject: [IA64] eliminate compile time warnings This patch removes following compile time warnings: drivers/pci/pci-sysfs.c: In function `pci_read_legacy_io': drivers/pci/pci-sysfs.c:257: warning: implicit declaration of function `ia64_pci_legacy_read' drivers/pci/pci-sysfs.c: In function `pci_write_legacy_io': drivers/pci/pci-sysfs.c:280: warning: implicit declaration of function `ia64_pci_legacy_write' It also fixes wrong definition of ia64_pci_legacy_write (type of `bus' is not `pci_dev', but `pci_bus'). Signed-Off-By: Satoru Takeuchi Signed-off-by: Tony Luck --- include/asm-ia64/machvec.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index c3e4ed8a3e1..a9c995a86c2 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -347,9 +347,11 @@ extern ia64_mv_dma_supported swiotlb_dma_supported; #endif #ifndef platform_pci_legacy_read # define platform_pci_legacy_read ia64_pci_legacy_read +extern int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size); #endif #ifndef platform_pci_legacy_write # define platform_pci_legacy_write ia64_pci_legacy_write +extern int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size); #endif #ifndef platform_inb # define platform_inb __ia64_inb -- cgit v1.2.3 From 7daa411b810d7eadfaabe3765ec5f827893dbb30 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 12 Apr 2006 21:05:59 -0500 Subject: [PATCH] powerpc: IOMMU support for honoring dma_mask Some devices don't support full 32-bit DMA address space, which we currently assume. Add the required mask-passing to the IOMMU allocators. Signed-off-by: Olof Johansson Signed-off-by: Paul Mackerras --- include/asm-powerpc/iommu.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index d5677cbec20..18ca29e9105 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h @@ -70,17 +70,18 @@ extern void iommu_free_table(struct device_node *dn); extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, - struct scatterlist *sglist, int nelems, + struct scatterlist *sglist, int nelems, unsigned long mask, enum dma_data_direction direction); extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, int nelems, enum dma_data_direction direction); extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, - dma_addr_t *dma_handle, gfp_t flag); + dma_addr_t *dma_handle, unsigned long mask, gfp_t flag); extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle); extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, - size_t size, enum dma_data_direction direction); + size_t size, unsigned long mask, + enum dma_data_direction direction); extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction); -- cgit v1.2.3 From e5ecc192dfc5e0b325dd8c99ce4c755714c9acbf Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 13 Apr 2006 18:23:53 -0700 Subject: [IA64] Setup an IA64 specific reclaim distance RECLAIM_DISTANCE is checked on bootup against the SLIT table distances. Zone reclaim is important for system that have higher latencies but not for systems that have multiple nodes on one motherboard and therefore low latencies. We found that on motherboard latencies are typically 1 to 1.4 of local memory access speed whereas multinode systems which benefit from zone reclaim have usually more than 1.5 times the latency of a local access. Set the reclaim distance for IA64 to 1.5 times. Signed-off-by: Christoph Lameter Signed-off-by: Tony Luck --- include/asm-ia64/topology.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index 3ee19dfa46d..616b5ed2aa7 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h @@ -22,6 +22,11 @@ /* Nodes w/o CPUs are preferred for memory allocations, see build_zonelists */ #define PENALTY_FOR_NODE_WITH_CPUS 255 +/* + * Distance above which we begin to use zone reclaim + */ +#define RECLAIM_DISTANCE 15 + /* * Returns the number of the node containing CPU 'cpu' */ -- cgit v1.2.3 From 2fd83038160531245099c3c5b3511fa4b80765eb Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 20 Apr 2006 20:40:23 +0000 Subject: [PARISC] Further work for multiple page sizes More work towards supporing multiple page sizes on 64-bit. Convert some assumptions that 64bit uses 3 level page tables into testing PT_NLEVELS. Also some BUG() to BUG_ON() conversions and some cleanups to assembler. Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- include/asm-parisc/page.h | 25 +++++++++++++++--- include/asm-parisc/pgtable.h | 63 +++++++++++++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 45e02aa5bf4..c0dd461fb8f 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h @@ -1,13 +1,30 @@ #ifndef _PARISC_PAGE_H #define _PARISC_PAGE_H -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#if !defined(__KERNEL__) +/* this is for userspace applications (4k page size) */ +# define PAGE_SHIFT 12 /* 4k */ +# define PAGE_SIZE (1UL << PAGE_SHIFT) +# define PAGE_MASK (~(PAGE_SIZE-1)) +#endif + #ifdef __KERNEL__ #include + +#if defined(CONFIG_PARISC_PAGE_SIZE_4KB) +# define PAGE_SHIFT 12 /* 4k */ +#elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) +# define PAGE_SHIFT 14 /* 16k */ +#elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) +# define PAGE_SHIFT 16 /* 64k */ +#else +# error "unknown default kernel page size" +#endif +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + + #ifndef __ASSEMBLY__ #include diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 4e34c6b4405..aec089eb8b8 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -59,16 +59,15 @@ #define ISTACK_SIZE 32768 /* Interrupt Stack Size */ #define ISTACK_ORDER 3 -/* This is the size of the initially mapped kernel memory (i.e. currently - * 0 to 1<<23 == 8MB */ +/* This is the size of the initially mapped kernel memory */ #ifdef CONFIG_64BIT -#define KERNEL_INITIAL_ORDER 24 +#define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ #else -#define KERNEL_INITIAL_ORDER 23 +#define KERNEL_INITIAL_ORDER 23 /* 0 to 1<<23 = 8MB */ #endif #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) -#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) #define PT_NLEVELS 3 #define PGD_ORDER 1 /* Number of pages per pgd */ #define PMD_ORDER 1 /* Number of pages per pmd */ @@ -111,11 +110,15 @@ #define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD) #define MAX_ADDRESS (1UL << MAX_ADDRBITS) -#define SPACEID_SHIFT (MAX_ADDRBITS - 32) +#define SPACEID_SHIFT (MAX_ADDRBITS - 32) /* This calculates the number of initial pages we need for the initial * page tables */ -#define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) +#if (KERNEL_INITIAL_ORDER) >= (PMD_SHIFT) +# define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) +#else +# define PT_INITIAL (1) /* all initial PTEs fit into one page */ +#endif /* * pgd entries used up by user/kernel: @@ -160,6 +163,10 @@ extern void *vmalloc_start; * to zero */ #define PTE_SHIFT xlate_pabit(_PAGE_USER_BIT) +/* PFN_PTE_SHIFT defines the shift of a PTE value to access the PFN field */ +#define PFN_PTE_SHIFT 12 + + /* this is how many bits may be used by the file functions */ #define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT) @@ -188,7 +195,8 @@ extern void *vmalloc_start; /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds * are page-aligned, we don't care about the PAGE_OFFSET bits, except * for a few meta-information bits, so we shift the address to be - * able to effectively address 40-bits of physical address space. */ + * able to effectively address 40/42/44-bits of physical address space + * depending on 4k/16k/64k PAGE_SIZE */ #define _PxD_PRESENT_BIT 31 #define _PxD_ATTACHED_BIT 30 #define _PxD_VALID_BIT 29 @@ -198,7 +206,7 @@ extern void *vmalloc_start; #define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT)) #define PxD_FLAG_MASK (0xf) #define PxD_FLAG_SHIFT (4) -#define PxD_VALUE_SHIFT (8) +#define PxD_VALUE_SHIFT (8) /* (PAGE_SHIFT-PxD_FLAG_SHIFT) */ #ifndef __ASSEMBLY__ @@ -246,6 +254,7 @@ extern void *vmalloc_start; #define __S110 PAGE_RWX #define __S111 PAGE_RWX + extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ /* initial page tables for 0-8MB for kernel */ @@ -272,7 +281,7 @@ extern unsigned long *empty_zero_page; #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) -#ifdef CONFIG_64BIT +#if PT_NLEVELS == 3 /* The first entry of the permanent pmd is not there if it contains * the gateway marker */ #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) @@ -282,7 +291,7 @@ extern unsigned long *empty_zero_page; #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) static inline void pmd_clear(pmd_t *pmd) { -#ifdef CONFIG_64BIT +#if PT_NLEVELS == 3 if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) /* This is the entry pointing to the permanent pmd * attached to the pgd; cannot clear it */ @@ -303,7 +312,7 @@ static inline void pmd_clear(pmd_t *pmd) { #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) static inline void pgd_clear(pgd_t *pgd) { -#ifdef CONFIG_64BIT +#if PT_NLEVELS == 3 if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) /* This is the permanent pmd attached to the pgd; cannot * free it */ @@ -351,7 +360,7 @@ extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return ({ \ pte_t __pte; \ \ - pte_val(__pte) = ((addr)+pgprot_val(pgprot)); \ + pte_val(__pte) = ((((addr)>>PAGE_SHIFT)<> PAGE_SHIFT) +#define pte_pfn(x) (pte_val(x) >> PFN_PTE_SHIFT) #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) @@ -499,6 +504,26 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #endif /* !__ASSEMBLY__ */ + +/* TLB page size encoding - see table 3-1 in parisc20.pdf */ +#define _PAGE_SIZE_ENCODING_4K 0 +#define _PAGE_SIZE_ENCODING_16K 1 +#define _PAGE_SIZE_ENCODING_64K 2 +#define _PAGE_SIZE_ENCODING_256K 3 +#define _PAGE_SIZE_ENCODING_1M 4 +#define _PAGE_SIZE_ENCODING_4M 5 +#define _PAGE_SIZE_ENCODING_16M 6 +#define _PAGE_SIZE_ENCODING_64M 7 + +#if defined(CONFIG_PARISC_PAGE_SIZE_4KB) +# define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K +#elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) +# define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_16K +#elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) +# define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_64K +#endif + + #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -- cgit v1.2.3 From 6ca773cf8b9dc19989c9b44635292b1ba80f9112 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 20 Apr 2006 04:44:07 +0000 Subject: [PARISC] Add new entries to the syscall table Most are easy, but sync_file_range needed special handling when entering through the 32-bit syscall table. Signed-off-by: Kyle McMartin --- include/asm-parisc/unistd.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index c56fccbf34a..0e1a30be2e3 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -780,8 +780,14 @@ #define __NR_readlinkat (__NR_Linux + 285) #define __NR_fchmodat (__NR_Linux + 286) #define __NR_faccessat (__NR_Linux + 287) +#define __NR_unshare (__NR_Linux + 288) +#define __NR_set_robust_list (__NR_Linux + 289) +#define __NR_get_robust_list (__NR_Linux + 290) +#define __NR_splice (__NR_Linux + 291) +#define __NR_sync_file_range (__NR_Linux + 292) +#define __NR_tee (__NR_Linux + 293) -#define __NR_Linux_syscalls 288 +#define __NR_Linux_syscalls 294 #define HPUX_GATEWAY_ADDR 0xC0000004 #define LINUX_GATEWAY_ADDR 0x100 -- cgit v1.2.3 From 1b52d7c2210b9a64c5cba6aded478c8217a8853c Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 20 Apr 2006 21:16:32 +0000 Subject: [PARISC] Make ioremap default to _nocache Since it is way more work to change most drivers to comply with parisc, take the easy way out and make ioremap _NO_CACHE by default. This is in line with what powerpc does. Signed-off-by: Kyle McMartin --- include/asm-parisc/io.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h index 29da31194b9..244f6b8883f 100644 --- a/include/asm-parisc/io.h +++ b/include/asm-parisc/io.h @@ -126,24 +126,17 @@ static inline void gsc_writeq(unsigned long long val, unsigned long addr) extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); -extern inline void __iomem * ioremap(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, 0); -} - -/* - * This one maps high address device memory and turns off caching for that area. - * it's useful if some control registers are in such an area and write combining - * or read caching is not desirable: +/* Most machines react poorly to I/O-space being cacheable... Instead let's + * define ioremap() in terms of ioremap_nocache(). */ -extern inline void * ioremap_nocache(unsigned long offset, unsigned long size) +extern inline void __iomem * ioremap(unsigned long offset, unsigned long size) { - return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */); + return __ioremap(offset, size, _PAGE_NO_CACHE); } +#define ioremap_nocache(off, sz) ioremap((off), (sz)) extern void iounmap(void __iomem *addr); - static inline unsigned char __raw_readb(const volatile void __iomem *addr) { return (*(volatile unsigned char __force *) (addr)); -- cgit v1.2.3 From d0e15bed84db7a9b0ea85d2ad9707b5e6d2e38da Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 23 Apr 2006 10:42:04 +1000 Subject: powerpc: Fix define_machine so machine_is() works from modules machine_is() was always returning 0 when used in a module, because we weren't exporting the machine definitions. This was why sound wasn't working on powermacs when CONFIG_SND_POWERMAC=m. Original fix from Ben Herrenschmidt, further fixed by me. Signed-off-by: Paul Mackerras --- include/asm-powerpc/machdep.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 5ed84768075..0f9254c1891 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -253,7 +253,11 @@ extern struct machdep_calls *machine_id; #define __machine_desc __attribute__ ((__section__ (".machine.desc"))) -#define define_machine(name) struct machdep_calls mach_##name __machine_desc = +#define define_machine(name) \ + extern struct machdep_calls mach_##name; \ + EXPORT_SYMBOL(mach_##name); \ + struct machdep_calls mach_##name __machine_desc = + #define machine_is(name) \ ({ \ extern struct machdep_calls mach_##name \ -- cgit v1.2.3 From 818667f7c40dd0bd14029b5ac1d0f5282e12310e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 20 Apr 2006 20:02:03 +0200 Subject: [PATCH] softmac: fix SIOCSIWAP There are some bugs in the current implementation of the SIOCSIWAP wext, for example that when you do it twice and it fails, it may still try another access point for some reason. This patch fixes this by introducing a new flag that tells the association code that the bssid that is in use was fixed by the user and shouldn't be deviated from. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/ieee80211softmac.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h index 6b3693f05ca..b1ebfbae397 100644 --- a/include/net/ieee80211softmac.h +++ b/include/net/ieee80211softmac.h @@ -96,10 +96,13 @@ struct ieee80211softmac_assoc_info { * * bssvalid is true if we found a matching network * and saved it's BSSID into the bssid above. + * + * bssfixed is used for SIOCSIWAP. */ u8 static_essid:1, associating:1, - bssvalid:1; + bssvalid:1, + bssfixed:1; /* Scan retries remaining */ int scan_retry; -- cgit v1.2.3 From d8fe3f19203b1f5070358aaa292d33295258b448 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Mon, 24 Apr 2006 13:48:51 -0700 Subject: [SPARC]: __NR_sys removal __NR_sys_sync_file_range part was lost somewhere... [glibc is already checking __NR_sync_file_range] Signed-off-by: OGAWA Hirofumi Signed-off-by: David S. Miller --- include/asm-sparc/unistd.h | 2 +- include/asm-sparc64/unistd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 45feff893b8..32a48f623e2 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -271,7 +271,7 @@ #define __NR_getsid 252 #define __NR_fdatasync 253 #define __NR_nfsservctl 254 -#define __NR_sys_sync_file_range 255 +#define __NR_sync_file_range 255 #define __NR_clock_settime 256 #define __NR_clock_gettime 257 #define __NR_clock_getres 258 diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 597f6923a46..ca80e8aca12 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -273,7 +273,7 @@ #define __NR_getsid 252 #define __NR_fdatasync 253 #define __NR_nfsservctl 254 -#define __NR_sys_sync_file_range 255 +#define __NR_sync_file_range 255 #define __NR_clock_settime 256 #define __NR_clock_gettime 257 #define __NR_clock_getres 258 -- cgit v1.2.3 From 55fe5866366ae42f259f27ae5962eb267d9ce172 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Apr 2006 17:16:28 -0700 Subject: [NETFILTER]: Fix compat_xt_counters alignment for non-x86 Some (?) non-x86 architectures require 8byte alignment for u_int64_t even when compiled for 32bit, using u_int32_t in compat_xt_counters breaks on these architectures, use u_int64_t for everything but x86. Reported by Andreas Schwab . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/x_tables.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index f6bdef82a32..38701454e19 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -361,7 +361,11 @@ struct compat_xt_entry_target struct compat_xt_counters { +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) u_int32_t cnt[4]; +#else + u_int64_t cnt[2]; +#endif }; struct compat_xt_counters_info -- cgit v1.2.3 From d5b415c95f0e6510451f1446cea832c1f77bd7ea Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 26 Apr 2006 00:13:18 -0400 Subject: Input: ads7846 - improve filtering for thumb press accuracy Providing more accurate coordinates for thumb press requires additional steps in the filtering logic: - Ignore samples found invalid by the debouncing logic, or the ones that have out of bound pressure value. - Add a parameter to repeat debouncing, so that more then two consecutive good readings are required for a valid sample. Signed-off-by: Imre Deak Acked-by: Juha Yrjola Signed-off-by: Dmitry Torokhov --- include/linux/spi/ads7846.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index d8823e237e0..adb3dafd33e 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -15,9 +15,11 @@ struct ads7846_platform_data { u16 y_min, y_max; u16 pressure_min, pressure_max; - u16 debounce_max; /* max number of readings per sample */ + u16 debounce_max; /* max number of additional readings + * per sample */ u16 debounce_tol; /* tolerance used for filtering */ - + u16 debounce_rep; /* additional consecutive good readings + * required after the first two */ int (*get_pendown_state)(void); }; -- cgit v1.2.3 From 1a0ccece05efb8a9c04b1130c24a2652239f3bea Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 26 Apr 2006 00:13:57 -0400 Subject: Input: allow passing NULL to input_free_device() Many drivers rely on input_free_device() behaving like kfree(). Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/input.h b/include/linux/input.h index b0e612dda0c..16c19d710a4 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1016,7 +1016,8 @@ static inline void input_put_device(struct input_dev *dev) static inline void input_free_device(struct input_dev *dev) { - input_put_device(dev); + if (dev) + input_put_device(dev); } int input_register_device(struct input_dev *); -- cgit v1.2.3 From ddc5d3414593e4d7ad7fbd33e7f7517fcc234544 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 26 Apr 2006 00:14:19 -0400 Subject: Input: move input_device_id to mod_devicetable.h Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 104 ++++++++++++++++++++-------------------- include/linux/mod_devicetable.h | 48 +++++++++++++++++++ 2 files changed, 101 insertions(+), 51 deletions(-) (limited to 'include') diff --git a/include/linux/input.h b/include/linux/input.h index 16c19d710a4..8298b4bf5a0 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -12,8 +12,6 @@ #ifdef __KERNEL__ #include #include -#include -#include #else #include #include @@ -577,15 +575,15 @@ struct input_absinfo { * Switch events */ -#define SW_0 0x00 -#define SW_1 0x01 -#define SW_2 0x02 -#define SW_3 0x03 -#define SW_4 0x04 -#define SW_5 0x05 -#define SW_6 0x06 -#define SW_7 0x07 -#define SW_MAX 0x0f +#define SW_0 0x00 +#define SW_1 0x01 +#define SW_2 0x02 +#define SW_3 0x03 +#define SW_4 0x04 +#define SW_5 0x05 +#define SW_6 0x06 +#define SW_7 0x07 +#define SW_MAX 0x0f /* * Misc events @@ -805,52 +803,16 @@ struct ff_effect { #define FF_MAX 0x7f -struct input_device_id { - - kernel_ulong_t flags; - - struct input_id id; - - kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1]; - kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1]; - kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1]; - kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1]; - kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1]; - kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1]; - kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1]; - kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1]; - kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1]; - - kernel_ulong_t driver_info; -}; - -/* - * Structure for hotplug & device<->driver matching. - */ - -#define INPUT_DEVICE_ID_MATCH_BUS 1 -#define INPUT_DEVICE_ID_MATCH_VENDOR 2 -#define INPUT_DEVICE_ID_MATCH_PRODUCT 4 -#define INPUT_DEVICE_ID_MATCH_VERSION 8 - -#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010 -#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020 -#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040 -#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080 -#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100 -#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200 -#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400 -#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800 -#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 - #ifdef __KERNEL__ /* * In-kernel definitions. */ +#include #include #include +#include #define NBITS(x) (((x)/BITS_PER_LONG)+1) #define BIT(x) (1UL<<((x)%BITS_PER_LONG)) @@ -951,9 +913,49 @@ struct input_dev { }; #define to_input_dev(d) container_of(d, struct input_dev, cdev) -#define INPUT_DEVICE_ID_MATCH_DEVICE\ +/* + * Verify that we are in sync with input_device_id mod_devicetable.h #defines + */ + +#if EV_MAX != INPUT_DEVICE_ID_EV_MAX +#error "EV_MAX and INPUT_DEVICE_ID_EV_MAX do not match" +#endif + +#if KEY_MAX != INPUT_DEVICE_ID_KEY_MAX +#error "KEY_MAX and INPUT_DEVICE_ID_KEY_MAX do not match" +#endif + +#if REL_MAX != INPUT_DEVICE_ID_REL_MAX +#error "REL_MAX and INPUT_DEVICE_ID_REL_MAX do not match" +#endif + +#if ABS_MAX != INPUT_DEVICE_ID_ABS_MAX +#error "ABS_MAX and INPUT_DEVICE_ID_ABS_MAX do not match" +#endif + +#if MSC_MAX != INPUT_DEVICE_ID_MSC_MAX +#error "MSC_MAX and INPUT_DEVICE_ID_MSC_MAX do not match" +#endif + +#if LED_MAX != INPUT_DEVICE_ID_LED_MAX +#error "LED_MAX and INPUT_DEVICE_ID_LED_MAX do not match" +#endif + +#if SND_MAX != INPUT_DEVICE_ID_SND_MAX +#error "SND_MAX and INPUT_DEVICE_ID_SND_MAX do not match" +#endif + +#if FF_MAX != INPUT_DEVICE_ID_FF_MAX +#error "FF_MAX and INPUT_DEVICE_ID_FF_MAX do not match" +#endif + +#if SW_MAX != INPUT_DEVICE_ID_SW_MAX +#error "SW_MAX and INPUT_DEVICE_ID_SW_MAX do not match" +#endif + +#define INPUT_DEVICE_ID_MATCH_DEVICE \ (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) -#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\ +#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION \ (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) struct input_handle; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 7b08c11ec4c..f6977708585 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -249,4 +249,52 @@ struct i2c_device_id { __u16 id; }; +/* Input */ +#define INPUT_DEVICE_ID_EV_MAX 0x1f +#define INPUT_DEVICE_ID_KEY_MAX 0x1ff +#define INPUT_DEVICE_ID_REL_MAX 0x0f +#define INPUT_DEVICE_ID_ABS_MAX 0x3f +#define INPUT_DEVICE_ID_MSC_MAX 0x07 +#define INPUT_DEVICE_ID_LED_MAX 0x0f +#define INPUT_DEVICE_ID_SND_MAX 0x07 +#define INPUT_DEVICE_ID_FF_MAX 0x7f +#define INPUT_DEVICE_ID_SW_MAX 0x0f + +#define INPUT_DEVICE_ID_MATCH_BUS 1 +#define INPUT_DEVICE_ID_MATCH_VENDOR 2 +#define INPUT_DEVICE_ID_MATCH_PRODUCT 4 +#define INPUT_DEVICE_ID_MATCH_VERSION 8 + +#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010 +#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020 +#define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040 +#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080 +#define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100 +#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200 +#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 +#define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 +#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 + +struct input_device_id { + + kernel_ulong_t flags; + + __u16 bustype; + __u16 vendor; + __u16 product; + __u16 version; + + kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; + + kernel_ulong_t driver_info; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ -- cgit v1.2.3 From 912d35f86781e64d73be1ef358f703c08905ac37 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 26 Apr 2006 10:59:21 +0200 Subject: [PATCH] Add support for the sys_vmsplice syscall sys_splice() moves data to/from pipes with a file input/output. sys_vmsplice() moves data to a pipe, with the input being a user address range instead. This uses an approach suggested by Linus, where we can hold partial ranges inside the pages[] map. Hopefully this will be useful for network receive support as well. Signed-off-by: Jens Axboe --- include/asm-i386/unistd.h | 3 ++- include/asm-ia64/unistd.h | 3 ++- include/asm-powerpc/unistd.h | 3 ++- include/asm-x86_64/unistd.h | 4 +++- include/linux/syscalls.h | 3 +++ 5 files changed, 12 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index d81d6cfc1bb..eb4b152c82f 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -321,8 +321,9 @@ #define __NR_splice 313 #define __NR_sync_file_range 314 #define __NR_tee 315 +#define __NR_vmsplice 316 -#define NR_syscalls 316 +#define NR_syscalls 317 /* * user-visible error numbers are in the range -1 - -128: see diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index a40ebec6aee..7107763168b 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h @@ -290,12 +290,13 @@ #define __NR_get_robust_list 1299 #define __NR_sync_file_range 1300 #define __NR_tee 1301 +#define __NR_vmsplice 1302 #ifdef __KERNEL__ #include -#define NR_syscalls 278 /* length of syscall table */ +#define NR_syscalls 279 /* length of syscall table */ #define __ARCH_WANT_SYS_RT_SIGACTION diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index c612f1a6277..34325e29259 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h @@ -303,8 +303,9 @@ #define __NR_unshare 282 #define __NR_splice 283 #define __NR_tee 284 +#define __NR_vmsplice 285 -#define __NR_syscalls 285 +#define __NR_syscalls 286 #ifdef __KERNEL__ #define __NR__exit __NR_exit diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 98c36eae567..feb77cb8c04 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -615,8 +615,10 @@ __SYSCALL(__NR_splice, sys_splice) __SYSCALL(__NR_tee, sys_tee) #define __NR_sync_file_range 277 __SYSCALL(__NR_sync_file_range, sys_sync_file_range) +#define __NR_vmsplice 278 +__SYSCALL(__NR_vmsplice, sys_vmsplice) -#define __NR_syscall_max __NR_sync_file_range +#define __NR_syscall_max __NR_vmsplice #ifndef __NO_STUBS diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index d3ebc0e68b2..3996960fc56 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -574,6 +574,9 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, int fd_out, loff_t __user *off_out, size_t len, unsigned int flags); +asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, + unsigned long nr_segs, unsigned int flags); + asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, -- cgit v1.2.3 From 734cbc363b159caee158d5a83408c72d98bcacf0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 25 Apr 2006 10:58:50 -0700 Subject: [PATCH] sky2: reschedule if irq still pending This is a workaround for the case edge-triggered irq's. Several users seem to have broken configurations sharing edge-triggered irq's. To avoid losing IRQ's, reshedule if more work arrives. The changes to netdevice.h are to extract the part that puts device back in list into separate inline. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- include/linux/netdevice.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 40ccf8cc423..01db7b88a2b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -829,19 +829,21 @@ static inline void netif_rx_schedule(struct net_device *dev) __netif_rx_schedule(dev); } -/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). - * Do not inline this? - */ + +static inline void __netif_rx_reschedule(struct net_device *dev, int undo) +{ + dev->quota += undo; + list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); + __raise_softirq_irqoff(NET_RX_SOFTIRQ); +} + +/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */ static inline int netif_rx_reschedule(struct net_device *dev, int undo) { if (netif_rx_schedule_prep(dev)) { unsigned long flags; - - dev->quota += undo; - local_irq_save(flags); - list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); - __raise_softirq_irqoff(NET_RX_SOFTIRQ); + __netif_rx_reschedule(dev, undo); local_irq_restore(flags); return 1; } -- cgit v1.2.3 From 00522fb41a2a9bf0f98a007c0e2b516a3873148c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 26 Apr 2006 14:39:29 +0200 Subject: [PATCH] splice: rearrange moving to/from pipe helpers We need these for people writing their own ->splice_read/write hooks. Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ef7f33c0be1..0008d4bd405 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -61,4 +61,21 @@ void __free_pipe_info(struct pipe_inode_info *); /* from/to, of course */ #define SPLICE_F_MORE (0x04) /* expect more data */ +/* + * Passed to the actors + */ +struct splice_desc { + unsigned int len, total_len; /* current and remaining length */ + unsigned int flags; /* splice flags */ + struct file *file; /* file to read/write */ + loff_t pos; /* file position */ +}; + +typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, + struct splice_desc *); + +extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, + loff_t *, size_t, unsigned int, + splice_actor *); + #endif -- cgit v1.2.3 From ebf43500ef148a380bd132743c3fc530111ac620 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 27 Apr 2006 08:46:01 +0200 Subject: [PATCH] Add find_get_pages_contig(): contiguous variant of find_get_pages() find_get_pages_contig() will break out if we hit a hole in the page cache. From Andrew Morton, small modifications and documentation by me. Signed-off-by: Jens Axboe --- include/linux/pagemap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 9539efd4f7e..7a1af574ded 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -78,6 +78,8 @@ extern struct page * find_or_create_page(struct address_space *mapping, unsigned long index, gfp_t gfp_mask); unsigned find_get_pages(struct address_space *mapping, pgoff_t start, unsigned int nr_pages, struct page **pages); +unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, + unsigned int nr_pages, struct page **pages); unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, int tag, unsigned int nr_pages, struct page **pages); -- cgit v1.2.3 From bc818247203a7bfc40296a3f5b760de84fb8e0d1 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 17 Apr 2006 21:19:12 +0900 Subject: [MIPS] Fix bitops for MIPS32/MIPS64 CPUs. With recent rewrite for generic bitops, fls() for 32bit kernel with MIPS64_CPU is broken. Also, ffs(), fls() should be defined the same way as the libc and compiler built-in routines (returns int instead of unsigned long). Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/bitops.h | 56 ++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index a1728f8c070..d2f444537e4 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -467,64 +467,56 @@ static inline unsigned long __ffs(unsigned long word) } /* - * ffs - find first bit set. + * fls - find last bit set. * @word: The word to search * - * Returns 1..SZLONG - * Returns 0 if no bit exists + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ - -static inline unsigned long ffs(unsigned long word) +static inline int fls(int word) { - if (!word) - return 0; + __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); - return __ffs(word) + 1; + return 32 - word; } -/* - * ffz - find first zero in word. - * @word: The word to search - * - * Undefined if no zero exists, so code should check against ~0UL first. - */ -static inline unsigned long ffz(unsigned long word) +#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPS64) +static inline int fls64(__u64 word) { - return __ffs (~word); + __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); + + return 64 - word; } +#else +#include +#endif /* - * fls - find last bit set. + * ffs - find first bit set. * @word: The word to search * - * Returns 1..SZLONG - * Returns 0 if no bit exists + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). */ -static inline unsigned long fls(unsigned long word) +static inline int ffs(int word) { -#ifdef CONFIG_CPU_MIPS32 - __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); - - return 32 - word; -#endif - -#ifdef CONFIG_CPU_MIPS64 - __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); + if (!word) + return 0; - return 64 - word; -#endif + return fls(word & -word); } #else #include #include -#include #include +#include #endif /*defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) */ -#include +#include #include #ifdef __KERNEL__ -- cgit v1.2.3 From 7a8341969fe0df4a1fffa141435e742456270ffd Mon Sep 17 00:00:00 2001 From: Chris Dearman Date: Sat, 15 Apr 2006 00:31:16 +0100 Subject: [MIPS] 24K LV: Add core card id. Signed-off-by: Ralf Baechle --- include/asm-mips/mips-boards/generic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h index 25b6ffc2662..fa8b913cc3e 100644 --- a/include/asm-mips/mips-boards/generic.h +++ b/include/asm-mips/mips-boards/generic.h @@ -67,6 +67,7 @@ #define MIPS_REVISION_CORID_CORE_FPGA2 7 #define MIPS_REVISION_CORID_CORE_FPGAR2 8 #define MIPS_REVISION_CORID_CORE_FPGA3 9 +#define MIPS_REVISION_CORID_CORE_24K 10 /**** Artificial corid defines ****/ /* -- cgit v1.2.3 From 6e5882cfa24e1456702e463f6920fc0ca3c3d2b8 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Thu, 27 Apr 2006 11:32:29 -0700 Subject: [PATCH] x86/PAE: Fix pte_clear for the >4GB RAM case Proposed fix for ptep_get_and_clear_full PAE bug. Pte_clear had the same bug, so use the same fix for both. Turns out pmd_clear had it as well, but pgds are not affected. The problem is rather intricate. Page table entries in PAE mode are 64-bits wide, but the only atomic 8-byte write operation available in 32-bit mode is cmpxchg8b, which is expensive (at least on P4), and thus avoided. But it can happen that the processor may prefetch entries into the TLB in the middle of an operation which clears a page table entry. So one must always clear the P-bit in the low word of the page table entry first when clearing it. Since the sequence *ptep = __pte(0) leaves the order of the write dependent on the compiler, it must be coded explicitly as a clear of the low word followed by a clear of the high word. Further, there must be a write memory barrier here to enforce proper ordering by the compiler (and, in the future, by the processor as well). On > 4GB memory machines, the implementation of pte_clear for PAE was clearly deficient, as it could leave virtual mappings of physical memory above 4GB aliased to memory below 4GB in the TLB. The implementation of ptep_get_and_clear_full has a similar bug, although not nearly as likely to occur, since the mappings being cleared are in the process of being destroyed, and should never be dereferenced again. But, as luck would have it, it is possible to trigger bugs even without ever dereferencing these bogus TLB mappings, even if the clear is followed fairly soon after with a TLB flush or invalidation. The problem is that memory above 4GB may now be aliased into the first 4GB of memory, and in fact, may hit a region of memory with non-memory semantics. These regions include AGP and PCI space. As such, these memory regions are not cached by the processor. This introduces the bug. The processor can speculate memory operations, including memory writes, as long as they are committed with the proper ordering. Speculating a memory write to a linear address that has a bogus TLB mapping is possible. Normally, the speculation is harmless. But for cached memory, it does leave the falsely speculated cacheline unmodified, but in a dirty state. This cache line will be eventually written back. If this cacheline happens to intersect a region of memory that is not protected by the cache coherency protocol, it can corrupt data in I/O memory, which is generally a very bad thing to do, and can cause total system failure or just plain undefined behavior. These bugs are extremely unlikely, but the severity is of such magnitude, and the fix so simple that I think fixing them immediately is justified. Also, they are nearly impossible to debug. Signed-off-by: Zachary Amsden Signed-off-by: Linus Torvalds --- include/asm-i386/pgtable-2level.h | 3 +++ include/asm-i386/pgtable-3level.h | 20 ++++++++++++++++++++ include/asm-i386/pgtable.h | 4 +--- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h index 27bde973abc..2756d4b04c2 100644 --- a/include/asm-i386/pgtable-2level.h +++ b/include/asm-i386/pgtable-2level.h @@ -18,6 +18,9 @@ #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) +#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) + #define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) #define pte_same(a, b) ((a).pte_low == (b).pte_low) #define pte_page(x) pfn_to_page(pte_pfn(x)) diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 36a5aa63cbb..dccb1b3337a 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -85,6 +85,26 @@ static inline void pud_clear (pud_t * pud) { } #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ pmd_index(address)) +/* + * For PTEs and PDEs, we must clear the P-bit first when clearing a page table + * entry, so clear the bottom half first and enforce ordering with a compiler + * barrier. + */ +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = 0; +} + +static inline void pmd_clear(pmd_t *pmd) +{ + u32 *tmp = (u32 *)pmd; + *tmp = 0; + smp_wmb(); + *(tmp + 1) = 0; +} + static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t res; diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index ee056c41a9f..672c3f76b9d 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -204,12 +204,10 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; extern unsigned long pg0[]; #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) @@ -268,7 +266,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long pte_t pte; if (full) { pte = *ptep; - *ptep = __pte(0); + pte_clear(mm, addr, ptep); } else { pte = ptep_get_and_clear(mm, addr, ptep); } -- cgit v1.2.3 From b7d90a356a43f4609bd6290fc2e1ca4ef79d4458 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 25 Apr 2006 12:56:04 +0200 Subject: [ALSA] Fix Oops at rmmod with CONFIG_SND_VERBOSE_PROCFS=n Fixed Oops at rmmod with CONFIG_SND_VERBOSE_PROCFS=n. Add ifdef to struct fields for optimization and better compile checks. Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 6 +++++- include/sound/pcm_oss.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index df70e7592ab..373425895fa 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -374,12 +374,14 @@ struct snd_pcm_substream { /* -- OSS things -- */ struct snd_pcm_oss_substream oss; #endif +#ifdef CONFIG_SND_VERBOSE_PROCFS struct snd_info_entry *proc_root; struct snd_info_entry *proc_info_entry; struct snd_info_entry *proc_hw_params_entry; struct snd_info_entry *proc_sw_params_entry; struct snd_info_entry *proc_status_entry; struct snd_info_entry *proc_prealloc_entry; +#endif /* misc flags */ unsigned int no_mmap_ctrl: 1; unsigned int hw_opened: 1; @@ -400,12 +402,14 @@ struct snd_pcm_str { struct snd_pcm_oss_stream oss; #endif struct snd_pcm_file *files; +#ifdef CONFIG_SND_VERBOSE_PROCFS struct snd_info_entry *proc_root; struct snd_info_entry *proc_info_entry; -#ifdef CONFIG_SND_DEBUG +#ifdef CONFIG_SND_PCM_XRUN_DEBUG unsigned int xrun_debug; /* 0 = disabled, 1 = verbose, 2 = stacktrace */ struct snd_info_entry *proc_xrun_debug_entry; #endif +#endif }; struct snd_pcm { diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h index 39df2baca18..c854647b6f3 100644 --- a/include/sound/pcm_oss.h +++ b/include/sound/pcm_oss.h @@ -75,7 +75,9 @@ struct snd_pcm_oss_substream { struct snd_pcm_oss_stream { struct snd_pcm_oss_setup *setup_list; /* setup list */ struct mutex setup_mutex; +#ifdef CONFIG_SND_VERBOSE_PROCFS struct snd_info_entry *proc_entry; +#endif }; struct snd_pcm_oss { -- cgit v1.2.3 From 4d17ffda331ba6030bb8c233c73d6a87954d8ea7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 25 Apr 2006 15:37:26 +0200 Subject: [PATCH] Kobject: fix build error This fixes a build error for various odd combinations of CONFIG_HOTPLUG and CONFIG_NET. Signed-off-by: Kay Sievers Cc: Nigel Cunningham Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/kobject.h b/include/linux/kobject.h index dcd0623be89..e38bb357282 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -259,7 +259,7 @@ struct subsys_attribute { extern int subsys_create_file(struct subsystem * , struct subsys_attribute *); extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *); -#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) +#if defined(CONFIG_HOTPLUG) void kobject_uevent(struct kobject *kobj, enum kobject_action action); int add_uevent_var(char **envp, int num_envp, int *cur_index, -- cgit v1.2.3 From bde11d794206ae8d72defd0e8a481181200f7dc4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 18 Apr 2006 21:30:22 -0700 Subject: [PATCH] Fix OCFS2 warning when DEBUG_FS is not enabled Fix the following warning which happens when OCFS2_FS is enabled but DEBUG_FS isn't: fs/ocfs2/dlmglue.c: In function `ocfs2_dlm_init_debug': fs/ocfs2/dlmglue.c:2036: warning: passing arg 5 of `debugfs_create_file' discards qualifiers from pointer target type Signed-off-by: Jean Delvare Cc: Arjan van de Ven Cc: Joel Becker Acked-by: Mark Fasheh Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/debugfs.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 176e2d37157..047567d34ca 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -58,9 +58,8 @@ struct dentry *debugfs_create_blob(const char *name, mode_t mode, */ static inline struct dentry *debugfs_create_file(const char *name, mode_t mode, - struct dentry *parent, - void *data, - struct file_operations *fops) + struct dentry *parent, void *data, + const struct file_operations *fops) { return ERR_PTR(-ENODEV); } -- cgit v1.2.3 From 5b3ef14e3e9d745a512d65fcb4ef9be541226d80 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 22 Apr 2006 12:14:44 +0200 Subject: [PATCH] Kobject: possible cleanups This patch contains the following possible cleanups: - #if 0 the following unused global function: - subsys_remove_file() - remove the following unused EXPORT_SYMBOL's: - kset_find_obj - subsystem_init - remove the following unused EXPORT_SYMBOL_GPL: - kobject_add_dir Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/kobject.h b/include/linux/kobject.h index e38bb357282..c187c53cecd 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -257,7 +257,6 @@ struct subsys_attribute { }; extern int subsys_create_file(struct subsystem * , struct subsys_attribute *); -extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *); #if defined(CONFIG_HOTPLUG) void kobject_uevent(struct kobject *kobj, enum kobject_action action); -- cgit v1.2.3 From f0fe253c4719faf76d40f581cdc0e8aef77273bb Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Sat, 22 Apr 2006 09:36:07 -0500 Subject: [IA64-SGI] - Fix discover of nearest cpu node to IO node Fix a bug that causes discovery of the nearest node/cpu to a TIO (IO node) to fail. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- include/asm-ia64/sn/sn2/sn_hwperf.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-ia64/sn/sn2/sn_hwperf.h b/include/asm-ia64/sn/sn2/sn_hwperf.h index 291ef3d69da..e61ebac38cd 100644 --- a/include/asm-ia64/sn/sn2/sn_hwperf.h +++ b/include/asm-ia64/sn/sn2/sn_hwperf.h @@ -45,8 +45,12 @@ struct sn_hwperf_object_info { #define SN_HWPERF_IS_NODE(x) ((x) && strstr((x)->name, "SHub")) #define SN_HWPERF_IS_NODE_SHUB2(x) ((x) && strstr((x)->name, "SHub 2.")) #define SN_HWPERF_IS_IONODE(x) ((x) && strstr((x)->name, "TIO")) -#define SN_HWPERF_IS_ROUTER(x) ((x) && strstr((x)->name, "Router")) #define SN_HWPERF_IS_NL3ROUTER(x) ((x) && strstr((x)->name, "NL3Router")) +#define SN_HWPERF_IS_NL4ROUTER(x) ((x) && strstr((x)->name, "NL4Router")) +#define SN_HWPERF_IS_OLDROUTER(x) ((x) && strstr((x)->name, "Router")) +#define SN_HWPERF_IS_ROUTER(x) (SN_HWPERF_IS_NL3ROUTER(x) || \ + SN_HWPERF_IS_NL4ROUTER(x) || \ + SN_HWPERF_IS_OLDROUTER(x)) #define SN_HWPERF_FOREIGN(x) ((x) && !(x)->sn_hwp_this_part && !(x)->sn_hwp_is_shared) #define SN_HWPERF_SAME_OBJTYPE(x,y) ((SN_HWPERF_IS_NODE(x) && SN_HWPERF_IS_NODE(y)) ||\ (SN_HWPERF_IS_IONODE(x) && SN_HWPERF_IS_IONODE(y)) ||\ -- cgit v1.2.3 From 1df57c0c21c92a6d4fcfe5304c84151ed9beb7a2 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Tue, 25 Apr 2006 10:47:48 -0500 Subject: [IA64] enable dumps to capture second page of kernel stack In SLES10 (2.6.16) crash dumping (in my experience, LKCD) is unable to capture the second page of the 2-page task/stack allocation. This is particularly troublesome for dump analysis, as the stack traceback cannot be done. (A similar convention is probably needed throughout the kernel to make kernel multi-page allocations detectable for dumping) Multi-page kernel allocations are represented by the single page structure associated with the first page of the allocation. The page structures associated with the other pages are unintialized. If the dumper is selecting only kernel pages it has no way to identify any but the first page of the allocation. The fix is to make the task/stack allocation a compound page. Signed-off-by: Cliff Wickman Signed-off-by: Tony Luck --- include/asm-ia64/thread_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h index 56394a2c705..e5392c4d30c 100644 --- a/include/asm-ia64/thread_info.h +++ b/include/asm-ia64/thread_info.h @@ -67,7 +67,7 @@ struct thread_info { #define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET) #define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR -#define alloc_task_struct() ((task_t *)__get_free_pages(GFP_KERNEL, KERNEL_STACK_SIZE_ORDER)) +#define alloc_task_struct() ((task_t *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER)) #define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER) #endif /* !__ASSEMBLY */ -- cgit v1.2.3 From f10a04c034c7285a1b15dfa4a83d3e56578e34e8 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 28 Apr 2006 15:02:51 +1000 Subject: [PATCH] powerpc: Fix pagetable bloat for hugepages At present, ARCH=powerpc kernels can waste considerable space in pagetables when making large hugepage mappings. Hugepage PTEs go in PMD pages, but each PMD page maps 256M and so contains only 16 hugepage PTEs (128 bytes of data), but takes up a 1024 byte allocation. With CONFIG_PPC_64K_PAGES enabled (64k base page size), the situation is worse. Now hugepage PTEs are at the PTE page level (also mapping 256M), so we store 16 hugepage PTEs in a 64k allocation. The PowerPC MMU already means that any 256M region is either all hugepage, or all normal pages. Thus, with some care, we can use a different allocation for the hugepage PTE tables and only allocate the 128 bytes necessary. Signed-off-by: Paul Mackerras --- include/asm-powerpc/page_64.h | 1 + include/asm-powerpc/pgalloc.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h index 3fb061bab9e..eab779c2199 100644 --- a/include/asm-powerpc/page_64.h +++ b/include/asm-powerpc/page_64.h @@ -101,6 +101,7 @@ extern unsigned int HPAGE_SHIFT; - (1U << GET_HTLB_AREA(addr))) & 0xffff) #define ARCH_HAS_HUGEPAGE_ONLY_RANGE +#define ARCH_HAS_HUGETLB_FREE_PGD_RANGE #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE #define ARCH_HAS_SETCLEAR_HUGE_PTE diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h index a00ee002cd1..9f0917c6865 100644 --- a/include/asm-powerpc/pgalloc.h +++ b/include/asm-powerpc/pgalloc.h @@ -17,11 +17,13 @@ extern kmem_cache_t *pgtable_cache[]; #define PTE_CACHE_NUM 0 #define PMD_CACHE_NUM 1 #define PGD_CACHE_NUM 2 +#define HUGEPTE_CACHE_NUM 3 #else #define PTE_CACHE_NUM 0 #define PMD_CACHE_NUM 1 #define PUD_CACHE_NUM 1 #define PGD_CACHE_NUM 0 +#define HUGEPTE_CACHE_NUM 2 #endif /* -- cgit v1.2.3 From 1269277a5e7c6d7ae1852e648a8bcdb78035e9fa Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 24 Apr 2006 23:22:17 +0100 Subject: [PATCH] powerpc: Use check_legacy_ioport() on ppc32 too. Some people report that we die on some Macs when we are expecting to catch machine checks after poking at some random I/O address. I'd seen it happen on my dual G4 with serial ports until we fixed those to use OF, but now other users are reporting it with i8042. This expands the use of check_legacy_ioport() to avoid that situation even on 32-bit kernels. Signed-off-by: David Woodhouse Signed-off-by: Paul Mackerras --- include/asm-powerpc/io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h index 68efbea379c..f1c2469b884 100644 --- a/include/asm-powerpc/io.h +++ b/include/asm-powerpc/io.h @@ -9,6 +9,9 @@ * 2 of the License, or (at your option) any later version. */ +/* Check of existence of legacy devices */ +extern int check_legacy_ioport(unsigned long base_port); + #ifndef CONFIG_PPC64 #include #else @@ -437,9 +440,6 @@ out: #define dma_cache_wback(_start,_size) do { } while (0) #define dma_cache_wback_inv(_start,_size) do { } while (0) -/* Check of existence of legacy devices */ -extern int check_legacy_ioport(unsigned long base_port); - /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem -- cgit v1.2.3 From 30aacebed0f0619f23ce84df7c59ad033ca08d77 Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Tue, 25 Apr 2006 01:22:44 -0700 Subject: [PATCH] ppc32: add 440GX erratum 440_43 workaround This patch adds workaround for PPC 440GX erratum 440_43. According to this erratum spurious MachineChecks (caused by L1 cache parity) can happen during DataTLB miss processing. We disable L1 cache parity checking for 440GX rev.C and rev.F Signed-off-by: Eugene Surovegin Signed-off-by: Paul Mackerras --- include/asm-ppc/reg_booke.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h index 00ad9c754c7..4944c0fb8be 100644 --- a/include/asm-ppc/reg_booke.h +++ b/include/asm-ppc/reg_booke.h @@ -237,6 +237,7 @@ do { \ #endif /* Bit definitions for CCR1. */ +#define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */ #define CCR1_TCS 0x00000080 /* Timer Clock Select */ /* Bit definitions for the MCSR. */ -- cgit v1.2.3 From 2833c28aa0d0326780acfa61149a2a02dcb2c9b4 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 27 Apr 2006 15:46:42 +0200 Subject: [PATCH] powerpc: Wire up *at syscalls Wire up *at syscalls. This patch has been tested on ppc64 (using glibc's testsuite, both 32bit and 64bit), and compile-tested for ppc32 (I have currently no ppc32 system available, but I expect no problems). Signed-off-by: Andreas Schwab Signed-off-by: Paul Mackerras --- include/asm-powerpc/unistd.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 34325e29259..908acb44cb8 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h @@ -304,8 +304,25 @@ #define __NR_splice 283 #define __NR_tee 284 #define __NR_vmsplice 285 +#define __NR_openat 286 +#define __NR_mkdirat 287 +#define __NR_mknodat 288 +#define __NR_fchownat 289 +#define __NR_futimesat 290 +#ifdef __powerpc64__ +#define __NR_newfstatat 291 +#else +#define __NR_fstatat64 291 +#endif +#define __NR_unlinkat 292 +#define __NR_renameat 293 +#define __NR_linkat 294 +#define __NR_symlinkat 295 +#define __NR_readlinkat 296 +#define __NR_fchmodat 297 +#define __NR_faccessat 298 -#define __NR_syscalls 286 +#define __NR_syscalls 299 #ifdef __KERNEL__ #define __NR__exit __NR_exit @@ -458,6 +475,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 #ifdef CONFIG_PPC64 #define __ARCH_WANT_COMPAT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND +#define __ARCH_WANT_SYS_NEWFSTATAT #endif /* -- cgit v1.2.3 From a73c87bfe98f4d54c919e920a6efb0a116115722 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Tue, 25 Apr 2006 20:26:33 +0400 Subject: [PATCH] ppc32: odd fixes and improvements in ppc_sys This consists of offsets fix in ..._devices.c, and update of ppc_sys_fixup_mem_resource() function to prevent subsequent fixups Signed-off-by: Vitaly Bordug Signed-off-by: Paul Mackerras --- include/asm-ppc/ppc_sys.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h index 4b94f7059eb..40f197af650 100644 --- a/include/asm-ppc/ppc_sys.h +++ b/include/asm-ppc/ppc_sys.h @@ -39,6 +39,8 @@ #error "need definition of ppc_sys_devices" #endif +#define PPC_SYS_IORESOURCE_FIXUPPED 0x00000001 + struct ppc_sys_spec { /* PPC sys is matched via (ID & mask) == value, id could be * PVR, SVR, IMMR, * etc. */ -- cgit v1.2.3 From 13e87ec68641fd54f3fa04eef3419d034ed2115a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 27 Apr 2006 18:39:18 -0700 Subject: [PATCH] request_irq(): remove warnings from irq probing - Add new SA_PROBEIRQ which suppresses the new sharing-mismatch warning. Some drivers like to use request_irq() to find an unused interrupt slot. - Use it in i82365.c - Kill unused SA_PROBE. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-xtensa/signal.h | 2 +- include/linux/signal.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-xtensa/signal.h b/include/asm-xtensa/signal.h index 5d6fc9cdf58..a99c9aec64e 100644 --- a/include/asm-xtensa/signal.h +++ b/include/asm-xtensa/signal.h @@ -118,9 +118,9 @@ typedef struct { * SA_INTERRUPT is also used by the irq handling routines. * SA_SHIRQ is for shared interrupt support on PCI and EISA. */ -#define SA_PROBE SA_ONESHOT #define SA_SAMPLE_RANDOM SA_RESTART #define SA_SHIRQ 0x04000000 +#define SA_PROBEIRQ 0x08000000 #endif #define SIG_BLOCK 0 /* for blocking signals */ diff --git a/include/linux/signal.h b/include/linux/signal.h index 162a8fd10b2..70739f51a09 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -14,10 +14,12 @@ * * SA_INTERRUPT is also used by the irq handling routines. * SA_SHIRQ is for shared interrupt support on PCI and EISA. + * SA_PROBEIRQ is set by callers when they expect sharing mismatches to occur */ -#define SA_PROBE SA_ONESHOT #define SA_SAMPLE_RANDOM SA_RESTART #define SA_SHIRQ 0x04000000 +#define SA_PROBEIRQ 0x08000000 + /* * As above, these correspond to the IORESOURCE_IRQ_* defines in * linux/ioport.h to select the interrupt line behaviour. When -- cgit v1.2.3 From 3363fbdd6fb4992ffe6c17c0dd7388ffa22d99e6 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 27 Apr 2006 18:40:12 -0700 Subject: [PATCH] s390: futex atomic operations Add support for atomic futex operations. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-s390/futex.h | 123 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h index 6a332a9f099..40c25e166a9 100644 --- a/include/asm-s390/futex.h +++ b/include/asm-s390/futex.h @@ -1,6 +1,121 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H +#ifndef _ASM_S390_FUTEX_H +#define _ASM_S390_FUTEX_H -#include +#ifdef __KERNEL__ -#endif +#include +#include +#include + +#ifndef __s390x__ +#define __futex_atomic_fixup \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,2b,1b,2b\n" \ + ".previous" +#else /* __s390x__ */ +#define __futex_atomic_fixup \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n" \ + " .quad 0b,2b,1b,2b\n" \ + ".previous" +#endif /* __s390x__ */ + +#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ + asm volatile(" l %1,0(%6)\n" \ + "0: " insn \ + " cs %1,%2,0(%6)\n" \ + "1: jl 0b\n" \ + " lhi %0,0\n" \ + "2:\n" \ + __futex_atomic_fixup \ + : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ + "=m" (*uaddr) \ + : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ + "m" (*uaddr) : "cc" ); + +static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) +{ + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, newval, ret; + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + + if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + + inc_preempt_count(); + + switch (op) { + case FUTEX_OP_SET: + __futex_atomic_op("lr %2,%5\n", + ret, oldval, newval, uaddr, oparg); + break; + case FUTEX_OP_ADD: + __futex_atomic_op("lr %2,%1\nar %2,%5\n", + ret, oldval, newval, uaddr, oparg); + break; + case FUTEX_OP_OR: + __futex_atomic_op("lr %2,%1\nor %2,%5\n", + ret, oldval, newval, uaddr, oparg); + break; + case FUTEX_OP_ANDN: + __futex_atomic_op("lr %2,%1\nnr %2,%5\n", + ret, oldval, newval, uaddr, oparg); + break; + case FUTEX_OP_XOR: + __futex_atomic_op("lr %2,%1\nxr %2,%5\n", + ret, oldval, newval, uaddr, oparg); + break; + default: + ret = -ENOSYS; + } + + dec_preempt_count(); + + if (!ret) { + switch (cmp) { + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; + default: ret = -ENOSYS; + } + } + return ret; +} + +static inline int +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) +{ + int ret; + + if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + asm volatile(" cs %1,%4,0(%5)\n" + "0: lr %0,%1\n" + "1:\n" +#ifndef __s390x__ + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 0b,1b\n" + ".previous" +#else /* __s390x__ */ + ".section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 0b,1b\n" + ".previous" +#endif /* __s390x__ */ + : "=d" (ret), "+d" (oldval), "=m" (*uaddr) + : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) + : "cc", "memory" ); + return oldval; +} + +#endif /* __KERNEL__ */ +#endif /* _ASM_S390_FUTEX_H */ -- cgit v1.2.3 From 58268b97f679108d32a882a7fc029585da801975 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 27 Apr 2006 18:40:24 -0700 Subject: [PATCH] s390: add read_mostly optimization Add a read_mostly section and define __read_mostly to prevent cache line pollution due to writes for mostly read variables. In addition fix the incorrect alignment of the cache_line_aligned data section. s390 has a cacheline size of 256 bytes. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-s390/cache.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-s390/cache.h b/include/asm-s390/cache.h index e20cdd9074d..cdf431b061b 100644 --- a/include/asm-s390/cache.h +++ b/include/asm-s390/cache.h @@ -16,4 +16,6 @@ #define ARCH_KMALLOC_MINALIGN 8 +#define __read_mostly __attribute__((__section__(".data.read_mostly"))) + #endif -- cgit v1.2.3 From 03054d51a70e8c273df5d9bc31fea6c843eaa1c3 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sat, 29 Apr 2006 09:51:06 +1000 Subject: [PATCH] powerpc: Add cputable entry for POWER6 Add a cputable entry for the POWER6 processor. The SIHV and SIPR bits in the mmcra have moved in POWER6, so disable support for that until oprofile is fixed. Also tell firmware that we know about POWER6. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- include/asm-powerpc/cputable.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 4321483cce5..9fcf0162d85 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -22,6 +22,7 @@ #define PPC_FEATURE_BOOKE 0x00008000 #define PPC_FEATURE_SMT 0x00004000 #define PPC_FEATURE_ICACHE_SNOOP 0x00002000 +#define PPC_FEATURE_ARCH_2_05 0x00001000 #ifdef __KERNEL__ #ifndef __ASSEMBLY__ @@ -320,6 +321,11 @@ extern void do_cpu_ftr_fixups(unsigned long offset); CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR) +#define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ + CPU_FTR_MMCRA | CPU_FTR_SMT | \ + CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ + CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE) #define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ @@ -331,8 +337,8 @@ extern void do_cpu_ftr_fixups(unsigned long offset); #ifdef __powerpc64__ #define CPU_FTRS_POSSIBLE \ (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \ - CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | \ - CPU_FTR_CI_LARGE_PAGE) + CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \ + CPU_FTRS_CELL | CPU_FTR_CI_LARGE_PAGE) #else enum { CPU_FTRS_POSSIBLE = @@ -376,8 +382,8 @@ enum { #ifdef __powerpc64__ #define CPU_FTRS_ALWAYS \ (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \ - CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & \ - CPU_FTRS_POSSIBLE) + CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \ + CPU_FTRS_CELL & CPU_FTRS_POSSIBLE) #else enum { CPU_FTRS_ALWAYS = -- cgit v1.2.3 From 08791e5cf62b6952ca32106aebb79b6066005de4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 29 Apr 2006 01:13:21 -0400 Subject: Input: ressurect EVIOCGREP and EVIOCSREP While writing to an event device allows to set repeat rate for an individual input device there is no way to retrieve current settings so we need to ressurect EVIOCGREP. Also ressurect EVIOCSREP so we have a symmetrical interface. Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/input.h b/include/linux/input.h index 8298b4bf5a0..50e338d2ffd 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -56,6 +56,8 @@ struct input_absinfo { #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ +#define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */ +#define EVIOCSREP _IOW('E', 0x03, int[2]) /* set repeat settings */ #define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ #define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ -- cgit v1.2.3 From 543f2a3382bd7abd7380903518c61f00c7c87577 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Sat, 29 Apr 2006 14:07:49 -0400 Subject: [PATCH] i386: fix broken FP exception handling The FXSAVE information leak patch introduced a bug in FP exception handling: it clears FP exceptions only when there are already none outstanding. Mikael Pettersson reported that causes problems with the Erlang runtime and has tested this fix. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Acked-by: Mikael Pettersson Signed-off-by: Linus Torvalds --- include/asm-i386/i387.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index 7b1f01191e7..bc1d6edae1e 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h @@ -58,13 +58,13 @@ static inline void __save_init_fpu( struct task_struct *tsk ) alternative_input( "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, "fxsave %[fx]\n" - "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", + "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", X86_FEATURE_FXSR, [fx] "m" (tsk->thread.i387.fxsave), [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is pending. Clear the x87 state here by setting it to fixed - values. __per_cpu_offset[0] is a random variable that should be in L1 */ + values. safe_address is a random variable that should be in L1 */ alternative_input( GENERIC_NOP8 GENERIC_NOP2, "emms\n\t" /* clear stack tags */ -- cgit v1.2.3 From da753beaeb1446aa87bcca7e8a0026633a8914f0 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 28 Apr 2006 15:21:23 -0700 Subject: [NET]: use hlist_unhashed() Use hlist_unhashed() rather than accessing inside data structure. Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/linux/list.h | 2 +- include/net/inet_timewait_sock.h | 2 +- include/net/sock.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/list.h b/include/linux/list.h index 67258b47e9c..76f05718342 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -619,7 +619,7 @@ static inline void hlist_del_rcu(struct hlist_node *n) static inline void hlist_del_init(struct hlist_node *n) { - if (n->pprev) { + if (!hlist_unhashed(n)) { __hlist_del(n); INIT_HLIST_NODE(n); } diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 1da294c4752..e837f98fdb5 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -150,7 +150,7 @@ static inline void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, static inline int inet_twsk_dead_hashed(const struct inet_timewait_sock *tw) { - return tw->tw_death_node.pprev != NULL; + return !hlist_unhashed(&tw->tw_death_node); } static inline void inet_twsk_dead_node_init(struct inet_timewait_sock *tw) diff --git a/include/net/sock.h b/include/net/sock.h index ff8b0dad7b0..c9fad6fb629 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -279,7 +279,7 @@ static inline int sk_unhashed(const struct sock *sk) static inline int sk_hashed(const struct sock *sk) { - return sk->sk_node.pprev != NULL; + return !sk_unhashed(sk); } static __inline__ void sk_node_init(struct hlist_node *node) -- cgit v1.2.3 From 1241140f5183db38393556832198a3b109bf9085 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 30 Apr 2006 21:40:13 -0700 Subject: [SPARC64]: Kill __flush_tlb_page() prototype. This function no longer exists. Signed-off-by: David S. Miller --- include/asm-sparc64/tlbflush.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h index 9ad5d9c51d4..e3a7c453b50 100644 --- a/include/asm-sparc64/tlbflush.h +++ b/include/asm-sparc64/tlbflush.h @@ -22,8 +22,6 @@ extern void flush_tlb_pending(void); /* Local cpu only. */ extern void __flush_tlb_all(void); -extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); - extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); #ifndef CONFIG_SMP -- cgit v1.2.3 From 5411be59db80333039386f3b1ccfe5eb9023a916 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 29 Mar 2006 20:23:36 -0500 Subject: [PATCH] drop task argument of audit_syscall_{entry,exit} ... it's always current, and that's a good thing - allows simpler locking. Signed-off-by: Al Viro --- include/linux/audit.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/audit.h b/include/linux/audit.h index 1c47c59058c..39fef6ebb85 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -287,10 +287,10 @@ struct netlink_skb_parms; /* Public API */ extern int audit_alloc(struct task_struct *task); extern void audit_free(struct task_struct *task); -extern void audit_syscall_entry(struct task_struct *task, int arch, +extern void audit_syscall_entry(int arch, int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); -extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code); +extern void audit_syscall_exit(int failed, long return_code); extern void audit_getname(const char *name); extern void audit_putname(const char *name); extern void __audit_inode(const char *name, const struct inode *inode, unsigned flags); @@ -323,8 +323,8 @@ extern int audit_set_macxattr(const char *name); #else #define audit_alloc(t) ({ 0; }) #define audit_free(t) do { ; } while (0) -#define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0) -#define audit_syscall_exit(t,f,r) do { ; } while (0) +#define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0) +#define audit_syscall_exit(f,r) do { ; } while (0) #define audit_getname(n) do { ; } while (0) #define audit_putname(n) do { ; } while (0) #define __audit_inode(n,i,f) do { ; } while (0) -- cgit v1.2.3 From 376bd9cb357ec945ac893feaeb63af7370a6e70b Mon Sep 17 00:00:00 2001 From: Darrel Goeddel Date: Fri, 24 Feb 2006 15:44:05 -0600 Subject: [PATCH] support for context based audit filtering The following patch provides selinux interfaces that will allow the audit system to perform filtering based on the process context (user, role, type, sensitivity, and clearance). These interfaces will allow the selinux module to perform efficient matches based on lower level selinux constructs, rather than relying on context retrievals and string comparisons within the audit module. It also allows for dominance checks on the mls portion of the contexts that are impossible with only string comparisons. Signed-off-by: Darrel Goeddel Signed-off-by: Al Viro --- include/linux/audit.h | 5 +++ include/linux/selinux.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 include/linux/selinux.h (limited to 'include') diff --git a/include/linux/audit.h b/include/linux/audit.h index 39fef6ebb85..740f950397b 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -145,6 +145,11 @@ #define AUDIT_PERS 10 #define AUDIT_ARCH 11 #define AUDIT_MSGTYPE 12 +#define AUDIT_SE_USER 13 /* security label user */ +#define AUDIT_SE_ROLE 14 /* security label role */ +#define AUDIT_SE_TYPE 15 /* security label type */ +#define AUDIT_SE_SEN 16 /* security label sensitivity label */ +#define AUDIT_SE_CLR 17 /* security label clearance label */ /* These are ONLY useful when checking * at syscall exit time (AUDIT_AT_EXIT). */ diff --git a/include/linux/selinux.h b/include/linux/selinux.h new file mode 100644 index 00000000000..9d684b1728b --- /dev/null +++ b/include/linux/selinux.h @@ -0,0 +1,112 @@ +/* + * SELinux services exported to the rest of the kernel. + * + * Author: James Morris + * + * Copyright (C) 2005 Red Hat, Inc., James Morris + * Copyright (C) 2006 Trusted Computer Solutions, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ +#ifndef _LINUX_SELINUX_H +#define _LINUX_SELINUX_H + +struct selinux_audit_rule; +struct audit_context; + +#ifdef CONFIG_SECURITY_SELINUX + +/** + * selinux_audit_rule_init - alloc/init an selinux audit rule structure. + * @field: the field this rule refers to + * @op: the operater the rule uses + * @rulestr: the text "target" of the rule + * @rule: pointer to the new rule structure returned via this + * + * Returns 0 if successful, -errno if not. On success, the rule structure + * will be allocated internally. The caller must free this structure with + * selinux_audit_rule_free() after use. + */ +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, + struct selinux_audit_rule **rule); + +/** + * selinux_audit_rule_free - free an selinux audit rule structure. + * @rule: pointer to the audit rule to be freed + * + * This will free all memory associated with the given rule. + * If @rule is NULL, no operation is performed. + */ +void selinux_audit_rule_free(struct selinux_audit_rule *rule); + +/** + * selinux_audit_rule_match - determine if a context ID matches a rule. + * @ctxid: the context ID to check + * @field: the field this rule refers to + * @op: the operater the rule uses + * @rule: pointer to the audit rule to check against + * @actx: the audit context (can be NULL) associated with the check + * + * Returns 1 if the context id matches the rule, 0 if it does not, and + * -errno on failure. + */ +int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, + struct selinux_audit_rule *rule, + struct audit_context *actx); + +/** + * selinux_audit_set_callback - set the callback for policy reloads. + * @callback: the function to call when the policy is reloaded + * + * This sets the function callback function that will update the rules + * upon policy reloads. This callback should rebuild all existing rules + * using selinux_audit_rule_init(). + */ +void selinux_audit_set_callback(int (*callback)(void)); + +/** + * selinux_task_ctxid - determine a context ID for a process. + * @tsk: the task object + * @ctxid: ID value returned via this + * + * On return, ctxid will contain an ID for the context. This value + * should only be used opaquely. + */ +void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid); + +#else + +static inline int selinux_audit_rule_init(u32 field, u32 op, + char *rulestr, + struct selinux_audit_rule **rule) +{ + return -ENOTSUPP; +} + +static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule) +{ + return; +} + +static inline int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, + struct selinux_audit_rule *rule, + struct audit_context *actx) +{ + return 0; +} + +static inline void selinux_audit_set_callback(int (*callback)(void)) +{ + return; +} + +static inline void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) +{ + *ctxid = 0; +} + +#endif /* CONFIG_SECURITY_SELINUX */ + +#endif /* _LINUX_SELINUX_H */ -- cgit v1.2.3 From 1b50eed9cac0e8e5e4d3a522d8aa267f7f8f8acb Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Mon, 3 Apr 2006 14:06:13 -0400 Subject: [PATCH] audit inode patch Previously, we were gathering the context instead of the sid. Now in this patch, we gather just the sid and convert to context only if an audit event is being output. This patch brings the performance hit from 146% down to 23% Signed-off-by: Al Viro --- include/linux/selinux.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'include') diff --git a/include/linux/selinux.h b/include/linux/selinux.h index 9d684b1728b..84a6c740468 100644 --- a/include/linux/selinux.h +++ b/include/linux/selinux.h @@ -15,6 +15,7 @@ struct selinux_audit_rule; struct audit_context; +struct inode; #ifdef CONFIG_SECURITY_SELINUX @@ -76,6 +77,27 @@ void selinux_audit_set_callback(int (*callback)(void)); */ void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid); +/** + * selinux_ctxid_to_string - map a security context ID to a string + * @ctxid: security context ID to be converted. + * @ctx: address of context string to be returned + * @ctxlen: length of returned context string. + * + * Returns 0 if successful, -errno if not. On success, the context + * string will be allocated internally, and the caller must call + * kfree() on it after use. + */ +int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen); + +/** + * selinux_get_inode_sid - get the inode's security context ID + * @inode: inode structure to get the sid from. + * @sid: pointer to security context ID to be filled in. + * + * Returns nothing + */ +void selinux_get_inode_sid(const struct inode *inode, u32 *sid); + #else static inline int selinux_audit_rule_init(u32 field, u32 op, @@ -107,6 +129,18 @@ static inline void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) *ctxid = 0; } +static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) +{ + *ctx = NULL; + *ctxlen = 0; + return 0; +} + +static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid) +{ + *sid = 0; +} + #endif /* CONFIG_SECURITY_SELINUX */ #endif /* _LINUX_SELINUX_H */ -- cgit v1.2.3 From 9c7aa6aa74fa8a5cda36e54cbbe4fffe0214497d Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Fri, 31 Mar 2006 15:22:49 -0500 Subject: [PATCH] change lspp ipc auditing Hi, The patch below converts IPC auditing to collect sid's and convert to context string only if it needs to output an audit record. This patch depends on the inode audit change patch already being applied. Signed-off-by: Steve Grubb Signed-off-by: Al Viro --- include/linux/security.h | 16 ---------------- include/linux/selinux.h | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/linux/security.h b/include/linux/security.h index aaa0a5cdbf7..1bab48f6aea 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -869,11 +869,6 @@ struct swap_info_struct; * @ipcp contains the kernel IPC permission structure * @flag contains the desired (requested) permission set * Return 0 if permission is granted. - * @ipc_getsecurity: - * Copy the security label associated with the ipc object into - * @buffer. @buffer may be NULL to request the size of the buffer - * required. @size indicates the size of @buffer in bytes. Return - * number of bytes used/required on success. * * Security hooks for individual messages held in System V IPC message queues * @msg_msg_alloc_security: @@ -1223,7 +1218,6 @@ struct security_operations { void (*task_to_inode)(struct task_struct *p, struct inode *inode); int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); - int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size); int (*msg_msg_alloc_security) (struct msg_msg * msg); void (*msg_msg_free_security) (struct msg_msg * msg); @@ -1887,11 +1881,6 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, return security_ops->ipc_permission (ipcp, flag); } -static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) -{ - return security_ops->ipc_getsecurity(ipcp, buffer, size); -} - static inline int security_msg_msg_alloc (struct msg_msg * msg) { return security_ops->msg_msg_alloc_security (msg); @@ -2532,11 +2521,6 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, return 0; } -static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) -{ - return -EOPNOTSUPP; -} - static inline int security_msg_msg_alloc (struct msg_msg * msg) { return 0; diff --git a/include/linux/selinux.h b/include/linux/selinux.h index 84a6c740468..413d66773b9 100644 --- a/include/linux/selinux.h +++ b/include/linux/selinux.h @@ -16,6 +16,7 @@ struct selinux_audit_rule; struct audit_context; struct inode; +struct kern_ipc_perm; #ifdef CONFIG_SECURITY_SELINUX @@ -98,6 +99,15 @@ int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen); */ void selinux_get_inode_sid(const struct inode *inode, u32 *sid); +/** + * selinux_get_ipc_sid - get the ipc security context ID + * @ipcp: ipc structure to get the sid from. + * @sid: pointer to security context ID to be filled in. + * + * Returns nothing + */ +void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid); + #else static inline int selinux_audit_rule_init(u32 field, u32 op, @@ -141,6 +151,11 @@ static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid) *sid = 0; } +static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) +{ + *sid = 0; +} + #endif /* CONFIG_SECURITY_SELINUX */ #endif /* _LINUX_SELINUX_H */ -- cgit v1.2.3 From e7c3497013a7e5496ce3d5fd3c73b5cf5af7a56e Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Mon, 3 Apr 2006 09:08:13 -0400 Subject: [PATCH] Reworked patch for labels on user space messages The below patch should be applied after the inode and ipc sid patches. This patch is a reworking of Tim's patch that has been updated to match the inode and ipc patches since its similar. [updated: > Stephen Smalley also wanted to change a variable from isec to tsec in the > user sid patch. ] Signed-off-by: Steve Grubb Signed-off-by: Al Viro --- include/linux/netlink.h | 1 + include/linux/selinux.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'include') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index f8f3d1c927f..87b8a5703eb 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -143,6 +143,7 @@ struct netlink_skb_parms __u32 dst_group; kernel_cap_t eff_cap; __u32 loginuid; /* Login (audit) uid */ + __u32 sid; /* SELinux security id */ }; #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) diff --git a/include/linux/selinux.h b/include/linux/selinux.h index 413d66773b9..4047bcde448 100644 --- a/include/linux/selinux.h +++ b/include/linux/selinux.h @@ -5,6 +5,7 @@ * * Copyright (C) 2005 Red Hat, Inc., James Morris * Copyright (C) 2006 Trusted Computer Solutions, Inc. + * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -108,6 +109,16 @@ void selinux_get_inode_sid(const struct inode *inode, u32 *sid); */ void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid); +/** + * selinux_get_task_sid - return the SID of task + * @tsk: the task whose SID will be returned + * @sid: pointer to security context ID to be filled in. + * + * Returns nothing + */ +void selinux_get_task_sid(struct task_struct *tsk, u32 *sid); + + #else static inline int selinux_audit_rule_init(u32 field, u32 op, @@ -156,6 +167,11 @@ static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *si *sid = 0; } +static inline void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) +{ + *sid = 0; +} + #endif /* CONFIG_SECURITY_SELINUX */ #endif /* _LINUX_SELINUX_H */ -- cgit v1.2.3 From ce29b682e228c70cdc91a1b2935c5adb2087bab8 Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Sat, 1 Apr 2006 18:29:34 -0500 Subject: [PATCH] More user space subject labels Hi, The patch below builds upon the patch sent earlier and adds subject label to all audit events generated via the netlink interface. It also cleans up a few other minor things. Signed-off-by: Steve Grubb Signed-off-by: Al Viro --- include/linux/audit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/audit.h b/include/linux/audit.h index 740f950397b..d5c40823e16 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -371,7 +371,7 @@ extern void audit_log_d_path(struct audit_buffer *ab, extern int audit_filter_user(struct netlink_skb_parms *cb, int type); extern int audit_filter_type(int type); extern int audit_receive_filter(int type, int pid, int uid, int seq, - void *data, size_t datasz, uid_t loginuid); + void *data, size_t datasz, uid_t loginuid, u32 sid); #else #define audit_log(c,g,t,f,...) do { ; } while (0) #define audit_log_start(c,g,t) ({ NULL; }) -- cgit v1.2.3 From 073115d6b29c7910feaa08241c6484637f5ca958 Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Sun, 2 Apr 2006 17:07:33 -0400 Subject: [PATCH] Rework of IPC auditing 1) The audit_ipc_perms() function has been split into two different functions: - audit_ipc_obj() - audit_ipc_set_perm() There's a key shift here... The audit_ipc_obj() collects the uid, gid, mode, and SElinux context label of the current ipc object. This audit_ipc_obj() hook is now found in several places. Most notably, it is hooked in ipcperms(), which is called in various places around the ipc code permforming a MAC check. Additionally there are several places where *checkid() is used to validate that an operation is being performed on a valid object while not necessarily having a nearby ipcperms() call. In these locations, audit_ipc_obj() is called to ensure that the information is captured by the audit system. The audit_set_new_perm() function is called any time the permissions on the ipc object changes. In this case, the NEW permissions are recorded (and note that an audit_ipc_obj() call exists just a few lines before each instance). 2) Support for an AUDIT_IPC_SET_PERM audit message type. This allows for separate auxiliary audit records for normal operations on an IPC object and permissions changes. Note that the same struct audit_aux_data_ipcctl is used and populated, however there are separate audit_log_format statements based on the type of the message. Finally, the AUDIT_IPC block of code in audit_free_aux() was extended to handle aux messages of this new type. No more mem leaks I hope ;-) Signed-off-by: Al Viro --- include/linux/audit.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/audit.h b/include/linux/audit.h index d5c40823e16..b74c148f14e 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -83,6 +83,7 @@ #define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ #define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */ #define AUDIT_CWD 1307 /* Current working directory */ +#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ @@ -319,7 +320,8 @@ extern void auditsc_get_stamp(struct audit_context *ctx, struct timespec *t, unsigned int *serial); extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); extern uid_t audit_get_loginuid(struct audit_context *ctx); -extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); +extern int audit_ipc_obj(struct kern_ipc_perm *ipcp); +extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); extern int audit_socketcall(int nargs, unsigned long *args); extern int audit_sockaddr(int len, void *addr); extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); @@ -338,7 +340,8 @@ extern int audit_set_macxattr(const char *name); #define audit_inode_child(d,i,p) do { ; } while (0) #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) #define audit_get_loginuid(c) ({ -1; }) -#define audit_ipc_perms(q,u,g,m,i) ({ 0; }) +#define audit_ipc_obj(i) ({ 0; }) +#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; }) #define audit_socketcall(n,a) ({ 0; }) #define audit_sockaddr(len, addr) ({ 0; }) #define audit_avc_path(dentry, mnt) ({ 0; }) -- cgit v1.2.3 From 0568b409c74f7a125d92a09a3f386785700ef688 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 1 May 2006 19:50:48 +0200 Subject: [PATCH] splice: fix bugs in pipe_to_file() Found by Oleg Nesterov , fixed by me. - Only allow full pages to go to the page cache. - Check page != buf->page instead of using PIPE_BUF_FLAG_STOLEN. - Remember to clear 'stolen' if add_to_page_cache() fails. And as a cleanup on that: - Make the bottom fall-through logic a little less convoluted. Also make the steal path hold an extra reference to the page, so we don't have to differentiate between stolen and non-stolen at the end. Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 0008d4bd405..3130977fc6a 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -5,8 +5,7 @@ #define PIPE_BUFFERS (16) -#define PIPE_BUF_FLAG_STOLEN 0x01 -#define PIPE_BUF_FLAG_LRU 0x02 +#define PIPE_BUF_FLAG_LRU 0x01 struct pipe_buffer { struct page *page; -- cgit v1.2.3 From f84d751994441292593523c7069ed147176f6cab Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 1 May 2006 19:59:03 +0200 Subject: [PATCH] pipe: introduce ->pin() buffer operation The ->map() function is really expensive on highmem machines right now, since it has to use the slower kmap() instead of kmap_atomic(). Splice rarely needs to access the virtual address of a page, so it's a waste of time doing it. Introduce ->pin() to take over the responsibility of making sure the page data is valid. ->map() is then reduced to just kmap(). That way we can also share a most of the pipe buffer ops between pipe.c and splice.c Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 3130977fc6a..b8aae1fc518 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -14,10 +14,23 @@ struct pipe_buffer { unsigned int flags; }; +/* + * Note on the nesting of these functions: + * + * ->pin() + * ->steal() + * ... + * ->map() + * ... + * ->unmap() + * + * That is, ->map() must be called on a pinned buffer, same goes for ->steal(). + */ struct pipe_buf_operations { int can_merge; - void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *); + void * (*map)(struct pipe_inode_info *, struct pipe_buffer *); void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); + int (*pin)(struct pipe_inode_info *, struct pipe_buffer *); void (*release)(struct pipe_inode_info *, struct pipe_buffer *); int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); void (*get)(struct pipe_inode_info *, struct pipe_buffer *); @@ -50,6 +63,12 @@ struct pipe_inode_info * alloc_pipe_info(struct inode * inode); void free_pipe_info(struct inode * inode); void __free_pipe_info(struct pipe_inode_info *); +/* Generic pipe buffer ops functions */ +void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *); +void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *); +void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); +int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); + /* * splice is tied to pipes as a transport (at least for now), so we'll just * add the splice flags here. -- cgit v1.2.3 From f6762b7ad8edd6abc802542ce845d3bc8adcb92f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 1 May 2006 20:02:05 +0200 Subject: [PATCH] pipe: enable atomic copying of pipe data to/from user space The pipe ->map() method uses kmap() to virtually map the pages, which is both slow and has known scalability issues on SMP. This patch enables atomic copying of pipe pages, by pre-faulting data and using kmap_atomic() instead. lmbench bw_pipe and lat_pipe measurements agree this is a Good Thing. Here are results from that on a UP machine with highmem (1.5GiB of RAM), running first a UP kernel, SMP kernel, and SMP kernel patched. Vanilla-UP: Pipe bandwidth: 1622.28 MB/sec Pipe bandwidth: 1610.59 MB/sec Pipe bandwidth: 1608.30 MB/sec Pipe latency: 7.3275 microseconds Pipe latency: 7.2995 microseconds Pipe latency: 7.3097 microseconds Vanilla-SMP: Pipe bandwidth: 1382.19 MB/sec Pipe bandwidth: 1317.27 MB/sec Pipe bandwidth: 1355.61 MB/sec Pipe latency: 9.6402 microseconds Pipe latency: 9.6696 microseconds Pipe latency: 9.6153 microseconds Patched-SMP: Pipe bandwidth: 1578.70 MB/sec Pipe bandwidth: 1579.95 MB/sec Pipe bandwidth: 1578.63 MB/sec Pipe latency: 9.1654 microseconds Pipe latency: 9.2266 microseconds Pipe latency: 9.1527 microseconds Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index b8aae1fc518..4c054491e38 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -5,7 +5,8 @@ #define PIPE_BUFFERS (16) -#define PIPE_BUF_FLAG_LRU 0x01 +#define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */ +#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ struct pipe_buffer { struct page *page; @@ -28,8 +29,8 @@ struct pipe_buffer { */ struct pipe_buf_operations { int can_merge; - void * (*map)(struct pipe_inode_info *, struct pipe_buffer *); - void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); + void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); + void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); int (*pin)(struct pipe_inode_info *, struct pipe_buffer *); void (*release)(struct pipe_inode_info *, struct pipe_buffer *); int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); @@ -64,8 +65,8 @@ void free_pipe_info(struct inode * inode); void __free_pipe_info(struct pipe_inode_info *); /* Generic pipe buffer ops functions */ -void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *); -void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *); +void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); +void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); -- cgit v1.2.3 From 7afa6fd037e51e95d322990cb127bb2b1217251a Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 1 May 2006 20:02:33 +0200 Subject: [PATCH] vmsplice: allow user to pass in gift pages If SPLICE_F_GIFT is set, the user is basically giving this pages away to the kernel. That means we can steal them for eg page cache uses instead of copying it. The data must be properly page aligned and also a multiple of the page size in length. Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 4c054491e38..df4d3fa7d3d 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -7,6 +7,7 @@ #define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */ #define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ +#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ struct pipe_buffer { struct page *page; @@ -79,6 +80,7 @@ int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); /* we may still block on the fd we splice */ /* from/to, of course */ #define SPLICE_F_MORE (0x04) /* expect more data */ +#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ /* * Passed to the actors -- cgit v1.2.3 From 953039c8df7beb2694814e20e2707a77d335a2e3 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 1 May 2006 12:16:12 -0700 Subject: [PATCH] powerpc: Allow devices to register with numa topology Change of_node_to_nid() to traverse the device tree, looking for a numa id. Cell uses this to assign ids to SPUs, which are children of the CPU node. Existing users of of_node_to_nid() are altered to use of_node_to_nid_single(), which doesn't do the traversal. Export an attach_sysdev_to_node() function, allowing system devices (eg. SPUs) to link themselves into the numa topology in sysfs. Signed-off-by: Arnd Bergmann Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-powerpc/topology.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h index 1e19cd00af2..87362a05542 100644 --- a/include/asm-powerpc/topology.h +++ b/include/asm-powerpc/topology.h @@ -4,6 +4,9 @@ #include +struct sys_device; +struct device_node; + #ifdef CONFIG_NUMA #include @@ -27,6 +30,8 @@ static inline int node_to_first_cpu(int node) return first_cpu(tmp); } +int of_node_to_nid(struct device_node *device); + #define pcibus_to_node(node) (-1) #define pcibus_to_cpumask(bus) (cpu_online_map) @@ -57,10 +62,29 @@ static inline int node_to_first_cpu(int node) extern void __init dump_numa_cpu_topology(void); +extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); +extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); + #else +static inline int of_node_to_nid(struct device_node *device) +{ + return 0; +} + static inline void dump_numa_cpu_topology(void) {} +static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) +{ + return 0; +} + +static inline void sysfs_remove_device_from_node(struct sys_device *dev, + int nid) +{ +} + + #include #endif /* CONFIG_NUMA */ -- cgit v1.2.3 From 8261aa600943046a5305564a1cd7432009971799 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 1 May 2006 12:16:13 -0700 Subject: [PATCH] powerpc: cell: Add numa id to struct spu Add an nid member to the spu structure, and store the numa id of the spu there on creation. Signed-off-by: Arnd Bergmann Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-powerpc/spu.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index f431d8b0b65..7cfcff3ef02 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -117,6 +117,7 @@ struct spu { struct list_head list; struct list_head sched_list; int number; + int nid; u32 isrc; u32 node; u64 flags; -- cgit v1.2.3 From 46c5ea3c9ae7fbc6e52a13c92e59d4fc7f4ca80a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 2 May 2006 05:12:22 +0200 Subject: [NETFILTER] x_tables: fix compat related crash on non-x86 When iptables userspace adds an ipt_standard_target, it calculates the size of the entire entry as: sizeof(struct ipt_entry) + XT_ALIGN(sizeof(struct ipt_standard_target)) ipt_standard_target looks like this: struct xt_standard_target { struct xt_entry_target target; int verdict; }; xt_entry_target contains a pointer, so when compiled for 64 bit the structure gets an extra 4 byte of padding at the end. On 32 bit architectures where iptables aligns to 8 byte it will also have 4 byte padding at the end because it is only 36 bytes large. The compat_ipt_standard_fn in the kernel adjusts the offsets by sizeof(struct ipt_standard_target) - sizeof(struct compat_ipt_standard_target), which will always result in 4, even if the structure from userspace was already padded to a multiple of 8. On x86 this works out by accident because userspace only aligns to 4, on all other architectures this is broken and causes incorrect adjustments to the size and following offsets. Thanks to Linus for lots of debugging help and testing. Signed-off-by: Patrick McHardy Signed-off-by: Linus Torvalds --- include/linux/netfilter/x_tables.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 38701454e19..48cc32d83f7 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -337,6 +337,10 @@ struct compat_xt_entry_match char name[XT_FUNCTION_MAXNAMELEN - 1]; u_int8_t revision; } user; + struct { + u_int16_t match_size; + compat_uptr_t match; + } kernel; u_int16_t match_size; } u; unsigned char data[0]; @@ -350,6 +354,10 @@ struct compat_xt_entry_target char name[XT_FUNCTION_MAXNAMELEN - 1]; u_int8_t revision; } user; + struct { + u_int16_t target_size; + compat_uptr_t target; + } kernel; u_int16_t target_size; } u; unsigned char data[0]; -- cgit v1.2.3 From a893b99be71f1d669b74f840e3a683dd077d007b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 2 May 2006 15:03:27 +0200 Subject: [PATCH] splice: fix page LRU accounting Currently we rely on the PIPE_BUF_FLAG_LRU flag being set correctly to know whether we need to fiddle with page LRU state after stealing it, however for some origins we just don't know if the page is on the LRU list or not. So remove PIPE_BUF_FLAG_LRU and do this check/add manually in pipe_to_file() instead. Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index df4d3fa7d3d..070954f0594 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -5,9 +5,8 @@ #define PIPE_BUFFERS (16) -#define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */ -#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ -#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ +#define PIPE_BUF_FLAG_ATOMIC 0x01 /* was atomically mapped */ +#define PIPE_BUF_FLAG_GIFT 0x02 /* page is a gift */ struct pipe_buffer { struct page *page; -- cgit v1.2.3 From 330ab71619bacc4d4494227a6cfc9b7f5500403d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 2 May 2006 15:29:57 +0200 Subject: [PATCH] vmsplice: restrict stealing a little more Apply the same rules as the anon pipe pages, only allow stealing if no one else is using the page. Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 070954f0594..ba73108cbf8 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -69,6 +69,7 @@ void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); +int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); /* * splice is tied to pipes as a transport (at least for now), so we'll just -- cgit v1.2.3