Annotation of /trunk/kernel-magellan/patches-4.15/0109-4.15.10-all-fixes.patch
Parent Directory | Revision Log
Revision 3093 -
(hide annotations)
(download)
Wed Mar 21 14:52:52 2018 UTC (6 years, 2 months ago) by niro
File size: 211061 byte(s)
Wed Mar 21 14:52:52 2018 UTC (6 years, 2 months ago) by niro
File size: 211061 byte(s)
-linux-4.15.10
1 | niro | 3093 | diff --git a/Documentation/devicetree/bindings/power/mti,mips-cpc.txt b/Documentation/devicetree/bindings/power/mti,mips-cpc.txt |
2 | new file mode 100644 | ||
3 | index 000000000000..c6b82511ae8a | ||
4 | --- /dev/null | ||
5 | +++ b/Documentation/devicetree/bindings/power/mti,mips-cpc.txt | ||
6 | @@ -0,0 +1,8 @@ | ||
7 | +Binding for MIPS Cluster Power Controller (CPC). | ||
8 | + | ||
9 | +This binding allows a system to specify where the CPC registers are | ||
10 | +located. | ||
11 | + | ||
12 | +Required properties: | ||
13 | +compatible : Should be "mti,mips-cpc". | ||
14 | +regs: Should describe the address & size of the CPC register region. | ||
15 | diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py | ||
16 | index 39aa9e8697cc..fbedcc39460b 100644 | ||
17 | --- a/Documentation/sphinx/kerneldoc.py | ||
18 | +++ b/Documentation/sphinx/kerneldoc.py | ||
19 | @@ -36,8 +36,7 @@ import glob | ||
20 | |||
21 | from docutils import nodes, statemachine | ||
22 | from docutils.statemachine import ViewList | ||
23 | -from docutils.parsers.rst import directives | ||
24 | -from sphinx.util.compat import Directive | ||
25 | +from docutils.parsers.rst import directives, Directive | ||
26 | from sphinx.ext.autodoc import AutodocReporter | ||
27 | |||
28 | __version__ = '1.0' | ||
29 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
30 | index 845fc25812f1..8e5d2e5d85bf 100644 | ||
31 | --- a/MAINTAINERS | ||
32 | +++ b/MAINTAINERS | ||
33 | @@ -9107,6 +9107,7 @@ MIPS GENERIC PLATFORM | ||
34 | M: Paul Burton <paul.burton@mips.com> | ||
35 | L: linux-mips@linux-mips.org | ||
36 | S: Supported | ||
37 | +F: Documentation/devicetree/bindings/power/mti,mips-cpc.txt | ||
38 | F: arch/mips/generic/ | ||
39 | F: arch/mips/tools/generic-board-config.sh | ||
40 | |||
41 | diff --git a/Makefile b/Makefile | ||
42 | index 0420f9a0c70f..7eed0f168b13 100644 | ||
43 | --- a/Makefile | ||
44 | +++ b/Makefile | ||
45 | @@ -1,7 +1,7 @@ | ||
46 | # SPDX-License-Identifier: GPL-2.0 | ||
47 | VERSION = 4 | ||
48 | PATCHLEVEL = 15 | ||
49 | -SUBLEVEL = 9 | ||
50 | +SUBLEVEL = 10 | ||
51 | EXTRAVERSION = | ||
52 | NAME = Fearless Coyote | ||
53 | |||
54 | @@ -487,6 +487,11 @@ KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) | ||
55 | KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) | ||
56 | endif | ||
57 | |||
58 | +RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register | ||
59 | +RETPOLINE_CFLAGS_CLANG := -mretpoline-external-thunk | ||
60 | +RETPOLINE_CFLAGS := $(call cc-option,$(RETPOLINE_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_CFLAGS_CLANG))) | ||
61 | +export RETPOLINE_CFLAGS | ||
62 | + | ||
63 | ifeq ($(config-targets),1) | ||
64 | # =========================================================================== | ||
65 | # *config targets only - make sure prerequisites are updated, and descend | ||
66 | diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c | ||
67 | index 451f96f3377c..5bdc2c4db9ad 100644 | ||
68 | --- a/arch/arm64/mm/mmu.c | ||
69 | +++ b/arch/arm64/mm/mmu.c | ||
70 | @@ -107,7 +107,7 @@ static bool pgattr_change_is_safe(u64 old, u64 new) | ||
71 | * The following mapping attributes may be updated in live | ||
72 | * kernel mappings without the need for break-before-make. | ||
73 | */ | ||
74 | - static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE; | ||
75 | + static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG; | ||
76 | |||
77 | /* creating or taking down mappings is always safe */ | ||
78 | if (old == 0 || new == 0) | ||
79 | @@ -117,9 +117,9 @@ static bool pgattr_change_is_safe(u64 old, u64 new) | ||
80 | if ((old | new) & PTE_CONT) | ||
81 | return false; | ||
82 | |||
83 | - /* Transitioning from Global to Non-Global is safe */ | ||
84 | - if (((old ^ new) == PTE_NG) && (new & PTE_NG)) | ||
85 | - return true; | ||
86 | + /* Transitioning from Non-Global to Global is unsafe */ | ||
87 | + if (old & ~new & PTE_NG) | ||
88 | + return false; | ||
89 | |||
90 | return ((old ^ new) & ~mask) == 0; | ||
91 | } | ||
92 | diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c | ||
93 | index 9ab48ff80c1c..6d11ae581ea7 100644 | ||
94 | --- a/arch/mips/ath25/board.c | ||
95 | +++ b/arch/mips/ath25/board.c | ||
96 | @@ -135,6 +135,8 @@ int __init ath25_find_config(phys_addr_t base, unsigned long size) | ||
97 | } | ||
98 | |||
99 | board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL); | ||
100 | + if (!board_data) | ||
101 | + goto error; | ||
102 | ath25_board.config = (struct ath25_boarddata *)board_data; | ||
103 | memcpy_fromio(board_data, bcfg, 0x100); | ||
104 | if (broken_boarddata) { | ||
105 | diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c | ||
106 | index 5b3a3f6a9ad3..d99f5242169e 100644 | ||
107 | --- a/arch/mips/cavium-octeon/octeon-irq.c | ||
108 | +++ b/arch/mips/cavium-octeon/octeon-irq.c | ||
109 | @@ -2277,6 +2277,8 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, | ||
110 | } | ||
111 | |||
112 | host_data = kzalloc(sizeof(*host_data), GFP_KERNEL); | ||
113 | + if (!host_data) | ||
114 | + return -ENOMEM; | ||
115 | raw_spin_lock_init(&host_data->lock); | ||
116 | |||
117 | addr = of_get_address(ciu_node, 0, NULL, NULL); | ||
118 | diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c | ||
119 | index 19c88d770054..fcf9af492d60 100644 | ||
120 | --- a/arch/mips/kernel/mips-cpc.c | ||
121 | +++ b/arch/mips/kernel/mips-cpc.c | ||
122 | @@ -10,6 +10,8 @@ | ||
123 | |||
124 | #include <linux/errno.h> | ||
125 | #include <linux/percpu.h> | ||
126 | +#include <linux/of.h> | ||
127 | +#include <linux/of_address.h> | ||
128 | #include <linux/spinlock.h> | ||
129 | |||
130 | #include <asm/mips-cps.h> | ||
131 | @@ -22,6 +24,17 @@ static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); | ||
132 | |||
133 | phys_addr_t __weak mips_cpc_default_phys_base(void) | ||
134 | { | ||
135 | + struct device_node *cpc_node; | ||
136 | + struct resource res; | ||
137 | + int err; | ||
138 | + | ||
139 | + cpc_node = of_find_compatible_node(of_root, NULL, "mti,mips-cpc"); | ||
140 | + if (cpc_node) { | ||
141 | + err = of_address_to_resource(cpc_node, 0, &res); | ||
142 | + if (!err) | ||
143 | + return res.start; | ||
144 | + } | ||
145 | + | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c | ||
150 | index 87dcac2447c8..382d12eb88f0 100644 | ||
151 | --- a/arch/mips/kernel/smp-bmips.c | ||
152 | +++ b/arch/mips/kernel/smp-bmips.c | ||
153 | @@ -168,11 +168,11 @@ static void bmips_prepare_cpus(unsigned int max_cpus) | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | - if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, | ||
158 | - "smp_ipi0", NULL)) | ||
159 | + if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, | ||
160 | + IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi0", NULL)) | ||
161 | panic("Can't request IPI0 interrupt"); | ||
162 | - if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, | ||
163 | - "smp_ipi1", NULL)) | ||
164 | + if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, | ||
165 | + IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi1", NULL)) | ||
166 | panic("Can't request IPI1 interrupt"); | ||
167 | } | ||
168 | |||
169 | diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c | ||
170 | index 5c03e371b7b8..004684eaa827 100644 | ||
171 | --- a/arch/s390/kvm/kvm-s390.c | ||
172 | +++ b/arch/s390/kvm/kvm-s390.c | ||
173 | @@ -2118,6 +2118,7 @@ static void sca_add_vcpu(struct kvm_vcpu *vcpu) | ||
174 | /* we still need the basic sca for the ipte control */ | ||
175 | vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32); | ||
176 | vcpu->arch.sie_block->scaol = (__u32)(__u64)sca; | ||
177 | + return; | ||
178 | } | ||
179 | read_lock(&vcpu->kvm->arch.sca_lock); | ||
180 | if (vcpu->kvm->arch.use_esca) { | ||
181 | diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig | ||
182 | index 20da391b5f32..7bb4eb14a2e0 100644 | ||
183 | --- a/arch/x86/Kconfig | ||
184 | +++ b/arch/x86/Kconfig | ||
185 | @@ -432,6 +432,7 @@ config GOLDFISH | ||
186 | config RETPOLINE | ||
187 | bool "Avoid speculative indirect branches in kernel" | ||
188 | default y | ||
189 | + select STACK_VALIDATION if HAVE_STACK_VALIDATION | ||
190 | help | ||
191 | Compile kernel with the retpoline compiler options to guard against | ||
192 | kernel-to-user data leaks by avoiding speculative indirect | ||
193 | diff --git a/arch/x86/Makefile b/arch/x86/Makefile | ||
194 | index fad55160dcb9..498c1b812300 100644 | ||
195 | --- a/arch/x86/Makefile | ||
196 | +++ b/arch/x86/Makefile | ||
197 | @@ -232,10 +232,9 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables | ||
198 | |||
199 | # Avoid indirect branches in kernel to deal with Spectre | ||
200 | ifdef CONFIG_RETPOLINE | ||
201 | - RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) | ||
202 | - ifneq ($(RETPOLINE_CFLAGS),) | ||
203 | - KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE | ||
204 | - endif | ||
205 | +ifneq ($(RETPOLINE_CFLAGS),) | ||
206 | + KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE | ||
207 | +endif | ||
208 | endif | ||
209 | |||
210 | archscripts: scripts_basic | ||
211 | diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h | ||
212 | index dce7092ab24a..5d10b7a85cad 100644 | ||
213 | --- a/arch/x86/entry/calling.h | ||
214 | +++ b/arch/x86/entry/calling.h | ||
215 | @@ -97,7 +97,7 @@ For 32-bit we have the following conventions - kernel is built with | ||
216 | |||
217 | #define SIZEOF_PTREGS 21*8 | ||
218 | |||
219 | -.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax | ||
220 | +.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0 | ||
221 | /* | ||
222 | * Push registers and sanitize registers of values that a | ||
223 | * speculation attack might otherwise want to exploit. The | ||
224 | @@ -105,32 +105,41 @@ For 32-bit we have the following conventions - kernel is built with | ||
225 | * could be put to use in a speculative execution gadget. | ||
226 | * Interleave XOR with PUSH for better uop scheduling: | ||
227 | */ | ||
228 | + .if \save_ret | ||
229 | + pushq %rsi /* pt_regs->si */ | ||
230 | + movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */ | ||
231 | + movq %rdi, 8(%rsp) /* pt_regs->di (overwriting original return address) */ | ||
232 | + .else | ||
233 | pushq %rdi /* pt_regs->di */ | ||
234 | pushq %rsi /* pt_regs->si */ | ||
235 | + .endif | ||
236 | pushq \rdx /* pt_regs->dx */ | ||
237 | pushq %rcx /* pt_regs->cx */ | ||
238 | pushq \rax /* pt_regs->ax */ | ||
239 | pushq %r8 /* pt_regs->r8 */ | ||
240 | - xorq %r8, %r8 /* nospec r8 */ | ||
241 | + xorl %r8d, %r8d /* nospec r8 */ | ||
242 | pushq %r9 /* pt_regs->r9 */ | ||
243 | - xorq %r9, %r9 /* nospec r9 */ | ||
244 | + xorl %r9d, %r9d /* nospec r9 */ | ||
245 | pushq %r10 /* pt_regs->r10 */ | ||
246 | - xorq %r10, %r10 /* nospec r10 */ | ||
247 | + xorl %r10d, %r10d /* nospec r10 */ | ||
248 | pushq %r11 /* pt_regs->r11 */ | ||
249 | - xorq %r11, %r11 /* nospec r11*/ | ||
250 | + xorl %r11d, %r11d /* nospec r11*/ | ||
251 | pushq %rbx /* pt_regs->rbx */ | ||
252 | xorl %ebx, %ebx /* nospec rbx*/ | ||
253 | pushq %rbp /* pt_regs->rbp */ | ||
254 | xorl %ebp, %ebp /* nospec rbp*/ | ||
255 | pushq %r12 /* pt_regs->r12 */ | ||
256 | - xorq %r12, %r12 /* nospec r12*/ | ||
257 | + xorl %r12d, %r12d /* nospec r12*/ | ||
258 | pushq %r13 /* pt_regs->r13 */ | ||
259 | - xorq %r13, %r13 /* nospec r13*/ | ||
260 | + xorl %r13d, %r13d /* nospec r13*/ | ||
261 | pushq %r14 /* pt_regs->r14 */ | ||
262 | - xorq %r14, %r14 /* nospec r14*/ | ||
263 | + xorl %r14d, %r14d /* nospec r14*/ | ||
264 | pushq %r15 /* pt_regs->r15 */ | ||
265 | - xorq %r15, %r15 /* nospec r15*/ | ||
266 | + xorl %r15d, %r15d /* nospec r15*/ | ||
267 | UNWIND_HINT_REGS | ||
268 | + .if \save_ret | ||
269 | + pushq %rsi /* return address on top of stack */ | ||
270 | + .endif | ||
271 | .endm | ||
272 | |||
273 | .macro POP_REGS pop_rdi=1 skip_r11rcx=0 | ||
274 | diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S | ||
275 | index 2a35b1e0fb90..60c4c342316c 100644 | ||
276 | --- a/arch/x86/entry/entry_32.S | ||
277 | +++ b/arch/x86/entry/entry_32.S | ||
278 | @@ -252,8 +252,7 @@ ENTRY(__switch_to_asm) | ||
279 | * exist, overwrite the RSB with entries which capture | ||
280 | * speculative execution to prevent attack. | ||
281 | */ | ||
282 | - /* Clobbers %ebx */ | ||
283 | - FILL_RETURN_BUFFER RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW | ||
284 | + FILL_RETURN_BUFFER %ebx, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW | ||
285 | #endif | ||
286 | |||
287 | /* restore callee-saved registers */ | ||
288 | diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S | ||
289 | index 4fd9044e72e7..50dcbf640850 100644 | ||
290 | --- a/arch/x86/entry/entry_64.S | ||
291 | +++ b/arch/x86/entry/entry_64.S | ||
292 | @@ -364,8 +364,7 @@ ENTRY(__switch_to_asm) | ||
293 | * exist, overwrite the RSB with entries which capture | ||
294 | * speculative execution to prevent attack. | ||
295 | */ | ||
296 | - /* Clobbers %rbx */ | ||
297 | - FILL_RETURN_BUFFER RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW | ||
298 | + FILL_RETURN_BUFFER %r12, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW | ||
299 | #endif | ||
300 | |||
301 | /* restore callee-saved registers */ | ||
302 | @@ -871,12 +870,8 @@ ENTRY(\sym) | ||
303 | pushq $-1 /* ORIG_RAX: no syscall to restart */ | ||
304 | .endif | ||
305 | |||
306 | - /* Save all registers in pt_regs */ | ||
307 | - PUSH_AND_CLEAR_REGS | ||
308 | - ENCODE_FRAME_POINTER | ||
309 | - | ||
310 | .if \paranoid < 2 | ||
311 | - testb $3, CS(%rsp) /* If coming from userspace, switch stacks */ | ||
312 | + testb $3, CS-ORIG_RAX(%rsp) /* If coming from userspace, switch stacks */ | ||
313 | jnz .Lfrom_usermode_switch_stack_\@ | ||
314 | .endif | ||
315 | |||
316 | @@ -1123,13 +1118,15 @@ idtentry machine_check do_mce has_error_code=0 paranoid=1 | ||
317 | #endif | ||
318 | |||
319 | /* | ||
320 | - * Switch gs if needed. | ||
321 | + * Save all registers in pt_regs, and switch gs if needed. | ||
322 | * Use slow, but surefire "are we in kernel?" check. | ||
323 | * Return: ebx=0: need swapgs on exit, ebx=1: otherwise | ||
324 | */ | ||
325 | ENTRY(paranoid_entry) | ||
326 | UNWIND_HINT_FUNC | ||
327 | cld | ||
328 | + PUSH_AND_CLEAR_REGS save_ret=1 | ||
329 | + ENCODE_FRAME_POINTER 8 | ||
330 | movl $1, %ebx | ||
331 | movl $MSR_GS_BASE, %ecx | ||
332 | rdmsr | ||
333 | @@ -1174,12 +1171,14 @@ ENTRY(paranoid_exit) | ||
334 | END(paranoid_exit) | ||
335 | |||
336 | /* | ||
337 | - * Switch gs if needed. | ||
338 | + * Save all registers in pt_regs, and switch GS if needed. | ||
339 | * Return: EBX=0: came from user mode; EBX=1: otherwise | ||
340 | */ | ||
341 | ENTRY(error_entry) | ||
342 | - UNWIND_HINT_REGS offset=8 | ||
343 | + UNWIND_HINT_FUNC | ||
344 | cld | ||
345 | + PUSH_AND_CLEAR_REGS save_ret=1 | ||
346 | + ENCODE_FRAME_POINTER 8 | ||
347 | testb $3, CS+8(%rsp) | ||
348 | jz .Lerror_kernelspace | ||
349 | |||
350 | @@ -1570,8 +1569,6 @@ end_repeat_nmi: | ||
351 | * frame to point back to repeat_nmi. | ||
352 | */ | ||
353 | pushq $-1 /* ORIG_RAX: no syscall to restart */ | ||
354 | - PUSH_AND_CLEAR_REGS | ||
355 | - ENCODE_FRAME_POINTER | ||
356 | |||
357 | /* | ||
358 | * Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit | ||
359 | diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S | ||
360 | index fd65e016e413..364ea4a207be 100644 | ||
361 | --- a/arch/x86/entry/entry_64_compat.S | ||
362 | +++ b/arch/x86/entry/entry_64_compat.S | ||
363 | @@ -85,25 +85,25 @@ ENTRY(entry_SYSENTER_compat) | ||
364 | pushq %rcx /* pt_regs->cx */ | ||
365 | pushq $-ENOSYS /* pt_regs->ax */ | ||
366 | pushq $0 /* pt_regs->r8 = 0 */ | ||
367 | - xorq %r8, %r8 /* nospec r8 */ | ||
368 | + xorl %r8d, %r8d /* nospec r8 */ | ||
369 | pushq $0 /* pt_regs->r9 = 0 */ | ||
370 | - xorq %r9, %r9 /* nospec r9 */ | ||
371 | + xorl %r9d, %r9d /* nospec r9 */ | ||
372 | pushq $0 /* pt_regs->r10 = 0 */ | ||
373 | - xorq %r10, %r10 /* nospec r10 */ | ||
374 | + xorl %r10d, %r10d /* nospec r10 */ | ||
375 | pushq $0 /* pt_regs->r11 = 0 */ | ||
376 | - xorq %r11, %r11 /* nospec r11 */ | ||
377 | + xorl %r11d, %r11d /* nospec r11 */ | ||
378 | pushq %rbx /* pt_regs->rbx */ | ||
379 | xorl %ebx, %ebx /* nospec rbx */ | ||
380 | pushq %rbp /* pt_regs->rbp (will be overwritten) */ | ||
381 | xorl %ebp, %ebp /* nospec rbp */ | ||
382 | pushq $0 /* pt_regs->r12 = 0 */ | ||
383 | - xorq %r12, %r12 /* nospec r12 */ | ||
384 | + xorl %r12d, %r12d /* nospec r12 */ | ||
385 | pushq $0 /* pt_regs->r13 = 0 */ | ||
386 | - xorq %r13, %r13 /* nospec r13 */ | ||
387 | + xorl %r13d, %r13d /* nospec r13 */ | ||
388 | pushq $0 /* pt_regs->r14 = 0 */ | ||
389 | - xorq %r14, %r14 /* nospec r14 */ | ||
390 | + xorl %r14d, %r14d /* nospec r14 */ | ||
391 | pushq $0 /* pt_regs->r15 = 0 */ | ||
392 | - xorq %r15, %r15 /* nospec r15 */ | ||
393 | + xorl %r15d, %r15d /* nospec r15 */ | ||
394 | cld | ||
395 | |||
396 | /* | ||
397 | @@ -224,25 +224,25 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) | ||
398 | pushq %rbp /* pt_regs->cx (stashed in bp) */ | ||
399 | pushq $-ENOSYS /* pt_regs->ax */ | ||
400 | pushq $0 /* pt_regs->r8 = 0 */ | ||
401 | - xorq %r8, %r8 /* nospec r8 */ | ||
402 | + xorl %r8d, %r8d /* nospec r8 */ | ||
403 | pushq $0 /* pt_regs->r9 = 0 */ | ||
404 | - xorq %r9, %r9 /* nospec r9 */ | ||
405 | + xorl %r9d, %r9d /* nospec r9 */ | ||
406 | pushq $0 /* pt_regs->r10 = 0 */ | ||
407 | - xorq %r10, %r10 /* nospec r10 */ | ||
408 | + xorl %r10d, %r10d /* nospec r10 */ | ||
409 | pushq $0 /* pt_regs->r11 = 0 */ | ||
410 | - xorq %r11, %r11 /* nospec r11 */ | ||
411 | + xorl %r11d, %r11d /* nospec r11 */ | ||
412 | pushq %rbx /* pt_regs->rbx */ | ||
413 | xorl %ebx, %ebx /* nospec rbx */ | ||
414 | pushq %rbp /* pt_regs->rbp (will be overwritten) */ | ||
415 | xorl %ebp, %ebp /* nospec rbp */ | ||
416 | pushq $0 /* pt_regs->r12 = 0 */ | ||
417 | - xorq %r12, %r12 /* nospec r12 */ | ||
418 | + xorl %r12d, %r12d /* nospec r12 */ | ||
419 | pushq $0 /* pt_regs->r13 = 0 */ | ||
420 | - xorq %r13, %r13 /* nospec r13 */ | ||
421 | + xorl %r13d, %r13d /* nospec r13 */ | ||
422 | pushq $0 /* pt_regs->r14 = 0 */ | ||
423 | - xorq %r14, %r14 /* nospec r14 */ | ||
424 | + xorl %r14d, %r14d /* nospec r14 */ | ||
425 | pushq $0 /* pt_regs->r15 = 0 */ | ||
426 | - xorq %r15, %r15 /* nospec r15 */ | ||
427 | + xorl %r15d, %r15d /* nospec r15 */ | ||
428 | |||
429 | /* | ||
430 | * User mode is traced as though IRQs are on, and SYSENTER | ||
431 | @@ -298,9 +298,9 @@ sysret32_from_system_call: | ||
432 | */ | ||
433 | SWITCH_TO_USER_CR3_NOSTACK scratch_reg=%r8 scratch_reg2=%r9 | ||
434 | |||
435 | - xorq %r8, %r8 | ||
436 | - xorq %r9, %r9 | ||
437 | - xorq %r10, %r10 | ||
438 | + xorl %r8d, %r8d | ||
439 | + xorl %r9d, %r9d | ||
440 | + xorl %r10d, %r10d | ||
441 | swapgs | ||
442 | sysretl | ||
443 | END(entry_SYSCALL_compat) | ||
444 | @@ -358,25 +358,25 @@ ENTRY(entry_INT80_compat) | ||
445 | pushq %rcx /* pt_regs->cx */ | ||
446 | pushq $-ENOSYS /* pt_regs->ax */ | ||
447 | pushq $0 /* pt_regs->r8 = 0 */ | ||
448 | - xorq %r8, %r8 /* nospec r8 */ | ||
449 | + xorl %r8d, %r8d /* nospec r8 */ | ||
450 | pushq $0 /* pt_regs->r9 = 0 */ | ||
451 | - xorq %r9, %r9 /* nospec r9 */ | ||
452 | + xorl %r9d, %r9d /* nospec r9 */ | ||
453 | pushq $0 /* pt_regs->r10 = 0 */ | ||
454 | - xorq %r10, %r10 /* nospec r10 */ | ||
455 | + xorl %r10d, %r10d /* nospec r10 */ | ||
456 | pushq $0 /* pt_regs->r11 = 0 */ | ||
457 | - xorq %r11, %r11 /* nospec r11 */ | ||
458 | + xorl %r11d, %r11d /* nospec r11 */ | ||
459 | pushq %rbx /* pt_regs->rbx */ | ||
460 | xorl %ebx, %ebx /* nospec rbx */ | ||
461 | pushq %rbp /* pt_regs->rbp */ | ||
462 | xorl %ebp, %ebp /* nospec rbp */ | ||
463 | pushq %r12 /* pt_regs->r12 */ | ||
464 | - xorq %r12, %r12 /* nospec r12 */ | ||
465 | + xorl %r12d, %r12d /* nospec r12 */ | ||
466 | pushq %r13 /* pt_regs->r13 */ | ||
467 | - xorq %r13, %r13 /* nospec r13 */ | ||
468 | + xorl %r13d, %r13d /* nospec r13 */ | ||
469 | pushq %r14 /* pt_regs->r14 */ | ||
470 | - xorq %r14, %r14 /* nospec r14 */ | ||
471 | + xorl %r14d, %r14d /* nospec r14 */ | ||
472 | pushq %r15 /* pt_regs->r15 */ | ||
473 | - xorq %r15, %r15 /* nospec r15 */ | ||
474 | + xorl %r15d, %r15d /* nospec r15 */ | ||
475 | cld | ||
476 | |||
477 | /* | ||
478 | diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h | ||
479 | index 4d4015ddcf26..c356098b6fb9 100644 | ||
480 | --- a/arch/x86/include/asm/apm.h | ||
481 | +++ b/arch/x86/include/asm/apm.h | ||
482 | @@ -7,6 +7,8 @@ | ||
483 | #ifndef _ASM_X86_MACH_DEFAULT_APM_H | ||
484 | #define _ASM_X86_MACH_DEFAULT_APM_H | ||
485 | |||
486 | +#include <asm/nospec-branch.h> | ||
487 | + | ||
488 | #ifdef APM_ZERO_SEGS | ||
489 | # define APM_DO_ZERO_SEGS \ | ||
490 | "pushl %%ds\n\t" \ | ||
491 | @@ -32,6 +34,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in, | ||
492 | * N.B. We do NOT need a cld after the BIOS call | ||
493 | * because we always save and restore the flags. | ||
494 | */ | ||
495 | + firmware_restrict_branch_speculation_start(); | ||
496 | __asm__ __volatile__(APM_DO_ZERO_SEGS | ||
497 | "pushl %%edi\n\t" | ||
498 | "pushl %%ebp\n\t" | ||
499 | @@ -44,6 +47,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in, | ||
500 | "=S" (*esi) | ||
501 | : "a" (func), "b" (ebx_in), "c" (ecx_in) | ||
502 | : "memory", "cc"); | ||
503 | + firmware_restrict_branch_speculation_end(); | ||
504 | } | ||
505 | |||
506 | static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in, | ||
507 | @@ -56,6 +60,7 @@ static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in, | ||
508 | * N.B. We do NOT need a cld after the BIOS call | ||
509 | * because we always save and restore the flags. | ||
510 | */ | ||
511 | + firmware_restrict_branch_speculation_start(); | ||
512 | __asm__ __volatile__(APM_DO_ZERO_SEGS | ||
513 | "pushl %%edi\n\t" | ||
514 | "pushl %%ebp\n\t" | ||
515 | @@ -68,6 +73,7 @@ static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in, | ||
516 | "=S" (si) | ||
517 | : "a" (func), "b" (ebx_in), "c" (ecx_in) | ||
518 | : "memory", "cc"); | ||
519 | + firmware_restrict_branch_speculation_end(); | ||
520 | return error; | ||
521 | } | ||
522 | |||
523 | diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h | ||
524 | index 4d111616524b..1908214b9125 100644 | ||
525 | --- a/arch/x86/include/asm/asm-prototypes.h | ||
526 | +++ b/arch/x86/include/asm/asm-prototypes.h | ||
527 | @@ -38,7 +38,4 @@ INDIRECT_THUNK(dx) | ||
528 | INDIRECT_THUNK(si) | ||
529 | INDIRECT_THUNK(di) | ||
530 | INDIRECT_THUNK(bp) | ||
531 | -asmlinkage void __fill_rsb(void); | ||
532 | -asmlinkage void __clear_rsb(void); | ||
533 | - | ||
534 | #endif /* CONFIG_RETPOLINE */ | ||
535 | diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h | ||
536 | index 73b5fff159a4..66c14347c502 100644 | ||
537 | --- a/arch/x86/include/asm/cpufeatures.h | ||
538 | +++ b/arch/x86/include/asm/cpufeatures.h | ||
539 | @@ -211,6 +211,7 @@ | ||
540 | #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ | ||
541 | |||
542 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ | ||
543 | +#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ | ||
544 | |||
545 | /* Virtualization flags: Linux defined, word 8 */ | ||
546 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | ||
547 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h | ||
548 | index 85f6ccb80b91..a399c1ebf6f0 100644 | ||
549 | --- a/arch/x86/include/asm/efi.h | ||
550 | +++ b/arch/x86/include/asm/efi.h | ||
551 | @@ -6,6 +6,7 @@ | ||
552 | #include <asm/pgtable.h> | ||
553 | #include <asm/processor-flags.h> | ||
554 | #include <asm/tlb.h> | ||
555 | +#include <asm/nospec-branch.h> | ||
556 | |||
557 | /* | ||
558 | * We map the EFI regions needed for runtime services non-contiguously, | ||
559 | @@ -36,8 +37,18 @@ | ||
560 | |||
561 | extern asmlinkage unsigned long efi_call_phys(void *, ...); | ||
562 | |||
563 | -#define arch_efi_call_virt_setup() kernel_fpu_begin() | ||
564 | -#define arch_efi_call_virt_teardown() kernel_fpu_end() | ||
565 | +#define arch_efi_call_virt_setup() \ | ||
566 | +({ \ | ||
567 | + kernel_fpu_begin(); \ | ||
568 | + firmware_restrict_branch_speculation_start(); \ | ||
569 | +}) | ||
570 | + | ||
571 | +#define arch_efi_call_virt_teardown() \ | ||
572 | +({ \ | ||
573 | + firmware_restrict_branch_speculation_end(); \ | ||
574 | + kernel_fpu_end(); \ | ||
575 | +}) | ||
576 | + | ||
577 | |||
578 | /* | ||
579 | * Wrap all the virtual calls in a way that forces the parameters on the stack. | ||
580 | @@ -73,6 +84,7 @@ struct efi_scratch { | ||
581 | efi_sync_low_kernel_mappings(); \ | ||
582 | preempt_disable(); \ | ||
583 | __kernel_fpu_begin(); \ | ||
584 | + firmware_restrict_branch_speculation_start(); \ | ||
585 | \ | ||
586 | if (efi_scratch.use_pgd) { \ | ||
587 | efi_scratch.prev_cr3 = __read_cr3(); \ | ||
588 | @@ -91,6 +103,7 @@ struct efi_scratch { | ||
589 | __flush_tlb_all(); \ | ||
590 | } \ | ||
591 | \ | ||
592 | + firmware_restrict_branch_speculation_end(); \ | ||
593 | __kernel_fpu_end(); \ | ||
594 | preempt_enable(); \ | ||
595 | }) | ||
596 | diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h | ||
597 | index c931b88982a0..1de72ce514cd 100644 | ||
598 | --- a/arch/x86/include/asm/mmu_context.h | ||
599 | +++ b/arch/x86/include/asm/mmu_context.h | ||
600 | @@ -74,6 +74,7 @@ static inline void *ldt_slot_va(int slot) | ||
601 | return (void *)(LDT_BASE_ADDR + LDT_SLOT_STRIDE * slot); | ||
602 | #else | ||
603 | BUG(); | ||
604 | + return (void *)fix_to_virt(FIX_HOLE); | ||
605 | #endif | ||
606 | } | ||
607 | |||
608 | diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h | ||
609 | index 81a1be326571..d0dabeae0505 100644 | ||
610 | --- a/arch/x86/include/asm/nospec-branch.h | ||
611 | +++ b/arch/x86/include/asm/nospec-branch.h | ||
612 | @@ -8,6 +8,50 @@ | ||
613 | #include <asm/cpufeatures.h> | ||
614 | #include <asm/msr-index.h> | ||
615 | |||
616 | +/* | ||
617 | + * Fill the CPU return stack buffer. | ||
618 | + * | ||
619 | + * Each entry in the RSB, if used for a speculative 'ret', contains an | ||
620 | + * infinite 'pause; lfence; jmp' loop to capture speculative execution. | ||
621 | + * | ||
622 | + * This is required in various cases for retpoline and IBRS-based | ||
623 | + * mitigations for the Spectre variant 2 vulnerability. Sometimes to | ||
624 | + * eliminate potentially bogus entries from the RSB, and sometimes | ||
625 | + * purely to ensure that it doesn't get empty, which on some CPUs would | ||
626 | + * allow predictions from other (unwanted!) sources to be used. | ||
627 | + * | ||
628 | + * We define a CPP macro such that it can be used from both .S files and | ||
629 | + * inline assembly. It's possible to do a .macro and then include that | ||
630 | + * from C via asm(".include <asm/nospec-branch.h>") but let's not go there. | ||
631 | + */ | ||
632 | + | ||
633 | +#define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ | ||
634 | +#define RSB_FILL_LOOPS 16 /* To avoid underflow */ | ||
635 | + | ||
636 | +/* | ||
637 | + * Google experimented with loop-unrolling and this turned out to be | ||
638 | + * the optimal version — two calls, each with their own speculation | ||
639 | + * trap should their return address end up getting used, in a loop. | ||
640 | + */ | ||
641 | +#define __FILL_RETURN_BUFFER(reg, nr, sp) \ | ||
642 | + mov $(nr/2), reg; \ | ||
643 | +771: \ | ||
644 | + call 772f; \ | ||
645 | +773: /* speculation trap */ \ | ||
646 | + pause; \ | ||
647 | + lfence; \ | ||
648 | + jmp 773b; \ | ||
649 | +772: \ | ||
650 | + call 774f; \ | ||
651 | +775: /* speculation trap */ \ | ||
652 | + pause; \ | ||
653 | + lfence; \ | ||
654 | + jmp 775b; \ | ||
655 | +774: \ | ||
656 | + dec reg; \ | ||
657 | + jnz 771b; \ | ||
658 | + add $(BITS_PER_LONG/8) * nr, sp; | ||
659 | + | ||
660 | #ifdef __ASSEMBLY__ | ||
661 | |||
662 | /* | ||
663 | @@ -23,6 +67,18 @@ | ||
664 | .popsection | ||
665 | .endm | ||
666 | |||
667 | +/* | ||
668 | + * This should be used immediately before an indirect jump/call. It tells | ||
669 | + * objtool the subsequent indirect jump/call is vouched safe for retpoline | ||
670 | + * builds. | ||
671 | + */ | ||
672 | +.macro ANNOTATE_RETPOLINE_SAFE | ||
673 | + .Lannotate_\@: | ||
674 | + .pushsection .discard.retpoline_safe | ||
675 | + _ASM_PTR .Lannotate_\@ | ||
676 | + .popsection | ||
677 | +.endm | ||
678 | + | ||
679 | /* | ||
680 | * These are the bare retpoline primitives for indirect jmp and call. | ||
681 | * Do not use these directly; they only exist to make the ALTERNATIVE | ||
682 | @@ -59,9 +115,9 @@ | ||
683 | .macro JMP_NOSPEC reg:req | ||
684 | #ifdef CONFIG_RETPOLINE | ||
685 | ANNOTATE_NOSPEC_ALTERNATIVE | ||
686 | - ALTERNATIVE_2 __stringify(jmp *\reg), \ | ||
687 | + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg), \ | ||
688 | __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \ | ||
689 | - __stringify(lfence; jmp *\reg), X86_FEATURE_RETPOLINE_AMD | ||
690 | + __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD | ||
691 | #else | ||
692 | jmp *\reg | ||
693 | #endif | ||
694 | @@ -70,18 +126,25 @@ | ||
695 | .macro CALL_NOSPEC reg:req | ||
696 | #ifdef CONFIG_RETPOLINE | ||
697 | ANNOTATE_NOSPEC_ALTERNATIVE | ||
698 | - ALTERNATIVE_2 __stringify(call *\reg), \ | ||
699 | + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg), \ | ||
700 | __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ | ||
701 | - __stringify(lfence; call *\reg), X86_FEATURE_RETPOLINE_AMD | ||
702 | + __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD | ||
703 | #else | ||
704 | call *\reg | ||
705 | #endif | ||
706 | .endm | ||
707 | |||
708 | -/* This clobbers the BX register */ | ||
709 | -.macro FILL_RETURN_BUFFER nr:req ftr:req | ||
710 | + /* | ||
711 | + * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP | ||
712 | + * monstrosity above, manually. | ||
713 | + */ | ||
714 | +.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req | ||
715 | #ifdef CONFIG_RETPOLINE | ||
716 | - ALTERNATIVE "", "call __clear_rsb", \ftr | ||
717 | + ANNOTATE_NOSPEC_ALTERNATIVE | ||
718 | + ALTERNATIVE "jmp .Lskip_rsb_\@", \ | ||
719 | + __stringify(__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)) \ | ||
720 | + \ftr | ||
721 | +.Lskip_rsb_\@: | ||
722 | #endif | ||
723 | .endm | ||
724 | |||
725 | @@ -93,6 +156,12 @@ | ||
726 | ".long 999b - .\n\t" \ | ||
727 | ".popsection\n\t" | ||
728 | |||
729 | +#define ANNOTATE_RETPOLINE_SAFE \ | ||
730 | + "999:\n\t" \ | ||
731 | + ".pushsection .discard.retpoline_safe\n\t" \ | ||
732 | + _ASM_PTR " 999b\n\t" \ | ||
733 | + ".popsection\n\t" | ||
734 | + | ||
735 | #if defined(CONFIG_X86_64) && defined(RETPOLINE) | ||
736 | |||
737 | /* | ||
738 | @@ -102,6 +171,7 @@ | ||
739 | # define CALL_NOSPEC \ | ||
740 | ANNOTATE_NOSPEC_ALTERNATIVE \ | ||
741 | ALTERNATIVE( \ | ||
742 | + ANNOTATE_RETPOLINE_SAFE \ | ||
743 | "call *%[thunk_target]\n", \ | ||
744 | "call __x86_indirect_thunk_%V[thunk_target]\n", \ | ||
745 | X86_FEATURE_RETPOLINE) | ||
746 | @@ -156,26 +226,54 @@ extern char __indirect_thunk_end[]; | ||
747 | static inline void vmexit_fill_RSB(void) | ||
748 | { | ||
749 | #ifdef CONFIG_RETPOLINE | ||
750 | - alternative_input("", | ||
751 | - "call __fill_rsb", | ||
752 | - X86_FEATURE_RETPOLINE, | ||
753 | - ASM_NO_INPUT_CLOBBER(_ASM_BX, "memory")); | ||
754 | + unsigned long loops; | ||
755 | + | ||
756 | + asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE | ||
757 | + ALTERNATIVE("jmp 910f", | ||
758 | + __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)), | ||
759 | + X86_FEATURE_RETPOLINE) | ||
760 | + "910:" | ||
761 | + : "=r" (loops), ASM_CALL_CONSTRAINT | ||
762 | + : : "memory" ); | ||
763 | #endif | ||
764 | } | ||
765 | |||
766 | +#define alternative_msr_write(_msr, _val, _feature) \ | ||
767 | + asm volatile(ALTERNATIVE("", \ | ||
768 | + "movl %[msr], %%ecx\n\t" \ | ||
769 | + "movl %[val], %%eax\n\t" \ | ||
770 | + "movl $0, %%edx\n\t" \ | ||
771 | + "wrmsr", \ | ||
772 | + _feature) \ | ||
773 | + : : [msr] "i" (_msr), [val] "i" (_val) \ | ||
774 | + : "eax", "ecx", "edx", "memory") | ||
775 | + | ||
776 | static inline void indirect_branch_prediction_barrier(void) | ||
777 | { | ||
778 | - asm volatile(ALTERNATIVE("", | ||
779 | - "movl %[msr], %%ecx\n\t" | ||
780 | - "movl %[val], %%eax\n\t" | ||
781 | - "movl $0, %%edx\n\t" | ||
782 | - "wrmsr", | ||
783 | - X86_FEATURE_USE_IBPB) | ||
784 | - : : [msr] "i" (MSR_IA32_PRED_CMD), | ||
785 | - [val] "i" (PRED_CMD_IBPB) | ||
786 | - : "eax", "ecx", "edx", "memory"); | ||
787 | + alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, | ||
788 | + X86_FEATURE_USE_IBPB); | ||
789 | } | ||
790 | |||
791 | +/* | ||
792 | + * With retpoline, we must use IBRS to restrict branch prediction | ||
793 | + * before calling into firmware. | ||
794 | + * | ||
795 | + * (Implemented as CPP macros due to header hell.) | ||
796 | + */ | ||
797 | +#define firmware_restrict_branch_speculation_start() \ | ||
798 | +do { \ | ||
799 | + preempt_disable(); \ | ||
800 | + alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS, \ | ||
801 | + X86_FEATURE_USE_IBRS_FW); \ | ||
802 | +} while (0) | ||
803 | + | ||
804 | +#define firmware_restrict_branch_speculation_end() \ | ||
805 | +do { \ | ||
806 | + alternative_msr_write(MSR_IA32_SPEC_CTRL, 0, \ | ||
807 | + X86_FEATURE_USE_IBRS_FW); \ | ||
808 | + preempt_enable(); \ | ||
809 | +} while (0) | ||
810 | + | ||
811 | #endif /* __ASSEMBLY__ */ | ||
812 | |||
813 | /* | ||
814 | diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h | ||
815 | index 554841fab717..c83a2f418cea 100644 | ||
816 | --- a/arch/x86/include/asm/paravirt.h | ||
817 | +++ b/arch/x86/include/asm/paravirt.h | ||
818 | @@ -7,6 +7,7 @@ | ||
819 | #ifdef CONFIG_PARAVIRT | ||
820 | #include <asm/pgtable_types.h> | ||
821 | #include <asm/asm.h> | ||
822 | +#include <asm/nospec-branch.h> | ||
823 | |||
824 | #include <asm/paravirt_types.h> | ||
825 | |||
826 | @@ -879,23 +880,27 @@ extern void default_banner(void); | ||
827 | |||
828 | #define INTERRUPT_RETURN \ | ||
829 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ | ||
830 | - jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret)) | ||
831 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
832 | + jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret);) | ||
833 | |||
834 | #define DISABLE_INTERRUPTS(clobbers) \ | ||
835 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ | ||
836 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | ||
837 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
838 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable); \ | ||
839 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | ||
840 | |||
841 | #define ENABLE_INTERRUPTS(clobbers) \ | ||
842 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ | ||
843 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | ||
844 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
845 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ | ||
846 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | ||
847 | |||
848 | #ifdef CONFIG_X86_32 | ||
849 | #define GET_CR0_INTO_EAX \ | ||
850 | push %ecx; push %edx; \ | ||
851 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
852 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ | ||
853 | pop %edx; pop %ecx | ||
854 | #else /* !CONFIG_X86_32 */ | ||
855 | @@ -917,21 +922,25 @@ extern void default_banner(void); | ||
856 | */ | ||
857 | #define SWAPGS \ | ||
858 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ | ||
859 | - call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs) \ | ||
860 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
861 | + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs); \ | ||
862 | ) | ||
863 | |||
864 | #define GET_CR2_INTO_RAX \ | ||
865 | - call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) | ||
866 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
867 | + call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2); | ||
868 | |||
869 | #define USERGS_SYSRET64 \ | ||
870 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ | ||
871 | CLBR_NONE, \ | ||
872 | - jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64)) | ||
873 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
874 | + jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64);) | ||
875 | |||
876 | #ifdef CONFIG_DEBUG_ENTRY | ||
877 | #define SAVE_FLAGS(clobbers) \ | ||
878 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_save_fl), clobbers, \ | ||
879 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | ||
880 | + ANNOTATE_RETPOLINE_SAFE; \ | ||
881 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_save_fl); \ | ||
882 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | ||
883 | #endif | ||
884 | diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h | ||
885 | index f624f1f10316..180bc0bff0fb 100644 | ||
886 | --- a/arch/x86/include/asm/paravirt_types.h | ||
887 | +++ b/arch/x86/include/asm/paravirt_types.h | ||
888 | @@ -43,6 +43,7 @@ | ||
889 | #include <asm/desc_defs.h> | ||
890 | #include <asm/kmap_types.h> | ||
891 | #include <asm/pgtable_types.h> | ||
892 | +#include <asm/nospec-branch.h> | ||
893 | |||
894 | struct page; | ||
895 | struct thread_struct; | ||
896 | @@ -392,7 +393,9 @@ int paravirt_disable_iospace(void); | ||
897 | * offset into the paravirt_patch_template structure, and can therefore be | ||
898 | * freely converted back into a structure offset. | ||
899 | */ | ||
900 | -#define PARAVIRT_CALL "call *%c[paravirt_opptr];" | ||
901 | +#define PARAVIRT_CALL \ | ||
902 | + ANNOTATE_RETPOLINE_SAFE \ | ||
903 | + "call *%c[paravirt_opptr];" | ||
904 | |||
905 | /* | ||
906 | * These macros are intended to wrap calls through one of the paravirt | ||
907 | diff --git a/arch/x86/include/asm/refcount.h b/arch/x86/include/asm/refcount.h | ||
908 | index 4e44250e7d0d..d65171120e90 100644 | ||
909 | --- a/arch/x86/include/asm/refcount.h | ||
910 | +++ b/arch/x86/include/asm/refcount.h | ||
911 | @@ -67,13 +67,13 @@ static __always_inline __must_check | ||
912 | bool refcount_sub_and_test(unsigned int i, refcount_t *r) | ||
913 | { | ||
914 | GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", REFCOUNT_CHECK_LT_ZERO, | ||
915 | - r->refs.counter, "er", i, "%0", e); | ||
916 | + r->refs.counter, "er", i, "%0", e, "cx"); | ||
917 | } | ||
918 | |||
919 | static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r) | ||
920 | { | ||
921 | GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", REFCOUNT_CHECK_LT_ZERO, | ||
922 | - r->refs.counter, "%0", e); | ||
923 | + r->refs.counter, "%0", e, "cx"); | ||
924 | } | ||
925 | |||
926 | static __always_inline __must_check | ||
927 | diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h | ||
928 | index f91c365e57c3..4914a3e7c803 100644 | ||
929 | --- a/arch/x86/include/asm/rmwcc.h | ||
930 | +++ b/arch/x86/include/asm/rmwcc.h | ||
931 | @@ -2,8 +2,7 @@ | ||
932 | #ifndef _ASM_X86_RMWcc | ||
933 | #define _ASM_X86_RMWcc | ||
934 | |||
935 | -#define __CLOBBERS_MEM "memory" | ||
936 | -#define __CLOBBERS_MEM_CC_CX "memory", "cc", "cx" | ||
937 | +#define __CLOBBERS_MEM(clb...) "memory", ## clb | ||
938 | |||
939 | #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO) | ||
940 | |||
941 | @@ -40,18 +39,19 @@ do { \ | ||
942 | #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ | ||
943 | |||
944 | #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ | ||
945 | - __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM) | ||
946 | + __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM()) | ||
947 | |||
948 | -#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc) \ | ||
949 | +#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc, clobbers...)\ | ||
950 | __GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc, \ | ||
951 | - __CLOBBERS_MEM_CC_CX) | ||
952 | + __CLOBBERS_MEM(clobbers)) | ||
953 | |||
954 | #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ | ||
955 | __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc, \ | ||
956 | - __CLOBBERS_MEM, vcon (val)) | ||
957 | + __CLOBBERS_MEM(), vcon (val)) | ||
958 | |||
959 | -#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc) \ | ||
960 | +#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc, \ | ||
961 | + clobbers...) \ | ||
962 | __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc, \ | ||
963 | - __CLOBBERS_MEM_CC_CX, vcon (val)) | ||
964 | + __CLOBBERS_MEM(clobbers), vcon (val)) | ||
965 | |||
966 | #endif /* _ASM_X86_RMWcc */ | ||
967 | diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h | ||
968 | index d6baf23782bc..5c019d23d06b 100644 | ||
969 | --- a/arch/x86/include/asm/sections.h | ||
970 | +++ b/arch/x86/include/asm/sections.h | ||
971 | @@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[]; | ||
972 | |||
973 | #if defined(CONFIG_X86_64) | ||
974 | extern char __end_rodata_hpage_align[]; | ||
975 | +extern char __entry_trampoline_start[], __entry_trampoline_end[]; | ||
976 | #endif | ||
977 | |||
978 | #endif /* _ASM_X86_SECTIONS_H */ | ||
979 | diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h | ||
980 | index 461f53d27708..a4189762b266 100644 | ||
981 | --- a/arch/x86/include/asm/smp.h | ||
982 | +++ b/arch/x86/include/asm/smp.h | ||
983 | @@ -129,6 +129,7 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) | ||
984 | void cpu_disable_common(void); | ||
985 | void native_smp_prepare_boot_cpu(void); | ||
986 | void native_smp_prepare_cpus(unsigned int max_cpus); | ||
987 | +void calculate_max_logical_packages(void); | ||
988 | void native_smp_cpus_done(unsigned int max_cpus); | ||
989 | void common_cpu_up(unsigned int cpunum, struct task_struct *tidle); | ||
990 | int native_cpu_up(unsigned int cpunum, struct task_struct *tidle); | ||
991 | diff --git a/arch/x86/include/uapi/asm/mce.h b/arch/x86/include/uapi/asm/mce.h | ||
992 | index 91723461dc1f..435db58a7bad 100644 | ||
993 | --- a/arch/x86/include/uapi/asm/mce.h | ||
994 | +++ b/arch/x86/include/uapi/asm/mce.h | ||
995 | @@ -30,6 +30,7 @@ struct mce { | ||
996 | __u64 synd; /* MCA_SYND MSR: only valid on SMCA systems */ | ||
997 | __u64 ipid; /* MCA_IPID MSR: only valid on SMCA systems */ | ||
998 | __u64 ppin; /* Protected Processor Inventory Number */ | ||
999 | + __u32 microcode;/* Microcode revision */ | ||
1000 | }; | ||
1001 | |||
1002 | #define MCE_GET_RECORD_LEN _IOR('M', 1, int) | ||
1003 | diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c | ||
1004 | index 8a7963421460..93d5f55cd8b6 100644 | ||
1005 | --- a/arch/x86/kernel/apic/io_apic.c | ||
1006 | +++ b/arch/x86/kernel/apic/io_apic.c | ||
1007 | @@ -1603,7 +1603,7 @@ static void __init delay_with_tsc(void) | ||
1008 | do { | ||
1009 | rep_nop(); | ||
1010 | now = rdtsc(); | ||
1011 | - } while ((now - start) < 40000000000UL / HZ && | ||
1012 | + } while ((now - start) < 40000000000ULL / HZ && | ||
1013 | time_before_eq(jiffies, end)); | ||
1014 | } | ||
1015 | |||
1016 | diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c | ||
1017 | index d71c8b54b696..bfca937bdcc3 100644 | ||
1018 | --- a/arch/x86/kernel/cpu/bugs.c | ||
1019 | +++ b/arch/x86/kernel/cpu/bugs.c | ||
1020 | @@ -300,6 +300,15 @@ static void __init spectre_v2_select_mitigation(void) | ||
1021 | setup_force_cpu_cap(X86_FEATURE_USE_IBPB); | ||
1022 | pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n"); | ||
1023 | } | ||
1024 | + | ||
1025 | + /* | ||
1026 | + * Retpoline means the kernel is safe because it has no indirect | ||
1027 | + * branches. But firmware isn't, so use IBRS to protect that. | ||
1028 | + */ | ||
1029 | + if (boot_cpu_has(X86_FEATURE_IBRS)) { | ||
1030 | + setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); | ||
1031 | + pr_info("Enabling Restricted Speculation for firmware calls\n"); | ||
1032 | + } | ||
1033 | } | ||
1034 | |||
1035 | #undef pr_fmt | ||
1036 | @@ -326,8 +335,9 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, c | ||
1037 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) | ||
1038 | return sprintf(buf, "Not affected\n"); | ||
1039 | |||
1040 | - return sprintf(buf, "%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], | ||
1041 | + return sprintf(buf, "%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], | ||
1042 | boot_cpu_has(X86_FEATURE_USE_IBPB) ? ", IBPB" : "", | ||
1043 | + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", | ||
1044 | spectre_v2_module_string()); | ||
1045 | } | ||
1046 | #endif | ||
1047 | diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c | ||
1048 | index d19e903214b4..4aa9fd379390 100644 | ||
1049 | --- a/arch/x86/kernel/cpu/intel.c | ||
1050 | +++ b/arch/x86/kernel/cpu/intel.c | ||
1051 | @@ -144,6 +144,13 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c) | ||
1052 | { | ||
1053 | int i; | ||
1054 | |||
1055 | + /* | ||
1056 | + * We know that the hypervisor lie to us on the microcode version so | ||
1057 | + * we may as well hope that it is running the correct version. | ||
1058 | + */ | ||
1059 | + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) | ||
1060 | + return false; | ||
1061 | + | ||
1062 | for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { | ||
1063 | if (c->x86_model == spectre_bad_microcodes[i].model && | ||
1064 | c->x86_stepping == spectre_bad_microcodes[i].stepping) | ||
1065 | diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c | ||
1066 | index 2fe482f6ecd8..7a16a0fd1cb1 100644 | ||
1067 | --- a/arch/x86/kernel/cpu/mcheck/mce.c | ||
1068 | +++ b/arch/x86/kernel/cpu/mcheck/mce.c | ||
1069 | @@ -57,6 +57,9 @@ | ||
1070 | |||
1071 | static DEFINE_MUTEX(mce_log_mutex); | ||
1072 | |||
1073 | +/* sysfs synchronization */ | ||
1074 | +static DEFINE_MUTEX(mce_sysfs_mutex); | ||
1075 | + | ||
1076 | #define CREATE_TRACE_POINTS | ||
1077 | #include <trace/events/mce.h> | ||
1078 | |||
1079 | @@ -131,6 +134,8 @@ void mce_setup(struct mce *m) | ||
1080 | |||
1081 | if (this_cpu_has(X86_FEATURE_INTEL_PPIN)) | ||
1082 | rdmsrl(MSR_PPIN, m->ppin); | ||
1083 | + | ||
1084 | + m->microcode = boot_cpu_data.microcode; | ||
1085 | } | ||
1086 | |||
1087 | DEFINE_PER_CPU(struct mce, injectm); | ||
1088 | @@ -263,7 +268,7 @@ static void __print_mce(struct mce *m) | ||
1089 | */ | ||
1090 | pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n", | ||
1091 | m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid, | ||
1092 | - cpu_data(m->extcpu).microcode); | ||
1093 | + m->microcode); | ||
1094 | } | ||
1095 | |||
1096 | static void print_mce(struct mce *m) | ||
1097 | @@ -2078,6 +2083,7 @@ static ssize_t set_ignore_ce(struct device *s, | ||
1098 | if (kstrtou64(buf, 0, &new) < 0) | ||
1099 | return -EINVAL; | ||
1100 | |||
1101 | + mutex_lock(&mce_sysfs_mutex); | ||
1102 | if (mca_cfg.ignore_ce ^ !!new) { | ||
1103 | if (new) { | ||
1104 | /* disable ce features */ | ||
1105 | @@ -2090,6 +2096,8 @@ static ssize_t set_ignore_ce(struct device *s, | ||
1106 | on_each_cpu(mce_enable_ce, (void *)1, 1); | ||
1107 | } | ||
1108 | } | ||
1109 | + mutex_unlock(&mce_sysfs_mutex); | ||
1110 | + | ||
1111 | return size; | ||
1112 | } | ||
1113 | |||
1114 | @@ -2102,6 +2110,7 @@ static ssize_t set_cmci_disabled(struct device *s, | ||
1115 | if (kstrtou64(buf, 0, &new) < 0) | ||
1116 | return -EINVAL; | ||
1117 | |||
1118 | + mutex_lock(&mce_sysfs_mutex); | ||
1119 | if (mca_cfg.cmci_disabled ^ !!new) { | ||
1120 | if (new) { | ||
1121 | /* disable cmci */ | ||
1122 | @@ -2113,6 +2122,8 @@ static ssize_t set_cmci_disabled(struct device *s, | ||
1123 | on_each_cpu(mce_enable_ce, NULL, 1); | ||
1124 | } | ||
1125 | } | ||
1126 | + mutex_unlock(&mce_sysfs_mutex); | ||
1127 | + | ||
1128 | return size; | ||
1129 | } | ||
1130 | |||
1131 | @@ -2120,8 +2131,19 @@ static ssize_t store_int_with_restart(struct device *s, | ||
1132 | struct device_attribute *attr, | ||
1133 | const char *buf, size_t size) | ||
1134 | { | ||
1135 | - ssize_t ret = device_store_int(s, attr, buf, size); | ||
1136 | + unsigned long old_check_interval = check_interval; | ||
1137 | + ssize_t ret = device_store_ulong(s, attr, buf, size); | ||
1138 | + | ||
1139 | + if (check_interval == old_check_interval) | ||
1140 | + return ret; | ||
1141 | + | ||
1142 | + if (check_interval < 1) | ||
1143 | + check_interval = 1; | ||
1144 | + | ||
1145 | + mutex_lock(&mce_sysfs_mutex); | ||
1146 | mce_restart(); | ||
1147 | + mutex_unlock(&mce_sysfs_mutex); | ||
1148 | + | ||
1149 | return ret; | ||
1150 | } | ||
1151 | |||
1152 | diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S | ||
1153 | index 04a625f0fcda..0f545b3cf926 100644 | ||
1154 | --- a/arch/x86/kernel/head_64.S | ||
1155 | +++ b/arch/x86/kernel/head_64.S | ||
1156 | @@ -23,6 +23,7 @@ | ||
1157 | #include <asm/nops.h> | ||
1158 | #include "../entry/calling.h" | ||
1159 | #include <asm/export.h> | ||
1160 | +#include <asm/nospec-branch.h> | ||
1161 | |||
1162 | #ifdef CONFIG_PARAVIRT | ||
1163 | #include <asm/asm-offsets.h> | ||
1164 | @@ -134,6 +135,7 @@ ENTRY(secondary_startup_64) | ||
1165 | |||
1166 | /* Ensure I am executing from virtual addresses */ | ||
1167 | movq $1f, %rax | ||
1168 | + ANNOTATE_RETPOLINE_SAFE | ||
1169 | jmp *%rax | ||
1170 | 1: | ||
1171 | UNWIND_HINT_EMPTY | ||
1172 | diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c | ||
1173 | index bd36f3c33cd0..0715f827607c 100644 | ||
1174 | --- a/arch/x86/kernel/kprobes/core.c | ||
1175 | +++ b/arch/x86/kernel/kprobes/core.c | ||
1176 | @@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler); | ||
1177 | |||
1178 | bool arch_within_kprobe_blacklist(unsigned long addr) | ||
1179 | { | ||
1180 | + bool is_in_entry_trampoline_section = false; | ||
1181 | + | ||
1182 | +#ifdef CONFIG_X86_64 | ||
1183 | + is_in_entry_trampoline_section = | ||
1184 | + (addr >= (unsigned long)__entry_trampoline_start && | ||
1185 | + addr < (unsigned long)__entry_trampoline_end); | ||
1186 | +#endif | ||
1187 | return (addr >= (unsigned long)__kprobes_text_start && | ||
1188 | addr < (unsigned long)__kprobes_text_end) || | ||
1189 | (addr >= (unsigned long)__entry_text_start && | ||
1190 | - addr < (unsigned long)__entry_text_end); | ||
1191 | + addr < (unsigned long)__entry_text_end) || | ||
1192 | + is_in_entry_trampoline_section; | ||
1193 | } | ||
1194 | |||
1195 | int __init arch_init_kprobes(void) | ||
1196 | diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c | ||
1197 | index 844279c3ff4a..d0829a6e1bf5 100644 | ||
1198 | --- a/arch/x86/kernel/smpboot.c | ||
1199 | +++ b/arch/x86/kernel/smpboot.c | ||
1200 | @@ -1282,11 +1282,10 @@ void __init native_smp_prepare_boot_cpu(void) | ||
1201 | cpu_set_state_online(me); | ||
1202 | } | ||
1203 | |||
1204 | -void __init native_smp_cpus_done(unsigned int max_cpus) | ||
1205 | +void __init calculate_max_logical_packages(void) | ||
1206 | { | ||
1207 | int ncpus; | ||
1208 | |||
1209 | - pr_debug("Boot done\n"); | ||
1210 | /* | ||
1211 | * Today neither Intel nor AMD support heterogenous systems so | ||
1212 | * extrapolate the boot cpu's data to all packages. | ||
1213 | @@ -1294,6 +1293,13 @@ void __init native_smp_cpus_done(unsigned int max_cpus) | ||
1214 | ncpus = cpu_data(0).booted_cores * topology_max_smt_threads(); | ||
1215 | __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus); | ||
1216 | pr_info("Max logical packages: %u\n", __max_logical_packages); | ||
1217 | +} | ||
1218 | + | ||
1219 | +void __init native_smp_cpus_done(unsigned int max_cpus) | ||
1220 | +{ | ||
1221 | + pr_debug("Boot done\n"); | ||
1222 | + | ||
1223 | + calculate_max_logical_packages(); | ||
1224 | |||
1225 | if (x86_has_numa_in_package) | ||
1226 | set_sched_topology(x86_numa_in_package_topology); | ||
1227 | diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S | ||
1228 | index 9b138a06c1a4..b854ebf5851b 100644 | ||
1229 | --- a/arch/x86/kernel/vmlinux.lds.S | ||
1230 | +++ b/arch/x86/kernel/vmlinux.lds.S | ||
1231 | @@ -118,9 +118,11 @@ SECTIONS | ||
1232 | |||
1233 | #ifdef CONFIG_X86_64 | ||
1234 | . = ALIGN(PAGE_SIZE); | ||
1235 | + VMLINUX_SYMBOL(__entry_trampoline_start) = .; | ||
1236 | _entry_trampoline = .; | ||
1237 | *(.entry_trampoline) | ||
1238 | . = ALIGN(PAGE_SIZE); | ||
1239 | + VMLINUX_SYMBOL(__entry_trampoline_end) = .; | ||
1240 | ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big"); | ||
1241 | #endif | ||
1242 | |||
1243 | diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile | ||
1244 | index 69a473919260..f23934bbaf4e 100644 | ||
1245 | --- a/arch/x86/lib/Makefile | ||
1246 | +++ b/arch/x86/lib/Makefile | ||
1247 | @@ -27,7 +27,6 @@ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | ||
1248 | lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o | ||
1249 | lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o | ||
1250 | lib-$(CONFIG_RETPOLINE) += retpoline.o | ||
1251 | -OBJECT_FILES_NON_STANDARD_retpoline.o :=y | ||
1252 | |||
1253 | obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o | ||
1254 | |||
1255 | diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S | ||
1256 | index 480edc3a5e03..c909961e678a 100644 | ||
1257 | --- a/arch/x86/lib/retpoline.S | ||
1258 | +++ b/arch/x86/lib/retpoline.S | ||
1259 | @@ -7,7 +7,6 @@ | ||
1260 | #include <asm/alternative-asm.h> | ||
1261 | #include <asm/export.h> | ||
1262 | #include <asm/nospec-branch.h> | ||
1263 | -#include <asm/bitsperlong.h> | ||
1264 | |||
1265 | .macro THUNK reg | ||
1266 | .section .text.__x86.indirect_thunk | ||
1267 | @@ -47,58 +46,3 @@ GENERATE_THUNK(r13) | ||
1268 | GENERATE_THUNK(r14) | ||
1269 | GENERATE_THUNK(r15) | ||
1270 | #endif | ||
1271 | - | ||
1272 | -/* | ||
1273 | - * Fill the CPU return stack buffer. | ||
1274 | - * | ||
1275 | - * Each entry in the RSB, if used for a speculative 'ret', contains an | ||
1276 | - * infinite 'pause; lfence; jmp' loop to capture speculative execution. | ||
1277 | - * | ||
1278 | - * This is required in various cases for retpoline and IBRS-based | ||
1279 | - * mitigations for the Spectre variant 2 vulnerability. Sometimes to | ||
1280 | - * eliminate potentially bogus entries from the RSB, and sometimes | ||
1281 | - * purely to ensure that it doesn't get empty, which on some CPUs would | ||
1282 | - * allow predictions from other (unwanted!) sources to be used. | ||
1283 | - * | ||
1284 | - * Google experimented with loop-unrolling and this turned out to be | ||
1285 | - * the optimal version - two calls, each with their own speculation | ||
1286 | - * trap should their return address end up getting used, in a loop. | ||
1287 | - */ | ||
1288 | -.macro STUFF_RSB nr:req sp:req | ||
1289 | - mov $(\nr / 2), %_ASM_BX | ||
1290 | - .align 16 | ||
1291 | -771: | ||
1292 | - call 772f | ||
1293 | -773: /* speculation trap */ | ||
1294 | - pause | ||
1295 | - lfence | ||
1296 | - jmp 773b | ||
1297 | - .align 16 | ||
1298 | -772: | ||
1299 | - call 774f | ||
1300 | -775: /* speculation trap */ | ||
1301 | - pause | ||
1302 | - lfence | ||
1303 | - jmp 775b | ||
1304 | - .align 16 | ||
1305 | -774: | ||
1306 | - dec %_ASM_BX | ||
1307 | - jnz 771b | ||
1308 | - add $((BITS_PER_LONG/8) * \nr), \sp | ||
1309 | -.endm | ||
1310 | - | ||
1311 | -#define RSB_FILL_LOOPS 16 /* To avoid underflow */ | ||
1312 | - | ||
1313 | -ENTRY(__fill_rsb) | ||
1314 | - STUFF_RSB RSB_FILL_LOOPS, %_ASM_SP | ||
1315 | - ret | ||
1316 | -END(__fill_rsb) | ||
1317 | -EXPORT_SYMBOL_GPL(__fill_rsb) | ||
1318 | - | ||
1319 | -#define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ | ||
1320 | - | ||
1321 | -ENTRY(__clear_rsb) | ||
1322 | - STUFF_RSB RSB_CLEAR_LOOPS, %_ASM_SP | ||
1323 | - ret | ||
1324 | -END(__clear_rsb) | ||
1325 | -EXPORT_SYMBOL_GPL(__clear_rsb) | ||
1326 | diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c | ||
1327 | index 800de815519c..c88573d90f3e 100644 | ||
1328 | --- a/arch/x86/mm/fault.c | ||
1329 | +++ b/arch/x86/mm/fault.c | ||
1330 | @@ -1248,10 +1248,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, | ||
1331 | tsk = current; | ||
1332 | mm = tsk->mm; | ||
1333 | |||
1334 | - /* | ||
1335 | - * Detect and handle instructions that would cause a page fault for | ||
1336 | - * both a tracked kernel page and a userspace page. | ||
1337 | - */ | ||
1338 | prefetchw(&mm->mmap_sem); | ||
1339 | |||
1340 | if (unlikely(kmmio_fault(regs, address))) | ||
1341 | diff --git a/arch/x86/mm/mem_encrypt_boot.S b/arch/x86/mm/mem_encrypt_boot.S | ||
1342 | index 01f682cf77a8..40a6085063d6 100644 | ||
1343 | --- a/arch/x86/mm/mem_encrypt_boot.S | ||
1344 | +++ b/arch/x86/mm/mem_encrypt_boot.S | ||
1345 | @@ -15,6 +15,7 @@ | ||
1346 | #include <asm/page.h> | ||
1347 | #include <asm/processor-flags.h> | ||
1348 | #include <asm/msr-index.h> | ||
1349 | +#include <asm/nospec-branch.h> | ||
1350 | |||
1351 | .text | ||
1352 | .code64 | ||
1353 | @@ -59,6 +60,7 @@ ENTRY(sme_encrypt_execute) | ||
1354 | movq %rax, %r8 /* Workarea encryption routine */ | ||
1355 | addq $PAGE_SIZE, %r8 /* Workarea intermediate copy buffer */ | ||
1356 | |||
1357 | + ANNOTATE_RETPOLINE_SAFE | ||
1358 | call *%rax /* Call the encryption routine */ | ||
1359 | |||
1360 | pop %r12 | ||
1361 | diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S | ||
1362 | index de53bd15df5a..24bb7598774e 100644 | ||
1363 | --- a/arch/x86/realmode/rm/trampoline_64.S | ||
1364 | +++ b/arch/x86/realmode/rm/trampoline_64.S | ||
1365 | @@ -102,7 +102,7 @@ ENTRY(startup_32) | ||
1366 | * don't we'll eventually crash trying to execute encrypted | ||
1367 | * instructions. | ||
1368 | */ | ||
1369 | - bt $TH_FLAGS_SME_ACTIVE_BIT, pa_tr_flags | ||
1370 | + btl $TH_FLAGS_SME_ACTIVE_BIT, pa_tr_flags | ||
1371 | jnc .Ldone | ||
1372 | movl $MSR_K8_SYSCFG, %ecx | ||
1373 | rdmsr | ||
1374 | diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c | ||
1375 | index 77c959cf81e7..7a43b2ae19f1 100644 | ||
1376 | --- a/arch/x86/xen/smp.c | ||
1377 | +++ b/arch/x86/xen/smp.c | ||
1378 | @@ -122,6 +122,8 @@ void __init xen_smp_cpus_done(unsigned int max_cpus) | ||
1379 | |||
1380 | if (xen_hvm_domain()) | ||
1381 | native_smp_cpus_done(max_cpus); | ||
1382 | + else | ||
1383 | + calculate_max_logical_packages(); | ||
1384 | |||
1385 | if (xen_have_vcpu_info_placement) | ||
1386 | return; | ||
1387 | diff --git a/drivers/block/loop.c b/drivers/block/loop.c | ||
1388 | index d5fe720cf149..89d2ee00cced 100644 | ||
1389 | --- a/drivers/block/loop.c | ||
1390 | +++ b/drivers/block/loop.c | ||
1391 | @@ -266,7 +266,7 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) | ||
1392 | struct iov_iter i; | ||
1393 | ssize_t bw; | ||
1394 | |||
1395 | - iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len); | ||
1396 | + iov_iter_bvec(&i, ITER_BVEC | WRITE, bvec, 1, bvec->bv_len); | ||
1397 | |||
1398 | file_start_write(file); | ||
1399 | bw = vfs_iter_write(file, &i, ppos, 0); | ||
1400 | diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c | ||
1401 | index 3cec403a80b3..5294442505cb 100644 | ||
1402 | --- a/drivers/char/tpm/tpm-interface.c | ||
1403 | +++ b/drivers/char/tpm/tpm-interface.c | ||
1404 | @@ -413,6 +413,9 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | ||
1405 | if (chip->dev.parent) | ||
1406 | pm_runtime_get_sync(chip->dev.parent); | ||
1407 | |||
1408 | + if (chip->ops->clk_enable != NULL) | ||
1409 | + chip->ops->clk_enable(chip, true); | ||
1410 | + | ||
1411 | /* Store the decision as chip->locality will be changed. */ | ||
1412 | need_locality = chip->locality == -1; | ||
1413 | |||
1414 | @@ -489,6 +492,9 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | ||
1415 | chip->locality = -1; | ||
1416 | } | ||
1417 | out_no_locality: | ||
1418 | + if (chip->ops->clk_enable != NULL) | ||
1419 | + chip->ops->clk_enable(chip, false); | ||
1420 | + | ||
1421 | if (chip->dev.parent) | ||
1422 | pm_runtime_put_sync(chip->dev.parent); | ||
1423 | |||
1424 | diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c | ||
1425 | index e2d1055fb814..f08949a5f678 100644 | ||
1426 | --- a/drivers/char/tpm/tpm_tis.c | ||
1427 | +++ b/drivers/char/tpm/tpm_tis.c | ||
1428 | @@ -133,93 +133,14 @@ static int check_acpi_tpm2(struct device *dev) | ||
1429 | } | ||
1430 | #endif | ||
1431 | |||
1432 | -#ifdef CONFIG_X86 | ||
1433 | -#define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 | ||
1434 | -#define ILB_REMAP_SIZE 0x100 | ||
1435 | -#define LPC_CNTRL_REG_OFFSET 0x84 | ||
1436 | -#define LPC_CLKRUN_EN (1 << 2) | ||
1437 | - | ||
1438 | -static void __iomem *ilb_base_addr; | ||
1439 | - | ||
1440 | -static inline bool is_bsw(void) | ||
1441 | -{ | ||
1442 | - return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); | ||
1443 | -} | ||
1444 | - | ||
1445 | -/** | ||
1446 | - * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running | ||
1447 | - */ | ||
1448 | -static void tpm_platform_begin_xfer(void) | ||
1449 | -{ | ||
1450 | - u32 clkrun_val; | ||
1451 | - | ||
1452 | - if (!is_bsw()) | ||
1453 | - return; | ||
1454 | - | ||
1455 | - clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
1456 | - | ||
1457 | - /* Disable LPC CLKRUN# */ | ||
1458 | - clkrun_val &= ~LPC_CLKRUN_EN; | ||
1459 | - iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
1460 | - | ||
1461 | - /* | ||
1462 | - * Write any random value on port 0x80 which is on LPC, to make | ||
1463 | - * sure LPC clock is running before sending any TPM command. | ||
1464 | - */ | ||
1465 | - outb(0xCC, 0x80); | ||
1466 | - | ||
1467 | -} | ||
1468 | - | ||
1469 | -/** | ||
1470 | - * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off | ||
1471 | - */ | ||
1472 | -static void tpm_platform_end_xfer(void) | ||
1473 | -{ | ||
1474 | - u32 clkrun_val; | ||
1475 | - | ||
1476 | - if (!is_bsw()) | ||
1477 | - return; | ||
1478 | - | ||
1479 | - clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
1480 | - | ||
1481 | - /* Enable LPC CLKRUN# */ | ||
1482 | - clkrun_val |= LPC_CLKRUN_EN; | ||
1483 | - iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
1484 | - | ||
1485 | - /* | ||
1486 | - * Write any random value on port 0x80 which is on LPC, to make | ||
1487 | - * sure LPC clock is running before sending any TPM command. | ||
1488 | - */ | ||
1489 | - outb(0xCC, 0x80); | ||
1490 | - | ||
1491 | -} | ||
1492 | -#else | ||
1493 | -static inline bool is_bsw(void) | ||
1494 | -{ | ||
1495 | - return false; | ||
1496 | -} | ||
1497 | - | ||
1498 | -static void tpm_platform_begin_xfer(void) | ||
1499 | -{ | ||
1500 | -} | ||
1501 | - | ||
1502 | -static void tpm_platform_end_xfer(void) | ||
1503 | -{ | ||
1504 | -} | ||
1505 | -#endif | ||
1506 | - | ||
1507 | static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, | ||
1508 | u8 *result) | ||
1509 | { | ||
1510 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | ||
1511 | |||
1512 | - tpm_platform_begin_xfer(); | ||
1513 | - | ||
1514 | while (len--) | ||
1515 | *result++ = ioread8(phy->iobase + addr); | ||
1516 | |||
1517 | - tpm_platform_end_xfer(); | ||
1518 | - | ||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | @@ -228,13 +149,9 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, | ||
1523 | { | ||
1524 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | ||
1525 | |||
1526 | - tpm_platform_begin_xfer(); | ||
1527 | - | ||
1528 | while (len--) | ||
1529 | iowrite8(*value++, phy->iobase + addr); | ||
1530 | |||
1531 | - tpm_platform_end_xfer(); | ||
1532 | - | ||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1536 | @@ -242,12 +159,8 @@ static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result) | ||
1537 | { | ||
1538 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | ||
1539 | |||
1540 | - tpm_platform_begin_xfer(); | ||
1541 | - | ||
1542 | *result = ioread16(phy->iobase + addr); | ||
1543 | |||
1544 | - tpm_platform_end_xfer(); | ||
1545 | - | ||
1546 | return 0; | ||
1547 | } | ||
1548 | |||
1549 | @@ -255,12 +168,8 @@ static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result) | ||
1550 | { | ||
1551 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | ||
1552 | |||
1553 | - tpm_platform_begin_xfer(); | ||
1554 | - | ||
1555 | *result = ioread32(phy->iobase + addr); | ||
1556 | |||
1557 | - tpm_platform_end_xfer(); | ||
1558 | - | ||
1559 | return 0; | ||
1560 | } | ||
1561 | |||
1562 | @@ -268,12 +177,8 @@ static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) | ||
1563 | { | ||
1564 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | ||
1565 | |||
1566 | - tpm_platform_begin_xfer(); | ||
1567 | - | ||
1568 | iowrite32(value, phy->iobase + addr); | ||
1569 | |||
1570 | - tpm_platform_end_xfer(); | ||
1571 | - | ||
1572 | return 0; | ||
1573 | } | ||
1574 | |||
1575 | @@ -461,11 +366,6 @@ static int __init init_tis(void) | ||
1576 | if (rc) | ||
1577 | goto err_force; | ||
1578 | |||
1579 | -#ifdef CONFIG_X86 | ||
1580 | - if (is_bsw()) | ||
1581 | - ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, | ||
1582 | - ILB_REMAP_SIZE); | ||
1583 | -#endif | ||
1584 | rc = platform_driver_register(&tis_drv); | ||
1585 | if (rc) | ||
1586 | goto err_platform; | ||
1587 | @@ -484,10 +384,6 @@ static int __init init_tis(void) | ||
1588 | err_platform: | ||
1589 | if (force_pdev) | ||
1590 | platform_device_unregister(force_pdev); | ||
1591 | -#ifdef CONFIG_X86 | ||
1592 | - if (is_bsw()) | ||
1593 | - iounmap(ilb_base_addr); | ||
1594 | -#endif | ||
1595 | err_force: | ||
1596 | return rc; | ||
1597 | } | ||
1598 | @@ -497,10 +393,6 @@ static void __exit cleanup_tis(void) | ||
1599 | pnp_unregister_driver(&tis_pnp_driver); | ||
1600 | platform_driver_unregister(&tis_drv); | ||
1601 | |||
1602 | -#ifdef CONFIG_X86 | ||
1603 | - if (is_bsw()) | ||
1604 | - iounmap(ilb_base_addr); | ||
1605 | -#endif | ||
1606 | if (force_pdev) | ||
1607 | platform_device_unregister(force_pdev); | ||
1608 | } | ||
1609 | diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c | ||
1610 | index 7561922bc8f8..08ae49dee8b1 100644 | ||
1611 | --- a/drivers/char/tpm/tpm_tis_core.c | ||
1612 | +++ b/drivers/char/tpm/tpm_tis_core.c | ||
1613 | @@ -31,6 +31,8 @@ | ||
1614 | #include "tpm.h" | ||
1615 | #include "tpm_tis_core.h" | ||
1616 | |||
1617 | +static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value); | ||
1618 | + | ||
1619 | /* Before we attempt to access the TPM we must see that the valid bit is set. | ||
1620 | * The specification says that this bit is 0 at reset and remains 0 until the | ||
1621 | * 'TPM has gone through its self test and initialization and has established | ||
1622 | @@ -422,19 +424,28 @@ static bool tpm_tis_update_timeouts(struct tpm_chip *chip, | ||
1623 | int i, rc; | ||
1624 | u32 did_vid; | ||
1625 | |||
1626 | + if (chip->ops->clk_enable != NULL) | ||
1627 | + chip->ops->clk_enable(chip, true); | ||
1628 | + | ||
1629 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid); | ||
1630 | if (rc < 0) | ||
1631 | - return rc; | ||
1632 | + goto out; | ||
1633 | |||
1634 | for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { | ||
1635 | if (vendor_timeout_overrides[i].did_vid != did_vid) | ||
1636 | continue; | ||
1637 | memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, | ||
1638 | sizeof(vendor_timeout_overrides[i].timeout_us)); | ||
1639 | - return true; | ||
1640 | + rc = true; | ||
1641 | } | ||
1642 | |||
1643 | - return false; | ||
1644 | + rc = false; | ||
1645 | + | ||
1646 | +out: | ||
1647 | + if (chip->ops->clk_enable != NULL) | ||
1648 | + chip->ops->clk_enable(chip, false); | ||
1649 | + | ||
1650 | + return rc; | ||
1651 | } | ||
1652 | |||
1653 | /* | ||
1654 | @@ -654,14 +665,73 @@ void tpm_tis_remove(struct tpm_chip *chip) | ||
1655 | u32 interrupt; | ||
1656 | int rc; | ||
1657 | |||
1658 | + tpm_tis_clkrun_enable(chip, true); | ||
1659 | + | ||
1660 | rc = tpm_tis_read32(priv, reg, &interrupt); | ||
1661 | if (rc < 0) | ||
1662 | interrupt = 0; | ||
1663 | |||
1664 | tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); | ||
1665 | + | ||
1666 | + tpm_tis_clkrun_enable(chip, false); | ||
1667 | + | ||
1668 | + if (priv->ilb_base_addr) | ||
1669 | + iounmap(priv->ilb_base_addr); | ||
1670 | } | ||
1671 | EXPORT_SYMBOL_GPL(tpm_tis_remove); | ||
1672 | |||
1673 | +/** | ||
1674 | + * tpm_tis_clkrun_enable() - Keep clkrun protocol disabled for entire duration | ||
1675 | + * of a single TPM command | ||
1676 | + * @chip: TPM chip to use | ||
1677 | + * @value: 1 - Disable CLKRUN protocol, so that clocks are free running | ||
1678 | + * 0 - Enable CLKRUN protocol | ||
1679 | + * Call this function directly in tpm_tis_remove() in error or driver removal | ||
1680 | + * path, since the chip->ops is set to NULL in tpm_chip_unregister(). | ||
1681 | + */ | ||
1682 | +static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value) | ||
1683 | +{ | ||
1684 | + struct tpm_tis_data *data = dev_get_drvdata(&chip->dev); | ||
1685 | + u32 clkrun_val; | ||
1686 | + | ||
1687 | + if (!IS_ENABLED(CONFIG_X86) || !is_bsw() || | ||
1688 | + !data->ilb_base_addr) | ||
1689 | + return; | ||
1690 | + | ||
1691 | + if (value) { | ||
1692 | + data->clkrun_enabled++; | ||
1693 | + if (data->clkrun_enabled > 1) | ||
1694 | + return; | ||
1695 | + clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
1696 | + | ||
1697 | + /* Disable LPC CLKRUN# */ | ||
1698 | + clkrun_val &= ~LPC_CLKRUN_EN; | ||
1699 | + iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
1700 | + | ||
1701 | + /* | ||
1702 | + * Write any random value on port 0x80 which is on LPC, to make | ||
1703 | + * sure LPC clock is running before sending any TPM command. | ||
1704 | + */ | ||
1705 | + outb(0xCC, 0x80); | ||
1706 | + } else { | ||
1707 | + data->clkrun_enabled--; | ||
1708 | + if (data->clkrun_enabled) | ||
1709 | + return; | ||
1710 | + | ||
1711 | + clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
1712 | + | ||
1713 | + /* Enable LPC CLKRUN# */ | ||
1714 | + clkrun_val |= LPC_CLKRUN_EN; | ||
1715 | + iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
1716 | + | ||
1717 | + /* | ||
1718 | + * Write any random value on port 0x80 which is on LPC, to make | ||
1719 | + * sure LPC clock is running before sending any TPM command. | ||
1720 | + */ | ||
1721 | + outb(0xCC, 0x80); | ||
1722 | + } | ||
1723 | +} | ||
1724 | + | ||
1725 | static const struct tpm_class_ops tpm_tis = { | ||
1726 | .flags = TPM_OPS_AUTO_STARTUP, | ||
1727 | .status = tpm_tis_status, | ||
1728 | @@ -674,6 +744,7 @@ static const struct tpm_class_ops tpm_tis = { | ||
1729 | .req_canceled = tpm_tis_req_canceled, | ||
1730 | .request_locality = request_locality, | ||
1731 | .relinquish_locality = release_locality, | ||
1732 | + .clk_enable = tpm_tis_clkrun_enable, | ||
1733 | }; | ||
1734 | |||
1735 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | ||
1736 | @@ -681,6 +752,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | ||
1737 | acpi_handle acpi_dev_handle) | ||
1738 | { | ||
1739 | u32 vendor, intfcaps, intmask; | ||
1740 | + u32 clkrun_val; | ||
1741 | u8 rid; | ||
1742 | int rc, probe; | ||
1743 | struct tpm_chip *chip; | ||
1744 | @@ -701,6 +773,23 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | ||
1745 | priv->phy_ops = phy_ops; | ||
1746 | dev_set_drvdata(&chip->dev, priv); | ||
1747 | |||
1748 | + if (is_bsw()) { | ||
1749 | + priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, | ||
1750 | + ILB_REMAP_SIZE); | ||
1751 | + if (!priv->ilb_base_addr) | ||
1752 | + return -ENOMEM; | ||
1753 | + | ||
1754 | + clkrun_val = ioread32(priv->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
1755 | + /* Check if CLKRUN# is already not enabled in the LPC bus */ | ||
1756 | + if (!(clkrun_val & LPC_CLKRUN_EN)) { | ||
1757 | + iounmap(priv->ilb_base_addr); | ||
1758 | + priv->ilb_base_addr = NULL; | ||
1759 | + } | ||
1760 | + } | ||
1761 | + | ||
1762 | + if (chip->ops->clk_enable != NULL) | ||
1763 | + chip->ops->clk_enable(chip, true); | ||
1764 | + | ||
1765 | if (wait_startup(chip, 0) != 0) { | ||
1766 | rc = -ENODEV; | ||
1767 | goto out_err; | ||
1768 | @@ -791,9 +880,20 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | ||
1769 | } | ||
1770 | } | ||
1771 | |||
1772 | - return tpm_chip_register(chip); | ||
1773 | + rc = tpm_chip_register(chip); | ||
1774 | + if (rc) | ||
1775 | + goto out_err; | ||
1776 | + | ||
1777 | + if (chip->ops->clk_enable != NULL) | ||
1778 | + chip->ops->clk_enable(chip, false); | ||
1779 | + | ||
1780 | + return 0; | ||
1781 | out_err: | ||
1782 | + if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) | ||
1783 | + chip->ops->clk_enable(chip, false); | ||
1784 | + | ||
1785 | tpm_tis_remove(chip); | ||
1786 | + | ||
1787 | return rc; | ||
1788 | } | ||
1789 | EXPORT_SYMBOL_GPL(tpm_tis_core_init); | ||
1790 | @@ -805,22 +905,31 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) | ||
1791 | u32 intmask; | ||
1792 | int rc; | ||
1793 | |||
1794 | + if (chip->ops->clk_enable != NULL) | ||
1795 | + chip->ops->clk_enable(chip, true); | ||
1796 | + | ||
1797 | /* reenable interrupts that device may have lost or | ||
1798 | * BIOS/firmware may have disabled | ||
1799 | */ | ||
1800 | rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq); | ||
1801 | if (rc < 0) | ||
1802 | - return; | ||
1803 | + goto out; | ||
1804 | |||
1805 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); | ||
1806 | if (rc < 0) | ||
1807 | - return; | ||
1808 | + goto out; | ||
1809 | |||
1810 | intmask |= TPM_INTF_CMD_READY_INT | ||
1811 | | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | ||
1812 | | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE; | ||
1813 | |||
1814 | tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); | ||
1815 | + | ||
1816 | +out: | ||
1817 | + if (chip->ops->clk_enable != NULL) | ||
1818 | + chip->ops->clk_enable(chip, false); | ||
1819 | + | ||
1820 | + return; | ||
1821 | } | ||
1822 | |||
1823 | int tpm_tis_resume(struct device *dev) | ||
1824 | diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h | ||
1825 | index 6bbac319ff3b..d5c6a2e952b3 100644 | ||
1826 | --- a/drivers/char/tpm/tpm_tis_core.h | ||
1827 | +++ b/drivers/char/tpm/tpm_tis_core.h | ||
1828 | @@ -79,6 +79,11 @@ enum tis_defaults { | ||
1829 | #define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) | ||
1830 | #define TPM_RID(l) (0x0F04 | ((l) << 12)) | ||
1831 | |||
1832 | +#define LPC_CNTRL_OFFSET 0x84 | ||
1833 | +#define LPC_CLKRUN_EN (1 << 2) | ||
1834 | +#define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 | ||
1835 | +#define ILB_REMAP_SIZE 0x100 | ||
1836 | + | ||
1837 | enum tpm_tis_flags { | ||
1838 | TPM_TIS_ITPM_WORKAROUND = BIT(0), | ||
1839 | }; | ||
1840 | @@ -89,6 +94,8 @@ struct tpm_tis_data { | ||
1841 | int irq; | ||
1842 | bool irq_tested; | ||
1843 | unsigned int flags; | ||
1844 | + void __iomem *ilb_base_addr; | ||
1845 | + u16 clkrun_enabled; | ||
1846 | wait_queue_head_t int_queue; | ||
1847 | wait_queue_head_t read_queue; | ||
1848 | const struct tpm_tis_phy_ops *phy_ops; | ||
1849 | @@ -144,6 +151,15 @@ static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr, | ||
1850 | return data->phy_ops->write32(data, addr, value); | ||
1851 | } | ||
1852 | |||
1853 | +static inline bool is_bsw(void) | ||
1854 | +{ | ||
1855 | +#ifdef CONFIG_X86 | ||
1856 | + return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); | ||
1857 | +#else | ||
1858 | + return false; | ||
1859 | +#endif | ||
1860 | +} | ||
1861 | + | ||
1862 | void tpm_tis_remove(struct tpm_chip *chip); | ||
1863 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | ||
1864 | const struct tpm_tis_phy_ops *phy_ops, | ||
1865 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | ||
1866 | index 57afad79f55d..8fa850a070e0 100644 | ||
1867 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | ||
1868 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | ||
1869 | @@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, | ||
1870 | size_t size; | ||
1871 | u32 retry = 3; | ||
1872 | |||
1873 | + if (amdgpu_acpi_pcie_notify_device_ready(adev)) | ||
1874 | + return -EINVAL; | ||
1875 | + | ||
1876 | /* Get the device handle */ | ||
1877 | handle = ACPI_HANDLE(&adev->pdev->dev); | ||
1878 | if (!handle) | ||
1879 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | ||
1880 | index df9cbc78e168..21e7ae159dff 100644 | ||
1881 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | ||
1882 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | ||
1883 | @@ -737,9 +737,11 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) | ||
1884 | enum drm_connector_status ret = connector_status_disconnected; | ||
1885 | int r; | ||
1886 | |||
1887 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
1888 | - if (r < 0) | ||
1889 | - return connector_status_disconnected; | ||
1890 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1891 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
1892 | + if (r < 0) | ||
1893 | + return connector_status_disconnected; | ||
1894 | + } | ||
1895 | |||
1896 | if (encoder) { | ||
1897 | struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); | ||
1898 | @@ -758,8 +760,12 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) | ||
1899 | /* check acpi lid status ??? */ | ||
1900 | |||
1901 | amdgpu_connector_update_scratch_regs(connector, ret); | ||
1902 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
1903 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
1904 | + | ||
1905 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1906 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
1907 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
1908 | + } | ||
1909 | + | ||
1910 | return ret; | ||
1911 | } | ||
1912 | |||
1913 | @@ -869,9 +875,11 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) | ||
1914 | enum drm_connector_status ret = connector_status_disconnected; | ||
1915 | int r; | ||
1916 | |||
1917 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
1918 | - if (r < 0) | ||
1919 | - return connector_status_disconnected; | ||
1920 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1921 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
1922 | + if (r < 0) | ||
1923 | + return connector_status_disconnected; | ||
1924 | + } | ||
1925 | |||
1926 | encoder = amdgpu_connector_best_single_encoder(connector); | ||
1927 | if (!encoder) | ||
1928 | @@ -925,8 +933,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) | ||
1929 | amdgpu_connector_update_scratch_regs(connector, ret); | ||
1930 | |||
1931 | out: | ||
1932 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
1933 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
1934 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1935 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
1936 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
1937 | + } | ||
1938 | |||
1939 | return ret; | ||
1940 | } | ||
1941 | @@ -989,9 +999,11 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) | ||
1942 | enum drm_connector_status ret = connector_status_disconnected; | ||
1943 | bool dret = false, broken_edid = false; | ||
1944 | |||
1945 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
1946 | - if (r < 0) | ||
1947 | - return connector_status_disconnected; | ||
1948 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1949 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
1950 | + if (r < 0) | ||
1951 | + return connector_status_disconnected; | ||
1952 | + } | ||
1953 | |||
1954 | if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { | ||
1955 | ret = connector->status; | ||
1956 | @@ -1116,8 +1128,10 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) | ||
1957 | amdgpu_connector_update_scratch_regs(connector, ret); | ||
1958 | |||
1959 | exit: | ||
1960 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
1961 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
1962 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1963 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
1964 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
1965 | + } | ||
1966 | |||
1967 | return ret; | ||
1968 | } | ||
1969 | @@ -1360,9 +1374,11 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) | ||
1970 | struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); | ||
1971 | int r; | ||
1972 | |||
1973 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
1974 | - if (r < 0) | ||
1975 | - return connector_status_disconnected; | ||
1976 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1977 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
1978 | + if (r < 0) | ||
1979 | + return connector_status_disconnected; | ||
1980 | + } | ||
1981 | |||
1982 | if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { | ||
1983 | ret = connector->status; | ||
1984 | @@ -1430,8 +1446,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) | ||
1985 | |||
1986 | amdgpu_connector_update_scratch_regs(connector, ret); | ||
1987 | out: | ||
1988 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
1989 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
1990 | + if (!drm_kms_helper_is_poll_worker()) { | ||
1991 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
1992 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
1993 | + } | ||
1994 | |||
1995 | return ret; | ||
1996 | } | ||
1997 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | ||
1998 | index e8bd50cf9785..9df2a8c7d35d 100644 | ||
1999 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | ||
2000 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | ||
2001 | @@ -297,12 +297,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) | ||
2002 | if (adev->uvd.vcpu_bo == NULL) | ||
2003 | return 0; | ||
2004 | |||
2005 | - for (i = 0; i < adev->uvd.max_handles; ++i) | ||
2006 | - if (atomic_read(&adev->uvd.handles[i])) | ||
2007 | - break; | ||
2008 | + /* only valid for physical mode */ | ||
2009 | + if (adev->asic_type < CHIP_POLARIS10) { | ||
2010 | + for (i = 0; i < adev->uvd.max_handles; ++i) | ||
2011 | + if (atomic_read(&adev->uvd.handles[i])) | ||
2012 | + break; | ||
2013 | |||
2014 | - if (i == AMDGPU_MAX_UVD_HANDLES) | ||
2015 | - return 0; | ||
2016 | + if (i == adev->uvd.max_handles) | ||
2017 | + return 0; | ||
2018 | + } | ||
2019 | |||
2020 | cancel_delayed_work_sync(&adev->uvd.idle_work); | ||
2021 | |||
2022 | diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | ||
2023 | index 419ba0ce7ee5..356ca560c80e 100644 | ||
2024 | --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | ||
2025 | +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | ||
2026 | @@ -4403,34 +4403,8 @@ static void gfx_v7_0_gpu_early_init(struct amdgpu_device *adev) | ||
2027 | case CHIP_KAVERI: | ||
2028 | adev->gfx.config.max_shader_engines = 1; | ||
2029 | adev->gfx.config.max_tile_pipes = 4; | ||
2030 | - if ((adev->pdev->device == 0x1304) || | ||
2031 | - (adev->pdev->device == 0x1305) || | ||
2032 | - (adev->pdev->device == 0x130C) || | ||
2033 | - (adev->pdev->device == 0x130F) || | ||
2034 | - (adev->pdev->device == 0x1310) || | ||
2035 | - (adev->pdev->device == 0x1311) || | ||
2036 | - (adev->pdev->device == 0x131C)) { | ||
2037 | - adev->gfx.config.max_cu_per_sh = 8; | ||
2038 | - adev->gfx.config.max_backends_per_se = 2; | ||
2039 | - } else if ((adev->pdev->device == 0x1309) || | ||
2040 | - (adev->pdev->device == 0x130A) || | ||
2041 | - (adev->pdev->device == 0x130D) || | ||
2042 | - (adev->pdev->device == 0x1313) || | ||
2043 | - (adev->pdev->device == 0x131D)) { | ||
2044 | - adev->gfx.config.max_cu_per_sh = 6; | ||
2045 | - adev->gfx.config.max_backends_per_se = 2; | ||
2046 | - } else if ((adev->pdev->device == 0x1306) || | ||
2047 | - (adev->pdev->device == 0x1307) || | ||
2048 | - (adev->pdev->device == 0x130B) || | ||
2049 | - (adev->pdev->device == 0x130E) || | ||
2050 | - (adev->pdev->device == 0x1315) || | ||
2051 | - (adev->pdev->device == 0x131B)) { | ||
2052 | - adev->gfx.config.max_cu_per_sh = 4; | ||
2053 | - adev->gfx.config.max_backends_per_se = 1; | ||
2054 | - } else { | ||
2055 | - adev->gfx.config.max_cu_per_sh = 3; | ||
2056 | - adev->gfx.config.max_backends_per_se = 1; | ||
2057 | - } | ||
2058 | + adev->gfx.config.max_cu_per_sh = 8; | ||
2059 | + adev->gfx.config.max_backends_per_se = 2; | ||
2060 | adev->gfx.config.max_sh_per_se = 1; | ||
2061 | adev->gfx.config.max_texture_channel_caches = 4; | ||
2062 | adev->gfx.config.max_gprs = 256; | ||
2063 | diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c | ||
2064 | index 8284d5dbfc30..4c178feeb4bd 100644 | ||
2065 | --- a/drivers/gpu/drm/amd/amdgpu/si.c | ||
2066 | +++ b/drivers/gpu/drm/amd/amdgpu/si.c | ||
2067 | @@ -31,6 +31,7 @@ | ||
2068 | #include "amdgpu_uvd.h" | ||
2069 | #include "amdgpu_vce.h" | ||
2070 | #include "atom.h" | ||
2071 | +#include "amd_pcie.h" | ||
2072 | #include "amdgpu_powerplay.h" | ||
2073 | #include "sid.h" | ||
2074 | #include "si_ih.h" | ||
2075 | @@ -1461,8 +1462,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | ||
2076 | { | ||
2077 | struct pci_dev *root = adev->pdev->bus->self; | ||
2078 | int bridge_pos, gpu_pos; | ||
2079 | - u32 speed_cntl, mask, current_data_rate; | ||
2080 | - int ret, i; | ||
2081 | + u32 speed_cntl, current_data_rate; | ||
2082 | + int i; | ||
2083 | u16 tmp16; | ||
2084 | |||
2085 | if (pci_is_root_bus(adev->pdev->bus)) | ||
2086 | @@ -1474,23 +1475,20 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | ||
2087 | if (adev->flags & AMD_IS_APU) | ||
2088 | return; | ||
2089 | |||
2090 | - ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); | ||
2091 | - if (ret != 0) | ||
2092 | - return; | ||
2093 | - | ||
2094 | - if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) | ||
2095 | + if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | | ||
2096 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) | ||
2097 | return; | ||
2098 | |||
2099 | speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); | ||
2100 | current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> | ||
2101 | LC_CURRENT_DATA_RATE_SHIFT; | ||
2102 | - if (mask & DRM_PCIE_SPEED_80) { | ||
2103 | + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { | ||
2104 | if (current_data_rate == 2) { | ||
2105 | DRM_INFO("PCIE gen 3 link speeds already enabled\n"); | ||
2106 | return; | ||
2107 | } | ||
2108 | DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n"); | ||
2109 | - } else if (mask & DRM_PCIE_SPEED_50) { | ||
2110 | + } else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) { | ||
2111 | if (current_data_rate == 1) { | ||
2112 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); | ||
2113 | return; | ||
2114 | @@ -1506,7 +1504,7 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | ||
2115 | if (!gpu_pos) | ||
2116 | return; | ||
2117 | |||
2118 | - if (mask & DRM_PCIE_SPEED_80) { | ||
2119 | + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { | ||
2120 | if (current_data_rate != 2) { | ||
2121 | u16 bridge_cfg, gpu_cfg; | ||
2122 | u16 bridge_cfg2, gpu_cfg2; | ||
2123 | @@ -1589,9 +1587,9 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | ||
2124 | |||
2125 | pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); | ||
2126 | tmp16 &= ~0xf; | ||
2127 | - if (mask & DRM_PCIE_SPEED_80) | ||
2128 | + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | ||
2129 | tmp16 |= 3; | ||
2130 | - else if (mask & DRM_PCIE_SPEED_50) | ||
2131 | + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) | ||
2132 | tmp16 |= 2; | ||
2133 | else | ||
2134 | tmp16 |= 1; | ||
2135 | diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | ||
2136 | index 3af322adae76..ea80b7ca5c37 100644 | ||
2137 | --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c | ||
2138 | +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | ||
2139 | @@ -26,6 +26,7 @@ | ||
2140 | #include "amdgpu_pm.h" | ||
2141 | #include "amdgpu_dpm.h" | ||
2142 | #include "amdgpu_atombios.h" | ||
2143 | +#include "amd_pcie.h" | ||
2144 | #include "sid.h" | ||
2145 | #include "r600_dpm.h" | ||
2146 | #include "si_dpm.h" | ||
2147 | @@ -3331,29 +3332,6 @@ static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev, | ||
2148 | } | ||
2149 | } | ||
2150 | |||
2151 | -static enum amdgpu_pcie_gen r600_get_pcie_gen_support(struct amdgpu_device *adev, | ||
2152 | - u32 sys_mask, | ||
2153 | - enum amdgpu_pcie_gen asic_gen, | ||
2154 | - enum amdgpu_pcie_gen default_gen) | ||
2155 | -{ | ||
2156 | - switch (asic_gen) { | ||
2157 | - case AMDGPU_PCIE_GEN1: | ||
2158 | - return AMDGPU_PCIE_GEN1; | ||
2159 | - case AMDGPU_PCIE_GEN2: | ||
2160 | - return AMDGPU_PCIE_GEN2; | ||
2161 | - case AMDGPU_PCIE_GEN3: | ||
2162 | - return AMDGPU_PCIE_GEN3; | ||
2163 | - default: | ||
2164 | - if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == AMDGPU_PCIE_GEN3)) | ||
2165 | - return AMDGPU_PCIE_GEN3; | ||
2166 | - else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == AMDGPU_PCIE_GEN2)) | ||
2167 | - return AMDGPU_PCIE_GEN2; | ||
2168 | - else | ||
2169 | - return AMDGPU_PCIE_GEN1; | ||
2170 | - } | ||
2171 | - return AMDGPU_PCIE_GEN1; | ||
2172 | -} | ||
2173 | - | ||
2174 | static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b, | ||
2175 | u32 *p, u32 *u) | ||
2176 | { | ||
2177 | @@ -5028,10 +5006,11 @@ static int si_populate_smc_acpi_state(struct amdgpu_device *adev, | ||
2178 | table->ACPIState.levels[0].vddc.index, | ||
2179 | &table->ACPIState.levels[0].std_vddc); | ||
2180 | } | ||
2181 | - table->ACPIState.levels[0].gen2PCIE = (u8)r600_get_pcie_gen_support(adev, | ||
2182 | - si_pi->sys_pcie_mask, | ||
2183 | - si_pi->boot_pcie_gen, | ||
2184 | - AMDGPU_PCIE_GEN1); | ||
2185 | + table->ACPIState.levels[0].gen2PCIE = | ||
2186 | + (u8)amdgpu_get_pcie_gen_support(adev, | ||
2187 | + si_pi->sys_pcie_mask, | ||
2188 | + si_pi->boot_pcie_gen, | ||
2189 | + AMDGPU_PCIE_GEN1); | ||
2190 | |||
2191 | if (si_pi->vddc_phase_shed_control) | ||
2192 | si_populate_phase_shedding_value(adev, | ||
2193 | @@ -7172,10 +7151,10 @@ static void si_parse_pplib_clock_info(struct amdgpu_device *adev, | ||
2194 | pl->vddc = le16_to_cpu(clock_info->si.usVDDC); | ||
2195 | pl->vddci = le16_to_cpu(clock_info->si.usVDDCI); | ||
2196 | pl->flags = le32_to_cpu(clock_info->si.ulFlags); | ||
2197 | - pl->pcie_gen = r600_get_pcie_gen_support(adev, | ||
2198 | - si_pi->sys_pcie_mask, | ||
2199 | - si_pi->boot_pcie_gen, | ||
2200 | - clock_info->si.ucPCIEGen); | ||
2201 | + pl->pcie_gen = amdgpu_get_pcie_gen_support(adev, | ||
2202 | + si_pi->sys_pcie_mask, | ||
2203 | + si_pi->boot_pcie_gen, | ||
2204 | + clock_info->si.ucPCIEGen); | ||
2205 | |||
2206 | /* patch up vddc if necessary */ | ||
2207 | ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc, | ||
2208 | @@ -7330,7 +7309,6 @@ static int si_dpm_init(struct amdgpu_device *adev) | ||
2209 | struct si_power_info *si_pi; | ||
2210 | struct atom_clock_dividers dividers; | ||
2211 | int ret; | ||
2212 | - u32 mask; | ||
2213 | |||
2214 | si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL); | ||
2215 | if (si_pi == NULL) | ||
2216 | @@ -7340,11 +7318,9 @@ static int si_dpm_init(struct amdgpu_device *adev) | ||
2217 | eg_pi = &ni_pi->eg; | ||
2218 | pi = &eg_pi->rv7xx; | ||
2219 | |||
2220 | - ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); | ||
2221 | - if (ret) | ||
2222 | - si_pi->sys_pcie_mask = 0; | ||
2223 | - else | ||
2224 | - si_pi->sys_pcie_mask = mask; | ||
2225 | + si_pi->sys_pcie_mask = | ||
2226 | + (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >> | ||
2227 | + CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT; | ||
2228 | si_pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID; | ||
2229 | si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev); | ||
2230 | |||
2231 | diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c | ||
2232 | index e230cc44a0a7..bd6cab5a9f43 100644 | ||
2233 | --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c | ||
2234 | +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c | ||
2235 | @@ -200,7 +200,8 @@ bool dc_stream_set_cursor_attributes( | ||
2236 | for (i = 0; i < MAX_PIPES; i++) { | ||
2237 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | ||
2238 | |||
2239 | - if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) | ||
2240 | + if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && | ||
2241 | + !pipe_ctx->plane_res.dpp) || !pipe_ctx->plane_res.ipp) | ||
2242 | continue; | ||
2243 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
2244 | continue; | ||
2245 | @@ -276,7 +277,8 @@ bool dc_stream_set_cursor_position( | ||
2246 | if (pipe_ctx->stream != stream || | ||
2247 | (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || | ||
2248 | !pipe_ctx->plane_state || | ||
2249 | - (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) | ||
2250 | + (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp) || | ||
2251 | + !pipe_ctx->plane_res.ipp) | ||
2252 | continue; | ||
2253 | |||
2254 | if (pipe_ctx->plane_state->address.type | ||
2255 | diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | ||
2256 | index fe88852b4774..00c728260616 100644 | ||
2257 | --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | ||
2258 | +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | ||
2259 | @@ -683,6 +683,7 @@ void dce110_link_encoder_construct( | ||
2260 | { | ||
2261 | struct bp_encoder_cap_info bp_cap_info = {0}; | ||
2262 | const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; | ||
2263 | + enum bp_result result = BP_RESULT_OK; | ||
2264 | |||
2265 | enc110->base.funcs = &dce110_lnk_enc_funcs; | ||
2266 | enc110->base.ctx = init_data->ctx; | ||
2267 | @@ -757,15 +758,24 @@ void dce110_link_encoder_construct( | ||
2268 | enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; | ||
2269 | } | ||
2270 | |||
2271 | + /* default to one to mirror Windows behavior */ | ||
2272 | + enc110->base.features.flags.bits.HDMI_6GB_EN = 1; | ||
2273 | + | ||
2274 | + result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios, | ||
2275 | + enc110->base.id, &bp_cap_info); | ||
2276 | + | ||
2277 | /* Override features with DCE-specific values */ | ||
2278 | - if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( | ||
2279 | - enc110->base.ctx->dc_bios, enc110->base.id, | ||
2280 | - &bp_cap_info)) { | ||
2281 | + if (BP_RESULT_OK == result) { | ||
2282 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = | ||
2283 | bp_cap_info.DP_HBR2_EN; | ||
2284 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = | ||
2285 | bp_cap_info.DP_HBR3_EN; | ||
2286 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; | ||
2287 | + } else { | ||
2288 | + dm_logger_write(enc110->base.ctx->logger, LOG_WARNING, | ||
2289 | + "%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", | ||
2290 | + __func__, | ||
2291 | + result); | ||
2292 | } | ||
2293 | } | ||
2294 | |||
2295 | diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | ||
2296 | index e33ec7fc5d09..6688cdb216e9 100644 | ||
2297 | --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | ||
2298 | +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | ||
2299 | @@ -2791,10 +2791,13 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, | ||
2300 | PHM_PlatformCaps_DisableMclkSwitchingForFrameLock); | ||
2301 | |||
2302 | |||
2303 | - disable_mclk_switching = ((1 < info.display_count) || | ||
2304 | - disable_mclk_switching_for_frame_lock || | ||
2305 | - smu7_vblank_too_short(hwmgr, mode_info.vblank_time_us) || | ||
2306 | - (mode_info.refresh_rate > 120)); | ||
2307 | + if (info.display_count == 0) | ||
2308 | + disable_mclk_switching = false; | ||
2309 | + else | ||
2310 | + disable_mclk_switching = ((1 < info.display_count) || | ||
2311 | + disable_mclk_switching_for_frame_lock || | ||
2312 | + smu7_vblank_too_short(hwmgr, mode_info.vblank_time_us) || | ||
2313 | + (mode_info.refresh_rate > 120)); | ||
2314 | |||
2315 | sclk = smu7_ps->performance_levels[0].engine_clock; | ||
2316 | mclk = smu7_ps->performance_levels[0].memory_clock; | ||
2317 | @@ -4569,13 +4572,6 @@ static int smu7_set_power_profile_state(struct pp_hwmgr *hwmgr, | ||
2318 | int tmp_result, result = 0; | ||
2319 | uint32_t sclk_mask = 0, mclk_mask = 0; | ||
2320 | |||
2321 | - if (hwmgr->chip_id == CHIP_FIJI) { | ||
2322 | - if (request->type == AMD_PP_GFX_PROFILE) | ||
2323 | - smu7_enable_power_containment(hwmgr); | ||
2324 | - else if (request->type == AMD_PP_COMPUTE_PROFILE) | ||
2325 | - smu7_disable_power_containment(hwmgr); | ||
2326 | - } | ||
2327 | - | ||
2328 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_AUTO) | ||
2329 | return -EINVAL; | ||
2330 | |||
2331 | diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | ||
2332 | index f8d838c2c8ee..9acbefb33bd6 100644 | ||
2333 | --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | ||
2334 | +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | ||
2335 | @@ -3208,10 +3208,13 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, | ||
2336 | disable_mclk_switching_for_vr = PP_CAP(PHM_PlatformCaps_DisableMclkSwitchForVR); | ||
2337 | force_mclk_high = PP_CAP(PHM_PlatformCaps_ForceMclkHigh); | ||
2338 | |||
2339 | - disable_mclk_switching = (info.display_count > 1) || | ||
2340 | - disable_mclk_switching_for_frame_lock || | ||
2341 | - disable_mclk_switching_for_vr || | ||
2342 | - force_mclk_high; | ||
2343 | + if (info.display_count == 0) | ||
2344 | + disable_mclk_switching = false; | ||
2345 | + else | ||
2346 | + disable_mclk_switching = (info.display_count > 1) || | ||
2347 | + disable_mclk_switching_for_frame_lock || | ||
2348 | + disable_mclk_switching_for_vr || | ||
2349 | + force_mclk_high; | ||
2350 | |||
2351 | sclk = vega10_ps->performance_levels[0].gfx_clock; | ||
2352 | mclk = vega10_ps->performance_levels[0].mem_clock; | ||
2353 | diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c | ||
2354 | index 279c1035c12d..5e1f1e2deb52 100644 | ||
2355 | --- a/drivers/gpu/drm/drm_framebuffer.c | ||
2356 | +++ b/drivers/gpu/drm/drm_framebuffer.c | ||
2357 | @@ -118,6 +118,10 @@ int drm_mode_addfb(struct drm_device *dev, | ||
2358 | r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); | ||
2359 | r.handles[0] = or->handle; | ||
2360 | |||
2361 | + if (r.pixel_format == DRM_FORMAT_XRGB2101010 && | ||
2362 | + dev->driver->driver_features & DRIVER_PREFER_XBGR_30BPP) | ||
2363 | + r.pixel_format = DRM_FORMAT_XBGR2101010; | ||
2364 | + | ||
2365 | ret = drm_mode_addfb2(dev, &r, file_priv); | ||
2366 | if (ret) | ||
2367 | return ret; | ||
2368 | diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c | ||
2369 | index 6dc2dde5b672..7a6b2dc08913 100644 | ||
2370 | --- a/drivers/gpu/drm/drm_probe_helper.c | ||
2371 | +++ b/drivers/gpu/drm/drm_probe_helper.c | ||
2372 | @@ -654,6 +654,26 @@ static void output_poll_execute(struct work_struct *work) | ||
2373 | schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); | ||
2374 | } | ||
2375 | |||
2376 | +/** | ||
2377 | + * drm_kms_helper_is_poll_worker - is %current task an output poll worker? | ||
2378 | + * | ||
2379 | + * Determine if %current task is an output poll worker. This can be used | ||
2380 | + * to select distinct code paths for output polling versus other contexts. | ||
2381 | + * | ||
2382 | + * One use case is to avoid a deadlock between the output poll worker and | ||
2383 | + * the autosuspend worker wherein the latter waits for polling to finish | ||
2384 | + * upon calling drm_kms_helper_poll_disable(), while the former waits for | ||
2385 | + * runtime suspend to finish upon calling pm_runtime_get_sync() in a | ||
2386 | + * connector ->detect hook. | ||
2387 | + */ | ||
2388 | +bool drm_kms_helper_is_poll_worker(void) | ||
2389 | +{ | ||
2390 | + struct work_struct *work = current_work(); | ||
2391 | + | ||
2392 | + return work && work->func == output_poll_execute; | ||
2393 | +} | ||
2394 | +EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); | ||
2395 | + | ||
2396 | /** | ||
2397 | * drm_kms_helper_poll_disable - disable output polling | ||
2398 | * @dev: drm_device | ||
2399 | diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c | ||
2400 | index 2cf10d17acfb..62004ea403c6 100644 | ||
2401 | --- a/drivers/gpu/drm/i915/i915_drv.c | ||
2402 | +++ b/drivers/gpu/drm/i915/i915_drv.c | ||
2403 | @@ -1827,6 +1827,8 @@ static int i915_drm_resume_early(struct drm_device *dev) | ||
2404 | if (IS_GEN9_LP(dev_priv) || | ||
2405 | !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload)) | ||
2406 | intel_power_domains_init_hw(dev_priv, true); | ||
2407 | + else | ||
2408 | + intel_display_set_init_power(dev_priv, true); | ||
2409 | |||
2410 | i915_gem_sanitize(dev_priv); | ||
2411 | |||
2412 | diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | ||
2413 | index 435ed95df144..3d0ae387691f 100644 | ||
2414 | --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c | ||
2415 | +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | ||
2416 | @@ -505,6 +505,8 @@ eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma) | ||
2417 | list_add_tail(&vma->exec_link, &eb->unbound); | ||
2418 | if (drm_mm_node_allocated(&vma->node)) | ||
2419 | err = i915_vma_unbind(vma); | ||
2420 | + if (unlikely(err)) | ||
2421 | + vma->exec_flags = NULL; | ||
2422 | } | ||
2423 | return err; | ||
2424 | } | ||
2425 | @@ -2419,7 +2421,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, | ||
2426 | if (out_fence) { | ||
2427 | if (err == 0) { | ||
2428 | fd_install(out_fence_fd, out_fence->file); | ||
2429 | - args->rsvd2 &= GENMASK_ULL(0, 31); /* keep in-fence */ | ||
2430 | + args->rsvd2 &= GENMASK_ULL(31, 0); /* keep in-fence */ | ||
2431 | args->rsvd2 |= (u64)out_fence_fd << 32; | ||
2432 | out_fence_fd = -1; | ||
2433 | } else { | ||
2434 | diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c | ||
2435 | index 59ee808f8fd9..cc2a10f22c3d 100644 | ||
2436 | --- a/drivers/gpu/drm/i915/i915_perf.c | ||
2437 | +++ b/drivers/gpu/drm/i915/i915_perf.c | ||
2438 | @@ -1301,9 +1301,8 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream) | ||
2439 | */ | ||
2440 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
2441 | dev_priv->perf.oa.exclusive_stream = NULL; | ||
2442 | - mutex_unlock(&dev_priv->drm.struct_mutex); | ||
2443 | - | ||
2444 | dev_priv->perf.oa.ops.disable_metric_set(dev_priv); | ||
2445 | + mutex_unlock(&dev_priv->drm.struct_mutex); | ||
2446 | |||
2447 | free_oa_buffer(dev_priv); | ||
2448 | |||
2449 | @@ -1755,22 +1754,13 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr | ||
2450 | * Note: it's only the RCS/Render context that has any OA state. | ||
2451 | */ | ||
2452 | static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, | ||
2453 | - const struct i915_oa_config *oa_config, | ||
2454 | - bool interruptible) | ||
2455 | + const struct i915_oa_config *oa_config) | ||
2456 | { | ||
2457 | struct i915_gem_context *ctx; | ||
2458 | int ret; | ||
2459 | unsigned int wait_flags = I915_WAIT_LOCKED; | ||
2460 | |||
2461 | - if (interruptible) { | ||
2462 | - ret = i915_mutex_lock_interruptible(&dev_priv->drm); | ||
2463 | - if (ret) | ||
2464 | - return ret; | ||
2465 | - | ||
2466 | - wait_flags |= I915_WAIT_INTERRUPTIBLE; | ||
2467 | - } else { | ||
2468 | - mutex_lock(&dev_priv->drm.struct_mutex); | ||
2469 | - } | ||
2470 | + lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
2471 | |||
2472 | /* Switch away from any user context. */ | ||
2473 | ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config); | ||
2474 | @@ -1818,8 +1808,6 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, | ||
2475 | } | ||
2476 | |||
2477 | out: | ||
2478 | - mutex_unlock(&dev_priv->drm.struct_mutex); | ||
2479 | - | ||
2480 | return ret; | ||
2481 | } | ||
2482 | |||
2483 | @@ -1862,7 +1850,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv, | ||
2484 | * to make sure all slices/subslices are ON before writing to NOA | ||
2485 | * registers. | ||
2486 | */ | ||
2487 | - ret = gen8_configure_all_contexts(dev_priv, oa_config, true); | ||
2488 | + ret = gen8_configure_all_contexts(dev_priv, oa_config); | ||
2489 | if (ret) | ||
2490 | return ret; | ||
2491 | |||
2492 | @@ -1877,7 +1865,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv, | ||
2493 | static void gen8_disable_metric_set(struct drm_i915_private *dev_priv) | ||
2494 | { | ||
2495 | /* Reset all contexts' slices/subslices configurations. */ | ||
2496 | - gen8_configure_all_contexts(dev_priv, NULL, false); | ||
2497 | + gen8_configure_all_contexts(dev_priv, NULL); | ||
2498 | |||
2499 | I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) & | ||
2500 | ~GT_NOA_ENABLE)); | ||
2501 | @@ -2127,6 +2115,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream, | ||
2502 | if (ret) | ||
2503 | goto err_oa_buf_alloc; | ||
2504 | |||
2505 | + ret = i915_mutex_lock_interruptible(&dev_priv->drm); | ||
2506 | + if (ret) | ||
2507 | + goto err_lock; | ||
2508 | + | ||
2509 | ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv, | ||
2510 | stream->oa_config); | ||
2511 | if (ret) | ||
2512 | @@ -2134,23 +2126,17 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream, | ||
2513 | |||
2514 | stream->ops = &i915_oa_stream_ops; | ||
2515 | |||
2516 | - /* Lock device for exclusive_stream access late because | ||
2517 | - * enable_metric_set() might lock as well on gen8+. | ||
2518 | - */ | ||
2519 | - ret = i915_mutex_lock_interruptible(&dev_priv->drm); | ||
2520 | - if (ret) | ||
2521 | - goto err_lock; | ||
2522 | - | ||
2523 | dev_priv->perf.oa.exclusive_stream = stream; | ||
2524 | |||
2525 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
2526 | |||
2527 | return 0; | ||
2528 | |||
2529 | -err_lock: | ||
2530 | +err_enable: | ||
2531 | dev_priv->perf.oa.ops.disable_metric_set(dev_priv); | ||
2532 | + mutex_unlock(&dev_priv->drm.struct_mutex); | ||
2533 | |||
2534 | -err_enable: | ||
2535 | +err_lock: | ||
2536 | free_oa_buffer(dev_priv); | ||
2537 | |||
2538 | err_oa_buf_alloc: | ||
2539 | diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c | ||
2540 | index 0ddba16fde1b..538a762f7318 100644 | ||
2541 | --- a/drivers/gpu/drm/i915/intel_audio.c | ||
2542 | +++ b/drivers/gpu/drm/i915/intel_audio.c | ||
2543 | @@ -754,11 +754,11 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv, | ||
2544 | { | ||
2545 | struct intel_encoder *encoder; | ||
2546 | |||
2547 | - if (WARN_ON(pipe >= INTEL_INFO(dev_priv)->num_pipes)) | ||
2548 | - return NULL; | ||
2549 | - | ||
2550 | /* MST */ | ||
2551 | if (pipe >= 0) { | ||
2552 | + if (WARN_ON(pipe >= ARRAY_SIZE(dev_priv->av_enc_map))) | ||
2553 | + return NULL; | ||
2554 | + | ||
2555 | encoder = dev_priv->av_enc_map[pipe]; | ||
2556 | /* | ||
2557 | * when bootup, audio driver may not know it is | ||
2558 | diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c | ||
2559 | index 50f8443641b8..a83e18c72f7b 100644 | ||
2560 | --- a/drivers/gpu/drm/i915/intel_display.c | ||
2561 | +++ b/drivers/gpu/drm/i915/intel_display.c | ||
2562 | @@ -14463,6 +14463,8 @@ static void sanitize_watermarks(struct drm_device *dev) | ||
2563 | |||
2564 | cs->wm.need_postvbl_update = true; | ||
2565 | dev_priv->display.optimize_watermarks(intel_state, cs); | ||
2566 | + | ||
2567 | + to_intel_crtc_state(crtc->state)->wm = cs->wm; | ||
2568 | } | ||
2569 | |||
2570 | put_state: | ||
2571 | diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c | ||
2572 | index 4dea833f9d1b..847cda4c017c 100644 | ||
2573 | --- a/drivers/gpu/drm/i915/intel_hdmi.c | ||
2574 | +++ b/drivers/gpu/drm/i915/intel_hdmi.c | ||
2575 | @@ -1573,12 +1573,20 @@ intel_hdmi_set_edid(struct drm_connector *connector) | ||
2576 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | ||
2577 | struct edid *edid; | ||
2578 | bool connected = false; | ||
2579 | + struct i2c_adapter *i2c; | ||
2580 | |||
2581 | intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); | ||
2582 | |||
2583 | - edid = drm_get_edid(connector, | ||
2584 | - intel_gmbus_get_adapter(dev_priv, | ||
2585 | - intel_hdmi->ddc_bus)); | ||
2586 | + i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); | ||
2587 | + | ||
2588 | + edid = drm_get_edid(connector, i2c); | ||
2589 | + | ||
2590 | + if (!edid && !intel_gmbus_is_forced_bit(i2c)) { | ||
2591 | + DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n"); | ||
2592 | + intel_gmbus_force_bit(i2c, true); | ||
2593 | + edid = drm_get_edid(connector, i2c); | ||
2594 | + intel_gmbus_force_bit(i2c, false); | ||
2595 | + } | ||
2596 | |||
2597 | intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); | ||
2598 | |||
2599 | diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c | ||
2600 | index 7e115f3927f6..d169bfb98368 100644 | ||
2601 | --- a/drivers/gpu/drm/i915/intel_runtime_pm.c | ||
2602 | +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | ||
2603 | @@ -1844,6 +1844,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | ||
2604 | CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ | ||
2605 | BIT_ULL(POWER_DOMAIN_MODESET) | \ | ||
2606 | BIT_ULL(POWER_DOMAIN_AUX_A) | \ | ||
2607 | + BIT_ULL(POWER_DOMAIN_GMBUS) | \ | ||
2608 | BIT_ULL(POWER_DOMAIN_INIT)) | ||
2609 | |||
2610 | static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { | ||
2611 | diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c | ||
2612 | index 69d6e61a01ec..6ed9cb053dfa 100644 | ||
2613 | --- a/drivers/gpu/drm/nouveau/nouveau_connector.c | ||
2614 | +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | ||
2615 | @@ -570,9 +570,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) | ||
2616 | nv_connector->edid = NULL; | ||
2617 | } | ||
2618 | |||
2619 | - ret = pm_runtime_get_sync(connector->dev->dev); | ||
2620 | - if (ret < 0 && ret != -EACCES) | ||
2621 | - return conn_status; | ||
2622 | + /* Outputs are only polled while runtime active, so acquiring a | ||
2623 | + * runtime PM ref here is unnecessary (and would deadlock upon | ||
2624 | + * runtime suspend because it waits for polling to finish). | ||
2625 | + */ | ||
2626 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2627 | + ret = pm_runtime_get_sync(connector->dev->dev); | ||
2628 | + if (ret < 0 && ret != -EACCES) | ||
2629 | + return conn_status; | ||
2630 | + } | ||
2631 | |||
2632 | nv_encoder = nouveau_connector_ddc_detect(connector); | ||
2633 | if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { | ||
2634 | @@ -647,8 +653,10 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) | ||
2635 | |||
2636 | out: | ||
2637 | |||
2638 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
2639 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
2640 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2641 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
2642 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
2643 | + } | ||
2644 | |||
2645 | return conn_status; | ||
2646 | } | ||
2647 | diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c | ||
2648 | index 584466ef688f..325bff420f5a 100644 | ||
2649 | --- a/drivers/gpu/drm/nouveau/nv50_display.c | ||
2650 | +++ b/drivers/gpu/drm/nouveau/nv50_display.c | ||
2651 | @@ -4426,6 +4426,7 @@ nv50_display_create(struct drm_device *dev) | ||
2652 | nouveau_display(dev)->fini = nv50_display_fini; | ||
2653 | disp->disp = &nouveau_display(dev)->disp; | ||
2654 | dev->mode_config.funcs = &nv50_disp_func; | ||
2655 | + dev->driver->driver_features |= DRIVER_PREFER_XBGR_30BPP; | ||
2656 | if (nouveau_atomic) | ||
2657 | dev->driver->driver_features |= DRIVER_ATOMIC; | ||
2658 | |||
2659 | diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c | ||
2660 | index a6511918f632..8ce36cf42055 100644 | ||
2661 | --- a/drivers/gpu/drm/radeon/cik.c | ||
2662 | +++ b/drivers/gpu/drm/radeon/cik.c | ||
2663 | @@ -3228,35 +3228,8 @@ static void cik_gpu_init(struct radeon_device *rdev) | ||
2664 | case CHIP_KAVERI: | ||
2665 | rdev->config.cik.max_shader_engines = 1; | ||
2666 | rdev->config.cik.max_tile_pipes = 4; | ||
2667 | - if ((rdev->pdev->device == 0x1304) || | ||
2668 | - (rdev->pdev->device == 0x1305) || | ||
2669 | - (rdev->pdev->device == 0x130C) || | ||
2670 | - (rdev->pdev->device == 0x130F) || | ||
2671 | - (rdev->pdev->device == 0x1310) || | ||
2672 | - (rdev->pdev->device == 0x1311) || | ||
2673 | - (rdev->pdev->device == 0x131C)) { | ||
2674 | - rdev->config.cik.max_cu_per_sh = 8; | ||
2675 | - rdev->config.cik.max_backends_per_se = 2; | ||
2676 | - } else if ((rdev->pdev->device == 0x1309) || | ||
2677 | - (rdev->pdev->device == 0x130A) || | ||
2678 | - (rdev->pdev->device == 0x130D) || | ||
2679 | - (rdev->pdev->device == 0x1313) || | ||
2680 | - (rdev->pdev->device == 0x131D)) { | ||
2681 | - rdev->config.cik.max_cu_per_sh = 6; | ||
2682 | - rdev->config.cik.max_backends_per_se = 2; | ||
2683 | - } else if ((rdev->pdev->device == 0x1306) || | ||
2684 | - (rdev->pdev->device == 0x1307) || | ||
2685 | - (rdev->pdev->device == 0x130B) || | ||
2686 | - (rdev->pdev->device == 0x130E) || | ||
2687 | - (rdev->pdev->device == 0x1315) || | ||
2688 | - (rdev->pdev->device == 0x1318) || | ||
2689 | - (rdev->pdev->device == 0x131B)) { | ||
2690 | - rdev->config.cik.max_cu_per_sh = 4; | ||
2691 | - rdev->config.cik.max_backends_per_se = 1; | ||
2692 | - } else { | ||
2693 | - rdev->config.cik.max_cu_per_sh = 3; | ||
2694 | - rdev->config.cik.max_backends_per_se = 1; | ||
2695 | - } | ||
2696 | + rdev->config.cik.max_cu_per_sh = 8; | ||
2697 | + rdev->config.cik.max_backends_per_se = 2; | ||
2698 | rdev->config.cik.max_sh_per_se = 1; | ||
2699 | rdev->config.cik.max_texture_channel_caches = 4; | ||
2700 | rdev->config.cik.max_gprs = 256; | ||
2701 | diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c | ||
2702 | index 59dcefb2df3b..30e129684c7c 100644 | ||
2703 | --- a/drivers/gpu/drm/radeon/radeon_connectors.c | ||
2704 | +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | ||
2705 | @@ -900,9 +900,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | ||
2706 | enum drm_connector_status ret = connector_status_disconnected; | ||
2707 | int r; | ||
2708 | |||
2709 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
2710 | - if (r < 0) | ||
2711 | - return connector_status_disconnected; | ||
2712 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2713 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
2714 | + if (r < 0) | ||
2715 | + return connector_status_disconnected; | ||
2716 | + } | ||
2717 | |||
2718 | if (encoder) { | ||
2719 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2720 | @@ -925,8 +927,12 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | ||
2721 | /* check acpi lid status ??? */ | ||
2722 | |||
2723 | radeon_connector_update_scratch_regs(connector, ret); | ||
2724 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
2725 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
2726 | + | ||
2727 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2728 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
2729 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
2730 | + } | ||
2731 | + | ||
2732 | return ret; | ||
2733 | } | ||
2734 | |||
2735 | @@ -1040,9 +1046,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | ||
2736 | enum drm_connector_status ret = connector_status_disconnected; | ||
2737 | int r; | ||
2738 | |||
2739 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
2740 | - if (r < 0) | ||
2741 | - return connector_status_disconnected; | ||
2742 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2743 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
2744 | + if (r < 0) | ||
2745 | + return connector_status_disconnected; | ||
2746 | + } | ||
2747 | |||
2748 | encoder = radeon_best_single_encoder(connector); | ||
2749 | if (!encoder) | ||
2750 | @@ -1109,8 +1117,10 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | ||
2751 | radeon_connector_update_scratch_regs(connector, ret); | ||
2752 | |||
2753 | out: | ||
2754 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
2755 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
2756 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2757 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
2758 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
2759 | + } | ||
2760 | |||
2761 | return ret; | ||
2762 | } | ||
2763 | @@ -1174,9 +1184,11 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | ||
2764 | if (!radeon_connector->dac_load_detect) | ||
2765 | return ret; | ||
2766 | |||
2767 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
2768 | - if (r < 0) | ||
2769 | - return connector_status_disconnected; | ||
2770 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2771 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
2772 | + if (r < 0) | ||
2773 | + return connector_status_disconnected; | ||
2774 | + } | ||
2775 | |||
2776 | encoder = radeon_best_single_encoder(connector); | ||
2777 | if (!encoder) | ||
2778 | @@ -1188,8 +1200,12 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | ||
2779 | if (ret == connector_status_connected) | ||
2780 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); | ||
2781 | radeon_connector_update_scratch_regs(connector, ret); | ||
2782 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
2783 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
2784 | + | ||
2785 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2786 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
2787 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
2788 | + } | ||
2789 | + | ||
2790 | return ret; | ||
2791 | } | ||
2792 | |||
2793 | @@ -1252,9 +1268,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | ||
2794 | enum drm_connector_status ret = connector_status_disconnected; | ||
2795 | bool dret = false, broken_edid = false; | ||
2796 | |||
2797 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
2798 | - if (r < 0) | ||
2799 | - return connector_status_disconnected; | ||
2800 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2801 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
2802 | + if (r < 0) | ||
2803 | + return connector_status_disconnected; | ||
2804 | + } | ||
2805 | |||
2806 | if (radeon_connector->detected_hpd_without_ddc) { | ||
2807 | force = true; | ||
2808 | @@ -1437,8 +1455,10 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | ||
2809 | } | ||
2810 | |||
2811 | exit: | ||
2812 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
2813 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
2814 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2815 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
2816 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
2817 | + } | ||
2818 | |||
2819 | return ret; | ||
2820 | } | ||
2821 | @@ -1689,9 +1709,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | ||
2822 | if (radeon_dig_connector->is_mst) | ||
2823 | return connector_status_disconnected; | ||
2824 | |||
2825 | - r = pm_runtime_get_sync(connector->dev->dev); | ||
2826 | - if (r < 0) | ||
2827 | - return connector_status_disconnected; | ||
2828 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2829 | + r = pm_runtime_get_sync(connector->dev->dev); | ||
2830 | + if (r < 0) | ||
2831 | + return connector_status_disconnected; | ||
2832 | + } | ||
2833 | |||
2834 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
2835 | ret = connector->status; | ||
2836 | @@ -1778,8 +1800,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | ||
2837 | } | ||
2838 | |||
2839 | out: | ||
2840 | - pm_runtime_mark_last_busy(connector->dev->dev); | ||
2841 | - pm_runtime_put_autosuspend(connector->dev->dev); | ||
2842 | + if (!drm_kms_helper_is_poll_worker()) { | ||
2843 | + pm_runtime_mark_last_busy(connector->dev->dev); | ||
2844 | + pm_runtime_put_autosuspend(connector->dev->dev); | ||
2845 | + } | ||
2846 | |||
2847 | return ret; | ||
2848 | } | ||
2849 | diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c | ||
2850 | index ffc10cadcf34..32b577c776b9 100644 | ||
2851 | --- a/drivers/gpu/drm/radeon/radeon_device.c | ||
2852 | +++ b/drivers/gpu/drm/radeon/radeon_device.c | ||
2853 | @@ -1397,6 +1397,10 @@ int radeon_device_init(struct radeon_device *rdev, | ||
2854 | if ((rdev->flags & RADEON_IS_PCI) && | ||
2855 | (rdev->family <= CHIP_RS740)) | ||
2856 | rdev->need_dma32 = true; | ||
2857 | +#ifdef CONFIG_PPC64 | ||
2858 | + if (rdev->family == CHIP_CEDAR) | ||
2859 | + rdev->need_dma32 = true; | ||
2860 | +#endif | ||
2861 | |||
2862 | dma_bits = rdev->need_dma32 ? 32 : 40; | ||
2863 | r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); | ||
2864 | diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c | ||
2865 | index 326ad068c15a..4b6542538ff9 100644 | ||
2866 | --- a/drivers/gpu/drm/radeon/radeon_pm.c | ||
2867 | +++ b/drivers/gpu/drm/radeon/radeon_pm.c | ||
2868 | @@ -47,7 +47,6 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev); | ||
2869 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); | ||
2870 | static void radeon_pm_update_profile(struct radeon_device *rdev); | ||
2871 | static void radeon_pm_set_clocks(struct radeon_device *rdev); | ||
2872 | -static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev); | ||
2873 | |||
2874 | int radeon_pm_get_type_index(struct radeon_device *rdev, | ||
2875 | enum radeon_pm_state_type ps_type, | ||
2876 | @@ -80,8 +79,6 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev) | ||
2877 | radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power); | ||
2878 | } | ||
2879 | mutex_unlock(&rdev->pm.mutex); | ||
2880 | - /* allow new DPM state to be picked */ | ||
2881 | - radeon_pm_compute_clocks_dpm(rdev); | ||
2882 | } else if (rdev->pm.pm_method == PM_METHOD_PROFILE) { | ||
2883 | if (rdev->pm.profile == PM_PROFILE_AUTO) { | ||
2884 | mutex_lock(&rdev->pm.mutex); | ||
2885 | @@ -885,8 +882,7 @@ static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, | ||
2886 | dpm_state = POWER_STATE_TYPE_INTERNAL_3DPERF; | ||
2887 | /* balanced states don't exist at the moment */ | ||
2888 | if (dpm_state == POWER_STATE_TYPE_BALANCED) | ||
2889 | - dpm_state = rdev->pm.dpm.ac_power ? | ||
2890 | - POWER_STATE_TYPE_PERFORMANCE : POWER_STATE_TYPE_BATTERY; | ||
2891 | + dpm_state = POWER_STATE_TYPE_PERFORMANCE; | ||
2892 | |||
2893 | restart_search: | ||
2894 | /* Pick the best power state based on current conditions */ | ||
2895 | diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c | ||
2896 | index d7d042a20ab4..4dff06ab771e 100644 | ||
2897 | --- a/drivers/infiniband/core/device.c | ||
2898 | +++ b/drivers/infiniband/core/device.c | ||
2899 | @@ -534,14 +534,14 @@ int ib_register_device(struct ib_device *device, | ||
2900 | ret = device->query_device(device, &device->attrs, &uhw); | ||
2901 | if (ret) { | ||
2902 | pr_warn("Couldn't query the device attributes\n"); | ||
2903 | - goto cache_cleanup; | ||
2904 | + goto cg_cleanup; | ||
2905 | } | ||
2906 | |||
2907 | ret = ib_device_register_sysfs(device, port_callback); | ||
2908 | if (ret) { | ||
2909 | pr_warn("Couldn't register device %s with driver model\n", | ||
2910 | device->name); | ||
2911 | - goto cache_cleanup; | ||
2912 | + goto cg_cleanup; | ||
2913 | } | ||
2914 | |||
2915 | device->reg_state = IB_DEV_REGISTERED; | ||
2916 | @@ -557,6 +557,8 @@ int ib_register_device(struct ib_device *device, | ||
2917 | mutex_unlock(&device_mutex); | ||
2918 | return 0; | ||
2919 | |||
2920 | +cg_cleanup: | ||
2921 | + ib_device_unregister_rdmacg(device); | ||
2922 | cache_cleanup: | ||
2923 | ib_cache_cleanup_one(device); | ||
2924 | ib_cache_release_one(device); | ||
2925 | diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c | ||
2926 | index 4e1f76730855..9cb801d1fe54 100644 | ||
2927 | --- a/drivers/infiniband/core/rdma_core.c | ||
2928 | +++ b/drivers/infiniband/core/rdma_core.c | ||
2929 | @@ -407,13 +407,13 @@ static int __must_check remove_commit_fd_uobject(struct ib_uobject *uobj, | ||
2930 | return ret; | ||
2931 | } | ||
2932 | |||
2933 | -static void lockdep_check(struct ib_uobject *uobj, bool exclusive) | ||
2934 | +static void assert_uverbs_usecnt(struct ib_uobject *uobj, bool exclusive) | ||
2935 | { | ||
2936 | #ifdef CONFIG_LOCKDEP | ||
2937 | if (exclusive) | ||
2938 | - WARN_ON(atomic_read(&uobj->usecnt) > 0); | ||
2939 | + WARN_ON(atomic_read(&uobj->usecnt) != -1); | ||
2940 | else | ||
2941 | - WARN_ON(atomic_read(&uobj->usecnt) == -1); | ||
2942 | + WARN_ON(atomic_read(&uobj->usecnt) <= 0); | ||
2943 | #endif | ||
2944 | } | ||
2945 | |||
2946 | @@ -452,7 +452,7 @@ int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj) | ||
2947 | WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); | ||
2948 | return 0; | ||
2949 | } | ||
2950 | - lockdep_check(uobj, true); | ||
2951 | + assert_uverbs_usecnt(uobj, true); | ||
2952 | ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_DESTROY); | ||
2953 | |||
2954 | up_read(&ucontext->cleanup_rwsem); | ||
2955 | @@ -482,7 +482,7 @@ int rdma_explicit_destroy(struct ib_uobject *uobject) | ||
2956 | WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); | ||
2957 | return 0; | ||
2958 | } | ||
2959 | - lockdep_check(uobject, true); | ||
2960 | + assert_uverbs_usecnt(uobject, true); | ||
2961 | ret = uobject->type->type_class->remove_commit(uobject, | ||
2962 | RDMA_REMOVE_DESTROY); | ||
2963 | if (ret) | ||
2964 | @@ -569,7 +569,7 @@ static void lookup_put_fd_uobject(struct ib_uobject *uobj, bool exclusive) | ||
2965 | |||
2966 | void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive) | ||
2967 | { | ||
2968 | - lockdep_check(uobj, exclusive); | ||
2969 | + assert_uverbs_usecnt(uobj, exclusive); | ||
2970 | uobj->type->type_class->lookup_put(uobj, exclusive); | ||
2971 | /* | ||
2972 | * In order to unlock an object, either decrease its usecnt for | ||
2973 | diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c | ||
2974 | index eb85b546e223..c8b3a45e9edc 100644 | ||
2975 | --- a/drivers/infiniband/core/ucma.c | ||
2976 | +++ b/drivers/infiniband/core/ucma.c | ||
2977 | @@ -1148,6 +1148,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, | ||
2978 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
2979 | return -EFAULT; | ||
2980 | |||
2981 | + if (cmd.qp_state > IB_QPS_ERR) | ||
2982 | + return -EINVAL; | ||
2983 | + | ||
2984 | ctx = ucma_get_ctx(file, cmd.id); | ||
2985 | if (IS_ERR(ctx)) | ||
2986 | return PTR_ERR(ctx); | ||
2987 | @@ -1293,6 +1296,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, | ||
2988 | if (IS_ERR(ctx)) | ||
2989 | return PTR_ERR(ctx); | ||
2990 | |||
2991 | + if (unlikely(cmd.optval > KMALLOC_MAX_SIZE)) | ||
2992 | + return -EINVAL; | ||
2993 | + | ||
2994 | optval = memdup_user((void __user *) (unsigned long) cmd.optval, | ||
2995 | cmd.optlen); | ||
2996 | if (IS_ERR(optval)) { | ||
2997 | diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c | ||
2998 | index 18705cbcdc8c..8b179238f405 100644 | ||
2999 | --- a/drivers/infiniband/hw/mlx5/cq.c | ||
3000 | +++ b/drivers/infiniband/hw/mlx5/cq.c | ||
3001 | @@ -1177,7 +1177,12 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, | ||
3002 | if (ucmd.reserved0 || ucmd.reserved1) | ||
3003 | return -EINVAL; | ||
3004 | |||
3005 | - umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size, | ||
3006 | + /* check multiplication overflow */ | ||
3007 | + if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1) | ||
3008 | + return -EINVAL; | ||
3009 | + | ||
3010 | + umem = ib_umem_get(context, ucmd.buf_addr, | ||
3011 | + (size_t)ucmd.cqe_size * entries, | ||
3012 | IB_ACCESS_LOCAL_WRITE, 1); | ||
3013 | if (IS_ERR(umem)) { | ||
3014 | err = PTR_ERR(umem); | ||
3015 | diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c | ||
3016 | index d109fe8290a7..3832edd867ed 100644 | ||
3017 | --- a/drivers/infiniband/hw/mlx5/mr.c | ||
3018 | +++ b/drivers/infiniband/hw/mlx5/mr.c | ||
3019 | @@ -1813,7 +1813,6 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, | ||
3020 | |||
3021 | mr->ibmr.iova = sg_dma_address(sg) + sg_offset; | ||
3022 | mr->ibmr.length = 0; | ||
3023 | - mr->ndescs = sg_nents; | ||
3024 | |||
3025 | for_each_sg(sgl, sg, sg_nents, i) { | ||
3026 | if (unlikely(i >= mr->max_descs)) | ||
3027 | @@ -1825,6 +1824,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr, | ||
3028 | |||
3029 | sg_offset = 0; | ||
3030 | } | ||
3031 | + mr->ndescs = i; | ||
3032 | |||
3033 | if (sg_offset_p) | ||
3034 | *sg_offset_p = sg_offset; | ||
3035 | diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c | ||
3036 | index 1f316d66e6f7..41614c185918 100644 | ||
3037 | --- a/drivers/input/keyboard/matrix_keypad.c | ||
3038 | +++ b/drivers/input/keyboard/matrix_keypad.c | ||
3039 | @@ -218,8 +218,10 @@ static void matrix_keypad_stop(struct input_dev *dev) | ||
3040 | { | ||
3041 | struct matrix_keypad *keypad = input_get_drvdata(dev); | ||
3042 | |||
3043 | + spin_lock_irq(&keypad->lock); | ||
3044 | keypad->stopped = true; | ||
3045 | - mb(); | ||
3046 | + spin_unlock_irq(&keypad->lock); | ||
3047 | + | ||
3048 | flush_work(&keypad->work.work); | ||
3049 | /* | ||
3050 | * matrix_keypad_scan() will leave IRQs enabled; | ||
3051 | diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c | ||
3052 | index cd9f61cb3fc6..ee5466a374bf 100644 | ||
3053 | --- a/drivers/input/mouse/synaptics.c | ||
3054 | +++ b/drivers/input/mouse/synaptics.c | ||
3055 | @@ -173,7 +173,6 @@ static const char * const smbus_pnp_ids[] = { | ||
3056 | "LEN0046", /* X250 */ | ||
3057 | "LEN004a", /* W541 */ | ||
3058 | "LEN200f", /* T450s */ | ||
3059 | - "LEN2018", /* T460p */ | ||
3060 | NULL | ||
3061 | }; | ||
3062 | |||
3063 | diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c | ||
3064 | index b4d28928dec5..14bdaf1cef2c 100644 | ||
3065 | --- a/drivers/md/bcache/super.c | ||
3066 | +++ b/drivers/md/bcache/super.c | ||
3067 | @@ -951,6 +951,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c) | ||
3068 | uint32_t rtime = cpu_to_le32(get_seconds()); | ||
3069 | struct uuid_entry *u; | ||
3070 | char buf[BDEVNAME_SIZE]; | ||
3071 | + struct cached_dev *exist_dc, *t; | ||
3072 | |||
3073 | bdevname(dc->bdev, buf); | ||
3074 | |||
3075 | @@ -974,6 +975,16 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c) | ||
3076 | return -EINVAL; | ||
3077 | } | ||
3078 | |||
3079 | + /* Check whether already attached */ | ||
3080 | + list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) { | ||
3081 | + if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) { | ||
3082 | + pr_err("Tried to attach %s but duplicate UUID already attached", | ||
3083 | + buf); | ||
3084 | + | ||
3085 | + return -EINVAL; | ||
3086 | + } | ||
3087 | + } | ||
3088 | + | ||
3089 | u = uuid_find(c, dc->sb.uuid); | ||
3090 | |||
3091 | if (u && | ||
3092 | @@ -1191,7 +1202,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, | ||
3093 | |||
3094 | return; | ||
3095 | err: | ||
3096 | - pr_notice("error opening %s: %s", bdevname(bdev, name), err); | ||
3097 | + pr_notice("error %s: %s", bdevname(bdev, name), err); | ||
3098 | bcache_device_stop(&dc->disk); | ||
3099 | } | ||
3100 | |||
3101 | @@ -1859,6 +1870,8 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | ||
3102 | const char *err = NULL; /* must be set for any error case */ | ||
3103 | int ret = 0; | ||
3104 | |||
3105 | + bdevname(bdev, name); | ||
3106 | + | ||
3107 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); | ||
3108 | ca->bdev = bdev; | ||
3109 | ca->bdev->bd_holder = ca; | ||
3110 | @@ -1867,11 +1880,12 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | ||
3111 | ca->sb_bio.bi_io_vec[0].bv_page = sb_page; | ||
3112 | get_page(sb_page); | ||
3113 | |||
3114 | - if (blk_queue_discard(bdev_get_queue(ca->bdev))) | ||
3115 | + if (blk_queue_discard(bdev_get_queue(bdev))) | ||
3116 | ca->discard = CACHE_DISCARD(&ca->sb); | ||
3117 | |||
3118 | ret = cache_alloc(ca); | ||
3119 | if (ret != 0) { | ||
3120 | + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | ||
3121 | if (ret == -ENOMEM) | ||
3122 | err = "cache_alloc(): -ENOMEM"; | ||
3123 | else | ||
3124 | @@ -1894,14 +1908,14 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | ||
3125 | goto out; | ||
3126 | } | ||
3127 | |||
3128 | - pr_info("registered cache device %s", bdevname(bdev, name)); | ||
3129 | + pr_info("registered cache device %s", name); | ||
3130 | |||
3131 | out: | ||
3132 | kobject_put(&ca->kobj); | ||
3133 | |||
3134 | err: | ||
3135 | if (err) | ||
3136 | - pr_notice("error opening %s: %s", bdevname(bdev, name), err); | ||
3137 | + pr_notice("error %s: %s", name, err); | ||
3138 | |||
3139 | return ret; | ||
3140 | } | ||
3141 | @@ -1990,6 +2004,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, | ||
3142 | if (err) | ||
3143 | goto err_close; | ||
3144 | |||
3145 | + err = "failed to register device"; | ||
3146 | if (SB_IS_BDEV(sb)) { | ||
3147 | struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); | ||
3148 | if (!dc) | ||
3149 | @@ -2004,7 +2019,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, | ||
3150 | goto err_close; | ||
3151 | |||
3152 | if (register_cache(sb, sb_page, bdev, ca) != 0) | ||
3153 | - goto err_close; | ||
3154 | + goto err; | ||
3155 | } | ||
3156 | out: | ||
3157 | if (sb_page) | ||
3158 | @@ -2017,7 +2032,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, | ||
3159 | err_close: | ||
3160 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | ||
3161 | err: | ||
3162 | - pr_info("error opening %s: %s", path, err); | ||
3163 | + pr_info("error %s: %s", path, err); | ||
3164 | ret = -EINVAL; | ||
3165 | goto out; | ||
3166 | } | ||
3167 | diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c | ||
3168 | index c546b567f3b5..b3454e8c0956 100644 | ||
3169 | --- a/drivers/md/dm-bufio.c | ||
3170 | +++ b/drivers/md/dm-bufio.c | ||
3171 | @@ -386,9 +386,6 @@ static void __cache_size_refresh(void) | ||
3172 | static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask, | ||
3173 | enum data_mode *data_mode) | ||
3174 | { | ||
3175 | - unsigned noio_flag; | ||
3176 | - void *ptr; | ||
3177 | - | ||
3178 | if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) { | ||
3179 | *data_mode = DATA_MODE_SLAB; | ||
3180 | return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask); | ||
3181 | @@ -412,16 +409,15 @@ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask, | ||
3182 | * all allocations done by this process (including pagetables) are done | ||
3183 | * as if GFP_NOIO was specified. | ||
3184 | */ | ||
3185 | + if (gfp_mask & __GFP_NORETRY) { | ||
3186 | + unsigned noio_flag = memalloc_noio_save(); | ||
3187 | + void *ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL); | ||
3188 | |||
3189 | - if (gfp_mask & __GFP_NORETRY) | ||
3190 | - noio_flag = memalloc_noio_save(); | ||
3191 | - | ||
3192 | - ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL); | ||
3193 | - | ||
3194 | - if (gfp_mask & __GFP_NORETRY) | ||
3195 | memalloc_noio_restore(noio_flag); | ||
3196 | + return ptr; | ||
3197 | + } | ||
3198 | |||
3199 | - return ptr; | ||
3200 | + return __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL); | ||
3201 | } | ||
3202 | |||
3203 | /* | ||
3204 | diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c | ||
3205 | index f6d4a50f1bdb..829ac22b72fc 100644 | ||
3206 | --- a/drivers/net/wireless/mac80211_hwsim.c | ||
3207 | +++ b/drivers/net/wireless/mac80211_hwsim.c | ||
3208 | @@ -3455,7 +3455,7 @@ static int __init init_mac80211_hwsim(void) | ||
3209 | |||
3210 | spin_lock_init(&hwsim_radio_lock); | ||
3211 | |||
3212 | - hwsim_wq = alloc_workqueue("hwsim_wq",WQ_MEM_RECLAIM,0); | ||
3213 | + hwsim_wq = alloc_workqueue("hwsim_wq", 0, 0); | ||
3214 | if (!hwsim_wq) | ||
3215 | return -ENOMEM; | ||
3216 | |||
3217 | diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c | ||
3218 | index 839650e0926a..3551fbd6fe41 100644 | ||
3219 | --- a/drivers/nvme/host/core.c | ||
3220 | +++ b/drivers/nvme/host/core.c | ||
3221 | @@ -2950,7 +2950,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | ||
3222 | |||
3223 | if (new) | ||
3224 | nvme_mpath_add_disk(ns->head); | ||
3225 | - nvme_mpath_add_disk_links(ns); | ||
3226 | return; | ||
3227 | out_unlink_ns: | ||
3228 | mutex_lock(&ctrl->subsys->lock); | ||
3229 | @@ -2970,7 +2969,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) | ||
3230 | return; | ||
3231 | |||
3232 | if (ns->disk && ns->disk->flags & GENHD_FL_UP) { | ||
3233 | - nvme_mpath_remove_disk_links(ns); | ||
3234 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, | ||
3235 | &nvme_ns_id_attr_group); | ||
3236 | if (ns->ndev) | ||
3237 | diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c | ||
3238 | index 1218a9fca846..cf16905d25e2 100644 | ||
3239 | --- a/drivers/nvme/host/multipath.c | ||
3240 | +++ b/drivers/nvme/host/multipath.c | ||
3241 | @@ -245,25 +245,6 @@ void nvme_mpath_add_disk(struct nvme_ns_head *head) | ||
3242 | head->disk->disk_name); | ||
3243 | } | ||
3244 | |||
3245 | -void nvme_mpath_add_disk_links(struct nvme_ns *ns) | ||
3246 | -{ | ||
3247 | - struct kobject *slave_disk_kobj, *holder_disk_kobj; | ||
3248 | - | ||
3249 | - if (!ns->head->disk) | ||
3250 | - return; | ||
3251 | - | ||
3252 | - slave_disk_kobj = &disk_to_dev(ns->disk)->kobj; | ||
3253 | - if (sysfs_create_link(ns->head->disk->slave_dir, slave_disk_kobj, | ||
3254 | - kobject_name(slave_disk_kobj))) | ||
3255 | - return; | ||
3256 | - | ||
3257 | - holder_disk_kobj = &disk_to_dev(ns->head->disk)->kobj; | ||
3258 | - if (sysfs_create_link(ns->disk->part0.holder_dir, holder_disk_kobj, | ||
3259 | - kobject_name(holder_disk_kobj))) | ||
3260 | - sysfs_remove_link(ns->head->disk->slave_dir, | ||
3261 | - kobject_name(slave_disk_kobj)); | ||
3262 | -} | ||
3263 | - | ||
3264 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) | ||
3265 | { | ||
3266 | if (!head->disk) | ||
3267 | @@ -278,14 +259,3 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) | ||
3268 | blk_cleanup_queue(head->disk->queue); | ||
3269 | put_disk(head->disk); | ||
3270 | } | ||
3271 | - | ||
3272 | -void nvme_mpath_remove_disk_links(struct nvme_ns *ns) | ||
3273 | -{ | ||
3274 | - if (!ns->head->disk) | ||
3275 | - return; | ||
3276 | - | ||
3277 | - sysfs_remove_link(ns->disk->part0.holder_dir, | ||
3278 | - kobject_name(&disk_to_dev(ns->head->disk)->kobj)); | ||
3279 | - sysfs_remove_link(ns->head->disk->slave_dir, | ||
3280 | - kobject_name(&disk_to_dev(ns->disk)->kobj)); | ||
3281 | -} | ||
3282 | diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h | ||
3283 | index a00eabd06427..55c49a1aa231 100644 | ||
3284 | --- a/drivers/nvme/host/nvme.h | ||
3285 | +++ b/drivers/nvme/host/nvme.h | ||
3286 | @@ -405,9 +405,7 @@ bool nvme_req_needs_failover(struct request *req); | ||
3287 | void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); | ||
3288 | int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); | ||
3289 | void nvme_mpath_add_disk(struct nvme_ns_head *head); | ||
3290 | -void nvme_mpath_add_disk_links(struct nvme_ns *ns); | ||
3291 | void nvme_mpath_remove_disk(struct nvme_ns_head *head); | ||
3292 | -void nvme_mpath_remove_disk_links(struct nvme_ns *ns); | ||
3293 | |||
3294 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | ||
3295 | { | ||
3296 | @@ -448,12 +446,6 @@ static inline void nvme_mpath_add_disk(struct nvme_ns_head *head) | ||
3297 | static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head) | ||
3298 | { | ||
3299 | } | ||
3300 | -static inline void nvme_mpath_add_disk_links(struct nvme_ns *ns) | ||
3301 | -{ | ||
3302 | -} | ||
3303 | -static inline void nvme_mpath_remove_disk_links(struct nvme_ns *ns) | ||
3304 | -{ | ||
3305 | -} | ||
3306 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | ||
3307 | { | ||
3308 | } | ||
3309 | diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c | ||
3310 | index 81e2157a7cfb..bc3e2d8d0cce 100644 | ||
3311 | --- a/drivers/pci/dwc/pcie-designware-host.c | ||
3312 | +++ b/drivers/pci/dwc/pcie-designware-host.c | ||
3313 | @@ -607,7 +607,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | ||
3314 | /* setup bus numbers */ | ||
3315 | val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS); | ||
3316 | val &= 0xff000000; | ||
3317 | - val |= 0x00010100; | ||
3318 | + val |= 0x00ff0100; | ||
3319 | dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val); | ||
3320 | |||
3321 | /* setup command register */ | ||
3322 | diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c | ||
3323 | index 72c8b3e1022b..e0a9c445ed67 100644 | ||
3324 | --- a/drivers/regulator/stm32-vrefbuf.c | ||
3325 | +++ b/drivers/regulator/stm32-vrefbuf.c | ||
3326 | @@ -51,7 +51,7 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev) | ||
3327 | * arbitrary timeout. | ||
3328 | */ | ||
3329 | ret = readl_poll_timeout(priv->base + STM32_VREFBUF_CSR, val, | ||
3330 | - !(val & STM32_VRR), 650, 10000); | ||
3331 | + val & STM32_VRR, 650, 10000); | ||
3332 | if (ret) { | ||
3333 | dev_err(&rdev->dev, "stm32 vrefbuf timed out!\n"); | ||
3334 | val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); | ||
3335 | diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c | ||
3336 | index 57bf43e34863..dd9464920456 100644 | ||
3337 | --- a/drivers/scsi/hosts.c | ||
3338 | +++ b/drivers/scsi/hosts.c | ||
3339 | @@ -328,8 +328,6 @@ static void scsi_host_dev_release(struct device *dev) | ||
3340 | if (shost->work_q) | ||
3341 | destroy_workqueue(shost->work_q); | ||
3342 | |||
3343 | - destroy_rcu_head(&shost->rcu); | ||
3344 | - | ||
3345 | if (shost->shost_state == SHOST_CREATED) { | ||
3346 | /* | ||
3347 | * Free the shost_dev device name here if scsi_host_alloc() | ||
3348 | @@ -404,7 +402,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | ||
3349 | INIT_LIST_HEAD(&shost->starved_list); | ||
3350 | init_waitqueue_head(&shost->host_wait); | ||
3351 | mutex_init(&shost->scan_mutex); | ||
3352 | - init_rcu_head(&shost->rcu); | ||
3353 | |||
3354 | index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); | ||
3355 | if (index < 0) | ||
3356 | diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h | ||
3357 | index 01a9b8971e88..93ff92e2363f 100644 | ||
3358 | --- a/drivers/scsi/qla2xxx/qla_def.h | ||
3359 | +++ b/drivers/scsi/qla2xxx/qla_def.h | ||
3360 | @@ -315,6 +315,29 @@ struct srb_cmd { | ||
3361 | /* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */ | ||
3362 | #define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID) | ||
3363 | |||
3364 | +/* | ||
3365 | + * 24 bit port ID type definition. | ||
3366 | + */ | ||
3367 | +typedef union { | ||
3368 | + uint32_t b24 : 24; | ||
3369 | + | ||
3370 | + struct { | ||
3371 | +#ifdef __BIG_ENDIAN | ||
3372 | + uint8_t domain; | ||
3373 | + uint8_t area; | ||
3374 | + uint8_t al_pa; | ||
3375 | +#elif defined(__LITTLE_ENDIAN) | ||
3376 | + uint8_t al_pa; | ||
3377 | + uint8_t area; | ||
3378 | + uint8_t domain; | ||
3379 | +#else | ||
3380 | +#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" | ||
3381 | +#endif | ||
3382 | + uint8_t rsvd_1; | ||
3383 | + } b; | ||
3384 | +} port_id_t; | ||
3385 | +#define INVALID_PORT_ID 0xFFFFFF | ||
3386 | + | ||
3387 | struct els_logo_payload { | ||
3388 | uint8_t opcode; | ||
3389 | uint8_t rsvd[3]; | ||
3390 | @@ -338,6 +361,7 @@ struct ct_arg { | ||
3391 | u32 rsp_size; | ||
3392 | void *req; | ||
3393 | void *rsp; | ||
3394 | + port_id_t id; | ||
3395 | }; | ||
3396 | |||
3397 | /* | ||
3398 | @@ -499,6 +523,7 @@ typedef struct srb { | ||
3399 | const char *name; | ||
3400 | int iocbs; | ||
3401 | struct qla_qpair *qpair; | ||
3402 | + struct list_head elem; | ||
3403 | u32 gen1; /* scratch */ | ||
3404 | u32 gen2; /* scratch */ | ||
3405 | union { | ||
3406 | @@ -2164,28 +2189,6 @@ struct imm_ntfy_from_isp { | ||
3407 | #define REQUEST_ENTRY_SIZE (sizeof(request_t)) | ||
3408 | |||
3409 | |||
3410 | -/* | ||
3411 | - * 24 bit port ID type definition. | ||
3412 | - */ | ||
3413 | -typedef union { | ||
3414 | - uint32_t b24 : 24; | ||
3415 | - | ||
3416 | - struct { | ||
3417 | -#ifdef __BIG_ENDIAN | ||
3418 | - uint8_t domain; | ||
3419 | - uint8_t area; | ||
3420 | - uint8_t al_pa; | ||
3421 | -#elif defined(__LITTLE_ENDIAN) | ||
3422 | - uint8_t al_pa; | ||
3423 | - uint8_t area; | ||
3424 | - uint8_t domain; | ||
3425 | -#else | ||
3426 | -#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" | ||
3427 | -#endif | ||
3428 | - uint8_t rsvd_1; | ||
3429 | - } b; | ||
3430 | -} port_id_t; | ||
3431 | -#define INVALID_PORT_ID 0xFFFFFF | ||
3432 | |||
3433 | /* | ||
3434 | * Switch info gathering structure. | ||
3435 | @@ -4107,6 +4110,7 @@ typedef struct scsi_qla_host { | ||
3436 | #define LOOP_READY 5 | ||
3437 | #define LOOP_DEAD 6 | ||
3438 | |||
3439 | + unsigned long relogin_jif; | ||
3440 | unsigned long dpc_flags; | ||
3441 | #define RESET_MARKER_NEEDED 0 /* Send marker to ISP. */ | ||
3442 | #define RESET_ACTIVE 1 | ||
3443 | @@ -4252,6 +4256,7 @@ typedef struct scsi_qla_host { | ||
3444 | uint8_t n2n_node_name[WWN_SIZE]; | ||
3445 | uint8_t n2n_port_name[WWN_SIZE]; | ||
3446 | uint16_t n2n_id; | ||
3447 | + struct list_head gpnid_list; | ||
3448 | } scsi_qla_host_t; | ||
3449 | |||
3450 | struct qla27xx_image_status { | ||
3451 | diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c | ||
3452 | index bc3db6abc9a0..7d715e58901f 100644 | ||
3453 | --- a/drivers/scsi/qla2xxx/qla_gs.c | ||
3454 | +++ b/drivers/scsi/qla2xxx/qla_gs.c | ||
3455 | @@ -175,6 +175,9 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | ||
3456 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | ||
3457 | } | ||
3458 | break; | ||
3459 | + case CS_TIMEOUT: | ||
3460 | + rval = QLA_FUNCTION_TIMEOUT; | ||
3461 | + /* drop through */ | ||
3462 | default: | ||
3463 | ql_dbg(ql_dbg_disc, vha, 0x2033, | ||
3464 | "%s failed, completion status (%x) on port_id: " | ||
3465 | @@ -2833,7 +2836,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) | ||
3466 | } | ||
3467 | } else { /* fcport->d_id.b24 != ea->id.b24 */ | ||
3468 | fcport->d_id.b24 = ea->id.b24; | ||
3469 | - if (fcport->deleted == QLA_SESS_DELETED) { | ||
3470 | + if (fcport->deleted != QLA_SESS_DELETED) { | ||
3471 | ql_dbg(ql_dbg_disc, vha, 0x2021, | ||
3472 | "%s %d %8phC post del sess\n", | ||
3473 | __func__, __LINE__, fcport->port_name); | ||
3474 | @@ -2889,9 +2892,22 @@ static void qla2x00_async_gidpn_sp_done(void *s, int res) | ||
3475 | ea.rc = res; | ||
3476 | ea.event = FCME_GIDPN_DONE; | ||
3477 | |||
3478 | - ql_dbg(ql_dbg_disc, vha, 0x204f, | ||
3479 | - "Async done-%s res %x, WWPN %8phC ID %3phC \n", | ||
3480 | - sp->name, res, fcport->port_name, id); | ||
3481 | + if (res == QLA_FUNCTION_TIMEOUT) { | ||
3482 | + ql_dbg(ql_dbg_disc, sp->vha, 0xffff, | ||
3483 | + "Async done-%s WWPN %8phC timed out.\n", | ||
3484 | + sp->name, fcport->port_name); | ||
3485 | + qla24xx_post_gidpn_work(sp->vha, fcport); | ||
3486 | + sp->free(sp); | ||
3487 | + return; | ||
3488 | + } else if (res) { | ||
3489 | + ql_dbg(ql_dbg_disc, sp->vha, 0xffff, | ||
3490 | + "Async done-%s fail res %x, WWPN %8phC\n", | ||
3491 | + sp->name, res, fcport->port_name); | ||
3492 | + } else { | ||
3493 | + ql_dbg(ql_dbg_disc, vha, 0x204f, | ||
3494 | + "Async done-%s good WWPN %8phC ID %3phC\n", | ||
3495 | + sp->name, fcport->port_name, id); | ||
3496 | + } | ||
3497 | |||
3498 | qla2x00_fcport_event_handler(vha, &ea); | ||
3499 | |||
3500 | @@ -3155,43 +3171,136 @@ void qla24xx_async_gpnid_done(scsi_qla_host_t *vha, srb_t *sp) | ||
3501 | |||
3502 | void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) | ||
3503 | { | ||
3504 | - fc_port_t *fcport; | ||
3505 | - unsigned long flags; | ||
3506 | + fc_port_t *fcport, *conflict, *t; | ||
3507 | |||
3508 | - spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
3509 | - fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1); | ||
3510 | - spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
3511 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3512 | + "%s %d port_id: %06x\n", | ||
3513 | + __func__, __LINE__, ea->id.b24); | ||
3514 | |||
3515 | - if (fcport) { | ||
3516 | - /* cable moved. just plugged in */ | ||
3517 | - fcport->rscn_gen++; | ||
3518 | - fcport->d_id = ea->id; | ||
3519 | - fcport->scan_state = QLA_FCPORT_FOUND; | ||
3520 | - fcport->flags |= FCF_FABRIC_DEVICE; | ||
3521 | - | ||
3522 | - switch (fcport->disc_state) { | ||
3523 | - case DSC_DELETED: | ||
3524 | - ql_dbg(ql_dbg_disc, vha, 0x210d, | ||
3525 | - "%s %d %8phC login\n", __func__, __LINE__, | ||
3526 | - fcport->port_name); | ||
3527 | - qla24xx_fcport_handle_login(vha, fcport); | ||
3528 | - break; | ||
3529 | - case DSC_DELETE_PEND: | ||
3530 | - break; | ||
3531 | - default: | ||
3532 | - ql_dbg(ql_dbg_disc, vha, 0x2064, | ||
3533 | - "%s %d %8phC post del sess\n", | ||
3534 | - __func__, __LINE__, fcport->port_name); | ||
3535 | - qlt_schedule_sess_for_deletion_lock(fcport); | ||
3536 | - break; | ||
3537 | + if (ea->rc) { | ||
3538 | + /* cable is disconnected */ | ||
3539 | + list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) { | ||
3540 | + if (fcport->d_id.b24 == ea->id.b24) { | ||
3541 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3542 | + "%s %d %8phC DS %d\n", | ||
3543 | + __func__, __LINE__, | ||
3544 | + fcport->port_name, | ||
3545 | + fcport->disc_state); | ||
3546 | + fcport->scan_state = QLA_FCPORT_SCAN; | ||
3547 | + switch (fcport->disc_state) { | ||
3548 | + case DSC_DELETED: | ||
3549 | + case DSC_DELETE_PEND: | ||
3550 | + break; | ||
3551 | + default: | ||
3552 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3553 | + "%s %d %8phC post del sess\n", | ||
3554 | + __func__, __LINE__, | ||
3555 | + fcport->port_name); | ||
3556 | + qlt_schedule_sess_for_deletion_lock | ||
3557 | + (fcport); | ||
3558 | + break; | ||
3559 | + } | ||
3560 | + } | ||
3561 | } | ||
3562 | } else { | ||
3563 | - /* create new fcport */ | ||
3564 | - ql_dbg(ql_dbg_disc, vha, 0x2065, | ||
3565 | - "%s %d %8phC post new sess\n", | ||
3566 | - __func__, __LINE__, ea->port_name); | ||
3567 | + /* cable is connected */ | ||
3568 | + fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1); | ||
3569 | + if (fcport) { | ||
3570 | + list_for_each_entry_safe(conflict, t, &vha->vp_fcports, | ||
3571 | + list) { | ||
3572 | + if ((conflict->d_id.b24 == ea->id.b24) && | ||
3573 | + (fcport != conflict)) { | ||
3574 | + /* 2 fcports with conflict Nport ID or | ||
3575 | + * an existing fcport is having nport ID | ||
3576 | + * conflict with new fcport. | ||
3577 | + */ | ||
3578 | + | ||
3579 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3580 | + "%s %d %8phC DS %d\n", | ||
3581 | + __func__, __LINE__, | ||
3582 | + conflict->port_name, | ||
3583 | + conflict->disc_state); | ||
3584 | + conflict->scan_state = QLA_FCPORT_SCAN; | ||
3585 | + switch (conflict->disc_state) { | ||
3586 | + case DSC_DELETED: | ||
3587 | + case DSC_DELETE_PEND: | ||
3588 | + break; | ||
3589 | + default: | ||
3590 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3591 | + "%s %d %8phC post del sess\n", | ||
3592 | + __func__, __LINE__, | ||
3593 | + conflict->port_name); | ||
3594 | + qlt_schedule_sess_for_deletion_lock | ||
3595 | + (conflict); | ||
3596 | + break; | ||
3597 | + } | ||
3598 | + } | ||
3599 | + } | ||
3600 | |||
3601 | - qla24xx_post_newsess_work(vha, &ea->id, ea->port_name, NULL); | ||
3602 | + fcport->rscn_gen++; | ||
3603 | + fcport->scan_state = QLA_FCPORT_FOUND; | ||
3604 | + fcport->flags |= FCF_FABRIC_DEVICE; | ||
3605 | + switch (fcport->disc_state) { | ||
3606 | + case DSC_LOGIN_COMPLETE: | ||
3607 | + /* recheck session is still intact. */ | ||
3608 | + ql_dbg(ql_dbg_disc, vha, 0x210d, | ||
3609 | + "%s %d %8phC revalidate session with ADISC\n", | ||
3610 | + __func__, __LINE__, fcport->port_name); | ||
3611 | + qla24xx_post_gpdb_work(vha, fcport, | ||
3612 | + PDO_FORCE_ADISC); | ||
3613 | + break; | ||
3614 | + case DSC_DELETED: | ||
3615 | + ql_dbg(ql_dbg_disc, vha, 0x210d, | ||
3616 | + "%s %d %8phC login\n", __func__, __LINE__, | ||
3617 | + fcport->port_name); | ||
3618 | + fcport->d_id = ea->id; | ||
3619 | + qla24xx_fcport_handle_login(vha, fcport); | ||
3620 | + break; | ||
3621 | + case DSC_DELETE_PEND: | ||
3622 | + fcport->d_id = ea->id; | ||
3623 | + break; | ||
3624 | + default: | ||
3625 | + fcport->d_id = ea->id; | ||
3626 | + break; | ||
3627 | + } | ||
3628 | + } else { | ||
3629 | + list_for_each_entry_safe(conflict, t, &vha->vp_fcports, | ||
3630 | + list) { | ||
3631 | + if (conflict->d_id.b24 == ea->id.b24) { | ||
3632 | + /* 2 fcports with conflict Nport ID or | ||
3633 | + * an existing fcport is having nport ID | ||
3634 | + * conflict with new fcport. | ||
3635 | + */ | ||
3636 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3637 | + "%s %d %8phC DS %d\n", | ||
3638 | + __func__, __LINE__, | ||
3639 | + conflict->port_name, | ||
3640 | + conflict->disc_state); | ||
3641 | + | ||
3642 | + conflict->scan_state = QLA_FCPORT_SCAN; | ||
3643 | + switch (conflict->disc_state) { | ||
3644 | + case DSC_DELETED: | ||
3645 | + case DSC_DELETE_PEND: | ||
3646 | + break; | ||
3647 | + default: | ||
3648 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
3649 | + "%s %d %8phC post del sess\n", | ||
3650 | + __func__, __LINE__, | ||
3651 | + conflict->port_name); | ||
3652 | + qlt_schedule_sess_for_deletion_lock | ||
3653 | + (conflict); | ||
3654 | + break; | ||
3655 | + } | ||
3656 | + } | ||
3657 | + } | ||
3658 | + | ||
3659 | + /* create new fcport */ | ||
3660 | + ql_dbg(ql_dbg_disc, vha, 0x2065, | ||
3661 | + "%s %d %8phC post new sess\n", | ||
3662 | + __func__, __LINE__, ea->port_name); | ||
3663 | + qla24xx_post_newsess_work(vha, &ea->id, | ||
3664 | + ea->port_name, NULL); | ||
3665 | + } | ||
3666 | } | ||
3667 | } | ||
3668 | |||
3669 | @@ -3205,11 +3314,18 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res) | ||
3670 | (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; | ||
3671 | struct event_arg ea; | ||
3672 | struct qla_work_evt *e; | ||
3673 | + unsigned long flags; | ||
3674 | |||
3675 | - ql_dbg(ql_dbg_disc, vha, 0x2066, | ||
3676 | - "Async done-%s res %x ID %3phC. %8phC\n", | ||
3677 | - sp->name, res, ct_req->req.port_id.port_id, | ||
3678 | - ct_rsp->rsp.gpn_id.port_name); | ||
3679 | + if (res) | ||
3680 | + ql_dbg(ql_dbg_disc, vha, 0x2066, | ||
3681 | + "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n", | ||
3682 | + sp->name, res, sp->gen1, ct_req->req.port_id.port_id, | ||
3683 | + ct_rsp->rsp.gpn_id.port_name); | ||
3684 | + else | ||
3685 | + ql_dbg(ql_dbg_disc, vha, 0x2066, | ||
3686 | + "Async done-%s good rscn gen %d ID %3phC. %8phC\n", | ||
3687 | + sp->name, sp->gen1, ct_req->req.port_id.port_id, | ||
3688 | + ct_rsp->rsp.gpn_id.port_name); | ||
3689 | |||
3690 | memset(&ea, 0, sizeof(ea)); | ||
3691 | memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); | ||
3692 | @@ -3220,6 +3336,23 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res) | ||
3693 | ea.rc = res; | ||
3694 | ea.event = FCME_GPNID_DONE; | ||
3695 | |||
3696 | + spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
3697 | + list_del(&sp->elem); | ||
3698 | + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
3699 | + | ||
3700 | + if (res) { | ||
3701 | + if (res == QLA_FUNCTION_TIMEOUT) { | ||
3702 | + qla24xx_post_gpnid_work(sp->vha, &ea.id); | ||
3703 | + sp->free(sp); | ||
3704 | + return; | ||
3705 | + } | ||
3706 | + } else if (sp->gen1) { | ||
3707 | + /* There was another RSCN for this Nport ID */ | ||
3708 | + qla24xx_post_gpnid_work(sp->vha, &ea.id); | ||
3709 | + sp->free(sp); | ||
3710 | + return; | ||
3711 | + } | ||
3712 | + | ||
3713 | qla2x00_fcport_event_handler(vha, &ea); | ||
3714 | |||
3715 | e = qla2x00_alloc_work(vha, QLA_EVT_GPNID_DONE); | ||
3716 | @@ -3253,8 +3386,9 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) | ||
3717 | { | ||
3718 | int rval = QLA_FUNCTION_FAILED; | ||
3719 | struct ct_sns_req *ct_req; | ||
3720 | - srb_t *sp; | ||
3721 | + srb_t *sp, *tsp; | ||
3722 | struct ct_sns_pkt *ct_sns; | ||
3723 | + unsigned long flags; | ||
3724 | |||
3725 | if (!vha->flags.online) | ||
3726 | goto done; | ||
3727 | @@ -3265,8 +3399,22 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) | ||
3728 | |||
3729 | sp->type = SRB_CT_PTHRU_CMD; | ||
3730 | sp->name = "gpnid"; | ||
3731 | + sp->u.iocb_cmd.u.ctarg.id = *id; | ||
3732 | + sp->gen1 = 0; | ||
3733 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); | ||
3734 | |||
3735 | + spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
3736 | + list_for_each_entry(tsp, &vha->gpnid_list, elem) { | ||
3737 | + if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) { | ||
3738 | + tsp->gen1++; | ||
3739 | + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
3740 | + sp->free(sp); | ||
3741 | + goto done; | ||
3742 | + } | ||
3743 | + } | ||
3744 | + list_add_tail(&sp->elem, &vha->gpnid_list); | ||
3745 | + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
3746 | + | ||
3747 | sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, | ||
3748 | sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, | ||
3749 | GFP_KERNEL); | ||
3750 | diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c | ||
3751 | index 1bafa043f9f1..6082389f25c3 100644 | ||
3752 | --- a/drivers/scsi/qla2xxx/qla_init.c | ||
3753 | +++ b/drivers/scsi/qla2xxx/qla_init.c | ||
3754 | @@ -863,6 +863,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | ||
3755 | int rval = ea->rc; | ||
3756 | fc_port_t *fcport = ea->fcport; | ||
3757 | unsigned long flags; | ||
3758 | + u16 opt = ea->sp->u.iocb_cmd.u.mbx.out_mb[10]; | ||
3759 | |||
3760 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
3761 | |||
3762 | @@ -893,7 +894,8 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | ||
3763 | } | ||
3764 | |||
3765 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
3766 | - ea->fcport->login_gen++; | ||
3767 | + if (opt != PDO_FORCE_ADISC) | ||
3768 | + ea->fcport->login_gen++; | ||
3769 | ea->fcport->deleted = 0; | ||
3770 | ea->fcport->logout_on_delete = 1; | ||
3771 | |||
3772 | @@ -917,6 +919,16 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | ||
3773 | |||
3774 | qla24xx_post_gpsc_work(vha, fcport); | ||
3775 | } | ||
3776 | + } else if (ea->fcport->login_succ) { | ||
3777 | + /* | ||
3778 | + * We have an existing session. A late RSCN delivery | ||
3779 | + * must have triggered the session to be re-validate. | ||
3780 | + * session is still valid. | ||
3781 | + */ | ||
3782 | + ql_dbg(ql_dbg_disc, vha, 0x20d6, | ||
3783 | + "%s %d %8phC session revalidate success\n", | ||
3784 | + __func__, __LINE__, fcport->port_name); | ||
3785 | + fcport->disc_state = DSC_LOGIN_COMPLETE; | ||
3786 | } | ||
3787 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
3788 | } /* gpdb event */ | ||
3789 | @@ -963,7 +975,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) | ||
3790 | ql_dbg(ql_dbg_disc, vha, 0x20bd, | ||
3791 | "%s %d %8phC post gnl\n", | ||
3792 | __func__, __LINE__, fcport->port_name); | ||
3793 | - qla24xx_async_gnl(vha, fcport); | ||
3794 | + qla24xx_post_gnl_work(vha, fcport); | ||
3795 | } else { | ||
3796 | ql_dbg(ql_dbg_disc, vha, 0x20bf, | ||
3797 | "%s %d %8phC post login\n", | ||
3798 | @@ -1040,9 +1052,8 @@ void qla24xx_handle_rscn_event(fc_port_t *fcport, struct event_arg *ea) | ||
3799 | switch (fcport->disc_state) { | ||
3800 | case DSC_DELETED: | ||
3801 | case DSC_LOGIN_COMPLETE: | ||
3802 | - qla24xx_post_gidpn_work(fcport->vha, fcport); | ||
3803 | + qla24xx_post_gpnid_work(fcport->vha, &ea->id); | ||
3804 | break; | ||
3805 | - | ||
3806 | default: | ||
3807 | break; | ||
3808 | } | ||
3809 | @@ -1132,7 +1143,7 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, | ||
3810 | ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n", | ||
3811 | __func__, __LINE__, fcport->port_name); | ||
3812 | |||
3813 | - qla24xx_async_gidpn(vha, fcport); | ||
3814 | + qla24xx_post_gidpn_work(vha, fcport); | ||
3815 | return; | ||
3816 | } | ||
3817 | |||
3818 | @@ -1347,6 +1358,7 @@ qla24xx_abort_sp_done(void *ptr, int res) | ||
3819 | srb_t *sp = ptr; | ||
3820 | struct srb_iocb *abt = &sp->u.iocb_cmd; | ||
3821 | |||
3822 | + del_timer(&sp->u.iocb_cmd.timer); | ||
3823 | complete(&abt->u.abt.comp); | ||
3824 | } | ||
3825 | |||
3826 | @@ -1452,6 +1464,8 @@ static void | ||
3827 | qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) | ||
3828 | { | ||
3829 | port_id_t cid; /* conflict Nport id */ | ||
3830 | + u16 lid; | ||
3831 | + struct fc_port *conflict_fcport; | ||
3832 | |||
3833 | switch (ea->data[0]) { | ||
3834 | case MBS_COMMAND_COMPLETE: | ||
3835 | @@ -1467,8 +1481,12 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) | ||
3836 | qla24xx_post_prli_work(vha, ea->fcport); | ||
3837 | } else { | ||
3838 | ql_dbg(ql_dbg_disc, vha, 0x20ea, | ||
3839 | - "%s %d %8phC post gpdb\n", | ||
3840 | - __func__, __LINE__, ea->fcport->port_name); | ||
3841 | + "%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n", | ||
3842 | + __func__, __LINE__, ea->fcport->port_name, | ||
3843 | + ea->fcport->loop_id, ea->fcport->d_id.b24); | ||
3844 | + | ||
3845 | + set_bit(ea->fcport->loop_id, vha->hw->loop_id_map); | ||
3846 | + ea->fcport->loop_id = FC_NO_LOOP_ID; | ||
3847 | ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; | ||
3848 | ea->fcport->logout_on_delete = 1; | ||
3849 | ea->fcport->send_els_logo = 0; | ||
3850 | @@ -1513,8 +1531,38 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) | ||
3851 | ea->fcport->d_id.b.domain, ea->fcport->d_id.b.area, | ||
3852 | ea->fcport->d_id.b.al_pa); | ||
3853 | |||
3854 | - qla2x00_clear_loop_id(ea->fcport); | ||
3855 | - qla24xx_post_gidpn_work(vha, ea->fcport); | ||
3856 | + lid = ea->iop[1] & 0xffff; | ||
3857 | + qlt_find_sess_invalidate_other(vha, | ||
3858 | + wwn_to_u64(ea->fcport->port_name), | ||
3859 | + ea->fcport->d_id, lid, &conflict_fcport); | ||
3860 | + | ||
3861 | + if (conflict_fcport) { | ||
3862 | + /* | ||
3863 | + * Another fcport share the same loop_id/nport id. | ||
3864 | + * Conflict fcport needs to finish cleanup before this | ||
3865 | + * fcport can proceed to login. | ||
3866 | + */ | ||
3867 | + conflict_fcport->conflict = ea->fcport; | ||
3868 | + ea->fcport->login_pause = 1; | ||
3869 | + | ||
3870 | + ql_dbg(ql_dbg_disc, vha, 0x20ed, | ||
3871 | + "%s %d %8phC NPortId %06x inuse with loopid 0x%x. post gidpn\n", | ||
3872 | + __func__, __LINE__, ea->fcport->port_name, | ||
3873 | + ea->fcport->d_id.b24, lid); | ||
3874 | + qla2x00_clear_loop_id(ea->fcport); | ||
3875 | + qla24xx_post_gidpn_work(vha, ea->fcport); | ||
3876 | + } else { | ||
3877 | + ql_dbg(ql_dbg_disc, vha, 0x20ed, | ||
3878 | + "%s %d %8phC NPortId %06x inuse with loopid 0x%x. sched delete\n", | ||
3879 | + __func__, __LINE__, ea->fcport->port_name, | ||
3880 | + ea->fcport->d_id.b24, lid); | ||
3881 | + | ||
3882 | + qla2x00_clear_loop_id(ea->fcport); | ||
3883 | + set_bit(lid, vha->hw->loop_id_map); | ||
3884 | + ea->fcport->loop_id = lid; | ||
3885 | + ea->fcport->keep_nport_handle = 0; | ||
3886 | + qlt_schedule_sess_for_deletion(ea->fcport, false); | ||
3887 | + } | ||
3888 | break; | ||
3889 | } | ||
3890 | return; | ||
3891 | @@ -8173,9 +8221,6 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair) | ||
3892 | int ret = QLA_FUNCTION_FAILED; | ||
3893 | struct qla_hw_data *ha = qpair->hw; | ||
3894 | |||
3895 | - if (!vha->flags.qpairs_req_created && !vha->flags.qpairs_rsp_created) | ||
3896 | - goto fail; | ||
3897 | - | ||
3898 | qpair->delete_in_progress = 1; | ||
3899 | while (atomic_read(&qpair->ref_count)) | ||
3900 | msleep(500); | ||
3901 | @@ -8183,6 +8228,7 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair) | ||
3902 | ret = qla25xx_delete_req_que(vha, qpair->req); | ||
3903 | if (ret != QLA_SUCCESS) | ||
3904 | goto fail; | ||
3905 | + | ||
3906 | ret = qla25xx_delete_rsp_que(vha, qpair->rsp); | ||
3907 | if (ret != QLA_SUCCESS) | ||
3908 | goto fail; | ||
3909 | diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c | ||
3910 | index d810a447cb4a..8ea59586f4f1 100644 | ||
3911 | --- a/drivers/scsi/qla2xxx/qla_iocb.c | ||
3912 | +++ b/drivers/scsi/qla2xxx/qla_iocb.c | ||
3913 | @@ -2392,26 +2392,13 @@ qla2x00_els_dcmd_iocb_timeout(void *data) | ||
3914 | srb_t *sp = data; | ||
3915 | fc_port_t *fcport = sp->fcport; | ||
3916 | struct scsi_qla_host *vha = sp->vha; | ||
3917 | - struct qla_hw_data *ha = vha->hw; | ||
3918 | struct srb_iocb *lio = &sp->u.iocb_cmd; | ||
3919 | - unsigned long flags = 0; | ||
3920 | |||
3921 | ql_dbg(ql_dbg_io, vha, 0x3069, | ||
3922 | "%s Timeout, hdl=%x, portid=%02x%02x%02x\n", | ||
3923 | sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, | ||
3924 | fcport->d_id.b.al_pa); | ||
3925 | |||
3926 | - /* Abort the exchange */ | ||
3927 | - spin_lock_irqsave(&ha->hardware_lock, flags); | ||
3928 | - if (ha->isp_ops->abort_command(sp)) { | ||
3929 | - ql_dbg(ql_dbg_io, vha, 0x3070, | ||
3930 | - "mbx abort_command failed.\n"); | ||
3931 | - } else { | ||
3932 | - ql_dbg(ql_dbg_io, vha, 0x3071, | ||
3933 | - "mbx abort_command success.\n"); | ||
3934 | - } | ||
3935 | - spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
3936 | - | ||
3937 | complete(&lio->u.els_logo.comp); | ||
3938 | } | ||
3939 | |||
3940 | diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c | ||
3941 | index 2fd79129bb2a..85382387a52b 100644 | ||
3942 | --- a/drivers/scsi/qla2xxx/qla_isr.c | ||
3943 | +++ b/drivers/scsi/qla2xxx/qla_isr.c | ||
3944 | @@ -1574,7 +1574,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | ||
3945 | /* borrowing sts_entry_24xx.comp_status. | ||
3946 | same location as ct_entry_24xx.comp_status | ||
3947 | */ | ||
3948 | - res = qla2x00_chk_ms_status(vha, (ms_iocb_entry_t *)pkt, | ||
3949 | + res = qla2x00_chk_ms_status(sp->vha, (ms_iocb_entry_t *)pkt, | ||
3950 | (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp, | ||
3951 | sp->name); | ||
3952 | sp->done(sp, res); | ||
3953 | @@ -2369,7 +2369,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | ||
3954 | int res = 0; | ||
3955 | uint16_t state_flags = 0; | ||
3956 | uint16_t retry_delay = 0; | ||
3957 | - uint8_t no_logout = 0; | ||
3958 | |||
3959 | sts = (sts_entry_t *) pkt; | ||
3960 | sts24 = (struct sts_entry_24xx *) pkt; | ||
3961 | @@ -2640,7 +2639,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | ||
3962 | break; | ||
3963 | |||
3964 | case CS_PORT_LOGGED_OUT: | ||
3965 | - no_logout = 1; | ||
3966 | case CS_PORT_CONFIG_CHG: | ||
3967 | case CS_PORT_BUSY: | ||
3968 | case CS_INCOMPLETE: | ||
3969 | @@ -2671,9 +2669,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | ||
3970 | port_state_str[atomic_read(&fcport->state)], | ||
3971 | comp_status); | ||
3972 | |||
3973 | - if (no_logout) | ||
3974 | - fcport->logout_on_delete = 0; | ||
3975 | - | ||
3976 | qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); | ||
3977 | qlt_schedule_sess_for_deletion_lock(fcport); | ||
3978 | } | ||
3979 | diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c | ||
3980 | index cb717d47339f..e2b5fa47bb57 100644 | ||
3981 | --- a/drivers/scsi/qla2xxx/qla_mbx.c | ||
3982 | +++ b/drivers/scsi/qla2xxx/qla_mbx.c | ||
3983 | @@ -6160,8 +6160,7 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, | ||
3984 | } | ||
3985 | |||
3986 | /* Check for logged in state. */ | ||
3987 | - if (current_login_state != PDS_PRLI_COMPLETE && | ||
3988 | - last_login_state != PDS_PRLI_COMPLETE) { | ||
3989 | + if (current_login_state != PDS_PRLI_COMPLETE) { | ||
3990 | ql_dbg(ql_dbg_mbx, vha, 0x119a, | ||
3991 | "Unable to verify login-state (%x/%x) for loop_id %x.\n", | ||
3992 | current_login_state, last_login_state, fcport->loop_id); | ||
3993 | diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c | ||
3994 | index bd9f14bf7ac2..e538e6308885 100644 | ||
3995 | --- a/drivers/scsi/qla2xxx/qla_mid.c | ||
3996 | +++ b/drivers/scsi/qla2xxx/qla_mid.c | ||
3997 | @@ -343,15 +343,21 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) | ||
3998 | "FCPort update end.\n"); | ||
3999 | } | ||
4000 | |||
4001 | - if ((test_and_clear_bit(RELOGIN_NEEDED, &vha->dpc_flags)) && | ||
4002 | - !test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) && | ||
4003 | - atomic_read(&vha->loop_state) != LOOP_DOWN) { | ||
4004 | - | ||
4005 | - ql_dbg(ql_dbg_dpc, vha, 0x4018, | ||
4006 | - "Relogin needed scheduled.\n"); | ||
4007 | - qla2x00_relogin(vha); | ||
4008 | - ql_dbg(ql_dbg_dpc, vha, 0x4019, | ||
4009 | - "Relogin needed end.\n"); | ||
4010 | + if (test_bit(RELOGIN_NEEDED, &vha->dpc_flags) && | ||
4011 | + !test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) && | ||
4012 | + atomic_read(&vha->loop_state) != LOOP_DOWN) { | ||
4013 | + | ||
4014 | + if (!vha->relogin_jif || | ||
4015 | + time_after_eq(jiffies, vha->relogin_jif)) { | ||
4016 | + vha->relogin_jif = jiffies + HZ; | ||
4017 | + clear_bit(RELOGIN_NEEDED, &vha->dpc_flags); | ||
4018 | + | ||
4019 | + ql_dbg(ql_dbg_dpc, vha, 0x4018, | ||
4020 | + "Relogin needed scheduled.\n"); | ||
4021 | + qla2x00_relogin(vha); | ||
4022 | + ql_dbg(ql_dbg_dpc, vha, 0x4019, | ||
4023 | + "Relogin needed end.\n"); | ||
4024 | + } | ||
4025 | } | ||
4026 | |||
4027 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) && | ||
4028 | @@ -569,14 +575,15 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | ||
4029 | int | ||
4030 | qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req) | ||
4031 | { | ||
4032 | - int ret = -1; | ||
4033 | + int ret = QLA_SUCCESS; | ||
4034 | |||
4035 | - if (req) { | ||
4036 | + if (req && vha->flags.qpairs_req_created) { | ||
4037 | req->options |= BIT_0; | ||
4038 | ret = qla25xx_init_req_que(vha, req); | ||
4039 | + if (ret != QLA_SUCCESS) | ||
4040 | + return QLA_FUNCTION_FAILED; | ||
4041 | } | ||
4042 | - if (ret == QLA_SUCCESS) | ||
4043 | - qla25xx_free_req_que(vha, req); | ||
4044 | + qla25xx_free_req_que(vha, req); | ||
4045 | |||
4046 | return ret; | ||
4047 | } | ||
4048 | @@ -584,14 +591,15 @@ qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req) | ||
4049 | int | ||
4050 | qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | ||
4051 | { | ||
4052 | - int ret = -1; | ||
4053 | + int ret = QLA_SUCCESS; | ||
4054 | |||
4055 | - if (rsp) { | ||
4056 | + if (rsp && vha->flags.qpairs_rsp_created) { | ||
4057 | rsp->options |= BIT_0; | ||
4058 | ret = qla25xx_init_rsp_que(vha, rsp); | ||
4059 | + if (ret != QLA_SUCCESS) | ||
4060 | + return QLA_FUNCTION_FAILED; | ||
4061 | } | ||
4062 | - if (ret == QLA_SUCCESS) | ||
4063 | - qla25xx_free_rsp_que(vha, rsp); | ||
4064 | + qla25xx_free_rsp_que(vha, rsp); | ||
4065 | |||
4066 | return ret; | ||
4067 | } | ||
4068 | diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c | ||
4069 | index 46f2d0cf7c0d..1f69e89b950f 100644 | ||
4070 | --- a/drivers/scsi/qla2xxx/qla_os.c | ||
4071 | +++ b/drivers/scsi/qla2xxx/qla_os.c | ||
4072 | @@ -3011,9 +3011,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
4073 | base_vha = qla2x00_create_host(sht, ha); | ||
4074 | if (!base_vha) { | ||
4075 | ret = -ENOMEM; | ||
4076 | - qla2x00_mem_free(ha); | ||
4077 | - qla2x00_free_req_que(ha, req); | ||
4078 | - qla2x00_free_rsp_que(ha, rsp); | ||
4079 | goto probe_hw_failed; | ||
4080 | } | ||
4081 | |||
4082 | @@ -3074,7 +3071,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
4083 | /* Set up the irqs */ | ||
4084 | ret = qla2x00_request_irqs(ha, rsp); | ||
4085 | if (ret) | ||
4086 | - goto probe_init_failed; | ||
4087 | + goto probe_hw_failed; | ||
4088 | |||
4089 | /* Alloc arrays of request and response ring ptrs */ | ||
4090 | if (!qla2x00_alloc_queues(ha, req, rsp)) { | ||
4091 | @@ -3193,10 +3190,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
4092 | host->can_queue, base_vha->req, | ||
4093 | base_vha->mgmt_svr_loop_id, host->sg_tablesize); | ||
4094 | |||
4095 | + ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 0); | ||
4096 | + | ||
4097 | if (ha->mqenable) { | ||
4098 | bool mq = false; | ||
4099 | bool startit = false; | ||
4100 | - ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 0); | ||
4101 | |||
4102 | if (QLA_TGT_MODE_ENABLED()) { | ||
4103 | mq = true; | ||
4104 | @@ -3390,6 +3388,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
4105 | scsi_host_put(base_vha->host); | ||
4106 | |||
4107 | probe_hw_failed: | ||
4108 | + qla2x00_mem_free(ha); | ||
4109 | + qla2x00_free_req_que(ha, req); | ||
4110 | + qla2x00_free_rsp_que(ha, rsp); | ||
4111 | qla2x00_clear_drv_active(ha); | ||
4112 | |||
4113 | iospace_config_failed: | ||
4114 | @@ -4514,6 +4515,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | ||
4115 | INIT_LIST_HEAD(&vha->qp_list); | ||
4116 | INIT_LIST_HEAD(&vha->gnl.fcports); | ||
4117 | INIT_LIST_HEAD(&vha->nvme_rport_list); | ||
4118 | + INIT_LIST_HEAD(&vha->gpnid_list); | ||
4119 | |||
4120 | spin_lock_init(&vha->work_lock); | ||
4121 | spin_lock_init(&vha->cmd_list_lock); | ||
4122 | @@ -4748,20 +4750,49 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | ||
4123 | } else { | ||
4124 | list_add_tail(&fcport->list, &vha->vp_fcports); | ||
4125 | |||
4126 | - if (pla) { | ||
4127 | - qlt_plogi_ack_link(vha, pla, fcport, | ||
4128 | - QLT_PLOGI_LINK_SAME_WWN); | ||
4129 | - pla->ref_count--; | ||
4130 | - } | ||
4131 | + } | ||
4132 | + if (pla) { | ||
4133 | + qlt_plogi_ack_link(vha, pla, fcport, | ||
4134 | + QLT_PLOGI_LINK_SAME_WWN); | ||
4135 | + pla->ref_count--; | ||
4136 | } | ||
4137 | } | ||
4138 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
4139 | |||
4140 | if (fcport) { | ||
4141 | - if (pla) | ||
4142 | + if (pla) { | ||
4143 | qlt_plogi_ack_unref(vha, pla); | ||
4144 | - else | ||
4145 | - qla24xx_async_gffid(vha, fcport); | ||
4146 | + } else { | ||
4147 | + spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
4148 | + tfcp = qla2x00_find_fcport_by_nportid(vha, | ||
4149 | + &e->u.new_sess.id, 1); | ||
4150 | + if (tfcp && (tfcp != fcport)) { | ||
4151 | + /* | ||
4152 | + * We have a conflict fcport with same NportID. | ||
4153 | + */ | ||
4154 | + ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
4155 | + "%s %8phC found conflict b4 add. DS %d LS %d\n", | ||
4156 | + __func__, tfcp->port_name, tfcp->disc_state, | ||
4157 | + tfcp->fw_login_state); | ||
4158 | + | ||
4159 | + switch (tfcp->disc_state) { | ||
4160 | + case DSC_DELETED: | ||
4161 | + break; | ||
4162 | + case DSC_DELETE_PEND: | ||
4163 | + fcport->login_pause = 1; | ||
4164 | + tfcp->conflict = fcport; | ||
4165 | + break; | ||
4166 | + default: | ||
4167 | + fcport->login_pause = 1; | ||
4168 | + tfcp->conflict = fcport; | ||
4169 | + qlt_schedule_sess_for_deletion_lock | ||
4170 | + (tfcp); | ||
4171 | + break; | ||
4172 | + } | ||
4173 | + } | ||
4174 | + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
4175 | + qla24xx_async_gnl(vha, fcport); | ||
4176 | + } | ||
4177 | } | ||
4178 | |||
4179 | if (free_fcport) { | ||
4180 | @@ -4874,7 +4905,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) | ||
4181 | */ | ||
4182 | if (atomic_read(&fcport->state) != FCS_ONLINE && | ||
4183 | fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) { | ||
4184 | - fcport->login_retry--; | ||
4185 | + | ||
4186 | if (fcport->flags & FCF_FABRIC_DEVICE) { | ||
4187 | ql_dbg(ql_dbg_disc, fcport->vha, 0x2108, | ||
4188 | "%s %8phC DS %d LS %d\n", __func__, | ||
4189 | @@ -4885,6 +4916,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) | ||
4190 | ea.fcport = fcport; | ||
4191 | qla2x00_fcport_event_handler(vha, &ea); | ||
4192 | } else { | ||
4193 | + fcport->login_retry--; | ||
4194 | status = qla2x00_local_device_login(vha, | ||
4195 | fcport); | ||
4196 | if (status == QLA_SUCCESS) { | ||
4197 | @@ -5867,16 +5899,21 @@ qla2x00_do_dpc(void *data) | ||
4198 | } | ||
4199 | |||
4200 | /* Retry each device up to login retry count */ | ||
4201 | - if ((test_and_clear_bit(RELOGIN_NEEDED, | ||
4202 | - &base_vha->dpc_flags)) && | ||
4203 | + if (test_bit(RELOGIN_NEEDED, &base_vha->dpc_flags) && | ||
4204 | !test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) && | ||
4205 | atomic_read(&base_vha->loop_state) != LOOP_DOWN) { | ||
4206 | |||
4207 | - ql_dbg(ql_dbg_dpc, base_vha, 0x400d, | ||
4208 | - "Relogin scheduled.\n"); | ||
4209 | - qla2x00_relogin(base_vha); | ||
4210 | - ql_dbg(ql_dbg_dpc, base_vha, 0x400e, | ||
4211 | - "Relogin end.\n"); | ||
4212 | + if (!base_vha->relogin_jif || | ||
4213 | + time_after_eq(jiffies, base_vha->relogin_jif)) { | ||
4214 | + base_vha->relogin_jif = jiffies + HZ; | ||
4215 | + clear_bit(RELOGIN_NEEDED, &base_vha->dpc_flags); | ||
4216 | + | ||
4217 | + ql_dbg(ql_dbg_dpc, base_vha, 0x400d, | ||
4218 | + "Relogin scheduled.\n"); | ||
4219 | + qla2x00_relogin(base_vha); | ||
4220 | + ql_dbg(ql_dbg_dpc, base_vha, 0x400e, | ||
4221 | + "Relogin end.\n"); | ||
4222 | + } | ||
4223 | } | ||
4224 | loop_resync_check: | ||
4225 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, | ||
4226 | @@ -6608,9 +6645,14 @@ qla83xx_disable_laser(scsi_qla_host_t *vha) | ||
4227 | |||
4228 | static int qla2xxx_map_queues(struct Scsi_Host *shost) | ||
4229 | { | ||
4230 | + int rc; | ||
4231 | scsi_qla_host_t *vha = (scsi_qla_host_t *)shost->hostdata; | ||
4232 | |||
4233 | - return blk_mq_pci_map_queues(&shost->tag_set, vha->hw->pdev); | ||
4234 | + if (USER_CTRL_IRQ(vha->hw)) | ||
4235 | + rc = blk_mq_map_queues(&shost->tag_set); | ||
4236 | + else | ||
4237 | + rc = blk_mq_pci_map_queues(&shost->tag_set, vha->hw->pdev); | ||
4238 | + return rc; | ||
4239 | } | ||
4240 | |||
4241 | static const struct pci_error_handlers qla2xxx_err_handler = { | ||
4242 | diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c | ||
4243 | index 18069edd4773..cb35bb1ae305 100644 | ||
4244 | --- a/drivers/scsi/qla2xxx/qla_target.c | ||
4245 | +++ b/drivers/scsi/qla2xxx/qla_target.c | ||
4246 | @@ -665,7 +665,7 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport, | ||
4247 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2); | ||
4248 | |||
4249 | sp->u.iocb_cmd.u.nack.ntfy = ntfy; | ||
4250 | - | ||
4251 | + sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; | ||
4252 | sp->done = qla2x00_async_nack_sp_done; | ||
4253 | |||
4254 | rval = qla2x00_start_sp(sp); | ||
4255 | @@ -890,6 +890,17 @@ qlt_plogi_ack_link(struct scsi_qla_host *vha, struct qlt_plogi_ack_t *pla, | ||
4256 | iocb->u.isp24.port_id[1], iocb->u.isp24.port_id[0], | ||
4257 | pla->ref_count, pla, link); | ||
4258 | |||
4259 | + if (link == QLT_PLOGI_LINK_CONFLICT) { | ||
4260 | + switch (sess->disc_state) { | ||
4261 | + case DSC_DELETED: | ||
4262 | + case DSC_DELETE_PEND: | ||
4263 | + pla->ref_count--; | ||
4264 | + return; | ||
4265 | + default: | ||
4266 | + break; | ||
4267 | + } | ||
4268 | + } | ||
4269 | + | ||
4270 | if (sess->plogi_link[link]) | ||
4271 | qlt_plogi_ack_unref(vha, sess->plogi_link[link]); | ||
4272 | |||
4273 | @@ -974,7 +985,7 @@ static void qlt_free_session_done(struct work_struct *work) | ||
4274 | qlt_send_first_logo(vha, &logo); | ||
4275 | } | ||
4276 | |||
4277 | - if (sess->logout_on_delete) { | ||
4278 | + if (sess->logout_on_delete && sess->loop_id != FC_NO_LOOP_ID) { | ||
4279 | int rc; | ||
4280 | |||
4281 | rc = qla2x00_post_async_logout_work(vha, sess, NULL); | ||
4282 | @@ -1033,8 +1044,7 @@ static void qlt_free_session_done(struct work_struct *work) | ||
4283 | sess->login_succ = 0; | ||
4284 | } | ||
4285 | |||
4286 | - if (sess->chip_reset != ha->base_qpair->chip_reset) | ||
4287 | - qla2x00_clear_loop_id(sess); | ||
4288 | + qla2x00_clear_loop_id(sess); | ||
4289 | |||
4290 | if (sess->conflict) { | ||
4291 | sess->conflict->login_pause = 0; | ||
4292 | @@ -1205,7 +1215,8 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess, | ||
4293 | ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, | ||
4294 | "Scheduling sess %p for deletion\n", sess); | ||
4295 | |||
4296 | - schedule_work(&sess->del_work); | ||
4297 | + INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); | ||
4298 | + queue_work(sess->vha->hw->wq, &sess->del_work); | ||
4299 | } | ||
4300 | |||
4301 | void qlt_schedule_sess_for_deletion_lock(struct fc_port *sess) | ||
4302 | @@ -1560,8 +1571,11 @@ static void qlt_release(struct qla_tgt *tgt) | ||
4303 | |||
4304 | btree_destroy64(&tgt->lun_qpair_map); | ||
4305 | |||
4306 | - if (ha->tgt.tgt_ops && ha->tgt.tgt_ops->remove_target) | ||
4307 | - ha->tgt.tgt_ops->remove_target(vha); | ||
4308 | + if (vha->vp_idx) | ||
4309 | + if (ha->tgt.tgt_ops && | ||
4310 | + ha->tgt.tgt_ops->remove_target && | ||
4311 | + vha->vha_tgt.target_lport_ptr) | ||
4312 | + ha->tgt.tgt_ops->remove_target(vha); | ||
4313 | |||
4314 | vha->vha_tgt.qla_tgt = NULL; | ||
4315 | |||
4316 | @@ -3708,7 +3722,7 @@ static int qlt_term_ctio_exchange(struct qla_qpair *qpair, void *ctio, | ||
4317 | term = 1; | ||
4318 | |||
4319 | if (term) | ||
4320 | - qlt_term_ctio_exchange(qpair, ctio, cmd, status); | ||
4321 | + qlt_send_term_exchange(qpair, cmd, &cmd->atio, 1, 0); | ||
4322 | |||
4323 | return term; | ||
4324 | } | ||
4325 | @@ -4584,9 +4598,9 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, | ||
4326 | "Invalidating sess %p loop_id %d wwn %llx.\n", | ||
4327 | other_sess, other_sess->loop_id, other_wwn); | ||
4328 | |||
4329 | - | ||
4330 | other_sess->keep_nport_handle = 1; | ||
4331 | - *conflict_sess = other_sess; | ||
4332 | + if (other_sess->disc_state != DSC_DELETED) | ||
4333 | + *conflict_sess = other_sess; | ||
4334 | qlt_schedule_sess_for_deletion(other_sess, | ||
4335 | true); | ||
4336 | } | ||
4337 | @@ -4733,6 +4747,10 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | ||
4338 | sess->d_id = port_id; | ||
4339 | sess->login_gen++; | ||
4340 | |||
4341 | + ql_dbg(ql_dbg_disc, vha, 0x20f9, | ||
4342 | + "%s %d %8phC DS %d\n", | ||
4343 | + __func__, __LINE__, sess->port_name, sess->disc_state); | ||
4344 | + | ||
4345 | switch (sess->disc_state) { | ||
4346 | case DSC_DELETED: | ||
4347 | qlt_plogi_ack_unref(vha, pla); | ||
4348 | @@ -4782,12 +4800,20 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | ||
4349 | } | ||
4350 | |||
4351 | if (conflict_sess) { | ||
4352 | - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf09b, | ||
4353 | - "PRLI with conflicting sess %p port %8phC\n", | ||
4354 | - conflict_sess, conflict_sess->port_name); | ||
4355 | - qlt_send_term_imm_notif(vha, iocb, 1); | ||
4356 | - res = 0; | ||
4357 | - break; | ||
4358 | + switch (conflict_sess->disc_state) { | ||
4359 | + case DSC_DELETED: | ||
4360 | + case DSC_DELETE_PEND: | ||
4361 | + break; | ||
4362 | + default: | ||
4363 | + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf09b, | ||
4364 | + "PRLI with conflicting sess %p port %8phC\n", | ||
4365 | + conflict_sess, conflict_sess->port_name); | ||
4366 | + conflict_sess->fw_login_state = | ||
4367 | + DSC_LS_PORT_UNAVAIL; | ||
4368 | + qlt_send_term_imm_notif(vha, iocb, 1); | ||
4369 | + res = 0; | ||
4370 | + break; | ||
4371 | + } | ||
4372 | } | ||
4373 | |||
4374 | if (sess != NULL) { | ||
4375 | @@ -5755,7 +5781,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, | ||
4376 | unsigned long flags; | ||
4377 | u8 newfcport = 0; | ||
4378 | |||
4379 | - fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); | ||
4380 | + fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL); | ||
4381 | if (!fcport) { | ||
4382 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06f, | ||
4383 | "qla_target(%d): Allocation of tmp FC port failed", | ||
4384 | @@ -5784,6 +5810,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, | ||
4385 | tfcp->port_type = fcport->port_type; | ||
4386 | tfcp->supported_classes = fcport->supported_classes; | ||
4387 | tfcp->flags |= fcport->flags; | ||
4388 | + tfcp->scan_state = QLA_FCPORT_FOUND; | ||
4389 | |||
4390 | del = fcport; | ||
4391 | fcport = tfcp; | ||
4392 | diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c | ||
4393 | index 3737c6d3b064..61628581c6a2 100644 | ||
4394 | --- a/drivers/scsi/scsi_error.c | ||
4395 | +++ b/drivers/scsi/scsi_error.c | ||
4396 | @@ -222,7 +222,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd) | ||
4397 | |||
4398 | static void scsi_eh_inc_host_failed(struct rcu_head *head) | ||
4399 | { | ||
4400 | - struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu); | ||
4401 | + struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu); | ||
4402 | + struct Scsi_Host *shost = scmd->device->host; | ||
4403 | unsigned long flags; | ||
4404 | |||
4405 | spin_lock_irqsave(shost->host_lock, flags); | ||
4406 | @@ -258,7 +259,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd) | ||
4407 | * Ensure that all tasks observe the host state change before the | ||
4408 | * host_failed change. | ||
4409 | */ | ||
4410 | - call_rcu(&shost->rcu, scsi_eh_inc_host_failed); | ||
4411 | + call_rcu(&scmd->rcu, scsi_eh_inc_host_failed); | ||
4412 | } | ||
4413 | |||
4414 | /** | ||
4415 | diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c | ||
4416 | index 83856ee14851..8f9a2e50d742 100644 | ||
4417 | --- a/drivers/scsi/scsi_lib.c | ||
4418 | +++ b/drivers/scsi/scsi_lib.c | ||
4419 | @@ -670,6 +670,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | ||
4420 | if (!blk_rq_is_scsi(req)) { | ||
4421 | WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); | ||
4422 | cmd->flags &= ~SCMD_INITIALIZED; | ||
4423 | + destroy_rcu_head(&cmd->rcu); | ||
4424 | } | ||
4425 | |||
4426 | if (req->mq_ctx) { | ||
4427 | @@ -1150,6 +1151,7 @@ void scsi_initialize_rq(struct request *rq) | ||
4428 | struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); | ||
4429 | |||
4430 | scsi_req_init(&cmd->req); | ||
4431 | + init_rcu_head(&cmd->rcu); | ||
4432 | cmd->jiffies_at_alloc = jiffies; | ||
4433 | cmd->retries = 0; | ||
4434 | } | ||
4435 | diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c | ||
4436 | index eb30f3e09a47..71458f493cf8 100644 | ||
4437 | --- a/drivers/virtio/virtio_ring.c | ||
4438 | +++ b/drivers/virtio/virtio_ring.c | ||
4439 | @@ -428,8 +428,6 @@ static inline int virtqueue_add(struct virtqueue *_vq, | ||
4440 | i = virtio16_to_cpu(_vq->vdev, vq->vring.desc[i].next); | ||
4441 | } | ||
4442 | |||
4443 | - vq->vq.num_free += total_sg; | ||
4444 | - | ||
4445 | if (indirect) | ||
4446 | kfree(desc); | ||
4447 | |||
4448 | diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c | ||
4449 | index 67fbe35ce7cf..b0a158073abd 100644 | ||
4450 | --- a/drivers/watchdog/hpwdt.c | ||
4451 | +++ b/drivers/watchdog/hpwdt.c | ||
4452 | @@ -28,16 +28,7 @@ | ||
4453 | #include <linux/types.h> | ||
4454 | #include <linux/uaccess.h> | ||
4455 | #include <linux/watchdog.h> | ||
4456 | -#ifdef CONFIG_HPWDT_NMI_DECODING | ||
4457 | -#include <linux/dmi.h> | ||
4458 | -#include <linux/spinlock.h> | ||
4459 | -#include <linux/nmi.h> | ||
4460 | -#include <linux/kdebug.h> | ||
4461 | -#include <linux/notifier.h> | ||
4462 | -#include <asm/set_memory.h> | ||
4463 | -#endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
4464 | #include <asm/nmi.h> | ||
4465 | -#include <asm/frame.h> | ||
4466 | |||
4467 | #define HPWDT_VERSION "1.4.0" | ||
4468 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) | ||
4469 | @@ -48,10 +39,14 @@ | ||
4470 | static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ | ||
4471 | static unsigned int reload; /* the computed soft_margin */ | ||
4472 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
4473 | +#ifdef CONFIG_HPWDT_NMI_DECODING | ||
4474 | +static unsigned int allow_kdump = 1; | ||
4475 | +#endif | ||
4476 | static char expect_release; | ||
4477 | static unsigned long hpwdt_is_open; | ||
4478 | |||
4479 | static void __iomem *pci_mem_addr; /* the PCI-memory address */ | ||
4480 | +static unsigned long __iomem *hpwdt_nmistat; | ||
4481 | static unsigned long __iomem *hpwdt_timer_reg; | ||
4482 | static unsigned long __iomem *hpwdt_timer_con; | ||
4483 | |||
4484 | @@ -62,373 +57,6 @@ static const struct pci_device_id hpwdt_devices[] = { | ||
4485 | }; | ||
4486 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); | ||
4487 | |||
4488 | -#ifdef CONFIG_HPWDT_NMI_DECODING | ||
4489 | -#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ | ||
4490 | -#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 | ||
4491 | -#define PCI_BIOS32_PARAGRAPH_LEN 16 | ||
4492 | -#define PCI_ROM_BASE1 0x000F0000 | ||
4493 | -#define ROM_SIZE 0x10000 | ||
4494 | - | ||
4495 | -struct bios32_service_dir { | ||
4496 | - u32 signature; | ||
4497 | - u32 entry_point; | ||
4498 | - u8 revision; | ||
4499 | - u8 length; | ||
4500 | - u8 checksum; | ||
4501 | - u8 reserved[5]; | ||
4502 | -}; | ||
4503 | - | ||
4504 | -/* type 212 */ | ||
4505 | -struct smbios_cru64_info { | ||
4506 | - u8 type; | ||
4507 | - u8 byte_length; | ||
4508 | - u16 handle; | ||
4509 | - u32 signature; | ||
4510 | - u64 physical_address; | ||
4511 | - u32 double_length; | ||
4512 | - u32 double_offset; | ||
4513 | -}; | ||
4514 | -#define SMBIOS_CRU64_INFORMATION 212 | ||
4515 | - | ||
4516 | -/* type 219 */ | ||
4517 | -struct smbios_proliant_info { | ||
4518 | - u8 type; | ||
4519 | - u8 byte_length; | ||
4520 | - u16 handle; | ||
4521 | - u32 power_features; | ||
4522 | - u32 omega_features; | ||
4523 | - u32 reserved; | ||
4524 | - u32 misc_features; | ||
4525 | -}; | ||
4526 | -#define SMBIOS_ICRU_INFORMATION 219 | ||
4527 | - | ||
4528 | - | ||
4529 | -struct cmn_registers { | ||
4530 | - union { | ||
4531 | - struct { | ||
4532 | - u8 ral; | ||
4533 | - u8 rah; | ||
4534 | - u16 rea2; | ||
4535 | - }; | ||
4536 | - u32 reax; | ||
4537 | - } u1; | ||
4538 | - union { | ||
4539 | - struct { | ||
4540 | - u8 rbl; | ||
4541 | - u8 rbh; | ||
4542 | - u8 reb2l; | ||
4543 | - u8 reb2h; | ||
4544 | - }; | ||
4545 | - u32 rebx; | ||
4546 | - } u2; | ||
4547 | - union { | ||
4548 | - struct { | ||
4549 | - u8 rcl; | ||
4550 | - u8 rch; | ||
4551 | - u16 rec2; | ||
4552 | - }; | ||
4553 | - u32 recx; | ||
4554 | - } u3; | ||
4555 | - union { | ||
4556 | - struct { | ||
4557 | - u8 rdl; | ||
4558 | - u8 rdh; | ||
4559 | - u16 red2; | ||
4560 | - }; | ||
4561 | - u32 redx; | ||
4562 | - } u4; | ||
4563 | - | ||
4564 | - u32 resi; | ||
4565 | - u32 redi; | ||
4566 | - u16 rds; | ||
4567 | - u16 res; | ||
4568 | - u32 reflags; | ||
4569 | -} __attribute__((packed)); | ||
4570 | - | ||
4571 | -static unsigned int hpwdt_nmi_decoding; | ||
4572 | -static unsigned int allow_kdump = 1; | ||
4573 | -static unsigned int is_icru; | ||
4574 | -static unsigned int is_uefi; | ||
4575 | -static DEFINE_SPINLOCK(rom_lock); | ||
4576 | -static void *cru_rom_addr; | ||
4577 | -static struct cmn_registers cmn_regs; | ||
4578 | - | ||
4579 | -extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | ||
4580 | - unsigned long *pRomEntry); | ||
4581 | - | ||
4582 | -#ifdef CONFIG_X86_32 | ||
4583 | -/* --32 Bit Bios------------------------------------------------------------ */ | ||
4584 | - | ||
4585 | -#define HPWDT_ARCH 32 | ||
4586 | - | ||
4587 | -asm(".text \n\t" | ||
4588 | - ".align 4 \n\t" | ||
4589 | - ".globl asminline_call \n" | ||
4590 | - "asminline_call: \n\t" | ||
4591 | - "pushl %ebp \n\t" | ||
4592 | - "movl %esp, %ebp \n\t" | ||
4593 | - "pusha \n\t" | ||
4594 | - "pushf \n\t" | ||
4595 | - "push %es \n\t" | ||
4596 | - "push %ds \n\t" | ||
4597 | - "pop %es \n\t" | ||
4598 | - "movl 8(%ebp),%eax \n\t" | ||
4599 | - "movl 4(%eax),%ebx \n\t" | ||
4600 | - "movl 8(%eax),%ecx \n\t" | ||
4601 | - "movl 12(%eax),%edx \n\t" | ||
4602 | - "movl 16(%eax),%esi \n\t" | ||
4603 | - "movl 20(%eax),%edi \n\t" | ||
4604 | - "movl (%eax),%eax \n\t" | ||
4605 | - "push %cs \n\t" | ||
4606 | - "call *12(%ebp) \n\t" | ||
4607 | - "pushf \n\t" | ||
4608 | - "pushl %eax \n\t" | ||
4609 | - "movl 8(%ebp),%eax \n\t" | ||
4610 | - "movl %ebx,4(%eax) \n\t" | ||
4611 | - "movl %ecx,8(%eax) \n\t" | ||
4612 | - "movl %edx,12(%eax) \n\t" | ||
4613 | - "movl %esi,16(%eax) \n\t" | ||
4614 | - "movl %edi,20(%eax) \n\t" | ||
4615 | - "movw %ds,24(%eax) \n\t" | ||
4616 | - "movw %es,26(%eax) \n\t" | ||
4617 | - "popl %ebx \n\t" | ||
4618 | - "movl %ebx,(%eax) \n\t" | ||
4619 | - "popl %ebx \n\t" | ||
4620 | - "movl %ebx,28(%eax) \n\t" | ||
4621 | - "pop %es \n\t" | ||
4622 | - "popf \n\t" | ||
4623 | - "popa \n\t" | ||
4624 | - "leave \n\t" | ||
4625 | - "ret \n\t" | ||
4626 | - ".previous"); | ||
4627 | - | ||
4628 | - | ||
4629 | -/* | ||
4630 | - * cru_detect | ||
4631 | - * | ||
4632 | - * Routine Description: | ||
4633 | - * This function uses the 32-bit BIOS Service Directory record to | ||
4634 | - * search for a $CRU record. | ||
4635 | - * | ||
4636 | - * Return Value: | ||
4637 | - * 0 : SUCCESS | ||
4638 | - * <0 : FAILURE | ||
4639 | - */ | ||
4640 | -static int cru_detect(unsigned long map_entry, | ||
4641 | - unsigned long map_offset) | ||
4642 | -{ | ||
4643 | - void *bios32_map; | ||
4644 | - unsigned long *bios32_entrypoint; | ||
4645 | - unsigned long cru_physical_address; | ||
4646 | - unsigned long cru_length; | ||
4647 | - unsigned long physical_bios_base = 0; | ||
4648 | - unsigned long physical_bios_offset = 0; | ||
4649 | - int retval = -ENODEV; | ||
4650 | - | ||
4651 | - bios32_map = ioremap(map_entry, (2 * PAGE_SIZE)); | ||
4652 | - | ||
4653 | - if (bios32_map == NULL) | ||
4654 | - return -ENODEV; | ||
4655 | - | ||
4656 | - bios32_entrypoint = bios32_map + map_offset; | ||
4657 | - | ||
4658 | - cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; | ||
4659 | - | ||
4660 | - set_memory_x((unsigned long)bios32_map, 2); | ||
4661 | - asminline_call(&cmn_regs, bios32_entrypoint); | ||
4662 | - | ||
4663 | - if (cmn_regs.u1.ral != 0) { | ||
4664 | - pr_warn("Call succeeded but with an error: 0x%x\n", | ||
4665 | - cmn_regs.u1.ral); | ||
4666 | - } else { | ||
4667 | - physical_bios_base = cmn_regs.u2.rebx; | ||
4668 | - physical_bios_offset = cmn_regs.u4.redx; | ||
4669 | - cru_length = cmn_regs.u3.recx; | ||
4670 | - cru_physical_address = | ||
4671 | - physical_bios_base + physical_bios_offset; | ||
4672 | - | ||
4673 | - /* If the values look OK, then map it in. */ | ||
4674 | - if ((physical_bios_base + physical_bios_offset)) { | ||
4675 | - cru_rom_addr = | ||
4676 | - ioremap(cru_physical_address, cru_length); | ||
4677 | - if (cru_rom_addr) { | ||
4678 | - set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, | ||
4679 | - (cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT); | ||
4680 | - retval = 0; | ||
4681 | - } | ||
4682 | - } | ||
4683 | - | ||
4684 | - pr_debug("CRU Base Address: 0x%lx\n", physical_bios_base); | ||
4685 | - pr_debug("CRU Offset Address: 0x%lx\n", physical_bios_offset); | ||
4686 | - pr_debug("CRU Length: 0x%lx\n", cru_length); | ||
4687 | - pr_debug("CRU Mapped Address: %p\n", &cru_rom_addr); | ||
4688 | - } | ||
4689 | - iounmap(bios32_map); | ||
4690 | - return retval; | ||
4691 | -} | ||
4692 | - | ||
4693 | -/* | ||
4694 | - * bios_checksum | ||
4695 | - */ | ||
4696 | -static int bios_checksum(const char __iomem *ptr, int len) | ||
4697 | -{ | ||
4698 | - char sum = 0; | ||
4699 | - int i; | ||
4700 | - | ||
4701 | - /* | ||
4702 | - * calculate checksum of size bytes. This should add up | ||
4703 | - * to zero if we have a valid header. | ||
4704 | - */ | ||
4705 | - for (i = 0; i < len; i++) | ||
4706 | - sum += ptr[i]; | ||
4707 | - | ||
4708 | - return ((sum == 0) && (len > 0)); | ||
4709 | -} | ||
4710 | - | ||
4711 | -/* | ||
4712 | - * bios32_present | ||
4713 | - * | ||
4714 | - * Routine Description: | ||
4715 | - * This function finds the 32-bit BIOS Service Directory | ||
4716 | - * | ||
4717 | - * Return Value: | ||
4718 | - * 0 : SUCCESS | ||
4719 | - * <0 : FAILURE | ||
4720 | - */ | ||
4721 | -static int bios32_present(const char __iomem *p) | ||
4722 | -{ | ||
4723 | - struct bios32_service_dir *bios_32_ptr; | ||
4724 | - int length; | ||
4725 | - unsigned long map_entry, map_offset; | ||
4726 | - | ||
4727 | - bios_32_ptr = (struct bios32_service_dir *) p; | ||
4728 | - | ||
4729 | - /* | ||
4730 | - * Search for signature by checking equal to the swizzled value | ||
4731 | - * instead of calling another routine to perform a strcmp. | ||
4732 | - */ | ||
4733 | - if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) { | ||
4734 | - length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN; | ||
4735 | - if (bios_checksum(p, length)) { | ||
4736 | - /* | ||
4737 | - * According to the spec, we're looking for the | ||
4738 | - * first 4KB-aligned address below the entrypoint | ||
4739 | - * listed in the header. The Service Directory code | ||
4740 | - * is guaranteed to occupy no more than 2 4KB pages. | ||
4741 | - */ | ||
4742 | - map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1); | ||
4743 | - map_offset = bios_32_ptr->entry_point - map_entry; | ||
4744 | - | ||
4745 | - return cru_detect(map_entry, map_offset); | ||
4746 | - } | ||
4747 | - } | ||
4748 | - return -ENODEV; | ||
4749 | -} | ||
4750 | - | ||
4751 | -static int detect_cru_service(void) | ||
4752 | -{ | ||
4753 | - char __iomem *p, *q; | ||
4754 | - int rc = -1; | ||
4755 | - | ||
4756 | - /* | ||
4757 | - * Search from 0x0f0000 through 0x0fffff, inclusive. | ||
4758 | - */ | ||
4759 | - p = ioremap(PCI_ROM_BASE1, ROM_SIZE); | ||
4760 | - if (p == NULL) | ||
4761 | - return -ENOMEM; | ||
4762 | - | ||
4763 | - for (q = p; q < p + ROM_SIZE; q += 16) { | ||
4764 | - rc = bios32_present(q); | ||
4765 | - if (!rc) | ||
4766 | - break; | ||
4767 | - } | ||
4768 | - iounmap(p); | ||
4769 | - return rc; | ||
4770 | -} | ||
4771 | -/* ------------------------------------------------------------------------- */ | ||
4772 | -#endif /* CONFIG_X86_32 */ | ||
4773 | -#ifdef CONFIG_X86_64 | ||
4774 | -/* --64 Bit Bios------------------------------------------------------------ */ | ||
4775 | - | ||
4776 | -#define HPWDT_ARCH 64 | ||
4777 | - | ||
4778 | -asm(".text \n\t" | ||
4779 | - ".align 4 \n\t" | ||
4780 | - ".globl asminline_call \n\t" | ||
4781 | - ".type asminline_call, @function \n\t" | ||
4782 | - "asminline_call: \n\t" | ||
4783 | - FRAME_BEGIN | ||
4784 | - "pushq %rax \n\t" | ||
4785 | - "pushq %rbx \n\t" | ||
4786 | - "pushq %rdx \n\t" | ||
4787 | - "pushq %r12 \n\t" | ||
4788 | - "pushq %r9 \n\t" | ||
4789 | - "movq %rsi, %r12 \n\t" | ||
4790 | - "movq %rdi, %r9 \n\t" | ||
4791 | - "movl 4(%r9),%ebx \n\t" | ||
4792 | - "movl 8(%r9),%ecx \n\t" | ||
4793 | - "movl 12(%r9),%edx \n\t" | ||
4794 | - "movl 16(%r9),%esi \n\t" | ||
4795 | - "movl 20(%r9),%edi \n\t" | ||
4796 | - "movl (%r9),%eax \n\t" | ||
4797 | - "call *%r12 \n\t" | ||
4798 | - "pushfq \n\t" | ||
4799 | - "popq %r12 \n\t" | ||
4800 | - "movl %eax, (%r9) \n\t" | ||
4801 | - "movl %ebx, 4(%r9) \n\t" | ||
4802 | - "movl %ecx, 8(%r9) \n\t" | ||
4803 | - "movl %edx, 12(%r9) \n\t" | ||
4804 | - "movl %esi, 16(%r9) \n\t" | ||
4805 | - "movl %edi, 20(%r9) \n\t" | ||
4806 | - "movq %r12, %rax \n\t" | ||
4807 | - "movl %eax, 28(%r9) \n\t" | ||
4808 | - "popq %r9 \n\t" | ||
4809 | - "popq %r12 \n\t" | ||
4810 | - "popq %rdx \n\t" | ||
4811 | - "popq %rbx \n\t" | ||
4812 | - "popq %rax \n\t" | ||
4813 | - FRAME_END | ||
4814 | - "ret \n\t" | ||
4815 | - ".previous"); | ||
4816 | - | ||
4817 | -/* | ||
4818 | - * dmi_find_cru | ||
4819 | - * | ||
4820 | - * Routine Description: | ||
4821 | - * This function checks whether or not a SMBIOS/DMI record is | ||
4822 | - * the 64bit CRU info or not | ||
4823 | - */ | ||
4824 | -static void dmi_find_cru(const struct dmi_header *dm, void *dummy) | ||
4825 | -{ | ||
4826 | - struct smbios_cru64_info *smbios_cru64_ptr; | ||
4827 | - unsigned long cru_physical_address; | ||
4828 | - | ||
4829 | - if (dm->type == SMBIOS_CRU64_INFORMATION) { | ||
4830 | - smbios_cru64_ptr = (struct smbios_cru64_info *) dm; | ||
4831 | - if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) { | ||
4832 | - cru_physical_address = | ||
4833 | - smbios_cru64_ptr->physical_address + | ||
4834 | - smbios_cru64_ptr->double_offset; | ||
4835 | - cru_rom_addr = ioremap(cru_physical_address, | ||
4836 | - smbios_cru64_ptr->double_length); | ||
4837 | - set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, | ||
4838 | - smbios_cru64_ptr->double_length >> PAGE_SHIFT); | ||
4839 | - } | ||
4840 | - } | ||
4841 | -} | ||
4842 | - | ||
4843 | -static int detect_cru_service(void) | ||
4844 | -{ | ||
4845 | - cru_rom_addr = NULL; | ||
4846 | - | ||
4847 | - dmi_walk(dmi_find_cru, NULL); | ||
4848 | - | ||
4849 | - /* if cru_rom_addr has been set then we found a CRU service */ | ||
4850 | - return ((cru_rom_addr != NULL) ? 0 : -ENODEV); | ||
4851 | -} | ||
4852 | -/* ------------------------------------------------------------------------- */ | ||
4853 | -#endif /* CONFIG_X86_64 */ | ||
4854 | -#endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
4855 | |||
4856 | /* | ||
4857 | * Watchdog operations | ||
4858 | @@ -475,32 +103,22 @@ static int hpwdt_time_left(void) | ||
4859 | } | ||
4860 | |||
4861 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
4862 | +static int hpwdt_my_nmi(void) | ||
4863 | +{ | ||
4864 | + return ioread8(hpwdt_nmistat) & 0x6; | ||
4865 | +} | ||
4866 | + | ||
4867 | /* | ||
4868 | * NMI Handler | ||
4869 | */ | ||
4870 | static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) | ||
4871 | { | ||
4872 | - unsigned long rom_pl; | ||
4873 | - static int die_nmi_called; | ||
4874 | - | ||
4875 | - if (!hpwdt_nmi_decoding) | ||
4876 | + if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi()) | ||
4877 | return NMI_DONE; | ||
4878 | |||
4879 | - spin_lock_irqsave(&rom_lock, rom_pl); | ||
4880 | - if (!die_nmi_called && !is_icru && !is_uefi) | ||
4881 | - asminline_call(&cmn_regs, cru_rom_addr); | ||
4882 | - die_nmi_called = 1; | ||
4883 | - spin_unlock_irqrestore(&rom_lock, rom_pl); | ||
4884 | - | ||
4885 | if (allow_kdump) | ||
4886 | hpwdt_stop(); | ||
4887 | |||
4888 | - if (!is_icru && !is_uefi) { | ||
4889 | - if (cmn_regs.u1.ral == 0) { | ||
4890 | - nmi_panic(regs, "An NMI occurred, but unable to determine source.\n"); | ||
4891 | - return NMI_HANDLED; | ||
4892 | - } | ||
4893 | - } | ||
4894 | nmi_panic(regs, "An NMI occurred. Depending on your system the reason " | ||
4895 | "for the NMI is logged in any one of the following " | ||
4896 | "resources:\n" | ||
4897 | @@ -666,84 +284,11 @@ static struct miscdevice hpwdt_miscdev = { | ||
4898 | * Init & Exit | ||
4899 | */ | ||
4900 | |||
4901 | -#ifdef CONFIG_HPWDT_NMI_DECODING | ||
4902 | -#ifdef CONFIG_X86_LOCAL_APIC | ||
4903 | -static void hpwdt_check_nmi_decoding(struct pci_dev *dev) | ||
4904 | -{ | ||
4905 | - /* | ||
4906 | - * If nmi_watchdog is turned off then we can turn on | ||
4907 | - * our nmi decoding capability. | ||
4908 | - */ | ||
4909 | - hpwdt_nmi_decoding = 1; | ||
4910 | -} | ||
4911 | -#else | ||
4912 | -static void hpwdt_check_nmi_decoding(struct pci_dev *dev) | ||
4913 | -{ | ||
4914 | - dev_warn(&dev->dev, "NMI decoding is disabled. " | ||
4915 | - "Your kernel does not support a NMI Watchdog.\n"); | ||
4916 | -} | ||
4917 | -#endif /* CONFIG_X86_LOCAL_APIC */ | ||
4918 | - | ||
4919 | -/* | ||
4920 | - * dmi_find_icru | ||
4921 | - * | ||
4922 | - * Routine Description: | ||
4923 | - * This function checks whether or not we are on an iCRU-based server. | ||
4924 | - * This check is independent of architecture and needs to be made for | ||
4925 | - * any ProLiant system. | ||
4926 | - */ | ||
4927 | -static void dmi_find_icru(const struct dmi_header *dm, void *dummy) | ||
4928 | -{ | ||
4929 | - struct smbios_proliant_info *smbios_proliant_ptr; | ||
4930 | - | ||
4931 | - if (dm->type == SMBIOS_ICRU_INFORMATION) { | ||
4932 | - smbios_proliant_ptr = (struct smbios_proliant_info *) dm; | ||
4933 | - if (smbios_proliant_ptr->misc_features & 0x01) | ||
4934 | - is_icru = 1; | ||
4935 | - if (smbios_proliant_ptr->misc_features & 0x408) | ||
4936 | - is_uefi = 1; | ||
4937 | - } | ||
4938 | -} | ||
4939 | |||
4940 | static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | ||
4941 | { | ||
4942 | +#ifdef CONFIG_HPWDT_NMI_DECODING | ||
4943 | int retval; | ||
4944 | - | ||
4945 | - /* | ||
4946 | - * On typical CRU-based systems we need to map that service in | ||
4947 | - * the BIOS. For 32 bit Operating Systems we need to go through | ||
4948 | - * the 32 Bit BIOS Service Directory. For 64 bit Operating | ||
4949 | - * Systems we get that service through SMBIOS. | ||
4950 | - * | ||
4951 | - * On systems that support the new iCRU service all we need to | ||
4952 | - * do is call dmi_walk to get the supported flag value and skip | ||
4953 | - * the old cru detect code. | ||
4954 | - */ | ||
4955 | - dmi_walk(dmi_find_icru, NULL); | ||
4956 | - if (!is_icru && !is_uefi) { | ||
4957 | - | ||
4958 | - /* | ||
4959 | - * We need to map the ROM to get the CRU service. | ||
4960 | - * For 32 bit Operating Systems we need to go through the 32 Bit | ||
4961 | - * BIOS Service Directory | ||
4962 | - * For 64 bit Operating Systems we get that service through SMBIOS. | ||
4963 | - */ | ||
4964 | - retval = detect_cru_service(); | ||
4965 | - if (retval < 0) { | ||
4966 | - dev_warn(&dev->dev, | ||
4967 | - "Unable to detect the %d Bit CRU Service.\n", | ||
4968 | - HPWDT_ARCH); | ||
4969 | - return retval; | ||
4970 | - } | ||
4971 | - | ||
4972 | - /* | ||
4973 | - * We know this is the only CRU call we need to make so lets keep as | ||
4974 | - * few instructions as possible once the NMI comes in. | ||
4975 | - */ | ||
4976 | - cmn_regs.u1.rah = 0x0D; | ||
4977 | - cmn_regs.u1.ral = 0x02; | ||
4978 | - } | ||
4979 | - | ||
4980 | /* | ||
4981 | * Only one function can register for NMI_UNKNOWN | ||
4982 | */ | ||
4983 | @@ -771,44 +316,25 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | ||
4984 | dev_warn(&dev->dev, | ||
4985 | "Unable to register a die notifier (err=%d).\n", | ||
4986 | retval); | ||
4987 | - if (cru_rom_addr) | ||
4988 | - iounmap(cru_rom_addr); | ||
4989 | return retval; | ||
4990 | +#endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
4991 | + return 0; | ||
4992 | } | ||
4993 | |||
4994 | static void hpwdt_exit_nmi_decoding(void) | ||
4995 | { | ||
4996 | +#ifdef CONFIG_HPWDT_NMI_DECODING | ||
4997 | unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); | ||
4998 | unregister_nmi_handler(NMI_SERR, "hpwdt"); | ||
4999 | unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); | ||
5000 | - if (cru_rom_addr) | ||
5001 | - iounmap(cru_rom_addr); | ||
5002 | -} | ||
5003 | -#else /* !CONFIG_HPWDT_NMI_DECODING */ | ||
5004 | -static void hpwdt_check_nmi_decoding(struct pci_dev *dev) | ||
5005 | -{ | ||
5006 | -} | ||
5007 | - | ||
5008 | -static int hpwdt_init_nmi_decoding(struct pci_dev *dev) | ||
5009 | -{ | ||
5010 | - return 0; | ||
5011 | +#endif | ||
5012 | } | ||
5013 | |||
5014 | -static void hpwdt_exit_nmi_decoding(void) | ||
5015 | -{ | ||
5016 | -} | ||
5017 | -#endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
5018 | - | ||
5019 | static int hpwdt_init_one(struct pci_dev *dev, | ||
5020 | const struct pci_device_id *ent) | ||
5021 | { | ||
5022 | int retval; | ||
5023 | |||
5024 | - /* | ||
5025 | - * Check if we can do NMI decoding or not | ||
5026 | - */ | ||
5027 | - hpwdt_check_nmi_decoding(dev); | ||
5028 | - | ||
5029 | /* | ||
5030 | * First let's find out if we are on an iLO2+ server. We will | ||
5031 | * not run on a legacy ASM box. | ||
5032 | @@ -842,6 +368,7 @@ static int hpwdt_init_one(struct pci_dev *dev, | ||
5033 | retval = -ENOMEM; | ||
5034 | goto error_pci_iomap; | ||
5035 | } | ||
5036 | + hpwdt_nmistat = pci_mem_addr + 0x6e; | ||
5037 | hpwdt_timer_reg = pci_mem_addr + 0x70; | ||
5038 | hpwdt_timer_con = pci_mem_addr + 0x72; | ||
5039 | |||
5040 | @@ -912,6 +439,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | ||
5041 | #ifdef CONFIG_HPWDT_NMI_DECODING | ||
5042 | module_param(allow_kdump, int, 0); | ||
5043 | MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); | ||
5044 | -#endif /* !CONFIG_HPWDT_NMI_DECODING */ | ||
5045 | +#endif /* CONFIG_HPWDT_NMI_DECODING */ | ||
5046 | |||
5047 | module_pci_driver(hpwdt_driver); | ||
5048 | diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c | ||
5049 | index 8c10b0562e75..621c517b325c 100644 | ||
5050 | --- a/fs/nfs/direct.c | ||
5051 | +++ b/fs/nfs/direct.c | ||
5052 | @@ -86,10 +86,10 @@ struct nfs_direct_req { | ||
5053 | struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX]; | ||
5054 | int mirror_count; | ||
5055 | |||
5056 | + loff_t io_start; /* Start offset for I/O */ | ||
5057 | ssize_t count, /* bytes actually processed */ | ||
5058 | max_count, /* max expected count */ | ||
5059 | bytes_left, /* bytes left to be sent */ | ||
5060 | - io_start, /* start of IO */ | ||
5061 | error; /* any reported error */ | ||
5062 | struct completion completion; /* wait for i/o completion */ | ||
5063 | |||
5064 | diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c | ||
5065 | index eb098ccfefd5..b99200828d08 100644 | ||
5066 | --- a/fs/nfs/pnfs.c | ||
5067 | +++ b/fs/nfs/pnfs.c | ||
5068 | @@ -292,8 +292,11 @@ pnfs_detach_layout_hdr(struct pnfs_layout_hdr *lo) | ||
5069 | void | ||
5070 | pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo) | ||
5071 | { | ||
5072 | - struct inode *inode = lo->plh_inode; | ||
5073 | + struct inode *inode; | ||
5074 | |||
5075 | + if (!lo) | ||
5076 | + return; | ||
5077 | + inode = lo->plh_inode; | ||
5078 | pnfs_layoutreturn_before_put_layout_hdr(lo); | ||
5079 | |||
5080 | if (refcount_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) { | ||
5081 | @@ -1241,10 +1244,12 @@ bool pnfs_roc(struct inode *ino, | ||
5082 | spin_lock(&ino->i_lock); | ||
5083 | lo = nfsi->layout; | ||
5084 | if (!lo || !pnfs_layout_is_valid(lo) || | ||
5085 | - test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) | ||
5086 | + test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) { | ||
5087 | + lo = NULL; | ||
5088 | goto out_noroc; | ||
5089 | + } | ||
5090 | + pnfs_get_layout_hdr(lo); | ||
5091 | if (test_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) { | ||
5092 | - pnfs_get_layout_hdr(lo); | ||
5093 | spin_unlock(&ino->i_lock); | ||
5094 | wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN, | ||
5095 | TASK_UNINTERRUPTIBLE); | ||
5096 | @@ -1312,10 +1317,12 @@ bool pnfs_roc(struct inode *ino, | ||
5097 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld; | ||
5098 | if (ld->prepare_layoutreturn) | ||
5099 | ld->prepare_layoutreturn(args); | ||
5100 | + pnfs_put_layout_hdr(lo); | ||
5101 | return true; | ||
5102 | } | ||
5103 | if (layoutreturn) | ||
5104 | pnfs_send_layoutreturn(lo, &stateid, iomode, true); | ||
5105 | + pnfs_put_layout_hdr(lo); | ||
5106 | return false; | ||
5107 | } | ||
5108 | |||
5109 | diff --git a/fs/nfs/write.c b/fs/nfs/write.c | ||
5110 | index cf61108f8f8d..8607ad8626f6 100644 | ||
5111 | --- a/fs/nfs/write.c | ||
5112 | +++ b/fs/nfs/write.c | ||
5113 | @@ -1878,40 +1878,43 @@ int nfs_generic_commit_list(struct inode *inode, struct list_head *head, | ||
5114 | return status; | ||
5115 | } | ||
5116 | |||
5117 | -int nfs_commit_inode(struct inode *inode, int how) | ||
5118 | +static int __nfs_commit_inode(struct inode *inode, int how, | ||
5119 | + struct writeback_control *wbc) | ||
5120 | { | ||
5121 | LIST_HEAD(head); | ||
5122 | struct nfs_commit_info cinfo; | ||
5123 | int may_wait = how & FLUSH_SYNC; | ||
5124 | - int error = 0; | ||
5125 | - int res; | ||
5126 | + int ret, nscan; | ||
5127 | |||
5128 | nfs_init_cinfo_from_inode(&cinfo, inode); | ||
5129 | nfs_commit_begin(cinfo.mds); | ||
5130 | - res = nfs_scan_commit(inode, &head, &cinfo); | ||
5131 | - if (res) | ||
5132 | - error = nfs_generic_commit_list(inode, &head, how, &cinfo); | ||
5133 | + for (;;) { | ||
5134 | + ret = nscan = nfs_scan_commit(inode, &head, &cinfo); | ||
5135 | + if (ret <= 0) | ||
5136 | + break; | ||
5137 | + ret = nfs_generic_commit_list(inode, &head, how, &cinfo); | ||
5138 | + if (ret < 0) | ||
5139 | + break; | ||
5140 | + ret = 0; | ||
5141 | + if (wbc && wbc->sync_mode == WB_SYNC_NONE) { | ||
5142 | + if (nscan < wbc->nr_to_write) | ||
5143 | + wbc->nr_to_write -= nscan; | ||
5144 | + else | ||
5145 | + wbc->nr_to_write = 0; | ||
5146 | + } | ||
5147 | + if (nscan < INT_MAX) | ||
5148 | + break; | ||
5149 | + cond_resched(); | ||
5150 | + } | ||
5151 | nfs_commit_end(cinfo.mds); | ||
5152 | - if (res == 0) | ||
5153 | - return res; | ||
5154 | - if (error < 0) | ||
5155 | - goto out_error; | ||
5156 | - if (!may_wait) | ||
5157 | - goto out_mark_dirty; | ||
5158 | - error = wait_on_commit(cinfo.mds); | ||
5159 | - if (error < 0) | ||
5160 | - return error; | ||
5161 | - return res; | ||
5162 | -out_error: | ||
5163 | - res = error; | ||
5164 | - /* Note: If we exit without ensuring that the commit is complete, | ||
5165 | - * we must mark the inode as dirty. Otherwise, future calls to | ||
5166 | - * sync_inode() with the WB_SYNC_ALL flag set will fail to ensure | ||
5167 | - * that the data is on the disk. | ||
5168 | - */ | ||
5169 | -out_mark_dirty: | ||
5170 | - __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
5171 | - return res; | ||
5172 | + if (ret || !may_wait) | ||
5173 | + return ret; | ||
5174 | + return wait_on_commit(cinfo.mds); | ||
5175 | +} | ||
5176 | + | ||
5177 | +int nfs_commit_inode(struct inode *inode, int how) | ||
5178 | +{ | ||
5179 | + return __nfs_commit_inode(inode, how, NULL); | ||
5180 | } | ||
5181 | EXPORT_SYMBOL_GPL(nfs_commit_inode); | ||
5182 | |||
5183 | @@ -1921,11 +1924,11 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
5184 | int flags = FLUSH_SYNC; | ||
5185 | int ret = 0; | ||
5186 | |||
5187 | - /* no commits means nothing needs to be done */ | ||
5188 | - if (!atomic_long_read(&nfsi->commit_info.ncommit)) | ||
5189 | - return ret; | ||
5190 | - | ||
5191 | if (wbc->sync_mode == WB_SYNC_NONE) { | ||
5192 | + /* no commits means nothing needs to be done */ | ||
5193 | + if (!atomic_long_read(&nfsi->commit_info.ncommit)) | ||
5194 | + goto check_requests_outstanding; | ||
5195 | + | ||
5196 | /* Don't commit yet if this is a non-blocking flush and there | ||
5197 | * are a lot of outstanding writes for this mapping. | ||
5198 | */ | ||
5199 | @@ -1936,16 +1939,16 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
5200 | flags = 0; | ||
5201 | } | ||
5202 | |||
5203 | - ret = nfs_commit_inode(inode, flags); | ||
5204 | - if (ret >= 0) { | ||
5205 | - if (wbc->sync_mode == WB_SYNC_NONE) { | ||
5206 | - if (ret < wbc->nr_to_write) | ||
5207 | - wbc->nr_to_write -= ret; | ||
5208 | - else | ||
5209 | - wbc->nr_to_write = 0; | ||
5210 | - } | ||
5211 | - return 0; | ||
5212 | - } | ||
5213 | + ret = __nfs_commit_inode(inode, flags, wbc); | ||
5214 | + if (!ret) { | ||
5215 | + if (flags & FLUSH_SYNC) | ||
5216 | + return 0; | ||
5217 | + } else if (atomic_long_read(&nfsi->commit_info.ncommit)) | ||
5218 | + goto out_mark_dirty; | ||
5219 | + | ||
5220 | +check_requests_outstanding: | ||
5221 | + if (!atomic_read(&nfsi->commit_info.rpcs_out)) | ||
5222 | + return ret; | ||
5223 | out_mark_dirty: | ||
5224 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
5225 | return ret; | ||
5226 | diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c | ||
5227 | index beb945e1963c..ef3e7ea76296 100644 | ||
5228 | --- a/fs/overlayfs/namei.c | ||
5229 | +++ b/fs/overlayfs/namei.c | ||
5230 | @@ -678,9 +678,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, | ||
5231 | stack[ctr].layer = lower.layer; | ||
5232 | ctr++; | ||
5233 | |||
5234 | - if (d.stop) | ||
5235 | - break; | ||
5236 | - | ||
5237 | /* | ||
5238 | * Following redirects can have security consequences: it's like | ||
5239 | * a symlink into the lower layer without the permission checks. | ||
5240 | @@ -697,6 +694,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, | ||
5241 | goto out_put; | ||
5242 | } | ||
5243 | |||
5244 | + if (d.stop) | ||
5245 | + break; | ||
5246 | + | ||
5247 | if (d.redirect && d.redirect[0] == '/' && poe != roe) { | ||
5248 | poe = roe; | ||
5249 | |||
5250 | diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h | ||
5251 | index 76e237bd989b..6914633037a5 100644 | ||
5252 | --- a/include/drm/drm_crtc_helper.h | ||
5253 | +++ b/include/drm/drm_crtc_helper.h | ||
5254 | @@ -77,5 +77,6 @@ void drm_kms_helper_hotplug_event(struct drm_device *dev); | ||
5255 | |||
5256 | void drm_kms_helper_poll_disable(struct drm_device *dev); | ||
5257 | void drm_kms_helper_poll_enable(struct drm_device *dev); | ||
5258 | +bool drm_kms_helper_is_poll_worker(void); | ||
5259 | |||
5260 | #endif | ||
5261 | diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h | ||
5262 | index 412e83a4d3db..29c839ed656b 100644 | ||
5263 | --- a/include/drm/drm_drv.h | ||
5264 | +++ b/include/drm/drm_drv.h | ||
5265 | @@ -55,6 +55,7 @@ struct drm_mode_create_dumb; | ||
5266 | #define DRIVER_ATOMIC 0x10000 | ||
5267 | #define DRIVER_KMS_LEGACY_CONTEXT 0x20000 | ||
5268 | #define DRIVER_SYNCOBJ 0x40000 | ||
5269 | +#define DRIVER_PREFER_XBGR_30BPP 0x80000 | ||
5270 | |||
5271 | /** | ||
5272 | * struct drm_driver - DRM driver structure | ||
5273 | diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h | ||
5274 | index 3b609edffa8f..be3aef6839f6 100644 | ||
5275 | --- a/include/linux/compiler-clang.h | ||
5276 | +++ b/include/linux/compiler-clang.h | ||
5277 | @@ -19,3 +19,8 @@ | ||
5278 | |||
5279 | #define randomized_struct_fields_start struct { | ||
5280 | #define randomized_struct_fields_end }; | ||
5281 | + | ||
5282 | +/* Clang doesn't have a way to turn it off per-function, yet. */ | ||
5283 | +#ifdef __noretpoline | ||
5284 | +#undef __noretpoline | ||
5285 | +#endif | ||
5286 | diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h | ||
5287 | index 73bc63e0a1c4..673fbf904fe5 100644 | ||
5288 | --- a/include/linux/compiler-gcc.h | ||
5289 | +++ b/include/linux/compiler-gcc.h | ||
5290 | @@ -93,6 +93,10 @@ | ||
5291 | #define __weak __attribute__((weak)) | ||
5292 | #define __alias(symbol) __attribute__((alias(#symbol))) | ||
5293 | |||
5294 | +#ifdef RETPOLINE | ||
5295 | +#define __noretpoline __attribute__((indirect_branch("keep"))) | ||
5296 | +#endif | ||
5297 | + | ||
5298 | /* | ||
5299 | * it doesn't make sense on ARM (currently the only user of __naked) | ||
5300 | * to trace naked functions because then mcount is called without | ||
5301 | diff --git a/include/linux/init.h b/include/linux/init.h | ||
5302 | index 506a98151131..bc27cf03c41e 100644 | ||
5303 | --- a/include/linux/init.h | ||
5304 | +++ b/include/linux/init.h | ||
5305 | @@ -6,10 +6,10 @@ | ||
5306 | #include <linux/types.h> | ||
5307 | |||
5308 | /* Built-in __init functions needn't be compiled with retpoline */ | ||
5309 | -#if defined(RETPOLINE) && !defined(MODULE) | ||
5310 | -#define __noretpoline __attribute__((indirect_branch("keep"))) | ||
5311 | +#if defined(__noretpoline) && !defined(MODULE) | ||
5312 | +#define __noinitretpoline __noretpoline | ||
5313 | #else | ||
5314 | -#define __noretpoline | ||
5315 | +#define __noinitretpoline | ||
5316 | #endif | ||
5317 | |||
5318 | /* These macros are used to mark some functions or | ||
5319 | @@ -47,7 +47,7 @@ | ||
5320 | |||
5321 | /* These are for everybody (although not all archs will actually | ||
5322 | discard it in modules) */ | ||
5323 | -#define __init __section(.init.text) __cold __latent_entropy __noretpoline | ||
5324 | +#define __init __section(.init.text) __cold __latent_entropy __noinitretpoline | ||
5325 | #define __initdata __section(.init.data) | ||
5326 | #define __initconst __section(.init.rodata) | ||
5327 | #define __exitdata __section(.exit.data) | ||
5328 | diff --git a/include/linux/nospec.h b/include/linux/nospec.h | ||
5329 | index 132e3f5a2e0d..e791ebc65c9c 100644 | ||
5330 | --- a/include/linux/nospec.h | ||
5331 | +++ b/include/linux/nospec.h | ||
5332 | @@ -5,6 +5,7 @@ | ||
5333 | |||
5334 | #ifndef _LINUX_NOSPEC_H | ||
5335 | #define _LINUX_NOSPEC_H | ||
5336 | +#include <asm/barrier.h> | ||
5337 | |||
5338 | /** | ||
5339 | * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise | ||
5340 | @@ -29,26 +30,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | ||
5341 | } | ||
5342 | #endif | ||
5343 | |||
5344 | -/* | ||
5345 | - * Warn developers about inappropriate array_index_nospec() usage. | ||
5346 | - * | ||
5347 | - * Even if the CPU speculates past the WARN_ONCE branch, the | ||
5348 | - * sign bit of @index is taken into account when generating the | ||
5349 | - * mask. | ||
5350 | - * | ||
5351 | - * This warning is compiled out when the compiler can infer that | ||
5352 | - * @index and @size are less than LONG_MAX. | ||
5353 | - */ | ||
5354 | -#define array_index_mask_nospec_check(index, size) \ | ||
5355 | -({ \ | ||
5356 | - if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, \ | ||
5357 | - "array_index_nospec() limited to range of [0, LONG_MAX]\n")) \ | ||
5358 | - _mask = 0; \ | ||
5359 | - else \ | ||
5360 | - _mask = array_index_mask_nospec(index, size); \ | ||
5361 | - _mask; \ | ||
5362 | -}) | ||
5363 | - | ||
5364 | /* | ||
5365 | * array_index_nospec - sanitize an array index after a bounds check | ||
5366 | * | ||
5367 | @@ -67,7 +48,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | ||
5368 | ({ \ | ||
5369 | typeof(index) _i = (index); \ | ||
5370 | typeof(size) _s = (size); \ | ||
5371 | - unsigned long _mask = array_index_mask_nospec_check(_i, _s); \ | ||
5372 | + unsigned long _mask = array_index_mask_nospec(_i, _s); \ | ||
5373 | \ | ||
5374 | BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ | ||
5375 | BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ | ||
5376 | diff --git a/include/linux/tpm.h b/include/linux/tpm.h | ||
5377 | index 5a090f5ab335..881312d85574 100644 | ||
5378 | --- a/include/linux/tpm.h | ||
5379 | +++ b/include/linux/tpm.h | ||
5380 | @@ -50,6 +50,7 @@ struct tpm_class_ops { | ||
5381 | unsigned long *timeout_cap); | ||
5382 | int (*request_locality)(struct tpm_chip *chip, int loc); | ||
5383 | void (*relinquish_locality)(struct tpm_chip *chip, int loc); | ||
5384 | + void (*clk_enable)(struct tpm_chip *chip, bool value); | ||
5385 | }; | ||
5386 | |||
5387 | #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) | ||
5388 | diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h | ||
5389 | index 4a54ef96aff5..bc0cda180c8b 100644 | ||
5390 | --- a/include/linux/workqueue.h | ||
5391 | +++ b/include/linux/workqueue.h | ||
5392 | @@ -465,6 +465,7 @@ extern bool cancel_delayed_work_sync(struct delayed_work *dwork); | ||
5393 | |||
5394 | extern void workqueue_set_max_active(struct workqueue_struct *wq, | ||
5395 | int max_active); | ||
5396 | +extern struct work_struct *current_work(void); | ||
5397 | extern bool current_is_workqueue_rescuer(void); | ||
5398 | extern bool workqueue_congested(int cpu, struct workqueue_struct *wq); | ||
5399 | extern unsigned int work_busy(struct work_struct *work); | ||
5400 | diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h | ||
5401 | index 7fb57e905526..7bc752fc98de 100644 | ||
5402 | --- a/include/scsi/scsi_cmnd.h | ||
5403 | +++ b/include/scsi/scsi_cmnd.h | ||
5404 | @@ -69,6 +69,9 @@ struct scsi_cmnd { | ||
5405 | struct list_head list; /* scsi_cmnd participates in queue lists */ | ||
5406 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ | ||
5407 | struct delayed_work abort_work; | ||
5408 | + | ||
5409 | + struct rcu_head rcu; | ||
5410 | + | ||
5411 | int eh_eflags; /* Used by error handlr */ | ||
5412 | |||
5413 | /* | ||
5414 | diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h | ||
5415 | index 1a1df0d21ee3..a8b7bf879ced 100644 | ||
5416 | --- a/include/scsi/scsi_host.h | ||
5417 | +++ b/include/scsi/scsi_host.h | ||
5418 | @@ -571,8 +571,6 @@ struct Scsi_Host { | ||
5419 | struct blk_mq_tag_set tag_set; | ||
5420 | }; | ||
5421 | |||
5422 | - struct rcu_head rcu; | ||
5423 | - | ||
5424 | atomic_t host_busy; /* commands actually active on low-level */ | ||
5425 | atomic_t host_blocked; | ||
5426 | |||
5427 | diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c | ||
5428 | index ce5b669003b2..ea8212118404 100644 | ||
5429 | --- a/kernel/bpf/cpumap.c | ||
5430 | +++ b/kernel/bpf/cpumap.c | ||
5431 | @@ -339,7 +339,7 @@ static int cpu_map_kthread_run(void *data) | ||
5432 | |||
5433 | struct bpf_cpu_map_entry *__cpu_map_entry_alloc(u32 qsize, u32 cpu, int map_id) | ||
5434 | { | ||
5435 | - gfp_t gfp = GFP_ATOMIC|__GFP_NOWARN; | ||
5436 | + gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; | ||
5437 | struct bpf_cpu_map_entry *rcpu; | ||
5438 | int numa, err; | ||
5439 | |||
5440 | diff --git a/kernel/panic.c b/kernel/panic.c | ||
5441 | index 2cfef408fec9..4b794f1d8561 100644 | ||
5442 | --- a/kernel/panic.c | ||
5443 | +++ b/kernel/panic.c | ||
5444 | @@ -640,7 +640,7 @@ device_initcall(register_warn_debugfs); | ||
5445 | */ | ||
5446 | __visible void __stack_chk_fail(void) | ||
5447 | { | ||
5448 | - panic("stack-protector: Kernel stack is corrupted in: %p\n", | ||
5449 | + panic("stack-protector: Kernel stack is corrupted in: %pB\n", | ||
5450 | __builtin_return_address(0)); | ||
5451 | } | ||
5452 | EXPORT_SYMBOL(__stack_chk_fail); | ||
5453 | diff --git a/kernel/workqueue.c b/kernel/workqueue.c | ||
5454 | index f699122dab32..34f1e1a2ec12 100644 | ||
5455 | --- a/kernel/workqueue.c | ||
5456 | +++ b/kernel/workqueue.c | ||
5457 | @@ -4168,6 +4168,22 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) | ||
5458 | } | ||
5459 | EXPORT_SYMBOL_GPL(workqueue_set_max_active); | ||
5460 | |||
5461 | +/** | ||
5462 | + * current_work - retrieve %current task's work struct | ||
5463 | + * | ||
5464 | + * Determine if %current task is a workqueue worker and what it's working on. | ||
5465 | + * Useful to find out the context that the %current task is running in. | ||
5466 | + * | ||
5467 | + * Return: work struct if %current task is a workqueue worker, %NULL otherwise. | ||
5468 | + */ | ||
5469 | +struct work_struct *current_work(void) | ||
5470 | +{ | ||
5471 | + struct worker *worker = current_wq_worker(); | ||
5472 | + | ||
5473 | + return worker ? worker->current_work : NULL; | ||
5474 | +} | ||
5475 | +EXPORT_SYMBOL(current_work); | ||
5476 | + | ||
5477 | /** | ||
5478 | * current_is_workqueue_rescuer - is %current workqueue rescuer? | ||
5479 | * | ||
5480 | diff --git a/lib/bug.c b/lib/bug.c | ||
5481 | index c1b0fad31b10..1077366f496b 100644 | ||
5482 | --- a/lib/bug.c | ||
5483 | +++ b/lib/bug.c | ||
5484 | @@ -150,6 +150,8 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) | ||
5485 | return BUG_TRAP_TYPE_NONE; | ||
5486 | |||
5487 | bug = find_bug(bugaddr); | ||
5488 | + if (!bug) | ||
5489 | + return BUG_TRAP_TYPE_NONE; | ||
5490 | |||
5491 | file = NULL; | ||
5492 | line = 0; | ||
5493 | @@ -191,7 +193,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) | ||
5494 | if (file) | ||
5495 | pr_crit("kernel BUG at %s:%u!\n", file, line); | ||
5496 | else | ||
5497 | - pr_crit("Kernel BUG at %p [verbose debug info unavailable]\n", | ||
5498 | + pr_crit("Kernel BUG at %pB [verbose debug info unavailable]\n", | ||
5499 | (void *)bugaddr); | ||
5500 | |||
5501 | return BUG_TRAP_TYPE_BUG; | ||
5502 | diff --git a/mm/memblock.c b/mm/memblock.c | ||
5503 | index 46aacdfa4f4d..d25b5a456cca 100644 | ||
5504 | --- a/mm/memblock.c | ||
5505 | +++ b/mm/memblock.c | ||
5506 | @@ -1107,7 +1107,7 @@ unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn, | ||
5507 | struct memblock_type *type = &memblock.memory; | ||
5508 | unsigned int right = type->cnt; | ||
5509 | unsigned int mid, left = 0; | ||
5510 | - phys_addr_t addr = PFN_PHYS(pfn + 1); | ||
5511 | + phys_addr_t addr = PFN_PHYS(++pfn); | ||
5512 | |||
5513 | do { | ||
5514 | mid = (right + left) / 2; | ||
5515 | @@ -1118,15 +1118,15 @@ unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn, | ||
5516 | type->regions[mid].size)) | ||
5517 | left = mid + 1; | ||
5518 | else { | ||
5519 | - /* addr is within the region, so pfn + 1 is valid */ | ||
5520 | - return min(pfn + 1, max_pfn); | ||
5521 | + /* addr is within the region, so pfn is valid */ | ||
5522 | + return pfn; | ||
5523 | } | ||
5524 | } while (left < right); | ||
5525 | |||
5526 | if (right == type->cnt) | ||
5527 | - return max_pfn; | ||
5528 | + return -1UL; | ||
5529 | else | ||
5530 | - return min(PHYS_PFN(type->regions[right].base), max_pfn); | ||
5531 | + return PHYS_PFN(type->regions[right].base); | ||
5532 | } | ||
5533 | |||
5534 | /** | ||
5535 | diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c | ||
5536 | index 279527f8b1fe..59baaecd3e54 100644 | ||
5537 | --- a/net/bridge/netfilter/ebt_among.c | ||
5538 | +++ b/net/bridge/netfilter/ebt_among.c | ||
5539 | @@ -172,18 +172,35 @@ ebt_among_mt(const struct sk_buff *skb, struct xt_action_param *par) | ||
5540 | return true; | ||
5541 | } | ||
5542 | |||
5543 | +static bool poolsize_invalid(const struct ebt_mac_wormhash *w) | ||
5544 | +{ | ||
5545 | + return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); | ||
5546 | +} | ||
5547 | + | ||
5548 | static int ebt_among_mt_check(const struct xt_mtchk_param *par) | ||
5549 | { | ||
5550 | const struct ebt_among_info *info = par->matchinfo; | ||
5551 | const struct ebt_entry_match *em = | ||
5552 | container_of(par->matchinfo, const struct ebt_entry_match, data); | ||
5553 | - int expected_length = sizeof(struct ebt_among_info); | ||
5554 | + unsigned int expected_length = sizeof(struct ebt_among_info); | ||
5555 | const struct ebt_mac_wormhash *wh_dst, *wh_src; | ||
5556 | int err; | ||
5557 | |||
5558 | + if (expected_length > em->match_size) | ||
5559 | + return -EINVAL; | ||
5560 | + | ||
5561 | wh_dst = ebt_among_wh_dst(info); | ||
5562 | - wh_src = ebt_among_wh_src(info); | ||
5563 | + if (poolsize_invalid(wh_dst)) | ||
5564 | + return -EINVAL; | ||
5565 | + | ||
5566 | expected_length += ebt_mac_wormhash_size(wh_dst); | ||
5567 | + if (expected_length > em->match_size) | ||
5568 | + return -EINVAL; | ||
5569 | + | ||
5570 | + wh_src = ebt_among_wh_src(info); | ||
5571 | + if (poolsize_invalid(wh_src)) | ||
5572 | + return -EINVAL; | ||
5573 | + | ||
5574 | expected_length += ebt_mac_wormhash_size(wh_src); | ||
5575 | |||
5576 | if (em->match_size != EBT_ALIGN(expected_length)) { | ||
5577 | diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c | ||
5578 | index 37817d25b63d..895ba1cd9750 100644 | ||
5579 | --- a/net/bridge/netfilter/ebtables.c | ||
5580 | +++ b/net/bridge/netfilter/ebtables.c | ||
5581 | @@ -2053,7 +2053,9 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, | ||
5582 | if (match_kern) | ||
5583 | match_kern->match_size = ret; | ||
5584 | |||
5585 | - WARN_ON(type == EBT_COMPAT_TARGET && size_left); | ||
5586 | + if (WARN_ON(type == EBT_COMPAT_TARGET && size_left)) | ||
5587 | + return -EINVAL; | ||
5588 | + | ||
5589 | match32 = (struct compat_ebt_entry_mwt *) buf; | ||
5590 | } | ||
5591 | |||
5592 | @@ -2109,6 +2111,15 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, | ||
5593 | * | ||
5594 | * offsets are relative to beginning of struct ebt_entry (i.e., 0). | ||
5595 | */ | ||
5596 | + for (i = 0; i < 4 ; ++i) { | ||
5597 | + if (offsets[i] >= *total) | ||
5598 | + return -EINVAL; | ||
5599 | + if (i == 0) | ||
5600 | + continue; | ||
5601 | + if (offsets[i-1] > offsets[i]) | ||
5602 | + return -EINVAL; | ||
5603 | + } | ||
5604 | + | ||
5605 | for (i = 0, j = 1 ; j < 4 ; j++, i++) { | ||
5606 | struct compat_ebt_entry_mwt *match32; | ||
5607 | unsigned int size; | ||
5608 | diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c | ||
5609 | index 0c3c944a7b72..8e5185ad6310 100644 | ||
5610 | --- a/net/ipv4/netfilter/arp_tables.c | ||
5611 | +++ b/net/ipv4/netfilter/arp_tables.c | ||
5612 | @@ -257,6 +257,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, | ||
5613 | } | ||
5614 | if (table_base + v | ||
5615 | != arpt_next_entry(e)) { | ||
5616 | + if (unlikely(stackidx >= private->stacksize)) { | ||
5617 | + verdict = NF_DROP; | ||
5618 | + break; | ||
5619 | + } | ||
5620 | jumpstack[stackidx++] = e; | ||
5621 | } | ||
5622 | |||
5623 | diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c | ||
5624 | index 2e0d339028bb..a74a81624983 100644 | ||
5625 | --- a/net/ipv4/netfilter/ip_tables.c | ||
5626 | +++ b/net/ipv4/netfilter/ip_tables.c | ||
5627 | @@ -335,8 +335,13 @@ ipt_do_table(struct sk_buff *skb, | ||
5628 | continue; | ||
5629 | } | ||
5630 | if (table_base + v != ipt_next_entry(e) && | ||
5631 | - !(e->ip.flags & IPT_F_GOTO)) | ||
5632 | + !(e->ip.flags & IPT_F_GOTO)) { | ||
5633 | + if (unlikely(stackidx >= private->stacksize)) { | ||
5634 | + verdict = NF_DROP; | ||
5635 | + break; | ||
5636 | + } | ||
5637 | jumpstack[stackidx++] = e; | ||
5638 | + } | ||
5639 | |||
5640 | e = get_entry(table_base, v); | ||
5641 | continue; | ||
5642 | diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c | ||
5643 | index 1e4a7209a3d2..77a01c484807 100644 | ||
5644 | --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c | ||
5645 | +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | ||
5646 | @@ -107,12 +107,6 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c) | ||
5647 | |||
5648 | local_bh_disable(); | ||
5649 | if (refcount_dec_and_lock(&c->entries, &cn->lock)) { | ||
5650 | - list_del_rcu(&c->list); | ||
5651 | - spin_unlock(&cn->lock); | ||
5652 | - local_bh_enable(); | ||
5653 | - | ||
5654 | - unregister_netdevice_notifier(&c->notifier); | ||
5655 | - | ||
5656 | /* In case anyone still accesses the file, the open/close | ||
5657 | * functions are also incrementing the refcount on their own, | ||
5658 | * so it's safe to remove the entry even if it's in use. */ | ||
5659 | @@ -120,6 +114,12 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c) | ||
5660 | if (cn->procdir) | ||
5661 | proc_remove(c->pde); | ||
5662 | #endif | ||
5663 | + list_del_rcu(&c->list); | ||
5664 | + spin_unlock(&cn->lock); | ||
5665 | + local_bh_enable(); | ||
5666 | + | ||
5667 | + unregister_netdevice_notifier(&c->notifier); | ||
5668 | + | ||
5669 | return; | ||
5670 | } | ||
5671 | local_bh_enable(); | ||
5672 | diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c | ||
5673 | index 39970e212ad5..9bf260459f83 100644 | ||
5674 | --- a/net/ipv6/netfilter.c | ||
5675 | +++ b/net/ipv6/netfilter.c | ||
5676 | @@ -21,18 +21,19 @@ | ||
5677 | int ip6_route_me_harder(struct net *net, struct sk_buff *skb) | ||
5678 | { | ||
5679 | const struct ipv6hdr *iph = ipv6_hdr(skb); | ||
5680 | + struct sock *sk = sk_to_full_sk(skb->sk); | ||
5681 | unsigned int hh_len; | ||
5682 | struct dst_entry *dst; | ||
5683 | struct flowi6 fl6 = { | ||
5684 | - .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, | ||
5685 | + .flowi6_oif = sk ? sk->sk_bound_dev_if : 0, | ||
5686 | .flowi6_mark = skb->mark, | ||
5687 | - .flowi6_uid = sock_net_uid(net, skb->sk), | ||
5688 | + .flowi6_uid = sock_net_uid(net, sk), | ||
5689 | .daddr = iph->daddr, | ||
5690 | .saddr = iph->saddr, | ||
5691 | }; | ||
5692 | int err; | ||
5693 | |||
5694 | - dst = ip6_route_output(net, skb->sk, &fl6); | ||
5695 | + dst = ip6_route_output(net, sk, &fl6); | ||
5696 | err = dst->error; | ||
5697 | if (err) { | ||
5698 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | ||
5699 | @@ -50,7 +51,7 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb) | ||
5700 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && | ||
5701 | xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) { | ||
5702 | skb_dst_set(skb, NULL); | ||
5703 | - dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0); | ||
5704 | + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0); | ||
5705 | if (IS_ERR(dst)) | ||
5706 | return PTR_ERR(dst); | ||
5707 | skb_dst_set(skb, dst); | ||
5708 | diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c | ||
5709 | index 1d7ae9366335..51f3bc632c7c 100644 | ||
5710 | --- a/net/ipv6/netfilter/ip6_tables.c | ||
5711 | +++ b/net/ipv6/netfilter/ip6_tables.c | ||
5712 | @@ -357,6 +357,10 @@ ip6t_do_table(struct sk_buff *skb, | ||
5713 | } | ||
5714 | if (table_base + v != ip6t_next_entry(e) && | ||
5715 | !(e->ipv6.flags & IP6T_F_GOTO)) { | ||
5716 | + if (unlikely(stackidx >= private->stacksize)) { | ||
5717 | + verdict = NF_DROP; | ||
5718 | + break; | ||
5719 | + } | ||
5720 | jumpstack[stackidx++] = e; | ||
5721 | } | ||
5722 | |||
5723 | diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | ||
5724 | index 1d2fb9267d6f..6a203fa82dbd 100644 | ||
5725 | --- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | ||
5726 | +++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | ||
5727 | @@ -99,6 +99,10 @@ static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb, | ||
5728 | !l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff, | ||
5729 | target, maniptype)) | ||
5730 | return false; | ||
5731 | + | ||
5732 | + /* must reload, offset might have changed */ | ||
5733 | + ipv6h = (void *)skb->data + iphdroff; | ||
5734 | + | ||
5735 | manip_addr: | ||
5736 | if (maniptype == NF_NAT_MANIP_SRC) | ||
5737 | ipv6h->saddr = target->src.u3.in6; | ||
5738 | diff --git a/net/netfilter/nf_nat_proto_common.c b/net/netfilter/nf_nat_proto_common.c | ||
5739 | index fbce552a796e..7d7466dbf663 100644 | ||
5740 | --- a/net/netfilter/nf_nat_proto_common.c | ||
5741 | +++ b/net/netfilter/nf_nat_proto_common.c | ||
5742 | @@ -41,7 +41,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, | ||
5743 | const struct nf_conn *ct, | ||
5744 | u16 *rover) | ||
5745 | { | ||
5746 | - unsigned int range_size, min, i; | ||
5747 | + unsigned int range_size, min, max, i; | ||
5748 | __be16 *portptr; | ||
5749 | u_int16_t off; | ||
5750 | |||
5751 | @@ -71,7 +71,10 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, | ||
5752 | } | ||
5753 | } else { | ||
5754 | min = ntohs(range->min_proto.all); | ||
5755 | - range_size = ntohs(range->max_proto.all) - min + 1; | ||
5756 | + max = ntohs(range->max_proto.all); | ||
5757 | + if (unlikely(max < min)) | ||
5758 | + swap(max, min); | ||
5759 | + range_size = max - min + 1; | ||
5760 | } | ||
5761 | |||
5762 | if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) { | ||
5763 | diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c | ||
5764 | index ee3421ad108d..18b7412ab99a 100644 | ||
5765 | --- a/net/netfilter/xt_IDLETIMER.c | ||
5766 | +++ b/net/netfilter/xt_IDLETIMER.c | ||
5767 | @@ -146,11 +146,11 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) | ||
5768 | timer_setup(&info->timer->timer, idletimer_tg_expired, 0); | ||
5769 | info->timer->refcnt = 1; | ||
5770 | |||
5771 | + INIT_WORK(&info->timer->work, idletimer_tg_work); | ||
5772 | + | ||
5773 | mod_timer(&info->timer->timer, | ||
5774 | msecs_to_jiffies(info->timeout * 1000) + jiffies); | ||
5775 | |||
5776 | - INIT_WORK(&info->timer->work, idletimer_tg_work); | ||
5777 | - | ||
5778 | return 0; | ||
5779 | |||
5780 | out_free_attr: | ||
5781 | @@ -191,7 +191,10 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) | ||
5782 | pr_debug("timeout value is zero\n"); | ||
5783 | return -EINVAL; | ||
5784 | } | ||
5785 | - | ||
5786 | + if (info->timeout >= INT_MAX / 1000) { | ||
5787 | + pr_debug("timeout value is too big\n"); | ||
5788 | + return -EINVAL; | ||
5789 | + } | ||
5790 | if (info->label[0] == '\0' || | ||
5791 | strnlen(info->label, | ||
5792 | MAX_IDLETIMER_LABEL_SIZE) == MAX_IDLETIMER_LABEL_SIZE) { | ||
5793 | diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c | ||
5794 | index 0971634e5444..18d3af5e1098 100644 | ||
5795 | --- a/net/netfilter/xt_LED.c | ||
5796 | +++ b/net/netfilter/xt_LED.c | ||
5797 | @@ -142,9 +142,10 @@ static int led_tg_check(const struct xt_tgchk_param *par) | ||
5798 | goto exit_alloc; | ||
5799 | } | ||
5800 | |||
5801 | - /* See if we need to set up a timer */ | ||
5802 | - if (ledinfo->delay > 0) | ||
5803 | - timer_setup(&ledinternal->timer, led_timeout_callback, 0); | ||
5804 | + /* Since the letinternal timer can be shared between multiple targets, | ||
5805 | + * always set it up, even if the current target does not need it | ||
5806 | + */ | ||
5807 | + timer_setup(&ledinternal->timer, led_timeout_callback, 0); | ||
5808 | |||
5809 | list_add_tail(&ledinternal->list, &xt_led_triggers); | ||
5810 | |||
5811 | @@ -181,8 +182,7 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par) | ||
5812 | |||
5813 | list_del(&ledinternal->list); | ||
5814 | |||
5815 | - if (ledinfo->delay > 0) | ||
5816 | - del_timer_sync(&ledinternal->timer); | ||
5817 | + del_timer_sync(&ledinternal->timer); | ||
5818 | |||
5819 | led_trigger_unregister(&ledinternal->netfilter_led_trigger); | ||
5820 | |||
5821 | diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c | ||
5822 | index 5da8746f7b88..b8a3e740ffd4 100644 | ||
5823 | --- a/net/netfilter/xt_hashlimit.c | ||
5824 | +++ b/net/netfilter/xt_hashlimit.c | ||
5825 | @@ -774,7 +774,7 @@ hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par, | ||
5826 | if (!dh->rateinfo.prev_window && | ||
5827 | (dh->rateinfo.current_rate <= dh->rateinfo.burst)) { | ||
5828 | spin_unlock(&dh->lock); | ||
5829 | - rcu_read_unlock_bh(); | ||
5830 | + local_bh_enable(); | ||
5831 | return !(cfg->mode & XT_HASHLIMIT_INVERT); | ||
5832 | } else { | ||
5833 | goto overlimit; | ||
5834 | diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c | ||
5835 | index 6451c5013e06..af465e681b9b 100644 | ||
5836 | --- a/net/smc/af_smc.c | ||
5837 | +++ b/net/smc/af_smc.c | ||
5838 | @@ -1369,8 +1369,10 @@ static int smc_create(struct net *net, struct socket *sock, int protocol, | ||
5839 | smc->use_fallback = false; /* assume rdma capability first */ | ||
5840 | rc = sock_create_kern(net, PF_INET, SOCK_STREAM, | ||
5841 | IPPROTO_TCP, &smc->clcsock); | ||
5842 | - if (rc) | ||
5843 | + if (rc) { | ||
5844 | sk_common_release(sk); | ||
5845 | + goto out; | ||
5846 | + } | ||
5847 | smc->sk.sk_sndbuf = max(smc->clcsock->sk->sk_sndbuf, SMC_BUF_MIN_SIZE); | ||
5848 | smc->sk.sk_rcvbuf = max(smc->clcsock->sk->sk_rcvbuf, SMC_BUF_MIN_SIZE); | ||
5849 | |||
5850 | diff --git a/scripts/Makefile.build b/scripts/Makefile.build | ||
5851 | index 47cddf32aeba..4f2b25d43ec9 100644 | ||
5852 | --- a/scripts/Makefile.build | ||
5853 | +++ b/scripts/Makefile.build | ||
5854 | @@ -256,6 +256,8 @@ __objtool_obj := $(objtree)/tools/objtool/objtool | ||
5855 | |||
5856 | objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check) | ||
5857 | |||
5858 | +objtool_args += $(if $(part-of-module), --module,) | ||
5859 | + | ||
5860 | ifndef CONFIG_FRAME_POINTER | ||
5861 | objtool_args += --no-fp | ||
5862 | endif | ||
5863 | @@ -264,6 +266,12 @@ objtool_args += --no-unreachable | ||
5864 | else | ||
5865 | objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable) | ||
5866 | endif | ||
5867 | +ifdef CONFIG_RETPOLINE | ||
5868 | +ifneq ($(RETPOLINE_CFLAGS),) | ||
5869 | + objtool_args += --retpoline | ||
5870 | +endif | ||
5871 | +endif | ||
5872 | + | ||
5873 | |||
5874 | ifdef CONFIG_MODVERSIONS | ||
5875 | objtool_o = $(@D)/.tmp_$(@F) | ||
5876 | diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib | ||
5877 | index 015aa9dbad86..06cf4c00fe88 100644 | ||
5878 | --- a/scripts/Makefile.lib | ||
5879 | +++ b/scripts/Makefile.lib | ||
5880 | @@ -287,11 +287,11 @@ cmd_dt_S_dtb= \ | ||
5881 | echo '\#include <asm-generic/vmlinux.lds.h>'; \ | ||
5882 | echo '.section .dtb.init.rodata,"a"'; \ | ||
5883 | echo '.balign STRUCT_ALIGNMENT'; \ | ||
5884 | - echo '.global __dtb_$(*F)_begin'; \ | ||
5885 | - echo '__dtb_$(*F)_begin:'; \ | ||
5886 | + echo '.global __dtb_$(subst -,_,$(*F))_begin'; \ | ||
5887 | + echo '__dtb_$(subst -,_,$(*F))_begin:'; \ | ||
5888 | echo '.incbin "$<" '; \ | ||
5889 | - echo '__dtb_$(*F)_end:'; \ | ||
5890 | - echo '.global __dtb_$(*F)_end'; \ | ||
5891 | + echo '__dtb_$(subst -,_,$(*F))_end:'; \ | ||
5892 | + echo '.global __dtb_$(subst -,_,$(*F))_end'; \ | ||
5893 | echo '.balign STRUCT_ALIGNMENT'; \ | ||
5894 | ) > $@ | ||
5895 | |||
5896 | diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c | ||
5897 | index a42cbbf2c8d9..35ff97bfd492 100644 | ||
5898 | --- a/sound/core/seq/seq_clientmgr.c | ||
5899 | +++ b/sound/core/seq/seq_clientmgr.c | ||
5900 | @@ -910,7 +910,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop) | ||
5901 | static int snd_seq_client_enqueue_event(struct snd_seq_client *client, | ||
5902 | struct snd_seq_event *event, | ||
5903 | struct file *file, int blocking, | ||
5904 | - int atomic, int hop) | ||
5905 | + int atomic, int hop, | ||
5906 | + struct mutex *mutexp) | ||
5907 | { | ||
5908 | struct snd_seq_event_cell *cell; | ||
5909 | int err; | ||
5910 | @@ -948,7 +949,8 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client, | ||
5911 | return -ENXIO; /* queue is not allocated */ | ||
5912 | |||
5913 | /* allocate an event cell */ | ||
5914 | - err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file); | ||
5915 | + err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, | ||
5916 | + file, mutexp); | ||
5917 | if (err < 0) | ||
5918 | return err; | ||
5919 | |||
5920 | @@ -1017,12 +1019,11 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, | ||
5921 | return -ENXIO; | ||
5922 | |||
5923 | /* allocate the pool now if the pool is not allocated yet */ | ||
5924 | + mutex_lock(&client->ioctl_mutex); | ||
5925 | if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) { | ||
5926 | - mutex_lock(&client->ioctl_mutex); | ||
5927 | err = snd_seq_pool_init(client->pool); | ||
5928 | - mutex_unlock(&client->ioctl_mutex); | ||
5929 | if (err < 0) | ||
5930 | - return -ENOMEM; | ||
5931 | + goto out; | ||
5932 | } | ||
5933 | |||
5934 | /* only process whole events */ | ||
5935 | @@ -1073,7 +1074,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, | ||
5936 | /* ok, enqueue it */ | ||
5937 | err = snd_seq_client_enqueue_event(client, &event, file, | ||
5938 | !(file->f_flags & O_NONBLOCK), | ||
5939 | - 0, 0); | ||
5940 | + 0, 0, &client->ioctl_mutex); | ||
5941 | if (err < 0) | ||
5942 | break; | ||
5943 | |||
5944 | @@ -1084,6 +1085,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, | ||
5945 | written += len; | ||
5946 | } | ||
5947 | |||
5948 | + out: | ||
5949 | + mutex_unlock(&client->ioctl_mutex); | ||
5950 | return written ? written : err; | ||
5951 | } | ||
5952 | |||
5953 | @@ -1838,6 +1841,9 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, | ||
5954 | (! snd_seq_write_pool_allocated(client) || | ||
5955 | info->output_pool != client->pool->size)) { | ||
5956 | if (snd_seq_write_pool_allocated(client)) { | ||
5957 | + /* is the pool in use? */ | ||
5958 | + if (atomic_read(&client->pool->counter)) | ||
5959 | + return -EBUSY; | ||
5960 | /* remove all existing cells */ | ||
5961 | snd_seq_pool_mark_closing(client->pool); | ||
5962 | snd_seq_queue_client_leave_cells(client->number); | ||
5963 | @@ -2260,7 +2266,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev, | ||
5964 | if (! cptr->accept_output) | ||
5965 | result = -EPERM; | ||
5966 | else /* send it */ | ||
5967 | - result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop); | ||
5968 | + result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, | ||
5969 | + atomic, hop, NULL); | ||
5970 | |||
5971 | snd_seq_client_unlock(cptr); | ||
5972 | return result; | ||
5973 | diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c | ||
5974 | index a8c2822e0198..72c0302a55d2 100644 | ||
5975 | --- a/sound/core/seq/seq_fifo.c | ||
5976 | +++ b/sound/core/seq/seq_fifo.c | ||
5977 | @@ -125,7 +125,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, | ||
5978 | return -EINVAL; | ||
5979 | |||
5980 | snd_use_lock_use(&f->use_lock); | ||
5981 | - err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ | ||
5982 | + err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL, NULL); /* always non-blocking */ | ||
5983 | if (err < 0) { | ||
5984 | if ((err == -ENOMEM) || (err == -EAGAIN)) | ||
5985 | atomic_inc(&f->overflow); | ||
5986 | diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c | ||
5987 | index f763682584a8..ab1112e90f88 100644 | ||
5988 | --- a/sound/core/seq/seq_memory.c | ||
5989 | +++ b/sound/core/seq/seq_memory.c | ||
5990 | @@ -220,7 +220,8 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) | ||
5991 | */ | ||
5992 | static int snd_seq_cell_alloc(struct snd_seq_pool *pool, | ||
5993 | struct snd_seq_event_cell **cellp, | ||
5994 | - int nonblock, struct file *file) | ||
5995 | + int nonblock, struct file *file, | ||
5996 | + struct mutex *mutexp) | ||
5997 | { | ||
5998 | struct snd_seq_event_cell *cell; | ||
5999 | unsigned long flags; | ||
6000 | @@ -244,7 +245,11 @@ static int snd_seq_cell_alloc(struct snd_seq_pool *pool, | ||
6001 | set_current_state(TASK_INTERRUPTIBLE); | ||
6002 | add_wait_queue(&pool->output_sleep, &wait); | ||
6003 | spin_unlock_irq(&pool->lock); | ||
6004 | + if (mutexp) | ||
6005 | + mutex_unlock(mutexp); | ||
6006 | schedule(); | ||
6007 | + if (mutexp) | ||
6008 | + mutex_lock(mutexp); | ||
6009 | spin_lock_irq(&pool->lock); | ||
6010 | remove_wait_queue(&pool->output_sleep, &wait); | ||
6011 | /* interrupted? */ | ||
6012 | @@ -287,7 +292,7 @@ static int snd_seq_cell_alloc(struct snd_seq_pool *pool, | ||
6013 | */ | ||
6014 | int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, | ||
6015 | struct snd_seq_event_cell **cellp, int nonblock, | ||
6016 | - struct file *file) | ||
6017 | + struct file *file, struct mutex *mutexp) | ||
6018 | { | ||
6019 | int ncells, err; | ||
6020 | unsigned int extlen; | ||
6021 | @@ -304,7 +309,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, | ||
6022 | if (ncells >= pool->total_elements) | ||
6023 | return -ENOMEM; | ||
6024 | |||
6025 | - err = snd_seq_cell_alloc(pool, &cell, nonblock, file); | ||
6026 | + err = snd_seq_cell_alloc(pool, &cell, nonblock, file, mutexp); | ||
6027 | if (err < 0) | ||
6028 | return err; | ||
6029 | |||
6030 | @@ -330,7 +335,8 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, | ||
6031 | int size = sizeof(struct snd_seq_event); | ||
6032 | if (len < size) | ||
6033 | size = len; | ||
6034 | - err = snd_seq_cell_alloc(pool, &tmp, nonblock, file); | ||
6035 | + err = snd_seq_cell_alloc(pool, &tmp, nonblock, file, | ||
6036 | + mutexp); | ||
6037 | if (err < 0) | ||
6038 | goto __error; | ||
6039 | if (cell->event.data.ext.ptr == NULL) | ||
6040 | diff --git a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h | ||
6041 | index 32f959c17786..3abe306c394a 100644 | ||
6042 | --- a/sound/core/seq/seq_memory.h | ||
6043 | +++ b/sound/core/seq/seq_memory.h | ||
6044 | @@ -66,7 +66,8 @@ struct snd_seq_pool { | ||
6045 | void snd_seq_cell_free(struct snd_seq_event_cell *cell); | ||
6046 | |||
6047 | int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, | ||
6048 | - struct snd_seq_event_cell **cellp, int nonblock, struct file *file); | ||
6049 | + struct snd_seq_event_cell **cellp, int nonblock, | ||
6050 | + struct file *file, struct mutex *mutexp); | ||
6051 | |||
6052 | /* return number of unused (free) cells */ | ||
6053 | static inline int snd_seq_unused_cells(struct snd_seq_pool *pool) | ||
6054 | diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c | ||
6055 | index 37e1cf8218ff..5b4dbcec6de8 100644 | ||
6056 | --- a/sound/pci/hda/patch_conexant.c | ||
6057 | +++ b/sound/pci/hda/patch_conexant.c | ||
6058 | @@ -957,6 +957,8 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | ||
6059 | SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), | ||
6060 | SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), | ||
6061 | SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), | ||
6062 | + SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), | ||
6063 | + SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), | ||
6064 | SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), | ||
6065 | SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), | ||
6066 | SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), | ||
6067 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c | ||
6068 | index 8fe38c18e29d..18bab5ffbe4a 100644 | ||
6069 | --- a/sound/pci/hda/patch_realtek.c | ||
6070 | +++ b/sound/pci/hda/patch_realtek.c | ||
6071 | @@ -5152,6 +5152,16 @@ static void alc298_fixup_speaker_volume(struct hda_codec *codec, | ||
6072 | } | ||
6073 | } | ||
6074 | |||
6075 | +/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */ | ||
6076 | +static void alc295_fixup_disable_dac3(struct hda_codec *codec, | ||
6077 | + const struct hda_fixup *fix, int action) | ||
6078 | +{ | ||
6079 | + if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
6080 | + hda_nid_t conn[2] = { 0x02, 0x03 }; | ||
6081 | + snd_hda_override_conn_list(codec, 0x17, 2, conn); | ||
6082 | + } | ||
6083 | +} | ||
6084 | + | ||
6085 | /* Hook to update amp GPIO4 for automute */ | ||
6086 | static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec, | ||
6087 | struct hda_jack_callback *jack) | ||
6088 | @@ -5344,6 +5354,7 @@ enum { | ||
6089 | ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, | ||
6090 | ALC255_FIXUP_DELL_SPK_NOISE, | ||
6091 | ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
6092 | + ALC295_FIXUP_DISABLE_DAC3, | ||
6093 | ALC280_FIXUP_HP_HEADSET_MIC, | ||
6094 | ALC221_FIXUP_HP_FRONT_MIC, | ||
6095 | ALC292_FIXUP_TPT460, | ||
6096 | @@ -5358,10 +5369,12 @@ enum { | ||
6097 | ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, | ||
6098 | ALC233_FIXUP_LENOVO_MULTI_CODECS, | ||
6099 | ALC294_FIXUP_LENOVO_MIC_LOCATION, | ||
6100 | + ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, | ||
6101 | ALC700_FIXUP_INTEL_REFERENCE, | ||
6102 | ALC274_FIXUP_DELL_BIND_DACS, | ||
6103 | ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, | ||
6104 | ALC298_FIXUP_TPT470_DOCK, | ||
6105 | + ALC255_FIXUP_DUMMY_LINEOUT_VERB, | ||
6106 | }; | ||
6107 | |||
6108 | static const struct hda_fixup alc269_fixups[] = { | ||
6109 | @@ -6076,6 +6089,10 @@ static const struct hda_fixup alc269_fixups[] = { | ||
6110 | .chained = true, | ||
6111 | .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, | ||
6112 | }, | ||
6113 | + [ALC295_FIXUP_DISABLE_DAC3] = { | ||
6114 | + .type = HDA_FIXUP_FUNC, | ||
6115 | + .v.func = alc295_fixup_disable_dac3, | ||
6116 | + }, | ||
6117 | [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { | ||
6118 | .type = HDA_FIXUP_PINS, | ||
6119 | .v.pins = (const struct hda_pintbl[]) { | ||
6120 | @@ -6161,6 +6178,18 @@ static const struct hda_fixup alc269_fixups[] = { | ||
6121 | { } | ||
6122 | }, | ||
6123 | }, | ||
6124 | + [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = { | ||
6125 | + .type = HDA_FIXUP_PINS, | ||
6126 | + .v.pins = (const struct hda_pintbl[]) { | ||
6127 | + { 0x16, 0x0101102f }, /* Rear Headset HP */ | ||
6128 | + { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */ | ||
6129 | + { 0x1a, 0x01a19030 }, /* Rear Headset MIC */ | ||
6130 | + { 0x1b, 0x02011020 }, | ||
6131 | + { } | ||
6132 | + }, | ||
6133 | + .chained = true, | ||
6134 | + .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | ||
6135 | + }, | ||
6136 | [ALC700_FIXUP_INTEL_REFERENCE] = { | ||
6137 | .type = HDA_FIXUP_VERBS, | ||
6138 | .v.verbs = (const struct hda_verb[]) { | ||
6139 | @@ -6197,6 +6226,15 @@ static const struct hda_fixup alc269_fixups[] = { | ||
6140 | .chained = true, | ||
6141 | .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE | ||
6142 | }, | ||
6143 | + [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = { | ||
6144 | + .type = HDA_FIXUP_PINS, | ||
6145 | + .v.pins = (const struct hda_pintbl[]) { | ||
6146 | + { 0x14, 0x0201101f }, | ||
6147 | + { } | ||
6148 | + }, | ||
6149 | + .chained = true, | ||
6150 | + .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE | ||
6151 | + }, | ||
6152 | }; | ||
6153 | |||
6154 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | ||
6155 | @@ -6245,10 +6283,13 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | ||
6156 | SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), | ||
6157 | SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), | ||
6158 | SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), | ||
6159 | + SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3), | ||
6160 | SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), | ||
6161 | + SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE), | ||
6162 | SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), | ||
6163 | SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), | ||
6164 | SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), | ||
6165 | + SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), | ||
6166 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
6167 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
6168 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | ||
6169 | @@ -6386,9 +6427,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | ||
6170 | SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK), | ||
6171 | SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | ||
6172 | SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | ||
6173 | + SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460), | ||
6174 | SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | ||
6175 | SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | ||
6176 | SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | ||
6177 | + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | ||
6178 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | ||
6179 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | ||
6180 | SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), | ||
6181 | @@ -6750,7 +6793,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | ||
6182 | {0x12, 0x90a60120}, | ||
6183 | {0x14, 0x90170110}, | ||
6184 | {0x21, 0x0321101f}), | ||
6185 | - SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
6186 | + SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, | ||
6187 | {0x12, 0xb7a60130}, | ||
6188 | {0x14, 0x90170110}, | ||
6189 | {0x21, 0x04211020}), | ||
6190 | diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c | ||
6191 | index 57254f5b2779..694abc628e9b 100644 | ||
6192 | --- a/tools/objtool/builtin-check.c | ||
6193 | +++ b/tools/objtool/builtin-check.c | ||
6194 | @@ -29,7 +29,7 @@ | ||
6195 | #include "builtin.h" | ||
6196 | #include "check.h" | ||
6197 | |||
6198 | -bool no_fp, no_unreachable; | ||
6199 | +bool no_fp, no_unreachable, retpoline, module; | ||
6200 | |||
6201 | static const char * const check_usage[] = { | ||
6202 | "objtool check [<options>] file.o", | ||
6203 | @@ -39,6 +39,8 @@ static const char * const check_usage[] = { | ||
6204 | const struct option check_options[] = { | ||
6205 | OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"), | ||
6206 | OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"), | ||
6207 | + OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"), | ||
6208 | + OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"), | ||
6209 | OPT_END(), | ||
6210 | }; | ||
6211 | |||
6212 | @@ -53,5 +55,5 @@ int cmd_check(int argc, const char **argv) | ||
6213 | |||
6214 | objname = argv[0]; | ||
6215 | |||
6216 | - return check(objname, no_fp, no_unreachable, false); | ||
6217 | + return check(objname, false); | ||
6218 | } | ||
6219 | diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c | ||
6220 | index 91e8e19ff5e0..77ea2b97117d 100644 | ||
6221 | --- a/tools/objtool/builtin-orc.c | ||
6222 | +++ b/tools/objtool/builtin-orc.c | ||
6223 | @@ -25,7 +25,6 @@ | ||
6224 | */ | ||
6225 | |||
6226 | #include <string.h> | ||
6227 | -#include <subcmd/parse-options.h> | ||
6228 | #include "builtin.h" | ||
6229 | #include "check.h" | ||
6230 | |||
6231 | @@ -36,9 +35,6 @@ static const char *orc_usage[] = { | ||
6232 | NULL, | ||
6233 | }; | ||
6234 | |||
6235 | -extern const struct option check_options[]; | ||
6236 | -extern bool no_fp, no_unreachable; | ||
6237 | - | ||
6238 | int cmd_orc(int argc, const char **argv) | ||
6239 | { | ||
6240 | const char *objname; | ||
6241 | @@ -54,7 +50,7 @@ int cmd_orc(int argc, const char **argv) | ||
6242 | |||
6243 | objname = argv[0]; | ||
6244 | |||
6245 | - return check(objname, no_fp, no_unreachable, true); | ||
6246 | + return check(objname, true); | ||
6247 | } | ||
6248 | |||
6249 | if (!strcmp(argv[0], "dump")) { | ||
6250 | diff --git a/tools/objtool/builtin.h b/tools/objtool/builtin.h | ||
6251 | index dd526067fed5..28ff40e19a14 100644 | ||
6252 | --- a/tools/objtool/builtin.h | ||
6253 | +++ b/tools/objtool/builtin.h | ||
6254 | @@ -17,6 +17,11 @@ | ||
6255 | #ifndef _BUILTIN_H | ||
6256 | #define _BUILTIN_H | ||
6257 | |||
6258 | +#include <subcmd/parse-options.h> | ||
6259 | + | ||
6260 | +extern const struct option check_options[]; | ||
6261 | +extern bool no_fp, no_unreachable, retpoline, module; | ||
6262 | + | ||
6263 | extern int cmd_check(int argc, const char **argv); | ||
6264 | extern int cmd_orc(int argc, const char **argv); | ||
6265 | |||
6266 | diff --git a/tools/objtool/check.c b/tools/objtool/check.c | ||
6267 | index c7fb5c2392ee..9d01d0b1084e 100644 | ||
6268 | --- a/tools/objtool/check.c | ||
6269 | +++ b/tools/objtool/check.c | ||
6270 | @@ -18,6 +18,7 @@ | ||
6271 | #include <string.h> | ||
6272 | #include <stdlib.h> | ||
6273 | |||
6274 | +#include "builtin.h" | ||
6275 | #include "check.h" | ||
6276 | #include "elf.h" | ||
6277 | #include "special.h" | ||
6278 | @@ -33,7 +34,6 @@ struct alternative { | ||
6279 | }; | ||
6280 | |||
6281 | const char *objname; | ||
6282 | -static bool no_fp; | ||
6283 | struct cfi_state initial_func_cfi; | ||
6284 | |||
6285 | struct instruction *find_insn(struct objtool_file *file, | ||
6286 | @@ -496,6 +496,7 @@ static int add_jump_destinations(struct objtool_file *file) | ||
6287 | * disguise, so convert them accordingly. | ||
6288 | */ | ||
6289 | insn->type = INSN_JUMP_DYNAMIC; | ||
6290 | + insn->retpoline_safe = true; | ||
6291 | continue; | ||
6292 | } else { | ||
6293 | /* sibling call */ | ||
6294 | @@ -547,7 +548,8 @@ static int add_call_destinations(struct objtool_file *file) | ||
6295 | if (!insn->call_dest && !insn->ignore) { | ||
6296 | WARN_FUNC("unsupported intra-function call", | ||
6297 | insn->sec, insn->offset); | ||
6298 | - WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE."); | ||
6299 | + if (retpoline) | ||
6300 | + WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE."); | ||
6301 | return -1; | ||
6302 | } | ||
6303 | |||
6304 | @@ -922,7 +924,11 @@ static struct rela *find_switch_table(struct objtool_file *file, | ||
6305 | if (find_symbol_containing(file->rodata, text_rela->addend)) | ||
6306 | continue; | ||
6307 | |||
6308 | - return find_rela_by_dest(file->rodata, text_rela->addend); | ||
6309 | + rodata_rela = find_rela_by_dest(file->rodata, text_rela->addend); | ||
6310 | + if (!rodata_rela) | ||
6311 | + continue; | ||
6312 | + | ||
6313 | + return rodata_rela; | ||
6314 | } | ||
6315 | |||
6316 | return NULL; | ||
6317 | @@ -1107,6 +1113,41 @@ static int read_unwind_hints(struct objtool_file *file) | ||
6318 | return 0; | ||
6319 | } | ||
6320 | |||
6321 | +static int read_retpoline_hints(struct objtool_file *file) | ||
6322 | +{ | ||
6323 | + struct section *sec; | ||
6324 | + struct instruction *insn; | ||
6325 | + struct rela *rela; | ||
6326 | + | ||
6327 | + sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe"); | ||
6328 | + if (!sec) | ||
6329 | + return 0; | ||
6330 | + | ||
6331 | + list_for_each_entry(rela, &sec->rela_list, list) { | ||
6332 | + if (rela->sym->type != STT_SECTION) { | ||
6333 | + WARN("unexpected relocation symbol type in %s", sec->name); | ||
6334 | + return -1; | ||
6335 | + } | ||
6336 | + | ||
6337 | + insn = find_insn(file, rela->sym->sec, rela->addend); | ||
6338 | + if (!insn) { | ||
6339 | + WARN("bad .discard.retpoline_safe entry"); | ||
6340 | + return -1; | ||
6341 | + } | ||
6342 | + | ||
6343 | + if (insn->type != INSN_JUMP_DYNAMIC && | ||
6344 | + insn->type != INSN_CALL_DYNAMIC) { | ||
6345 | + WARN_FUNC("retpoline_safe hint not an indirect jump/call", | ||
6346 | + insn->sec, insn->offset); | ||
6347 | + return -1; | ||
6348 | + } | ||
6349 | + | ||
6350 | + insn->retpoline_safe = true; | ||
6351 | + } | ||
6352 | + | ||
6353 | + return 0; | ||
6354 | +} | ||
6355 | + | ||
6356 | static int decode_sections(struct objtool_file *file) | ||
6357 | { | ||
6358 | int ret; | ||
6359 | @@ -1145,6 +1186,10 @@ static int decode_sections(struct objtool_file *file) | ||
6360 | if (ret) | ||
6361 | return ret; | ||
6362 | |||
6363 | + ret = read_retpoline_hints(file); | ||
6364 | + if (ret) | ||
6365 | + return ret; | ||
6366 | + | ||
6367 | return 0; | ||
6368 | } | ||
6369 | |||
6370 | @@ -1890,6 +1935,38 @@ static int validate_unwind_hints(struct objtool_file *file) | ||
6371 | return warnings; | ||
6372 | } | ||
6373 | |||
6374 | +static int validate_retpoline(struct objtool_file *file) | ||
6375 | +{ | ||
6376 | + struct instruction *insn; | ||
6377 | + int warnings = 0; | ||
6378 | + | ||
6379 | + for_each_insn(file, insn) { | ||
6380 | + if (insn->type != INSN_JUMP_DYNAMIC && | ||
6381 | + insn->type != INSN_CALL_DYNAMIC) | ||
6382 | + continue; | ||
6383 | + | ||
6384 | + if (insn->retpoline_safe) | ||
6385 | + continue; | ||
6386 | + | ||
6387 | + /* | ||
6388 | + * .init.text code is ran before userspace and thus doesn't | ||
6389 | + * strictly need retpolines, except for modules which are | ||
6390 | + * loaded late, they very much do need retpoline in their | ||
6391 | + * .init.text | ||
6392 | + */ | ||
6393 | + if (!strcmp(insn->sec->name, ".init.text") && !module) | ||
6394 | + continue; | ||
6395 | + | ||
6396 | + WARN_FUNC("indirect %s found in RETPOLINE build", | ||
6397 | + insn->sec, insn->offset, | ||
6398 | + insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call"); | ||
6399 | + | ||
6400 | + warnings++; | ||
6401 | + } | ||
6402 | + | ||
6403 | + return warnings; | ||
6404 | +} | ||
6405 | + | ||
6406 | static bool is_kasan_insn(struct instruction *insn) | ||
6407 | { | ||
6408 | return (insn->type == INSN_CALL && | ||
6409 | @@ -2021,13 +2098,12 @@ static void cleanup(struct objtool_file *file) | ||
6410 | elf_close(file->elf); | ||
6411 | } | ||
6412 | |||
6413 | -int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc) | ||
6414 | +int check(const char *_objname, bool orc) | ||
6415 | { | ||
6416 | struct objtool_file file; | ||
6417 | int ret, warnings = 0; | ||
6418 | |||
6419 | objname = _objname; | ||
6420 | - no_fp = _no_fp; | ||
6421 | |||
6422 | file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY); | ||
6423 | if (!file.elf) | ||
6424 | @@ -2051,6 +2127,13 @@ int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc) | ||
6425 | if (list_empty(&file.insn_list)) | ||
6426 | goto out; | ||
6427 | |||
6428 | + if (retpoline) { | ||
6429 | + ret = validate_retpoline(&file); | ||
6430 | + if (ret < 0) | ||
6431 | + return ret; | ||
6432 | + warnings += ret; | ||
6433 | + } | ||
6434 | + | ||
6435 | ret = validate_functions(&file); | ||
6436 | if (ret < 0) | ||
6437 | goto out; | ||
6438 | diff --git a/tools/objtool/check.h b/tools/objtool/check.h | ||
6439 | index 23a1d065cae1..c6b68fcb926f 100644 | ||
6440 | --- a/tools/objtool/check.h | ||
6441 | +++ b/tools/objtool/check.h | ||
6442 | @@ -45,6 +45,7 @@ struct instruction { | ||
6443 | unsigned char type; | ||
6444 | unsigned long immediate; | ||
6445 | bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; | ||
6446 | + bool retpoline_safe; | ||
6447 | struct symbol *call_dest; | ||
6448 | struct instruction *jump_dest; | ||
6449 | struct instruction *first_jump_src; | ||
6450 | @@ -63,7 +64,7 @@ struct objtool_file { | ||
6451 | bool ignore_unreachables, c_file, hints; | ||
6452 | }; | ||
6453 | |||
6454 | -int check(const char *objname, bool no_fp, bool no_unreachable, bool orc); | ||
6455 | +int check(const char *objname, bool orc); | ||
6456 | |||
6457 | struct instruction *find_insn(struct objtool_file *file, | ||
6458 | struct section *sec, unsigned long offset); | ||
6459 | diff --git a/tools/perf/util/trigger.h b/tools/perf/util/trigger.h | ||
6460 | index 370138e7e35c..88223bc7c82b 100644 | ||
6461 | --- a/tools/perf/util/trigger.h | ||
6462 | +++ b/tools/perf/util/trigger.h | ||
6463 | @@ -12,7 +12,7 @@ | ||
6464 | * States and transits: | ||
6465 | * | ||
6466 | * | ||
6467 | - * OFF--(on)--> READY --(hit)--> HIT | ||
6468 | + * OFF--> ON --> READY --(hit)--> HIT | ||
6469 | * ^ | | ||
6470 | * | (ready) | ||
6471 | * | | | ||
6472 | @@ -27,8 +27,9 @@ struct trigger { | ||
6473 | volatile enum { | ||
6474 | TRIGGER_ERROR = -2, | ||
6475 | TRIGGER_OFF = -1, | ||
6476 | - TRIGGER_READY = 0, | ||
6477 | - TRIGGER_HIT = 1, | ||
6478 | + TRIGGER_ON = 0, | ||
6479 | + TRIGGER_READY = 1, | ||
6480 | + TRIGGER_HIT = 2, | ||
6481 | } state; | ||
6482 | const char *name; | ||
6483 | }; | ||
6484 | @@ -50,7 +51,7 @@ static inline bool trigger_is_error(struct trigger *t) | ||
6485 | static inline void trigger_on(struct trigger *t) | ||
6486 | { | ||
6487 | TRIGGER_WARN_ONCE(t, TRIGGER_OFF); | ||
6488 | - t->state = TRIGGER_READY; | ||
6489 | + t->state = TRIGGER_ON; | ||
6490 | } | ||
6491 | |||
6492 | static inline void trigger_ready(struct trigger *t) |