diff options
author | Ingo Molnar <mingo@kernel.org> | 2018-03-12 07:14:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-03-12 07:14:57 -0400 |
commit | 9884afa2fdce71cd35bb79303f9050f0d76e3d03 (patch) | |
tree | e4bd1187eee271fd93b8a99c5a951afaa53c4d80 | |
parent | fbfcd0199170984bd3c2812e49ed0fe7b226959a (diff) | |
parent | 0c8efd610b58cb23cefdfa12015799079aef94ae (diff) |
Merge tag 'v4.16-rc5' into locking/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
88 files changed, 850 insertions, 1084 deletions
diff --git a/Documentation/devicetree/bindings/dma/mv-xor-v2.txt b/Documentation/devicetree/bindings/dma/mv-xor-v2.txt index 217a90eaabe7..9c38bbe7e6d7 100644 --- a/Documentation/devicetree/bindings/dma/mv-xor-v2.txt +++ b/Documentation/devicetree/bindings/dma/mv-xor-v2.txt | |||
@@ -11,7 +11,11 @@ Required properties: | |||
11 | interrupts. | 11 | interrupts. |
12 | 12 | ||
13 | Optional properties: | 13 | Optional properties: |
14 | - clocks: Optional reference to the clock used by the XOR engine. | 14 | - clocks: Optional reference to the clocks used by the XOR engine. |
15 | - clock-names: mandatory if there is a second clock, in this case the | ||
16 | name must be "core" for the first clock and "reg" for the second | ||
17 | one | ||
18 | |||
15 | 19 | ||
16 | Example: | 20 | Example: |
17 | 21 | ||
@@ -2,7 +2,7 @@ | |||
2 | VERSION = 4 | 2 | VERSION = 4 |
3 | PATCHLEVEL = 16 | 3 | PATCHLEVEL = 16 |
4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
5 | EXTRAVERSION = -rc4 | 5 | EXTRAVERSION = -rc5 |
6 | NAME = Fearless Coyote | 6 | NAME = Fearless Coyote |
7 | 7 | ||
8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index eb7f43f23521..0fa71a78ec99 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -2307,7 +2307,7 @@ choice | |||
2307 | it can be used to assist security vulnerability exploitation. | 2307 | it can be used to assist security vulnerability exploitation. |
2308 | 2308 | ||
2309 | This setting can be changed at boot time via the kernel command | 2309 | This setting can be changed at boot time via the kernel command |
2310 | line parameter vsyscall=[native|emulate|none]. | 2310 | line parameter vsyscall=[emulate|none]. |
2311 | 2311 | ||
2312 | On a system with recent enough glibc (2.14 or newer) and no | 2312 | On a system with recent enough glibc (2.14 or newer) and no |
2313 | static binaries, you can say None without a performance penalty | 2313 | static binaries, you can say None without a performance penalty |
@@ -2315,15 +2315,6 @@ choice | |||
2315 | 2315 | ||
2316 | If unsure, select "Emulate". | 2316 | If unsure, select "Emulate". |
2317 | 2317 | ||
2318 | config LEGACY_VSYSCALL_NATIVE | ||
2319 | bool "Native" | ||
2320 | help | ||
2321 | Actual executable code is located in the fixed vsyscall | ||
2322 | address mapping, implementing time() efficiently. Since | ||
2323 | this makes the mapping executable, it can be used during | ||
2324 | security vulnerability exploitation (traditionally as | ||
2325 | ROP gadgets). This configuration is not recommended. | ||
2326 | |||
2327 | config LEGACY_VSYSCALL_EMULATE | 2318 | config LEGACY_VSYSCALL_EMULATE |
2328 | bool "Emulate" | 2319 | bool "Emulate" |
2329 | help | 2320 | help |
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index e811dd9c5e99..08425c42f8b7 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S | |||
@@ -363,9 +363,7 @@ ENTRY(entry_INT80_compat) | |||
363 | pushq 2*8(%rdi) /* regs->ip */ | 363 | pushq 2*8(%rdi) /* regs->ip */ |
364 | pushq 1*8(%rdi) /* regs->orig_ax */ | 364 | pushq 1*8(%rdi) /* regs->orig_ax */ |
365 | 365 | ||
366 | movq (%rdi), %rdi /* restore %rdi */ | 366 | pushq (%rdi) /* pt_regs->di */ |
367 | |||
368 | pushq %rdi /* pt_regs->di */ | ||
369 | pushq %rsi /* pt_regs->si */ | 367 | pushq %rsi /* pt_regs->si */ |
370 | pushq %rdx /* pt_regs->dx */ | 368 | pushq %rdx /* pt_regs->dx */ |
371 | pushq %rcx /* pt_regs->cx */ | 369 | pushq %rcx /* pt_regs->cx */ |
@@ -406,15 +404,3 @@ ENTRY(entry_INT80_compat) | |||
406 | TRACE_IRQS_ON | 404 | TRACE_IRQS_ON |
407 | jmp swapgs_restore_regs_and_return_to_usermode | 405 | jmp swapgs_restore_regs_and_return_to_usermode |
408 | END(entry_INT80_compat) | 406 | END(entry_INT80_compat) |
409 | |||
410 | ENTRY(stub32_clone) | ||
411 | /* | ||
412 | * The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr). | ||
413 | * The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val). | ||
414 | * | ||
415 | * The native 64-bit kernel's sys_clone() implements the latter, | ||
416 | * so we need to swap arguments here before calling it: | ||
417 | */ | ||
418 | xchg %r8, %rcx | ||
419 | jmp sys_clone | ||
420 | ENDPROC(stub32_clone) | ||
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index 448ac2161112..2a5e99cff859 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl | |||
@@ -8,12 +8,12 @@ | |||
8 | # | 8 | # |
9 | 0 i386 restart_syscall sys_restart_syscall | 9 | 0 i386 restart_syscall sys_restart_syscall |
10 | 1 i386 exit sys_exit | 10 | 1 i386 exit sys_exit |
11 | 2 i386 fork sys_fork sys_fork | 11 | 2 i386 fork sys_fork |
12 | 3 i386 read sys_read | 12 | 3 i386 read sys_read |
13 | 4 i386 write sys_write | 13 | 4 i386 write sys_write |
14 | 5 i386 open sys_open compat_sys_open | 14 | 5 i386 open sys_open compat_sys_open |
15 | 6 i386 close sys_close | 15 | 6 i386 close sys_close |
16 | 7 i386 waitpid sys_waitpid sys32_waitpid | 16 | 7 i386 waitpid sys_waitpid compat_sys_x86_waitpid |
17 | 8 i386 creat sys_creat | 17 | 8 i386 creat sys_creat |
18 | 9 i386 link sys_link | 18 | 9 i386 link sys_link |
19 | 10 i386 unlink sys_unlink | 19 | 10 i386 unlink sys_unlink |
@@ -78,7 +78,7 @@ | |||
78 | 69 i386 ssetmask sys_ssetmask | 78 | 69 i386 ssetmask sys_ssetmask |
79 | 70 i386 setreuid sys_setreuid16 | 79 | 70 i386 setreuid sys_setreuid16 |
80 | 71 i386 setregid sys_setregid16 | 80 | 71 i386 setregid sys_setregid16 |
81 | 72 i386 sigsuspend sys_sigsuspend sys_sigsuspend | 81 | 72 i386 sigsuspend sys_sigsuspend |
82 | 73 i386 sigpending sys_sigpending compat_sys_sigpending | 82 | 73 i386 sigpending sys_sigpending compat_sys_sigpending |
83 | 74 i386 sethostname sys_sethostname | 83 | 74 i386 sethostname sys_sethostname |
84 | 75 i386 setrlimit sys_setrlimit compat_sys_setrlimit | 84 | 75 i386 setrlimit sys_setrlimit compat_sys_setrlimit |
@@ -96,7 +96,7 @@ | |||
96 | 87 i386 swapon sys_swapon | 96 | 87 i386 swapon sys_swapon |
97 | 88 i386 reboot sys_reboot | 97 | 88 i386 reboot sys_reboot |
98 | 89 i386 readdir sys_old_readdir compat_sys_old_readdir | 98 | 89 i386 readdir sys_old_readdir compat_sys_old_readdir |
99 | 90 i386 mmap sys_old_mmap sys32_mmap | 99 | 90 i386 mmap sys_old_mmap compat_sys_x86_mmap |
100 | 91 i386 munmap sys_munmap | 100 | 91 i386 munmap sys_munmap |
101 | 92 i386 truncate sys_truncate compat_sys_truncate | 101 | 92 i386 truncate sys_truncate compat_sys_truncate |
102 | 93 i386 ftruncate sys_ftruncate compat_sys_ftruncate | 102 | 93 i386 ftruncate sys_ftruncate compat_sys_ftruncate |
@@ -126,7 +126,7 @@ | |||
126 | 117 i386 ipc sys_ipc compat_sys_ipc | 126 | 117 i386 ipc sys_ipc compat_sys_ipc |
127 | 118 i386 fsync sys_fsync | 127 | 118 i386 fsync sys_fsync |
128 | 119 i386 sigreturn sys_sigreturn sys32_sigreturn | 128 | 119 i386 sigreturn sys_sigreturn sys32_sigreturn |
129 | 120 i386 clone sys_clone stub32_clone | 129 | 120 i386 clone sys_clone compat_sys_x86_clone |
130 | 121 i386 setdomainname sys_setdomainname | 130 | 121 i386 setdomainname sys_setdomainname |
131 | 122 i386 uname sys_newuname | 131 | 122 i386 uname sys_newuname |
132 | 123 i386 modify_ldt sys_modify_ldt | 132 | 123 i386 modify_ldt sys_modify_ldt |
@@ -186,8 +186,8 @@ | |||
186 | 177 i386 rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait | 186 | 177 i386 rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait |
187 | 178 i386 rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo | 187 | 178 i386 rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo |
188 | 179 i386 rt_sigsuspend sys_rt_sigsuspend | 188 | 179 i386 rt_sigsuspend sys_rt_sigsuspend |
189 | 180 i386 pread64 sys_pread64 sys32_pread | 189 | 180 i386 pread64 sys_pread64 compat_sys_x86_pread |
190 | 181 i386 pwrite64 sys_pwrite64 sys32_pwrite | 190 | 181 i386 pwrite64 sys_pwrite64 compat_sys_x86_pwrite |
191 | 182 i386 chown sys_chown16 | 191 | 182 i386 chown sys_chown16 |
192 | 183 i386 getcwd sys_getcwd | 192 | 183 i386 getcwd sys_getcwd |
193 | 184 i386 capget sys_capget | 193 | 184 i386 capget sys_capget |
@@ -196,14 +196,14 @@ | |||
196 | 187 i386 sendfile sys_sendfile compat_sys_sendfile | 196 | 187 i386 sendfile sys_sendfile compat_sys_sendfile |
197 | 188 i386 getpmsg | 197 | 188 i386 getpmsg |
198 | 189 i386 putpmsg | 198 | 189 i386 putpmsg |
199 | 190 i386 vfork sys_vfork sys_vfork | 199 | 190 i386 vfork sys_vfork |
200 | 191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit | 200 | 191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit |
201 | 192 i386 mmap2 sys_mmap_pgoff | 201 | 192 i386 mmap2 sys_mmap_pgoff |
202 | 193 i386 truncate64 sys_truncate64 sys32_truncate64 | 202 | 193 i386 truncate64 sys_truncate64 compat_sys_x86_truncate64 |
203 | 194 i386 ftruncate64 sys_ftruncate64 sys32_ftruncate64 | 203 | 194 i386 ftruncate64 sys_ftruncate64 compat_sys_x86_ftruncate64 |
204 | 195 i386 stat64 sys_stat64 sys32_stat64 | 204 | 195 i386 stat64 sys_stat64 compat_sys_x86_stat64 |
205 | 196 i386 lstat64 sys_lstat64 sys32_lstat64 | 205 | 196 i386 lstat64 sys_lstat64 compat_sys_x86_lstat64 |
206 | 197 i386 fstat64 sys_fstat64 sys32_fstat64 | 206 | 197 i386 fstat64 sys_fstat64 compat_sys_x86_fstat64 |
207 | 198 i386 lchown32 sys_lchown | 207 | 198 i386 lchown32 sys_lchown |
208 | 199 i386 getuid32 sys_getuid | 208 | 199 i386 getuid32 sys_getuid |
209 | 200 i386 getgid32 sys_getgid | 209 | 200 i386 getgid32 sys_getgid |
@@ -231,7 +231,7 @@ | |||
231 | # 222 is unused | 231 | # 222 is unused |
232 | # 223 is unused | 232 | # 223 is unused |
233 | 224 i386 gettid sys_gettid | 233 | 224 i386 gettid sys_gettid |
234 | 225 i386 readahead sys_readahead sys32_readahead | 234 | 225 i386 readahead sys_readahead compat_sys_x86_readahead |
235 | 226 i386 setxattr sys_setxattr | 235 | 226 i386 setxattr sys_setxattr |
236 | 227 i386 lsetxattr sys_lsetxattr | 236 | 227 i386 lsetxattr sys_lsetxattr |
237 | 228 i386 fsetxattr sys_fsetxattr | 237 | 228 i386 fsetxattr sys_fsetxattr |
@@ -256,7 +256,7 @@ | |||
256 | 247 i386 io_getevents sys_io_getevents compat_sys_io_getevents | 256 | 247 i386 io_getevents sys_io_getevents compat_sys_io_getevents |
257 | 248 i386 io_submit sys_io_submit compat_sys_io_submit | 257 | 248 i386 io_submit sys_io_submit compat_sys_io_submit |
258 | 249 i386 io_cancel sys_io_cancel | 258 | 249 i386 io_cancel sys_io_cancel |
259 | 250 i386 fadvise64 sys_fadvise64 sys32_fadvise64 | 259 | 250 i386 fadvise64 sys_fadvise64 compat_sys_x86_fadvise64 |
260 | # 251 is available for reuse (was briefly sys_set_zone_reclaim) | 260 | # 251 is available for reuse (was briefly sys_set_zone_reclaim) |
261 | 252 i386 exit_group sys_exit_group | 261 | 252 i386 exit_group sys_exit_group |
262 | 253 i386 lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie | 262 | 253 i386 lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie |
@@ -278,7 +278,7 @@ | |||
278 | 269 i386 fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 | 278 | 269 i386 fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 |
279 | 270 i386 tgkill sys_tgkill | 279 | 270 i386 tgkill sys_tgkill |
280 | 271 i386 utimes sys_utimes compat_sys_utimes | 280 | 271 i386 utimes sys_utimes compat_sys_utimes |
281 | 272 i386 fadvise64_64 sys_fadvise64_64 sys32_fadvise64_64 | 281 | 272 i386 fadvise64_64 sys_fadvise64_64 compat_sys_x86_fadvise64_64 |
282 | 273 i386 vserver | 282 | 273 i386 vserver |
283 | 274 i386 mbind sys_mbind | 283 | 274 i386 mbind sys_mbind |
284 | 275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy | 284 | 275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy |
@@ -306,7 +306,7 @@ | |||
306 | 297 i386 mknodat sys_mknodat | 306 | 297 i386 mknodat sys_mknodat |
307 | 298 i386 fchownat sys_fchownat | 307 | 298 i386 fchownat sys_fchownat |
308 | 299 i386 futimesat sys_futimesat compat_sys_futimesat | 308 | 299 i386 futimesat sys_futimesat compat_sys_futimesat |
309 | 300 i386 fstatat64 sys_fstatat64 sys32_fstatat | 309 | 300 i386 fstatat64 sys_fstatat64 compat_sys_x86_fstatat |
310 | 301 i386 unlinkat sys_unlinkat | 310 | 301 i386 unlinkat sys_unlinkat |
311 | 302 i386 renameat sys_renameat | 311 | 302 i386 renameat sys_renameat |
312 | 303 i386 linkat sys_linkat | 312 | 303 i386 linkat sys_linkat |
@@ -320,7 +320,7 @@ | |||
320 | 311 i386 set_robust_list sys_set_robust_list compat_sys_set_robust_list | 320 | 311 i386 set_robust_list sys_set_robust_list compat_sys_set_robust_list |
321 | 312 i386 get_robust_list sys_get_robust_list compat_sys_get_robust_list | 321 | 312 i386 get_robust_list sys_get_robust_list compat_sys_get_robust_list |
322 | 313 i386 splice sys_splice | 322 | 313 i386 splice sys_splice |
323 | 314 i386 sync_file_range sys_sync_file_range sys32_sync_file_range | 323 | 314 i386 sync_file_range sys_sync_file_range compat_sys_x86_sync_file_range |
324 | 315 i386 tee sys_tee | 324 | 315 i386 tee sys_tee |
325 | 316 i386 vmsplice sys_vmsplice compat_sys_vmsplice | 325 | 316 i386 vmsplice sys_vmsplice compat_sys_vmsplice |
326 | 317 i386 move_pages sys_move_pages compat_sys_move_pages | 326 | 317 i386 move_pages sys_move_pages compat_sys_move_pages |
@@ -330,7 +330,7 @@ | |||
330 | 321 i386 signalfd sys_signalfd compat_sys_signalfd | 330 | 321 i386 signalfd sys_signalfd compat_sys_signalfd |
331 | 322 i386 timerfd_create sys_timerfd_create | 331 | 322 i386 timerfd_create sys_timerfd_create |
332 | 323 i386 eventfd sys_eventfd | 332 | 323 i386 eventfd sys_eventfd |
333 | 324 i386 fallocate sys_fallocate sys32_fallocate | 333 | 324 i386 fallocate sys_fallocate compat_sys_x86_fallocate |
334 | 325 i386 timerfd_settime sys_timerfd_settime compat_sys_timerfd_settime | 334 | 325 i386 timerfd_settime sys_timerfd_settime compat_sys_timerfd_settime |
335 | 326 i386 timerfd_gettime sys_timerfd_gettime compat_sys_timerfd_gettime | 335 | 326 i386 timerfd_gettime sys_timerfd_gettime compat_sys_timerfd_gettime |
336 | 327 i386 signalfd4 sys_signalfd4 compat_sys_signalfd4 | 336 | 327 i386 signalfd4 sys_signalfd4 compat_sys_signalfd4 |
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c index 577fa8adb785..8560ef68a9d6 100644 --- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c | |||
@@ -42,10 +42,8 @@ | |||
42 | #define CREATE_TRACE_POINTS | 42 | #define CREATE_TRACE_POINTS |
43 | #include "vsyscall_trace.h" | 43 | #include "vsyscall_trace.h" |
44 | 44 | ||
45 | static enum { EMULATE, NATIVE, NONE } vsyscall_mode = | 45 | static enum { EMULATE, NONE } vsyscall_mode = |
46 | #if defined(CONFIG_LEGACY_VSYSCALL_NATIVE) | 46 | #ifdef CONFIG_LEGACY_VSYSCALL_NONE |
47 | NATIVE; | ||
48 | #elif defined(CONFIG_LEGACY_VSYSCALL_NONE) | ||
49 | NONE; | 47 | NONE; |
50 | #else | 48 | #else |
51 | EMULATE; | 49 | EMULATE; |
@@ -56,8 +54,6 @@ static int __init vsyscall_setup(char *str) | |||
56 | if (str) { | 54 | if (str) { |
57 | if (!strcmp("emulate", str)) | 55 | if (!strcmp("emulate", str)) |
58 | vsyscall_mode = EMULATE; | 56 | vsyscall_mode = EMULATE; |
59 | else if (!strcmp("native", str)) | ||
60 | vsyscall_mode = NATIVE; | ||
61 | else if (!strcmp("none", str)) | 57 | else if (!strcmp("none", str)) |
62 | vsyscall_mode = NONE; | 58 | vsyscall_mode = NONE; |
63 | else | 59 | else |
@@ -139,10 +135,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) | |||
139 | 135 | ||
140 | WARN_ON_ONCE(address != regs->ip); | 136 | WARN_ON_ONCE(address != regs->ip); |
141 | 137 | ||
142 | /* This should be unreachable in NATIVE mode. */ | ||
143 | if (WARN_ON(vsyscall_mode == NATIVE)) | ||
144 | return false; | ||
145 | |||
146 | if (vsyscall_mode == NONE) { | 138 | if (vsyscall_mode == NONE) { |
147 | warn_bad_vsyscall(KERN_INFO, regs, | 139 | warn_bad_vsyscall(KERN_INFO, regs, |
148 | "vsyscall attempted with vsyscall=none"); | 140 | "vsyscall attempted with vsyscall=none"); |
@@ -370,9 +362,7 @@ void __init map_vsyscall(void) | |||
370 | 362 | ||
371 | if (vsyscall_mode != NONE) { | 363 | if (vsyscall_mode != NONE) { |
372 | __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, | 364 | __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, |
373 | vsyscall_mode == NATIVE | 365 | PAGE_KERNEL_VVAR); |
374 | ? PAGE_KERNEL_VSYSCALL | ||
375 | : PAGE_KERNEL_VVAR); | ||
376 | set_vsyscall_pgtable_user_bits(swapper_pg_dir); | 366 | set_vsyscall_pgtable_user_bits(swapper_pg_dir); |
377 | } | 367 | } |
378 | 368 | ||
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 6d8044ab1060..22ec65bc033a 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c | |||
@@ -3606,7 +3606,7 @@ static struct intel_uncore_type skx_uncore_imc = { | |||
3606 | }; | 3606 | }; |
3607 | 3607 | ||
3608 | static struct attribute *skx_upi_uncore_formats_attr[] = { | 3608 | static struct attribute *skx_upi_uncore_formats_attr[] = { |
3609 | &format_attr_event_ext.attr, | 3609 | &format_attr_event.attr, |
3610 | &format_attr_umask_ext.attr, | 3610 | &format_attr_umask_ext.attr, |
3611 | &format_attr_edge.attr, | 3611 | &format_attr_edge.attr, |
3612 | &format_attr_inv.attr, | 3612 | &format_attr_inv.attr, |
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 96cd33bbfc85..6512498bbef6 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c | |||
@@ -51,15 +51,14 @@ | |||
51 | #define AA(__x) ((unsigned long)(__x)) | 51 | #define AA(__x) ((unsigned long)(__x)) |
52 | 52 | ||
53 | 53 | ||
54 | asmlinkage long sys32_truncate64(const char __user *filename, | 54 | COMPAT_SYSCALL_DEFINE3(x86_truncate64, const char __user *, filename, |
55 | unsigned long offset_low, | 55 | unsigned long, offset_low, unsigned long, offset_high) |
56 | unsigned long offset_high) | ||
57 | { | 56 | { |
58 | return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); | 57 | return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); |
59 | } | 58 | } |
60 | 59 | ||
61 | asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long offset_low, | 60 | COMPAT_SYSCALL_DEFINE3(x86_ftruncate64, unsigned int, fd, |
62 | unsigned long offset_high) | 61 | unsigned long, offset_low, unsigned long, offset_high) |
63 | { | 62 | { |
64 | return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low); | 63 | return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low); |
65 | } | 64 | } |
@@ -96,8 +95,8 @@ static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat) | |||
96 | return 0; | 95 | return 0; |
97 | } | 96 | } |
98 | 97 | ||
99 | asmlinkage long sys32_stat64(const char __user *filename, | 98 | COMPAT_SYSCALL_DEFINE2(x86_stat64, const char __user *, filename, |
100 | struct stat64 __user *statbuf) | 99 | struct stat64 __user *, statbuf) |
101 | { | 100 | { |
102 | struct kstat stat; | 101 | struct kstat stat; |
103 | int ret = vfs_stat(filename, &stat); | 102 | int ret = vfs_stat(filename, &stat); |
@@ -107,8 +106,8 @@ asmlinkage long sys32_stat64(const char __user *filename, | |||
107 | return ret; | 106 | return ret; |
108 | } | 107 | } |
109 | 108 | ||
110 | asmlinkage long sys32_lstat64(const char __user *filename, | 109 | COMPAT_SYSCALL_DEFINE2(x86_lstat64, const char __user *, filename, |
111 | struct stat64 __user *statbuf) | 110 | struct stat64 __user *, statbuf) |
112 | { | 111 | { |
113 | struct kstat stat; | 112 | struct kstat stat; |
114 | int ret = vfs_lstat(filename, &stat); | 113 | int ret = vfs_lstat(filename, &stat); |
@@ -117,7 +116,8 @@ asmlinkage long sys32_lstat64(const char __user *filename, | |||
117 | return ret; | 116 | return ret; |
118 | } | 117 | } |
119 | 118 | ||
120 | asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf) | 119 | COMPAT_SYSCALL_DEFINE2(x86_fstat64, unsigned int, fd, |
120 | struct stat64 __user *, statbuf) | ||
121 | { | 121 | { |
122 | struct kstat stat; | 122 | struct kstat stat; |
123 | int ret = vfs_fstat(fd, &stat); | 123 | int ret = vfs_fstat(fd, &stat); |
@@ -126,8 +126,9 @@ asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf) | |||
126 | return ret; | 126 | return ret; |
127 | } | 127 | } |
128 | 128 | ||
129 | asmlinkage long sys32_fstatat(unsigned int dfd, const char __user *filename, | 129 | COMPAT_SYSCALL_DEFINE4(x86_fstatat, unsigned int, dfd, |
130 | struct stat64 __user *statbuf, int flag) | 130 | const char __user *, filename, |
131 | struct stat64 __user *, statbuf, int, flag) | ||
131 | { | 132 | { |
132 | struct kstat stat; | 133 | struct kstat stat; |
133 | int error; | 134 | int error; |
@@ -153,7 +154,7 @@ struct mmap_arg_struct32 { | |||
153 | unsigned int offset; | 154 | unsigned int offset; |
154 | }; | 155 | }; |
155 | 156 | ||
156 | asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg) | 157 | COMPAT_SYSCALL_DEFINE1(x86_mmap, struct mmap_arg_struct32 __user *, arg) |
157 | { | 158 | { |
158 | struct mmap_arg_struct32 a; | 159 | struct mmap_arg_struct32 a; |
159 | 160 | ||
@@ -167,22 +168,22 @@ asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg) | |||
167 | a.offset>>PAGE_SHIFT); | 168 | a.offset>>PAGE_SHIFT); |
168 | } | 169 | } |
169 | 170 | ||
170 | asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int __user *stat_addr, | 171 | COMPAT_SYSCALL_DEFINE3(x86_waitpid, compat_pid_t, pid, unsigned int __user *, |
171 | int options) | 172 | stat_addr, int, options) |
172 | { | 173 | { |
173 | return compat_sys_wait4(pid, stat_addr, options, NULL); | 174 | return compat_sys_wait4(pid, stat_addr, options, NULL); |
174 | } | 175 | } |
175 | 176 | ||
176 | /* warning: next two assume little endian */ | 177 | /* warning: next two assume little endian */ |
177 | asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count, | 178 | COMPAT_SYSCALL_DEFINE5(x86_pread, unsigned int, fd, char __user *, ubuf, |
178 | u32 poslo, u32 poshi) | 179 | u32, count, u32, poslo, u32, poshi) |
179 | { | 180 | { |
180 | return sys_pread64(fd, ubuf, count, | 181 | return sys_pread64(fd, ubuf, count, |
181 | ((loff_t)AA(poshi) << 32) | AA(poslo)); | 182 | ((loff_t)AA(poshi) << 32) | AA(poslo)); |
182 | } | 183 | } |
183 | 184 | ||
184 | asmlinkage long sys32_pwrite(unsigned int fd, const char __user *ubuf, | 185 | COMPAT_SYSCALL_DEFINE5(x86_pwrite, unsigned int, fd, const char __user *, ubuf, |
185 | u32 count, u32 poslo, u32 poshi) | 186 | u32, count, u32, poslo, u32, poshi) |
186 | { | 187 | { |
187 | return sys_pwrite64(fd, ubuf, count, | 188 | return sys_pwrite64(fd, ubuf, count, |
188 | ((loff_t)AA(poshi) << 32) | AA(poslo)); | 189 | ((loff_t)AA(poshi) << 32) | AA(poslo)); |
@@ -193,8 +194,9 @@ asmlinkage long sys32_pwrite(unsigned int fd, const char __user *ubuf, | |||
193 | * Some system calls that need sign extended arguments. This could be | 194 | * Some system calls that need sign extended arguments. This could be |
194 | * done by a generic wrapper. | 195 | * done by a generic wrapper. |
195 | */ | 196 | */ |
196 | long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, | 197 | COMPAT_SYSCALL_DEFINE6(x86_fadvise64_64, int, fd, __u32, offset_low, |
197 | __u32 len_low, __u32 len_high, int advice) | 198 | __u32, offset_high, __u32, len_low, __u32, len_high, |
199 | int, advice) | ||
198 | { | 200 | { |
199 | return sys_fadvise64_64(fd, | 201 | return sys_fadvise64_64(fd, |
200 | (((u64)offset_high)<<32) | offset_low, | 202 | (((u64)offset_high)<<32) | offset_low, |
@@ -202,31 +204,43 @@ long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, | |||
202 | advice); | 204 | advice); |
203 | } | 205 | } |
204 | 206 | ||
205 | asmlinkage ssize_t sys32_readahead(int fd, unsigned off_lo, unsigned off_hi, | 207 | COMPAT_SYSCALL_DEFINE4(x86_readahead, int, fd, unsigned int, off_lo, |
206 | size_t count) | 208 | unsigned int, off_hi, size_t, count) |
207 | { | 209 | { |
208 | return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count); | 210 | return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count); |
209 | } | 211 | } |
210 | 212 | ||
211 | asmlinkage long sys32_sync_file_range(int fd, unsigned off_low, unsigned off_hi, | 213 | COMPAT_SYSCALL_DEFINE6(x86_sync_file_range, int, fd, unsigned int, off_low, |
212 | unsigned n_low, unsigned n_hi, int flags) | 214 | unsigned int, off_hi, unsigned int, n_low, |
215 | unsigned int, n_hi, int, flags) | ||
213 | { | 216 | { |
214 | return sys_sync_file_range(fd, | 217 | return sys_sync_file_range(fd, |
215 | ((u64)off_hi << 32) | off_low, | 218 | ((u64)off_hi << 32) | off_low, |
216 | ((u64)n_hi << 32) | n_low, flags); | 219 | ((u64)n_hi << 32) | n_low, flags); |
217 | } | 220 | } |
218 | 221 | ||
219 | asmlinkage long sys32_fadvise64(int fd, unsigned offset_lo, unsigned offset_hi, | 222 | COMPAT_SYSCALL_DEFINE5(x86_fadvise64, int, fd, unsigned int, offset_lo, |
220 | size_t len, int advice) | 223 | unsigned int, offset_hi, size_t, len, int, advice) |
221 | { | 224 | { |
222 | return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo, | 225 | return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo, |
223 | len, advice); | 226 | len, advice); |
224 | } | 227 | } |
225 | 228 | ||
226 | asmlinkage long sys32_fallocate(int fd, int mode, unsigned offset_lo, | 229 | COMPAT_SYSCALL_DEFINE6(x86_fallocate, int, fd, int, mode, |
227 | unsigned offset_hi, unsigned len_lo, | 230 | unsigned int, offset_lo, unsigned int, offset_hi, |
228 | unsigned len_hi) | 231 | unsigned int, len_lo, unsigned int, len_hi) |
229 | { | 232 | { |
230 | return sys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo, | 233 | return sys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo, |
231 | ((u64)len_hi << 32) | len_lo); | 234 | ((u64)len_hi << 32) | len_lo); |
232 | } | 235 | } |
236 | |||
237 | /* | ||
238 | * The 32-bit clone ABI is CONFIG_CLONE_BACKWARDS | ||
239 | */ | ||
240 | COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, | ||
241 | unsigned long, newsp, int __user *, parent_tidptr, | ||
242 | unsigned long, tls_val, int __user *, child_tidptr) | ||
243 | { | ||
244 | return sys_clone(clone_flags, newsp, parent_tidptr, child_tidptr, | ||
245 | tls_val); | ||
246 | } | ||
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 246f15b4e64c..acfe755562a6 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h | |||
@@ -174,7 +174,6 @@ enum page_cache_mode { | |||
174 | #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) | 174 | #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) |
175 | #define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) | 175 | #define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) |
176 | #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_NOCACHE) | 176 | #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_NOCACHE) |
177 | #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) | ||
178 | #define __PAGE_KERNEL_VVAR (__PAGE_KERNEL_RO | _PAGE_USER) | 177 | #define __PAGE_KERNEL_VVAR (__PAGE_KERNEL_RO | _PAGE_USER) |
179 | #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) | 178 | #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) |
180 | #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) | 179 | #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) |
@@ -206,7 +205,6 @@ enum page_cache_mode { | |||
206 | #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) | 205 | #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) |
207 | #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) | 206 | #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) |
208 | #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) | 207 | #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) |
209 | #define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC) | ||
210 | #define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) | 208 | #define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) |
211 | 209 | ||
212 | #define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) | 210 | #define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) |
diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h index d6baf23782bc..5c019d23d06b 100644 --- a/arch/x86/include/asm/sections.h +++ b/arch/x86/include/asm/sections.h | |||
@@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[]; | |||
10 | 10 | ||
11 | #if defined(CONFIG_X86_64) | 11 | #if defined(CONFIG_X86_64) |
12 | extern char __end_rodata_hpage_align[]; | 12 | extern char __end_rodata_hpage_align[]; |
13 | extern char __entry_trampoline_start[], __entry_trampoline_end[]; | ||
13 | #endif | 14 | #endif |
14 | 15 | ||
15 | #endif /* _ASM_X86_SECTIONS_H */ | 16 | #endif /* _ASM_X86_SECTIONS_H */ |
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h index 82c34ee25a65..906794aa034e 100644 --- a/arch/x86/include/asm/sys_ia32.h +++ b/arch/x86/include/asm/sys_ia32.h | |||
@@ -20,31 +20,43 @@ | |||
20 | #include <asm/ia32.h> | 20 | #include <asm/ia32.h> |
21 | 21 | ||
22 | /* ia32/sys_ia32.c */ | 22 | /* ia32/sys_ia32.c */ |
23 | asmlinkage long sys32_truncate64(const char __user *, unsigned long, unsigned long); | 23 | asmlinkage long compat_sys_x86_truncate64(const char __user *, unsigned long, |
24 | asmlinkage long sys32_ftruncate64(unsigned int, unsigned long, unsigned long); | 24 | unsigned long); |
25 | asmlinkage long compat_sys_x86_ftruncate64(unsigned int, unsigned long, | ||
26 | unsigned long); | ||
25 | 27 | ||
26 | asmlinkage long sys32_stat64(const char __user *, struct stat64 __user *); | 28 | asmlinkage long compat_sys_x86_stat64(const char __user *, |
27 | asmlinkage long sys32_lstat64(const char __user *, struct stat64 __user *); | 29 | struct stat64 __user *); |
28 | asmlinkage long sys32_fstat64(unsigned int, struct stat64 __user *); | 30 | asmlinkage long compat_sys_x86_lstat64(const char __user *, |
29 | asmlinkage long sys32_fstatat(unsigned int, const char __user *, | 31 | struct stat64 __user *); |
32 | asmlinkage long compat_sys_x86_fstat64(unsigned int, struct stat64 __user *); | ||
33 | asmlinkage long compat_sys_x86_fstatat(unsigned int, const char __user *, | ||
30 | struct stat64 __user *, int); | 34 | struct stat64 __user *, int); |
31 | struct mmap_arg_struct32; | 35 | struct mmap_arg_struct32; |
32 | asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *); | 36 | asmlinkage long compat_sys_x86_mmap(struct mmap_arg_struct32 __user *); |
33 | 37 | ||
34 | asmlinkage long sys32_waitpid(compat_pid_t, unsigned int __user *, int); | 38 | asmlinkage long compat_sys_x86_waitpid(compat_pid_t, unsigned int __user *, |
39 | int); | ||
35 | 40 | ||
36 | asmlinkage long sys32_pread(unsigned int, char __user *, u32, u32, u32); | 41 | asmlinkage long compat_sys_x86_pread(unsigned int, char __user *, u32, u32, |
37 | asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32); | 42 | u32); |
43 | asmlinkage long compat_sys_x86_pwrite(unsigned int, const char __user *, u32, | ||
44 | u32, u32); | ||
38 | 45 | ||
39 | long sys32_fadvise64_64(int, __u32, __u32, __u32, __u32, int); | 46 | asmlinkage long compat_sys_x86_fadvise64_64(int, __u32, __u32, __u32, __u32, |
40 | long sys32_vm86_warning(void); | 47 | int); |
41 | 48 | ||
42 | asmlinkage ssize_t sys32_readahead(int, unsigned, unsigned, size_t); | 49 | asmlinkage ssize_t compat_sys_x86_readahead(int, unsigned int, unsigned int, |
43 | asmlinkage long sys32_sync_file_range(int, unsigned, unsigned, | 50 | size_t); |
44 | unsigned, unsigned, int); | 51 | asmlinkage long compat_sys_x86_sync_file_range(int, unsigned int, unsigned int, |
45 | asmlinkage long sys32_fadvise64(int, unsigned, unsigned, size_t, int); | 52 | unsigned int, unsigned int, |
46 | asmlinkage long sys32_fallocate(int, int, unsigned, | 53 | int); |
47 | unsigned, unsigned, unsigned); | 54 | asmlinkage long compat_sys_x86_fadvise64(int, unsigned int, unsigned int, |
55 | size_t, int); | ||
56 | asmlinkage long compat_sys_x86_fallocate(int, int, unsigned int, unsigned int, | ||
57 | unsigned int, unsigned int); | ||
58 | asmlinkage long compat_sys_x86_clone(unsigned long, unsigned long, int __user *, | ||
59 | unsigned long, int __user *); | ||
48 | 60 | ||
49 | /* ia32/ia32_signal.c */ | 61 | /* ia32/ia32_signal.c */ |
50 | asmlinkage long sys32_sigreturn(void); | 62 | asmlinkage long sys32_sigreturn(void); |
diff --git a/arch/x86/include/uapi/asm/mce.h b/arch/x86/include/uapi/asm/mce.h index 91723461dc1f..435db58a7bad 100644 --- a/arch/x86/include/uapi/asm/mce.h +++ b/arch/x86/include/uapi/asm/mce.h | |||
@@ -30,6 +30,7 @@ struct mce { | |||
30 | __u64 synd; /* MCA_SYND MSR: only valid on SMCA systems */ | 30 | __u64 synd; /* MCA_SYND MSR: only valid on SMCA systems */ |
31 | __u64 ipid; /* MCA_IPID MSR: only valid on SMCA systems */ | 31 | __u64 ipid; /* MCA_IPID MSR: only valid on SMCA systems */ |
32 | __u64 ppin; /* Protected Processor Inventory Number */ | 32 | __u64 ppin; /* Protected Processor Inventory Number */ |
33 | __u32 microcode;/* Microcode revision */ | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | #define MCE_GET_RECORD_LEN _IOR('M', 1, int) | 36 | #define MCE_GET_RECORD_LEN _IOR('M', 1, int) |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index d19e903214b4..4aa9fd379390 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -144,6 +144,13 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c) | |||
144 | { | 144 | { |
145 | int i; | 145 | int i; |
146 | 146 | ||
147 | /* | ||
148 | * We know that the hypervisor lie to us on the microcode version so | ||
149 | * we may as well hope that it is running the correct version. | ||
150 | */ | ||
151 | if (cpu_has(c, X86_FEATURE_HYPERVISOR)) | ||
152 | return false; | ||
153 | |||
147 | for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { | 154 | for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { |
148 | if (c->x86_model == spectre_bad_microcodes[i].model && | 155 | if (c->x86_model == spectre_bad_microcodes[i].model && |
149 | c->x86_stepping == spectre_bad_microcodes[i].stepping) | 156 | c->x86_stepping == spectre_bad_microcodes[i].stepping) |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 8ff94d1e2dce..466f47301334 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -56,6 +56,9 @@ | |||
56 | 56 | ||
57 | static DEFINE_MUTEX(mce_log_mutex); | 57 | static DEFINE_MUTEX(mce_log_mutex); |
58 | 58 | ||
59 | /* sysfs synchronization */ | ||
60 | static DEFINE_MUTEX(mce_sysfs_mutex); | ||
61 | |||
59 | #define CREATE_TRACE_POINTS | 62 | #define CREATE_TRACE_POINTS |
60 | #include <trace/events/mce.h> | 63 | #include <trace/events/mce.h> |
61 | 64 | ||
@@ -130,6 +133,8 @@ void mce_setup(struct mce *m) | |||
130 | 133 | ||
131 | if (this_cpu_has(X86_FEATURE_INTEL_PPIN)) | 134 | if (this_cpu_has(X86_FEATURE_INTEL_PPIN)) |
132 | rdmsrl(MSR_PPIN, m->ppin); | 135 | rdmsrl(MSR_PPIN, m->ppin); |
136 | |||
137 | m->microcode = boot_cpu_data.microcode; | ||
133 | } | 138 | } |
134 | 139 | ||
135 | DEFINE_PER_CPU(struct mce, injectm); | 140 | DEFINE_PER_CPU(struct mce, injectm); |
@@ -262,7 +267,7 @@ static void __print_mce(struct mce *m) | |||
262 | */ | 267 | */ |
263 | pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n", | 268 | pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n", |
264 | m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid, | 269 | m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid, |
265 | cpu_data(m->extcpu).microcode); | 270 | m->microcode); |
266 | } | 271 | } |
267 | 272 | ||
268 | static void print_mce(struct mce *m) | 273 | static void print_mce(struct mce *m) |
@@ -2086,6 +2091,7 @@ static ssize_t set_ignore_ce(struct device *s, | |||
2086 | if (kstrtou64(buf, 0, &new) < 0) | 2091 | if (kstrtou64(buf, 0, &new) < 0) |
2087 | return -EINVAL; | 2092 | return -EINVAL; |
2088 | 2093 | ||
2094 | mutex_lock(&mce_sysfs_mutex); | ||
2089 | if (mca_cfg.ignore_ce ^ !!new) { | 2095 | if (mca_cfg.ignore_ce ^ !!new) { |
2090 | if (new) { | 2096 | if (new) { |
2091 | /* disable ce features */ | 2097 | /* disable ce features */ |
@@ -2098,6 +2104,8 @@ static ssize_t set_ignore_ce(struct device *s, | |||
2098 | on_each_cpu(mce_enable_ce, (void *)1, 1); | 2104 | on_each_cpu(mce_enable_ce, (void *)1, 1); |
2099 | } | 2105 | } |
2100 | } | 2106 | } |
2107 | mutex_unlock(&mce_sysfs_mutex); | ||
2108 | |||
2101 | return size; | 2109 | return size; |
2102 | } | 2110 | } |
2103 | 2111 | ||
@@ -2110,6 +2118,7 @@ static ssize_t set_cmci_disabled(struct device *s, | |||
2110 | if (kstrtou64(buf, 0, &new) < 0) | 2118 | if (kstrtou64(buf, 0, &new) < 0) |
2111 | return -EINVAL; | 2119 | return -EINVAL; |
2112 | 2120 | ||
2121 | mutex_lock(&mce_sysfs_mutex); | ||
2113 | if (mca_cfg.cmci_disabled ^ !!new) { | 2122 | if (mca_cfg.cmci_disabled ^ !!new) { |
2114 | if (new) { | 2123 | if (new) { |
2115 | /* disable cmci */ | 2124 | /* disable cmci */ |
@@ -2121,6 +2130,8 @@ static ssize_t set_cmci_disabled(struct device *s, | |||
2121 | on_each_cpu(mce_enable_ce, NULL, 1); | 2130 | on_each_cpu(mce_enable_ce, NULL, 1); |
2122 | } | 2131 | } |
2123 | } | 2132 | } |
2133 | mutex_unlock(&mce_sysfs_mutex); | ||
2134 | |||
2124 | return size; | 2135 | return size; |
2125 | } | 2136 | } |
2126 | 2137 | ||
@@ -2128,8 +2139,19 @@ static ssize_t store_int_with_restart(struct device *s, | |||
2128 | struct device_attribute *attr, | 2139 | struct device_attribute *attr, |
2129 | const char *buf, size_t size) | 2140 | const char *buf, size_t size) |
2130 | { | 2141 | { |
2131 | ssize_t ret = device_store_int(s, attr, buf, size); | 2142 | unsigned long old_check_interval = check_interval; |
2143 | ssize_t ret = device_store_ulong(s, attr, buf, size); | ||
2144 | |||
2145 | if (check_interval == old_check_interval) | ||
2146 | return ret; | ||
2147 | |||
2148 | if (check_interval < 1) | ||
2149 | check_interval = 1; | ||
2150 | |||
2151 | mutex_lock(&mce_sysfs_mutex); | ||
2132 | mce_restart(); | 2152 | mce_restart(); |
2153 | mutex_unlock(&mce_sysfs_mutex); | ||
2154 | |||
2133 | return ret; | 2155 | return ret; |
2134 | } | 2156 | } |
2135 | 2157 | ||
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index aa1b9a422f2b..70ecbc8099c9 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c | |||
@@ -22,13 +22,16 @@ | |||
22 | #define pr_fmt(fmt) "microcode: " fmt | 22 | #define pr_fmt(fmt) "microcode: " fmt |
23 | 23 | ||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/stop_machine.h> | ||
25 | #include <linux/syscore_ops.h> | 26 | #include <linux/syscore_ops.h> |
26 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
27 | #include <linux/capability.h> | 28 | #include <linux/capability.h> |
28 | #include <linux/firmware.h> | 29 | #include <linux/firmware.h> |
29 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/delay.h> | ||
30 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
31 | #include <linux/cpu.h> | 33 | #include <linux/cpu.h> |
34 | #include <linux/nmi.h> | ||
32 | #include <linux/fs.h> | 35 | #include <linux/fs.h> |
33 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
34 | 37 | ||
@@ -64,6 +67,11 @@ LIST_HEAD(microcode_cache); | |||
64 | */ | 67 | */ |
65 | static DEFINE_MUTEX(microcode_mutex); | 68 | static DEFINE_MUTEX(microcode_mutex); |
66 | 69 | ||
70 | /* | ||
71 | * Serialize late loading so that CPUs get updated one-by-one. | ||
72 | */ | ||
73 | static DEFINE_SPINLOCK(update_lock); | ||
74 | |||
67 | struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; | 75 | struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; |
68 | 76 | ||
69 | struct cpu_info_ctx { | 77 | struct cpu_info_ctx { |
@@ -373,26 +381,23 @@ static int collect_cpu_info(int cpu) | |||
373 | return ret; | 381 | return ret; |
374 | } | 382 | } |
375 | 383 | ||
376 | struct apply_microcode_ctx { | ||
377 | enum ucode_state err; | ||
378 | }; | ||
379 | |||
380 | static void apply_microcode_local(void *arg) | 384 | static void apply_microcode_local(void *arg) |
381 | { | 385 | { |
382 | struct apply_microcode_ctx *ctx = arg; | 386 | enum ucode_state *err = arg; |
383 | 387 | ||
384 | ctx->err = microcode_ops->apply_microcode(smp_processor_id()); | 388 | *err = microcode_ops->apply_microcode(smp_processor_id()); |
385 | } | 389 | } |
386 | 390 | ||
387 | static int apply_microcode_on_target(int cpu) | 391 | static int apply_microcode_on_target(int cpu) |
388 | { | 392 | { |
389 | struct apply_microcode_ctx ctx = { .err = 0 }; | 393 | enum ucode_state err; |
390 | int ret; | 394 | int ret; |
391 | 395 | ||
392 | ret = smp_call_function_single(cpu, apply_microcode_local, &ctx, 1); | 396 | ret = smp_call_function_single(cpu, apply_microcode_local, &err, 1); |
393 | if (!ret) | 397 | if (!ret) { |
394 | ret = ctx.err; | 398 | if (err == UCODE_ERROR) |
395 | 399 | ret = 1; | |
400 | } | ||
396 | return ret; | 401 | return ret; |
397 | } | 402 | } |
398 | 403 | ||
@@ -489,19 +494,100 @@ static void __exit microcode_dev_exit(void) | |||
489 | /* fake device for request_firmware */ | 494 | /* fake device for request_firmware */ |
490 | static struct platform_device *microcode_pdev; | 495 | static struct platform_device *microcode_pdev; |
491 | 496 | ||
492 | static enum ucode_state reload_for_cpu(int cpu) | 497 | /* |
498 | * Late loading dance. Why the heavy-handed stomp_machine effort? | ||
499 | * | ||
500 | * - HT siblings must be idle and not execute other code while the other sibling | ||
501 | * is loading microcode in order to avoid any negative interactions caused by | ||
502 | * the loading. | ||
503 | * | ||
504 | * - In addition, microcode update on the cores must be serialized until this | ||
505 | * requirement can be relaxed in the future. Right now, this is conservative | ||
506 | * and good. | ||
507 | */ | ||
508 | #define SPINUNIT 100 /* 100 nsec */ | ||
509 | |||
510 | static int check_online_cpus(void) | ||
493 | { | 511 | { |
494 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 512 | if (num_online_cpus() == num_present_cpus()) |
495 | enum ucode_state ustate; | 513 | return 0; |
496 | 514 | ||
497 | if (!uci->valid) | 515 | pr_err("Not all CPUs online, aborting microcode update.\n"); |
498 | return UCODE_OK; | 516 | |
517 | return -EINVAL; | ||
518 | } | ||
519 | |||
520 | static atomic_t late_cpus; | ||
521 | |||
522 | /* | ||
523 | * Returns: | ||
524 | * < 0 - on error | ||
525 | * 0 - no update done | ||
526 | * 1 - microcode was updated | ||
527 | */ | ||
528 | static int __reload_late(void *info) | ||
529 | { | ||
530 | unsigned int timeout = NSEC_PER_SEC; | ||
531 | int all_cpus = num_online_cpus(); | ||
532 | int cpu = smp_processor_id(); | ||
533 | enum ucode_state err; | ||
534 | int ret = 0; | ||
535 | |||
536 | atomic_dec(&late_cpus); | ||
537 | |||
538 | /* | ||
539 | * Wait for all CPUs to arrive. A load will not be attempted unless all | ||
540 | * CPUs show up. | ||
541 | * */ | ||
542 | while (atomic_read(&late_cpus)) { | ||
543 | if (timeout < SPINUNIT) { | ||
544 | pr_err("Timeout while waiting for CPUs rendezvous, remaining: %d\n", | ||
545 | atomic_read(&late_cpus)); | ||
546 | return -1; | ||
547 | } | ||
499 | 548 | ||
500 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, true); | 549 | ndelay(SPINUNIT); |
501 | if (ustate != UCODE_OK) | 550 | timeout -= SPINUNIT; |
502 | return ustate; | ||
503 | 551 | ||
504 | return apply_microcode_on_target(cpu); | 552 | touch_nmi_watchdog(); |
553 | } | ||
554 | |||
555 | spin_lock(&update_lock); | ||
556 | apply_microcode_local(&err); | ||
557 | spin_unlock(&update_lock); | ||
558 | |||
559 | if (err > UCODE_NFOUND) { | ||
560 | pr_warn("Error reloading microcode on CPU %d\n", cpu); | ||
561 | ret = -1; | ||
562 | } else if (err == UCODE_UPDATED) { | ||
563 | ret = 1; | ||
564 | } | ||
565 | |||
566 | atomic_inc(&late_cpus); | ||
567 | |||
568 | while (atomic_read(&late_cpus) != all_cpus) | ||
569 | cpu_relax(); | ||
570 | |||
571 | return ret; | ||
572 | } | ||
573 | |||
574 | /* | ||
575 | * Reload microcode late on all CPUs. Wait for a sec until they | ||
576 | * all gather together. | ||
577 | */ | ||
578 | static int microcode_reload_late(void) | ||
579 | { | ||
580 | int ret; | ||
581 | |||
582 | atomic_set(&late_cpus, num_online_cpus()); | ||
583 | |||
584 | ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask); | ||
585 | if (ret < 0) | ||
586 | return ret; | ||
587 | else if (ret > 0) | ||
588 | microcode_check(); | ||
589 | |||
590 | return ret; | ||
505 | } | 591 | } |
506 | 592 | ||
507 | static ssize_t reload_store(struct device *dev, | 593 | static ssize_t reload_store(struct device *dev, |
@@ -509,10 +595,9 @@ static ssize_t reload_store(struct device *dev, | |||
509 | const char *buf, size_t size) | 595 | const char *buf, size_t size) |
510 | { | 596 | { |
511 | enum ucode_state tmp_ret = UCODE_OK; | 597 | enum ucode_state tmp_ret = UCODE_OK; |
512 | bool do_callback = false; | 598 | int bsp = boot_cpu_data.cpu_index; |
513 | unsigned long val; | 599 | unsigned long val; |
514 | ssize_t ret = 0; | 600 | ssize_t ret = 0; |
515 | int cpu; | ||
516 | 601 | ||
517 | ret = kstrtoul(buf, 0, &val); | 602 | ret = kstrtoul(buf, 0, &val); |
518 | if (ret) | 603 | if (ret) |
@@ -521,29 +606,24 @@ static ssize_t reload_store(struct device *dev, | |||
521 | if (val != 1) | 606 | if (val != 1) |
522 | return size; | 607 | return size; |
523 | 608 | ||
524 | get_online_cpus(); | 609 | tmp_ret = microcode_ops->request_microcode_fw(bsp, µcode_pdev->dev, true); |
525 | mutex_lock(µcode_mutex); | 610 | if (tmp_ret != UCODE_OK) |
526 | for_each_online_cpu(cpu) { | 611 | return size; |
527 | tmp_ret = reload_for_cpu(cpu); | ||
528 | if (tmp_ret > UCODE_NFOUND) { | ||
529 | pr_warn("Error reloading microcode on CPU %d\n", cpu); | ||
530 | |||
531 | /* set retval for the first encountered reload error */ | ||
532 | if (!ret) | ||
533 | ret = -EINVAL; | ||
534 | } | ||
535 | 612 | ||
536 | if (tmp_ret == UCODE_UPDATED) | 613 | get_online_cpus(); |
537 | do_callback = true; | ||
538 | } | ||
539 | 614 | ||
540 | if (!ret && do_callback) | 615 | ret = check_online_cpus(); |
541 | microcode_check(); | 616 | if (ret) |
617 | goto put; | ||
542 | 618 | ||
619 | mutex_lock(µcode_mutex); | ||
620 | ret = microcode_reload_late(); | ||
543 | mutex_unlock(µcode_mutex); | 621 | mutex_unlock(µcode_mutex); |
622 | |||
623 | put: | ||
544 | put_online_cpus(); | 624 | put_online_cpus(); |
545 | 625 | ||
546 | if (!ret) | 626 | if (ret >= 0) |
547 | ret = size; | 627 | ret = size; |
548 | 628 | ||
549 | return ret; | 629 | return ret; |
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 923054a6b760..2aded9db1d42 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -589,6 +589,23 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) | |||
589 | if (!mc) | 589 | if (!mc) |
590 | return 0; | 590 | return 0; |
591 | 591 | ||
592 | /* | ||
593 | * Save us the MSR write below - which is a particular expensive | ||
594 | * operation - when the other hyperthread has updated the microcode | ||
595 | * already. | ||
596 | */ | ||
597 | rev = intel_get_microcode_revision(); | ||
598 | if (rev >= mc->hdr.rev) { | ||
599 | uci->cpu_sig.rev = rev; | ||
600 | return UCODE_OK; | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * Writeback and invalidate caches before updating microcode to avoid | ||
605 | * internal issues depending on what the microcode is updating. | ||
606 | */ | ||
607 | native_wbinvd(); | ||
608 | |||
592 | /* write microcode via MSR 0x79 */ | 609 | /* write microcode via MSR 0x79 */ |
593 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); | 610 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
594 | 611 | ||
@@ -774,9 +791,9 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | |||
774 | 791 | ||
775 | static enum ucode_state apply_microcode_intel(int cpu) | 792 | static enum ucode_state apply_microcode_intel(int cpu) |
776 | { | 793 | { |
794 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
795 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
777 | struct microcode_intel *mc; | 796 | struct microcode_intel *mc; |
778 | struct ucode_cpu_info *uci; | ||
779 | struct cpuinfo_x86 *c; | ||
780 | static int prev_rev; | 797 | static int prev_rev; |
781 | u32 rev; | 798 | u32 rev; |
782 | 799 | ||
@@ -784,15 +801,32 @@ static enum ucode_state apply_microcode_intel(int cpu) | |||
784 | if (WARN_ON(raw_smp_processor_id() != cpu)) | 801 | if (WARN_ON(raw_smp_processor_id() != cpu)) |
785 | return UCODE_ERROR; | 802 | return UCODE_ERROR; |
786 | 803 | ||
787 | uci = ucode_cpu_info + cpu; | 804 | /* Look for a newer patch in our cache: */ |
788 | mc = uci->mc; | 805 | mc = find_patch(uci); |
789 | if (!mc) { | 806 | if (!mc) { |
790 | /* Look for a newer patch in our cache: */ | 807 | mc = uci->mc; |
791 | mc = find_patch(uci); | ||
792 | if (!mc) | 808 | if (!mc) |
793 | return UCODE_NFOUND; | 809 | return UCODE_NFOUND; |
794 | } | 810 | } |
795 | 811 | ||
812 | /* | ||
813 | * Save us the MSR write below - which is a particular expensive | ||
814 | * operation - when the other hyperthread has updated the microcode | ||
815 | * already. | ||
816 | */ | ||
817 | rev = intel_get_microcode_revision(); | ||
818 | if (rev >= mc->hdr.rev) { | ||
819 | uci->cpu_sig.rev = rev; | ||
820 | c->microcode = rev; | ||
821 | return UCODE_OK; | ||
822 | } | ||
823 | |||
824 | /* | ||
825 | * Writeback and invalidate caches before updating microcode to avoid | ||
826 | * internal issues depending on what the microcode is updating. | ||
827 | */ | ||
828 | native_wbinvd(); | ||
829 | |||
796 | /* write microcode via MSR 0x79 */ | 830 | /* write microcode via MSR 0x79 */ |
797 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); | 831 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
798 | 832 | ||
@@ -813,8 +847,6 @@ static enum ucode_state apply_microcode_intel(int cpu) | |||
813 | prev_rev = rev; | 847 | prev_rev = rev; |
814 | } | 848 | } |
815 | 849 | ||
816 | c = &cpu_data(cpu); | ||
817 | |||
818 | uci->cpu_sig.rev = rev; | 850 | uci->cpu_sig.rev = rev; |
819 | c->microcode = rev; | 851 | c->microcode = rev; |
820 | 852 | ||
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 2f723301eb58..38deafebb21b 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c | |||
@@ -23,7 +23,7 @@ | |||
23 | /* | 23 | /* |
24 | * this changes the io permissions bitmap in the current task. | 24 | * this changes the io permissions bitmap in the current task. |
25 | */ | 25 | */ |
26 | asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) | 26 | SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on) |
27 | { | 27 | { |
28 | struct thread_struct *t = ¤t->thread; | 28 | struct thread_struct *t = ¤t->thread; |
29 | struct tss_struct *tss; | 29 | struct tss_struct *tss; |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index bd36f3c33cd0..0715f827607c 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler); | |||
1168 | 1168 | ||
1169 | bool arch_within_kprobe_blacklist(unsigned long addr) | 1169 | bool arch_within_kprobe_blacklist(unsigned long addr) |
1170 | { | 1170 | { |
1171 | bool is_in_entry_trampoline_section = false; | ||
1172 | |||
1173 | #ifdef CONFIG_X86_64 | ||
1174 | is_in_entry_trampoline_section = | ||
1175 | (addr >= (unsigned long)__entry_trampoline_start && | ||
1176 | addr < (unsigned long)__entry_trampoline_end); | ||
1177 | #endif | ||
1171 | return (addr >= (unsigned long)__kprobes_text_start && | 1178 | return (addr >= (unsigned long)__kprobes_text_start && |
1172 | addr < (unsigned long)__kprobes_text_end) || | 1179 | addr < (unsigned long)__kprobes_text_end) || |
1173 | (addr >= (unsigned long)__entry_text_start && | 1180 | (addr >= (unsigned long)__entry_text_start && |
1174 | addr < (unsigned long)__entry_text_end); | 1181 | addr < (unsigned long)__entry_text_end) || |
1182 | is_in_entry_trampoline_section; | ||
1175 | } | 1183 | } |
1176 | 1184 | ||
1177 | int __init arch_init_kprobes(void) | 1185 | int __init arch_init_kprobes(void) |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 9b138a06c1a4..b854ebf5851b 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
@@ -118,9 +118,11 @@ SECTIONS | |||
118 | 118 | ||
119 | #ifdef CONFIG_X86_64 | 119 | #ifdef CONFIG_X86_64 |
120 | . = ALIGN(PAGE_SIZE); | 120 | . = ALIGN(PAGE_SIZE); |
121 | VMLINUX_SYMBOL(__entry_trampoline_start) = .; | ||
121 | _entry_trampoline = .; | 122 | _entry_trampoline = .; |
122 | *(.entry_trampoline) | 123 | *(.entry_trampoline) |
123 | . = ALIGN(PAGE_SIZE); | 124 | . = ALIGN(PAGE_SIZE); |
125 | VMLINUX_SYMBOL(__entry_trampoline_end) = .; | ||
124 | ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big"); | 126 | ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big"); |
125 | #endif | 127 | #endif |
126 | 128 | ||
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c index ce38f165489b..631507f0c198 100644 --- a/arch/x86/mm/pti.c +++ b/arch/x86/mm/pti.c | |||
@@ -332,7 +332,7 @@ static void __init pti_clone_user_shared(void) | |||
332 | } | 332 | } |
333 | 333 | ||
334 | /* | 334 | /* |
335 | * Clone the ESPFIX P4D into the user space visinble page table | 335 | * Clone the ESPFIX P4D into the user space visible page table |
336 | */ | 336 | */ |
337 | static void __init pti_setup_espfix64(void) | 337 | static void __init pti_setup_espfix64(void) |
338 | { | 338 | { |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 87855b5123a6..ee62d2d517bf 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -266,7 +266,7 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) | |||
266 | struct iov_iter i; | 266 | struct iov_iter i; |
267 | ssize_t bw; | 267 | ssize_t bw; |
268 | 268 | ||
269 | iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len); | 269 | iov_iter_bvec(&i, ITER_BVEC | WRITE, bvec, 1, bvec->bv_len); |
270 | 270 | ||
271 | file_start_write(file); | 271 | file_start_write(file); |
272 | bw = vfs_iter_write(file, &i, ppos, 0); | 272 | bw = vfs_iter_write(file, &i, ppos, 0); |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index e126e4cac2ca..92ec1bbece51 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -262,6 +262,7 @@ static DEFINE_SPINLOCK(minor_lock); | |||
262 | 262 | ||
263 | static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo); | 263 | static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo); |
264 | static void blkfront_gather_backend_features(struct blkfront_info *info); | 264 | static void blkfront_gather_backend_features(struct blkfront_info *info); |
265 | static int negotiate_mq(struct blkfront_info *info); | ||
265 | 266 | ||
266 | static int get_id_from_freelist(struct blkfront_ring_info *rinfo) | 267 | static int get_id_from_freelist(struct blkfront_ring_info *rinfo) |
267 | { | 268 | { |
@@ -1774,11 +1775,18 @@ static int talk_to_blkback(struct xenbus_device *dev, | |||
1774 | unsigned int i, max_page_order; | 1775 | unsigned int i, max_page_order; |
1775 | unsigned int ring_page_order; | 1776 | unsigned int ring_page_order; |
1776 | 1777 | ||
1778 | if (!info) | ||
1779 | return -ENODEV; | ||
1780 | |||
1777 | max_page_order = xenbus_read_unsigned(info->xbdev->otherend, | 1781 | max_page_order = xenbus_read_unsigned(info->xbdev->otherend, |
1778 | "max-ring-page-order", 0); | 1782 | "max-ring-page-order", 0); |
1779 | ring_page_order = min(xen_blkif_max_ring_order, max_page_order); | 1783 | ring_page_order = min(xen_blkif_max_ring_order, max_page_order); |
1780 | info->nr_ring_pages = 1 << ring_page_order; | 1784 | info->nr_ring_pages = 1 << ring_page_order; |
1781 | 1785 | ||
1786 | err = negotiate_mq(info); | ||
1787 | if (err) | ||
1788 | goto destroy_blkring; | ||
1789 | |||
1782 | for (i = 0; i < info->nr_rings; i++) { | 1790 | for (i = 0; i < info->nr_rings; i++) { |
1783 | struct blkfront_ring_info *rinfo = &info->rinfo[i]; | 1791 | struct blkfront_ring_info *rinfo = &info->rinfo[i]; |
1784 | 1792 | ||
@@ -1978,11 +1986,6 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
1978 | } | 1986 | } |
1979 | 1987 | ||
1980 | info->xbdev = dev; | 1988 | info->xbdev = dev; |
1981 | err = negotiate_mq(info); | ||
1982 | if (err) { | ||
1983 | kfree(info); | ||
1984 | return err; | ||
1985 | } | ||
1986 | 1989 | ||
1987 | mutex_init(&info->mutex); | 1990 | mutex_init(&info->mutex); |
1988 | info->vdevice = vdevice; | 1991 | info->vdevice = vdevice; |
@@ -2099,10 +2102,6 @@ static int blkfront_resume(struct xenbus_device *dev) | |||
2099 | 2102 | ||
2100 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); | 2103 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); |
2101 | 2104 | ||
2102 | err = negotiate_mq(info); | ||
2103 | if (err) | ||
2104 | return err; | ||
2105 | |||
2106 | err = talk_to_blkback(dev, info); | 2105 | err = talk_to_blkback(dev, info); |
2107 | if (!err) | 2106 | if (!err) |
2108 | blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings); | 2107 | blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings); |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index b3b4ed9b6874..d2e5382821a4 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -386,6 +386,7 @@ config ATMEL_PIT | |||
386 | 386 | ||
387 | config ATMEL_ST | 387 | config ATMEL_ST |
388 | bool "Atmel ST timer support" if COMPILE_TEST | 388 | bool "Atmel ST timer support" if COMPILE_TEST |
389 | depends on HAS_IOMEM | ||
389 | select TIMER_OF | 390 | select TIMER_OF |
390 | select MFD_SYSCON | 391 | select MFD_SYSCON |
391 | help | 392 | help |
diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c index f652a0e0f5a2..3548caa9e933 100644 --- a/drivers/dma/mv_xor_v2.c +++ b/drivers/dma/mv_xor_v2.c | |||
@@ -163,6 +163,7 @@ struct mv_xor_v2_device { | |||
163 | void __iomem *dma_base; | 163 | void __iomem *dma_base; |
164 | void __iomem *glob_base; | 164 | void __iomem *glob_base; |
165 | struct clk *clk; | 165 | struct clk *clk; |
166 | struct clk *reg_clk; | ||
166 | struct tasklet_struct irq_tasklet; | 167 | struct tasklet_struct irq_tasklet; |
167 | struct list_head free_sw_desc; | 168 | struct list_head free_sw_desc; |
168 | struct dma_device dmadev; | 169 | struct dma_device dmadev; |
@@ -749,13 +750,26 @@ static int mv_xor_v2_probe(struct platform_device *pdev) | |||
749 | if (ret) | 750 | if (ret) |
750 | return ret; | 751 | return ret; |
751 | 752 | ||
753 | xor_dev->reg_clk = devm_clk_get(&pdev->dev, "reg"); | ||
754 | if (PTR_ERR(xor_dev->reg_clk) != -ENOENT) { | ||
755 | if (!IS_ERR(xor_dev->reg_clk)) { | ||
756 | ret = clk_prepare_enable(xor_dev->reg_clk); | ||
757 | if (ret) | ||
758 | return ret; | ||
759 | } else { | ||
760 | return PTR_ERR(xor_dev->reg_clk); | ||
761 | } | ||
762 | } | ||
763 | |||
752 | xor_dev->clk = devm_clk_get(&pdev->dev, NULL); | 764 | xor_dev->clk = devm_clk_get(&pdev->dev, NULL); |
753 | if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) | 765 | if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) { |
754 | return -EPROBE_DEFER; | 766 | ret = EPROBE_DEFER; |
767 | goto disable_reg_clk; | ||
768 | } | ||
755 | if (!IS_ERR(xor_dev->clk)) { | 769 | if (!IS_ERR(xor_dev->clk)) { |
756 | ret = clk_prepare_enable(xor_dev->clk); | 770 | ret = clk_prepare_enable(xor_dev->clk); |
757 | if (ret) | 771 | if (ret) |
758 | return ret; | 772 | goto disable_reg_clk; |
759 | } | 773 | } |
760 | 774 | ||
761 | ret = platform_msi_domain_alloc_irqs(&pdev->dev, 1, | 775 | ret = platform_msi_domain_alloc_irqs(&pdev->dev, 1, |
@@ -866,8 +880,9 @@ free_hw_desq: | |||
866 | free_msi_irqs: | 880 | free_msi_irqs: |
867 | platform_msi_domain_free_irqs(&pdev->dev); | 881 | platform_msi_domain_free_irqs(&pdev->dev); |
868 | disable_clk: | 882 | disable_clk: |
869 | if (!IS_ERR(xor_dev->clk)) | 883 | clk_disable_unprepare(xor_dev->clk); |
870 | clk_disable_unprepare(xor_dev->clk); | 884 | disable_reg_clk: |
885 | clk_disable_unprepare(xor_dev->reg_clk); | ||
871 | return ret; | 886 | return ret; |
872 | } | 887 | } |
873 | 888 | ||
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index e3ff162c03fc..d0cacdb0713e 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c | |||
@@ -917,7 +917,7 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl, | |||
917 | 917 | ||
918 | rcar_dmac_chan_configure_desc(chan, desc); | 918 | rcar_dmac_chan_configure_desc(chan, desc); |
919 | 919 | ||
920 | max_chunk_size = (RCAR_DMATCR_MASK + 1) << desc->xfer_shift; | 920 | max_chunk_size = RCAR_DMATCR_MASK << desc->xfer_shift; |
921 | 921 | ||
922 | /* | 922 | /* |
923 | * Allocate and fill the transfer chunk descriptors. We own the only | 923 | * Allocate and fill the transfer chunk descriptors. We own the only |
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index e76de57dd617..ebaea8b1594b 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/err.h> | 17 | #include <linux/err.h> |
19 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
@@ -37,10 +36,9 @@ struct gpio_rcar_priv { | |||
37 | struct platform_device *pdev; | 36 | struct platform_device *pdev; |
38 | struct gpio_chip gpio_chip; | 37 | struct gpio_chip gpio_chip; |
39 | struct irq_chip irq_chip; | 38 | struct irq_chip irq_chip; |
40 | struct clk *clk; | ||
41 | unsigned int irq_parent; | 39 | unsigned int irq_parent; |
40 | atomic_t wakeup_path; | ||
42 | bool has_both_edge_trigger; | 41 | bool has_both_edge_trigger; |
43 | bool needs_clk; | ||
44 | }; | 42 | }; |
45 | 43 | ||
46 | #define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */ | 44 | #define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */ |
@@ -186,13 +184,10 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) | |||
186 | } | 184 | } |
187 | } | 185 | } |
188 | 186 | ||
189 | if (!p->clk) | ||
190 | return 0; | ||
191 | |||
192 | if (on) | 187 | if (on) |
193 | clk_enable(p->clk); | 188 | atomic_inc(&p->wakeup_path); |
194 | else | 189 | else |
195 | clk_disable(p->clk); | 190 | atomic_dec(&p->wakeup_path); |
196 | 191 | ||
197 | return 0; | 192 | return 0; |
198 | } | 193 | } |
@@ -330,17 +325,14 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset, | |||
330 | 325 | ||
331 | struct gpio_rcar_info { | 326 | struct gpio_rcar_info { |
332 | bool has_both_edge_trigger; | 327 | bool has_both_edge_trigger; |
333 | bool needs_clk; | ||
334 | }; | 328 | }; |
335 | 329 | ||
336 | static const struct gpio_rcar_info gpio_rcar_info_gen1 = { | 330 | static const struct gpio_rcar_info gpio_rcar_info_gen1 = { |
337 | .has_both_edge_trigger = false, | 331 | .has_both_edge_trigger = false, |
338 | .needs_clk = false, | ||
339 | }; | 332 | }; |
340 | 333 | ||
341 | static const struct gpio_rcar_info gpio_rcar_info_gen2 = { | 334 | static const struct gpio_rcar_info gpio_rcar_info_gen2 = { |
342 | .has_both_edge_trigger = true, | 335 | .has_both_edge_trigger = true, |
343 | .needs_clk = true, | ||
344 | }; | 336 | }; |
345 | 337 | ||
346 | static const struct of_device_id gpio_rcar_of_table[] = { | 338 | static const struct of_device_id gpio_rcar_of_table[] = { |
@@ -403,7 +395,6 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins) | |||
403 | ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); | 395 | ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); |
404 | *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; | 396 | *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; |
405 | p->has_both_edge_trigger = info->has_both_edge_trigger; | 397 | p->has_both_edge_trigger = info->has_both_edge_trigger; |
406 | p->needs_clk = info->needs_clk; | ||
407 | 398 | ||
408 | if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { | 399 | if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { |
409 | dev_warn(&p->pdev->dev, | 400 | dev_warn(&p->pdev->dev, |
@@ -440,16 +431,6 @@ static int gpio_rcar_probe(struct platform_device *pdev) | |||
440 | 431 | ||
441 | platform_set_drvdata(pdev, p); | 432 | platform_set_drvdata(pdev, p); |
442 | 433 | ||
443 | p->clk = devm_clk_get(dev, NULL); | ||
444 | if (IS_ERR(p->clk)) { | ||
445 | if (p->needs_clk) { | ||
446 | dev_err(dev, "unable to get clock\n"); | ||
447 | ret = PTR_ERR(p->clk); | ||
448 | goto err0; | ||
449 | } | ||
450 | p->clk = NULL; | ||
451 | } | ||
452 | |||
453 | pm_runtime_enable(dev); | 434 | pm_runtime_enable(dev); |
454 | 435 | ||
455 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 436 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
@@ -531,11 +512,24 @@ static int gpio_rcar_remove(struct platform_device *pdev) | |||
531 | return 0; | 512 | return 0; |
532 | } | 513 | } |
533 | 514 | ||
515 | static int __maybe_unused gpio_rcar_suspend(struct device *dev) | ||
516 | { | ||
517 | struct gpio_rcar_priv *p = dev_get_drvdata(dev); | ||
518 | |||
519 | if (atomic_read(&p->wakeup_path)) | ||
520 | device_set_wakeup_path(dev); | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL); | ||
526 | |||
534 | static struct platform_driver gpio_rcar_device_driver = { | 527 | static struct platform_driver gpio_rcar_device_driver = { |
535 | .probe = gpio_rcar_probe, | 528 | .probe = gpio_rcar_probe, |
536 | .remove = gpio_rcar_remove, | 529 | .remove = gpio_rcar_remove, |
537 | .driver = { | 530 | .driver = { |
538 | .name = "gpio_rcar", | 531 | .name = "gpio_rcar", |
532 | .pm = &gpio_rcar_pm_ops, | ||
539 | .of_match_table = of_match_ptr(gpio_rcar_of_table), | 533 | .of_match_table = of_match_ptr(gpio_rcar_of_table), |
540 | } | 534 | } |
541 | }; | 535 | }; |
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index a5b4cf030c11..9183d148d644 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -550,18 +550,13 @@ static int addr_resolve(struct sockaddr *src_in, | |||
550 | dst_release(dst); | 550 | dst_release(dst); |
551 | } | 551 | } |
552 | 552 | ||
553 | if (ndev->flags & IFF_LOOPBACK) { | 553 | if (ndev) { |
554 | ret = rdma_translate_ip(dst_in, addr); | 554 | if (ndev->flags & IFF_LOOPBACK) |
555 | /* | 555 | ret = rdma_translate_ip(dst_in, addr); |
556 | * Put the loopback device and get the translated | 556 | else |
557 | * device instead. | 557 | addr->bound_dev_if = ndev->ifindex; |
558 | */ | ||
559 | dev_put(ndev); | 558 | dev_put(ndev); |
560 | ndev = dev_get_by_index(addr->net, addr->bound_dev_if); | ||
561 | } else { | ||
562 | addr->bound_dev_if = ndev->ifindex; | ||
563 | } | 559 | } |
564 | dev_put(ndev); | ||
565 | 560 | ||
566 | return ret; | 561 | return ret; |
567 | } | 562 | } |
diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c index bc79ca8215d7..af5ad6a56ae4 100644 --- a/drivers/infiniband/core/cq.c +++ b/drivers/infiniband/core/cq.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | /* # of WCs to poll for with a single call to ib_poll_cq */ | 18 | /* # of WCs to poll for with a single call to ib_poll_cq */ |
19 | #define IB_POLL_BATCH 16 | 19 | #define IB_POLL_BATCH 16 |
20 | #define IB_POLL_BATCH_DIRECT 8 | ||
20 | 21 | ||
21 | /* # of WCs to iterate over before yielding */ | 22 | /* # of WCs to iterate over before yielding */ |
22 | #define IB_POLL_BUDGET_IRQ 256 | 23 | #define IB_POLL_BUDGET_IRQ 256 |
@@ -25,18 +26,18 @@ | |||
25 | #define IB_POLL_FLAGS \ | 26 | #define IB_POLL_FLAGS \ |
26 | (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS) | 27 | (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS) |
27 | 28 | ||
28 | static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) | 29 | static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *wcs, |
30 | int batch) | ||
29 | { | 31 | { |
30 | int i, n, completed = 0; | 32 | int i, n, completed = 0; |
31 | struct ib_wc *wcs = poll_wc ? : cq->wc; | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * budget might be (-1) if the caller does not | 35 | * budget might be (-1) if the caller does not |
35 | * want to bound this call, thus we need unsigned | 36 | * want to bound this call, thus we need unsigned |
36 | * minimum here. | 37 | * minimum here. |
37 | */ | 38 | */ |
38 | while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH, | 39 | while ((n = ib_poll_cq(cq, min_t(u32, batch, |
39 | budget - completed), wcs)) > 0) { | 40 | budget - completed), wcs)) > 0) { |
40 | for (i = 0; i < n; i++) { | 41 | for (i = 0; i < n; i++) { |
41 | struct ib_wc *wc = &wcs[i]; | 42 | struct ib_wc *wc = &wcs[i]; |
42 | 43 | ||
@@ -48,8 +49,7 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) | |||
48 | 49 | ||
49 | completed += n; | 50 | completed += n; |
50 | 51 | ||
51 | if (n != IB_POLL_BATCH || | 52 | if (n != batch || (budget != -1 && completed >= budget)) |
52 | (budget != -1 && completed >= budget)) | ||
53 | break; | 53 | break; |
54 | } | 54 | } |
55 | 55 | ||
@@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) | |||
72 | */ | 72 | */ |
73 | int ib_process_cq_direct(struct ib_cq *cq, int budget) | 73 | int ib_process_cq_direct(struct ib_cq *cq, int budget) |
74 | { | 74 | { |
75 | struct ib_wc wcs[IB_POLL_BATCH]; | 75 | struct ib_wc wcs[IB_POLL_BATCH_DIRECT]; |
76 | 76 | ||
77 | return __ib_process_cq(cq, budget, wcs); | 77 | return __ib_process_cq(cq, budget, wcs, IB_POLL_BATCH_DIRECT); |
78 | } | 78 | } |
79 | EXPORT_SYMBOL(ib_process_cq_direct); | 79 | EXPORT_SYMBOL(ib_process_cq_direct); |
80 | 80 | ||
@@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget) | |||
88 | struct ib_cq *cq = container_of(iop, struct ib_cq, iop); | 88 | struct ib_cq *cq = container_of(iop, struct ib_cq, iop); |
89 | int completed; | 89 | int completed; |
90 | 90 | ||
91 | completed = __ib_process_cq(cq, budget, NULL); | 91 | completed = __ib_process_cq(cq, budget, cq->wc, IB_POLL_BATCH); |
92 | if (completed < budget) { | 92 | if (completed < budget) { |
93 | irq_poll_complete(&cq->iop); | 93 | irq_poll_complete(&cq->iop); |
94 | if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) | 94 | if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) |
@@ -108,7 +108,8 @@ static void ib_cq_poll_work(struct work_struct *work) | |||
108 | struct ib_cq *cq = container_of(work, struct ib_cq, work); | 108 | struct ib_cq *cq = container_of(work, struct ib_cq, work); |
109 | int completed; | 109 | int completed; |
110 | 110 | ||
111 | completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL); | 111 | completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, cq->wc, |
112 | IB_POLL_BATCH); | ||
112 | if (completed >= IB_POLL_BUDGET_WORKQUEUE || | 113 | if (completed >= IB_POLL_BUDGET_WORKQUEUE || |
113 | ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) | 114 | ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) |
114 | queue_work(ib_comp_wq, &cq->work); | 115 | queue_work(ib_comp_wq, &cq->work); |
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index e8010e73a1cf..bb065c9449be 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
@@ -536,14 +536,14 @@ int ib_register_device(struct ib_device *device, | |||
536 | ret = device->query_device(device, &device->attrs, &uhw); | 536 | ret = device->query_device(device, &device->attrs, &uhw); |
537 | if (ret) { | 537 | if (ret) { |
538 | pr_warn("Couldn't query the device attributes\n"); | 538 | pr_warn("Couldn't query the device attributes\n"); |
539 | goto cache_cleanup; | 539 | goto cg_cleanup; |
540 | } | 540 | } |
541 | 541 | ||
542 | ret = ib_device_register_sysfs(device, port_callback); | 542 | ret = ib_device_register_sysfs(device, port_callback); |
543 | if (ret) { | 543 | if (ret) { |
544 | pr_warn("Couldn't register device %s with driver model\n", | 544 | pr_warn("Couldn't register device %s with driver model\n", |
545 | device->name); | 545 | device->name); |
546 | goto cache_cleanup; | 546 | goto cg_cleanup; |
547 | } | 547 | } |
548 | 548 | ||
549 | device->reg_state = IB_DEV_REGISTERED; | 549 | device->reg_state = IB_DEV_REGISTERED; |
@@ -559,6 +559,8 @@ int ib_register_device(struct ib_device *device, | |||
559 | mutex_unlock(&device_mutex); | 559 | mutex_unlock(&device_mutex); |
560 | return 0; | 560 | return 0; |
561 | 561 | ||
562 | cg_cleanup: | ||
563 | ib_device_unregister_rdmacg(device); | ||
562 | cache_cleanup: | 564 | cache_cleanup: |
563 | ib_cache_cleanup_one(device); | 565 | ib_cache_cleanup_one(device); |
564 | ib_cache_release_one(device); | 566 | ib_cache_release_one(device); |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 8cf15d4a8ac4..9f029a1ca5ea 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -1291,10 +1291,9 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num, | |||
1291 | 1291 | ||
1292 | resolved_dev = dev_get_by_index(dev_addr.net, | 1292 | resolved_dev = dev_get_by_index(dev_addr.net, |
1293 | dev_addr.bound_dev_if); | 1293 | dev_addr.bound_dev_if); |
1294 | if (resolved_dev->flags & IFF_LOOPBACK) { | 1294 | if (!resolved_dev) { |
1295 | dev_put(resolved_dev); | 1295 | dev_put(idev); |
1296 | resolved_dev = idev; | 1296 | return -ENODEV; |
1297 | dev_hold(resolved_dev); | ||
1298 | } | 1297 | } |
1299 | ndev = ib_get_ndev_from_path(rec); | 1298 | ndev = ib_get_ndev_from_path(rec); |
1300 | rcu_read_lock(); | 1299 | rcu_read_lock(); |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index f015f1bf88c9..3a9d0f5b5881 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -1149,6 +1149,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, | |||
1149 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1149 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
1150 | return -EFAULT; | 1150 | return -EFAULT; |
1151 | 1151 | ||
1152 | if (cmd.qp_state > IB_QPS_ERR) | ||
1153 | return -EINVAL; | ||
1154 | |||
1152 | ctx = ucma_get_ctx(file, cmd.id); | 1155 | ctx = ucma_get_ctx(file, cmd.id); |
1153 | if (IS_ERR(ctx)) | 1156 | if (IS_ERR(ctx)) |
1154 | return PTR_ERR(ctx); | 1157 | return PTR_ERR(ctx); |
@@ -1294,6 +1297,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, | |||
1294 | if (IS_ERR(ctx)) | 1297 | if (IS_ERR(ctx)) |
1295 | return PTR_ERR(ctx); | 1298 | return PTR_ERR(ctx); |
1296 | 1299 | ||
1300 | if (unlikely(cmd.optval > KMALLOC_MAX_SIZE)) | ||
1301 | return -EINVAL; | ||
1302 | |||
1297 | optval = memdup_user((void __user *) (unsigned long) cmd.optval, | 1303 | optval = memdup_user((void __user *) (unsigned long) cmd.optval, |
1298 | cmd.optlen); | 1304 | cmd.optlen); |
1299 | if (IS_ERR(optval)) { | 1305 | if (IS_ERR(optval)) { |
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 643174d949a8..0dd75f449872 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c | |||
@@ -785,7 +785,7 @@ int bnxt_re_query_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr) | |||
785 | return 0; | 785 | return 0; |
786 | } | 786 | } |
787 | 787 | ||
788 | static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp) | 788 | unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp) |
789 | __acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock) | 789 | __acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock) |
790 | { | 790 | { |
791 | unsigned long flags; | 791 | unsigned long flags; |
@@ -799,8 +799,8 @@ static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp) | |||
799 | return flags; | 799 | return flags; |
800 | } | 800 | } |
801 | 801 | ||
802 | static void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, | 802 | void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, |
803 | unsigned long flags) | 803 | unsigned long flags) |
804 | __releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock) | 804 | __releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock) |
805 | { | 805 | { |
806 | if (qp->rcq != qp->scq) | 806 | if (qp->rcq != qp->scq) |
@@ -1606,6 +1606,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, | |||
1606 | int status; | 1606 | int status; |
1607 | union ib_gid sgid; | 1607 | union ib_gid sgid; |
1608 | struct ib_gid_attr sgid_attr; | 1608 | struct ib_gid_attr sgid_attr; |
1609 | unsigned int flags; | ||
1609 | u8 nw_type; | 1610 | u8 nw_type; |
1610 | 1611 | ||
1611 | qp->qplib_qp.modify_flags = 0; | 1612 | qp->qplib_qp.modify_flags = 0; |
@@ -1634,14 +1635,18 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, | |||
1634 | dev_dbg(rdev_to_dev(rdev), | 1635 | dev_dbg(rdev_to_dev(rdev), |
1635 | "Move QP = %p to flush list\n", | 1636 | "Move QP = %p to flush list\n", |
1636 | qp); | 1637 | qp); |
1638 | flags = bnxt_re_lock_cqs(qp); | ||
1637 | bnxt_qplib_add_flush_qp(&qp->qplib_qp); | 1639 | bnxt_qplib_add_flush_qp(&qp->qplib_qp); |
1640 | bnxt_re_unlock_cqs(qp, flags); | ||
1638 | } | 1641 | } |
1639 | if (!qp->sumem && | 1642 | if (!qp->sumem && |
1640 | qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) { | 1643 | qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) { |
1641 | dev_dbg(rdev_to_dev(rdev), | 1644 | dev_dbg(rdev_to_dev(rdev), |
1642 | "Move QP = %p out of flush list\n", | 1645 | "Move QP = %p out of flush list\n", |
1643 | qp); | 1646 | qp); |
1647 | flags = bnxt_re_lock_cqs(qp); | ||
1644 | bnxt_qplib_clean_qp(&qp->qplib_qp); | 1648 | bnxt_qplib_clean_qp(&qp->qplib_qp); |
1649 | bnxt_re_unlock_cqs(qp, flags); | ||
1645 | } | 1650 | } |
1646 | } | 1651 | } |
1647 | if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) { | 1652 | if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) { |
@@ -2227,10 +2232,13 @@ static int bnxt_re_build_inv_wqe(struct ib_send_wr *wr, | |||
2227 | wqe->type = BNXT_QPLIB_SWQE_TYPE_LOCAL_INV; | 2232 | wqe->type = BNXT_QPLIB_SWQE_TYPE_LOCAL_INV; |
2228 | wqe->local_inv.inv_l_key = wr->ex.invalidate_rkey; | 2233 | wqe->local_inv.inv_l_key = wr->ex.invalidate_rkey; |
2229 | 2234 | ||
2235 | /* Need unconditional fence for local invalidate | ||
2236 | * opcode to work as expected. | ||
2237 | */ | ||
2238 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE; | ||
2239 | |||
2230 | if (wr->send_flags & IB_SEND_SIGNALED) | 2240 | if (wr->send_flags & IB_SEND_SIGNALED) |
2231 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP; | 2241 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP; |
2232 | if (wr->send_flags & IB_SEND_FENCE) | ||
2233 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE; | ||
2234 | if (wr->send_flags & IB_SEND_SOLICITED) | 2242 | if (wr->send_flags & IB_SEND_SOLICITED) |
2235 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT; | 2243 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT; |
2236 | 2244 | ||
@@ -2251,8 +2259,12 @@ static int bnxt_re_build_reg_wqe(struct ib_reg_wr *wr, | |||
2251 | wqe->frmr.levels = qplib_frpl->hwq.level + 1; | 2259 | wqe->frmr.levels = qplib_frpl->hwq.level + 1; |
2252 | wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR; | 2260 | wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR; |
2253 | 2261 | ||
2254 | if (wr->wr.send_flags & IB_SEND_FENCE) | 2262 | /* Need unconditional fence for reg_mr |
2255 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE; | 2263 | * opcode to function as expected. |
2264 | */ | ||
2265 | |||
2266 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE; | ||
2267 | |||
2256 | if (wr->wr.send_flags & IB_SEND_SIGNALED) | 2268 | if (wr->wr.send_flags & IB_SEND_SIGNALED) |
2257 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP; | 2269 | wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP; |
2258 | 2270 | ||
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h index b88a48d43a9d..e62b7c2c7da6 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h | |||
@@ -222,4 +222,7 @@ struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev, | |||
222 | struct ib_udata *udata); | 222 | struct ib_udata *udata); |
223 | int bnxt_re_dealloc_ucontext(struct ib_ucontext *context); | 223 | int bnxt_re_dealloc_ucontext(struct ib_ucontext *context); |
224 | int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); | 224 | int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); |
225 | |||
226 | unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp); | ||
227 | void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags); | ||
225 | #endif /* __BNXT_RE_IB_VERBS_H__ */ | 228 | #endif /* __BNXT_RE_IB_VERBS_H__ */ |
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 33a448036c2e..f6e361750466 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c | |||
@@ -730,6 +730,13 @@ static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, | |||
730 | struct bnxt_re_qp *qp) | 730 | struct bnxt_re_qp *qp) |
731 | { | 731 | { |
732 | struct ib_event event; | 732 | struct ib_event event; |
733 | unsigned int flags; | ||
734 | |||
735 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) { | ||
736 | flags = bnxt_re_lock_cqs(qp); | ||
737 | bnxt_qplib_add_flush_qp(&qp->qplib_qp); | ||
738 | bnxt_re_unlock_cqs(qp, flags); | ||
739 | } | ||
733 | 740 | ||
734 | memset(&event, 0, sizeof(event)); | 741 | memset(&event, 0, sizeof(event)); |
735 | if (qp->qplib_qp.srq) { | 742 | if (qp->qplib_qp.srq) { |
@@ -1416,9 +1423,12 @@ static void bnxt_re_task(struct work_struct *work) | |||
1416 | switch (re_work->event) { | 1423 | switch (re_work->event) { |
1417 | case NETDEV_REGISTER: | 1424 | case NETDEV_REGISTER: |
1418 | rc = bnxt_re_ib_reg(rdev); | 1425 | rc = bnxt_re_ib_reg(rdev); |
1419 | if (rc) | 1426 | if (rc) { |
1420 | dev_err(rdev_to_dev(rdev), | 1427 | dev_err(rdev_to_dev(rdev), |
1421 | "Failed to register with IB: %#x", rc); | 1428 | "Failed to register with IB: %#x", rc); |
1429 | bnxt_re_remove_one(rdev); | ||
1430 | bnxt_re_dev_unreg(rdev); | ||
1431 | } | ||
1422 | break; | 1432 | break; |
1423 | case NETDEV_UP: | 1433 | case NETDEV_UP: |
1424 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, | 1434 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 3ea5b9624f6b..06b42c880fd4 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c | |||
@@ -88,75 +88,35 @@ static void __bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) | |||
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp, | 91 | static void bnxt_qplib_acquire_cq_flush_locks(struct bnxt_qplib_qp *qp, |
92 | unsigned long *flags) | 92 | unsigned long *flags) |
93 | __acquires(&qp->scq->hwq.lock) __acquires(&qp->rcq->hwq.lock) | 93 | __acquires(&qp->scq->flush_lock) __acquires(&qp->rcq->flush_lock) |
94 | { | 94 | { |
95 | spin_lock_irqsave(&qp->scq->hwq.lock, *flags); | 95 | spin_lock_irqsave(&qp->scq->flush_lock, *flags); |
96 | if (qp->scq == qp->rcq) | 96 | if (qp->scq == qp->rcq) |
97 | __acquire(&qp->rcq->hwq.lock); | 97 | __acquire(&qp->rcq->flush_lock); |
98 | else | 98 | else |
99 | spin_lock(&qp->rcq->hwq.lock); | 99 | spin_lock(&qp->rcq->flush_lock); |
100 | } | 100 | } |
101 | 101 | ||
102 | void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp, | 102 | static void bnxt_qplib_release_cq_flush_locks(struct bnxt_qplib_qp *qp, |
103 | unsigned long *flags) | 103 | unsigned long *flags) |
104 | __releases(&qp->scq->hwq.lock) __releases(&qp->rcq->hwq.lock) | 104 | __releases(&qp->scq->flush_lock) __releases(&qp->rcq->flush_lock) |
105 | { | 105 | { |
106 | if (qp->scq == qp->rcq) | 106 | if (qp->scq == qp->rcq) |
107 | __release(&qp->rcq->hwq.lock); | 107 | __release(&qp->rcq->flush_lock); |
108 | else | 108 | else |
109 | spin_unlock(&qp->rcq->hwq.lock); | 109 | spin_unlock(&qp->rcq->flush_lock); |
110 | spin_unlock_irqrestore(&qp->scq->hwq.lock, *flags); | 110 | spin_unlock_irqrestore(&qp->scq->flush_lock, *flags); |
111 | } | ||
112 | |||
113 | static struct bnxt_qplib_cq *bnxt_qplib_find_buddy_cq(struct bnxt_qplib_qp *qp, | ||
114 | struct bnxt_qplib_cq *cq) | ||
115 | { | ||
116 | struct bnxt_qplib_cq *buddy_cq = NULL; | ||
117 | |||
118 | if (qp->scq == qp->rcq) | ||
119 | buddy_cq = NULL; | ||
120 | else if (qp->scq == cq) | ||
121 | buddy_cq = qp->rcq; | ||
122 | else | ||
123 | buddy_cq = qp->scq; | ||
124 | return buddy_cq; | ||
125 | } | ||
126 | |||
127 | static void bnxt_qplib_lock_buddy_cq(struct bnxt_qplib_qp *qp, | ||
128 | struct bnxt_qplib_cq *cq) | ||
129 | __acquires(&buddy_cq->hwq.lock) | ||
130 | { | ||
131 | struct bnxt_qplib_cq *buddy_cq = NULL; | ||
132 | |||
133 | buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq); | ||
134 | if (!buddy_cq) | ||
135 | __acquire(&cq->hwq.lock); | ||
136 | else | ||
137 | spin_lock(&buddy_cq->hwq.lock); | ||
138 | } | ||
139 | |||
140 | static void bnxt_qplib_unlock_buddy_cq(struct bnxt_qplib_qp *qp, | ||
141 | struct bnxt_qplib_cq *cq) | ||
142 | __releases(&buddy_cq->hwq.lock) | ||
143 | { | ||
144 | struct bnxt_qplib_cq *buddy_cq = NULL; | ||
145 | |||
146 | buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq); | ||
147 | if (!buddy_cq) | ||
148 | __release(&cq->hwq.lock); | ||
149 | else | ||
150 | spin_unlock(&buddy_cq->hwq.lock); | ||
151 | } | 111 | } |
152 | 112 | ||
153 | void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) | 113 | void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp) |
154 | { | 114 | { |
155 | unsigned long flags; | 115 | unsigned long flags; |
156 | 116 | ||
157 | bnxt_qplib_acquire_cq_locks(qp, &flags); | 117 | bnxt_qplib_acquire_cq_flush_locks(qp, &flags); |
158 | __bnxt_qplib_add_flush_qp(qp); | 118 | __bnxt_qplib_add_flush_qp(qp); |
159 | bnxt_qplib_release_cq_locks(qp, &flags); | 119 | bnxt_qplib_release_cq_flush_locks(qp, &flags); |
160 | } | 120 | } |
161 | 121 | ||
162 | static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp) | 122 | static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp) |
@@ -177,7 +137,7 @@ void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) | |||
177 | { | 137 | { |
178 | unsigned long flags; | 138 | unsigned long flags; |
179 | 139 | ||
180 | bnxt_qplib_acquire_cq_locks(qp, &flags); | 140 | bnxt_qplib_acquire_cq_flush_locks(qp, &flags); |
181 | __clean_cq(qp->scq, (u64)(unsigned long)qp); | 141 | __clean_cq(qp->scq, (u64)(unsigned long)qp); |
182 | qp->sq.hwq.prod = 0; | 142 | qp->sq.hwq.prod = 0; |
183 | qp->sq.hwq.cons = 0; | 143 | qp->sq.hwq.cons = 0; |
@@ -186,7 +146,7 @@ void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) | |||
186 | qp->rq.hwq.cons = 0; | 146 | qp->rq.hwq.cons = 0; |
187 | 147 | ||
188 | __bnxt_qplib_del_flush_qp(qp); | 148 | __bnxt_qplib_del_flush_qp(qp); |
189 | bnxt_qplib_release_cq_locks(qp, &flags); | 149 | bnxt_qplib_release_cq_flush_locks(qp, &flags); |
190 | } | 150 | } |
191 | 151 | ||
192 | static void bnxt_qpn_cqn_sched_task(struct work_struct *work) | 152 | static void bnxt_qpn_cqn_sched_task(struct work_struct *work) |
@@ -2107,9 +2067,6 @@ void bnxt_qplib_mark_qp_error(void *qp_handle) | |||
2107 | /* Must block new posting of SQ and RQ */ | 2067 | /* Must block new posting of SQ and RQ */ |
2108 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2068 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2109 | bnxt_qplib_cancel_phantom_processing(qp); | 2069 | bnxt_qplib_cancel_phantom_processing(qp); |
2110 | |||
2111 | /* Add qp to flush list of the CQ */ | ||
2112 | __bnxt_qplib_add_flush_qp(qp); | ||
2113 | } | 2070 | } |
2114 | 2071 | ||
2115 | /* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive) | 2072 | /* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive) |
@@ -2285,9 +2242,9 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, | |||
2285 | sw_sq_cons, cqe->wr_id, cqe->status); | 2242 | sw_sq_cons, cqe->wr_id, cqe->status); |
2286 | cqe++; | 2243 | cqe++; |
2287 | (*budget)--; | 2244 | (*budget)--; |
2288 | bnxt_qplib_lock_buddy_cq(qp, cq); | ||
2289 | bnxt_qplib_mark_qp_error(qp); | 2245 | bnxt_qplib_mark_qp_error(qp); |
2290 | bnxt_qplib_unlock_buddy_cq(qp, cq); | 2246 | /* Add qp to flush list of the CQ */ |
2247 | bnxt_qplib_add_flush_qp(qp); | ||
2291 | } else { | 2248 | } else { |
2292 | if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { | 2249 | if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { |
2293 | /* Before we complete, do WA 9060 */ | 2250 | /* Before we complete, do WA 9060 */ |
@@ -2403,9 +2360,7 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq, | |||
2403 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { | 2360 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { |
2404 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2361 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2405 | /* Add qp to flush list of the CQ */ | 2362 | /* Add qp to flush list of the CQ */ |
2406 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2363 | bnxt_qplib_add_flush_qp(qp); |
2407 | __bnxt_qplib_add_flush_qp(qp); | ||
2408 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2409 | } | 2364 | } |
2410 | } | 2365 | } |
2411 | 2366 | ||
@@ -2489,9 +2444,7 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq, | |||
2489 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { | 2444 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { |
2490 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2445 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2491 | /* Add qp to flush list of the CQ */ | 2446 | /* Add qp to flush list of the CQ */ |
2492 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2447 | bnxt_qplib_add_flush_qp(qp); |
2493 | __bnxt_qplib_add_flush_qp(qp); | ||
2494 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2495 | } | 2448 | } |
2496 | } | 2449 | } |
2497 | done: | 2450 | done: |
@@ -2501,11 +2454,9 @@ done: | |||
2501 | bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) | 2454 | bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) |
2502 | { | 2455 | { |
2503 | struct cq_base *hw_cqe, **hw_cqe_ptr; | 2456 | struct cq_base *hw_cqe, **hw_cqe_ptr; |
2504 | unsigned long flags; | ||
2505 | u32 sw_cons, raw_cons; | 2457 | u32 sw_cons, raw_cons; |
2506 | bool rc = true; | 2458 | bool rc = true; |
2507 | 2459 | ||
2508 | spin_lock_irqsave(&cq->hwq.lock, flags); | ||
2509 | raw_cons = cq->hwq.cons; | 2460 | raw_cons = cq->hwq.cons; |
2510 | sw_cons = HWQ_CMP(raw_cons, &cq->hwq); | 2461 | sw_cons = HWQ_CMP(raw_cons, &cq->hwq); |
2511 | hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr; | 2462 | hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr; |
@@ -2513,7 +2464,6 @@ bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq) | |||
2513 | 2464 | ||
2514 | /* Check for Valid bit. If the CQE is valid, return false */ | 2465 | /* Check for Valid bit. If the CQE is valid, return false */ |
2515 | rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements); | 2466 | rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements); |
2516 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | ||
2517 | return rc; | 2467 | return rc; |
2518 | } | 2468 | } |
2519 | 2469 | ||
@@ -2602,9 +2552,7 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq, | |||
2602 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { | 2552 | if (hwcqe->status != CQ_RES_RC_STATUS_OK) { |
2603 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; | 2553 | qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; |
2604 | /* Add qp to flush list of the CQ */ | 2554 | /* Add qp to flush list of the CQ */ |
2605 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2555 | bnxt_qplib_add_flush_qp(qp); |
2606 | __bnxt_qplib_add_flush_qp(qp); | ||
2607 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2608 | } | 2556 | } |
2609 | } | 2557 | } |
2610 | 2558 | ||
@@ -2719,9 +2667,7 @@ do_rq: | |||
2719 | */ | 2667 | */ |
2720 | 2668 | ||
2721 | /* Add qp to flush list of the CQ */ | 2669 | /* Add qp to flush list of the CQ */ |
2722 | bnxt_qplib_lock_buddy_cq(qp, cq); | 2670 | bnxt_qplib_add_flush_qp(qp); |
2723 | __bnxt_qplib_add_flush_qp(qp); | ||
2724 | bnxt_qplib_unlock_buddy_cq(qp, cq); | ||
2725 | done: | 2671 | done: |
2726 | return rc; | 2672 | return rc; |
2727 | } | 2673 | } |
@@ -2750,7 +2696,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, | |||
2750 | u32 budget = num_cqes; | 2696 | u32 budget = num_cqes; |
2751 | unsigned long flags; | 2697 | unsigned long flags; |
2752 | 2698 | ||
2753 | spin_lock_irqsave(&cq->hwq.lock, flags); | 2699 | spin_lock_irqsave(&cq->flush_lock, flags); |
2754 | list_for_each_entry(qp, &cq->sqf_head, sq_flush) { | 2700 | list_for_each_entry(qp, &cq->sqf_head, sq_flush) { |
2755 | dev_dbg(&cq->hwq.pdev->dev, | 2701 | dev_dbg(&cq->hwq.pdev->dev, |
2756 | "QPLIB: FP: Flushing SQ QP= %p", | 2702 | "QPLIB: FP: Flushing SQ QP= %p", |
@@ -2764,7 +2710,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, | |||
2764 | qp); | 2710 | qp); |
2765 | __flush_rq(&qp->rq, qp, &cqe, &budget); | 2711 | __flush_rq(&qp->rq, qp, &cqe, &budget); |
2766 | } | 2712 | } |
2767 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | 2713 | spin_unlock_irqrestore(&cq->flush_lock, flags); |
2768 | 2714 | ||
2769 | return num_cqes - budget; | 2715 | return num_cqes - budget; |
2770 | } | 2716 | } |
@@ -2773,11 +2719,9 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, | |||
2773 | int num_cqes, struct bnxt_qplib_qp **lib_qp) | 2719 | int num_cqes, struct bnxt_qplib_qp **lib_qp) |
2774 | { | 2720 | { |
2775 | struct cq_base *hw_cqe, **hw_cqe_ptr; | 2721 | struct cq_base *hw_cqe, **hw_cqe_ptr; |
2776 | unsigned long flags; | ||
2777 | u32 sw_cons, raw_cons; | 2722 | u32 sw_cons, raw_cons; |
2778 | int budget, rc = 0; | 2723 | int budget, rc = 0; |
2779 | 2724 | ||
2780 | spin_lock_irqsave(&cq->hwq.lock, flags); | ||
2781 | raw_cons = cq->hwq.cons; | 2725 | raw_cons = cq->hwq.cons; |
2782 | budget = num_cqes; | 2726 | budget = num_cqes; |
2783 | 2727 | ||
@@ -2853,20 +2797,15 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, | |||
2853 | bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ); | 2797 | bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ); |
2854 | } | 2798 | } |
2855 | exit: | 2799 | exit: |
2856 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | ||
2857 | return num_cqes - budget; | 2800 | return num_cqes - budget; |
2858 | } | 2801 | } |
2859 | 2802 | ||
2860 | void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type) | 2803 | void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type) |
2861 | { | 2804 | { |
2862 | unsigned long flags; | ||
2863 | |||
2864 | spin_lock_irqsave(&cq->hwq.lock, flags); | ||
2865 | if (arm_type) | 2805 | if (arm_type) |
2866 | bnxt_qplib_arm_cq(cq, arm_type); | 2806 | bnxt_qplib_arm_cq(cq, arm_type); |
2867 | /* Using cq->arm_state variable to track whether to issue cq handler */ | 2807 | /* Using cq->arm_state variable to track whether to issue cq handler */ |
2868 | atomic_set(&cq->arm_state, 1); | 2808 | atomic_set(&cq->arm_state, 1); |
2869 | spin_unlock_irqrestore(&cq->hwq.lock, flags); | ||
2870 | } | 2809 | } |
2871 | 2810 | ||
2872 | void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp) | 2811 | void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp) |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h index ca0a2ffa3509..ade9f13c0fd1 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h | |||
@@ -389,6 +389,18 @@ struct bnxt_qplib_cq { | |||
389 | struct list_head sqf_head, rqf_head; | 389 | struct list_head sqf_head, rqf_head; |
390 | atomic_t arm_state; | 390 | atomic_t arm_state; |
391 | spinlock_t compl_lock; /* synch CQ handlers */ | 391 | spinlock_t compl_lock; /* synch CQ handlers */ |
392 | /* Locking Notes: | ||
393 | * QP can move to error state from modify_qp, async error event or error | ||
394 | * CQE as part of poll_cq. When QP is moved to error state, it gets added | ||
395 | * to two flush lists, one each for SQ and RQ. | ||
396 | * Each flush list is protected by qplib_cq->flush_lock. Both scq and rcq | ||
397 | * flush_locks should be acquired when QP is moved to error. The control path | ||
398 | * operations(modify_qp and async error events) are synchronized with poll_cq | ||
399 | * using upper level CQ locks (bnxt_re_cq->cq_lock) of both SCQ and RCQ. | ||
400 | * The qplib_cq->flush_lock is required to synchronize two instances of poll_cq | ||
401 | * of the same QP while manipulating the flush list. | ||
402 | */ | ||
403 | spinlock_t flush_lock; /* QP flush management */ | ||
392 | }; | 404 | }; |
393 | 405 | ||
394 | #define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE sizeof(struct xrrq_irrq) | 406 | #define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE sizeof(struct xrrq_irrq) |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 8329ec6a7946..80027a494730 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | |||
@@ -305,9 +305,8 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, | |||
305 | err_event->res_err_state_reason); | 305 | err_event->res_err_state_reason); |
306 | if (!qp) | 306 | if (!qp) |
307 | break; | 307 | break; |
308 | bnxt_qplib_acquire_cq_locks(qp, &flags); | ||
309 | bnxt_qplib_mark_qp_error(qp); | 308 | bnxt_qplib_mark_qp_error(qp); |
310 | bnxt_qplib_release_cq_locks(qp, &flags); | 309 | rcfw->aeq_handler(rcfw, qp_event, qp); |
311 | break; | 310 | break; |
312 | default: | 311 | default: |
313 | /* Command Response */ | 312 | /* Command Response */ |
@@ -460,7 +459,11 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw, | |||
460 | int rc; | 459 | int rc; |
461 | 460 | ||
462 | RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags); | 461 | RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags); |
463 | 462 | /* Supply (log-base-2-of-host-page-size - base-page-shift) | |
463 | * to bono to adjust the doorbell page sizes. | ||
464 | */ | ||
465 | req.log2_dbr_pg_size = cpu_to_le16(PAGE_SHIFT - | ||
466 | RCFW_DBR_BASE_PAGE_SHIFT); | ||
464 | /* | 467 | /* |
465 | * VFs need not setup the HW context area, PF | 468 | * VFs need not setup the HW context area, PF |
466 | * shall setup this area for VF. Skipping the | 469 | * shall setup this area for VF. Skipping the |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h index 6bee6e3636ea..c7cce2e4185e 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #define RCFW_COMM_SIZE 0x104 | 49 | #define RCFW_COMM_SIZE 0x104 |
50 | 50 | ||
51 | #define RCFW_DBR_PCI_BAR_REGION 2 | 51 | #define RCFW_DBR_PCI_BAR_REGION 2 |
52 | #define RCFW_DBR_BASE_PAGE_SHIFT 12 | ||
52 | 53 | ||
53 | #define RCFW_CMD_PREP(req, CMD, cmd_flags) \ | 54 | #define RCFW_CMD_PREP(req, CMD, cmd_flags) \ |
54 | do { \ | 55 | do { \ |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c index 03057983341f..ee98e5efef84 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c | |||
@@ -139,7 +139,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, | |||
139 | attr->max_pkey = le32_to_cpu(sb->max_pkeys); | 139 | attr->max_pkey = le32_to_cpu(sb->max_pkeys); |
140 | 140 | ||
141 | attr->max_inline_data = le32_to_cpu(sb->max_inline_data); | 141 | attr->max_inline_data = le32_to_cpu(sb->max_inline_data); |
142 | attr->l2_db_size = (sb->l2_db_space_size + 1) * PAGE_SIZE; | 142 | attr->l2_db_size = (sb->l2_db_space_size + 1) * |
143 | (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); | ||
143 | attr->max_sgid = le32_to_cpu(sb->max_gid); | 144 | attr->max_sgid = le32_to_cpu(sb->max_gid); |
144 | 145 | ||
145 | bnxt_qplib_query_version(rcfw, attr->fw_ver); | 146 | bnxt_qplib_query_version(rcfw, attr->fw_ver); |
diff --git a/drivers/infiniband/hw/bnxt_re/roce_hsi.h b/drivers/infiniband/hw/bnxt_re/roce_hsi.h index 2d7ea096a247..3e5a4f760d0e 100644 --- a/drivers/infiniband/hw/bnxt_re/roce_hsi.h +++ b/drivers/infiniband/hw/bnxt_re/roce_hsi.h | |||
@@ -1761,7 +1761,30 @@ struct cmdq_initialize_fw { | |||
1761 | #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_2M (0x3UL << 4) | 1761 | #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_2M (0x3UL << 4) |
1762 | #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_8M (0x4UL << 4) | 1762 | #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_8M (0x4UL << 4) |
1763 | #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_1G (0x5UL << 4) | 1763 | #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_1G (0x5UL << 4) |
1764 | __le16 reserved16; | 1764 | /* This value is (log-base-2-of-DBR-page-size - 12). |
1765 | * 0 for 4KB. HW supported values are enumerated below. | ||
1766 | */ | ||
1767 | __le16 log2_dbr_pg_size; | ||
1768 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_MASK 0xfUL | ||
1769 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_SFT 0 | ||
1770 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_4K 0x0UL | ||
1771 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_8K 0x1UL | ||
1772 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_16K 0x2UL | ||
1773 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_32K 0x3UL | ||
1774 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_64K 0x4UL | ||
1775 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128K 0x5UL | ||
1776 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_256K 0x6UL | ||
1777 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_512K 0x7UL | ||
1778 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_1M 0x8UL | ||
1779 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_2M 0x9UL | ||
1780 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_4M 0xaUL | ||
1781 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_8M 0xbUL | ||
1782 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_16M 0xcUL | ||
1783 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_32M 0xdUL | ||
1784 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_64M 0xeUL | ||
1785 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128M 0xfUL | ||
1786 | #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_LAST \ | ||
1787 | CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128M | ||
1765 | __le64 qpc_page_dir; | 1788 | __le64 qpc_page_dir; |
1766 | __le64 mrw_page_dir; | 1789 | __le64 mrw_page_dir; |
1767 | __le64 srq_page_dir; | 1790 | __le64 srq_page_dir; |
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 9a566ee3ceff..82adc0d1d30e 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
@@ -601,6 +601,7 @@ static void use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct | |||
601 | wc->dlid_path_bits = 0; | 601 | wc->dlid_path_bits = 0; |
602 | 602 | ||
603 | if (is_eth) { | 603 | if (is_eth) { |
604 | wc->slid = 0; | ||
604 | wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid); | 605 | wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid); |
605 | memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4); | 606 | memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4); |
606 | memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2); | 607 | memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2); |
@@ -851,7 +852,6 @@ repoll: | |||
851 | } | 852 | } |
852 | } | 853 | } |
853 | 854 | ||
854 | wc->slid = be16_to_cpu(cqe->rlid); | ||
855 | g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); | 855 | g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); |
856 | wc->src_qp = g_mlpath_rqpn & 0xffffff; | 856 | wc->src_qp = g_mlpath_rqpn & 0xffffff; |
857 | wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f; | 857 | wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f; |
@@ -860,6 +860,7 @@ repoll: | |||
860 | wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status, | 860 | wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status, |
861 | cqe->checksum) ? IB_WC_IP_CSUM_OK : 0; | 861 | cqe->checksum) ? IB_WC_IP_CSUM_OK : 0; |
862 | if (is_eth) { | 862 | if (is_eth) { |
863 | wc->slid = 0; | ||
863 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 13; | 864 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 13; |
864 | if (be32_to_cpu(cqe->vlan_my_qpn) & | 865 | if (be32_to_cpu(cqe->vlan_my_qpn) & |
865 | MLX4_CQE_CVLAN_PRESENT_MASK) { | 866 | MLX4_CQE_CVLAN_PRESENT_MASK) { |
@@ -871,6 +872,7 @@ repoll: | |||
871 | memcpy(wc->smac, cqe->smac, ETH_ALEN); | 872 | memcpy(wc->smac, cqe->smac, ETH_ALEN); |
872 | wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC); | 873 | wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC); |
873 | } else { | 874 | } else { |
875 | wc->slid = be16_to_cpu(cqe->rlid); | ||
874 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 12; | 876 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 12; |
875 | wc->vlan_id = 0xffff; | 877 | wc->vlan_id = 0xffff; |
876 | } | 878 | } |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 8d2ee9322f2e..5a0e4fc4785a 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -219,8 +219,6 @@ static int mlx4_ib_update_gids_v1_v2(struct gid_entry *gids, | |||
219 | gid_tbl[i].version = 2; | 219 | gid_tbl[i].version = 2; |
220 | if (!ipv6_addr_v4mapped((struct in6_addr *)&gids[i].gid)) | 220 | if (!ipv6_addr_v4mapped((struct in6_addr *)&gids[i].gid)) |
221 | gid_tbl[i].type = 1; | 221 | gid_tbl[i].type = 1; |
222 | else | ||
223 | memset(&gid_tbl[i].gid, 0, 12); | ||
224 | } | 222 | } |
225 | } | 223 | } |
226 | 224 | ||
@@ -366,8 +364,13 @@ static int mlx4_ib_del_gid(struct ib_device *device, | |||
366 | if (!gids) { | 364 | if (!gids) { |
367 | ret = -ENOMEM; | 365 | ret = -ENOMEM; |
368 | } else { | 366 | } else { |
369 | for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) | 367 | for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) { |
370 | memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid)); | 368 | memcpy(&gids[i].gid, |
369 | &port_gid_table->gids[i].gid, | ||
370 | sizeof(union ib_gid)); | ||
371 | gids[i].gid_type = | ||
372 | port_gid_table->gids[i].gid_type; | ||
373 | } | ||
371 | } | 374 | } |
372 | } | 375 | } |
373 | spin_unlock_bh(&iboe->lock); | 376 | spin_unlock_bh(&iboe->lock); |
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index 5b974fb97611..15457c9569a7 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c | |||
@@ -226,7 +226,6 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, | |||
226 | wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey); | 226 | wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey); |
227 | break; | 227 | break; |
228 | } | 228 | } |
229 | wc->slid = be16_to_cpu(cqe->slid); | ||
230 | wc->src_qp = be32_to_cpu(cqe->flags_rqpn) & 0xffffff; | 229 | wc->src_qp = be32_to_cpu(cqe->flags_rqpn) & 0xffffff; |
231 | wc->dlid_path_bits = cqe->ml_path; | 230 | wc->dlid_path_bits = cqe->ml_path; |
232 | g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3; | 231 | g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3; |
@@ -241,10 +240,12 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, | |||
241 | } | 240 | } |
242 | 241 | ||
243 | if (ll != IB_LINK_LAYER_ETHERNET) { | 242 | if (ll != IB_LINK_LAYER_ETHERNET) { |
243 | wc->slid = be16_to_cpu(cqe->slid); | ||
244 | wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf; | 244 | wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf; |
245 | return; | 245 | return; |
246 | } | 246 | } |
247 | 247 | ||
248 | wc->slid = 0; | ||
248 | vlan_present = cqe->l4_l3_hdr_type & 0x1; | 249 | vlan_present = cqe->l4_l3_hdr_type & 0x1; |
249 | roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3; | 250 | roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3; |
250 | if (vlan_present) { | 251 | if (vlan_present) { |
@@ -1177,7 +1178,12 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, | |||
1177 | if (ucmd.reserved0 || ucmd.reserved1) | 1178 | if (ucmd.reserved0 || ucmd.reserved1) |
1178 | return -EINVAL; | 1179 | return -EINVAL; |
1179 | 1180 | ||
1180 | umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size, | 1181 | /* check multiplication overflow */ |
1182 | if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1) | ||
1183 | return -EINVAL; | ||
1184 | |||
1185 | umem = ib_umem_get(context, ucmd.buf_addr, | ||
1186 | (size_t)ucmd.cqe_size * entries, | ||
1181 | IB_ACCESS_LOCAL_WRITE, 1); | 1187 | IB_ACCESS_LOCAL_WRITE, 1); |
1182 | if (IS_ERR(umem)) { | 1188 | if (IS_ERR(umem)) { |
1183 | err = PTR_ERR(umem); | 1189 | err = PTR_ERR(umem); |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 4236c8086820..033b6af90de9 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -245,12 +245,16 @@ struct mlx5_core_dev *mlx5_ib_get_native_port_mdev(struct mlx5_ib_dev *ibdev, | |||
245 | struct mlx5_ib_multiport_info *mpi; | 245 | struct mlx5_ib_multiport_info *mpi; |
246 | struct mlx5_ib_port *port; | 246 | struct mlx5_ib_port *port; |
247 | 247 | ||
248 | if (!mlx5_core_mp_enabled(ibdev->mdev) || | ||
249 | ll != IB_LINK_LAYER_ETHERNET) { | ||
250 | if (native_port_num) | ||
251 | *native_port_num = ib_port_num; | ||
252 | return ibdev->mdev; | ||
253 | } | ||
254 | |||
248 | if (native_port_num) | 255 | if (native_port_num) |
249 | *native_port_num = 1; | 256 | *native_port_num = 1; |
250 | 257 | ||
251 | if (!mlx5_core_mp_enabled(ibdev->mdev) || ll != IB_LINK_LAYER_ETHERNET) | ||
252 | return ibdev->mdev; | ||
253 | |||
254 | port = &ibdev->port[ib_port_num - 1]; | 258 | port = &ibdev->port[ib_port_num - 1]; |
255 | if (!port) | 259 | if (!port) |
256 | return NULL; | 260 | return NULL; |
@@ -3263,7 +3267,7 @@ static void mlx5_ib_handle_event(struct work_struct *_work) | |||
3263 | struct mlx5_ib_dev *ibdev; | 3267 | struct mlx5_ib_dev *ibdev; |
3264 | struct ib_event ibev; | 3268 | struct ib_event ibev; |
3265 | bool fatal = false; | 3269 | bool fatal = false; |
3266 | u8 port = 0; | 3270 | u8 port = (u8)work->param; |
3267 | 3271 | ||
3268 | if (mlx5_core_is_mp_slave(work->dev)) { | 3272 | if (mlx5_core_is_mp_slave(work->dev)) { |
3269 | ibdev = mlx5_ib_get_ibdev_from_mpi(work->context); | 3273 | ibdev = mlx5_ib_get_ibdev_from_mpi(work->context); |
@@ -3283,8 +3287,6 @@ static void mlx5_ib_handle_event(struct work_struct *_work) | |||
3283 | case MLX5_DEV_EVENT_PORT_UP: | 3287 | case MLX5_DEV_EVENT_PORT_UP: |
3284 | case MLX5_DEV_EVENT_PORT_DOWN: | 3288 | case MLX5_DEV_EVENT_PORT_DOWN: |
3285 | case MLX5_DEV_EVENT_PORT_INITIALIZED: | 3289 | case MLX5_DEV_EVENT_PORT_INITIALIZED: |
3286 | port = (u8)work->param; | ||
3287 | |||
3288 | /* In RoCE, port up/down events are handled in | 3290 | /* In RoCE, port up/down events are handled in |
3289 | * mlx5_netdev_event(). | 3291 | * mlx5_netdev_event(). |
3290 | */ | 3292 | */ |
@@ -3298,24 +3300,19 @@ static void mlx5_ib_handle_event(struct work_struct *_work) | |||
3298 | 3300 | ||
3299 | case MLX5_DEV_EVENT_LID_CHANGE: | 3301 | case MLX5_DEV_EVENT_LID_CHANGE: |
3300 | ibev.event = IB_EVENT_LID_CHANGE; | 3302 | ibev.event = IB_EVENT_LID_CHANGE; |
3301 | port = (u8)work->param; | ||
3302 | break; | 3303 | break; |
3303 | 3304 | ||
3304 | case MLX5_DEV_EVENT_PKEY_CHANGE: | 3305 | case MLX5_DEV_EVENT_PKEY_CHANGE: |
3305 | ibev.event = IB_EVENT_PKEY_CHANGE; | 3306 | ibev.event = IB_EVENT_PKEY_CHANGE; |
3306 | port = (u8)work->param; | ||
3307 | |||
3308 | schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work); | 3307 | schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work); |
3309 | break; | 3308 | break; |
3310 | 3309 | ||
3311 | case MLX5_DEV_EVENT_GUID_CHANGE: | 3310 | case MLX5_DEV_EVENT_GUID_CHANGE: |
3312 | ibev.event = IB_EVENT_GID_CHANGE; | 3311 | ibev.event = IB_EVENT_GID_CHANGE; |
3313 | port = (u8)work->param; | ||
3314 | break; | 3312 | break; |
3315 | 3313 | ||
3316 | case MLX5_DEV_EVENT_CLIENT_REREG: | 3314 | case MLX5_DEV_EVENT_CLIENT_REREG: |
3317 | ibev.event = IB_EVENT_CLIENT_REREGISTER; | 3315 | ibev.event = IB_EVENT_CLIENT_REREGISTER; |
3318 | port = (u8)work->param; | ||
3319 | break; | 3316 | break; |
3320 | case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT: | 3317 | case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT: |
3321 | schedule_work(&ibdev->delay_drop.delay_drop_work); | 3318 | schedule_work(&ibdev->delay_drop.delay_drop_work); |
@@ -3327,7 +3324,7 @@ static void mlx5_ib_handle_event(struct work_struct *_work) | |||
3327 | ibev.device = &ibdev->ib_dev; | 3324 | ibev.device = &ibdev->ib_dev; |
3328 | ibev.element.port_num = port; | 3325 | ibev.element.port_num = port; |
3329 | 3326 | ||
3330 | if (port < 1 || port > ibdev->num_ports) { | 3327 | if (!rdma_is_port_valid(&ibdev->ib_dev, port)) { |
3331 | mlx5_ib_warn(ibdev, "warning: event on port %d\n", port); | 3328 | mlx5_ib_warn(ibdev, "warning: event on port %d\n", port); |
3332 | goto out; | 3329 | goto out; |
3333 | } | 3330 | } |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 556e015678de..1961c6a45437 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
@@ -1816,7 +1816,6 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, | |||
1816 | 1816 | ||
1817 | mr->ibmr.iova = sg_dma_address(sg) + sg_offset; | 1817 | mr->ibmr.iova = sg_dma_address(sg) + sg_offset; |
1818 | mr->ibmr.length = 0; | 1818 | mr->ibmr.length = 0; |
1819 | mr->ndescs = sg_nents; | ||
1820 | 1819 | ||
1821 | for_each_sg(sgl, sg, sg_nents, i) { | 1820 | for_each_sg(sgl, sg, sg_nents, i) { |
1822 | if (unlikely(i >= mr->max_descs)) | 1821 | if (unlikely(i >= mr->max_descs)) |
@@ -1828,6 +1827,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, | |||
1828 | 1827 | ||
1829 | sg_offset = 0; | 1828 | sg_offset = 0; |
1830 | } | 1829 | } |
1830 | mr->ndescs = i; | ||
1831 | 1831 | ||
1832 | if (sg_offset_p) | 1832 | if (sg_offset_p) |
1833 | *sg_offset_p = sg_offset; | 1833 | *sg_offset_p = sg_offset; |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 39d24bf694a8..36197fbac63a 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -1584,6 +1584,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, | |||
1584 | u32 uidx = MLX5_IB_DEFAULT_UIDX; | 1584 | u32 uidx = MLX5_IB_DEFAULT_UIDX; |
1585 | struct mlx5_ib_create_qp ucmd; | 1585 | struct mlx5_ib_create_qp ucmd; |
1586 | struct mlx5_ib_qp_base *base; | 1586 | struct mlx5_ib_qp_base *base; |
1587 | int mlx5_st; | ||
1587 | void *qpc; | 1588 | void *qpc; |
1588 | u32 *in; | 1589 | u32 *in; |
1589 | int err; | 1590 | int err; |
@@ -1592,6 +1593,10 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, | |||
1592 | spin_lock_init(&qp->sq.lock); | 1593 | spin_lock_init(&qp->sq.lock); |
1593 | spin_lock_init(&qp->rq.lock); | 1594 | spin_lock_init(&qp->rq.lock); |
1594 | 1595 | ||
1596 | mlx5_st = to_mlx5_st(init_attr->qp_type); | ||
1597 | if (mlx5_st < 0) | ||
1598 | return -EINVAL; | ||
1599 | |||
1595 | if (init_attr->rwq_ind_tbl) { | 1600 | if (init_attr->rwq_ind_tbl) { |
1596 | if (!udata) | 1601 | if (!udata) |
1597 | return -ENOSYS; | 1602 | return -ENOSYS; |
@@ -1753,7 +1758,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, | |||
1753 | 1758 | ||
1754 | qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); | 1759 | qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); |
1755 | 1760 | ||
1756 | MLX5_SET(qpc, qpc, st, to_mlx5_st(init_attr->qp_type)); | 1761 | MLX5_SET(qpc, qpc, st, mlx5_st); |
1757 | MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); | 1762 | MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); |
1758 | 1763 | ||
1759 | if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR) | 1764 | if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR) |
@@ -3095,8 +3100,10 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, | |||
3095 | goto out; | 3100 | goto out; |
3096 | 3101 | ||
3097 | if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE || | 3102 | if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE || |
3098 | !optab[mlx5_cur][mlx5_new]) | 3103 | !optab[mlx5_cur][mlx5_new]) { |
3104 | err = -EINVAL; | ||
3099 | goto out; | 3105 | goto out; |
3106 | } | ||
3100 | 3107 | ||
3101 | op = optab[mlx5_cur][mlx5_new]; | 3108 | op = optab[mlx5_cur][mlx5_new]; |
3102 | optpar = ib_mask_to_mlx5_opt(attr_mask); | 3109 | optpar = ib_mask_to_mlx5_opt(attr_mask); |
diff --git a/drivers/infiniband/hw/qedr/qedr_iw_cm.c b/drivers/infiniband/hw/qedr/qedr_iw_cm.c index 478b7317b80a..26dc374787f7 100644 --- a/drivers/infiniband/hw/qedr/qedr_iw_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_iw_cm.c | |||
@@ -458,8 +458,7 @@ qedr_addr6_resolve(struct qedr_dev *dev, | |||
458 | } | 458 | } |
459 | return -EINVAL; | 459 | return -EINVAL; |
460 | } | 460 | } |
461 | neigh = dst_neigh_lookup(dst, &dst_in); | 461 | neigh = dst_neigh_lookup(dst, &fl6.daddr); |
462 | |||
463 | if (neigh) { | 462 | if (neigh) { |
464 | rcu_read_lock(); | 463 | rcu_read_lock(); |
465 | if (neigh->nud_state & NUD_VALID) { | 464 | if (neigh->nud_state & NUD_VALID) { |
@@ -494,10 +493,14 @@ int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
494 | 493 | ||
495 | qp = idr_find(&dev->qpidr, conn_param->qpn); | 494 | qp = idr_find(&dev->qpidr, conn_param->qpn); |
496 | 495 | ||
497 | laddr = (struct sockaddr_in *)&cm_id->local_addr; | 496 | laddr = (struct sockaddr_in *)&cm_id->m_local_addr; |
498 | raddr = (struct sockaddr_in *)&cm_id->remote_addr; | 497 | raddr = (struct sockaddr_in *)&cm_id->m_remote_addr; |
499 | laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr; | 498 | laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr; |
500 | raddr6 = (struct sockaddr_in6 *)&cm_id->remote_addr; | 499 | raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr; |
500 | |||
501 | DP_DEBUG(dev, QEDR_MSG_IWARP, "MAPPED %d %d\n", | ||
502 | ntohs(((struct sockaddr_in *)&cm_id->remote_addr)->sin_port), | ||
503 | ntohs(raddr->sin_port)); | ||
501 | 504 | ||
502 | DP_DEBUG(dev, QEDR_MSG_IWARP, | 505 | DP_DEBUG(dev, QEDR_MSG_IWARP, |
503 | "Connect source address: %pISpc, remote address: %pISpc\n", | 506 | "Connect source address: %pISpc, remote address: %pISpc\n", |
@@ -599,8 +602,8 @@ int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
599 | int rc; | 602 | int rc; |
600 | int i; | 603 | int i; |
601 | 604 | ||
602 | laddr = (struct sockaddr_in *)&cm_id->local_addr; | 605 | laddr = (struct sockaddr_in *)&cm_id->m_local_addr; |
603 | laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr; | 606 | laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr; |
604 | 607 | ||
605 | DP_DEBUG(dev, QEDR_MSG_IWARP, | 608 | DP_DEBUG(dev, QEDR_MSG_IWARP, |
606 | "Create Listener address: %pISpc\n", &cm_id->local_addr); | 609 | "Create Listener address: %pISpc\n", &cm_id->local_addr); |
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index 53f00dbf313f..875b17272d65 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c | |||
@@ -3034,6 +3034,11 @@ static int __qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
3034 | 3034 | ||
3035 | switch (wr->opcode) { | 3035 | switch (wr->opcode) { |
3036 | case IB_WR_SEND_WITH_IMM: | 3036 | case IB_WR_SEND_WITH_IMM: |
3037 | if (unlikely(rdma_protocol_iwarp(&dev->ibdev, 1))) { | ||
3038 | rc = -EINVAL; | ||
3039 | *bad_wr = wr; | ||
3040 | break; | ||
3041 | } | ||
3037 | wqe->req_type = RDMA_SQ_REQ_TYPE_SEND_WITH_IMM; | 3042 | wqe->req_type = RDMA_SQ_REQ_TYPE_SEND_WITH_IMM; |
3038 | swqe = (struct rdma_sq_send_wqe_1st *)wqe; | 3043 | swqe = (struct rdma_sq_send_wqe_1st *)wqe; |
3039 | swqe->wqe_size = 2; | 3044 | swqe->wqe_size = 2; |
@@ -3075,6 +3080,11 @@ static int __qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
3075 | break; | 3080 | break; |
3076 | 3081 | ||
3077 | case IB_WR_RDMA_WRITE_WITH_IMM: | 3082 | case IB_WR_RDMA_WRITE_WITH_IMM: |
3083 | if (unlikely(rdma_protocol_iwarp(&dev->ibdev, 1))) { | ||
3084 | rc = -EINVAL; | ||
3085 | *bad_wr = wr; | ||
3086 | break; | ||
3087 | } | ||
3078 | wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR_WITH_IMM; | 3088 | wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR_WITH_IMM; |
3079 | rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe; | 3089 | rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe; |
3080 | 3090 | ||
@@ -3724,7 +3734,7 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
3724 | { | 3734 | { |
3725 | struct qedr_dev *dev = get_qedr_dev(ibcq->device); | 3735 | struct qedr_dev *dev = get_qedr_dev(ibcq->device); |
3726 | struct qedr_cq *cq = get_qedr_cq(ibcq); | 3736 | struct qedr_cq *cq = get_qedr_cq(ibcq); |
3727 | union rdma_cqe *cqe = cq->latest_cqe; | 3737 | union rdma_cqe *cqe; |
3728 | u32 old_cons, new_cons; | 3738 | u32 old_cons, new_cons; |
3729 | unsigned long flags; | 3739 | unsigned long flags; |
3730 | int update = 0; | 3740 | int update = 0; |
@@ -3741,6 +3751,7 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
3741 | return qedr_gsi_poll_cq(ibcq, num_entries, wc); | 3751 | return qedr_gsi_poll_cq(ibcq, num_entries, wc); |
3742 | 3752 | ||
3743 | spin_lock_irqsave(&cq->cq_lock, flags); | 3753 | spin_lock_irqsave(&cq->cq_lock, flags); |
3754 | cqe = cq->latest_cqe; | ||
3744 | old_cons = qed_chain_get_cons_idx_u32(&cq->pbl); | 3755 | old_cons = qed_chain_get_cons_idx_u32(&cq->pbl); |
3745 | while (num_entries && is_valid_cqe(cq, cqe)) { | 3756 | while (num_entries && is_valid_cqe(cq, cqe)) { |
3746 | struct qedr_qp *qp; | 3757 | struct qedr_qp *qp; |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 4d1d8dfb2d2a..f2273143b3cb 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -963,6 +963,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, | |||
963 | uint32_t rtime = cpu_to_le32(get_seconds()); | 963 | uint32_t rtime = cpu_to_le32(get_seconds()); |
964 | struct uuid_entry *u; | 964 | struct uuid_entry *u; |
965 | char buf[BDEVNAME_SIZE]; | 965 | char buf[BDEVNAME_SIZE]; |
966 | struct cached_dev *exist_dc, *t; | ||
966 | 967 | ||
967 | bdevname(dc->bdev, buf); | 968 | bdevname(dc->bdev, buf); |
968 | 969 | ||
@@ -987,6 +988,16 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, | |||
987 | return -EINVAL; | 988 | return -EINVAL; |
988 | } | 989 | } |
989 | 990 | ||
991 | /* Check whether already attached */ | ||
992 | list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) { | ||
993 | if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) { | ||
994 | pr_err("Tried to attach %s but duplicate UUID already attached", | ||
995 | buf); | ||
996 | |||
997 | return -EINVAL; | ||
998 | } | ||
999 | } | ||
1000 | |||
990 | u = uuid_find(c, dc->sb.uuid); | 1001 | u = uuid_find(c, dc->sb.uuid); |
991 | 1002 | ||
992 | if (u && | 1003 | if (u && |
@@ -1204,7 +1215,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, | |||
1204 | 1215 | ||
1205 | return; | 1216 | return; |
1206 | err: | 1217 | err: |
1207 | pr_notice("error opening %s: %s", bdevname(bdev, name), err); | 1218 | pr_notice("error %s: %s", bdevname(bdev, name), err); |
1208 | bcache_device_stop(&dc->disk); | 1219 | bcache_device_stop(&dc->disk); |
1209 | } | 1220 | } |
1210 | 1221 | ||
@@ -1883,6 +1894,8 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1883 | const char *err = NULL; /* must be set for any error case */ | 1894 | const char *err = NULL; /* must be set for any error case */ |
1884 | int ret = 0; | 1895 | int ret = 0; |
1885 | 1896 | ||
1897 | bdevname(bdev, name); | ||
1898 | |||
1886 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); | 1899 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); |
1887 | ca->bdev = bdev; | 1900 | ca->bdev = bdev; |
1888 | ca->bdev->bd_holder = ca; | 1901 | ca->bdev->bd_holder = ca; |
@@ -1891,11 +1904,12 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1891 | bio_first_bvec_all(&ca->sb_bio)->bv_page = sb_page; | 1904 | bio_first_bvec_all(&ca->sb_bio)->bv_page = sb_page; |
1892 | get_page(sb_page); | 1905 | get_page(sb_page); |
1893 | 1906 | ||
1894 | if (blk_queue_discard(bdev_get_queue(ca->bdev))) | 1907 | if (blk_queue_discard(bdev_get_queue(bdev))) |
1895 | ca->discard = CACHE_DISCARD(&ca->sb); | 1908 | ca->discard = CACHE_DISCARD(&ca->sb); |
1896 | 1909 | ||
1897 | ret = cache_alloc(ca); | 1910 | ret = cache_alloc(ca); |
1898 | if (ret != 0) { | 1911 | if (ret != 0) { |
1912 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | ||
1899 | if (ret == -ENOMEM) | 1913 | if (ret == -ENOMEM) |
1900 | err = "cache_alloc(): -ENOMEM"; | 1914 | err = "cache_alloc(): -ENOMEM"; |
1901 | else | 1915 | else |
@@ -1918,14 +1932,14 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1918 | goto out; | 1932 | goto out; |
1919 | } | 1933 | } |
1920 | 1934 | ||
1921 | pr_info("registered cache device %s", bdevname(bdev, name)); | 1935 | pr_info("registered cache device %s", name); |
1922 | 1936 | ||
1923 | out: | 1937 | out: |
1924 | kobject_put(&ca->kobj); | 1938 | kobject_put(&ca->kobj); |
1925 | 1939 | ||
1926 | err: | 1940 | err: |
1927 | if (err) | 1941 | if (err) |
1928 | pr_notice("error opening %s: %s", bdevname(bdev, name), err); | 1942 | pr_notice("error %s: %s", name, err); |
1929 | 1943 | ||
1930 | return ret; | 1944 | return ret; |
1931 | } | 1945 | } |
@@ -2014,6 +2028,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, | |||
2014 | if (err) | 2028 | if (err) |
2015 | goto err_close; | 2029 | goto err_close; |
2016 | 2030 | ||
2031 | err = "failed to register device"; | ||
2017 | if (SB_IS_BDEV(sb)) { | 2032 | if (SB_IS_BDEV(sb)) { |
2018 | struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); | 2033 | struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); |
2019 | if (!dc) | 2034 | if (!dc) |
@@ -2028,7 +2043,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, | |||
2028 | goto err_close; | 2043 | goto err_close; |
2029 | 2044 | ||
2030 | if (register_cache(sb, sb_page, bdev, ca) != 0) | 2045 | if (register_cache(sb, sb_page, bdev, ca) != 0) |
2031 | goto err_close; | 2046 | goto err; |
2032 | } | 2047 | } |
2033 | out: | 2048 | out: |
2034 | if (sb_page) | 2049 | if (sb_page) |
@@ -2041,7 +2056,7 @@ out: | |||
2041 | err_close: | 2056 | err_close: |
2042 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | 2057 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
2043 | err: | 2058 | err: |
2044 | pr_info("error opening %s: %s", path, err); | 2059 | pr_info("error %s: %s", path, err); |
2045 | ret = -EINVAL; | 2060 | ret = -EINVAL; |
2046 | goto out; | 2061 | goto out; |
2047 | } | 2062 | } |
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 414c9af54ded..aa2032fa80d4 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
@@ -386,9 +386,6 @@ static void __cache_size_refresh(void) | |||
386 | static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask, | 386 | static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask, |
387 | enum data_mode *data_mode) | 387 | enum data_mode *data_mode) |
388 | { | 388 | { |
389 | unsigned noio_flag; | ||
390 | void *ptr; | ||
391 | |||
392 | if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) { | 389 | if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) { |
393 | *data_mode = DATA_MODE_SLAB; | 390 | *data_mode = DATA_MODE_SLAB; |
394 | return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask); | 391 | return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask); |
@@ -412,16 +409,15 @@ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask, | |||
412 | * all allocations done by this process (including pagetables) are done | 409 | * all allocations done by this process (including pagetables) are done |
413 | * as if GFP_NOIO was specified. | 410 | * as if GFP_NOIO was specified. |
414 | */ | 411 | */ |
412 | if (gfp_mask & __GFP_NORETRY) { | ||
413 | unsigned noio_flag = memalloc_noio_save(); | ||
414 | void *ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL); | ||
415 | 415 | ||
416 | if (gfp_mask & __GFP_NORETRY) | ||
417 | noio_flag = memalloc_noio_save(); | ||
418 | |||
419 | ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL); | ||
420 | |||
421 | if (gfp_mask & __GFP_NORETRY) | ||
422 | memalloc_noio_restore(noio_flag); | 416 | memalloc_noio_restore(noio_flag); |
417 | return ptr; | ||
418 | } | ||
423 | 419 | ||
424 | return ptr; | 420 | return __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL); |
425 | } | 421 | } |
426 | 422 | ||
427 | /* | 423 | /* |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 7d3e572072f5..3fde9e9faddd 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <scsi/scsi_device.h> | ||
25 | #include <scsi/scsi_dh.h> | 26 | #include <scsi/scsi_dh.h> |
26 | #include <linux/atomic.h> | 27 | #include <linux/atomic.h> |
27 | #include <linux/blk-mq.h> | 28 | #include <linux/blk-mq.h> |
@@ -211,25 +212,13 @@ static int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m) | |||
211 | else | 212 | else |
212 | m->queue_mode = DM_TYPE_REQUEST_BASED; | 213 | m->queue_mode = DM_TYPE_REQUEST_BASED; |
213 | 214 | ||
214 | } else if (m->queue_mode == DM_TYPE_BIO_BASED || | 215 | } else if (m->queue_mode == DM_TYPE_BIO_BASED) { |
215 | m->queue_mode == DM_TYPE_NVME_BIO_BASED) { | ||
216 | INIT_WORK(&m->process_queued_bios, process_queued_bios); | 216 | INIT_WORK(&m->process_queued_bios, process_queued_bios); |
217 | 217 | /* | |
218 | if (m->queue_mode == DM_TYPE_BIO_BASED) { | 218 | * bio-based doesn't support any direct scsi_dh management; |
219 | /* | 219 | * it just discovers if a scsi_dh is attached. |
220 | * bio-based doesn't support any direct scsi_dh management; | 220 | */ |
221 | * it just discovers if a scsi_dh is attached. | 221 | set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags); |
222 | */ | ||
223 | set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | if (m->queue_mode != DM_TYPE_NVME_BIO_BASED) { | ||
228 | set_bit(MPATHF_QUEUE_IO, &m->flags); | ||
229 | atomic_set(&m->pg_init_in_progress, 0); | ||
230 | atomic_set(&m->pg_init_count, 0); | ||
231 | m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT; | ||
232 | init_waitqueue_head(&m->pg_init_wait); | ||
233 | } | 222 | } |
234 | 223 | ||
235 | dm_table_set_type(ti->table, m->queue_mode); | 224 | dm_table_set_type(ti->table, m->queue_mode); |
@@ -337,14 +326,12 @@ static void __switch_pg(struct multipath *m, struct priority_group *pg) | |||
337 | { | 326 | { |
338 | m->current_pg = pg; | 327 | m->current_pg = pg; |
339 | 328 | ||
340 | if (m->queue_mode == DM_TYPE_NVME_BIO_BASED) | ||
341 | return; | ||
342 | |||
343 | /* Must we initialise the PG first, and queue I/O till it's ready? */ | 329 | /* Must we initialise the PG first, and queue I/O till it's ready? */ |
344 | if (m->hw_handler_name) { | 330 | if (m->hw_handler_name) { |
345 | set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); | 331 | set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); |
346 | set_bit(MPATHF_QUEUE_IO, &m->flags); | 332 | set_bit(MPATHF_QUEUE_IO, &m->flags); |
347 | } else { | 333 | } else { |
334 | /* FIXME: not needed if no scsi_dh is attached */ | ||
348 | clear_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); | 335 | clear_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); |
349 | clear_bit(MPATHF_QUEUE_IO, &m->flags); | 336 | clear_bit(MPATHF_QUEUE_IO, &m->flags); |
350 | } | 337 | } |
@@ -385,8 +372,7 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes) | |||
385 | unsigned bypassed = 1; | 372 | unsigned bypassed = 1; |
386 | 373 | ||
387 | if (!atomic_read(&m->nr_valid_paths)) { | 374 | if (!atomic_read(&m->nr_valid_paths)) { |
388 | if (m->queue_mode != DM_TYPE_NVME_BIO_BASED) | 375 | clear_bit(MPATHF_QUEUE_IO, &m->flags); |
389 | clear_bit(MPATHF_QUEUE_IO, &m->flags); | ||
390 | goto failed; | 376 | goto failed; |
391 | } | 377 | } |
392 | 378 | ||
@@ -599,7 +585,7 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) | |||
599 | return pgpath; | 585 | return pgpath; |
600 | } | 586 | } |
601 | 587 | ||
602 | static struct pgpath *__map_bio_nvme(struct multipath *m, struct bio *bio) | 588 | static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio) |
603 | { | 589 | { |
604 | struct pgpath *pgpath; | 590 | struct pgpath *pgpath; |
605 | unsigned long flags; | 591 | unsigned long flags; |
@@ -634,8 +620,8 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, | |||
634 | { | 620 | { |
635 | struct pgpath *pgpath; | 621 | struct pgpath *pgpath; |
636 | 622 | ||
637 | if (m->queue_mode == DM_TYPE_NVME_BIO_BASED) | 623 | if (!m->hw_handler_name) |
638 | pgpath = __map_bio_nvme(m, bio); | 624 | pgpath = __map_bio_fast(m, bio); |
639 | else | 625 | else |
640 | pgpath = __map_bio(m, bio); | 626 | pgpath = __map_bio(m, bio); |
641 | 627 | ||
@@ -675,8 +661,7 @@ static void process_queued_io_list(struct multipath *m) | |||
675 | { | 661 | { |
676 | if (m->queue_mode == DM_TYPE_MQ_REQUEST_BASED) | 662 | if (m->queue_mode == DM_TYPE_MQ_REQUEST_BASED) |
677 | dm_mq_kick_requeue_list(dm_table_get_md(m->ti->table)); | 663 | dm_mq_kick_requeue_list(dm_table_get_md(m->ti->table)); |
678 | else if (m->queue_mode == DM_TYPE_BIO_BASED || | 664 | else if (m->queue_mode == DM_TYPE_BIO_BASED) |
679 | m->queue_mode == DM_TYPE_NVME_BIO_BASED) | ||
680 | queue_work(kmultipathd, &m->process_queued_bios); | 665 | queue_work(kmultipathd, &m->process_queued_bios); |
681 | } | 666 | } |
682 | 667 | ||
@@ -838,6 +823,16 @@ retain: | |||
838 | */ | 823 | */ |
839 | kfree(m->hw_handler_name); | 824 | kfree(m->hw_handler_name); |
840 | m->hw_handler_name = attached_handler_name; | 825 | m->hw_handler_name = attached_handler_name; |
826 | |||
827 | /* | ||
828 | * Init fields that are only used when a scsi_dh is attached | ||
829 | */ | ||
830 | if (!test_and_set_bit(MPATHF_QUEUE_IO, &m->flags)) { | ||
831 | atomic_set(&m->pg_init_in_progress, 0); | ||
832 | atomic_set(&m->pg_init_count, 0); | ||
833 | m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT; | ||
834 | init_waitqueue_head(&m->pg_init_wait); | ||
835 | } | ||
841 | } | 836 | } |
842 | } | 837 | } |
843 | 838 | ||
@@ -873,6 +868,7 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps | |||
873 | int r; | 868 | int r; |
874 | struct pgpath *p; | 869 | struct pgpath *p; |
875 | struct multipath *m = ti->private; | 870 | struct multipath *m = ti->private; |
871 | struct scsi_device *sdev; | ||
876 | 872 | ||
877 | /* we need at least a path arg */ | 873 | /* we need at least a path arg */ |
878 | if (as->argc < 1) { | 874 | if (as->argc < 1) { |
@@ -891,7 +887,9 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps | |||
891 | goto bad; | 887 | goto bad; |
892 | } | 888 | } |
893 | 889 | ||
894 | if (m->queue_mode != DM_TYPE_NVME_BIO_BASED) { | 890 | sdev = scsi_device_from_queue(bdev_get_queue(p->path.dev->bdev)); |
891 | if (sdev) { | ||
892 | put_device(&sdev->sdev_gendev); | ||
895 | INIT_DELAYED_WORK(&p->activate_path, activate_path_work); | 893 | INIT_DELAYED_WORK(&p->activate_path, activate_path_work); |
896 | r = setup_scsi_dh(p->path.dev->bdev, m, &ti->error); | 894 | r = setup_scsi_dh(p->path.dev->bdev, m, &ti->error); |
897 | if (r) { | 895 | if (r) { |
@@ -1001,8 +999,7 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) | |||
1001 | if (!hw_argc) | 999 | if (!hw_argc) |
1002 | return 0; | 1000 | return 0; |
1003 | 1001 | ||
1004 | if (m->queue_mode == DM_TYPE_BIO_BASED || | 1002 | if (m->queue_mode == DM_TYPE_BIO_BASED) { |
1005 | m->queue_mode == DM_TYPE_NVME_BIO_BASED) { | ||
1006 | dm_consume_args(as, hw_argc); | 1003 | dm_consume_args(as, hw_argc); |
1007 | DMERR("bio-based multipath doesn't allow hardware handler args"); | 1004 | DMERR("bio-based multipath doesn't allow hardware handler args"); |
1008 | return 0; | 1005 | return 0; |
@@ -1091,8 +1088,6 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m) | |||
1091 | 1088 | ||
1092 | if (!strcasecmp(queue_mode_name, "bio")) | 1089 | if (!strcasecmp(queue_mode_name, "bio")) |
1093 | m->queue_mode = DM_TYPE_BIO_BASED; | 1090 | m->queue_mode = DM_TYPE_BIO_BASED; |
1094 | else if (!strcasecmp(queue_mode_name, "nvme")) | ||
1095 | m->queue_mode = DM_TYPE_NVME_BIO_BASED; | ||
1096 | else if (!strcasecmp(queue_mode_name, "rq")) | 1091 | else if (!strcasecmp(queue_mode_name, "rq")) |
1097 | m->queue_mode = DM_TYPE_REQUEST_BASED; | 1092 | m->queue_mode = DM_TYPE_REQUEST_BASED; |
1098 | else if (!strcasecmp(queue_mode_name, "mq")) | 1093 | else if (!strcasecmp(queue_mode_name, "mq")) |
@@ -1193,7 +1188,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
1193 | ti->num_discard_bios = 1; | 1188 | ti->num_discard_bios = 1; |
1194 | ti->num_write_same_bios = 1; | 1189 | ti->num_write_same_bios = 1; |
1195 | ti->num_write_zeroes_bios = 1; | 1190 | ti->num_write_zeroes_bios = 1; |
1196 | if (m->queue_mode == DM_TYPE_BIO_BASED || m->queue_mode == DM_TYPE_NVME_BIO_BASED) | 1191 | if (m->queue_mode == DM_TYPE_BIO_BASED) |
1197 | ti->per_io_data_size = multipath_per_bio_data_size(); | 1192 | ti->per_io_data_size = multipath_per_bio_data_size(); |
1198 | else | 1193 | else |
1199 | ti->per_io_data_size = sizeof(struct dm_mpath_io); | 1194 | ti->per_io_data_size = sizeof(struct dm_mpath_io); |
@@ -1730,9 +1725,6 @@ static void multipath_status(struct dm_target *ti, status_type_t type, | |||
1730 | case DM_TYPE_BIO_BASED: | 1725 | case DM_TYPE_BIO_BASED: |
1731 | DMEMIT("queue_mode bio "); | 1726 | DMEMIT("queue_mode bio "); |
1732 | break; | 1727 | break; |
1733 | case DM_TYPE_NVME_BIO_BASED: | ||
1734 | DMEMIT("queue_mode nvme "); | ||
1735 | break; | ||
1736 | case DM_TYPE_MQ_REQUEST_BASED: | 1728 | case DM_TYPE_MQ_REQUEST_BASED: |
1737 | DMEMIT("queue_mode mq "); | 1729 | DMEMIT("queue_mode mq "); |
1738 | break; | 1730 | break; |
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 7ef469e902c6..c1d1034ff7b7 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -3408,9 +3408,10 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery, | |||
3408 | set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags); | 3408 | set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags); |
3409 | 3409 | ||
3410 | } else { | 3410 | } else { |
3411 | if (test_bit(MD_RECOVERY_NEEDED, &recovery) || | 3411 | if (!test_bit(MD_RECOVERY_INTR, &recovery) && |
3412 | test_bit(MD_RECOVERY_RESHAPE, &recovery) || | 3412 | (test_bit(MD_RECOVERY_NEEDED, &recovery) || |
3413 | test_bit(MD_RECOVERY_RUNNING, &recovery)) | 3413 | test_bit(MD_RECOVERY_RESHAPE, &recovery) || |
3414 | test_bit(MD_RECOVERY_RUNNING, &recovery))) | ||
3414 | r = mddev->curr_resync_completed; | 3415 | r = mddev->curr_resync_completed; |
3415 | else | 3416 | else |
3416 | r = mddev->recovery_cp; | 3417 | r = mddev->recovery_cp; |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 5fe7ec356c33..7eb3e2a3c07d 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -942,17 +942,12 @@ static int dm_table_determine_type(struct dm_table *t) | |||
942 | 942 | ||
943 | if (t->type != DM_TYPE_NONE) { | 943 | if (t->type != DM_TYPE_NONE) { |
944 | /* target already set the table's type */ | 944 | /* target already set the table's type */ |
945 | if (t->type == DM_TYPE_BIO_BASED) | 945 | if (t->type == DM_TYPE_BIO_BASED) { |
946 | return 0; | 946 | /* possibly upgrade to a variant of bio-based */ |
947 | else if (t->type == DM_TYPE_NVME_BIO_BASED) { | 947 | goto verify_bio_based; |
948 | if (!dm_table_does_not_support_partial_completion(t)) { | ||
949 | DMERR("nvme bio-based is only possible with devices" | ||
950 | " that don't support partial completion"); | ||
951 | return -EINVAL; | ||
952 | } | ||
953 | /* Fallthru, also verify all devices are blk-mq */ | ||
954 | } | 948 | } |
955 | BUG_ON(t->type == DM_TYPE_DAX_BIO_BASED); | 949 | BUG_ON(t->type == DM_TYPE_DAX_BIO_BASED); |
950 | BUG_ON(t->type == DM_TYPE_NVME_BIO_BASED); | ||
956 | goto verify_rq_based; | 951 | goto verify_rq_based; |
957 | } | 952 | } |
958 | 953 | ||
@@ -985,6 +980,7 @@ static int dm_table_determine_type(struct dm_table *t) | |||
985 | } | 980 | } |
986 | 981 | ||
987 | if (bio_based) { | 982 | if (bio_based) { |
983 | verify_bio_based: | ||
988 | /* We must use this table as bio-based */ | 984 | /* We must use this table as bio-based */ |
989 | t->type = DM_TYPE_BIO_BASED; | 985 | t->type = DM_TYPE_BIO_BASED; |
990 | if (dm_table_supports_dax(t) || | 986 | if (dm_table_supports_dax(t) || |
@@ -1755,7 +1751,7 @@ static int device_no_partial_completion(struct dm_target *ti, struct dm_dev *dev | |||
1755 | char b[BDEVNAME_SIZE]; | 1751 | char b[BDEVNAME_SIZE]; |
1756 | 1752 | ||
1757 | /* For now, NVMe devices are the only devices of this class */ | 1753 | /* For now, NVMe devices are the only devices of this class */ |
1758 | return (strncmp(bdevname(dev->bdev, b), "nvme", 3) == 0); | 1754 | return (strncmp(bdevname(dev->bdev, b), "nvme", 4) == 0); |
1759 | } | 1755 | } |
1760 | 1756 | ||
1761 | static bool dm_table_does_not_support_partial_completion(struct dm_table *t) | 1757 | static bool dm_table_does_not_support_partial_completion(struct dm_table *t) |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 68136806d365..45328d8b2859 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -458,9 +458,11 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
458 | return dm_get_geometry(md, geo); | 458 | return dm_get_geometry(md, geo); |
459 | } | 459 | } |
460 | 460 | ||
461 | static int dm_grab_bdev_for_ioctl(struct mapped_device *md, | 461 | static char *_dm_claim_ptr = "I belong to device-mapper"; |
462 | struct block_device **bdev, | 462 | |
463 | fmode_t *mode) | 463 | static int dm_get_bdev_for_ioctl(struct mapped_device *md, |
464 | struct block_device **bdev, | ||
465 | fmode_t *mode) | ||
464 | { | 466 | { |
465 | struct dm_target *tgt; | 467 | struct dm_target *tgt; |
466 | struct dm_table *map; | 468 | struct dm_table *map; |
@@ -490,6 +492,10 @@ retry: | |||
490 | goto out; | 492 | goto out; |
491 | 493 | ||
492 | bdgrab(*bdev); | 494 | bdgrab(*bdev); |
495 | r = blkdev_get(*bdev, *mode, _dm_claim_ptr); | ||
496 | if (r < 0) | ||
497 | goto out; | ||
498 | |||
493 | dm_put_live_table(md, srcu_idx); | 499 | dm_put_live_table(md, srcu_idx); |
494 | return r; | 500 | return r; |
495 | 501 | ||
@@ -508,7 +514,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
508 | struct mapped_device *md = bdev->bd_disk->private_data; | 514 | struct mapped_device *md = bdev->bd_disk->private_data; |
509 | int r; | 515 | int r; |
510 | 516 | ||
511 | r = dm_grab_bdev_for_ioctl(md, &bdev, &mode); | 517 | r = dm_get_bdev_for_ioctl(md, &bdev, &mode); |
512 | if (r < 0) | 518 | if (r < 0) |
513 | return r; | 519 | return r; |
514 | 520 | ||
@@ -528,7 +534,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
528 | 534 | ||
529 | r = __blkdev_driver_ioctl(bdev, mode, cmd, arg); | 535 | r = __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
530 | out: | 536 | out: |
531 | bdput(bdev); | 537 | blkdev_put(bdev, mode); |
532 | return r; | 538 | return r; |
533 | } | 539 | } |
534 | 540 | ||
@@ -708,14 +714,13 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU) | |||
708 | static int open_table_device(struct table_device *td, dev_t dev, | 714 | static int open_table_device(struct table_device *td, dev_t dev, |
709 | struct mapped_device *md) | 715 | struct mapped_device *md) |
710 | { | 716 | { |
711 | static char *_claim_ptr = "I belong to device-mapper"; | ||
712 | struct block_device *bdev; | 717 | struct block_device *bdev; |
713 | 718 | ||
714 | int r; | 719 | int r; |
715 | 720 | ||
716 | BUG_ON(td->dm_dev.bdev); | 721 | BUG_ON(td->dm_dev.bdev); |
717 | 722 | ||
718 | bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _claim_ptr); | 723 | bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _dm_claim_ptr); |
719 | if (IS_ERR(bdev)) | 724 | if (IS_ERR(bdev)) |
720 | return PTR_ERR(bdev); | 725 | return PTR_ERR(bdev); |
721 | 726 | ||
@@ -3011,7 +3016,7 @@ static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type, | |||
3011 | fmode_t mode; | 3016 | fmode_t mode; |
3012 | int r; | 3017 | int r; |
3013 | 3018 | ||
3014 | r = dm_grab_bdev_for_ioctl(md, &bdev, &mode); | 3019 | r = dm_get_bdev_for_ioctl(md, &bdev, &mode); |
3015 | if (r < 0) | 3020 | if (r < 0) |
3016 | return r; | 3021 | return r; |
3017 | 3022 | ||
@@ -3021,7 +3026,7 @@ static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type, | |||
3021 | else | 3026 | else |
3022 | r = -EOPNOTSUPP; | 3027 | r = -EOPNOTSUPP; |
3023 | 3028 | ||
3024 | bdput(bdev); | 3029 | blkdev_put(bdev, mode); |
3025 | return r; | 3030 | return r; |
3026 | } | 3031 | } |
3027 | 3032 | ||
@@ -3032,7 +3037,7 @@ static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type) | |||
3032 | fmode_t mode; | 3037 | fmode_t mode; |
3033 | int r; | 3038 | int r; |
3034 | 3039 | ||
3035 | r = dm_grab_bdev_for_ioctl(md, &bdev, &mode); | 3040 | r = dm_get_bdev_for_ioctl(md, &bdev, &mode); |
3036 | if (r < 0) | 3041 | if (r < 0) |
3037 | return r; | 3042 | return r; |
3038 | 3043 | ||
@@ -3042,7 +3047,7 @@ static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type) | |||
3042 | else | 3047 | else |
3043 | r = -EOPNOTSUPP; | 3048 | r = -EOPNOTSUPP; |
3044 | 3049 | ||
3045 | bdput(bdev); | 3050 | blkdev_put(bdev, mode); |
3046 | return r; | 3051 | return r; |
3047 | } | 3052 | } |
3048 | 3053 | ||
@@ -3054,7 +3059,7 @@ static int dm_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key, | |||
3054 | fmode_t mode; | 3059 | fmode_t mode; |
3055 | int r; | 3060 | int r; |
3056 | 3061 | ||
3057 | r = dm_grab_bdev_for_ioctl(md, &bdev, &mode); | 3062 | r = dm_get_bdev_for_ioctl(md, &bdev, &mode); |
3058 | if (r < 0) | 3063 | if (r < 0) |
3059 | return r; | 3064 | return r; |
3060 | 3065 | ||
@@ -3064,7 +3069,7 @@ static int dm_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key, | |||
3064 | else | 3069 | else |
3065 | r = -EOPNOTSUPP; | 3070 | r = -EOPNOTSUPP; |
3066 | 3071 | ||
3067 | bdput(bdev); | 3072 | blkdev_put(bdev, mode); |
3068 | return r; | 3073 | return r; |
3069 | } | 3074 | } |
3070 | 3075 | ||
@@ -3075,7 +3080,7 @@ static int dm_pr_clear(struct block_device *bdev, u64 key) | |||
3075 | fmode_t mode; | 3080 | fmode_t mode; |
3076 | int r; | 3081 | int r; |
3077 | 3082 | ||
3078 | r = dm_grab_bdev_for_ioctl(md, &bdev, &mode); | 3083 | r = dm_get_bdev_for_ioctl(md, &bdev, &mode); |
3079 | if (r < 0) | 3084 | if (r < 0) |
3080 | return r; | 3085 | return r; |
3081 | 3086 | ||
@@ -3085,7 +3090,7 @@ static int dm_pr_clear(struct block_device *bdev, u64 key) | |||
3085 | else | 3090 | else |
3086 | r = -EOPNOTSUPP; | 3091 | r = -EOPNOTSUPP; |
3087 | 3092 | ||
3088 | bdput(bdev); | 3093 | blkdev_put(bdev, mode); |
3089 | return r; | 3094 | return r; |
3090 | } | 3095 | } |
3091 | 3096 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index 21d29f7936f6..d39b0b7011b2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c | |||
@@ -124,7 +124,7 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force) | |||
124 | trigger_cmd_completions(dev); | 124 | trigger_cmd_completions(dev); |
125 | } | 125 | } |
126 | 126 | ||
127 | mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 0); | 127 | mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 1); |
128 | mlx5_core_err(dev, "end\n"); | 128 | mlx5_core_err(dev, "end\n"); |
129 | 129 | ||
130 | unlock: | 130 | unlock: |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 817e5e2766da..7aeca5db7916 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
@@ -3033,7 +3033,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | |||
3033 | ns->disk->disk_name); | 3033 | ns->disk->disk_name); |
3034 | 3034 | ||
3035 | nvme_mpath_add_disk(ns->head); | 3035 | nvme_mpath_add_disk(ns->head); |
3036 | nvme_mpath_add_disk_links(ns); | ||
3037 | return; | 3036 | return; |
3038 | out_unlink_ns: | 3037 | out_unlink_ns: |
3039 | mutex_lock(&ctrl->subsys->lock); | 3038 | mutex_lock(&ctrl->subsys->lock); |
@@ -3053,7 +3052,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) | |||
3053 | return; | 3052 | return; |
3054 | 3053 | ||
3055 | if (ns->disk && ns->disk->flags & GENHD_FL_UP) { | 3054 | if (ns->disk && ns->disk->flags & GENHD_FL_UP) { |
3056 | nvme_mpath_remove_disk_links(ns); | ||
3057 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, | 3055 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, |
3058 | &nvme_ns_id_attr_group); | 3056 | &nvme_ns_id_attr_group); |
3059 | if (ns->ndev) | 3057 | if (ns->ndev) |
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index a1c58e35075e..8f0f34d06d46 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c | |||
@@ -650,6 +650,11 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
650 | ret = -EINVAL; | 650 | ret = -EINVAL; |
651 | goto out; | 651 | goto out; |
652 | } | 652 | } |
653 | if (opts->discovery_nqn) { | ||
654 | pr_debug("Ignoring nr_io_queues value for discovery controller\n"); | ||
655 | break; | ||
656 | } | ||
657 | |||
653 | opts->nr_io_queues = min_t(unsigned int, | 658 | opts->nr_io_queues = min_t(unsigned int, |
654 | num_online_cpus(), token); | 659 | num_online_cpus(), token); |
655 | break; | 660 | break; |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 7f51f8414b97..1dc1387b7134 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
@@ -1206,7 +1206,7 @@ nvme_fc_connect_admin_queue(struct nvme_fc_ctrl *ctrl, | |||
1206 | sizeof(struct fcnvme_lsdesc_cr_assoc_cmd)); | 1206 | sizeof(struct fcnvme_lsdesc_cr_assoc_cmd)); |
1207 | 1207 | ||
1208 | assoc_rqst->assoc_cmd.ersp_ratio = cpu_to_be16(ersp_ratio); | 1208 | assoc_rqst->assoc_cmd.ersp_ratio = cpu_to_be16(ersp_ratio); |
1209 | assoc_rqst->assoc_cmd.sqsize = cpu_to_be16(qsize); | 1209 | assoc_rqst->assoc_cmd.sqsize = cpu_to_be16(qsize - 1); |
1210 | /* Linux supports only Dynamic controllers */ | 1210 | /* Linux supports only Dynamic controllers */ |
1211 | assoc_rqst->assoc_cmd.cntlid = cpu_to_be16(0xffff); | 1211 | assoc_rqst->assoc_cmd.cntlid = cpu_to_be16(0xffff); |
1212 | uuid_copy(&assoc_rqst->assoc_cmd.hostid, &ctrl->ctrl.opts->host->id); | 1212 | uuid_copy(&assoc_rqst->assoc_cmd.hostid, &ctrl->ctrl.opts->host->id); |
@@ -1321,7 +1321,7 @@ nvme_fc_connect_queue(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, | |||
1321 | sizeof(struct fcnvme_lsdesc_cr_conn_cmd)); | 1321 | sizeof(struct fcnvme_lsdesc_cr_conn_cmd)); |
1322 | conn_rqst->connect_cmd.ersp_ratio = cpu_to_be16(ersp_ratio); | 1322 | conn_rqst->connect_cmd.ersp_ratio = cpu_to_be16(ersp_ratio); |
1323 | conn_rqst->connect_cmd.qid = cpu_to_be16(queue->qnum); | 1323 | conn_rqst->connect_cmd.qid = cpu_to_be16(queue->qnum); |
1324 | conn_rqst->connect_cmd.sqsize = cpu_to_be16(qsize); | 1324 | conn_rqst->connect_cmd.sqsize = cpu_to_be16(qsize - 1); |
1325 | 1325 | ||
1326 | lsop->queue = queue; | 1326 | lsop->queue = queue; |
1327 | lsreq->rqstaddr = conn_rqst; | 1327 | lsreq->rqstaddr = conn_rqst; |
@@ -2481,11 +2481,11 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl) | |||
2481 | goto out_free_tag_set; | 2481 | goto out_free_tag_set; |
2482 | } | 2482 | } |
2483 | 2483 | ||
2484 | ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.opts->queue_size); | 2484 | ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.sqsize + 1); |
2485 | if (ret) | 2485 | if (ret) |
2486 | goto out_cleanup_blk_queue; | 2486 | goto out_cleanup_blk_queue; |
2487 | 2487 | ||
2488 | ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.opts->queue_size); | 2488 | ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.sqsize + 1); |
2489 | if (ret) | 2489 | if (ret) |
2490 | goto out_delete_hw_queues; | 2490 | goto out_delete_hw_queues; |
2491 | 2491 | ||
@@ -2532,11 +2532,11 @@ nvme_fc_reinit_io_queues(struct nvme_fc_ctrl *ctrl) | |||
2532 | if (ret) | 2532 | if (ret) |
2533 | goto out_free_io_queues; | 2533 | goto out_free_io_queues; |
2534 | 2534 | ||
2535 | ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.opts->queue_size); | 2535 | ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.sqsize + 1); |
2536 | if (ret) | 2536 | if (ret) |
2537 | goto out_free_io_queues; | 2537 | goto out_free_io_queues; |
2538 | 2538 | ||
2539 | ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.opts->queue_size); | 2539 | ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.sqsize + 1); |
2540 | if (ret) | 2540 | if (ret) |
2541 | goto out_delete_hw_queues; | 2541 | goto out_delete_hw_queues; |
2542 | 2542 | ||
@@ -2632,13 +2632,12 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) | |||
2632 | nvme_fc_init_queue(ctrl, 0); | 2632 | nvme_fc_init_queue(ctrl, 0); |
2633 | 2633 | ||
2634 | ret = __nvme_fc_create_hw_queue(ctrl, &ctrl->queues[0], 0, | 2634 | ret = __nvme_fc_create_hw_queue(ctrl, &ctrl->queues[0], 0, |
2635 | NVME_AQ_BLK_MQ_DEPTH); | 2635 | NVME_AQ_DEPTH); |
2636 | if (ret) | 2636 | if (ret) |
2637 | goto out_free_queue; | 2637 | goto out_free_queue; |
2638 | 2638 | ||
2639 | ret = nvme_fc_connect_admin_queue(ctrl, &ctrl->queues[0], | 2639 | ret = nvme_fc_connect_admin_queue(ctrl, &ctrl->queues[0], |
2640 | NVME_AQ_BLK_MQ_DEPTH, | 2640 | NVME_AQ_DEPTH, (NVME_AQ_DEPTH / 4)); |
2641 | (NVME_AQ_BLK_MQ_DEPTH / 4)); | ||
2642 | if (ret) | 2641 | if (ret) |
2643 | goto out_delete_hw_queue; | 2642 | goto out_delete_hw_queue; |
2644 | 2643 | ||
@@ -2666,7 +2665,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) | |||
2666 | } | 2665 | } |
2667 | 2666 | ||
2668 | ctrl->ctrl.sqsize = | 2667 | ctrl->ctrl.sqsize = |
2669 | min_t(int, NVME_CAP_MQES(ctrl->ctrl.cap) + 1, ctrl->ctrl.sqsize); | 2668 | min_t(int, NVME_CAP_MQES(ctrl->ctrl.cap), ctrl->ctrl.sqsize); |
2670 | 2669 | ||
2671 | ret = nvme_enable_ctrl(&ctrl->ctrl, ctrl->ctrl.cap); | 2670 | ret = nvme_enable_ctrl(&ctrl->ctrl, ctrl->ctrl.cap); |
2672 | if (ret) | 2671 | if (ret) |
@@ -2699,6 +2698,14 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) | |||
2699 | opts->queue_size = ctrl->ctrl.maxcmd; | 2698 | opts->queue_size = ctrl->ctrl.maxcmd; |
2700 | } | 2699 | } |
2701 | 2700 | ||
2701 | if (opts->queue_size > ctrl->ctrl.sqsize + 1) { | ||
2702 | /* warn if sqsize is lower than queue_size */ | ||
2703 | dev_warn(ctrl->ctrl.device, | ||
2704 | "queue_size %zu > ctrl sqsize %u, clamping down\n", | ||
2705 | opts->queue_size, ctrl->ctrl.sqsize + 1); | ||
2706 | opts->queue_size = ctrl->ctrl.sqsize + 1; | ||
2707 | } | ||
2708 | |||
2702 | ret = nvme_fc_init_aen_ops(ctrl); | 2709 | ret = nvme_fc_init_aen_ops(ctrl); |
2703 | if (ret) | 2710 | if (ret) |
2704 | goto out_term_aen_ops; | 2711 | goto out_term_aen_ops; |
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index b7e5c6db4d92..060f69e03427 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c | |||
@@ -210,25 +210,6 @@ void nvme_mpath_add_disk(struct nvme_ns_head *head) | |||
210 | mutex_unlock(&head->subsys->lock); | 210 | mutex_unlock(&head->subsys->lock); |
211 | } | 211 | } |
212 | 212 | ||
213 | void nvme_mpath_add_disk_links(struct nvme_ns *ns) | ||
214 | { | ||
215 | struct kobject *slave_disk_kobj, *holder_disk_kobj; | ||
216 | |||
217 | if (!ns->head->disk) | ||
218 | return; | ||
219 | |||
220 | slave_disk_kobj = &disk_to_dev(ns->disk)->kobj; | ||
221 | if (sysfs_create_link(ns->head->disk->slave_dir, slave_disk_kobj, | ||
222 | kobject_name(slave_disk_kobj))) | ||
223 | return; | ||
224 | |||
225 | holder_disk_kobj = &disk_to_dev(ns->head->disk)->kobj; | ||
226 | if (sysfs_create_link(ns->disk->part0.holder_dir, holder_disk_kobj, | ||
227 | kobject_name(holder_disk_kobj))) | ||
228 | sysfs_remove_link(ns->head->disk->slave_dir, | ||
229 | kobject_name(slave_disk_kobj)); | ||
230 | } | ||
231 | |||
232 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) | 213 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) |
233 | { | 214 | { |
234 | if (!head->disk) | 215 | if (!head->disk) |
@@ -243,14 +224,3 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) | |||
243 | blk_cleanup_queue(head->disk->queue); | 224 | blk_cleanup_queue(head->disk->queue); |
244 | put_disk(head->disk); | 225 | put_disk(head->disk); |
245 | } | 226 | } |
246 | |||
247 | void nvme_mpath_remove_disk_links(struct nvme_ns *ns) | ||
248 | { | ||
249 | if (!ns->head->disk) | ||
250 | return; | ||
251 | |||
252 | sysfs_remove_link(ns->disk->part0.holder_dir, | ||
253 | kobject_name(&disk_to_dev(ns->head->disk)->kobj)); | ||
254 | sysfs_remove_link(ns->head->disk->slave_dir, | ||
255 | kobject_name(&disk_to_dev(ns->disk)->kobj)); | ||
256 | } | ||
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 0521e4707d1c..d733b14ede9d 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
@@ -410,9 +410,7 @@ bool nvme_req_needs_failover(struct request *req, blk_status_t error); | |||
410 | void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); | 410 | void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); |
411 | int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); | 411 | int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); |
412 | void nvme_mpath_add_disk(struct nvme_ns_head *head); | 412 | void nvme_mpath_add_disk(struct nvme_ns_head *head); |
413 | void nvme_mpath_add_disk_links(struct nvme_ns *ns); | ||
414 | void nvme_mpath_remove_disk(struct nvme_ns_head *head); | 413 | void nvme_mpath_remove_disk(struct nvme_ns_head *head); |
415 | void nvme_mpath_remove_disk_links(struct nvme_ns *ns); | ||
416 | 414 | ||
417 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | 415 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) |
418 | { | 416 | { |
@@ -454,12 +452,6 @@ static inline void nvme_mpath_add_disk(struct nvme_ns_head *head) | |||
454 | static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head) | 452 | static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head) |
455 | { | 453 | { |
456 | } | 454 | } |
457 | static inline void nvme_mpath_add_disk_links(struct nvme_ns *ns) | ||
458 | { | ||
459 | } | ||
460 | static inline void nvme_mpath_remove_disk_links(struct nvme_ns *ns) | ||
461 | { | ||
462 | } | ||
463 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | 455 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) |
464 | { | 456 | { |
465 | } | 457 | } |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 5933a5c732e8..b6f43b738f03 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1153,12 +1153,6 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) | |||
1153 | if (!(csts & NVME_CSTS_CFS) && !nssro) | 1153 | if (!(csts & NVME_CSTS_CFS) && !nssro) |
1154 | return false; | 1154 | return false; |
1155 | 1155 | ||
1156 | /* If PCI error recovery process is happening, we cannot reset or | ||
1157 | * the recovery mechanism will surely fail. | ||
1158 | */ | ||
1159 | if (pci_channel_offline(to_pci_dev(dev->dev))) | ||
1160 | return false; | ||
1161 | |||
1162 | return true; | 1156 | return true; |
1163 | } | 1157 | } |
1164 | 1158 | ||
@@ -1189,6 +1183,13 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
1189 | struct nvme_command cmd; | 1183 | struct nvme_command cmd; |
1190 | u32 csts = readl(dev->bar + NVME_REG_CSTS); | 1184 | u32 csts = readl(dev->bar + NVME_REG_CSTS); |
1191 | 1185 | ||
1186 | /* If PCI error recovery process is happening, we cannot reset or | ||
1187 | * the recovery mechanism will surely fail. | ||
1188 | */ | ||
1189 | mb(); | ||
1190 | if (pci_channel_offline(to_pci_dev(dev->dev))) | ||
1191 | return BLK_EH_RESET_TIMER; | ||
1192 | |||
1192 | /* | 1193 | /* |
1193 | * Reset immediately if the controller is failed | 1194 | * Reset immediately if the controller is failed |
1194 | */ | 1195 | */ |
@@ -1913,7 +1914,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1913 | int result, nr_io_queues; | 1914 | int result, nr_io_queues; |
1914 | unsigned long size; | 1915 | unsigned long size; |
1915 | 1916 | ||
1916 | nr_io_queues = num_present_cpus(); | 1917 | nr_io_queues = num_possible_cpus(); |
1917 | result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); | 1918 | result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); |
1918 | if (result < 0) | 1919 | if (result < 0) |
1919 | return result; | 1920 | return result; |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 9a8f96465cdc..d10ffe51da24 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -105,31 +105,44 @@ config ASUS_LAPTOP | |||
105 | 105 | ||
106 | If you have an ACPI-compatible ASUS laptop, say Y or M here. | 106 | If you have an ACPI-compatible ASUS laptop, say Y or M here. |
107 | 107 | ||
108 | # | ||
109 | # If the DELL_SMBIOS_SMM feature is enabled, the DELL_SMBIOS driver | ||
110 | # becomes dependent on the DCDBAS driver. The "depends" line prevents a | ||
111 | # configuration where DELL_SMBIOS=y while DCDBAS=m. | ||
112 | # | ||
108 | config DELL_SMBIOS | 113 | config DELL_SMBIOS |
109 | tristate | 114 | tristate "Dell SMBIOS driver" |
115 | depends on DCDBAS || DCDBAS=n | ||
116 | ---help--- | ||
117 | This provides support for the Dell SMBIOS calling interface. | ||
118 | If you have a Dell computer you should enable this option. | ||
119 | |||
120 | Be sure to select at least one backend for it to work properly. | ||
110 | 121 | ||
111 | config DELL_SMBIOS_WMI | 122 | config DELL_SMBIOS_WMI |
112 | tristate "Dell SMBIOS calling interface (WMI implementation)" | 123 | bool "Dell SMBIOS driver WMI backend" |
124 | default y | ||
113 | depends on ACPI_WMI | 125 | depends on ACPI_WMI |
114 | select DELL_WMI_DESCRIPTOR | 126 | select DELL_WMI_DESCRIPTOR |
115 | select DELL_SMBIOS | 127 | depends on DELL_SMBIOS |
116 | ---help--- | 128 | ---help--- |
117 | This provides an implementation for the Dell SMBIOS calling interface | 129 | This provides an implementation for the Dell SMBIOS calling interface |
118 | communicated over ACPI-WMI. | 130 | communicated over ACPI-WMI. |
119 | 131 | ||
120 | If you have a Dell computer from >2007 you should say Y or M here. | 132 | If you have a Dell computer from >2007 you should say Y here. |
121 | If you aren't sure and this module doesn't work for your computer | 133 | If you aren't sure and this module doesn't work for your computer |
122 | it just won't load. | 134 | it just won't load. |
123 | 135 | ||
124 | config DELL_SMBIOS_SMM | 136 | config DELL_SMBIOS_SMM |
125 | tristate "Dell SMBIOS calling interface (SMM implementation)" | 137 | bool "Dell SMBIOS driver SMM backend" |
138 | default y | ||
126 | depends on DCDBAS | 139 | depends on DCDBAS |
127 | select DELL_SMBIOS | 140 | depends on DELL_SMBIOS |
128 | ---help--- | 141 | ---help--- |
129 | This provides an implementation for the Dell SMBIOS calling interface | 142 | This provides an implementation for the Dell SMBIOS calling interface |
130 | communicated over SMI/SMM. | 143 | communicated over SMI/SMM. |
131 | 144 | ||
132 | If you have a Dell computer from <=2017 you should say Y or M here. | 145 | If you have a Dell computer from <=2017 you should say Y here. |
133 | If you aren't sure and this module doesn't work for your computer | 146 | If you aren't sure and this module doesn't work for your computer |
134 | it just won't load. | 147 | it just won't load. |
135 | 148 | ||
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index c388608ad2a3..2ba6cb795338 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -13,8 +13,9 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o | |||
13 | obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o | 13 | obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o |
14 | obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o | 14 | obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o |
15 | obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o | 15 | obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o |
16 | obj-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o | 16 | dell-smbios-objs := dell-smbios-base.o |
17 | obj-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o | 17 | dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o |
18 | dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o | ||
18 | obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o | 19 | obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o |
19 | obj-$(CONFIG_DELL_WMI) += dell-wmi.o | 20 | obj-$(CONFIG_DELL_WMI) += dell-wmi.o |
20 | obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o | 21 | obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o |
diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios-base.c index 8541cde4cb7d..5bcf8a18f785 100644 --- a/drivers/platform/x86/dell-smbios.c +++ b/drivers/platform/x86/dell-smbios-base.c | |||
@@ -36,7 +36,7 @@ static DEFINE_MUTEX(smbios_mutex); | |||
36 | struct smbios_device { | 36 | struct smbios_device { |
37 | struct list_head list; | 37 | struct list_head list; |
38 | struct device *device; | 38 | struct device *device; |
39 | int (*call_fn)(struct calling_interface_buffer *); | 39 | int (*call_fn)(struct calling_interface_buffer *arg); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct smbios_call { | 42 | struct smbios_call { |
@@ -352,8 +352,10 @@ static void __init parse_da_table(const struct dmi_header *dm) | |||
352 | struct calling_interface_structure *table = | 352 | struct calling_interface_structure *table = |
353 | container_of(dm, struct calling_interface_structure, header); | 353 | container_of(dm, struct calling_interface_structure, header); |
354 | 354 | ||
355 | /* 4 bytes of table header, plus 7 bytes of Dell header, plus at least | 355 | /* |
356 | 6 bytes of entry */ | 356 | * 4 bytes of table header, plus 7 bytes of Dell header |
357 | * plus at least 6 bytes of entry | ||
358 | */ | ||
357 | 359 | ||
358 | if (dm->length < 17) | 360 | if (dm->length < 17) |
359 | return; | 361 | return; |
@@ -554,7 +556,7 @@ static void free_group(struct platform_device *pdev) | |||
554 | static int __init dell_smbios_init(void) | 556 | static int __init dell_smbios_init(void) |
555 | { | 557 | { |
556 | const struct dmi_device *valid; | 558 | const struct dmi_device *valid; |
557 | int ret; | 559 | int ret, wmi, smm; |
558 | 560 | ||
559 | valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL); | 561 | valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL); |
560 | if (!valid) { | 562 | if (!valid) { |
@@ -589,8 +591,24 @@ static int __init dell_smbios_init(void) | |||
589 | if (ret) | 591 | if (ret) |
590 | goto fail_create_group; | 592 | goto fail_create_group; |
591 | 593 | ||
594 | /* register backends */ | ||
595 | wmi = init_dell_smbios_wmi(); | ||
596 | if (wmi) | ||
597 | pr_debug("Failed to initialize WMI backend: %d\n", wmi); | ||
598 | smm = init_dell_smbios_smm(); | ||
599 | if (smm) | ||
600 | pr_debug("Failed to initialize SMM backend: %d\n", smm); | ||
601 | if (wmi && smm) { | ||
602 | pr_err("No SMBIOS backends available (wmi: %d, smm: %d)\n", | ||
603 | wmi, smm); | ||
604 | goto fail_sysfs; | ||
605 | } | ||
606 | |||
592 | return 0; | 607 | return 0; |
593 | 608 | ||
609 | fail_sysfs: | ||
610 | free_group(platform_device); | ||
611 | |||
594 | fail_create_group: | 612 | fail_create_group: |
595 | platform_device_del(platform_device); | 613 | platform_device_del(platform_device); |
596 | 614 | ||
@@ -607,6 +625,8 @@ fail_platform_driver: | |||
607 | 625 | ||
608 | static void __exit dell_smbios_exit(void) | 626 | static void __exit dell_smbios_exit(void) |
609 | { | 627 | { |
628 | exit_dell_smbios_wmi(); | ||
629 | exit_dell_smbios_smm(); | ||
610 | mutex_lock(&smbios_mutex); | 630 | mutex_lock(&smbios_mutex); |
611 | if (platform_device) { | 631 | if (platform_device) { |
612 | free_group(platform_device); | 632 | free_group(platform_device); |
@@ -623,5 +643,6 @@ module_exit(dell_smbios_exit); | |||
623 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | 643 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); |
624 | MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); | 644 | MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); |
625 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); | 645 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); |
646 | MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>"); | ||
626 | MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS"); | 647 | MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS"); |
627 | MODULE_LICENSE("GPL"); | 648 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/platform/x86/dell-smbios-smm.c b/drivers/platform/x86/dell-smbios-smm.c index 89f65c4651a0..e9e9da556318 100644 --- a/drivers/platform/x86/dell-smbios-smm.c +++ b/drivers/platform/x86/dell-smbios-smm.c | |||
@@ -58,7 +58,7 @@ static const struct dmi_system_id dell_device_table[] __initconst = { | |||
58 | }; | 58 | }; |
59 | MODULE_DEVICE_TABLE(dmi, dell_device_table); | 59 | MODULE_DEVICE_TABLE(dmi, dell_device_table); |
60 | 60 | ||
61 | static void __init parse_da_table(const struct dmi_header *dm) | 61 | static void parse_da_table(const struct dmi_header *dm) |
62 | { | 62 | { |
63 | struct calling_interface_structure *table = | 63 | struct calling_interface_structure *table = |
64 | container_of(dm, struct calling_interface_structure, header); | 64 | container_of(dm, struct calling_interface_structure, header); |
@@ -73,7 +73,7 @@ static void __init parse_da_table(const struct dmi_header *dm) | |||
73 | da_command_code = table->cmdIOCode; | 73 | da_command_code = table->cmdIOCode; |
74 | } | 74 | } |
75 | 75 | ||
76 | static void __init find_cmd_address(const struct dmi_header *dm, void *dummy) | 76 | static void find_cmd_address(const struct dmi_header *dm, void *dummy) |
77 | { | 77 | { |
78 | switch (dm->type) { | 78 | switch (dm->type) { |
79 | case 0xda: /* Calling interface */ | 79 | case 0xda: /* Calling interface */ |
@@ -128,7 +128,7 @@ static bool test_wsmt_enabled(void) | |||
128 | return false; | 128 | return false; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int __init dell_smbios_smm_init(void) | 131 | int init_dell_smbios_smm(void) |
132 | { | 132 | { |
133 | int ret; | 133 | int ret; |
134 | /* | 134 | /* |
@@ -176,7 +176,7 @@ fail_platform_device_alloc: | |||
176 | return ret; | 176 | return ret; |
177 | } | 177 | } |
178 | 178 | ||
179 | static void __exit dell_smbios_smm_exit(void) | 179 | void exit_dell_smbios_smm(void) |
180 | { | 180 | { |
181 | if (platform_device) { | 181 | if (platform_device) { |
182 | dell_smbios_unregister_device(&platform_device->dev); | 182 | dell_smbios_unregister_device(&platform_device->dev); |
@@ -184,13 +184,3 @@ static void __exit dell_smbios_smm_exit(void) | |||
184 | free_page((unsigned long)buffer); | 184 | free_page((unsigned long)buffer); |
185 | } | 185 | } |
186 | } | 186 | } |
187 | |||
188 | subsys_initcall(dell_smbios_smm_init); | ||
189 | module_exit(dell_smbios_smm_exit); | ||
190 | |||
191 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | ||
192 | MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); | ||
193 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); | ||
194 | MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>"); | ||
195 | MODULE_DESCRIPTION("Dell SMBIOS communications over SMI"); | ||
196 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/platform/x86/dell-smbios-wmi.c b/drivers/platform/x86/dell-smbios-wmi.c index 609557aa5868..fbefedb1c172 100644 --- a/drivers/platform/x86/dell-smbios-wmi.c +++ b/drivers/platform/x86/dell-smbios-wmi.c | |||
@@ -228,7 +228,7 @@ static const struct wmi_device_id dell_smbios_wmi_id_table[] = { | |||
228 | { }, | 228 | { }, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | static void __init parse_b1_table(const struct dmi_header *dm) | 231 | static void parse_b1_table(const struct dmi_header *dm) |
232 | { | 232 | { |
233 | struct misc_bios_flags_structure *flags = | 233 | struct misc_bios_flags_structure *flags = |
234 | container_of(dm, struct misc_bios_flags_structure, header); | 234 | container_of(dm, struct misc_bios_flags_structure, header); |
@@ -242,7 +242,7 @@ static void __init parse_b1_table(const struct dmi_header *dm) | |||
242 | wmi_supported = 1; | 242 | wmi_supported = 1; |
243 | } | 243 | } |
244 | 244 | ||
245 | static void __init find_b1(const struct dmi_header *dm, void *dummy) | 245 | static void find_b1(const struct dmi_header *dm, void *dummy) |
246 | { | 246 | { |
247 | switch (dm->type) { | 247 | switch (dm->type) { |
248 | case 0xb1: /* misc bios flags */ | 248 | case 0xb1: /* misc bios flags */ |
@@ -261,7 +261,7 @@ static struct wmi_driver dell_smbios_wmi_driver = { | |||
261 | .filter_callback = dell_smbios_wmi_filter, | 261 | .filter_callback = dell_smbios_wmi_filter, |
262 | }; | 262 | }; |
263 | 263 | ||
264 | static int __init init_dell_smbios_wmi(void) | 264 | int init_dell_smbios_wmi(void) |
265 | { | 265 | { |
266 | dmi_walk(find_b1, NULL); | 266 | dmi_walk(find_b1, NULL); |
267 | 267 | ||
@@ -271,15 +271,9 @@ static int __init init_dell_smbios_wmi(void) | |||
271 | return wmi_driver_register(&dell_smbios_wmi_driver); | 271 | return wmi_driver_register(&dell_smbios_wmi_driver); |
272 | } | 272 | } |
273 | 273 | ||
274 | static void __exit exit_dell_smbios_wmi(void) | 274 | void exit_dell_smbios_wmi(void) |
275 | { | 275 | { |
276 | wmi_driver_unregister(&dell_smbios_wmi_driver); | 276 | wmi_driver_unregister(&dell_smbios_wmi_driver); |
277 | } | 277 | } |
278 | 278 | ||
279 | module_init(init_dell_smbios_wmi); | ||
280 | module_exit(exit_dell_smbios_wmi); | ||
281 | |||
282 | MODULE_ALIAS("wmi:" DELL_WMI_SMBIOS_GUID); | 279 | MODULE_ALIAS("wmi:" DELL_WMI_SMBIOS_GUID); |
283 | MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>"); | ||
284 | MODULE_DESCRIPTION("Dell SMBIOS communications over WMI"); | ||
285 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/platform/x86/dell-smbios.h b/drivers/platform/x86/dell-smbios.h index 138d478d9adc..d8adaf959740 100644 --- a/drivers/platform/x86/dell-smbios.h +++ b/drivers/platform/x86/dell-smbios.h | |||
@@ -75,4 +75,29 @@ int dell_laptop_register_notifier(struct notifier_block *nb); | |||
75 | int dell_laptop_unregister_notifier(struct notifier_block *nb); | 75 | int dell_laptop_unregister_notifier(struct notifier_block *nb); |
76 | void dell_laptop_call_notifier(unsigned long action, void *data); | 76 | void dell_laptop_call_notifier(unsigned long action, void *data); |
77 | 77 | ||
78 | #endif | 78 | /* for the supported backends */ |
79 | #ifdef CONFIG_DELL_SMBIOS_WMI | ||
80 | int init_dell_smbios_wmi(void); | ||
81 | void exit_dell_smbios_wmi(void); | ||
82 | #else /* CONFIG_DELL_SMBIOS_WMI */ | ||
83 | static inline int init_dell_smbios_wmi(void) | ||
84 | { | ||
85 | return -ENODEV; | ||
86 | } | ||
87 | static inline void exit_dell_smbios_wmi(void) | ||
88 | {} | ||
89 | #endif /* CONFIG_DELL_SMBIOS_WMI */ | ||
90 | |||
91 | #ifdef CONFIG_DELL_SMBIOS_SMM | ||
92 | int init_dell_smbios_smm(void); | ||
93 | void exit_dell_smbios_smm(void); | ||
94 | #else /* CONFIG_DELL_SMBIOS_SMM */ | ||
95 | static inline int init_dell_smbios_smm(void) | ||
96 | { | ||
97 | return -ENODEV; | ||
98 | } | ||
99 | static inline void exit_dell_smbios_smm(void) | ||
100 | {} | ||
101 | #endif /* CONFIG_DELL_SMBIOS_SMM */ | ||
102 | |||
103 | #endif /* _DELL_SMBIOS_H_ */ | ||
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index e0678c14480f..3a33c5344bd5 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c | |||
@@ -566,7 +566,8 @@ static ssize_t watchdog_write(struct file *file, const char __user *buf, | |||
566 | char c; | 566 | char c; |
567 | if (get_user(c, buf + i)) | 567 | if (get_user(c, buf + i)) |
568 | return -EFAULT; | 568 | return -EFAULT; |
569 | expect_close = (c == 'V'); | 569 | if (c == 'V') |
570 | expect_close = true; | ||
570 | } | 571 | } |
571 | 572 | ||
572 | /* Properly order writes across fork()ed processes */ | 573 | /* Properly order writes across fork()ed processes */ |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index f1f00dfc0e68..b0a158073abd 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -28,16 +28,7 @@ | |||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
30 | #include <linux/watchdog.h> | 30 | #include <linux/watchdog.h> |
31 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
32 | #include <linux/dmi.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | #include <linux/nmi.h> | ||
35 | #include <linux/kdebug.h> | ||
36 | #include <linux/notifier.h> | ||
37 | #include <asm/set_memory.h> | ||
38 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
39 | #include <asm/nmi.h> | 31 | #include <asm/nmi.h> |
40 | #include <asm/frame.h> | ||
41 | 32 | ||
42 | #define HPWDT_VERSION "1.4.0" | 33 | #define HPWDT_VERSION "1.4.0" |
43 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) | 34 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) |
@@ -48,6 +39,9 @@ | |||
48 | static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ | 39 | static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ |
49 | static unsigned int reload; /* the computed soft_margin */ | 40 | static unsigned int reload; /* the computed soft_margin */ |
50 | static bool nowayout = WATCHDOG_NOWAYOUT; | 41 | static bool nowayout = WATCHDOG_NOWAYOUT; |
42 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
43 | static unsigned int allow_kdump = 1; | ||
44 | #endif | ||
51 | static char expect_release; | 45 | static char expect_release; |
52 | static unsigned long hpwdt_is_open; | 46 | static unsigned long hpwdt_is_open; |
53 | 47 | ||
@@ -63,373 +57,6 @@ static const struct pci_device_id hpwdt_devices[] = { | |||
63 | }; | 57 | }; |
64 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); | 58 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); |
65 | 59 | ||
66 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
67 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ | ||
68 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 | ||
69 | #define PCI_BIOS32_PARAGRAPH_LEN 16 | ||
70 | #define PCI_ROM_BASE1 0x000F0000 | ||
71 | #define ROM_SIZE 0x10000 | ||
72 | |||
73 | struct bios32_service_dir { | ||
74 | u32 signature; | ||
75 | u32 entry_point; | ||
76 | u8 revision; | ||
77 | u8 length; | ||
78 | u8 checksum; | ||
79 | u8 reserved[5]; | ||
80 | }; | ||
81 | |||
82 | /* type 212 */ | ||
83 | struct smbios_cru64_info { | ||
84 | u8 type; | ||
85 | u8 byte_length; | ||
86 | u16 handle; | ||
87 | u32 signature; | ||
88 | u64 physical_address; | ||
89 | u32 double_length; | ||
90 | u32 double_offset; | ||
91 | }; | ||
92 | #define SMBIOS_CRU64_INFORMATION 212 | ||
93 | |||
94 | /* type 219 */ | ||
95 | struct smbios_proliant_info { | ||
96 | u8 type; | ||
97 | u8 byte_length; | ||
98 | u16 handle; | ||
99 | u32 power_features; | ||
100 | u32 omega_features; | ||
101 | u32 reserved; | ||
102 | u32 misc_features; | ||
103 | }; | ||
104 | #define SMBIOS_ICRU_INFORMATION 219 | ||
105 | |||
106 | |||
107 | struct cmn_registers { | ||
108 | union { | ||
109 | struct { | ||
110 | u8 ral; | ||
111 | u8 rah; | ||
112 | u16 rea2; | ||
113 | }; | ||
114 | u32 reax; | ||
115 | } u1; | ||
116 | union { | ||
117 | struct { | ||
118 | u8 rbl; | ||
119 | u8 rbh; | ||
120 | u8 reb2l; | ||
121 | u8 reb2h; | ||
122 | }; | ||
123 | u32 rebx; | ||
124 | } u2; | ||
125 | union { | ||
126 | struct { | ||
127 | u8 rcl; | ||
128 | u8 rch; | ||
129 | u16 rec2; | ||
130 | }; | ||
131 | u32 recx; | ||
132 | } u3; | ||
133 | union { | ||
134 | struct { | ||
135 | u8 rdl; | ||
136 | u8 rdh; | ||
137 | u16 red2; | ||
138 | }; | ||
139 | u32 redx; | ||
140 | } u4; | ||
141 | |||
142 | u32 resi; | ||
143 | u32 redi; | ||
144 | u16 rds; | ||
145 | u16 res; | ||
146 | u32 reflags; | ||
147 | } __attribute__((packed)); | ||
148 | |||
149 | static unsigned int hpwdt_nmi_decoding; | ||
150 | static unsigned int allow_kdump = 1; | ||
151 | static unsigned int is_icru; | ||
152 | static unsigned int is_uefi; | ||
153 | static DEFINE_SPINLOCK(rom_lock); | ||
154 | static void *cru_rom_addr; | ||
155 | static struct cmn_registers cmn_regs; | ||
156 | |||
157 | extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | ||
158 | unsigned long *pRomEntry); | ||
159 | |||
160 | #ifdef CONFIG_X86_32 | ||
161 | /* --32 Bit Bios------------------------------------------------------------ */ | ||
162 | |||
163 | #define HPWDT_ARCH 32 | ||
164 | |||
165 | asm(".text \n\t" | ||
166 | ".align 4 \n\t" | ||
167 | ".globl asminline_call \n" | ||
168 | "asminline_call: \n\t" | ||
169 | "pushl %ebp \n\t" | ||
170 | "movl %esp, %ebp \n\t" | ||
171 | "pusha \n\t" | ||
172 | "pushf \n\t" | ||
173 | "push %es \n\t" | ||
174 | "push %ds \n\t" | ||
175 | "pop %es \n\t" | ||
176 | "movl 8(%ebp),%eax \n\t" | ||
177 | "movl 4(%eax),%ebx \n\t" | ||
178 | "movl 8(%eax),%ecx \n\t" | ||
179 | "movl 12(%eax),%edx \n\t" | ||
180 | "movl 16(%eax),%esi \n\t" | ||
181 | "movl 20(%eax),%edi \n\t" | ||
182 | "movl (%eax),%eax \n\t" | ||
183 | "push %cs \n\t" | ||
184 | "call *12(%ebp) \n\t" | ||
185 | "pushf \n\t" | ||
186 | "pushl %eax \n\t" | ||
187 | "movl 8(%ebp),%eax \n\t" | ||
188 | "movl %ebx,4(%eax) \n\t" | ||
189 | "movl %ecx,8(%eax) \n\t" | ||
190 | "movl %edx,12(%eax) \n\t" | ||
191 | "movl %esi,16(%eax) \n\t" | ||
192 | "movl %edi,20(%eax) \n\t" | ||
193 | "movw %ds,24(%eax) \n\t" | ||
194 | "movw %es,26(%eax) \n\t" | ||
195 | "popl %ebx \n\t" | ||
196 | "movl %ebx,(%eax) \n\t" | ||
197 | "popl %ebx \n\t" | ||
198 | "movl %ebx,28(%eax) \n\t" | ||
199 | "pop %es \n\t" | ||
200 | "popf \n\t" | ||
201 | "popa \n\t" | ||
202 | "leave \n\t" | ||
203 | "ret \n\t" | ||
204 | ".previous"); | ||
205 | |||
206 | |||
207 | /* | ||
208 | * cru_detect | ||
209 | * | ||
210 | * Routine Description: | ||
211 | * This function uses the 32-bit BIOS Service Directory record to | ||
212 | * search for a $CRU record. | ||
213 | * | ||
214 | * Return Value: | ||
215 | * 0 : SUCCESS | ||
216 | * <0 : FAILURE | ||
217 | */ | ||
218 | static int cru_detect(unsigned long map_entry, | ||
219 | unsigned long map_offset) | ||
220 | { | ||
221 | void *bios32_map; | ||
222 | unsigned long *bios32_entrypoint; | ||
223 | unsigned long cru_physical_address; | ||
224 | unsigned long cru_length; | ||
225 | unsigned long physical_bios_base = 0; | ||
226 | unsigned long physical_bios_offset = 0; | ||
227 | int retval = -ENODEV; | ||
228 | |||
229 | bios32_map = ioremap(map_entry, (2 * PAGE_SIZE)); | ||
230 | |||
231 | if (bios32_map == NULL) | ||
232 | return -ENODEV; | ||
233 | |||
234 | bios32_entrypoint = bios32_map + map_offset; | ||
235 | |||
236 | cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; | ||
237 | |||
238 | set_memory_x((unsigned long)bios32_map, 2); | ||
239 | asminline_call(&cmn_regs, bios32_entrypoint); | ||
240 | |||
241 | if (cmn_regs.u1.ral != 0) { | ||
242 | pr_warn("Call succeeded but with an error: 0x%x\n", | ||
243 | cmn_regs.u1.ral); | ||
244 | } else { | ||
245 | physical_bios_base = cmn_regs.u2.rebx; | ||
246 | physical_bios_offset = cmn_regs.u4.redx; | ||
247 | cru_length = cmn_regs.u3.recx; | ||
248 | cru_physical_address = | ||
249 | physical_bios_base + physical_bios_offset; | ||
250 | |||
251 | /* If the values look OK, then map it in. */ | ||
252 | if ((physical_bios_base + physical_bios_offset)) { | ||
253 | cru_rom_addr = | ||
254 | ioremap(cru_physical_address, cru_length); | ||
255 | if (cru_rom_addr) { | ||
256 | set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, | ||
257 | (cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT); | ||
258 | retval = 0; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | pr_debug("CRU Base Address: 0x%lx\n", physical_bios_base); | ||
263 | pr_debug("CRU Offset Address: 0x%lx\n", physical_bios_offset); | ||
264 | pr_debug("CRU Length: 0x%lx\n", cru_length); | ||
265 | pr_debug("CRU Mapped Address: %p\n", &cru_rom_addr); | ||
266 | } | ||
267 | iounmap(bios32_map); | ||
268 | return retval; | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * bios_checksum | ||
273 | */ | ||
274 | static int bios_checksum(const char __iomem *ptr, int len) | ||
275 | { | ||
276 | char sum = 0; | ||
277 | int i; | ||
278 | |||
279 | /* | ||
280 | * calculate checksum of size bytes. This should add up | ||
281 | * to zero if we have a valid header. | ||
282 | */ | ||
283 | for (i = 0; i < len; i++) | ||
284 | sum += ptr[i]; | ||
285 | |||
286 | return ((sum == 0) && (len > 0)); | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * bios32_present | ||
291 | * | ||
292 | * Routine Description: | ||
293 | * This function finds the 32-bit BIOS Service Directory | ||
294 | * | ||
295 | * Return Value: | ||
296 | * 0 : SUCCESS | ||
297 | * <0 : FAILURE | ||
298 | */ | ||
299 | static int bios32_present(const char __iomem *p) | ||
300 | { | ||
301 | struct bios32_service_dir *bios_32_ptr; | ||
302 | int length; | ||
303 | unsigned long map_entry, map_offset; | ||
304 | |||
305 | bios_32_ptr = (struct bios32_service_dir *) p; | ||
306 | |||
307 | /* | ||
308 | * Search for signature by checking equal to the swizzled value | ||
309 | * instead of calling another routine to perform a strcmp. | ||
310 | */ | ||
311 | if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) { | ||
312 | length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN; | ||
313 | if (bios_checksum(p, length)) { | ||
314 | /* | ||
315 | * According to the spec, we're looking for the | ||
316 | * first 4KB-aligned address below the entrypoint | ||
317 | * listed in the header. The Service Directory code | ||
318 | * is guaranteed to occupy no more than 2 4KB pages. | ||
319 | */ | ||
320 | map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1); | ||
321 | map_offset = bios_32_ptr->entry_point - map_entry; | ||
322 | |||
323 | return cru_detect(map_entry, map_offset); | ||
324 | } | ||
325 | } | ||
326 | return -ENODEV; | ||
327 | } | ||
328 | |||
329 | static int detect_cru_service(void) | ||
330 | { | ||
331 | char __iomem *p, *q; | ||
332 | int rc = -1; | ||
333 | |||
334 | /* | ||
335 | * Search from 0x0f0000 through 0x0fffff, inclusive. | ||
336 | */ | ||
337 | p = ioremap(PCI_ROM_BASE1, ROM_SIZE); | ||
338 | if (p == NULL) | ||
339 | return -ENOMEM; | ||
340 | |||
341 | for (q = p; q < p + ROM_SIZE; q += 16) { | ||
342 | rc = bios32_present(q); | ||
343 | if (!rc) | ||
344 | break; | ||
345 | } | ||
346 | iounmap(p); | ||
347 | return rc; | ||
348 | } | ||
349 | /* ------------------------------------------------------------------------- */ | ||
350 | #endif /* CONFIG_X86_32 */ | ||
351 | #ifdef CONFIG_X86_64 | ||
352 | /* --64 Bit Bios------------------------------------------------------------ */ | ||
353 | |||
354 | #define HPWDT_ARCH 64 | ||
355 | |||
356 | asm(".text \n\t" | ||
357 | ".align 4 \n\t" | ||
358 | ".globl asminline_call \n\t" | ||
359 | ".type asminline_call, @function \n\t" | ||
360 | "asminline_call: \n\t" | ||
361 | FRAME_BEGIN | ||
362 | "pushq %rax \n\t" | ||
363 | "pushq %rbx \n\t" | ||
364 | "pushq %rdx \n\t" | ||
365 | "pushq %r12 \n\t" | ||
366 | "pushq %r9 \n\t" | ||
367 | "movq %rsi, %r12 \n\t" | ||
368 | "movq %rdi, %r9 \n\t" | ||
369 | "movl 4(%r9),%ebx \n\t" | ||
370 | "movl 8(%r9),%ecx \n\t" | ||
371 | "movl 12(%r9),%edx \n\t" | ||
372 | "movl 16(%r9),%esi \n\t" | ||
373 | "movl 20(%r9),%edi \n\t" | ||
374 | "movl (%r9),%eax \n\t" | ||
375 | "call *%r12 \n\t" | ||
376 | "pushfq \n\t" | ||
377 | "popq %r12 \n\t" | ||
378 | "movl %eax, (%r9) \n\t" | ||
379 | "movl %ebx, 4(%r9) \n\t" | ||
380 | "movl %ecx, 8(%r9) \n\t" | ||
381 | "movl %edx, 12(%r9) \n\t" | ||
382 | "movl %esi, 16(%r9) \n\t" | ||
383 | "movl %edi, 20(%r9) \n\t" | ||
384 | "movq %r12, %rax \n\t" | ||
385 | "movl %eax, 28(%r9) \n\t" | ||
386 | "popq %r9 \n\t" | ||
387 | "popq %r12 \n\t" | ||
388 | "popq %rdx \n\t" | ||
389 | "popq %rbx \n\t" | ||
390 | "popq %rax \n\t" | ||
391 | FRAME_END | ||
392 | "ret \n\t" | ||
393 | ".previous"); | ||
394 | |||
395 | /* | ||
396 | * dmi_find_cru | ||
397 | * | ||
398 | * Routine Description: | ||
399 | * This function checks whether or not a SMBIOS/DMI record is | ||
400 | * the 64bit CRU info or not | ||
401 | */ | ||
402 | static void dmi_find_cru(const struct dmi_header *dm, void *dummy) | ||
403 | { | ||
404 | struct smbios_cru64_info *smbios_cru64_ptr; | ||
405 | unsigned long cru_physical_address; | ||
406 | |||
407 | if (dm->type == SMBIOS_CRU64_INFORMATION) { | ||
408 | smbios_cru64_ptr = (struct smbios_cru64_info *) dm; | ||
409 | if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) { | ||
410 | cru_physical_address = | ||
411 | smbios_cru64_ptr->physical_address + | ||
412 | smbios_cru64_ptr->double_offset; | ||
413 | cru_rom_addr = ioremap(cru_physical_address, | ||
414 | smbios_cru64_ptr->double_length); | ||
415 | set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, | ||
416 | smbios_cru64_ptr->double_length >> PAGE_SHIFT); | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static int detect_cru_service(void) | ||
422 | { | ||
423 | cru_rom_addr = NULL; | ||
424 | |||
425 | dmi_walk(dmi_find_cru, NULL); | ||
426 | |||
427 | /* if cru_rom_addr has been set then we found a CRU service */ | ||
428 | return ((cru_rom_addr != NULL) ? 0 : -ENODEV); | ||
429 | } | ||
430 | /* ------------------------------------------------------------------------- */ | ||
431 | #endif /* CONFIG_X86_64 */ | ||
432 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
433 | 60 | ||
434 | /* | 61 | /* |
435 | * Watchdog operations | 62 | * Watchdog operations |
@@ -486,30 +113,12 @@ static int hpwdt_my_nmi(void) | |||
486 | */ | 113 | */ |
487 | static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) | 114 | static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) |
488 | { | 115 | { |
489 | unsigned long rom_pl; | ||
490 | static int die_nmi_called; | ||
491 | |||
492 | if (!hpwdt_nmi_decoding) | ||
493 | return NMI_DONE; | ||
494 | |||
495 | if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) | 116 | if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) |
496 | return NMI_DONE; | 117 | return NMI_DONE; |
497 | 118 | ||
498 | spin_lock_irqsave(&rom_lock, rom_pl); | ||
499 | if (!die_nmi_called && !is_icru && !is_uefi) | ||
500 | asminline_call(&cmn_regs, cru_rom_addr); | ||
501 | die_nmi_called = 1; | ||
502 | spin_unlock_irqrestore(&rom_lock, rom_pl); | ||
503 | |||
504 | if (allow_kdump) | 119 | if (allow_kdump) |
505 | hpwdt_stop(); | 120 | hpwdt_stop(); |
506 | 121 | ||
507 | if (!is_icru && !is_uefi) { | ||
508 | if (cmn_regs.u1.ral == 0) { | ||
509 | nmi_panic(regs, "An NMI occurred, but unable to determine source.\n"); | ||
510 | return NMI_HANDLED; | ||
511 | } | ||
512 | } | ||
513 | nmi_panic(regs, "An NMI occurred. Depending on your system the reason " | 122 | nmi_panic(regs, "An NMI occurred. Depending on your system the reason " |
514 | "for the NMI is logged in any one of the following " | 123 | "for the NMI is logged in any one of the following " |
515 | "resources:\n" | 124 | "resources:\n" |
@@ -675,84 +284,11 @@ static struct miscdevice hpwdt_miscdev = { | |||
675 | * Init & Exit | 284 | * Init & Exit |
676 | */ | 285 | */ |
677 | 286 | ||
678 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
679 | #ifdef CONFIG_X86_LOCAL_APIC | ||
680 | static void hpwdt_check_nmi_decoding(struct pci_dev *dev) | ||
681 | { | ||
682 | /* | ||
683 | * If nmi_watchdog is turned off then we can turn on | ||
684 | * our nmi decoding capability. | ||
685 | */ | ||
686 | hpwdt_nmi_decoding = 1; | ||
687 | } | ||
688 | #else | ||
689 | static void hpwdt_check_nmi_decoding(struct pci_dev *dev) | ||
690 | { | ||
691 | dev_warn(&dev->dev, "NMI decoding is disabled. " | ||
692 | "Your kernel does not support a NMI Watchdog.\n"); | ||
693 | } | ||
694 | #endif /* CONFIG_X86_LOCAL_APIC */ | ||
695 | |||
696 | /* | ||
697 | * dmi_find_icru | ||
698 | * | ||
699 | * Routine Description: | ||
700 | * This function checks whether or not we are on an iCRU-based server. | ||
701 | * This check is independent of architecture and needs to be made for | ||
702 | * any ProLiant system. | ||
703 | */ | ||
704 | static void dmi_find_icru(const struct dmi_header *dm, void *dummy) | ||
705 | { | ||
706 | struct smbios_proliant_info *smbios_proliant_ptr; | ||
707 | |||
708 | if (dm->type == SMBIOS_ICRU_INFORMATION) { | ||
709 | smbios_proliant_ptr = (struct smbios_proliant_info *) dm; | ||
710 | if (smbios_proliant_ptr->misc_features & 0x01) | ||
711 | is_icru = 1; | ||
712 | if (smbios_proliant_ptr->misc_features & 0x1400) | ||
713 | is_uefi = 1; | ||
714 | } | ||
715 | } | ||
716 | 287 | ||
717 | static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | 288 | static int hpwdt_init_nmi_decoding(struct pci_dev *dev) |
718 | { | 289 | { |
290 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
719 | int retval; | 291 | int retval; |
720 | |||
721 | /* | ||
722 | * On typical CRU-based systems we need to map that service in | ||
723 | * the BIOS. For 32 bit Operating Systems we need to go through | ||
724 | * the 32 Bit BIOS Service Directory. For 64 bit Operating | ||
725 | * Systems we get that service through SMBIOS. | ||
726 | * | ||
727 | * On systems that support the new iCRU service all we need to | ||
728 | * do is call dmi_walk to get the supported flag value and skip | ||
729 | * the old cru detect code. | ||
730 | */ | ||
731 | dmi_walk(dmi_find_icru, NULL); | ||
732 | if (!is_icru && !is_uefi) { | ||
733 | |||
734 | /* | ||
735 | * We need to map the ROM to get the CRU service. | ||
736 | * For 32 bit Operating Systems we need to go through the 32 Bit | ||
737 | * BIOS Service Directory | ||
738 | * For 64 bit Operating Systems we get that service through SMBIOS. | ||
739 | */ | ||
740 | retval = detect_cru_service(); | ||
741 | if (retval < 0) { | ||
742 | dev_warn(&dev->dev, | ||
743 | "Unable to detect the %d Bit CRU Service.\n", | ||
744 | HPWDT_ARCH); | ||
745 | return retval; | ||
746 | } | ||
747 | |||
748 | /* | ||
749 | * We know this is the only CRU call we need to make so lets keep as | ||
750 | * few instructions as possible once the NMI comes in. | ||
751 | */ | ||
752 | cmn_regs.u1.rah = 0x0D; | ||
753 | cmn_regs.u1.ral = 0x02; | ||
754 | } | ||
755 | |||
756 | /* | 292 | /* |
757 | * Only one function can register for NMI_UNKNOWN | 293 | * Only one function can register for NMI_UNKNOWN |
758 | */ | 294 | */ |
@@ -780,45 +316,26 @@ error: | |||
780 | dev_warn(&dev->dev, | 316 | dev_warn(&dev->dev, |
781 | "Unable to register a die notifier (err=%d).\n", | 317 | "Unable to register a die notifier (err=%d).\n", |
782 | retval); | 318 | retval); |
783 | if (cru_rom_addr) | ||
784 | iounmap(cru_rom_addr); | ||
785 | return retval; | 319 | return retval; |
320 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
321 | return 0; | ||
786 | } | 322 | } |
787 | 323 | ||
788 | static void hpwdt_exit_nmi_decoding(void) | 324 | static void hpwdt_exit_nmi_decoding(void) |
789 | { | 325 | { |
326 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
790 | unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); | 327 | unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); |
791 | unregister_nmi_handler(NMI_SERR, "hpwdt"); | 328 | unregister_nmi_handler(NMI_SERR, "hpwdt"); |
792 | unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); | 329 | unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); |
793 | if (cru_rom_addr) | 330 | #endif |
794 | iounmap(cru_rom_addr); | ||
795 | } | ||
796 | #else /* !CONFIG_HPWDT_NMI_DECODING */ | ||
797 | static void hpwdt_check_nmi_decoding(struct pci_dev *dev) | ||
798 | { | ||
799 | } | ||
800 | |||
801 | static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | ||
802 | { | ||
803 | return 0; | ||
804 | } | 331 | } |
805 | 332 | ||
806 | static void hpwdt_exit_nmi_decoding(void) | ||
807 | { | ||
808 | } | ||
809 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
810 | |||
811 | static int hpwdt_init_one(struct pci_dev *dev, | 333 | static int hpwdt_init_one(struct pci_dev *dev, |
812 | const struct pci_device_id *ent) | 334 | const struct pci_device_id *ent) |
813 | { | 335 | { |
814 | int retval; | 336 | int retval; |
815 | 337 | ||
816 | /* | 338 | /* |
817 | * Check if we can do NMI decoding or not | ||
818 | */ | ||
819 | hpwdt_check_nmi_decoding(dev); | ||
820 | |||
821 | /* | ||
822 | * First let's find out if we are on an iLO2+ server. We will | 339 | * First let's find out if we are on an iLO2+ server. We will |
823 | * not run on a legacy ASM box. | 340 | * not run on a legacy ASM box. |
824 | * So we only support the G5 ProLiant servers and higher. | 341 | * So we only support the G5 ProLiant servers and higher. |
@@ -922,6 +439,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | |||
922 | #ifdef CONFIG_HPWDT_NMI_DECODING | 439 | #ifdef CONFIG_HPWDT_NMI_DECODING |
923 | module_param(allow_kdump, int, 0); | 440 | module_param(allow_kdump, int, 0); |
924 | MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); | 441 | MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); |
925 | #endif /* !CONFIG_HPWDT_NMI_DECODING */ | 442 | #endif /* CONFIG_HPWDT_NMI_DECODING */ |
926 | 443 | ||
927 | module_pci_driver(hpwdt_driver); | 444 | module_pci_driver(hpwdt_driver); |
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index 316c2eb122d2..e8bd9887c566 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c | |||
@@ -50,6 +50,7 @@ | |||
50 | */ | 50 | */ |
51 | 51 | ||
52 | #include <linux/io.h> | 52 | #include <linux/io.h> |
53 | #include <linux/io-64-nonatomic-lo-hi.h> | ||
53 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
54 | #include <linux/module.h> | 55 | #include <linux/module.h> |
55 | #include <linux/moduleparam.h> | 56 | #include <linux/moduleparam.h> |
@@ -159,7 +160,7 @@ static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd) | |||
159 | !(readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0)) | 160 | !(readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0)) |
160 | timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR); | 161 | timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR); |
161 | 162 | ||
162 | timeleft += readq(gwdt->control_base + SBSA_GWDT_WCV) - | 163 | timeleft += lo_hi_readq(gwdt->control_base + SBSA_GWDT_WCV) - |
163 | arch_counter_get_cntvct(); | 164 | arch_counter_get_cntvct(); |
164 | 165 | ||
165 | do_div(timeleft, gwdt->clk); | 166 | do_div(timeleft, gwdt->clk); |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 96db9ae5d5af..4b838470fac4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -2246,7 +2246,7 @@ static void ctx_resched(struct perf_cpu_context *cpuctx, | |||
2246 | struct perf_event_context *task_ctx, | 2246 | struct perf_event_context *task_ctx, |
2247 | enum event_type_t event_type) | 2247 | enum event_type_t event_type) |
2248 | { | 2248 | { |
2249 | enum event_type_t ctx_event_type = event_type & EVENT_ALL; | 2249 | enum event_type_t ctx_event_type; |
2250 | bool cpu_event = !!(event_type & EVENT_CPU); | 2250 | bool cpu_event = !!(event_type & EVENT_CPU); |
2251 | 2251 | ||
2252 | /* | 2252 | /* |
@@ -2256,6 +2256,8 @@ static void ctx_resched(struct perf_cpu_context *cpuctx, | |||
2256 | if (event_type & EVENT_PINNED) | 2256 | if (event_type & EVENT_PINNED) |
2257 | event_type |= EVENT_FLEXIBLE; | 2257 | event_type |= EVENT_FLEXIBLE; |
2258 | 2258 | ||
2259 | ctx_event_type = event_type & EVENT_ALL; | ||
2260 | |||
2259 | perf_pmu_disable(cpuctx->ctx.pmu); | 2261 | perf_pmu_disable(cpuctx->ctx.pmu); |
2260 | if (task_ctx) | 2262 | if (task_ctx) |
2261 | task_ctx_sched_out(cpuctx, task_ctx, event_type); | 2263 | task_ctx_sched_out(cpuctx, task_ctx, event_type); |
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 65cc0cb984e6..940633c63254 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c | |||
@@ -1616,11 +1616,12 @@ bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, | |||
1616 | void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) | 1616 | void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) |
1617 | { | 1617 | { |
1618 | DEFINE_WAKE_Q(wake_q); | 1618 | DEFINE_WAKE_Q(wake_q); |
1619 | unsigned long flags; | ||
1619 | bool postunlock; | 1620 | bool postunlock; |
1620 | 1621 | ||
1621 | raw_spin_lock_irq(&lock->wait_lock); | 1622 | raw_spin_lock_irqsave(&lock->wait_lock, flags); |
1622 | postunlock = __rt_mutex_futex_unlock(lock, &wake_q); | 1623 | postunlock = __rt_mutex_futex_unlock(lock, &wake_q); |
1623 | raw_spin_unlock_irq(&lock->wait_lock); | 1624 | raw_spin_unlock_irqrestore(&lock->wait_lock, flags); |
1624 | 1625 | ||
1625 | if (postunlock) | 1626 | if (postunlock) |
1626 | rt_mutex_postunlock(&wake_q); | 1627 | rt_mutex_postunlock(&wake_q); |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5589bae34af6..a6f538b31ad6 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -297,11 +297,11 @@ cmd_dt_S_dtb= \ | |||
297 | echo '\#include <asm-generic/vmlinux.lds.h>'; \ | 297 | echo '\#include <asm-generic/vmlinux.lds.h>'; \ |
298 | echo '.section .dtb.init.rodata,"a"'; \ | 298 | echo '.section .dtb.init.rodata,"a"'; \ |
299 | echo '.balign STRUCT_ALIGNMENT'; \ | 299 | echo '.balign STRUCT_ALIGNMENT'; \ |
300 | echo '.global __dtb_$(*F)_begin'; \ | 300 | echo '.global __dtb_$(subst -,_,$(*F))_begin'; \ |
301 | echo '__dtb_$(*F)_begin:'; \ | 301 | echo '__dtb_$(subst -,_,$(*F))_begin:'; \ |
302 | echo '.incbin "$<" '; \ | 302 | echo '.incbin "$<" '; \ |
303 | echo '__dtb_$(*F)_end:'; \ | 303 | echo '__dtb_$(subst -,_,$(*F))_end:'; \ |
304 | echo '.global __dtb_$(*F)_end'; \ | 304 | echo '.global __dtb_$(subst -,_,$(*F))_end'; \ |
305 | echo '.balign STRUCT_ALIGNMENT'; \ | 305 | echo '.balign STRUCT_ALIGNMENT'; \ |
306 | ) > $@ | 306 | ) > $@ |
307 | 307 | ||
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index fa3d39b6f23b..449b68c4c90c 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
@@ -93,14 +93,6 @@ | |||
93 | * (Note: it'd be easy to port over the complete mkdep state machine, | 93 | * (Note: it'd be easy to port over the complete mkdep state machine, |
94 | * but I don't think the added complexity is worth it) | 94 | * but I don't think the added complexity is worth it) |
95 | */ | 95 | */ |
96 | /* | ||
97 | * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto | ||
98 | * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not | ||
99 | * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as | ||
100 | * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h, | ||
101 | * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that | ||
102 | * those files will have correct dependencies. | ||
103 | */ | ||
104 | 96 | ||
105 | #include <sys/types.h> | 97 | #include <sys/types.h> |
106 | #include <sys/stat.h> | 98 | #include <sys/stat.h> |
@@ -233,8 +225,13 @@ static int str_ends_with(const char *s, int slen, const char *sub) | |||
233 | static void parse_config_file(const char *p) | 225 | static void parse_config_file(const char *p) |
234 | { | 226 | { |
235 | const char *q, *r; | 227 | const char *q, *r; |
228 | const char *start = p; | ||
236 | 229 | ||
237 | while ((p = strstr(p, "CONFIG_"))) { | 230 | while ((p = strstr(p, "CONFIG_"))) { |
231 | if (p > start && (isalnum(p[-1]) || p[-1] == '_')) { | ||
232 | p += 7; | ||
233 | continue; | ||
234 | } | ||
238 | p += 7; | 235 | p += 7; |
239 | q = p; | 236 | q = p; |
240 | while (*q && (isalnum(*q) || *q == '_')) | 237 | while (*q && (isalnum(*q) || *q == '_')) |
@@ -286,8 +283,6 @@ static int is_ignored_file(const char *s, int len) | |||
286 | { | 283 | { |
287 | return str_ends_with(s, len, "include/generated/autoconf.h") || | 284 | return str_ends_with(s, len, "include/generated/autoconf.h") || |
288 | str_ends_with(s, len, "include/generated/autoksyms.h") || | 285 | str_ends_with(s, len, "include/generated/autoksyms.h") || |
289 | str_ends_with(s, len, "arch/um/include/uml-config.h") || | ||
290 | str_ends_with(s, len, "include/linux/kconfig.h") || | ||
291 | str_ends_with(s, len, ".ver"); | 286 | str_ends_with(s, len, ".ver"); |
292 | } | 287 | } |
293 | 288 | ||
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 94b664817ad9..d84a5674e95e 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter | |||
@@ -15,7 +15,7 @@ signal(SIGPIPE, SIG_DFL) | |||
15 | if len(sys.argv) < 3: | 15 | if len(sys.argv) < 3: |
16 | sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0]) | 16 | sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0]) |
17 | sys.stderr.write("The options are:\n") | 17 | sys.stderr.write("The options are:\n") |
18 | sys.stderr.write("-c cateogrize output based on symbole type\n") | 18 | sys.stderr.write("-c categorize output based on symbol type\n") |
19 | sys.stderr.write("-d Show delta of Data Section\n") | 19 | sys.stderr.write("-d Show delta of Data Section\n") |
20 | sys.stderr.write("-t Show delta of text Section\n") | 20 | sys.stderr.write("-t Show delta of text Section\n") |
21 | sys.exit(-1) | 21 | sys.exit(-1) |
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 0dfe4d3f74e2..f41079da38c5 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h | |||
@@ -213,6 +213,7 @@ | |||
213 | #define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ | 213 | #define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ |
214 | 214 | ||
215 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ | 215 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ |
216 | #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ | ||
216 | 217 | ||
217 | /* Virtualization flags: Linux defined, word 8 */ | 218 | /* Virtualization flags: Linux defined, word 8 */ |
218 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | 219 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ |
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 0fb5ef939732..7b26d4b0b052 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h | |||
@@ -761,6 +761,7 @@ struct kvm_ppc_resize_hpt { | |||
761 | #define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 | 761 | #define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 |
762 | #define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 | 762 | #define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 |
763 | #define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2) | 763 | #define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2) |
764 | #define KVM_GET_MSR_FEATURE_INDEX_LIST _IOWR(KVMIO, 0x0a, struct kvm_msr_list) | ||
764 | 765 | ||
765 | /* | 766 | /* |
766 | * Extension capability list. | 767 | * Extension capability list. |
@@ -934,6 +935,7 @@ struct kvm_ppc_resize_hpt { | |||
934 | #define KVM_CAP_S390_AIS_MIGRATION 150 | 935 | #define KVM_CAP_S390_AIS_MIGRATION 150 |
935 | #define KVM_CAP_PPC_GET_CPU_CHAR 151 | 936 | #define KVM_CAP_PPC_GET_CPU_CHAR 151 |
936 | #define KVM_CAP_S390_BPB 152 | 937 | #define KVM_CAP_S390_BPB 152 |
938 | #define KVM_CAP_GET_MSR_FEATURES 153 | ||
937 | 939 | ||
938 | #ifdef KVM_CAP_IRQ_ROUTING | 940 | #ifdef KVM_CAP_IRQ_ROUTING |
939 | 941 | ||
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 46c1d239cc1b..92b6a2c21631 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
@@ -1116,42 +1116,29 @@ static int read_unwind_hints(struct objtool_file *file) | |||
1116 | 1116 | ||
1117 | static int read_retpoline_hints(struct objtool_file *file) | 1117 | static int read_retpoline_hints(struct objtool_file *file) |
1118 | { | 1118 | { |
1119 | struct section *sec, *relasec; | 1119 | struct section *sec; |
1120 | struct instruction *insn; | 1120 | struct instruction *insn; |
1121 | struct rela *rela; | 1121 | struct rela *rela; |
1122 | int i; | ||
1123 | 1122 | ||
1124 | sec = find_section_by_name(file->elf, ".discard.retpoline_safe"); | 1123 | sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe"); |
1125 | if (!sec) | 1124 | if (!sec) |
1126 | return 0; | 1125 | return 0; |
1127 | 1126 | ||
1128 | relasec = sec->rela; | 1127 | list_for_each_entry(rela, &sec->rela_list, list) { |
1129 | if (!relasec) { | 1128 | if (rela->sym->type != STT_SECTION) { |
1130 | WARN("missing .rela.discard.retpoline_safe section"); | 1129 | WARN("unexpected relocation symbol type in %s", sec->name); |
1131 | return -1; | ||
1132 | } | ||
1133 | |||
1134 | if (sec->len % sizeof(unsigned long)) { | ||
1135 | WARN("retpoline_safe size mismatch: %d %ld", sec->len, sizeof(unsigned long)); | ||
1136 | return -1; | ||
1137 | } | ||
1138 | |||
1139 | for (i = 0; i < sec->len / sizeof(unsigned long); i++) { | ||
1140 | rela = find_rela_by_dest(sec, i * sizeof(unsigned long)); | ||
1141 | if (!rela) { | ||
1142 | WARN("can't find rela for retpoline_safe[%d]", i); | ||
1143 | return -1; | 1130 | return -1; |
1144 | } | 1131 | } |
1145 | 1132 | ||
1146 | insn = find_insn(file, rela->sym->sec, rela->addend); | 1133 | insn = find_insn(file, rela->sym->sec, rela->addend); |
1147 | if (!insn) { | 1134 | if (!insn) { |
1148 | WARN("can't find insn for retpoline_safe[%d]", i); | 1135 | WARN("bad .discard.retpoline_safe entry"); |
1149 | return -1; | 1136 | return -1; |
1150 | } | 1137 | } |
1151 | 1138 | ||
1152 | if (insn->type != INSN_JUMP_DYNAMIC && | 1139 | if (insn->type != INSN_JUMP_DYNAMIC && |
1153 | insn->type != INSN_CALL_DYNAMIC) { | 1140 | insn->type != INSN_CALL_DYNAMIC) { |
1154 | WARN_FUNC("retpoline_safe hint not a indirect jump/call", | 1141 | WARN_FUNC("retpoline_safe hint not an indirect jump/call", |
1155 | insn->sec, insn->offset); | 1142 | insn->sec, insn->offset); |
1156 | return -1; | 1143 | return -1; |
1157 | } | 1144 | } |
diff --git a/tools/perf/Documentation/perf-kallsyms.txt b/tools/perf/Documentation/perf-kallsyms.txt index 954ea9e21236..cf9f4040ea5c 100644 --- a/tools/perf/Documentation/perf-kallsyms.txt +++ b/tools/perf/Documentation/perf-kallsyms.txt | |||
@@ -8,7 +8,7 @@ perf-kallsyms - Searches running kernel for symbols | |||
8 | SYNOPSIS | 8 | SYNOPSIS |
9 | -------- | 9 | -------- |
10 | [verse] | 10 | [verse] |
11 | 'perf kallsyms <options> symbol_name[,symbol_name...]' | 11 | 'perf kallsyms' [<options>] symbol_name[,symbol_name...] |
12 | 12 | ||
13 | DESCRIPTION | 13 | DESCRIPTION |
14 | ----------- | 14 | ----------- |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index bf4ca749d1ac..a217623fec2e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -881,6 +881,15 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
881 | } | 881 | } |
882 | } | 882 | } |
883 | 883 | ||
884 | /* | ||
885 | * If we have just single event and are sending data | ||
886 | * through pipe, we need to force the ids allocation, | ||
887 | * because we synthesize event name through the pipe | ||
888 | * and need the id for that. | ||
889 | */ | ||
890 | if (data->is_pipe && rec->evlist->nr_entries == 1) | ||
891 | rec->opts.sample_id = true; | ||
892 | |||
884 | if (record__open(rec) != 0) { | 893 | if (record__open(rec) != 0) { |
885 | err = -1; | 894 | err = -1; |
886 | goto out_child; | 895 | goto out_child; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 98bf9d32f222..54a4c152edb3 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -917,7 +917,7 @@ static void print_metric_csv(void *ctx, | |||
917 | char buf[64], *vals, *ends; | 917 | char buf[64], *vals, *ends; |
918 | 918 | ||
919 | if (unit == NULL || fmt == NULL) { | 919 | if (unit == NULL || fmt == NULL) { |
920 | fprintf(out, "%s%s%s%s", csv_sep, csv_sep, csv_sep, csv_sep); | 920 | fprintf(out, "%s%s", csv_sep, csv_sep); |
921 | return; | 921 | return; |
922 | } | 922 | } |
923 | snprintf(buf, sizeof(buf), fmt, val); | 923 | snprintf(buf, sizeof(buf), fmt, val); |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b7c823ba8374..35ac016fcb98 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -991,7 +991,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top, | |||
991 | evlist__for_each_entry(evlist, counter) | 991 | evlist__for_each_entry(evlist, counter) |
992 | counter->attr.write_backward = false; | 992 | counter->attr.write_backward = false; |
993 | opts->overwrite = false; | 993 | opts->overwrite = false; |
994 | ui__warning("fall back to non-overwrite mode\n"); | 994 | pr_debug2("fall back to non-overwrite mode\n"); |
995 | return 1; | 995 | return 1; |
996 | } | 996 | } |
997 | 997 | ||
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index cfe46236a5e5..57b9b342d533 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -61,6 +61,7 @@ struct record_opts { | |||
61 | bool tail_synthesize; | 61 | bool tail_synthesize; |
62 | bool overwrite; | 62 | bool overwrite; |
63 | bool ignore_missing_thread; | 63 | bool ignore_missing_thread; |
64 | bool sample_id; | ||
64 | unsigned int freq; | 65 | unsigned int freq; |
65 | unsigned int mmap_pages; | 66 | unsigned int mmap_pages; |
66 | unsigned int auxtrace_mmap_pages; | 67 | unsigned int auxtrace_mmap_pages; |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 286427975112..fbf927cf775d 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -327,7 +327,32 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
327 | if (!disasm_line__is_valid_jump(cursor, sym)) | 327 | if (!disasm_line__is_valid_jump(cursor, sym)) |
328 | return; | 328 | return; |
329 | 329 | ||
330 | /* | ||
331 | * This first was seen with a gcc function, _cpp_lex_token, that | ||
332 | * has the usual jumps: | ||
333 | * | ||
334 | * │1159e6c: ↓ jne 115aa32 <_cpp_lex_token@@Base+0xf92> | ||
335 | * | ||
336 | * I.e. jumps to a label inside that function (_cpp_lex_token), and | ||
337 | * those works, but also this kind: | ||
338 | * | ||
339 | * │1159e8b: ↓ jne c469be <cpp_named_operator2name@@Base+0xa72> | ||
340 | * | ||
341 | * I.e. jumps to another function, outside _cpp_lex_token, which | ||
342 | * are not being correctly handled generating as a side effect references | ||
343 | * to ab->offset[] entries that are set to NULL, so to make this code | ||
344 | * more robust, check that here. | ||
345 | * | ||
346 | * A proper fix for will be put in place, looking at the function | ||
347 | * name right after the '<' token and probably treating this like a | ||
348 | * 'call' instruction. | ||
349 | */ | ||
330 | target = ab->offsets[cursor->ops.target.offset]; | 350 | target = ab->offsets[cursor->ops.target.offset]; |
351 | if (target == NULL) { | ||
352 | ui_helpline__printf("WARN: jump target inconsistency, press 'o', ab->offsets[%#x] = NULL\n", | ||
353 | cursor->ops.target.offset); | ||
354 | return; | ||
355 | } | ||
331 | 356 | ||
332 | bcursor = browser_line(&cursor->al); | 357 | bcursor = browser_line(&cursor->al); |
333 | btarget = browser_line(target); | 358 | btarget = browser_line(target); |
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 9faf3b5367db..6470ea2aa25e 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
@@ -60,6 +60,12 @@ | |||
60 | #include "sane_ctype.h" | 60 | #include "sane_ctype.h" |
61 | #include "symbol/kallsyms.h" | 61 | #include "symbol/kallsyms.h" |
62 | 62 | ||
63 | static bool auxtrace__dont_decode(struct perf_session *session) | ||
64 | { | ||
65 | return !session->itrace_synth_opts || | ||
66 | session->itrace_synth_opts->dont_decode; | ||
67 | } | ||
68 | |||
63 | int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, | 69 | int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, |
64 | struct auxtrace_mmap_params *mp, | 70 | struct auxtrace_mmap_params *mp, |
65 | void *userpg, int fd) | 71 | void *userpg, int fd) |
@@ -762,6 +768,9 @@ int auxtrace_queues__process_index(struct auxtrace_queues *queues, | |||
762 | size_t i; | 768 | size_t i; |
763 | int err; | 769 | int err; |
764 | 770 | ||
771 | if (auxtrace__dont_decode(session)) | ||
772 | return 0; | ||
773 | |||
765 | list_for_each_entry(auxtrace_index, &session->auxtrace_index, list) { | 774 | list_for_each_entry(auxtrace_index, &session->auxtrace_index, list) { |
766 | for (i = 0; i < auxtrace_index->nr; i++) { | 775 | for (i = 0; i < auxtrace_index->nr; i++) { |
767 | ent = &auxtrace_index->entries[i]; | 776 | ent = &auxtrace_index->entries[i]; |
@@ -892,12 +901,6 @@ out_free: | |||
892 | return err; | 901 | return err; |
893 | } | 902 | } |
894 | 903 | ||
895 | static bool auxtrace__dont_decode(struct perf_session *session) | ||
896 | { | ||
897 | return !session->itrace_synth_opts || | ||
898 | session->itrace_synth_opts->dont_decode; | ||
899 | } | ||
900 | |||
901 | int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, | 904 | int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, |
902 | union perf_event *event, | 905 | union perf_event *event, |
903 | struct perf_session *session) | 906 | struct perf_session *session) |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 1e97937b03a9..6f09e4962dad 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
@@ -137,6 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, | |||
137 | struct perf_evsel *evsel; | 137 | struct perf_evsel *evsel; |
138 | bool use_sample_identifier = false; | 138 | bool use_sample_identifier = false; |
139 | bool use_comm_exec; | 139 | bool use_comm_exec; |
140 | bool sample_id = opts->sample_id; | ||
140 | 141 | ||
141 | /* | 142 | /* |
142 | * Set the evsel leader links before we configure attributes, | 143 | * Set the evsel leader links before we configure attributes, |
@@ -163,8 +164,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, | |||
163 | * match the id. | 164 | * match the id. |
164 | */ | 165 | */ |
165 | use_sample_identifier = perf_can_sample_identifier(); | 166 | use_sample_identifier = perf_can_sample_identifier(); |
166 | evlist__for_each_entry(evlist, evsel) | 167 | sample_id = true; |
167 | perf_evsel__set_sample_id(evsel, use_sample_identifier); | ||
168 | } else if (evlist->nr_entries > 1) { | 168 | } else if (evlist->nr_entries > 1) { |
169 | struct perf_evsel *first = perf_evlist__first(evlist); | 169 | struct perf_evsel *first = perf_evlist__first(evlist); |
170 | 170 | ||
@@ -174,6 +174,10 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, | |||
174 | use_sample_identifier = perf_can_sample_identifier(); | 174 | use_sample_identifier = perf_can_sample_identifier(); |
175 | break; | 175 | break; |
176 | } | 176 | } |
177 | sample_id = true; | ||
178 | } | ||
179 | |||
180 | if (sample_id) { | ||
177 | evlist__for_each_entry(evlist, evsel) | 181 | evlist__for_each_entry(evlist, evsel) |
178 | perf_evsel__set_sample_id(evsel, use_sample_identifier); | 182 | perf_evsel__set_sample_id(evsel, use_sample_identifier); |
179 | } | 183 | } |
diff --git a/tools/perf/util/trigger.h b/tools/perf/util/trigger.h index 370138e7e35c..88223bc7c82b 100644 --- a/tools/perf/util/trigger.h +++ b/tools/perf/util/trigger.h | |||
@@ -12,7 +12,7 @@ | |||
12 | * States and transits: | 12 | * States and transits: |
13 | * | 13 | * |
14 | * | 14 | * |
15 | * OFF--(on)--> READY --(hit)--> HIT | 15 | * OFF--> ON --> READY --(hit)--> HIT |
16 | * ^ | | 16 | * ^ | |
17 | * | (ready) | 17 | * | (ready) |
18 | * | | | 18 | * | | |
@@ -27,8 +27,9 @@ struct trigger { | |||
27 | volatile enum { | 27 | volatile enum { |
28 | TRIGGER_ERROR = -2, | 28 | TRIGGER_ERROR = -2, |
29 | TRIGGER_OFF = -1, | 29 | TRIGGER_OFF = -1, |
30 | TRIGGER_READY = 0, | 30 | TRIGGER_ON = 0, |
31 | TRIGGER_HIT = 1, | 31 | TRIGGER_READY = 1, |
32 | TRIGGER_HIT = 2, | ||
32 | } state; | 33 | } state; |
33 | const char *name; | 34 | const char *name; |
34 | }; | 35 | }; |
@@ -50,7 +51,7 @@ static inline bool trigger_is_error(struct trigger *t) | |||
50 | static inline void trigger_on(struct trigger *t) | 51 | static inline void trigger_on(struct trigger *t) |
51 | { | 52 | { |
52 | TRIGGER_WARN_ONCE(t, TRIGGER_OFF); | 53 | TRIGGER_WARN_ONCE(t, TRIGGER_OFF); |
53 | t->state = TRIGGER_READY; | 54 | t->state = TRIGGER_ON; |
54 | } | 55 | } |
55 | 56 | ||
56 | static inline void trigger_ready(struct trigger *t) | 57 | static inline void trigger_ready(struct trigger *t) |
diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index be81621446f0..0b4f1cc2291c 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c | |||
@@ -450,7 +450,7 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void) | |||
450 | num_vsyscall_traps++; | 450 | num_vsyscall_traps++; |
451 | } | 451 | } |
452 | 452 | ||
453 | static int test_native_vsyscall(void) | 453 | static int test_emulation(void) |
454 | { | 454 | { |
455 | time_t tmp; | 455 | time_t tmp; |
456 | bool is_native; | 456 | bool is_native; |
@@ -458,7 +458,7 @@ static int test_native_vsyscall(void) | |||
458 | if (!vtime) | 458 | if (!vtime) |
459 | return 0; | 459 | return 0; |
460 | 460 | ||
461 | printf("[RUN]\tchecking for native vsyscall\n"); | 461 | printf("[RUN]\tchecking that vsyscalls are emulated\n"); |
462 | sethandler(SIGTRAP, sigtrap, 0); | 462 | sethandler(SIGTRAP, sigtrap, 0); |
463 | set_eflags(get_eflags() | X86_EFLAGS_TF); | 463 | set_eflags(get_eflags() | X86_EFLAGS_TF); |
464 | vtime(&tmp); | 464 | vtime(&tmp); |
@@ -474,11 +474,12 @@ static int test_native_vsyscall(void) | |||
474 | */ | 474 | */ |
475 | is_native = (num_vsyscall_traps > 1); | 475 | is_native = (num_vsyscall_traps > 1); |
476 | 476 | ||
477 | printf("\tvsyscalls are %s (%d instructions in vsyscall page)\n", | 477 | printf("[%s]\tvsyscalls are %s (%d instructions in vsyscall page)\n", |
478 | (is_native ? "FAIL" : "OK"), | ||
478 | (is_native ? "native" : "emulated"), | 479 | (is_native ? "native" : "emulated"), |
479 | (int)num_vsyscall_traps); | 480 | (int)num_vsyscall_traps); |
480 | 481 | ||
481 | return 0; | 482 | return is_native; |
482 | } | 483 | } |
483 | #endif | 484 | #endif |
484 | 485 | ||
@@ -498,7 +499,7 @@ int main(int argc, char **argv) | |||
498 | nerrs += test_vsys_r(); | 499 | nerrs += test_vsys_r(); |
499 | 500 | ||
500 | #ifdef __x86_64__ | 501 | #ifdef __x86_64__ |
501 | nerrs += test_native_vsyscall(); | 502 | nerrs += test_emulation(); |
502 | #endif | 503 | #endif |
503 | 504 | ||
504 | return nerrs ? 1 : 0; | 505 | return nerrs ? 1 : 0; |