diff options
Diffstat (limited to 'arch/sparc')
52 files changed, 656 insertions, 916 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 9f2edb5c5551..3d361f236308 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -23,7 +23,6 @@ config SPARC | |||
23 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 23 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
24 | select RTC_CLASS | 24 | select RTC_CLASS |
25 | select RTC_DRV_M48T59 | 25 | select RTC_DRV_M48T59 |
26 | select HAVE_IRQ_WORK | ||
27 | select HAVE_DMA_ATTRS | 26 | select HAVE_DMA_ATTRS |
28 | select HAVE_DMA_API_DEBUG | 27 | select HAVE_DMA_API_DEBUG |
29 | select HAVE_ARCH_JUMP_LABEL | 28 | select HAVE_ARCH_JUMP_LABEL |
@@ -41,12 +40,15 @@ config SPARC | |||
41 | select GENERIC_STRNCPY_FROM_USER | 40 | select GENERIC_STRNCPY_FROM_USER |
42 | select GENERIC_STRNLEN_USER | 41 | select GENERIC_STRNLEN_USER |
43 | select MODULES_USE_ELF_RELA | 42 | select MODULES_USE_ELF_RELA |
43 | select ODD_RT_SIGACTION | ||
44 | select OLD_SIGSUSPEND | ||
44 | 45 | ||
45 | config SPARC32 | 46 | config SPARC32 |
46 | def_bool !64BIT | 47 | def_bool !64BIT |
47 | select GENERIC_ATOMIC64 | 48 | select GENERIC_ATOMIC64 |
48 | select CLZ_TAB | 49 | select CLZ_TAB |
49 | select HAVE_UID16 | 50 | select HAVE_UID16 |
51 | select OLD_SIGACTION | ||
50 | 52 | ||
51 | config SPARC64 | 53 | config SPARC64 |
52 | def_bool 64BIT | 54 | def_bool 64BIT |
@@ -61,6 +63,7 @@ config SPARC64 | |||
61 | select HAVE_MEMBLOCK | 63 | select HAVE_MEMBLOCK |
62 | select HAVE_MEMBLOCK_NODE_MAP | 64 | select HAVE_MEMBLOCK_NODE_MAP |
63 | select HAVE_SYSCALL_WRAPPERS | 65 | select HAVE_SYSCALL_WRAPPERS |
66 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE | ||
64 | select HAVE_DYNAMIC_FTRACE | 67 | select HAVE_DYNAMIC_FTRACE |
65 | select HAVE_FTRACE_MCOUNT_RECORD | 68 | select HAVE_FTRACE_MCOUNT_RECORD |
66 | select HAVE_SYSCALL_TRACEPOINTS | 69 | select HAVE_SYSCALL_TRACEPOINTS |
@@ -81,12 +84,6 @@ config ARCH_DEFCONFIG | |||
81 | default "arch/sparc/configs/sparc32_defconfig" if SPARC32 | 84 | default "arch/sparc/configs/sparc32_defconfig" if SPARC32 |
82 | default "arch/sparc/configs/sparc64_defconfig" if SPARC64 | 85 | default "arch/sparc/configs/sparc64_defconfig" if SPARC64 |
83 | 86 | ||
84 | # CONFIG_BITS can be used at source level to get 32/64 bits | ||
85 | config BITS | ||
86 | int | ||
87 | default 32 if SPARC32 | ||
88 | default 64 if SPARC64 | ||
89 | |||
90 | config IOMMU_HELPER | 87 | config IOMMU_HELPER |
91 | bool | 88 | bool |
92 | default y if SPARC64 | 89 | default y if SPARC64 |
@@ -143,9 +140,6 @@ config GENERIC_GPIO | |||
143 | help | 140 | help |
144 | Generic GPIO API support | 141 | Generic GPIO API support |
145 | 142 | ||
146 | config ARCH_NO_VIRT_TO_BUS | ||
147 | def_bool y | ||
148 | |||
149 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC | 143 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC |
150 | def_bool y if SPARC64 | 144 | def_bool y if SPARC64 |
151 | 145 | ||
@@ -197,7 +191,7 @@ config RWSEM_XCHGADD_ALGORITHM | |||
197 | 191 | ||
198 | config GENERIC_HWEIGHT | 192 | config GENERIC_HWEIGHT |
199 | bool | 193 | bool |
200 | default y if !ULTRA_HAS_POPULATION_COUNT | 194 | default y |
201 | 195 | ||
202 | config GENERIC_CALIBRATE_DELAY | 196 | config GENERIC_CALIBRATE_DELAY |
203 | bool | 197 | bool |
@@ -543,6 +537,7 @@ config COMPAT | |||
543 | select COMPAT_BINFMT_ELF | 537 | select COMPAT_BINFMT_ELF |
544 | select HAVE_UID16 | 538 | select HAVE_UID16 |
545 | select ARCH_WANT_OLD_COMPAT_IPC | 539 | select ARCH_WANT_OLD_COMPAT_IPC |
540 | select COMPAT_OLD_SIGACTION | ||
546 | 541 | ||
547 | config SYSVIPC_COMPAT | 542 | config SYSVIPC_COMPAT |
548 | bool | 543 | bool |
diff --git a/arch/sparc/include/asm/compat_signal.h b/arch/sparc/include/asm/compat_signal.h index b759eab9b51c..9ed1f128b4d1 100644 --- a/arch/sparc/include/asm/compat_signal.h +++ b/arch/sparc/include/asm/compat_signal.h | |||
@@ -18,12 +18,6 @@ struct __old_sigaction32 { | |||
18 | unsigned int sa_flags; | 18 | unsigned int sa_flags; |
19 | unsigned sa_restorer; /* not used by Linux/SPARC yet */ | 19 | unsigned sa_restorer; /* not used by Linux/SPARC yet */ |
20 | }; | 20 | }; |
21 | |||
22 | typedef struct sigaltstack32 { | ||
23 | u32 ss_sp; | ||
24 | int ss_flags; | ||
25 | compat_size_t ss_size; | ||
26 | } stack_t32; | ||
27 | #endif | 21 | #endif |
28 | 22 | ||
29 | #endif /* !(_COMPAT_SIGNAL_H) */ | 23 | #endif /* !(_COMPAT_SIGNAL_H) */ |
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h index ac74a2c98e6d..a24e41fcdde1 100644 --- a/arch/sparc/include/asm/elf_32.h +++ b/arch/sparc/include/asm/elf_32.h | |||
@@ -128,7 +128,4 @@ typedef struct { | |||
128 | 128 | ||
129 | #define ELF_PLATFORM (NULL) | 129 | #define ELF_PLATFORM (NULL) |
130 | 130 | ||
131 | #define SET_PERSONALITY(ex) \ | ||
132 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
133 | |||
134 | #endif /* !(__ASMSPARC_ELF_H) */ | 131 | #endif /* !(__ASMSPARC_ELF_H) */ |
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index 9661e9bc7bb6..7eb57d245044 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h | |||
@@ -12,7 +12,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | |||
12 | 12 | ||
13 | static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm) | 13 | static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm) |
14 | { | 14 | { |
15 | hugetlb_setup(mm); | ||
16 | } | 15 | } |
17 | 16 | ||
18 | static inline int is_hugepage_only_range(struct mm_struct *mm, | 17 | static inline int is_hugepage_only_range(struct mm_struct *mm, |
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index 4b39f74d6ca0..e15538899f3d 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h | |||
@@ -27,8 +27,8 @@ | |||
27 | #ifndef __ASSEMBLY__ | 27 | #ifndef __ASSEMBLY__ |
28 | 28 | ||
29 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) | 29 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) |
30 | struct mm_struct; | 30 | struct pt_regs; |
31 | extern void hugetlb_setup(struct mm_struct *mm); | 31 | extern void hugetlb_setup(struct pt_regs *regs); |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #define WANT_PAGE_VIRTUAL | 34 | #define WANT_PAGE_VIRTUAL |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 7870be0f5adc..08fcce90316b 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -71,7 +71,6 @@ | |||
71 | #define PMD_PADDR _AC(0xfffffffe,UL) | 71 | #define PMD_PADDR _AC(0xfffffffe,UL) |
72 | #define PMD_PADDR_SHIFT _AC(11,UL) | 72 | #define PMD_PADDR_SHIFT _AC(11,UL) |
73 | 73 | ||
74 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
75 | #define PMD_ISHUGE _AC(0x00000001,UL) | 74 | #define PMD_ISHUGE _AC(0x00000001,UL) |
76 | 75 | ||
77 | /* This is the PMD layout when PMD_ISHUGE is set. With 4MB huge | 76 | /* This is the PMD layout when PMD_ISHUGE is set. With 4MB huge |
@@ -86,7 +85,6 @@ | |||
86 | #define PMD_HUGE_ACCESSED _AC(0x00000080,UL) | 85 | #define PMD_HUGE_ACCESSED _AC(0x00000080,UL) |
87 | #define PMD_HUGE_EXEC _AC(0x00000040,UL) | 86 | #define PMD_HUGE_EXEC _AC(0x00000040,UL) |
88 | #define PMD_HUGE_SPLITTING _AC(0x00000020,UL) | 87 | #define PMD_HUGE_SPLITTING _AC(0x00000020,UL) |
89 | #endif | ||
90 | 88 | ||
91 | /* PGDs point to PMD tables which are 8K aligned. */ | 89 | /* PGDs point to PMD tables which are 8K aligned. */ |
92 | #define PGD_PADDR _AC(0xfffffffc,UL) | 90 | #define PGD_PADDR _AC(0xfffffffc,UL) |
@@ -628,6 +626,12 @@ static inline unsigned long pte_special(pte_t pte) | |||
628 | return pte_val(pte) & _PAGE_SPECIAL; | 626 | return pte_val(pte) & _PAGE_SPECIAL; |
629 | } | 627 | } |
630 | 628 | ||
629 | static inline int pmd_large(pmd_t pmd) | ||
630 | { | ||
631 | return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) == | ||
632 | (PMD_ISHUGE | PMD_HUGE_PRESENT); | ||
633 | } | ||
634 | |||
631 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 635 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
632 | static inline int pmd_young(pmd_t pmd) | 636 | static inline int pmd_young(pmd_t pmd) |
633 | { | 637 | { |
@@ -646,12 +650,6 @@ static inline unsigned long pmd_pfn(pmd_t pmd) | |||
646 | return val >> (PAGE_SHIFT - PMD_PADDR_SHIFT); | 650 | return val >> (PAGE_SHIFT - PMD_PADDR_SHIFT); |
647 | } | 651 | } |
648 | 652 | ||
649 | static inline int pmd_large(pmd_t pmd) | ||
650 | { | ||
651 | return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) == | ||
652 | (PMD_ISHUGE | PMD_HUGE_PRESENT); | ||
653 | } | ||
654 | |||
655 | static inline int pmd_trans_splitting(pmd_t pmd) | 653 | static inline int pmd_trans_splitting(pmd_t pmd) |
656 | { | 654 | { |
657 | return (pmd_val(pmd) & (PMD_ISHUGE|PMD_HUGE_SPLITTING)) == | 655 | return (pmd_val(pmd) & (PMD_ISHUGE|PMD_HUGE_SPLITTING)) == |
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index c1e01914fd98..2c7baa4c4505 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h | |||
@@ -118,6 +118,7 @@ extern unsigned long get_wchan(struct task_struct *); | |||
118 | extern struct task_struct *last_task_used_math; | 118 | extern struct task_struct *last_task_used_math; |
119 | 119 | ||
120 | #define cpu_relax() barrier() | 120 | #define cpu_relax() barrier() |
121 | extern void (*sparc_idle)(void); | ||
121 | 122 | ||
122 | #endif | 123 | #endif |
123 | 124 | ||
diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h index 77b85850d543..c33ce3f2ba84 100644 --- a/arch/sparc/include/asm/signal.h +++ b/arch/sparc/include/asm/signal.h | |||
@@ -21,10 +21,8 @@ | |||
21 | */ | 21 | */ |
22 | #define SA_STATIC_ALLOC 0x8000 | 22 | #define SA_STATIC_ALLOC 0x8000 |
23 | 23 | ||
24 | struct k_sigaction { | 24 | #define __ARCH_HAS_KA_RESTORER |
25 | struct __new_sigaction sa; | 25 | #define __ARCH_HAS_SA_RESTORER |
26 | void __user *ka_restorer; | ||
27 | }; | ||
28 | 26 | ||
29 | #endif /* !(__ASSEMBLY__) */ | 27 | #endif /* !(__ASSEMBLY__) */ |
30 | #endif /* !(__SPARC_SIGNAL_H) */ | 28 | #endif /* !(__SPARC_SIGNAL_H) */ |
diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h index d06a26601753..6b67e50fb9b4 100644 --- a/arch/sparc/include/asm/spitfire.h +++ b/arch/sparc/include/asm/spitfire.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define SUN4V_CHIP_NIAGARA3 0x03 | 45 | #define SUN4V_CHIP_NIAGARA3 0x03 |
46 | #define SUN4V_CHIP_NIAGARA4 0x04 | 46 | #define SUN4V_CHIP_NIAGARA4 0x04 |
47 | #define SUN4V_CHIP_NIAGARA5 0x05 | 47 | #define SUN4V_CHIP_NIAGARA5 0x05 |
48 | #define SUN4V_CHIP_SPARC64X 0x8a | ||
48 | #define SUN4V_CHIP_UNKNOWN 0xff | 49 | #define SUN4V_CHIP_UNKNOWN 0xff |
49 | 50 | ||
50 | #ifndef __ASSEMBLY__ | 51 | #ifndef __ASSEMBLY__ |
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index b4c258de4443..e696432b950d 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h | |||
@@ -157,17 +157,26 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
157 | andn REG2, 0x7, REG2; \ | 157 | andn REG2, 0x7, REG2; \ |
158 | add REG1, REG2, REG1; | 158 | add REG1, REG2, REG1; |
159 | 159 | ||
160 | /* This macro exists only to make the PMD translator below easier | 160 | /* These macros exists only to make the PMD translator below |
161 | * to read. It hides the ELF section switch for the sun4v code | 161 | * easier to read. It hides the ELF section switch for the |
162 | * patching. | 162 | * sun4v code patching. |
163 | */ | 163 | */ |
164 | #define OR_PTE_BIT(REG, NAME) \ | 164 | #define OR_PTE_BIT_1INSN(REG, NAME) \ |
165 | 661: or REG, _PAGE_##NAME##_4U, REG; \ | 165 | 661: or REG, _PAGE_##NAME##_4U, REG; \ |
166 | .section .sun4v_1insn_patch, "ax"; \ | 166 | .section .sun4v_1insn_patch, "ax"; \ |
167 | .word 661b; \ | 167 | .word 661b; \ |
168 | or REG, _PAGE_##NAME##_4V, REG; \ | 168 | or REG, _PAGE_##NAME##_4V, REG; \ |
169 | .previous; | 169 | .previous; |
170 | 170 | ||
171 | #define OR_PTE_BIT_2INSN(REG, TMP, NAME) \ | ||
172 | 661: sethi %hi(_PAGE_##NAME##_4U), TMP; \ | ||
173 | or REG, TMP, REG; \ | ||
174 | .section .sun4v_2insn_patch, "ax"; \ | ||
175 | .word 661b; \ | ||
176 | mov -1, TMP; \ | ||
177 | or REG, _PAGE_##NAME##_4V, REG; \ | ||
178 | .previous; | ||
179 | |||
171 | /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */ | 180 | /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */ |
172 | #define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \ | 181 | #define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \ |
173 | 661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \ | 182 | 661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \ |
@@ -214,12 +223,13 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
214 | andn REG1, PMD_HUGE_PROTBITS, REG2; \ | 223 | andn REG1, PMD_HUGE_PROTBITS, REG2; \ |
215 | sllx REG2, PMD_PADDR_SHIFT, REG2; \ | 224 | sllx REG2, PMD_PADDR_SHIFT, REG2; \ |
216 | /* REG2 now holds PFN << PAGE_SHIFT */ \ | 225 | /* REG2 now holds PFN << PAGE_SHIFT */ \ |
217 | andcc REG1, PMD_HUGE_EXEC, %g0; \ | 226 | andcc REG1, PMD_HUGE_WRITE, %g0; \ |
218 | bne,a,pt %xcc, 1f; \ | ||
219 | OR_PTE_BIT(REG2, EXEC); \ | ||
220 | 1: andcc REG1, PMD_HUGE_WRITE, %g0; \ | ||
221 | bne,a,pt %xcc, 1f; \ | 227 | bne,a,pt %xcc, 1f; \ |
222 | OR_PTE_BIT(REG2, W); \ | 228 | OR_PTE_BIT_1INSN(REG2, W); \ |
229 | 1: andcc REG1, PMD_HUGE_EXEC, %g0; \ | ||
230 | be,pt %xcc, 1f; \ | ||
231 | nop; \ | ||
232 | OR_PTE_BIT_2INSN(REG2, REG1, EXEC); \ | ||
223 | /* REG1 can now be clobbered, build final PTE */ \ | 233 | /* REG1 can now be clobbered, build final PTE */ \ |
224 | 1: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \ | 234 | 1: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \ |
225 | ba,pt %xcc, PTE_LABEL; \ | 235 | ba,pt %xcc, PTE_LABEL; \ |
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 87ce24c5eb95..5356810bd7e7 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
@@ -38,14 +38,11 @@ | |||
38 | #define __ARCH_WANT_SYS_OLDUMOUNT | 38 | #define __ARCH_WANT_SYS_OLDUMOUNT |
39 | #define __ARCH_WANT_SYS_SIGPENDING | 39 | #define __ARCH_WANT_SYS_SIGPENDING |
40 | #define __ARCH_WANT_SYS_SIGPROCMASK | 40 | #define __ARCH_WANT_SYS_SIGPROCMASK |
41 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
42 | #ifdef __32bit_syscall_numbers__ | 41 | #ifdef __32bit_syscall_numbers__ |
43 | #define __ARCH_WANT_SYS_IPC | 42 | #define __ARCH_WANT_SYS_IPC |
44 | #else | 43 | #else |
45 | #define __ARCH_WANT_COMPAT_SYS_TIME | 44 | #define __ARCH_WANT_COMPAT_SYS_TIME |
46 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | ||
47 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE | 45 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE |
48 | #define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL | ||
49 | #endif | 46 | #endif |
50 | 47 | ||
51 | /* | 48 | /* |
diff --git a/arch/sparc/include/uapi/asm/signal.h b/arch/sparc/include/uapi/asm/signal.h index c4ffd6c97106..f387400fcfdf 100644 --- a/arch/sparc/include/uapi/asm/signal.h +++ b/arch/sparc/include/uapi/asm/signal.h | |||
@@ -153,6 +153,7 @@ struct sigstack { | |||
153 | 153 | ||
154 | #include <asm-generic/signal-defs.h> | 154 | #include <asm-generic/signal-defs.h> |
155 | 155 | ||
156 | #ifndef __KERNEL__ | ||
156 | struct __new_sigaction { | 157 | struct __new_sigaction { |
157 | __sighandler_t sa_handler; | 158 | __sighandler_t sa_handler; |
158 | unsigned long sa_flags; | 159 | unsigned long sa_flags; |
@@ -166,6 +167,7 @@ struct __old_sigaction { | |||
166 | unsigned long sa_flags; | 167 | unsigned long sa_flags; |
167 | void (*sa_restorer)(void); /* not used by Linux/SPARC yet */ | 168 | void (*sa_restorer)(void); /* not used by Linux/SPARC yet */ |
168 | }; | 169 | }; |
170 | #endif | ||
169 | 171 | ||
170 | typedef struct sigaltstack { | 172 | typedef struct sigaltstack { |
171 | void __user *ss_sp; | 173 | void __user *ss_sp; |
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index c83a937ead00..cbbad74b2e06 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #define SO_PEERCRED 0x0040 | 15 | #define SO_PEERCRED 0x0040 |
16 | #define SO_LINGER 0x0080 | 16 | #define SO_LINGER 0x0080 |
17 | #define SO_OOBINLINE 0x0100 | 17 | #define SO_OOBINLINE 0x0100 |
18 | /* To add :#define SO_REUSEPORT 0x0200 */ | 18 | #define SO_REUSEPORT 0x0200 |
19 | #define SO_BSDCOMPAT 0x0400 | 19 | #define SO_BSDCOMPAT 0x0400 |
20 | #define SO_RCVLOWAT 0x0800 | 20 | #define SO_RCVLOWAT 0x0800 |
21 | #define SO_SNDLOWAT 0x1000 | 21 | #define SO_SNDLOWAT 0x1000 |
@@ -66,6 +66,7 @@ | |||
66 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ | 66 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ |
67 | #define SO_NOFCS 0x0027 | 67 | #define SO_NOFCS 0x0027 |
68 | 68 | ||
69 | #define SO_LOCK_FILTER 0x0028 | ||
69 | 70 | ||
70 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | 71 | /* Security levels - as per NRL IPv6 - don't actually do anything */ |
71 | #define SO_SECURITY_AUTHENTICATION 0x5001 | 72 | #define SO_SECURITY_AUTHENTICATION 0x5001 |
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 348fa1aeabce..eefda32b595e 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
21 | #include <asm/auxio.h> | 21 | #include <asm/auxio.h> |
22 | #include <asm/apc.h> | 22 | #include <asm/apc.h> |
23 | #include <asm/processor.h> | ||
23 | 24 | ||
24 | /* Debugging | 25 | /* Debugging |
25 | * | 26 | * |
@@ -158,7 +159,7 @@ static int apc_probe(struct platform_device *op) | |||
158 | 159 | ||
159 | /* Assign power management IDLE handler */ | 160 | /* Assign power management IDLE handler */ |
160 | if (!apc_no_idle) | 161 | if (!apc_no_idle) |
161 | pm_idle = apc_swift_idle; | 162 | sparc_idle = apc_swift_idle; |
162 | 163 | ||
163 | printk(KERN_INFO "%s: power management initialized%s\n", | 164 | printk(KERN_INFO "%s: power management initialized%s\n", |
164 | APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : ""); | 165 | APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : ""); |
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index a6c94a2bf9d4..5c5125895db8 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c | |||
@@ -493,6 +493,12 @@ static void __init sun4v_cpu_probe(void) | |||
493 | sparc_pmu_type = "niagara5"; | 493 | sparc_pmu_type = "niagara5"; |
494 | break; | 494 | break; |
495 | 495 | ||
496 | case SUN4V_CHIP_SPARC64X: | ||
497 | sparc_cpu_type = "SPARC64-X"; | ||
498 | sparc_fpu_type = "SPARC64-X integrated FPU"; | ||
499 | sparc_pmu_type = "sparc64-x"; | ||
500 | break; | ||
501 | |||
496 | default: | 502 | default: |
497 | printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", | 503 | printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", |
498 | prom_cpu_compatible); | 504 | prom_cpu_compatible); |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 21fd1a8f47d2..e2a030045089 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -820,14 +820,6 @@ sys_sparc_pipe: | |||
820 | mov %l5, %o7 | 820 | mov %l5, %o7 |
821 | 821 | ||
822 | .align 4 | 822 | .align 4 |
823 | .globl sys_sigaltstack | ||
824 | sys_sigaltstack: | ||
825 | mov %o7, %l5 | ||
826 | mov %fp, %o2 | ||
827 | call do_sigaltstack | ||
828 | mov %l5, %o7 | ||
829 | |||
830 | .align 4 | ||
831 | .globl sys_sigstack | 823 | .globl sys_sigstack |
832 | sys_sigstack: | 824 | sys_sigstack: |
833 | mov %o7, %l5 | 825 | mov %o7, %l5 |
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 2feb15c35d9e..26b706a1867d 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S | |||
@@ -134,6 +134,8 @@ prom_niagara_prefix: | |||
134 | .asciz "SUNW,UltraSPARC-T" | 134 | .asciz "SUNW,UltraSPARC-T" |
135 | prom_sparc_prefix: | 135 | prom_sparc_prefix: |
136 | .asciz "SPARC-" | 136 | .asciz "SPARC-" |
137 | prom_sparc64x_prefix: | ||
138 | .asciz "SPARC64-X" | ||
137 | .align 4 | 139 | .align 4 |
138 | prom_root_compatible: | 140 | prom_root_compatible: |
139 | .skip 64 | 141 | .skip 64 |
@@ -412,7 +414,7 @@ sun4v_chip_type: | |||
412 | cmp %g2, 'T' | 414 | cmp %g2, 'T' |
413 | be,pt %xcc, 70f | 415 | be,pt %xcc, 70f |
414 | cmp %g2, 'M' | 416 | cmp %g2, 'M' |
415 | bne,pn %xcc, 4f | 417 | bne,pn %xcc, 49f |
416 | nop | 418 | nop |
417 | 419 | ||
418 | 70: ldub [%g1 + 7], %g2 | 420 | 70: ldub [%g1 + 7], %g2 |
@@ -425,7 +427,7 @@ sun4v_chip_type: | |||
425 | cmp %g2, '5' | 427 | cmp %g2, '5' |
426 | be,pt %xcc, 5f | 428 | be,pt %xcc, 5f |
427 | mov SUN4V_CHIP_NIAGARA5, %g4 | 429 | mov SUN4V_CHIP_NIAGARA5, %g4 |
428 | ba,pt %xcc, 4f | 430 | ba,pt %xcc, 49f |
429 | nop | 431 | nop |
430 | 432 | ||
431 | 91: sethi %hi(prom_cpu_compatible), %g1 | 433 | 91: sethi %hi(prom_cpu_compatible), %g1 |
@@ -439,6 +441,25 @@ sun4v_chip_type: | |||
439 | mov SUN4V_CHIP_NIAGARA2, %g4 | 441 | mov SUN4V_CHIP_NIAGARA2, %g4 |
440 | 442 | ||
441 | 4: | 443 | 4: |
444 | /* Athena */ | ||
445 | sethi %hi(prom_cpu_compatible), %g1 | ||
446 | or %g1, %lo(prom_cpu_compatible), %g1 | ||
447 | sethi %hi(prom_sparc64x_prefix), %g7 | ||
448 | or %g7, %lo(prom_sparc64x_prefix), %g7 | ||
449 | mov 9, %g3 | ||
450 | 41: ldub [%g7], %g2 | ||
451 | ldub [%g1], %g4 | ||
452 | cmp %g2, %g4 | ||
453 | bne,pn %icc, 49f | ||
454 | add %g7, 1, %g7 | ||
455 | subcc %g3, 1, %g3 | ||
456 | bne,pt %xcc, 41b | ||
457 | add %g1, 1, %g1 | ||
458 | mov SUN4V_CHIP_SPARC64X, %g4 | ||
459 | ba,pt %xcc, 5f | ||
460 | nop | ||
461 | |||
462 | 49: | ||
442 | mov SUN4V_CHIP_UNKNOWN, %g4 | 463 | mov SUN4V_CHIP_UNKNOWN, %g4 |
443 | 5: sethi %hi(sun4v_chip_type), %g2 | 464 | 5: sethi %hi(sun4v_chip_type), %g2 |
444 | or %g2, %lo(sun4v_chip_type), %g2 | 465 | or %g2, %lo(sun4v_chip_type), %g2 |
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5de9ce0..a702d9ab019c 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h | |||
@@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); | |||
48 | extern void sun4m_unmask_profile_irq(void); | 48 | extern void sun4m_unmask_profile_irq(void); |
49 | extern void sun4m_clear_profile_irq(int cpu); | 49 | extern void sun4m_clear_profile_irq(int cpu); |
50 | 50 | ||
51 | /* sun4m_smp.c */ | ||
52 | void sun4m_cpu_pre_starting(void *arg); | ||
53 | void sun4m_cpu_pre_online(void *arg); | ||
54 | |||
51 | /* sun4d_irq.c */ | 55 | /* sun4d_irq.c */ |
52 | extern spinlock_t sun4d_imsk_lock; | 56 | extern spinlock_t sun4d_imsk_lock; |
53 | 57 | ||
@@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); | |||
60 | extern void sun4d_distribute_irqs(void); | 64 | extern void sun4d_distribute_irqs(void); |
61 | extern void sun4d_free_irq(unsigned int irq, void *dev_id); | 65 | extern void sun4d_free_irq(unsigned int irq, void *dev_id); |
62 | 66 | ||
67 | /* sun4d_smp.c */ | ||
68 | void sun4d_cpu_pre_starting(void *arg); | ||
69 | void sun4d_cpu_pre_online(void *arg); | ||
70 | |||
71 | /* leon_smp.c */ | ||
72 | void leon_cpu_pre_starting(void *arg); | ||
73 | void leon_cpu_pre_online(void *arg); | ||
74 | |||
63 | /* head_32.S */ | 75 | /* head_32.S */ |
64 | extern unsigned int t_nmi[]; | 76 | extern unsigned int t_nmi[]; |
65 | extern unsigned int linux_trap_ipi15_sun4d[]; | 77 | extern unsigned int linux_trap_ipi15_sun4d[]; |
diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c index 2e424a576a36..dcf210811af4 100644 --- a/arch/sparc/kernel/kgdb_32.c +++ b/arch/sparc/kernel/kgdb_32.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/kgdb.h> | 6 | #include <linux/kgdb.h> |
7 | #include <linux/kdebug.h> | 7 | #include <linux/kdebug.h> |
8 | #include <linux/sched.h> | ||
8 | 9 | ||
9 | #include <asm/kdebug.h> | 10 | #include <asm/kdebug.h> |
10 | #include <asm/ptrace.h> | 11 | #include <asm/ptrace.h> |
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index a39d1ba5a119..e72212148d2a 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c | |||
@@ -511,7 +511,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
511 | { | 511 | { |
512 | struct kretprobe_instance *ri = NULL; | 512 | struct kretprobe_instance *ri = NULL; |
513 | struct hlist_head *head, empty_rp; | 513 | struct hlist_head *head, empty_rp; |
514 | struct hlist_node *node, *tmp; | 514 | struct hlist_node *tmp; |
515 | unsigned long flags, orig_ret_address = 0; | 515 | unsigned long flags, orig_ret_address = 0; |
516 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; | 516 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; |
517 | 517 | ||
@@ -531,7 +531,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
531 | * real return address, and all the rest will point to | 531 | * real return address, and all the rest will point to |
532 | * kretprobe_trampoline | 532 | * kretprobe_trampoline |
533 | */ | 533 | */ |
534 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | 534 | hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
535 | if (ri->task != current) | 535 | if (ri->task != current) |
536 | /* another task is sharing our hash bucket */ | 536 | /* another task is sharing our hash bucket */ |
537 | continue; | 537 | continue; |
@@ -559,7 +559,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
559 | kretprobe_hash_unlock(current, &flags); | 559 | kretprobe_hash_unlock(current, &flags); |
560 | preempt_enable_no_resched(); | 560 | preempt_enable_no_resched(); |
561 | 561 | ||
562 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | 562 | hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
563 | hlist_del(&ri->hlist); | 563 | hlist_del(&ri->hlist); |
564 | kfree(ri); | 564 | kfree(ri); |
565 | } | 565 | } |
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 9fcc6b4e93b3..54df554b82d9 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -953,9 +953,8 @@ static HLIST_HEAD(ldc_channel_list); | |||
953 | static int __ldc_channel_exists(unsigned long id) | 953 | static int __ldc_channel_exists(unsigned long id) |
954 | { | 954 | { |
955 | struct ldc_channel *lp; | 955 | struct ldc_channel *lp; |
956 | struct hlist_node *n; | ||
957 | 956 | ||
958 | hlist_for_each_entry(lp, n, &ldc_channel_list, list) { | 957 | hlist_for_each_entry(lp, &ldc_channel_list, list) { |
959 | if (lp->id == id) | 958 | if (lp->id == id) |
960 | return 1; | 959 | return 1; |
961 | } | 960 | } |
diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index fc4320886a3a..4d1487138d26 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c | |||
@@ -186,6 +186,8 @@ struct grpci2_cap_first { | |||
186 | #define CAP9_IOMAP_OFS 0x20 | 186 | #define CAP9_IOMAP_OFS 0x20 |
187 | #define CAP9_BARSIZE_OFS 0x24 | 187 | #define CAP9_BARSIZE_OFS 0x24 |
188 | 188 | ||
189 | #define TGT 256 | ||
190 | |||
189 | struct grpci2_priv { | 191 | struct grpci2_priv { |
190 | struct leon_pci_info info; /* must be on top of this structure */ | 192 | struct leon_pci_info info; /* must be on top of this structure */ |
191 | struct grpci2_regs *regs; | 193 | struct grpci2_regs *regs; |
@@ -237,8 +239,12 @@ static int grpci2_cfg_r32(struct grpci2_priv *priv, unsigned int bus, | |||
237 | if (where & 0x3) | 239 | if (where & 0x3) |
238 | return -EINVAL; | 240 | return -EINVAL; |
239 | 241 | ||
240 | if (bus == 0 && PCI_SLOT(devfn) != 0) | 242 | if (bus == 0) { |
241 | devfn += (0x8 * 6); | 243 | devfn += (0x8 * 6); /* start at AD16=Device0 */ |
244 | } else if (bus == TGT) { | ||
245 | bus = 0; | ||
246 | devfn = 0; /* special case: bridge controller itself */ | ||
247 | } | ||
242 | 248 | ||
243 | /* Select bus */ | 249 | /* Select bus */ |
244 | spin_lock_irqsave(&grpci2_dev_lock, flags); | 250 | spin_lock_irqsave(&grpci2_dev_lock, flags); |
@@ -303,8 +309,12 @@ static int grpci2_cfg_w32(struct grpci2_priv *priv, unsigned int bus, | |||
303 | if (where & 0x3) | 309 | if (where & 0x3) |
304 | return -EINVAL; | 310 | return -EINVAL; |
305 | 311 | ||
306 | if (bus == 0 && PCI_SLOT(devfn) != 0) | 312 | if (bus == 0) { |
307 | devfn += (0x8 * 6); | 313 | devfn += (0x8 * 6); /* start at AD16=Device0 */ |
314 | } else if (bus == TGT) { | ||
315 | bus = 0; | ||
316 | devfn = 0; /* special case: bridge controller itself */ | ||
317 | } | ||
308 | 318 | ||
309 | /* Select bus */ | 319 | /* Select bus */ |
310 | spin_lock_irqsave(&grpci2_dev_lock, flags); | 320 | spin_lock_irqsave(&grpci2_dev_lock, flags); |
@@ -368,7 +378,7 @@ static int grpci2_read_config(struct pci_bus *bus, unsigned int devfn, | |||
368 | unsigned int busno = bus->number; | 378 | unsigned int busno = bus->number; |
369 | int ret; | 379 | int ret; |
370 | 380 | ||
371 | if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0)) { | 381 | if (PCI_SLOT(devfn) > 15 || busno > 255) { |
372 | *val = ~0; | 382 | *val = ~0; |
373 | return 0; | 383 | return 0; |
374 | } | 384 | } |
@@ -406,7 +416,7 @@ static int grpci2_write_config(struct pci_bus *bus, unsigned int devfn, | |||
406 | struct grpci2_priv *priv = grpci2priv; | 416 | struct grpci2_priv *priv = grpci2priv; |
407 | unsigned int busno = bus->number; | 417 | unsigned int busno = bus->number; |
408 | 418 | ||
409 | if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0)) | 419 | if (PCI_SLOT(devfn) > 15 || busno > 255) |
410 | return 0; | 420 | return 0; |
411 | 421 | ||
412 | #ifdef GRPCI2_DEBUG_CFGACCESS | 422 | #ifdef GRPCI2_DEBUG_CFGACCESS |
@@ -578,15 +588,15 @@ void grpci2_hw_init(struct grpci2_priv *priv) | |||
578 | REGSTORE(regs->ahbmst_map[i], priv->pci_area); | 588 | REGSTORE(regs->ahbmst_map[i], priv->pci_area); |
579 | 589 | ||
580 | /* Get the GRPCI2 Host PCI ID */ | 590 | /* Get the GRPCI2 Host PCI ID */ |
581 | grpci2_cfg_r32(priv, 0, 0, PCI_VENDOR_ID, &priv->pciid); | 591 | grpci2_cfg_r32(priv, TGT, 0, PCI_VENDOR_ID, &priv->pciid); |
582 | 592 | ||
583 | /* Get address to first (always defined) capability structure */ | 593 | /* Get address to first (always defined) capability structure */ |
584 | grpci2_cfg_r8(priv, 0, 0, PCI_CAPABILITY_LIST, &capptr); | 594 | grpci2_cfg_r8(priv, TGT, 0, PCI_CAPABILITY_LIST, &capptr); |
585 | 595 | ||
586 | /* Enable/Disable Byte twisting */ | 596 | /* Enable/Disable Byte twisting */ |
587 | grpci2_cfg_r32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, &io_map); | 597 | grpci2_cfg_r32(priv, TGT, 0, capptr+CAP9_IOMAP_OFS, &io_map); |
588 | io_map = (io_map & ~0x1) | (priv->bt_enabled ? 1 : 0); | 598 | io_map = (io_map & ~0x1) | (priv->bt_enabled ? 1 : 0); |
589 | grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, io_map); | 599 | grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_IOMAP_OFS, io_map); |
590 | 600 | ||
591 | /* Setup the Host's PCI Target BARs for other peripherals to access, | 601 | /* Setup the Host's PCI Target BARs for other peripherals to access, |
592 | * and do DMA to the host's memory. The target BARs can be sized and | 602 | * and do DMA to the host's memory. The target BARs can be sized and |
@@ -617,17 +627,18 @@ void grpci2_hw_init(struct grpci2_priv *priv) | |||
617 | pciadr = 0; | 627 | pciadr = 0; |
618 | } | 628 | } |
619 | } | 629 | } |
620 | grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BARSIZE_OFS+i*4, bar_sz); | 630 | grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_BARSIZE_OFS+i*4, |
621 | grpci2_cfg_w32(priv, 0, 0, PCI_BASE_ADDRESS_0+i*4, pciadr); | 631 | bar_sz); |
622 | grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr); | 632 | grpci2_cfg_w32(priv, TGT, 0, PCI_BASE_ADDRESS_0+i*4, pciadr); |
633 | grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr); | ||
623 | printk(KERN_INFO " TGT BAR[%d]: 0x%08x (PCI)-> 0x%08x\n", | 634 | printk(KERN_INFO " TGT BAR[%d]: 0x%08x (PCI)-> 0x%08x\n", |
624 | i, pciadr, ahbadr); | 635 | i, pciadr, ahbadr); |
625 | } | 636 | } |
626 | 637 | ||
627 | /* set as bus master and enable pci memory responses */ | 638 | /* set as bus master and enable pci memory responses */ |
628 | grpci2_cfg_r32(priv, 0, 0, PCI_COMMAND, &data); | 639 | grpci2_cfg_r32(priv, TGT, 0, PCI_COMMAND, &data); |
629 | data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); | 640 | data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); |
630 | grpci2_cfg_w32(priv, 0, 0, PCI_COMMAND, data); | 641 | grpci2_cfg_w32(priv, TGT, 0, PCI_COMMAND, data); |
631 | 642 | ||
632 | /* Enable Error respone (CPU-TRAP) on illegal memory access. */ | 643 | /* Enable Error respone (CPU-TRAP) on illegal memory access. */ |
633 | REGSTORE(regs->ctrl, CTRL_ER | CTRL_PE); | 644 | REGSTORE(regs->ctrl, CTRL_ER | CTRL_PE); |
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index 4e174321097d..708bca435219 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <asm/leon_amba.h> | 9 | #include <asm/leon_amba.h> |
10 | #include <asm/cpu_type.h> | 10 | #include <asm/cpu_type.h> |
11 | #include <asm/leon.h> | 11 | #include <asm/leon.h> |
12 | #include <asm/processor.h> | ||
12 | 13 | ||
13 | /* List of Systems that need fixup instructions around power-down instruction */ | 14 | /* List of Systems that need fixup instructions around power-down instruction */ |
14 | unsigned int pmc_leon_fixup_ids[] = { | 15 | unsigned int pmc_leon_fixup_ids[] = { |
@@ -69,9 +70,9 @@ static int __init leon_pmc_install(void) | |||
69 | if (sparc_cpu_model == sparc_leon) { | 70 | if (sparc_cpu_model == sparc_leon) { |
70 | /* Assign power management IDLE handler */ | 71 | /* Assign power management IDLE handler */ |
71 | if (pmc_leon_need_fixup()) | 72 | if (pmc_leon_need_fixup()) |
72 | pm_idle = pmc_leon_idle_fixup; | 73 | sparc_idle = pmc_leon_idle_fixup; |
73 | else | 74 | else |
74 | pm_idle = pmc_leon_idle; | 75 | sparc_idle = pmc_leon_idle; |
75 | 76 | ||
76 | printk(KERN_INFO "leon: power management initialized\n"); | 77 | printk(KERN_INFO "leon: power management initialized\n"); |
77 | } | 78 | } |
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d9c8ef..9b40c9c12a0c 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c | |||
@@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, | |||
69 | return val; | 69 | return val; |
70 | } | 70 | } |
71 | 71 | ||
72 | void __cpuinit leon_callin(void) | 72 | void __cpuinit leon_cpu_pre_starting(void *arg) |
73 | { | 73 | { |
74 | int cpuid = hard_smp_processor_id(); | ||
75 | |||
76 | local_ops->cache_all(); | ||
77 | local_ops->tlb_all(); | ||
78 | leon_configure_cache_smp(); | 74 | leon_configure_cache_smp(); |
75 | } | ||
79 | 76 | ||
80 | notify_cpu_starting(cpuid); | 77 | void __cpuinit leon_cpu_pre_online(void *arg) |
81 | 78 | { | |
82 | /* Get our local ticker going. */ | 79 | int cpuid = hard_smp_processor_id(); |
83 | register_percpu_ce(cpuid); | ||
84 | |||
85 | calibrate_delay(); | ||
86 | smp_store_cpu_info(cpuid); | ||
87 | |||
88 | local_ops->cache_all(); | ||
89 | local_ops->tlb_all(); | ||
90 | 80 | ||
91 | /* | 81 | /* Allow master to continue. The master will then give us the |
92 | * Unblock the master CPU _only_ when the scheduler state | 82 | * go-ahead by setting the smp_commenced_mask and will wait without |
93 | * of all secondary CPUs will be up-to-date, so after | 83 | * timeouts until our setup is completed fully (signified by |
94 | * the SMP initialization the master will be just allowed | 84 | * our bit being set in the cpu_online_mask). |
95 | * to call the scheduler code. | ||
96 | * Allow master to continue. | ||
97 | */ | 85 | */ |
98 | do_swap(&cpu_callin_map[cpuid], 1); | 86 | do_swap(&cpu_callin_map[cpuid], 1); |
99 | 87 | ||
@@ -110,9 +98,6 @@ void __cpuinit leon_callin(void) | |||
110 | 98 | ||
111 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) | 99 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) |
112 | mb(); | 100 | mb(); |
113 | |||
114 | local_irq_enable(); | ||
115 | set_cpu_online(cpuid, true); | ||
116 | } | 101 | } |
117 | 102 | ||
118 | /* | 103 | /* |
diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index dcbb62f63068..8b7297faca79 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/oplib.h> | 17 | #include <asm/oplib.h> |
18 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
19 | #include <asm/auxio.h> | 19 | #include <asm/auxio.h> |
20 | #include <asm/processor.h> | ||
20 | 21 | ||
21 | /* Debug | 22 | /* Debug |
22 | * | 23 | * |
@@ -63,7 +64,7 @@ static int pmc_probe(struct platform_device *op) | |||
63 | 64 | ||
64 | #ifndef PMC_NO_IDLE | 65 | #ifndef PMC_NO_IDLE |
65 | /* Assign power management IDLE handler */ | 66 | /* Assign power management IDLE handler */ |
66 | pm_idle = pmc_swift_idle; | 67 | sparc_idle = pmc_swift_idle; |
67 | #endif | 68 | #endif |
68 | 69 | ||
69 | printk(KERN_INFO "%s: power management initialized\n", PMC_DEVNAME); | 70 | printk(KERN_INFO "%s: power management initialized\n", PMC_DEVNAME); |
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index be8e862badaf..62eede13831a 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -43,8 +43,7 @@ | |||
43 | * Power management idle function | 43 | * Power management idle function |
44 | * Set in pm platform drivers (apc.c and pmc.c) | 44 | * Set in pm platform drivers (apc.c and pmc.c) |
45 | */ | 45 | */ |
46 | void (*pm_idle)(void); | 46 | void (*sparc_idle)(void); |
47 | EXPORT_SYMBOL(pm_idle); | ||
48 | 47 | ||
49 | /* | 48 | /* |
50 | * Power-off handler instantiation for pm.h compliance | 49 | * Power-off handler instantiation for pm.h compliance |
@@ -75,8 +74,8 @@ void cpu_idle(void) | |||
75 | /* endless idle loop with no priority at all */ | 74 | /* endless idle loop with no priority at all */ |
76 | for (;;) { | 75 | for (;;) { |
77 | while (!need_resched()) { | 76 | while (!need_resched()) { |
78 | if (pm_idle) | 77 | if (sparc_idle) |
79 | (*pm_idle)(); | 78 | (*sparc_idle)(); |
80 | else | 79 | else |
81 | cpu_relax(); | 80 | cpu_relax(); |
82 | } | 81 | } |
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 1303021748c8..9f20566b0773 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c | |||
@@ -64,7 +64,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len | |||
64 | err = -ENODEV; | 64 | err = -ENODEV; |
65 | 65 | ||
66 | mutex_lock(&of_set_property_mutex); | 66 | mutex_lock(&of_set_property_mutex); |
67 | write_lock(&devtree_lock); | 67 | raw_spin_lock(&devtree_lock); |
68 | prevp = &dp->properties; | 68 | prevp = &dp->properties; |
69 | while (*prevp) { | 69 | while (*prevp) { |
70 | struct property *prop = *prevp; | 70 | struct property *prop = *prevp; |
@@ -91,7 +91,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len | |||
91 | } | 91 | } |
92 | prevp = &(*prevp)->next; | 92 | prevp = &(*prevp)->next; |
93 | } | 93 | } |
94 | write_unlock(&devtree_lock); | 94 | raw_spin_unlock(&devtree_lock); |
95 | mutex_unlock(&of_set_property_mutex); | 95 | mutex_unlock(&of_set_property_mutex); |
96 | 96 | ||
97 | /* XXX Upate procfs if necessary... */ | 97 | /* XXX Upate procfs if necessary... */ |
diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index 1271b3a27d4e..be5bdf93c767 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c | |||
@@ -554,10 +554,8 @@ static void __init sbus_iommu_init(struct platform_device *op) | |||
554 | regs = pr->phys_addr; | 554 | regs = pr->phys_addr; |
555 | 555 | ||
556 | iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); | 556 | iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); |
557 | if (!iommu) | ||
558 | goto fatal_memory_error; | ||
559 | strbuf = kzalloc(sizeof(*strbuf), GFP_ATOMIC); | 557 | strbuf = kzalloc(sizeof(*strbuf), GFP_ATOMIC); |
560 | if (!strbuf) | 558 | if (!iommu || !strbuf) |
561 | goto fatal_memory_error; | 559 | goto fatal_memory_error; |
562 | 560 | ||
563 | op->dev.archdata.iommu = iommu; | 561 | op->dev.archdata.iommu = iommu; |
@@ -656,6 +654,8 @@ static void __init sbus_iommu_init(struct platform_device *op) | |||
656 | return; | 654 | return; |
657 | 655 | ||
658 | fatal_memory_error: | 656 | fatal_memory_error: |
657 | kfree(iommu); | ||
658 | kfree(strbuf); | ||
659 | prom_printf("sbus_iommu_init: Fatal memory allocation error.\n"); | 659 | prom_printf("sbus_iommu_init: Fatal memory allocation error.\n"); |
660 | } | 660 | } |
661 | 661 | ||
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 0eaf0059aaef..88a127b9c69e 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -115,7 +115,7 @@ static void __init process_switch(char c) | |||
115 | break; | 115 | break; |
116 | } | 116 | } |
117 | cheetah_pcache_forced_on = 1; | 117 | cheetah_pcache_forced_on = 1; |
118 | add_taint(TAINT_MACHINE_CHECK); | 118 | add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); |
119 | cheetah_enable_pcache(); | 119 | cheetah_enable_pcache(); |
120 | break; | 120 | break; |
121 | 121 | ||
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 53e48f721ce3..b524f91dd0e5 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -61,7 +61,7 @@ struct rt_signal_frame32 { | |||
61 | compat_sigset_t mask; | 61 | compat_sigset_t mask; |
62 | /* __siginfo_fpu_t * */ u32 fpu_save; | 62 | /* __siginfo_fpu_t * */ u32 fpu_save; |
63 | unsigned int insns[2]; | 63 | unsigned int insns[2]; |
64 | stack_t32 stack; | 64 | compat_stack_t stack; |
65 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ | 65 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ |
66 | /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ | 66 | /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ |
67 | siginfo_extra_v8plus_t v8plus; | 67 | siginfo_extra_v8plus_t v8plus; |
@@ -230,13 +230,11 @@ segv: | |||
230 | asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | 230 | asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) |
231 | { | 231 | { |
232 | struct rt_signal_frame32 __user *sf; | 232 | struct rt_signal_frame32 __user *sf; |
233 | unsigned int psr, pc, npc, u_ss_sp; | 233 | unsigned int psr, pc, npc; |
234 | compat_uptr_t fpu_save; | 234 | compat_uptr_t fpu_save; |
235 | compat_uptr_t rwin_save; | 235 | compat_uptr_t rwin_save; |
236 | mm_segment_t old_fs; | ||
237 | sigset_t set; | 236 | sigset_t set; |
238 | compat_sigset_t seta; | 237 | compat_sigset_t seta; |
239 | stack_t st; | ||
240 | int err, i; | 238 | int err, i; |
241 | 239 | ||
242 | /* Always make any pending restarted system calls return -EINTR */ | 240 | /* Always make any pending restarted system calls return -EINTR */ |
@@ -295,20 +293,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | |||
295 | if (!err && fpu_save) | 293 | if (!err && fpu_save) |
296 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); | 294 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); |
297 | err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); | 295 | err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); |
298 | err |= __get_user(u_ss_sp, &sf->stack.ss_sp); | 296 | err |= compat_restore_altstack(&sf->stack); |
299 | st.ss_sp = compat_ptr(u_ss_sp); | ||
300 | err |= __get_user(st.ss_flags, &sf->stack.ss_flags); | ||
301 | err |= __get_user(st.ss_size, &sf->stack.ss_size); | ||
302 | if (err) | 297 | if (err) |
303 | goto segv; | 298 | goto segv; |
304 | 299 | ||
305 | /* It is more difficult to avoid calling this function than to | ||
306 | call it and ignore errors. */ | ||
307 | old_fs = get_fs(); | ||
308 | set_fs(KERNEL_DS); | ||
309 | do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); | ||
310 | set_fs(old_fs); | ||
311 | |||
312 | err |= __get_user(rwin_save, &sf->rwin_save); | 300 | err |= __get_user(rwin_save, &sf->rwin_save); |
313 | if (!err && rwin_save) { | 301 | if (!err && rwin_save) { |
314 | if (restore_rwin_state(compat_ptr(rwin_save))) | 302 | if (restore_rwin_state(compat_ptr(rwin_save))) |
@@ -335,7 +323,7 @@ static int invalid_frame_pointer(void __user *fp, int fplen) | |||
335 | return 0; | 323 | return 0; |
336 | } | 324 | } |
337 | 325 | ||
338 | static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) | 326 | static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) |
339 | { | 327 | { |
340 | unsigned long sp; | 328 | unsigned long sp; |
341 | 329 | ||
@@ -350,12 +338,7 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns | |||
350 | return (void __user *) -1L; | 338 | return (void __user *) -1L; |
351 | 339 | ||
352 | /* This is the X/Open sanctioned signal stack switching. */ | 340 | /* This is the X/Open sanctioned signal stack switching. */ |
353 | if (sa->sa_flags & SA_ONSTACK) { | 341 | sp = sigsp(sp, ksig) - framesize; |
354 | if (sas_ss_flags(sp) == 0) | ||
355 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
356 | } | ||
357 | |||
358 | sp -= framesize; | ||
359 | 342 | ||
360 | /* Always align the stack frame. This handles two cases. First, | 343 | /* Always align the stack frame. This handles two cases. First, |
361 | * sigaltstack need not be mindful of platform specific stack | 344 | * sigaltstack need not be mindful of platform specific stack |
@@ -426,8 +409,8 @@ out_irqs_on: | |||
426 | 409 | ||
427 | } | 410 | } |
428 | 411 | ||
429 | static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 412 | static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs, |
430 | int signo, sigset_t *oldset) | 413 | sigset_t *oldset) |
431 | { | 414 | { |
432 | struct signal_frame32 __user *sf; | 415 | struct signal_frame32 __user *sf; |
433 | int i, err, wsaved; | 416 | int i, err, wsaved; |
@@ -449,10 +432,12 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
449 | sigframe_size += sizeof(__siginfo_rwin_t); | 432 | sigframe_size += sizeof(__siginfo_rwin_t); |
450 | 433 | ||
451 | sf = (struct signal_frame32 __user *) | 434 | sf = (struct signal_frame32 __user *) |
452 | get_sigframe(&ka->sa, regs, sigframe_size); | 435 | get_sigframe(ksig, regs, sigframe_size); |
453 | 436 | ||
454 | if (invalid_frame_pointer(sf, sigframe_size)) | 437 | if (invalid_frame_pointer(sf, sigframe_size)) { |
455 | goto sigill; | 438 | do_exit(SIGILL); |
439 | return -EINVAL; | ||
440 | } | ||
456 | 441 | ||
457 | tail = (sf + 1); | 442 | tail = (sf + 1); |
458 | 443 | ||
@@ -526,16 +511,16 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
526 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); | 511 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); |
527 | } | 512 | } |
528 | if (err) | 513 | if (err) |
529 | goto sigsegv; | 514 | return err; |
530 | 515 | ||
531 | /* 3. signal handler back-trampoline and parameters */ | 516 | /* 3. signal handler back-trampoline and parameters */ |
532 | regs->u_regs[UREG_FP] = (unsigned long) sf; | 517 | regs->u_regs[UREG_FP] = (unsigned long) sf; |
533 | regs->u_regs[UREG_I0] = signo; | 518 | regs->u_regs[UREG_I0] = ksig->sig; |
534 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 519 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
535 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; | 520 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; |
536 | 521 | ||
537 | /* 4. signal handler */ | 522 | /* 4. signal handler */ |
538 | regs->tpc = (unsigned long) ka->sa.sa_handler; | 523 | regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; |
539 | regs->tnpc = (regs->tpc + 4); | 524 | regs->tnpc = (regs->tpc + 4); |
540 | if (test_thread_flag(TIF_32BIT)) { | 525 | if (test_thread_flag(TIF_32BIT)) { |
541 | regs->tpc &= 0xffffffff; | 526 | regs->tpc &= 0xffffffff; |
@@ -543,8 +528,8 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
543 | } | 528 | } |
544 | 529 | ||
545 | /* 5. return to kernel instructions */ | 530 | /* 5. return to kernel instructions */ |
546 | if (ka->ka_restorer) { | 531 | if (ksig->ka.ka_restorer) { |
547 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 532 | regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; |
548 | } else { | 533 | } else { |
549 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 534 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
550 | 535 | ||
@@ -553,23 +538,14 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
553 | err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ | 538 | err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ |
554 | err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ | 539 | err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ |
555 | if (err) | 540 | if (err) |
556 | goto sigsegv; | 541 | return err; |
557 | flush_signal_insns(address); | 542 | flush_signal_insns(address); |
558 | } | 543 | } |
559 | return 0; | 544 | return 0; |
560 | |||
561 | sigill: | ||
562 | do_exit(SIGILL); | ||
563 | return -EINVAL; | ||
564 | |||
565 | sigsegv: | ||
566 | force_sigsegv(signo, current); | ||
567 | return -EFAULT; | ||
568 | } | 545 | } |
569 | 546 | ||
570 | static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 547 | static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs, |
571 | unsigned long signr, sigset_t *oldset, | 548 | sigset_t *oldset) |
572 | siginfo_t *info) | ||
573 | { | 549 | { |
574 | struct rt_signal_frame32 __user *sf; | 550 | struct rt_signal_frame32 __user *sf; |
575 | int i, err, wsaved; | 551 | int i, err, wsaved; |
@@ -591,10 +567,12 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
591 | sigframe_size += sizeof(__siginfo_rwin_t); | 567 | sigframe_size += sizeof(__siginfo_rwin_t); |
592 | 568 | ||
593 | sf = (struct rt_signal_frame32 __user *) | 569 | sf = (struct rt_signal_frame32 __user *) |
594 | get_sigframe(&ka->sa, regs, sigframe_size); | 570 | get_sigframe(ksig, regs, sigframe_size); |
595 | 571 | ||
596 | if (invalid_frame_pointer(sf, sigframe_size)) | 572 | if (invalid_frame_pointer(sf, sigframe_size)) { |
597 | goto sigill; | 573 | do_exit(SIGILL); |
574 | return -EINVAL; | ||
575 | } | ||
598 | 576 | ||
599 | tail = (sf + 1); | 577 | tail = (sf + 1); |
600 | 578 | ||
@@ -639,12 +617,10 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
639 | } | 617 | } |
640 | 618 | ||
641 | /* Update the siginfo structure. */ | 619 | /* Update the siginfo structure. */ |
642 | err |= copy_siginfo_to_user32(&sf->info, info); | 620 | err |= copy_siginfo_to_user32(&sf->info, &ksig->info); |
643 | 621 | ||
644 | /* Setup sigaltstack */ | 622 | /* Setup sigaltstack */ |
645 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 623 | err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]); |
646 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | ||
647 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | ||
648 | 624 | ||
649 | switch (_NSIG_WORDS) { | 625 | switch (_NSIG_WORDS) { |
650 | case 4: seta.sig[7] = (oldset->sig[3] >> 32); | 626 | case 4: seta.sig[7] = (oldset->sig[3] >> 32); |
@@ -674,16 +650,16 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
674 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); | 650 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); |
675 | } | 651 | } |
676 | if (err) | 652 | if (err) |
677 | goto sigsegv; | 653 | return err; |
678 | 654 | ||
679 | /* 3. signal handler back-trampoline and parameters */ | 655 | /* 3. signal handler back-trampoline and parameters */ |
680 | regs->u_regs[UREG_FP] = (unsigned long) sf; | 656 | regs->u_regs[UREG_FP] = (unsigned long) sf; |
681 | regs->u_regs[UREG_I0] = signr; | 657 | regs->u_regs[UREG_I0] = ksig->sig; |
682 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 658 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
683 | regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; | 659 | regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; |
684 | 660 | ||
685 | /* 4. signal handler */ | 661 | /* 4. signal handler */ |
686 | regs->tpc = (unsigned long) ka->sa.sa_handler; | 662 | regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; |
687 | regs->tnpc = (regs->tpc + 4); | 663 | regs->tnpc = (regs->tpc + 4); |
688 | if (test_thread_flag(TIF_32BIT)) { | 664 | if (test_thread_flag(TIF_32BIT)) { |
689 | regs->tpc &= 0xffffffff; | 665 | regs->tpc &= 0xffffffff; |
@@ -691,8 +667,8 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
691 | } | 667 | } |
692 | 668 | ||
693 | /* 5. return to kernel instructions */ | 669 | /* 5. return to kernel instructions */ |
694 | if (ka->ka_restorer) | 670 | if (ksig->ka.ka_restorer) |
695 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 671 | regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; |
696 | else { | 672 | else { |
697 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 673 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
698 | 674 | ||
@@ -704,36 +680,25 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
704 | /* t 0x10 */ | 680 | /* t 0x10 */ |
705 | err |= __put_user(0x91d02010, &sf->insns[1]); | 681 | err |= __put_user(0x91d02010, &sf->insns[1]); |
706 | if (err) | 682 | if (err) |
707 | goto sigsegv; | 683 | return err; |
708 | 684 | ||
709 | flush_signal_insns(address); | 685 | flush_signal_insns(address); |
710 | } | 686 | } |
711 | return 0; | 687 | return 0; |
712 | |||
713 | sigill: | ||
714 | do_exit(SIGILL); | ||
715 | return -EINVAL; | ||
716 | |||
717 | sigsegv: | ||
718 | force_sigsegv(signr, current); | ||
719 | return -EFAULT; | ||
720 | } | 688 | } |
721 | 689 | ||
722 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | 690 | static inline void handle_signal32(struct ksignal *ksig, |
723 | siginfo_t *info, | 691 | struct pt_regs *regs) |
724 | sigset_t *oldset, struct pt_regs *regs) | ||
725 | { | 692 | { |
693 | sigset_t *oldset = sigmask_to_save(); | ||
726 | int err; | 694 | int err; |
727 | 695 | ||
728 | if (ka->sa.sa_flags & SA_SIGINFO) | 696 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
729 | err = setup_rt_frame32(ka, regs, signr, oldset, info); | 697 | err = setup_rt_frame32(ksig, regs, oldset); |
730 | else | 698 | else |
731 | err = setup_frame32(ka, regs, signr, oldset); | 699 | err = setup_frame32(ksig, regs, oldset); |
732 | |||
733 | if (err) | ||
734 | return; | ||
735 | 700 | ||
736 | signal_delivered(signr, info, ka, regs, 0); | 701 | signal_setup_done(err, ksig, 0); |
737 | } | 702 | } |
738 | 703 | ||
739 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 704 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
@@ -761,52 +726,43 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs | |||
761 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 726 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
762 | * mistake. | 727 | * mistake. |
763 | */ | 728 | */ |
764 | void do_signal32(sigset_t *oldset, struct pt_regs * regs) | 729 | void do_signal32(struct pt_regs * regs) |
765 | { | 730 | { |
766 | struct k_sigaction ka; | 731 | struct ksignal ksig; |
767 | unsigned long orig_i0; | 732 | unsigned long orig_i0 = 0; |
768 | int restart_syscall; | 733 | int restart_syscall = 0; |
769 | siginfo_t info; | 734 | bool has_handler = get_signal(&ksig); |
770 | int signr; | ||
771 | |||
772 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | ||
773 | 735 | ||
774 | restart_syscall = 0; | ||
775 | orig_i0 = 0; | ||
776 | if (pt_regs_is_syscall(regs) && | 736 | if (pt_regs_is_syscall(regs) && |
777 | (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { | 737 | (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { |
778 | restart_syscall = 1; | 738 | restart_syscall = 1; |
779 | orig_i0 = regs->u_regs[UREG_G6]; | 739 | orig_i0 = regs->u_regs[UREG_G6]; |
780 | } | 740 | } |
781 | 741 | ||
782 | if (signr > 0) { | 742 | if (has_handler) { |
783 | if (restart_syscall) | 743 | if (restart_syscall) |
784 | syscall_restart32(orig_i0, regs, &ka.sa); | 744 | syscall_restart32(orig_i0, regs, &ksig.ka.sa); |
785 | handle_signal32(signr, &ka, &info, oldset, regs); | 745 | handle_signal32(&ksig, regs); |
786 | return; | 746 | } else { |
787 | } | 747 | if (restart_syscall) { |
788 | if (restart_syscall && | 748 | switch (regs->u_regs[UREG_I0]) { |
789 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 749 | case ERESTARTNOHAND: |
790 | regs->u_regs[UREG_I0] == ERESTARTSYS || | 750 | case ERESTARTSYS: |
791 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { | 751 | case ERESTARTNOINTR: |
792 | /* replay the system call when we are done */ | 752 | /* replay the system call when we are done */ |
793 | regs->u_regs[UREG_I0] = orig_i0; | 753 | regs->u_regs[UREG_I0] = orig_i0; |
794 | regs->tpc -= 4; | 754 | regs->tpc -= 4; |
795 | regs->tnpc -= 4; | 755 | regs->tnpc -= 4; |
796 | pt_regs_clear_syscall(regs); | 756 | pt_regs_clear_syscall(regs); |
797 | } | 757 | case ERESTART_RESTARTBLOCK: |
798 | if (restart_syscall && | 758 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
799 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 759 | regs->tpc -= 4; |
800 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 760 | regs->tnpc -= 4; |
801 | regs->tpc -= 4; | 761 | pt_regs_clear_syscall(regs); |
802 | regs->tnpc -= 4; | 762 | } |
803 | pt_regs_clear_syscall(regs); | 763 | } |
764 | restore_saved_sigmask(); | ||
804 | } | 765 | } |
805 | |||
806 | /* If there's no signal to deliver, we just put the saved sigmask | ||
807 | * back | ||
808 | */ | ||
809 | restore_saved_sigmask(); | ||
810 | } | 766 | } |
811 | 767 | ||
812 | struct sigstack32 { | 768 | struct sigstack32 { |
@@ -856,29 +812,3 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp) | |||
856 | out: | 812 | out: |
857 | return ret; | 813 | return ret; |
858 | } | 814 | } |
859 | |||
860 | asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) | ||
861 | { | ||
862 | stack_t uss, uoss; | ||
863 | u32 u_ss_sp = 0; | ||
864 | int ret; | ||
865 | mm_segment_t old_fs; | ||
866 | stack_t32 __user *uss32 = compat_ptr(ussa); | ||
867 | stack_t32 __user *uoss32 = compat_ptr(uossa); | ||
868 | |||
869 | if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) || | ||
870 | __get_user(uss.ss_flags, &uss32->ss_flags) || | ||
871 | __get_user(uss.ss_size, &uss32->ss_size))) | ||
872 | return -EFAULT; | ||
873 | uss.ss_sp = compat_ptr(u_ss_sp); | ||
874 | old_fs = get_fs(); | ||
875 | set_fs(KERNEL_DS); | ||
876 | ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL, | ||
877 | uossa ? (stack_t __user *) &uoss : NULL, sp); | ||
878 | set_fs(old_fs); | ||
879 | if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) || | ||
880 | __put_user(uoss.ss_flags, &uoss32->ss_flags) || | ||
881 | __put_user(uoss.ss_size, &uoss32->ss_size))) | ||
882 | return -EFAULT; | ||
883 | return ret; | ||
884 | } | ||
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 68f9c8650af4..7d5d8e1f8415 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
@@ -59,18 +59,6 @@ struct rt_signal_frame { | |||
59 | #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) | 59 | #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) |
60 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) | 60 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) |
61 | 61 | ||
62 | static int _sigpause_common(old_sigset_t set) | ||
63 | { | ||
64 | sigset_t blocked; | ||
65 | siginitset(&blocked, set); | ||
66 | return sigsuspend(&blocked); | ||
67 | } | ||
68 | |||
69 | asmlinkage int sys_sigsuspend(old_sigset_t set) | ||
70 | { | ||
71 | return _sigpause_common(set); | ||
72 | } | ||
73 | |||
74 | asmlinkage void do_sigreturn(struct pt_regs *regs) | 62 | asmlinkage void do_sigreturn(struct pt_regs *regs) |
75 | { | 63 | { |
76 | struct signal_frame __user *sf; | 64 | struct signal_frame __user *sf; |
@@ -141,9 +129,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
141 | unsigned int psr, pc, npc; | 129 | unsigned int psr, pc, npc; |
142 | __siginfo_fpu_t __user *fpu_save; | 130 | __siginfo_fpu_t __user *fpu_save; |
143 | __siginfo_rwin_t __user *rwin_save; | 131 | __siginfo_rwin_t __user *rwin_save; |
144 | mm_segment_t old_fs; | ||
145 | sigset_t set; | 132 | sigset_t set; |
146 | stack_t st; | ||
147 | int err; | 133 | int err; |
148 | 134 | ||
149 | synchronize_user_stack(); | 135 | synchronize_user_stack(); |
@@ -171,8 +157,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
171 | if (!err && fpu_save) | 157 | if (!err && fpu_save) |
172 | err |= restore_fpu_state(regs, fpu_save); | 158 | err |= restore_fpu_state(regs, fpu_save); |
173 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); | 159 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
174 | 160 | err |= restore_altstack(&sf->stack); | |
175 | err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t)); | ||
176 | 161 | ||
177 | if (err) | 162 | if (err) |
178 | goto segv; | 163 | goto segv; |
@@ -180,14 +165,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
180 | regs->pc = pc; | 165 | regs->pc = pc; |
181 | regs->npc = npc; | 166 | regs->npc = npc; |
182 | 167 | ||
183 | /* It is more difficult to avoid calling this function than to | ||
184 | * call it and ignore errors. | ||
185 | */ | ||
186 | old_fs = get_fs(); | ||
187 | set_fs(KERNEL_DS); | ||
188 | do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf); | ||
189 | set_fs(old_fs); | ||
190 | |||
191 | err |= __get_user(rwin_save, &sf->rwin_save); | 168 | err |= __get_user(rwin_save, &sf->rwin_save); |
192 | if (!err && rwin_save) { | 169 | if (!err && rwin_save) { |
193 | if (restore_rwin_state(rwin_save)) | 170 | if (restore_rwin_state(rwin_save)) |
@@ -209,7 +186,7 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen) | |||
209 | return 0; | 186 | return 0; |
210 | } | 187 | } |
211 | 188 | ||
212 | static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) | 189 | static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) |
213 | { | 190 | { |
214 | unsigned long sp = regs->u_regs[UREG_FP]; | 191 | unsigned long sp = regs->u_regs[UREG_FP]; |
215 | 192 | ||
@@ -221,12 +198,7 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re | |||
221 | return (void __user *) -1L; | 198 | return (void __user *) -1L; |
222 | 199 | ||
223 | /* This is the X/Open sanctioned signal stack switching. */ | 200 | /* This is the X/Open sanctioned signal stack switching. */ |
224 | if (sa->sa_flags & SA_ONSTACK) { | 201 | sp = sigsp(sp, ksig) - framesize; |
225 | if (sas_ss_flags(sp) == 0) | ||
226 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
227 | } | ||
228 | |||
229 | sp -= framesize; | ||
230 | 202 | ||
231 | /* Always align the stack frame. This handles two cases. First, | 203 | /* Always align the stack frame. This handles two cases. First, |
232 | * sigaltstack need not be mindful of platform specific stack | 204 | * sigaltstack need not be mindful of platform specific stack |
@@ -239,8 +211,8 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re | |||
239 | return (void __user *) sp; | 211 | return (void __user *) sp; |
240 | } | 212 | } |
241 | 213 | ||
242 | static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | 214 | static int setup_frame(struct ksignal *ksig, struct pt_regs *regs, |
243 | int signo, sigset_t *oldset) | 215 | sigset_t *oldset) |
244 | { | 216 | { |
245 | struct signal_frame __user *sf; | 217 | struct signal_frame __user *sf; |
246 | int sigframe_size, err, wsaved; | 218 | int sigframe_size, err, wsaved; |
@@ -258,10 +230,12 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
258 | sigframe_size += sizeof(__siginfo_rwin_t); | 230 | sigframe_size += sizeof(__siginfo_rwin_t); |
259 | 231 | ||
260 | sf = (struct signal_frame __user *) | 232 | sf = (struct signal_frame __user *) |
261 | get_sigframe(&ka->sa, regs, sigframe_size); | 233 | get_sigframe(ksig, regs, sigframe_size); |
262 | 234 | ||
263 | if (invalid_frame_pointer(sf, sigframe_size)) | 235 | if (invalid_frame_pointer(sf, sigframe_size)) { |
264 | goto sigill_and_return; | 236 | do_exit(SIGILL); |
237 | return -EINVAL; | ||
238 | } | ||
265 | 239 | ||
266 | tail = sf + 1; | 240 | tail = sf + 1; |
267 | 241 | ||
@@ -300,21 +274,21 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
300 | err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); | 274 | err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); |
301 | } | 275 | } |
302 | if (err) | 276 | if (err) |
303 | goto sigsegv; | 277 | return err; |
304 | 278 | ||
305 | /* 3. signal handler back-trampoline and parameters */ | 279 | /* 3. signal handler back-trampoline and parameters */ |
306 | regs->u_regs[UREG_FP] = (unsigned long) sf; | 280 | regs->u_regs[UREG_FP] = (unsigned long) sf; |
307 | regs->u_regs[UREG_I0] = signo; | 281 | regs->u_regs[UREG_I0] = ksig->sig; |
308 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 282 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
309 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; | 283 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; |
310 | 284 | ||
311 | /* 4. signal handler */ | 285 | /* 4. signal handler */ |
312 | regs->pc = (unsigned long) ka->sa.sa_handler; | 286 | regs->pc = (unsigned long) ksig->ka.sa.sa_handler; |
313 | regs->npc = (regs->pc + 4); | 287 | regs->npc = (regs->pc + 4); |
314 | 288 | ||
315 | /* 5. return to kernel instructions */ | 289 | /* 5. return to kernel instructions */ |
316 | if (ka->ka_restorer) | 290 | if (ksig->ka.ka_restorer) |
317 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 291 | regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; |
318 | else { | 292 | else { |
319 | regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); | 293 | regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); |
320 | 294 | ||
@@ -324,24 +298,16 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
324 | /* t 0x10 */ | 298 | /* t 0x10 */ |
325 | err |= __put_user(0x91d02010, &sf->insns[1]); | 299 | err |= __put_user(0x91d02010, &sf->insns[1]); |
326 | if (err) | 300 | if (err) |
327 | goto sigsegv; | 301 | return err; |
328 | 302 | ||
329 | /* Flush instruction space. */ | 303 | /* Flush instruction space. */ |
330 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); | 304 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
331 | } | 305 | } |
332 | return 0; | 306 | return 0; |
333 | |||
334 | sigill_and_return: | ||
335 | do_exit(SIGILL); | ||
336 | return -EINVAL; | ||
337 | |||
338 | sigsegv: | ||
339 | force_sigsegv(signo, current); | ||
340 | return -EFAULT; | ||
341 | } | 307 | } |
342 | 308 | ||
343 | static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | 309 | static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, |
344 | int signo, sigset_t *oldset, siginfo_t *info) | 310 | sigset_t *oldset) |
345 | { | 311 | { |
346 | struct rt_signal_frame __user *sf; | 312 | struct rt_signal_frame __user *sf; |
347 | int sigframe_size, wsaved; | 313 | int sigframe_size, wsaved; |
@@ -357,9 +323,11 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
357 | if (wsaved) | 323 | if (wsaved) |
358 | sigframe_size += sizeof(__siginfo_rwin_t); | 324 | sigframe_size += sizeof(__siginfo_rwin_t); |
359 | sf = (struct rt_signal_frame __user *) | 325 | sf = (struct rt_signal_frame __user *) |
360 | get_sigframe(&ka->sa, regs, sigframe_size); | 326 | get_sigframe(ksig, regs, sigframe_size); |
361 | if (invalid_frame_pointer(sf, sigframe_size)) | 327 | if (invalid_frame_pointer(sf, sigframe_size)) { |
362 | goto sigill; | 328 | do_exit(SIGILL); |
329 | return -EINVAL; | ||
330 | } | ||
363 | 331 | ||
364 | tail = sf + 1; | 332 | tail = sf + 1; |
365 | err = __put_user(regs->pc, &sf->regs.pc); | 333 | err = __put_user(regs->pc, &sf->regs.pc); |
@@ -391,9 +359,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
391 | err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); | 359 | err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); |
392 | 360 | ||
393 | /* Setup sigaltstack */ | 361 | /* Setup sigaltstack */ |
394 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 362 | err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); |
395 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | ||
396 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | ||
397 | 363 | ||
398 | if (!wsaved) { | 364 | if (!wsaved) { |
399 | err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], | 365 | err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], |
@@ -405,21 +371,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
405 | err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); | 371 | err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); |
406 | } | 372 | } |
407 | 373 | ||
408 | err |= copy_siginfo_to_user(&sf->info, info); | 374 | err |= copy_siginfo_to_user(&sf->info, &ksig->info); |
409 | 375 | ||
410 | if (err) | 376 | if (err) |
411 | goto sigsegv; | 377 | return err; |
412 | 378 | ||
413 | regs->u_regs[UREG_FP] = (unsigned long) sf; | 379 | regs->u_regs[UREG_FP] = (unsigned long) sf; |
414 | regs->u_regs[UREG_I0] = signo; | 380 | regs->u_regs[UREG_I0] = ksig->sig; |
415 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 381 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
416 | regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; | 382 | regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; |
417 | 383 | ||
418 | regs->pc = (unsigned long) ka->sa.sa_handler; | 384 | regs->pc = (unsigned long) ksig->ka.sa.sa_handler; |
419 | regs->npc = (regs->pc + 4); | 385 | regs->npc = (regs->pc + 4); |
420 | 386 | ||
421 | if (ka->ka_restorer) | 387 | if (ksig->ka.ka_restorer) |
422 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 388 | regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; |
423 | else { | 389 | else { |
424 | regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); | 390 | regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); |
425 | 391 | ||
@@ -429,38 +395,25 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
429 | /* t 0x10 */ | 395 | /* t 0x10 */ |
430 | err |= __put_user(0x91d02010, &sf->insns[1]); | 396 | err |= __put_user(0x91d02010, &sf->insns[1]); |
431 | if (err) | 397 | if (err) |
432 | goto sigsegv; | 398 | return err; |
433 | 399 | ||
434 | /* Flush instruction space. */ | 400 | /* Flush instruction space. */ |
435 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); | 401 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
436 | } | 402 | } |
437 | return 0; | 403 | return 0; |
438 | |||
439 | sigill: | ||
440 | do_exit(SIGILL); | ||
441 | return -EINVAL; | ||
442 | |||
443 | sigsegv: | ||
444 | force_sigsegv(signo, current); | ||
445 | return -EFAULT; | ||
446 | } | 404 | } |
447 | 405 | ||
448 | static inline void | 406 | static inline void |
449 | handle_signal(unsigned long signr, struct k_sigaction *ka, | 407 | handle_signal(struct ksignal *ksig, struct pt_regs *regs) |
450 | siginfo_t *info, struct pt_regs *regs) | ||
451 | { | 408 | { |
452 | sigset_t *oldset = sigmask_to_save(); | 409 | sigset_t *oldset = sigmask_to_save(); |
453 | int err; | 410 | int err; |
454 | 411 | ||
455 | if (ka->sa.sa_flags & SA_SIGINFO) | 412 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
456 | err = setup_rt_frame(ka, regs, signr, oldset, info); | 413 | err = setup_rt_frame(ksig, regs, oldset); |
457 | else | 414 | else |
458 | err = setup_frame(ka, regs, signr, oldset); | 415 | err = setup_frame(ksig, regs, oldset); |
459 | 416 | signal_setup_done(err, ksig, 0); | |
460 | if (err) | ||
461 | return; | ||
462 | |||
463 | signal_delivered(signr, info, ka, regs, 0); | ||
464 | } | 417 | } |
465 | 418 | ||
466 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 419 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -490,10 +443,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | |||
490 | */ | 443 | */ |
491 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | 444 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0) |
492 | { | 445 | { |
493 | struct k_sigaction ka; | 446 | struct ksignal ksig; |
494 | int restart_syscall; | 447 | int restart_syscall; |
495 | siginfo_t info; | 448 | bool has_handler; |
496 | int signr; | ||
497 | 449 | ||
498 | /* It's a lot of work and synchronization to add a new ptrace | 450 | /* It's a lot of work and synchronization to add a new ptrace |
499 | * register for GDB to save and restore in order to get | 451 | * register for GDB to save and restore in order to get |
@@ -516,7 +468,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
516 | if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) | 468 | if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) |
517 | regs->u_regs[UREG_G6] = orig_i0; | 469 | regs->u_regs[UREG_G6] = orig_i0; |
518 | 470 | ||
519 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 471 | has_handler = get_signal(&ksig); |
520 | 472 | ||
521 | /* If the debugger messes with the program counter, it clears | 473 | /* If the debugger messes with the program counter, it clears |
522 | * the software "in syscall" bit, directing us to not perform | 474 | * the software "in syscall" bit, directing us to not perform |
@@ -528,35 +480,30 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
528 | orig_i0 = regs->u_regs[UREG_G6]; | 480 | orig_i0 = regs->u_regs[UREG_G6]; |
529 | } | 481 | } |
530 | 482 | ||
531 | 483 | if (has_handler) { | |
532 | if (signr > 0) { | ||
533 | if (restart_syscall) | 484 | if (restart_syscall) |
534 | syscall_restart(orig_i0, regs, &ka.sa); | 485 | syscall_restart(orig_i0, regs, &ksig.ka.sa); |
535 | handle_signal(signr, &ka, &info, regs); | 486 | handle_signal(&ksig, regs); |
536 | return; | 487 | } else { |
537 | } | 488 | if (restart_syscall) { |
538 | if (restart_syscall && | 489 | switch (regs->u_regs[UREG_I0]) { |
539 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 490 | case ERESTARTNOHAND: |
540 | regs->u_regs[UREG_I0] == ERESTARTSYS || | 491 | case ERESTARTSYS: |
541 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { | 492 | case ERESTARTNOINTR: |
542 | /* replay the system call when we are done */ | 493 | /* replay the system call when we are done */ |
543 | regs->u_regs[UREG_I0] = orig_i0; | 494 | regs->u_regs[UREG_I0] = orig_i0; |
544 | regs->pc -= 4; | 495 | regs->pc -= 4; |
545 | regs->npc -= 4; | 496 | regs->npc -= 4; |
546 | pt_regs_clear_syscall(regs); | 497 | pt_regs_clear_syscall(regs); |
547 | } | 498 | case ERESTART_RESTARTBLOCK: |
548 | if (restart_syscall && | 499 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
549 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 500 | regs->pc -= 4; |
550 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 501 | regs->npc -= 4; |
551 | regs->pc -= 4; | 502 | pt_regs_clear_syscall(regs); |
552 | regs->npc -= 4; | 503 | } |
553 | pt_regs_clear_syscall(regs); | 504 | } |
505 | restore_saved_sigmask(); | ||
554 | } | 506 | } |
555 | |||
556 | /* if there's no signal to deliver, we just put the saved sigmask | ||
557 | * back | ||
558 | */ | ||
559 | restore_saved_sigmask(); | ||
560 | } | 507 | } |
561 | 508 | ||
562 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, | 509 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 689e1ba62809..35923e8abd82 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -236,23 +236,6 @@ struct rt_signal_frame { | |||
236 | __siginfo_rwin_t *rwin_save; | 236 | __siginfo_rwin_t *rwin_save; |
237 | }; | 237 | }; |
238 | 238 | ||
239 | static long _sigpause_common(old_sigset_t set) | ||
240 | { | ||
241 | sigset_t blocked; | ||
242 | siginitset(&blocked, set); | ||
243 | return sigsuspend(&blocked); | ||
244 | } | ||
245 | |||
246 | asmlinkage long sys_sigpause(unsigned int set) | ||
247 | { | ||
248 | return _sigpause_common(set); | ||
249 | } | ||
250 | |||
251 | asmlinkage long sys_sigsuspend(old_sigset_t set) | ||
252 | { | ||
253 | return _sigpause_common(set); | ||
254 | } | ||
255 | |||
256 | void do_rt_sigreturn(struct pt_regs *regs) | 239 | void do_rt_sigreturn(struct pt_regs *regs) |
257 | { | 240 | { |
258 | struct rt_signal_frame __user *sf; | 241 | struct rt_signal_frame __user *sf; |
@@ -295,7 +278,8 @@ void do_rt_sigreturn(struct pt_regs *regs) | |||
295 | err |= restore_fpu_state(regs, fpu_save); | 278 | err |= restore_fpu_state(regs, fpu_save); |
296 | 279 | ||
297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); | 280 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
298 | if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) | 281 | err |= restore_altstack(&sf->stack); |
282 | if (err) | ||
299 | goto segv; | 283 | goto segv; |
300 | 284 | ||
301 | err |= __get_user(rwin_save, &sf->rwin_save); | 285 | err |= __get_user(rwin_save, &sf->rwin_save); |
@@ -324,7 +308,7 @@ static int invalid_frame_pointer(void __user *fp) | |||
324 | return 0; | 308 | return 0; |
325 | } | 309 | } |
326 | 310 | ||
327 | static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) | 311 | static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) |
328 | { | 312 | { |
329 | unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; | 313 | unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; |
330 | 314 | ||
@@ -336,12 +320,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * | |||
336 | return (void __user *) -1L; | 320 | return (void __user *) -1L; |
337 | 321 | ||
338 | /* This is the X/Open sanctioned signal stack switching. */ | 322 | /* This is the X/Open sanctioned signal stack switching. */ |
339 | if (ka->sa.sa_flags & SA_ONSTACK) { | 323 | sp = sigsp(sp, ksig) - framesize; |
340 | if (sas_ss_flags(sp) == 0) | ||
341 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
342 | } | ||
343 | |||
344 | sp -= framesize; | ||
345 | 324 | ||
346 | /* Always align the stack frame. This handles two cases. First, | 325 | /* Always align the stack frame. This handles two cases. First, |
347 | * sigaltstack need not be mindful of platform specific stack | 326 | * sigaltstack need not be mindful of platform specific stack |
@@ -355,8 +334,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * | |||
355 | } | 334 | } |
356 | 335 | ||
357 | static inline int | 336 | static inline int |
358 | setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | 337 | setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) |
359 | int signo, sigset_t *oldset, siginfo_t *info) | ||
360 | { | 338 | { |
361 | struct rt_signal_frame __user *sf; | 339 | struct rt_signal_frame __user *sf; |
362 | int wsaved, err, sf_size; | 340 | int wsaved, err, sf_size; |
@@ -374,10 +352,12 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
374 | if (wsaved) | 352 | if (wsaved) |
375 | sf_size += sizeof(__siginfo_rwin_t); | 353 | sf_size += sizeof(__siginfo_rwin_t); |
376 | sf = (struct rt_signal_frame __user *) | 354 | sf = (struct rt_signal_frame __user *) |
377 | get_sigframe(ka, regs, sf_size); | 355 | get_sigframe(ksig, regs, sf_size); |
378 | 356 | ||
379 | if (invalid_frame_pointer (sf)) | 357 | if (invalid_frame_pointer (sf)) { |
380 | goto sigill; | 358 | do_exit(SIGILL); /* won't return, actually */ |
359 | return -EINVAL; | ||
360 | } | ||
381 | 361 | ||
382 | tail = (sf + 1); | 362 | tail = (sf + 1); |
383 | 363 | ||
@@ -403,11 +383,9 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
403 | } | 383 | } |
404 | 384 | ||
405 | /* Setup sigaltstack */ | 385 | /* Setup sigaltstack */ |
406 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 386 | err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); |
407 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | ||
408 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | ||
409 | 387 | ||
410 | err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); | 388 | err |= copy_to_user(&sf->mask, sigmask_to_save(), sizeof(sigset_t)); |
411 | 389 | ||
412 | if (!wsaved) { | 390 | if (!wsaved) { |
413 | err |= copy_in_user((u64 __user *)sf, | 391 | err |= copy_in_user((u64 __user *)sf, |
@@ -420,18 +398,18 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
420 | rp = ¤t_thread_info()->reg_window[wsaved - 1]; | 398 | rp = ¤t_thread_info()->reg_window[wsaved - 1]; |
421 | err |= copy_to_user(sf, rp, sizeof(struct reg_window)); | 399 | err |= copy_to_user(sf, rp, sizeof(struct reg_window)); |
422 | } | 400 | } |
423 | if (info) | 401 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
424 | err |= copy_siginfo_to_user(&sf->info, info); | 402 | err |= copy_siginfo_to_user(&sf->info, &ksig->info); |
425 | else { | 403 | else { |
426 | err |= __put_user(signo, &sf->info.si_signo); | 404 | err |= __put_user(ksig->sig, &sf->info.si_signo); |
427 | err |= __put_user(SI_NOINFO, &sf->info.si_code); | 405 | err |= __put_user(SI_NOINFO, &sf->info.si_code); |
428 | } | 406 | } |
429 | if (err) | 407 | if (err) |
430 | goto sigsegv; | 408 | return err; |
431 | 409 | ||
432 | /* 3. signal handler back-trampoline and parameters */ | 410 | /* 3. signal handler back-trampoline and parameters */ |
433 | regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS; | 411 | regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS; |
434 | regs->u_regs[UREG_I0] = signo; | 412 | regs->u_regs[UREG_I0] = ksig->sig; |
435 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 413 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
436 | 414 | ||
437 | /* The sigcontext is passed in this way because of how it | 415 | /* The sigcontext is passed in this way because of how it |
@@ -441,37 +419,15 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
441 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; | 419 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; |
442 | 420 | ||
443 | /* 5. signal handler */ | 421 | /* 5. signal handler */ |
444 | regs->tpc = (unsigned long) ka->sa.sa_handler; | 422 | regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; |
445 | regs->tnpc = (regs->tpc + 4); | 423 | regs->tnpc = (regs->tpc + 4); |
446 | if (test_thread_flag(TIF_32BIT)) { | 424 | if (test_thread_flag(TIF_32BIT)) { |
447 | regs->tpc &= 0xffffffff; | 425 | regs->tpc &= 0xffffffff; |
448 | regs->tnpc &= 0xffffffff; | 426 | regs->tnpc &= 0xffffffff; |
449 | } | 427 | } |
450 | /* 4. return to kernel instructions */ | 428 | /* 4. return to kernel instructions */ |
451 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 429 | regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; |
452 | return 0; | 430 | return 0; |
453 | |||
454 | sigill: | ||
455 | do_exit(SIGILL); | ||
456 | return -EINVAL; | ||
457 | |||
458 | sigsegv: | ||
459 | force_sigsegv(signo, current); | ||
460 | return -EFAULT; | ||
461 | } | ||
462 | |||
463 | static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | ||
464 | siginfo_t *info, | ||
465 | sigset_t *oldset, struct pt_regs *regs) | ||
466 | { | ||
467 | int err; | ||
468 | |||
469 | err = setup_rt_frame(ka, regs, signr, oldset, | ||
470 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | ||
471 | if (err) | ||
472 | return; | ||
473 | |||
474 | signal_delivered(signr, info, ka, regs, 0); | ||
475 | } | 431 | } |
476 | 432 | ||
477 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 433 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -501,11 +457,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | |||
501 | */ | 457 | */ |
502 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | 458 | static void do_signal(struct pt_regs *regs, unsigned long orig_i0) |
503 | { | 459 | { |
504 | struct k_sigaction ka; | 460 | struct ksignal ksig; |
505 | int restart_syscall; | 461 | int restart_syscall; |
506 | sigset_t *oldset = sigmask_to_save(); | 462 | bool has_handler; |
507 | siginfo_t info; | ||
508 | int signr; | ||
509 | 463 | ||
510 | /* It's a lot of work and synchronization to add a new ptrace | 464 | /* It's a lot of work and synchronization to add a new ptrace |
511 | * register for GDB to save and restore in order to get | 465 | * register for GDB to save and restore in order to get |
@@ -531,13 +485,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
531 | 485 | ||
532 | #ifdef CONFIG_COMPAT | 486 | #ifdef CONFIG_COMPAT |
533 | if (test_thread_flag(TIF_32BIT)) { | 487 | if (test_thread_flag(TIF_32BIT)) { |
534 | extern void do_signal32(sigset_t *, struct pt_regs *); | 488 | extern void do_signal32(struct pt_regs *); |
535 | do_signal32(oldset, regs); | 489 | do_signal32(regs); |
536 | return; | 490 | return; |
537 | } | 491 | } |
538 | #endif | 492 | #endif |
539 | 493 | ||
540 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 494 | has_handler = get_signal(&ksig); |
541 | 495 | ||
542 | restart_syscall = 0; | 496 | restart_syscall = 0; |
543 | if (pt_regs_is_syscall(regs) && | 497 | if (pt_regs_is_syscall(regs) && |
@@ -546,34 +500,30 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
546 | orig_i0 = regs->u_regs[UREG_G6]; | 500 | orig_i0 = regs->u_regs[UREG_G6]; |
547 | } | 501 | } |
548 | 502 | ||
549 | if (signr > 0) { | 503 | if (has_handler) { |
550 | if (restart_syscall) | 504 | if (restart_syscall) |
551 | syscall_restart(orig_i0, regs, &ka.sa); | 505 | syscall_restart(orig_i0, regs, &ksig.ka.sa); |
552 | handle_signal(signr, &ka, &info, oldset, regs); | 506 | signal_setup_done(setup_rt_frame(&ksig, regs), &ksig, 0); |
553 | return; | 507 | } else { |
554 | } | 508 | if (restart_syscall) { |
555 | if (restart_syscall && | 509 | switch (regs->u_regs[UREG_I0]) { |
556 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 510 | case ERESTARTNOHAND: |
557 | regs->u_regs[UREG_I0] == ERESTARTSYS || | 511 | case ERESTARTSYS: |
558 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { | 512 | case ERESTARTNOINTR: |
559 | /* replay the system call when we are done */ | 513 | /* replay the system call when we are done */ |
560 | regs->u_regs[UREG_I0] = orig_i0; | 514 | regs->u_regs[UREG_I0] = orig_i0; |
561 | regs->tpc -= 4; | 515 | regs->tpc -= 4; |
562 | regs->tnpc -= 4; | 516 | regs->tnpc -= 4; |
563 | pt_regs_clear_syscall(regs); | 517 | pt_regs_clear_syscall(regs); |
564 | } | 518 | case ERESTART_RESTARTBLOCK: |
565 | if (restart_syscall && | 519 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
566 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 520 | regs->tpc -= 4; |
567 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 521 | regs->tnpc -= 4; |
568 | regs->tpc -= 4; | 522 | pt_regs_clear_syscall(regs); |
569 | regs->tnpc -= 4; | 523 | } |
570 | pt_regs_clear_syscall(regs); | 524 | } |
525 | restore_saved_sigmask(); | ||
571 | } | 526 | } |
572 | |||
573 | /* If there's no signal to deliver, we just put the saved sigmask | ||
574 | * back | ||
575 | */ | ||
576 | restore_saved_sigmask(); | ||
577 | } | 527 | } |
578 | 528 | ||
579 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) | 529 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e5134a..9e7e6d718367 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/seq_file.h> | 20 | #include <linux/seq_file.h> |
21 | #include <linux/cache.h> | 21 | #include <linux/cache.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/cpu.h> | ||
23 | 24 | ||
24 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
25 | #include <linux/atomic.h> | 26 | #include <linux/atomic.h> |
@@ -32,8 +33,10 @@ | |||
32 | #include <asm/cacheflush.h> | 33 | #include <asm/cacheflush.h> |
33 | #include <asm/tlbflush.h> | 34 | #include <asm/tlbflush.h> |
34 | #include <asm/cpudata.h> | 35 | #include <asm/cpudata.h> |
36 | #include <asm/timer.h> | ||
35 | #include <asm/leon.h> | 37 | #include <asm/leon.h> |
36 | 38 | ||
39 | #include "kernel.h" | ||
37 | #include "irq.h" | 40 | #include "irq.h" |
38 | 41 | ||
39 | volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; | 42 | volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; |
@@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
294 | return ret; | 297 | return ret; |
295 | } | 298 | } |
296 | 299 | ||
300 | void __cpuinit arch_cpu_pre_starting(void *arg) | ||
301 | { | ||
302 | local_ops->cache_all(); | ||
303 | local_ops->tlb_all(); | ||
304 | |||
305 | switch(sparc_cpu_model) { | ||
306 | case sun4m: | ||
307 | sun4m_cpu_pre_starting(arg); | ||
308 | break; | ||
309 | case sun4d: | ||
310 | sun4d_cpu_pre_starting(arg); | ||
311 | break; | ||
312 | case sparc_leon: | ||
313 | leon_cpu_pre_starting(arg); | ||
314 | break; | ||
315 | default: | ||
316 | BUG(); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | void __cpuinit arch_cpu_pre_online(void *arg) | ||
321 | { | ||
322 | unsigned int cpuid = hard_smp_processor_id(); | ||
323 | |||
324 | register_percpu_ce(cpuid); | ||
325 | |||
326 | calibrate_delay(); | ||
327 | smp_store_cpu_info(cpuid); | ||
328 | |||
329 | local_ops->cache_all(); | ||
330 | local_ops->tlb_all(); | ||
331 | |||
332 | switch(sparc_cpu_model) { | ||
333 | case sun4m: | ||
334 | sun4m_cpu_pre_online(arg); | ||
335 | break; | ||
336 | case sun4d: | ||
337 | sun4d_cpu_pre_online(arg); | ||
338 | break; | ||
339 | case sparc_leon: | ||
340 | leon_cpu_pre_online(arg); | ||
341 | break; | ||
342 | default: | ||
343 | BUG(); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | void __cpuinit sparc_start_secondary(void *arg) | ||
348 | { | ||
349 | unsigned int cpu; | ||
350 | |||
351 | /* | ||
352 | * SMP booting is extremely fragile in some architectures. So run | ||
353 | * the cpu initialization code first before anything else. | ||
354 | */ | ||
355 | arch_cpu_pre_starting(arg); | ||
356 | |||
357 | preempt_disable(); | ||
358 | cpu = smp_processor_id(); | ||
359 | |||
360 | /* Invoke the CPU_STARTING notifier callbacks */ | ||
361 | notify_cpu_starting(cpu); | ||
362 | |||
363 | arch_cpu_pre_online(arg); | ||
364 | |||
365 | /* Set the CPU in the cpu_online_mask */ | ||
366 | set_cpu_online(cpu, true); | ||
367 | |||
368 | /* Enable local interrupts now */ | ||
369 | local_irq_enable(); | ||
370 | |||
371 | wmb(); | ||
372 | cpu_idle(); | ||
373 | |||
374 | /* We should never reach here! */ | ||
375 | BUG(); | ||
376 | } | ||
377 | |||
378 | void __cpuinit smp_callin(void) | ||
379 | { | ||
380 | sparc_start_secondary(NULL); | ||
381 | } | ||
382 | |||
297 | void smp_bogo(struct seq_file *m) | 383 | void smp_bogo(struct seq_file *m) |
298 | { | 384 | { |
299 | int i; | 385 | int i; |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31de586..c9eb82f23d92 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) | |||
50 | "i" (ASI_M_CTL)); | 50 | "i" (ASI_M_CTL)); |
51 | } | 51 | } |
52 | 52 | ||
53 | void __cpuinit smp4d_callin(void) | 53 | void __cpuinit sun4d_cpu_pre_starting(void *arg) |
54 | { | 54 | { |
55 | int cpuid = hard_smp_processor_id(); | 55 | int cpuid = hard_smp_processor_id(); |
56 | unsigned long flags; | ||
57 | 56 | ||
58 | /* Show we are alive */ | 57 | /* Show we are alive */ |
59 | cpu_leds[cpuid] = 0x6; | 58 | cpu_leds[cpuid] = 0x6; |
@@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) | |||
61 | 60 | ||
62 | /* Enable level15 interrupt, disable level14 interrupt for now */ | 61 | /* Enable level15 interrupt, disable level14 interrupt for now */ |
63 | cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); | 62 | cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); |
63 | } | ||
64 | 64 | ||
65 | local_ops->cache_all(); | 65 | void __cpuinit sun4d_cpu_pre_online(void *arg) |
66 | local_ops->tlb_all(); | 66 | { |
67 | unsigned long flags; | ||
68 | int cpuid; | ||
67 | 69 | ||
68 | notify_cpu_starting(cpuid); | 70 | cpuid = hard_smp_processor_id(); |
69 | /* | 71 | |
70 | * Unblock the master CPU _only_ when the scheduler state | 72 | /* Unblock the master CPU _only_ when the scheduler state |
71 | * of all secondary CPUs will be up-to-date, so after | 73 | * of all secondary CPUs will be up-to-date, so after |
72 | * the SMP initialization the master will be just allowed | 74 | * the SMP initialization the master will be just allowed |
73 | * to call the scheduler code. | 75 | * to call the scheduler code. |
74 | */ | 76 | */ |
75 | /* Get our local ticker going. */ | ||
76 | register_percpu_ce(cpuid); | ||
77 | |||
78 | calibrate_delay(); | ||
79 | smp_store_cpu_info(cpuid); | ||
80 | local_ops->cache_all(); | ||
81 | local_ops->tlb_all(); | ||
82 | |||
83 | /* Allow master to continue. */ | ||
84 | sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); | 77 | sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); |
85 | local_ops->cache_all(); | 78 | local_ops->cache_all(); |
86 | local_ops->tlb_all(); | 79 | local_ops->tlb_all(); |
@@ -106,16 +99,12 @@ void __cpuinit smp4d_callin(void) | |||
106 | local_ops->cache_all(); | 99 | local_ops->cache_all(); |
107 | local_ops->tlb_all(); | 100 | local_ops->tlb_all(); |
108 | 101 | ||
109 | local_irq_enable(); /* We don't allow PIL 14 yet */ | ||
110 | |||
111 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) | 102 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) |
112 | barrier(); | 103 | barrier(); |
113 | 104 | ||
114 | spin_lock_irqsave(&sun4d_imsk_lock, flags); | 105 | spin_lock_irqsave(&sun4d_imsk_lock, flags); |
115 | cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ | 106 | cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ |
116 | spin_unlock_irqrestore(&sun4d_imsk_lock, flags); | 107 | spin_unlock_irqrestore(&sun4d_imsk_lock, flags); |
117 | set_cpu_online(cpuid, true); | ||
118 | |||
119 | } | 108 | } |
120 | 109 | ||
121 | /* | 110 | /* |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 128af7304288..8a65f158153d 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
@@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) | |||
34 | return val; | 34 | return val; |
35 | } | 35 | } |
36 | 36 | ||
37 | void __cpuinit smp4m_callin(void) | 37 | void __cpuinit sun4m_cpu_pre_starting(void *arg) |
38 | { | 38 | { |
39 | int cpuid = hard_smp_processor_id(); | 39 | } |
40 | |||
41 | local_ops->cache_all(); | ||
42 | local_ops->tlb_all(); | ||
43 | |||
44 | notify_cpu_starting(cpuid); | ||
45 | |||
46 | register_percpu_ce(cpuid); | ||
47 | |||
48 | calibrate_delay(); | ||
49 | smp_store_cpu_info(cpuid); | ||
50 | 40 | ||
51 | local_ops->cache_all(); | 41 | void __cpuinit sun4m_cpu_pre_online(void *arg) |
52 | local_ops->tlb_all(); | 42 | { |
43 | int cpuid = hard_smp_processor_id(); | ||
53 | 44 | ||
54 | /* | 45 | /* Allow master to continue. The master will then give us the |
55 | * Unblock the master CPU _only_ when the scheduler state | 46 | * go-ahead by setting the smp_commenced_mask and will wait without |
56 | * of all secondary CPUs will be up-to-date, so after | 47 | * timeouts until our setup is completed fully (signified by |
57 | * the SMP initialization the master will be just allowed | 48 | * our bit being set in the cpu_online_mask). |
58 | * to call the scheduler code. | ||
59 | */ | 49 | */ |
60 | /* Allow master to continue. */ | ||
61 | swap_ulong(&cpu_callin_map[cpuid], 1); | 50 | swap_ulong(&cpu_callin_map[cpuid], 1); |
62 | 51 | ||
63 | /* XXX: What's up with all the flushes? */ | 52 | /* XXX: What's up with all the flushes? */ |
@@ -75,10 +64,6 @@ void __cpuinit smp4m_callin(void) | |||
75 | 64 | ||
76 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) | 65 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) |
77 | mb(); | 66 | mb(); |
78 | |||
79 | local_irq_enable(); | ||
80 | |||
81 | set_cpu_online(cpuid, true); | ||
82 | } | 67 | } |
83 | 68 | ||
84 | /* | 69 | /* |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 8475a474273a..240a3cecc11e 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
@@ -36,108 +36,22 @@ STUB: sra REG1, 0, REG1; \ | |||
36 | jmpl %g1 + %lo(SYSCALL), %g0; \ | 36 | jmpl %g1 + %lo(SYSCALL), %g0; \ |
37 | sra REG3, 0, REG3 | 37 | sra REG3, 0, REG3 |
38 | 38 | ||
39 | #define SIGN4(STUB,SYSCALL,REG1,REG2,REG3,REG4) \ | ||
40 | .align 32; \ | ||
41 | .globl STUB; \ | ||
42 | STUB: sra REG1, 0, REG1; \ | ||
43 | sethi %hi(SYSCALL), %g1; \ | ||
44 | sra REG2, 0, REG2; \ | ||
45 | sra REG3, 0, REG3; \ | ||
46 | jmpl %g1 + %lo(SYSCALL), %g0; \ | ||
47 | sra REG4, 0, REG4 | ||
48 | |||
49 | SIGN1(sys32_exit, sparc_exit, %o0) | ||
50 | SIGN1(sys32_exit_group, sparc_exit_group, %o0) | ||
51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) | ||
52 | SIGN1(sys32_creat, sys_creat, %o1) | ||
53 | SIGN1(sys32_mknod, sys_mknod, %o1) | ||
54 | SIGN1(sys32_umount, sys_umount, %o1) | ||
55 | SIGN1(sys32_signal, sys_signal, %o0) | ||
56 | SIGN1(sys32_access, sys_access, %o1) | ||
57 | SIGN1(sys32_msync, sys_msync, %o2) | ||
58 | SIGN2(sys32_reboot, sys_reboot, %o0, %o1) | ||
59 | SIGN1(sys32_setitimer, compat_sys_setitimer, %o0) | ||
60 | SIGN1(sys32_getitimer, compat_sys_getitimer, %o0) | ||
61 | SIGN1(sys32_sethostname, sys_sethostname, %o1) | ||
62 | SIGN1(sys32_swapon, sys_swapon, %o1) | ||
63 | SIGN1(sys32_sigaction, compat_sys_sigaction, %o0) | ||
64 | SIGN1(sys32_rt_sigaction, compat_sys_rt_sigaction, %o0) | ||
65 | SIGN1(sys32_sigprocmask, compat_sys_sigprocmask, %o0) | ||
66 | SIGN1(sys32_rt_sigprocmask, compat_sys_rt_sigprocmask, %o0) | ||
67 | SIGN2(sys32_rt_sigqueueinfo, compat_sys_rt_sigqueueinfo, %o0, %o1) | ||
68 | SIGN1(sys32_getrusage, compat_sys_getrusage, %o0) | 39 | SIGN1(sys32_getrusage, compat_sys_getrusage, %o0) |
69 | SIGN1(sys32_setxattr, sys_setxattr, %o4) | ||
70 | SIGN1(sys32_lsetxattr, sys_lsetxattr, %o4) | ||
71 | SIGN1(sys32_fsetxattr, sys_fsetxattr, %o4) | ||
72 | SIGN1(sys32_fgetxattr, sys_fgetxattr, %o0) | ||
73 | SIGN1(sys32_flistxattr, sys_flistxattr, %o0) | ||
74 | SIGN1(sys32_fremovexattr, sys_fremovexattr, %o0) | ||
75 | SIGN2(sys32_tkill, sys_tkill, %o0, %o1) | ||
76 | SIGN1(sys32_epoll_create, sys_epoll_create, %o0) | ||
77 | SIGN3(sys32_epoll_ctl, sys_epoll_ctl, %o0, %o1, %o2) | ||
78 | SIGN3(sys32_epoll_wait, sys_epoll_wait, %o0, %o2, %o3) | ||
79 | SIGN1(sys32_readahead, compat_sys_readahead, %o0) | 40 | SIGN1(sys32_readahead, compat_sys_readahead, %o0) |
80 | SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4) | 41 | SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4) |
81 | SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5) | 42 | SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5) |
82 | SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1) | ||
83 | SIGN1(sys32_mlockall, sys_mlockall, %o0) | ||
84 | SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1) | 43 | SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1) |
85 | SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) | 44 | SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) |
86 | SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) | 45 | SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) |
87 | SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) | 46 | SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) |
88 | SIGN1(sys32_select, compat_sys_select, %o0) | 47 | SIGN1(sys32_select, compat_sys_select, %o0) |
89 | SIGN1(sys32_mkdir, sys_mkdir, %o1) | ||
90 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) | 48 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) |
91 | SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) | ||
92 | SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) | 49 | SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) |
93 | SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1) | ||
94 | SIGN1(sys32_prctl, sys_prctl, %o0) | ||
95 | SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0) | ||
96 | SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2) | ||
97 | SIGN1(sys32_getgroups, sys_getgroups, %o0) | ||
98 | SIGN1(sys32_getpgid, sys_getpgid, %o0) | ||
99 | SIGN2(sys32_getpriority, sys_getpriority, %o0, %o1) | ||
100 | SIGN1(sys32_getsid, sys_getsid, %o0) | ||
101 | SIGN2(sys32_kill, sys_kill, %o0, %o1) | ||
102 | SIGN1(sys32_nice, sys_nice, %o0) | ||
103 | SIGN1(sys32_lseek, sys_lseek, %o1) | ||
104 | SIGN2(sys32_open, sparc32_open, %o1, %o2) | ||
105 | SIGN1(sys32_readlink, sys_readlink, %o2) | ||
106 | SIGN1(sys32_sched_get_priority_max, sys_sched_get_priority_max, %o0) | ||
107 | SIGN1(sys32_sched_get_priority_min, sys_sched_get_priority_min, %o0) | ||
108 | SIGN1(sys32_sched_getparam, sys_sched_getparam, %o0) | ||
109 | SIGN1(sys32_sched_getscheduler, sys_sched_getscheduler, %o0) | ||
110 | SIGN1(sys32_sched_setparam, sys_sched_setparam, %o0) | ||
111 | SIGN2(sys32_sched_setscheduler, sys_sched_setscheduler, %o0, %o1) | ||
112 | SIGN1(sys32_getdomainname, sys_getdomainname, %o1) | ||
113 | SIGN1(sys32_setdomainname, sys_setdomainname, %o1) | ||
114 | SIGN1(sys32_setgroups, sys_setgroups, %o0) | ||
115 | SIGN2(sys32_setpgid, sys_setpgid, %o0, %o1) | ||
116 | SIGN3(sys32_setpriority, sys_setpriority, %o0, %o1, %o2) | ||
117 | SIGN1(sys32_ssetmask, sys_ssetmask, %o0) | ||
118 | SIGN2(sys32_syslog, sys_syslog, %o0, %o2) | ||
119 | SIGN1(sys32_umask, sys_umask, %o0) | ||
120 | SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2) | ||
121 | SIGN1(sys32_sendto, sys_sendto, %o0) | ||
122 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) | 50 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) |
123 | SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2) | ||
124 | SIGN2(sys32_connect, sys_connect, %o0, %o2) | ||
125 | SIGN2(sys32_bind, sys_bind, %o0, %o2) | ||
126 | SIGN2(sys32_listen, sys_listen, %o0, %o1) | ||
127 | SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) | 51 | SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) |
128 | SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) | 52 | SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) |
129 | SIGN2(sys32_shutdown, sys_shutdown, %o0, %o1) | ||
130 | SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2) | ||
131 | SIGN1(sys32_getpeername, sys_getpeername, %o0) | ||
132 | SIGN1(sys32_getsockname, sys_getsockname, %o0) | ||
133 | SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) | ||
134 | SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) | ||
135 | SIGN2(sys32_splice, sys_splice, %o0, %o2) | ||
136 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) | 53 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) |
137 | SIGN2(sys32_tee, sys_tee, %o0, %o1) | ||
138 | SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0) | 54 | SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0) |
139 | SIGN1(sys32_truncate, sys_truncate, %o1) | ||
140 | SIGN1(sys32_ftruncate, sys_ftruncate, %o1) | ||
141 | 55 | ||
142 | .globl sys32_mmap2 | 56 | .globl sys32_mmap2 |
143 | sys32_mmap2: | 57 | sys32_mmap2: |
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 4a4cdc633f6b..f38f2280fade 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
@@ -206,133 +206,19 @@ asmlinkage long compat_sys_fstatat64(unsigned int dfd, | |||
206 | return cp_compat_stat64(&stat, statbuf); | 206 | return cp_compat_stat64(&stat, statbuf); |
207 | } | 207 | } |
208 | 208 | ||
209 | asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) | 209 | COMPAT_SYSCALL_DEFINE3(sparc_sigaction, int, sig, |
210 | struct compat_old_sigaction __user *,act, | ||
211 | struct compat_old_sigaction __user *,oact) | ||
210 | { | 212 | { |
211 | return sys_sysfs(option, arg1, arg2); | ||
212 | } | ||
213 | |||
214 | asmlinkage long compat_sys_rt_sigprocmask(int how, | ||
215 | compat_sigset_t __user *set, | ||
216 | compat_sigset_t __user *oset, | ||
217 | compat_size_t sigsetsize) | ||
218 | { | ||
219 | sigset_t s; | ||
220 | compat_sigset_t s32; | ||
221 | int ret; | ||
222 | mm_segment_t old_fs = get_fs(); | ||
223 | |||
224 | if (set) { | ||
225 | if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) | ||
226 | return -EFAULT; | ||
227 | switch (_NSIG_WORDS) { | ||
228 | case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); | ||
229 | case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); | ||
230 | case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); | ||
231 | case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); | ||
232 | } | ||
233 | } | ||
234 | set_fs (KERNEL_DS); | ||
235 | ret = sys_rt_sigprocmask(how, | ||
236 | set ? (sigset_t __user *) &s : NULL, | ||
237 | oset ? (sigset_t __user *) &s : NULL, | ||
238 | sigsetsize); | ||
239 | set_fs (old_fs); | ||
240 | if (ret) return ret; | ||
241 | if (oset) { | ||
242 | switch (_NSIG_WORDS) { | ||
243 | case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; | ||
244 | case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; | ||
245 | case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; | ||
246 | case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; | ||
247 | } | ||
248 | if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) | ||
249 | return -EFAULT; | ||
250 | } | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set, | ||
255 | compat_size_t sigsetsize) | ||
256 | { | ||
257 | sigset_t s; | ||
258 | compat_sigset_t s32; | ||
259 | int ret; | ||
260 | mm_segment_t old_fs = get_fs(); | ||
261 | |||
262 | set_fs (KERNEL_DS); | ||
263 | ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); | ||
264 | set_fs (old_fs); | ||
265 | if (!ret) { | ||
266 | switch (_NSIG_WORDS) { | ||
267 | case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; | ||
268 | case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; | ||
269 | case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; | ||
270 | case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; | ||
271 | } | ||
272 | if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) | ||
273 | return -EFAULT; | ||
274 | } | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig, | ||
279 | struct compat_siginfo __user *uinfo) | ||
280 | { | ||
281 | siginfo_t info; | ||
282 | int ret; | ||
283 | mm_segment_t old_fs = get_fs(); | ||
284 | |||
285 | if (copy_siginfo_from_user32(&info, uinfo)) | ||
286 | return -EFAULT; | ||
287 | |||
288 | set_fs (KERNEL_DS); | ||
289 | ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info); | ||
290 | set_fs (old_fs); | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act, | ||
295 | struct old_sigaction32 __user *oact) | ||
296 | { | ||
297 | struct k_sigaction new_ka, old_ka; | ||
298 | int ret; | ||
299 | |||
300 | WARN_ON_ONCE(sig >= 0); | 213 | WARN_ON_ONCE(sig >= 0); |
301 | sig = -sig; | 214 | return compat_sys_sigaction(-sig, act, oact); |
302 | |||
303 | if (act) { | ||
304 | compat_old_sigset_t mask; | ||
305 | u32 u_handler, u_restorer; | ||
306 | |||
307 | ret = get_user(u_handler, &act->sa_handler); | ||
308 | new_ka.sa.sa_handler = compat_ptr(u_handler); | ||
309 | ret |= __get_user(u_restorer, &act->sa_restorer); | ||
310 | new_ka.sa.sa_restorer = compat_ptr(u_restorer); | ||
311 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
312 | ret |= __get_user(mask, &act->sa_mask); | ||
313 | if (ret) | ||
314 | return ret; | ||
315 | new_ka.ka_restorer = NULL; | ||
316 | siginitset(&new_ka.sa.sa_mask, mask); | ||
317 | } | ||
318 | |||
319 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
320 | |||
321 | if (!ret && oact) { | ||
322 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); | ||
323 | ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer); | ||
324 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
325 | ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
326 | } | ||
327 | |||
328 | return ret; | ||
329 | } | 215 | } |
330 | 216 | ||
331 | asmlinkage long compat_sys_rt_sigaction(int sig, | 217 | COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, |
332 | struct sigaction32 __user *act, | 218 | struct compat_sigaction __user *,act, |
333 | struct sigaction32 __user *oact, | 219 | struct compat_sigaction __user *,oact, |
334 | void __user *restorer, | 220 | void __user *,restorer, |
335 | compat_size_t sigsetsize) | 221 | compat_size_t,sigsetsize) |
336 | { | 222 | { |
337 | struct k_sigaction new_ka, old_ka; | 223 | struct k_sigaction new_ka, old_ka; |
338 | int ret; | 224 | int ret; |
@@ -349,12 +235,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig, | |||
349 | ret = get_user(u_handler, &act->sa_handler); | 235 | ret = get_user(u_handler, &act->sa_handler); |
350 | new_ka.sa.sa_handler = compat_ptr(u_handler); | 236 | new_ka.sa.sa_handler = compat_ptr(u_handler); |
351 | ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); | 237 | ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); |
352 | switch (_NSIG_WORDS) { | 238 | sigset_from_compat(&new_ka.sa.sa_mask, &set32); |
353 | case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32); | ||
354 | case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32); | ||
355 | case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32); | ||
356 | case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32); | ||
357 | } | ||
358 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); | 239 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); |
359 | ret |= __get_user(u_restorer, &act->sa_restorer); | 240 | ret |= __get_user(u_restorer, &act->sa_restorer); |
360 | new_ka.sa.sa_restorer = compat_ptr(u_restorer); | 241 | new_ka.sa.sa_restorer = compat_ptr(u_restorer); |
@@ -365,12 +246,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig, | |||
365 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 246 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); |
366 | 247 | ||
367 | if (!ret && oact) { | 248 | if (!ret && oact) { |
368 | switch (_NSIG_WORDS) { | 249 | sigset_to_compat(&set32, &old_ka.sa.sa_mask); |
369 | case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3]; | ||
370 | case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2]; | ||
371 | case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1]; | ||
372 | case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0]; | ||
373 | } | ||
374 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); | 250 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); |
375 | ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); | 251 | ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); |
376 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | 252 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); |
@@ -382,35 +258,6 @@ asmlinkage long compat_sys_rt_sigaction(int sig, | |||
382 | return ret; | 258 | return ret; |
383 | } | 259 | } |
384 | 260 | ||
385 | #ifdef CONFIG_MODULES | ||
386 | |||
387 | asmlinkage long sys32_init_module(void __user *umod, u32 len, | ||
388 | const char __user *uargs) | ||
389 | { | ||
390 | return sys_init_module(umod, len, uargs); | ||
391 | } | ||
392 | |||
393 | asmlinkage long sys32_delete_module(const char __user *name_user, | ||
394 | unsigned int flags) | ||
395 | { | ||
396 | return sys_delete_module(name_user, flags); | ||
397 | } | ||
398 | |||
399 | #else /* CONFIG_MODULES */ | ||
400 | |||
401 | asmlinkage long sys32_init_module(const char __user *name_user, | ||
402 | struct module __user *mod_user) | ||
403 | { | ||
404 | return -ENOSYS; | ||
405 | } | ||
406 | |||
407 | asmlinkage long sys32_delete_module(const char __user *name_user) | ||
408 | { | ||
409 | return -ENOSYS; | ||
410 | } | ||
411 | |||
412 | #endif /* CONFIG_MODULES */ | ||
413 | |||
414 | asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, | 261 | asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, |
415 | char __user *ubuf, | 262 | char __user *ubuf, |
416 | compat_size_t count, | 263 | compat_size_t count, |
@@ -456,16 +303,6 @@ long compat_sys_fadvise64_64(int fd, | |||
456 | advice); | 303 | advice); |
457 | } | 304 | } |
458 | 305 | ||
459 | /* This is just a version for 32-bit applications which does | ||
460 | * not force O_LARGEFILE on. | ||
461 | */ | ||
462 | |||
463 | asmlinkage long sparc32_open(const char __user *filename, | ||
464 | int flags, int mode) | ||
465 | { | ||
466 | return do_sys_open(AT_FDCWD, filename, flags, mode); | ||
467 | } | ||
468 | |||
469 | long sys32_lookup_dcookie(unsigned long cookie_high, | 306 | long sys32_lookup_dcookie(unsigned long cookie_high, |
470 | unsigned long cookie_low, | 307 | unsigned long cookie_low, |
471 | char __user *buf, size_t len) | 308 | char __user *buf, size_t len) |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 2da0bdcae52f..3a8d1844402e 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
@@ -160,49 +160,19 @@ sparc_breakpoint (struct pt_regs *regs) | |||
160 | #endif | 160 | #endif |
161 | } | 161 | } |
162 | 162 | ||
163 | asmlinkage int | 163 | SYSCALL_DEFINE3(sparc_sigaction, int, sig, |
164 | sparc_sigaction (int sig, const struct old_sigaction __user *act, | 164 | struct old_sigaction __user *,act, |
165 | struct old_sigaction __user *oact) | 165 | struct old_sigaction __user *,oact) |
166 | { | 166 | { |
167 | struct k_sigaction new_ka, old_ka; | ||
168 | int ret; | ||
169 | |||
170 | WARN_ON_ONCE(sig >= 0); | 167 | WARN_ON_ONCE(sig >= 0); |
171 | sig = -sig; | 168 | return sys_sigaction(-sig, act, oact); |
172 | |||
173 | if (act) { | ||
174 | unsigned long mask; | ||
175 | |||
176 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
177 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
178 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || | ||
179 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
180 | __get_user(mask, &act->sa_mask)) | ||
181 | return -EFAULT; | ||
182 | siginitset(&new_ka.sa.sa_mask, mask); | ||
183 | new_ka.ka_restorer = NULL; | ||
184 | } | ||
185 | |||
186 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
187 | |||
188 | if (!ret && oact) { | ||
189 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
190 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
191 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || | ||
192 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
193 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
194 | return -EFAULT; | ||
195 | } | ||
196 | |||
197 | return ret; | ||
198 | } | 169 | } |
199 | 170 | ||
200 | asmlinkage long | 171 | SYSCALL_DEFINE5(rt_sigaction, int, sig, |
201 | sys_rt_sigaction(int sig, | 172 | const struct sigaction __user *, act, |
202 | const struct sigaction __user *act, | 173 | struct sigaction __user *, oact, |
203 | struct sigaction __user *oact, | 174 | void __user *, restorer, |
204 | void __user *restorer, | 175 | size_t, sigsetsize) |
205 | size_t sigsetsize) | ||
206 | { | 176 | { |
207 | struct k_sigaction new_ka, old_ka; | 177 | struct k_sigaction new_ka, old_ka; |
208 | int ret; | 178 | int ret; |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index e0fed7711a94..22a1098961f5 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
@@ -25,16 +25,10 @@ sys_nis_syscall: | |||
25 | sys_memory_ordering: | 25 | sys_memory_ordering: |
26 | ba,pt %xcc, sparc_memory_ordering | 26 | ba,pt %xcc, sparc_memory_ordering |
27 | add %sp, PTREGS_OFF, %o1 | 27 | add %sp, PTREGS_OFF, %o1 |
28 | sys_sigaltstack: | ||
29 | ba,pt %xcc, do_sigaltstack | ||
30 | add %i6, STACK_BIAS, %o2 | ||
31 | #ifdef CONFIG_COMPAT | 28 | #ifdef CONFIG_COMPAT |
32 | sys32_sigstack: | 29 | sys32_sigstack: |
33 | ba,pt %xcc, do_sys32_sigstack | 30 | ba,pt %xcc, do_sys32_sigstack |
34 | mov %i6, %o2 | 31 | mov %i6, %o2 |
35 | sys32_sigaltstack: | ||
36 | ba,pt %xcc, do_sys32_sigaltstack | ||
37 | mov %i6, %o2 | ||
38 | #endif | 32 | #endif |
39 | .align 32 | 33 | .align 32 |
40 | #ifdef CONFIG_COMPAT | 34 | #ifdef CONFIG_COMPAT |
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index 118759cd7342..26e6dd72e92a 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h | |||
@@ -3,8 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/signal.h> | ||
6 | #include <asm/utrap.h> | 7 | #include <asm/utrap.h> |
7 | #include <asm/signal.h> | ||
8 | 8 | ||
9 | extern asmlinkage unsigned long sys_getpagesize(void); | 9 | extern asmlinkage unsigned long sys_getpagesize(void); |
10 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); | 10 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); |
@@ -36,8 +36,6 @@ extern asmlinkage long sys_rt_sigaction(int sig, | |||
36 | 36 | ||
37 | extern asmlinkage void sparc64_set_context(struct pt_regs *regs); | 37 | extern asmlinkage void sparc64_set_context(struct pt_regs *regs); |
38 | extern asmlinkage void sparc64_get_context(struct pt_regs *regs); | 38 | extern asmlinkage void sparc64_get_context(struct pt_regs *regs); |
39 | extern asmlinkage long sys_sigpause(unsigned int set); | ||
40 | extern asmlinkage long sys_sigsuspend(old_sigset_t set); | ||
41 | extern void do_rt_sigreturn(struct pt_regs *regs); | 39 | extern void do_rt_sigreturn(struct pt_regs *regs); |
42 | 40 | ||
43 | #endif /* _SYSTBLS_H */ | 41 | #endif /* _SYSTBLS_H */ |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6ac43c36bbbf..7b87171ecf1e 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
@@ -55,7 +55,7 @@ sys_call_table: | |||
55 | /*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_ni_syscall | 55 | /*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_ni_syscall |
56 | /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname | 56 | /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname |
57 | /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl | 57 | /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl |
58 | /*195*/ .long sys_epoll_wait, sys_ioprio_set, sys_getppid, sparc_sigaction, sys_sgetmask | 58 | /*195*/ .long sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_sparc_sigaction, sys_sgetmask |
59 | /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_old_readdir | 59 | /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_old_readdir |
60 | /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 | 60 | /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 |
61 | /*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo | 61 | /*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo |
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 1009ecb92678..088134834dab 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -18,63 +18,63 @@ | |||
18 | 18 | ||
19 | .globl sys_call_table32 | 19 | .globl sys_call_table32 |
20 | sys_call_table32: | 20 | sys_call_table32: |
21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write | 21 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write |
22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link | 22 | /*5*/ .word compat_sys_open, sys_close, compat_sys_wait4, sys_creat, sys_link |
23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod | 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod |
24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek | 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, compat_sys_lseek |
25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause | 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause |
27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice | 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice |
28 | .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile | 28 | .word sys_chown, sys_sync, sys_kill, compat_sys_newstat, sys32_sendfile |
29 | /*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid | 29 | /*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid |
30 | .word sys32_umount, sys_setgid16, sys_getgid16, sys32_signal, sys_geteuid16 | 30 | .word sys_umount, sys_setgid16, sys_getgid16, sys_signal, sys_geteuid16 |
31 | /*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl | 31 | /*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl |
32 | .word sys32_reboot, sys32_mmap2, sys_symlink, sys32_readlink, sys32_execve | 32 | .word sys_reboot, sys32_mmap2, sys_symlink, sys_readlink, sys32_execve |
33 | /*60*/ .word sys32_umask, sys_chroot, compat_sys_newfstat, compat_sys_fstat64, sys_getpagesize | 33 | /*60*/ .word sys_umask, sys_chroot, compat_sys_newfstat, compat_sys_fstat64, sys_getpagesize |
34 | .word sys32_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid | 34 | .word sys_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid |
35 | /*70*/ .word sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect | 35 | /*70*/ .word sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect |
36 | .word sys_madvise, sys_vhangup, sys32_truncate64, sys_mincore, sys_getgroups16 | 36 | .word sys_madvise, sys_vhangup, sys32_truncate64, sys_mincore, sys_getgroups16 |
37 | /*80*/ .word sys_setgroups16, sys_getpgrp, sys32_setgroups, sys32_setitimer, sys32_ftruncate64 | 37 | /*80*/ .word sys_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64 |
38 | .word sys32_swapon, sys32_getitimer, sys_setuid, sys32_sethostname, sys_setgid | 38 | .word sys_swapon, compat_sys_getitimer, sys_setuid, sys_sethostname, sys_setgid |
39 | /*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid | 39 | /*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid |
40 | .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall | 40 | .word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall |
41 | /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending | 41 | /*100*/ .word sys_getpriority, sys32_rt_sigreturn, compat_sys_rt_sigaction, compat_sys_rt_sigprocmask, compat_sys_rt_sigpending |
42 | .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid | 42 | .word compat_sys_rt_sigtimedwait, compat_sys_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid |
43 | /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall | 43 | /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall |
44 | .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd | 44 | .word sys_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd |
45 | /*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod | 45 | /*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod |
46 | .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys32_truncate | 46 | .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, compat_sys_truncate |
47 | /*130*/ .word sys32_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall | 47 | /*130*/ .word compat_sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall |
48 | .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 | 48 | .word sys_nis_syscall, sys_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 |
49 | /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit | 49 | /*140*/ .word sys_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit |
50 | .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write | 50 | .word compat_sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write |
51 | /*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 | 51 | /*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 |
52 | .word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount | 52 | .word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount |
53 | /*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall | 53 | /*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall |
54 | .word sys_quotactl, sys_set_tid_address, compat_sys_mount, compat_sys_ustat, sys32_setxattr | 54 | .word sys_quotactl, sys_set_tid_address, compat_sys_mount, compat_sys_ustat, sys_setxattr |
55 | /*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents | 55 | /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents |
56 | .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr | 56 | .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr |
57 | /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall | 57 | /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall |
58 | .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_newuname | 58 | .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname |
59 | /*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl | 59 | /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl |
60 | .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask | 60 | .word sys_epoll_wait, sys_ioprio_set, sys_getppid, compat_sys_sparc_sigaction, sys_sgetmask |
61 | /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir | 61 | /*200*/ .word sys_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir |
62 | .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 | 62 | .word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys32_fadvise64 |
63 | /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, compat_sys_sysinfo | 63 | /*210*/ .word sys32_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, compat_sys_sysinfo |
64 | .word compat_sys_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex | 64 | .word compat_sys_ipc, sys32_sigreturn, sys_clone, sys_ioprio_get, compat_sys_adjtimex |
65 | /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid | 65 | /*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid |
66 | .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 | 66 | .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 |
67 | /*230*/ .word sys32_select, compat_sys_time, sys32_splice, compat_sys_stime, compat_sys_statfs64 | 67 | /*230*/ .word sys32_select, compat_sys_time, sys_splice, compat_sys_stime, compat_sys_statfs64 |
68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall | 68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall |
69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler | 69 | /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler |
70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep | 70 | .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, compat_sys_sched_rr_get_interval, compat_sys_nanosleep |
71 | /*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys_nis_syscall | 71 | /*250*/ .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall |
72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep | 72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep |
73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun | 73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun |
74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy | 74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
75 | /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink | 75 | /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink |
76 | .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid | 76 | .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid |
77 | /*280*/ .word sys32_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat | 77 | /*280*/ .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat |
78 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 | 78 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 |
79 | /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 79 | /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
80 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare | 80 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare |
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index af27acab4486..6cdb08cdabf0 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S | |||
@@ -79,18 +79,15 @@ cpu3_startup: | |||
79 | nop | 79 | nop |
80 | 80 | ||
81 | /* Start this processor. */ | 81 | /* Start this processor. */ |
82 | call smp4m_callin | 82 | call smp_callin |
83 | nop | 83 | nop |
84 | 84 | ||
85 | b,a smp_do_cpu_idle | 85 | b,a smp_panic |
86 | 86 | ||
87 | .text | 87 | .text |
88 | .align 4 | 88 | .align 4 |
89 | 89 | ||
90 | smp_do_cpu_idle: | 90 | smp_panic: |
91 | call cpu_idle | ||
92 | mov 0, %o0 | ||
93 | |||
94 | call cpu_panic | 91 | call cpu_panic |
95 | nop | 92 | nop |
96 | 93 | ||
@@ -144,10 +141,10 @@ sun4d_cpu_startup: | |||
144 | nop | 141 | nop |
145 | 142 | ||
146 | /* Start this processor. */ | 143 | /* Start this processor. */ |
147 | call smp4d_callin | 144 | call smp_callin |
148 | nop | 145 | nop |
149 | 146 | ||
150 | b,a smp_do_cpu_idle | 147 | b,a smp_panic |
151 | 148 | ||
152 | __CPUINIT | 149 | __CPUINIT |
153 | .align 4 | 150 | .align 4 |
@@ -201,7 +198,7 @@ leon_smp_cpu_startup: | |||
201 | nop | 198 | nop |
202 | 199 | ||
203 | /* Start this processor. */ | 200 | /* Start this processor. */ |
204 | call leon_callin | 201 | call smp_callin |
205 | nop | 202 | nop |
206 | 203 | ||
207 | b,a smp_do_cpu_idle | 204 | b,a smp_panic |
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index a5785ea2a85d..662982946a89 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c | |||
@@ -58,7 +58,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
58 | 58 | ||
59 | printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); | 59 | printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); |
60 | show_regs(regs); | 60 | show_regs(regs); |
61 | add_taint(TAINT_DIE); | 61 | add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); |
62 | 62 | ||
63 | __SAVE; __SAVE; __SAVE; __SAVE; | 63 | __SAVE; __SAVE; __SAVE; __SAVE; |
64 | __SAVE; __SAVE; __SAVE; __SAVE; | 64 | __SAVE; __SAVE; __SAVE; __SAVE; |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index e7ecf1507d90..8d38ca97aa23 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -2383,7 +2383,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2383 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); | 2383 | notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); |
2384 | __asm__ __volatile__("flushw"); | 2384 | __asm__ __volatile__("flushw"); |
2385 | show_regs(regs); | 2385 | show_regs(regs); |
2386 | add_taint(TAINT_DIE); | 2386 | add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); |
2387 | if (regs->tstate & TSTATE_PRIV) { | 2387 | if (regs->tstate & TSTATE_PRIV) { |
2388 | struct thread_info *tp = current_thread_info(); | 2388 | struct thread_info *tp = current_thread_info(); |
2389 | struct reg_window *rw = (struct reg_window *) | 2389 | struct reg_window *rw = (struct reg_window *) |
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index d4bdc7a62375..a313e4a9399b 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S | |||
@@ -136,12 +136,43 @@ tsb_miss_page_table_walk_sun4v_fastpath: | |||
136 | nop | 136 | nop |
137 | 137 | ||
138 | /* It is a huge page, use huge page TSB entry address we | 138 | /* It is a huge page, use huge page TSB entry address we |
139 | * calculated above. | 139 | * calculated above. If the huge page TSB has not been |
140 | * allocated, setup a trap stack and call hugetlb_setup() | ||
141 | * to do so, then return from the trap to replay the TLB | ||
142 | * miss. | ||
143 | * | ||
144 | * This is necessary to handle the case of transparent huge | ||
145 | * pages where we don't really have a non-atomic context | ||
146 | * in which to allocate the hugepage TSB hash table. When | ||
147 | * the 'mm' faults in the hugepage for the first time, we | ||
148 | * thus handle it here. This also makes sure that we can | ||
149 | * allocate the TSB hash table on the correct NUMA node. | ||
140 | */ | 150 | */ |
141 | TRAP_LOAD_TRAP_BLOCK(%g7, %g2) | 151 | TRAP_LOAD_TRAP_BLOCK(%g7, %g2) |
142 | ldx [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP], %g2 | 152 | ldx [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP], %g1 |
143 | cmp %g2, -1 | 153 | cmp %g1, -1 |
144 | movne %xcc, %g2, %g1 | 154 | bne,pt %xcc, 60f |
155 | nop | ||
156 | |||
157 | 661: rdpr %pstate, %g5 | ||
158 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate | ||
159 | .section .sun4v_2insn_patch, "ax" | ||
160 | .word 661b | ||
161 | SET_GL(1) | ||
162 | nop | ||
163 | .previous | ||
164 | |||
165 | rdpr %tl, %g3 | ||
166 | cmp %g3, 1 | ||
167 | bne,pn %xcc, winfix_trampoline | ||
168 | nop | ||
169 | ba,pt %xcc, etrap | ||
170 | rd %pc, %g7 | ||
171 | call hugetlb_setup | ||
172 | add %sp, PTREGS_OFF, %o0 | ||
173 | ba,pt %xcc, rtrap | ||
174 | nop | ||
175 | |||
145 | 60: | 176 | 60: |
146 | #endif | 177 | #endif |
147 | 178 | ||
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 097aee763af3..5062ff389e83 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
@@ -472,8 +472,13 @@ good_area: | |||
472 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) | 472 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) |
473 | mm_rss = mm->context.huge_pte_count; | 473 | mm_rss = mm->context.huge_pte_count; |
474 | if (unlikely(mm_rss > | 474 | if (unlikely(mm_rss > |
475 | mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit)) | 475 | mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit)) { |
476 | tsb_grow(mm, MM_TSB_HUGE, mm_rss); | 476 | if (mm->context.tsb_block[MM_TSB_HUGE].tsb) |
477 | tsb_grow(mm, MM_TSB_HUGE, mm_rss); | ||
478 | else | ||
479 | hugetlb_setup(regs); | ||
480 | |||
481 | } | ||
477 | #endif | 482 | #endif |
478 | return; | 483 | return; |
479 | 484 | ||
diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index 42c55df3aec3..01ee23dd724d 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c | |||
@@ -66,6 +66,56 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, | |||
66 | return 1; | 66 | return 1; |
67 | } | 67 | } |
68 | 68 | ||
69 | static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, | ||
70 | unsigned long end, int write, struct page **pages, | ||
71 | int *nr) | ||
72 | { | ||
73 | struct page *head, *page, *tail; | ||
74 | u32 mask; | ||
75 | int refs; | ||
76 | |||
77 | mask = PMD_HUGE_PRESENT; | ||
78 | if (write) | ||
79 | mask |= PMD_HUGE_WRITE; | ||
80 | if ((pmd_val(pmd) & mask) != mask) | ||
81 | return 0; | ||
82 | |||
83 | refs = 0; | ||
84 | head = pmd_page(pmd); | ||
85 | page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); | ||
86 | tail = page; | ||
87 | do { | ||
88 | VM_BUG_ON(compound_head(page) != head); | ||
89 | pages[*nr] = page; | ||
90 | (*nr)++; | ||
91 | page++; | ||
92 | refs++; | ||
93 | } while (addr += PAGE_SIZE, addr != end); | ||
94 | |||
95 | if (!page_cache_add_speculative(head, refs)) { | ||
96 | *nr -= refs; | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | if (unlikely(pmd_val(pmd) != pmd_val(*pmdp))) { | ||
101 | *nr -= refs; | ||
102 | while (refs--) | ||
103 | put_page(head); | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | /* Any tail page need their mapcount reference taken before we | ||
108 | * return. | ||
109 | */ | ||
110 | while (refs--) { | ||
111 | if (PageTail(tail)) | ||
112 | get_huge_page_tail(tail); | ||
113 | tail++; | ||
114 | } | ||
115 | |||
116 | return 1; | ||
117 | } | ||
118 | |||
69 | static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | 119 | static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, |
70 | int write, struct page **pages, int *nr) | 120 | int write, struct page **pages, int *nr) |
71 | { | 121 | { |
@@ -77,9 +127,14 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | |||
77 | pmd_t pmd = *pmdp; | 127 | pmd_t pmd = *pmdp; |
78 | 128 | ||
79 | next = pmd_addr_end(addr, end); | 129 | next = pmd_addr_end(addr, end); |
80 | if (pmd_none(pmd)) | 130 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) |
81 | return 0; | 131 | return 0; |
82 | if (!gup_pte_range(pmd, addr, next, write, pages, nr)) | 132 | if (unlikely(pmd_large(pmd))) { |
133 | if (!gup_huge_pmd(pmdp, pmd, addr, next, | ||
134 | write, pages, nr)) | ||
135 | return 0; | ||
136 | } else if (!gup_pte_range(pmd, addr, next, write, | ||
137 | pages, nr)) | ||
83 | return 0; | 138 | return 0; |
84 | } while (pmdp++, addr = next, addr != end); | 139 | } while (pmdp++, addr = next, addr != end); |
85 | 140 | ||
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index dde85ef1c56d..48e0c030e8f5 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c | |||
@@ -57,7 +57,7 @@ void show_mem(unsigned int filter) | |||
57 | printk("Mem-info:\n"); | 57 | printk("Mem-info:\n"); |
58 | show_free_areas(filter); | 58 | show_free_areas(filter); |
59 | printk("Free swap: %6ldkB\n", | 59 | printk("Free swap: %6ldkB\n", |
60 | nr_swap_pages << (PAGE_SHIFT-10)); | 60 | get_nr_swap_pages() << (PAGE_SHIFT-10)); |
61 | printk("%ld pages of RAM\n", totalram_pages); | 61 | printk("%ld pages of RAM\n", totalram_pages); |
62 | printk("%ld free pages\n", nr_free_pages()); | 62 | printk("%ld free pages\n", nr_free_pages()); |
63 | } | 63 | } |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index c3b72423c846..1588d33d5492 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -314,16 +314,31 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde | |||
314 | struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb; | 314 | struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb; |
315 | unsigned long tag; | 315 | unsigned long tag; |
316 | 316 | ||
317 | if (unlikely(!tsb)) | ||
318 | return; | ||
319 | |||
317 | tsb += ((address >> tsb_hash_shift) & | 320 | tsb += ((address >> tsb_hash_shift) & |
318 | (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL)); | 321 | (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL)); |
319 | tag = (address >> 22UL); | 322 | tag = (address >> 22UL); |
320 | tsb_insert(tsb, tag, tte); | 323 | tsb_insert(tsb, tag, tte); |
321 | } | 324 | } |
322 | 325 | ||
326 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) | ||
327 | static inline bool is_hugetlb_pte(pte_t pte) | ||
328 | { | ||
329 | if ((tlb_type == hypervisor && | ||
330 | (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) || | ||
331 | (tlb_type != hypervisor && | ||
332 | (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) | ||
333 | return true; | ||
334 | return false; | ||
335 | } | ||
336 | #endif | ||
337 | |||
323 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) | 338 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) |
324 | { | 339 | { |
325 | unsigned long tsb_index, tsb_hash_shift, flags; | ||
326 | struct mm_struct *mm; | 340 | struct mm_struct *mm; |
341 | unsigned long flags; | ||
327 | pte_t pte = *ptep; | 342 | pte_t pte = *ptep; |
328 | 343 | ||
329 | if (tlb_type != hypervisor) { | 344 | if (tlb_type != hypervisor) { |
@@ -335,25 +350,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * | |||
335 | 350 | ||
336 | mm = vma->vm_mm; | 351 | mm = vma->vm_mm; |
337 | 352 | ||
338 | tsb_index = MM_TSB_BASE; | ||
339 | tsb_hash_shift = PAGE_SHIFT; | ||
340 | |||
341 | spin_lock_irqsave(&mm->context.lock, flags); | 353 | spin_lock_irqsave(&mm->context.lock, flags); |
342 | 354 | ||
343 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) | 355 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) |
344 | if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) { | 356 | if (mm->context.huge_pte_count && is_hugetlb_pte(pte)) |
345 | if ((tlb_type == hypervisor && | 357 | __update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT, |
346 | (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) || | 358 | address, pte_val(pte)); |
347 | (tlb_type != hypervisor && | 359 | else |
348 | (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) { | ||
349 | tsb_index = MM_TSB_HUGE; | ||
350 | tsb_hash_shift = HPAGE_SHIFT; | ||
351 | } | ||
352 | } | ||
353 | #endif | 360 | #endif |
354 | 361 | __update_mmu_tsb_insert(mm, MM_TSB_BASE, PAGE_SHIFT, | |
355 | __update_mmu_tsb_insert(mm, tsb_index, tsb_hash_shift, | 362 | address, pte_val(pte)); |
356 | address, pte_val(pte)); | ||
357 | 363 | ||
358 | spin_unlock_irqrestore(&mm->context.lock, flags); | 364 | spin_unlock_irqrestore(&mm->context.lock, flags); |
359 | } | 365 | } |
@@ -2021,6 +2027,16 @@ static void __init patch_tlb_miss_handler_bitmap(void) | |||
2021 | flushi(&valid_addr_bitmap_insn[0]); | 2027 | flushi(&valid_addr_bitmap_insn[0]); |
2022 | } | 2028 | } |
2023 | 2029 | ||
2030 | static void __init register_page_bootmem_info(void) | ||
2031 | { | ||
2032 | #ifdef CONFIG_NEED_MULTIPLE_NODES | ||
2033 | int i; | ||
2034 | |||
2035 | for_each_online_node(i) | ||
2036 | if (NODE_DATA(i)->node_spanned_pages) | ||
2037 | register_page_bootmem_info_node(NODE_DATA(i)); | ||
2038 | #endif | ||
2039 | } | ||
2024 | void __init mem_init(void) | 2040 | void __init mem_init(void) |
2025 | { | 2041 | { |
2026 | unsigned long codepages, datapages, initpages; | 2042 | unsigned long codepages, datapages, initpages; |
@@ -2038,20 +2054,8 @@ void __init mem_init(void) | |||
2038 | 2054 | ||
2039 | high_memory = __va(last_valid_pfn << PAGE_SHIFT); | 2055 | high_memory = __va(last_valid_pfn << PAGE_SHIFT); |
2040 | 2056 | ||
2041 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 2057 | register_page_bootmem_info(); |
2042 | { | ||
2043 | int i; | ||
2044 | for_each_online_node(i) { | ||
2045 | if (NODE_DATA(i)->node_spanned_pages != 0) { | ||
2046 | totalram_pages += | ||
2047 | free_all_bootmem_node(NODE_DATA(i)); | ||
2048 | } | ||
2049 | } | ||
2050 | totalram_pages += free_low_memory_core_early(MAX_NUMNODES); | ||
2051 | } | ||
2052 | #else | ||
2053 | totalram_pages = free_all_bootmem(); | 2058 | totalram_pages = free_all_bootmem(); |
2054 | #endif | ||
2055 | 2059 | ||
2056 | /* We subtract one to account for the mem_map_zero page | 2060 | /* We subtract one to account for the mem_map_zero page |
2057 | * allocated below. | 2061 | * allocated below. |
@@ -2231,6 +2235,11 @@ void __meminit vmemmap_populate_print_last(void) | |||
2231 | node_start = 0; | 2235 | node_start = 0; |
2232 | } | 2236 | } |
2233 | } | 2237 | } |
2238 | |||
2239 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | ||
2240 | { | ||
2241 | } | ||
2242 | |||
2234 | #endif /* CONFIG_SPARSEMEM_VMEMMAP */ | 2243 | #endif /* CONFIG_SPARSEMEM_VMEMMAP */ |
2235 | 2244 | ||
2236 | static void prot_init_common(unsigned long page_none, | 2245 | static void prot_init_common(unsigned long page_none, |
@@ -2712,14 +2721,28 @@ static void context_reload(void *__data) | |||
2712 | load_secondary_context(mm); | 2721 | load_secondary_context(mm); |
2713 | } | 2722 | } |
2714 | 2723 | ||
2715 | void hugetlb_setup(struct mm_struct *mm) | 2724 | void hugetlb_setup(struct pt_regs *regs) |
2716 | { | 2725 | { |
2717 | struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE]; | 2726 | struct mm_struct *mm = current->mm; |
2727 | struct tsb_config *tp; | ||
2718 | 2728 | ||
2719 | if (likely(tp->tsb != NULL)) | 2729 | if (in_atomic() || !mm) { |
2720 | return; | 2730 | const struct exception_table_entry *entry; |
2731 | |||
2732 | entry = search_exception_tables(regs->tpc); | ||
2733 | if (entry) { | ||
2734 | regs->tpc = entry->fixup; | ||
2735 | regs->tnpc = regs->tpc + 4; | ||
2736 | return; | ||
2737 | } | ||
2738 | pr_alert("Unexpected HugeTLB setup in atomic context.\n"); | ||
2739 | die_if_kernel("HugeTSB in atomic", regs); | ||
2740 | } | ||
2741 | |||
2742 | tp = &mm->context.tsb_block[MM_TSB_HUGE]; | ||
2743 | if (likely(tp->tsb == NULL)) | ||
2744 | tsb_grow(mm, MM_TSB_HUGE, 0); | ||
2721 | 2745 | ||
2722 | tsb_grow(mm, MM_TSB_HUGE, 0); | ||
2723 | tsb_context_switch(mm); | 2746 | tsb_context_switch(mm); |
2724 | smp_tsb_sync(mm); | 2747 | smp_tsb_sync(mm); |
2725 | 2748 | ||
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 3e8fec391fe0..ba6ae7ffdc2c 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
@@ -135,8 +135,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
135 | mm->context.huge_pte_count++; | 135 | mm->context.huge_pte_count++; |
136 | else | 136 | else |
137 | mm->context.huge_pte_count--; | 137 | mm->context.huge_pte_count--; |
138 | if (mm->context.huge_pte_count == 1) | 138 | |
139 | hugetlb_setup(mm); | 139 | /* Do not try to allocate the TSB hash table if we |
140 | * don't have one already. We have various locks held | ||
141 | * and thus we'll end up doing a GFP_KERNEL allocation | ||
142 | * in an atomic context. | ||
143 | * | ||
144 | * Instead, we let the first TLB miss on a hugepage | ||
145 | * take care of this. | ||
146 | */ | ||
140 | } | 147 | } |
141 | 148 | ||
142 | if (!pmd_none(orig)) { | 149 | if (!pmd_none(orig)) { |
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 7f6474347491..428982b9becf 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c | |||
@@ -314,7 +314,7 @@ void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss) | |||
314 | retry_tsb_alloc: | 314 | retry_tsb_alloc: |
315 | gfp_flags = GFP_KERNEL; | 315 | gfp_flags = GFP_KERNEL; |
316 | if (new_size > (PAGE_SIZE * 2)) | 316 | if (new_size > (PAGE_SIZE * 2)) |
317 | gfp_flags = __GFP_NOWARN | __GFP_NORETRY; | 317 | gfp_flags |= __GFP_NOWARN | __GFP_NORETRY; |
318 | 318 | ||
319 | new_tsb = kmem_cache_alloc_node(tsb_caches[new_cache_index], | 319 | new_tsb = kmem_cache_alloc_node(tsb_caches[new_cache_index], |
320 | gfp_flags, numa_node_id()); | 320 | gfp_flags, numa_node_id()); |