From 6f25f3986af0353b0bdc220f79b89c997d0ceda4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Mar 2006 13:29:26 -0800 Subject: [PATCH 1/6] [SPARC64]: Make tsb_sync() mm comparison more precise. switch_mm() changes the mm state and does a tsb_context_switch() first, then we do the cpu register state switch which changes current_thread_info() and current(). So it's safer to check the PGD physical address stored in the trap block (which will be updated by the tsb_context_switch() in switch_mm()) than current->active_mm. Technically we should never run here in between those two updates, because interrupts are disabled during the entire context switch operation. But some day we might like to leave interrupts enabled during the context switch and this change allows that to happen without any surprises. Signed-off-by: David S. Miller --- arch/sparc64/kernel/smp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 7dc28a484268..8175a6968c6b 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -830,9 +830,16 @@ void smp_call_function_client(int irq, struct pt_regs *regs) static void tsb_sync(void *info) { + struct trap_per_cpu *tp = &trap_block[raw_smp_processor_id()]; struct mm_struct *mm = info; - if (current->active_mm == mm) + /* It is not valid to test "currrent->active_mm == mm" here. + * + * The value of "current" is not changed atomically with + * switch_mm(). But that's OK, we just need to check the + * current cpu's trap block PGD physical address. + */ + if (tp->pgd_paddr == __pa(mm->pgd)) tsb_context_switch(mm); } From 73c50a27a453a5ed0d21ff23bd67c1dd6d864cb8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Mar 2006 13:32:24 -0800 Subject: [PATCH 2/6] [SPARC64]: Document the instruction checks we do in do_sparc64_fault(). Signed-off-by: David S. Miller --- arch/sparc64/mm/fault.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 0db2f7d9fab5..6e002aacb961 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -327,8 +327,12 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) insn = get_fault_insn(regs, 0); if (!insn) goto continue_fault; + /* All loads, stores and atomics have bits 30 and 31 both set + * in the instruction. Bit 21 is set in all stores, but we + * have to avoid prefetches which also have bit 21 set. + */ if ((insn & 0xc0200000) == 0xc0200000 && - (insn & 0x1780000) != 0x1680000) { + (insn & 0x01780000) != 0x01680000) { /* Don't bother updating thread struct value, * because update_mmu_cache only cares which tlb * the access came from. From 9df1dab1df58ef20ef7df9b8f39d86cf5d2d1949 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 31 Mar 2006 00:36:25 -0800 Subject: [PATCH 3/6] [SPARC64]: Align address in huge_pte_alloc(). We are about to fill in all HPAGE_SIZE's worth of PAGE_SIZE ptes, so we have to give the first pte in that set else we scribble over random memory when we fill in the ptes. Signed-off-by: David S. Miller --- arch/sparc64/mm/hugetlbpage.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 074620d413d4..fbbbebbad8a4 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -198,6 +198,13 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) pmd_t *pmd; pte_t *pte = NULL; + /* We must align the address, because our caller will run + * set_huge_pte_at() on whatever we return, which writes out + * all of the sub-ptes for the hugepage range. So we have + * to give it the first such sub-pte. + */ + addr &= HPAGE_MASK; + pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); if (pud) { From 3cc1cc444f4c058deae9d5113ebb80e798c3076e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 31 Mar 2006 01:41:17 -0800 Subject: [PATCH 4/6] [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 900fb0b940d8..30389085a359 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16 -# Sun Mar 26 14:58:11 2006 +# Fri Mar 31 01:40:57 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -180,6 +180,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y CONFIG_INET_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y @@ -203,6 +204,7 @@ CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m +CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m # CONFIG_NETFILTER is not set @@ -308,7 +310,6 @@ CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_UB=m # CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 # CONFIG_BLK_DEV_INITRD is not set CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 @@ -449,6 +450,7 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID5=m +# CONFIG_MD_RAID5_RESHAPE is not set CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m # CONFIG_MD_FAULTY is not set @@ -741,9 +743,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -826,6 +826,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set +# CONFIG_FB_FIRMWARE_EDID is not set CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -1116,6 +1117,11 @@ CONFIG_USB_HIDDEV=y # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + # # Misc Linux/SPARC drivers # From 1339713a327d4538ca9173ab70afef9a1d57fd07 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 31 Mar 2006 02:04:15 -0800 Subject: [PATCH 5/6] [SPARC]: Wire up sys_splice() into the syscall tables. Signed-off-by: David S. Miller --- arch/sparc/kernel/systbls.S | 2 +- arch/sparc64/kernel/sys32.S | 1 + arch/sparc64/kernel/systbls.S | 4 ++-- include/asm-sparc/unistd.h | 2 +- include/asm-sparc64/unistd.h | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 768de64b371f..df33dbf06e8c 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -64,7 +64,7 @@ sys_call_table: /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 -/*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64 +/*230*/ .long sys_select, sys_time, sys_splice, sys_stime, sys_statfs64 /* "We are the Knights of the Forest of Ni!!" */ /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index c4a1cef4b1e5..64d970330ef7 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -136,6 +136,7 @@ SIGN1(sys32_getpeername, sys_getpeername, %o0) SIGN1(sys32_getsockname, sys_getsockname, %o0) SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) +SIGN2(sys32_splice, sys_splice, %o0, %o1) .globl sys32_mmap2 sys32_mmap2: diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 3b250f2318fd..c64f3ed3fcef 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -66,7 +66,7 @@ sys_call_table32: .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 -/*230*/ .word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64 +/*230*/ .word sys32_select, compat_sys_time, sys32_splice, compat_sys_stime, compat_sys_statfs64 .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep @@ -135,7 +135,7 @@ sys_call_table: .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid -/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64 +/*230*/ .word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64 .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 64ec640a40ee..e059cfb815c7 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_oldstat 232 Linux Specific */ +#define __NR_sys_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 a284986b1541..02e1aacd3dab 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_oldstat 232 Linux Specific */ +#define __NR_sys_splice 232 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */ #define __NR_statfs64 234 /* Linux Specific */ #define __NR_fstatfs64 235 /* Linux Specific */ From 289eee6fa78e999208120c856ef3ae5a817fd59c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 31 Mar 2006 23:49:34 -0800 Subject: [PATCH 6/6] [SPARC]: Wire up sys_sync_file_range() into syscall tables. Signed-off-by: David S. Miller --- arch/sparc/kernel/systbls.S | 2 +- arch/sparc64/kernel/sys32.S | 1 + arch/sparc64/kernel/sys_sparc32.c | 8 ++++++++ arch/sparc64/kernel/systbls.S | 4 ++-- include/asm-sparc/unistd.h | 4 ++-- include/asm-sparc64/unistd.h | 2 +- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index df33dbf06e8c..fbbec5e761c6 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -70,7 +70,7 @@ sys_call_table: /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl -/*255*/ .long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep +/*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 64d970330ef7..86dd5cb81e09 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -137,6 +137,7 @@ SIGN1(sys32_getsockname, sys_getsockname, %o0) SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) SIGN2(sys32_splice, sys_splice, %o0, %o1) +SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) .globl sys32_mmap2 sys32_mmap2: diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 2e906bad56fa..31030bf00f1a 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1069,3 +1069,11 @@ long sys32_lookup_dcookie(unsigned long cookie_high, return sys_lookup_dcookie((cookie_high << 32) | cookie_low, buf, len); } + +long compat_sync_file_range(int fd, unsigned long off_high, unsigned long off_low, unsigned long nb_high, unsigned long nb_low, int flags) +{ + return sys_sync_file_range(fd, + (off_high << 32) | off_low, + (nb_high << 32) | nb_low, + flags); +} diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index c64f3ed3fcef..857b82c82875 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -71,7 +71,7 @@ sys_call_table32: /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl - .word sys_ni_syscall, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep + .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink @@ -140,7 +140,7 @@ sys_call_table: /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl - .word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep + .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index e059cfb815c7..264f0ebeaedc 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -180,7 +180,7 @@ #define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS */ #define __NR_getdomainname 162 /* SunOS Specific */ #define __NR_setdomainname 163 /* Common */ -/* #define __NR_ni_syscall 164 ENOSYS under SunOS */ +/* #define __NR_utrap_install 164 Linux sparc64 specific */ #define __NR_quotactl 165 /* Common */ #define __NR_set_tid_address 166 /* Linux specific, exportfs under SunOS */ #define __NR_mount 167 /* Common */ @@ -271,7 +271,7 @@ #define __NR_getsid 252 #define __NR_fdatasync 253 #define __NR_nfsservctl 254 -#define __NR_aplib 255 +#define __NR_sys_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 02e1aacd3dab..d0544b4f47b7 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_aplib 255 +#define __NR_sys_sync_file_range 255 #define __NR_clock_settime 256 #define __NR_clock_gettime 257 #define __NR_clock_getres 258