Contents of /trunk/kernel-alx-legacy/patches-4.9/0181-4.9.82-all-fixes.patch
Parent Directory | Revision Log
Revision 3608 -
(show annotations)
(download)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 135433 byte(s)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 135433 byte(s)
-added kerenl-alx-legacy pkg
1 | diff --git a/Makefile b/Makefile |
2 | index 4d5753f1c37b..d338530540e0 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 9 |
8 | -SUBLEVEL = 81 |
9 | +SUBLEVEL = 82 |
10 | EXTRAVERSION = |
11 | NAME = Roaring Lionus |
12 | |
13 | diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h |
14 | index 2b0ac429f5eb..412bb3c24f36 100644 |
15 | --- a/arch/alpha/kernel/pci_impl.h |
16 | +++ b/arch/alpha/kernel/pci_impl.h |
17 | @@ -143,7 +143,8 @@ struct pci_iommu_arena |
18 | }; |
19 | |
20 | #if defined(CONFIG_ALPHA_SRM) && \ |
21 | - (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA)) |
22 | + (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA) || \ |
23 | + defined(CONFIG_ALPHA_AVANTI)) |
24 | # define NEED_SRM_SAVE_RESTORE |
25 | #else |
26 | # undef NEED_SRM_SAVE_RESTORE |
27 | diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c |
28 | index b483156698d5..60c17b9bf04d 100644 |
29 | --- a/arch/alpha/kernel/process.c |
30 | +++ b/arch/alpha/kernel/process.c |
31 | @@ -265,12 +265,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp, |
32 | application calling fork. */ |
33 | if (clone_flags & CLONE_SETTLS) |
34 | childti->pcb.unique = regs->r20; |
35 | + else |
36 | + regs->r20 = 0; /* OSF/1 has some strange fork() semantics. */ |
37 | childti->pcb.usp = usp ?: rdusp(); |
38 | *childregs = *regs; |
39 | childregs->r0 = 0; |
40 | childregs->r19 = 0; |
41 | childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */ |
42 | - regs->r20 = 0; |
43 | stack = ((struct switch_stack *) regs) - 1; |
44 | *childstack = *stack; |
45 | childstack->r26 = (unsigned long) ret_from_fork; |
46 | diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c |
47 | index 74aceead06e9..32ba92cdf5f6 100644 |
48 | --- a/arch/alpha/kernel/traps.c |
49 | +++ b/arch/alpha/kernel/traps.c |
50 | @@ -158,11 +158,16 @@ void show_stack(struct task_struct *task, unsigned long *sp) |
51 | for(i=0; i < kstack_depth_to_print; i++) { |
52 | if (((long) stack & (THREAD_SIZE-1)) == 0) |
53 | break; |
54 | - if (i && ((i % 4) == 0)) |
55 | - printk("\n "); |
56 | - printk("%016lx ", *stack++); |
57 | + if ((i % 4) == 0) { |
58 | + if (i) |
59 | + pr_cont("\n"); |
60 | + printk(" "); |
61 | + } else { |
62 | + pr_cont(" "); |
63 | + } |
64 | + pr_cont("%016lx", *stack++); |
65 | } |
66 | - printk("\n"); |
67 | + pr_cont("\n"); |
68 | dik_show_trace(sp); |
69 | } |
70 | |
71 | diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c |
72 | index 19b5f5c1c0ff..c38bfbeec306 100644 |
73 | --- a/arch/arm/kvm/arm.c |
74 | +++ b/arch/arm/kvm/arm.c |
75 | @@ -1165,6 +1165,7 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, |
76 | cpu_hyp_reset(); |
77 | |
78 | return NOTIFY_OK; |
79 | + case CPU_PM_ENTER_FAILED: |
80 | case CPU_PM_EXIT: |
81 | if (__this_cpu_read(kvm_arm_hardware_enabled)) |
82 | /* The hardware was enabled before suspend. */ |
83 | diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c |
84 | index 42f5daf715d0..4e57ebca6e69 100644 |
85 | --- a/arch/arm/kvm/handle_exit.c |
86 | +++ b/arch/arm/kvm/handle_exit.c |
87 | @@ -38,7 +38,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) |
88 | |
89 | ret = kvm_psci_call(vcpu); |
90 | if (ret < 0) { |
91 | - kvm_inject_undefined(vcpu); |
92 | + vcpu_set_reg(vcpu, 0, ~0UL); |
93 | return 1; |
94 | } |
95 | |
96 | @@ -47,7 +47,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) |
97 | |
98 | static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) |
99 | { |
100 | - kvm_inject_undefined(vcpu); |
101 | + /* |
102 | + * "If an SMC instruction executed at Non-secure EL1 is |
103 | + * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a |
104 | + * Trap exception, not a Secure Monitor Call exception [...]" |
105 | + * |
106 | + * We need to advance the PC after the trap, as it would |
107 | + * otherwise return to the same address... |
108 | + */ |
109 | + vcpu_set_reg(vcpu, 0, ~0UL); |
110 | + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); |
111 | return 1; |
112 | } |
113 | |
114 | diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c |
115 | index b9920b1edd5a..70cef54dc40f 100644 |
116 | --- a/arch/mn10300/mm/misalignment.c |
117 | +++ b/arch/mn10300/mm/misalignment.c |
118 | @@ -437,7 +437,7 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) |
119 | |
120 | info.si_signo = SIGSEGV; |
121 | info.si_errno = 0; |
122 | - info.si_code = 0; |
123 | + info.si_code = SEGV_MAPERR; |
124 | info.si_addr = (void *) regs->pc; |
125 | force_sig_info(SIGSEGV, &info, current); |
126 | return; |
127 | diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c |
128 | index 3d3f6062f49c..605a284922fb 100644 |
129 | --- a/arch/openrisc/kernel/traps.c |
130 | +++ b/arch/openrisc/kernel/traps.c |
131 | @@ -302,12 +302,12 @@ asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address) |
132 | siginfo_t info; |
133 | |
134 | if (user_mode(regs)) { |
135 | - /* Send a SIGSEGV */ |
136 | - info.si_signo = SIGSEGV; |
137 | + /* Send a SIGBUS */ |
138 | + info.si_signo = SIGBUS; |
139 | info.si_errno = 0; |
140 | - /* info.si_code has been set above */ |
141 | - info.si_addr = (void *)address; |
142 | - force_sig_info(SIGSEGV, &info, current); |
143 | + info.si_code = BUS_ADRALN; |
144 | + info.si_addr = (void __user *)address; |
145 | + force_sig_info(SIGBUS, &info, current); |
146 | } else { |
147 | printk("KERNEL: Unaligned Access 0x%.8lx\n", address); |
148 | show_registers(regs); |
149 | diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h |
150 | index 0e12cb2437d1..dc0996b9d75d 100644 |
151 | --- a/arch/powerpc/include/asm/hvcall.h |
152 | +++ b/arch/powerpc/include/asm/hvcall.h |
153 | @@ -319,6 +319,7 @@ |
154 | #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 |
155 | |
156 | #ifndef __ASSEMBLY__ |
157 | +#include <linux/types.h> |
158 | |
159 | /** |
160 | * plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments |
161 | diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c |
162 | index ff639342a8be..c5b997757988 100644 |
163 | --- a/arch/sh/kernel/traps_32.c |
164 | +++ b/arch/sh/kernel/traps_32.c |
165 | @@ -607,7 +607,8 @@ asmlinkage void do_divide_error(unsigned long r4) |
166 | break; |
167 | } |
168 | |
169 | - force_sig_info(SIGFPE, &info, current); |
170 | + info.si_signo = SIGFPE; |
171 | + force_sig_info(info.si_signo, &info, current); |
172 | } |
173 | #endif |
174 | |
175 | diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c |
176 | index e32142bc071d..28c372003e44 100644 |
177 | --- a/arch/x86/crypto/poly1305_glue.c |
178 | +++ b/arch/x86/crypto/poly1305_glue.c |
179 | @@ -164,7 +164,6 @@ static struct shash_alg alg = { |
180 | .init = poly1305_simd_init, |
181 | .update = poly1305_simd_update, |
182 | .final = crypto_poly1305_final, |
183 | - .setkey = crypto_poly1305_setkey, |
184 | .descsize = sizeof(struct poly1305_simd_desc_ctx), |
185 | .base = { |
186 | .cra_name = "poly1305", |
187 | diff --git a/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c b/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c |
188 | index 36870b26067a..d08805032f01 100644 |
189 | --- a/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c |
190 | +++ b/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c |
191 | @@ -57,10 +57,12 @@ void sha512_mb_mgr_init_avx2(struct sha512_mb_mgr *state) |
192 | { |
193 | unsigned int j; |
194 | |
195 | - state->lens[0] = 0; |
196 | - state->lens[1] = 1; |
197 | - state->lens[2] = 2; |
198 | - state->lens[3] = 3; |
199 | + /* initially all lanes are unused */ |
200 | + state->lens[0] = 0xFFFFFFFF00000000; |
201 | + state->lens[1] = 0xFFFFFFFF00000001; |
202 | + state->lens[2] = 0xFFFFFFFF00000002; |
203 | + state->lens[3] = 0xFFFFFFFF00000003; |
204 | + |
205 | state->unused_lanes = 0xFF03020100; |
206 | for (j = 0; j < 4; j++) |
207 | state->ldata[j].job_in_lane = NULL; |
208 | diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h |
209 | index 9ee85066f407..62210da19a92 100644 |
210 | --- a/arch/x86/include/asm/vsyscall.h |
211 | +++ b/arch/x86/include/asm/vsyscall.h |
212 | @@ -13,7 +13,6 @@ extern void map_vsyscall(void); |
213 | */ |
214 | extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); |
215 | extern bool vsyscall_enabled(void); |
216 | -extern unsigned long vsyscall_pgprot; |
217 | #else |
218 | static inline void map_vsyscall(void) {} |
219 | static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) |
220 | @@ -22,5 +21,6 @@ static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) |
221 | } |
222 | static inline bool vsyscall_enabled(void) { return false; } |
223 | #endif |
224 | +extern unsigned long vsyscall_pgprot; |
225 | |
226 | #endif /* _ASM_X86_VSYSCALL_H */ |
227 | diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c |
228 | index d49da86e3099..d66224e695cf 100644 |
229 | --- a/arch/x86/kvm/vmx.c |
230 | +++ b/arch/x86/kvm/vmx.c |
231 | @@ -4967,14 +4967,15 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, |
232 | |
233 | if (is_guest_mode(vcpu) && |
234 | vector == vmx->nested.posted_intr_nv) { |
235 | - /* the PIR and ON have been set by L1. */ |
236 | - kvm_vcpu_trigger_posted_interrupt(vcpu); |
237 | /* |
238 | * If a posted intr is not recognized by hardware, |
239 | * we will accomplish it in the next vmentry. |
240 | */ |
241 | vmx->nested.pi_pending = true; |
242 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
243 | + /* the PIR and ON have been set by L1. */ |
244 | + if (!kvm_vcpu_trigger_posted_interrupt(vcpu)) |
245 | + kvm_vcpu_kick(vcpu); |
246 | return 0; |
247 | } |
248 | return -1; |
249 | diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h |
250 | index b39531babec0..72bfc1cbc2b5 100644 |
251 | --- a/arch/xtensa/include/asm/futex.h |
252 | +++ b/arch/xtensa/include/asm/futex.h |
253 | @@ -109,7 +109,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
254 | u32 oldval, u32 newval) |
255 | { |
256 | int ret = 0; |
257 | - u32 prev; |
258 | |
259 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) |
260 | return -EFAULT; |
261 | @@ -120,26 +119,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
262 | |
263 | __asm__ __volatile__ ( |
264 | " # futex_atomic_cmpxchg_inatomic\n" |
265 | - "1: l32i %1, %3, 0\n" |
266 | - " mov %0, %5\n" |
267 | - " wsr %1, scompare1\n" |
268 | - "2: s32c1i %0, %3, 0\n" |
269 | - "3:\n" |
270 | + " wsr %5, scompare1\n" |
271 | + "1: s32c1i %1, %4, 0\n" |
272 | + " s32i %1, %6, 0\n" |
273 | + "2:\n" |
274 | " .section .fixup,\"ax\"\n" |
275 | " .align 4\n" |
276 | - "4: .long 3b\n" |
277 | - "5: l32r %1, 4b\n" |
278 | - " movi %0, %6\n" |
279 | + "3: .long 2b\n" |
280 | + "4: l32r %1, 3b\n" |
281 | + " movi %0, %7\n" |
282 | " jx %1\n" |
283 | " .previous\n" |
284 | " .section __ex_table,\"a\"\n" |
285 | - " .long 1b,5b,2b,5b\n" |
286 | + " .long 1b,4b\n" |
287 | " .previous\n" |
288 | - : "+r" (ret), "=&r" (prev), "+m" (*uaddr) |
289 | - : "r" (uaddr), "r" (oldval), "r" (newval), "I" (-EFAULT) |
290 | + : "+r" (ret), "+r" (newval), "+m" (*uaddr), "+m" (*uval) |
291 | + : "r" (uaddr), "r" (oldval), "r" (uval), "I" (-EFAULT) |
292 | : "memory"); |
293 | |
294 | - *uval = prev; |
295 | return ret; |
296 | } |
297 | |
298 | diff --git a/crypto/ahash.c b/crypto/ahash.c |
299 | index cce0268a13fe..f3fa104de479 100644 |
300 | --- a/crypto/ahash.c |
301 | +++ b/crypto/ahash.c |
302 | @@ -625,5 +625,16 @@ struct hash_alg_common *ahash_attr_alg(struct rtattr *rta, u32 type, u32 mask) |
303 | } |
304 | EXPORT_SYMBOL_GPL(ahash_attr_alg); |
305 | |
306 | +bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg) |
307 | +{ |
308 | + struct crypto_alg *alg = &halg->base; |
309 | + |
310 | + if (alg->cra_type != &crypto_ahash_type) |
311 | + return crypto_shash_alg_has_setkey(__crypto_shash_alg(alg)); |
312 | + |
313 | + return __crypto_ahash_alg(alg)->setkey != NULL; |
314 | +} |
315 | +EXPORT_SYMBOL_GPL(crypto_hash_alg_has_setkey); |
316 | + |
317 | MODULE_LICENSE("GPL"); |
318 | MODULE_DESCRIPTION("Asynchronous cryptographic hash type"); |
319 | diff --git a/crypto/cryptd.c b/crypto/cryptd.c |
320 | index 0c654e59f215..af9ad45d1909 100644 |
321 | --- a/crypto/cryptd.c |
322 | +++ b/crypto/cryptd.c |
323 | @@ -691,7 +691,8 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, |
324 | inst->alg.finup = cryptd_hash_finup_enqueue; |
325 | inst->alg.export = cryptd_hash_export; |
326 | inst->alg.import = cryptd_hash_import; |
327 | - inst->alg.setkey = cryptd_hash_setkey; |
328 | + if (crypto_shash_alg_has_setkey(salg)) |
329 | + inst->alg.setkey = cryptd_hash_setkey; |
330 | inst->alg.digest = cryptd_hash_digest_enqueue; |
331 | |
332 | err = ahash_register_instance(tmpl, inst); |
333 | diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c |
334 | index a14100e74754..6e9389c8bfbd 100644 |
335 | --- a/crypto/mcryptd.c |
336 | +++ b/crypto/mcryptd.c |
337 | @@ -534,7 +534,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, |
338 | inst->alg.finup = mcryptd_hash_finup_enqueue; |
339 | inst->alg.export = mcryptd_hash_export; |
340 | inst->alg.import = mcryptd_hash_import; |
341 | - inst->alg.setkey = mcryptd_hash_setkey; |
342 | + if (crypto_hash_alg_has_setkey(halg)) |
343 | + inst->alg.setkey = mcryptd_hash_setkey; |
344 | inst->alg.digest = mcryptd_hash_digest_enqueue; |
345 | |
346 | err = ahash_register_instance(tmpl, inst); |
347 | diff --git a/crypto/poly1305_generic.c b/crypto/poly1305_generic.c |
348 | index 2df9835dfbc0..bca99238948f 100644 |
349 | --- a/crypto/poly1305_generic.c |
350 | +++ b/crypto/poly1305_generic.c |
351 | @@ -51,17 +51,6 @@ int crypto_poly1305_init(struct shash_desc *desc) |
352 | } |
353 | EXPORT_SYMBOL_GPL(crypto_poly1305_init); |
354 | |
355 | -int crypto_poly1305_setkey(struct crypto_shash *tfm, |
356 | - const u8 *key, unsigned int keylen) |
357 | -{ |
358 | - /* Poly1305 requires a unique key for each tag, which implies that |
359 | - * we can't set it on the tfm that gets accessed by multiple users |
360 | - * simultaneously. Instead we expect the key as the first 32 bytes in |
361 | - * the update() call. */ |
362 | - return -ENOTSUPP; |
363 | -} |
364 | -EXPORT_SYMBOL_GPL(crypto_poly1305_setkey); |
365 | - |
366 | static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key) |
367 | { |
368 | /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ |
369 | @@ -80,6 +69,11 @@ static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key) |
370 | dctx->s[3] = le32_to_cpuvp(key + 12); |
371 | } |
372 | |
373 | +/* |
374 | + * Poly1305 requires a unique key for each tag, which implies that we can't set |
375 | + * it on the tfm that gets accessed by multiple users simultaneously. Instead we |
376 | + * expect the key as the first 32 bytes in the update() call. |
377 | + */ |
378 | unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx, |
379 | const u8 *src, unsigned int srclen) |
380 | { |
381 | @@ -285,7 +279,6 @@ static struct shash_alg poly1305_alg = { |
382 | .init = crypto_poly1305_init, |
383 | .update = crypto_poly1305_update, |
384 | .final = crypto_poly1305_final, |
385 | - .setkey = crypto_poly1305_setkey, |
386 | .descsize = sizeof(struct poly1305_desc_ctx), |
387 | .base = { |
388 | .cra_name = "poly1305", |
389 | diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c |
390 | index fe03d00de22b..b1815b20a99c 100644 |
391 | --- a/drivers/acpi/nfit/core.c |
392 | +++ b/drivers/acpi/nfit/core.c |
393 | @@ -1535,6 +1535,9 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) |
394 | struct kernfs_node *nfit_kernfs; |
395 | |
396 | nvdimm = nfit_mem->nvdimm; |
397 | + if (!nvdimm) |
398 | + continue; |
399 | + |
400 | nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit"); |
401 | if (nfit_kernfs) |
402 | nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs, |
403 | diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c |
404 | index 2fa8304171e0..7a3431018e0a 100644 |
405 | --- a/drivers/acpi/sbshc.c |
406 | +++ b/drivers/acpi/sbshc.c |
407 | @@ -275,8 +275,8 @@ static int acpi_smbus_hc_add(struct acpi_device *device) |
408 | device->driver_data = hc; |
409 | |
410 | acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc); |
411 | - printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n", |
412 | - hc->ec, hc->offset, hc->query_bit); |
413 | + dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n", |
414 | + hc->offset, hc->query_bit); |
415 | |
416 | return 0; |
417 | } |
418 | diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c |
419 | index c94038206c3a..9b46ef4c851e 100644 |
420 | --- a/drivers/ata/ahci.c |
421 | +++ b/drivers/ata/ahci.c |
422 | @@ -265,9 +265,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { |
423 | { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */ |
424 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ |
425 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ |
426 | - { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */ |
427 | + { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH M AHCI */ |
428 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ |
429 | - { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ |
430 | + { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH M RAID */ |
431 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ |
432 | { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */ |
433 | { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */ |
434 | @@ -290,9 +290,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { |
435 | { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */ |
436 | { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */ |
437 | { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ |
438 | - { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ |
439 | + { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT M AHCI */ |
440 | { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ |
441 | - { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ |
442 | + { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT M RAID */ |
443 | { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ |
444 | { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ |
445 | { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ |
446 | @@ -301,20 +301,20 @@ static const struct pci_device_id ahci_pci_tbl[] = { |
447 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ |
448 | { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ |
449 | { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ |
450 | - { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */ |
451 | + { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point M AHCI */ |
452 | { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */ |
453 | { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ |
454 | { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ |
455 | - { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ |
456 | + { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point M RAID */ |
457 | { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ |
458 | { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */ |
459 | - { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */ |
460 | + { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point M AHCI */ |
461 | { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */ |
462 | - { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */ |
463 | + { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point M RAID */ |
464 | { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */ |
465 | - { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ |
466 | + { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point M RAID */ |
467 | { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ |
468 | - { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ |
469 | + { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point M RAID */ |
470 | { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ |
471 | { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ |
472 | { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ |
473 | @@ -355,21 +355,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { |
474 | { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */ |
475 | { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */ |
476 | { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */ |
477 | - { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */ |
478 | + { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series M AHCI */ |
479 | { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */ |
480 | - { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */ |
481 | + { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series M RAID */ |
482 | { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */ |
483 | - { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ |
484 | + { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series M RAID */ |
485 | { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ |
486 | - { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ |
487 | + { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series M RAID */ |
488 | { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */ |
489 | { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ |
490 | { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ |
491 | { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */ |
492 | - { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ |
493 | + { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H M AHCI */ |
494 | { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ |
495 | { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */ |
496 | - { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ |
497 | + { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H M RAID */ |
498 | { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ |
499 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ |
500 | { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/ |
501 | @@ -383,6 +383,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { |
502 | { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ |
503 | { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ |
504 | { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ |
505 | + { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ |
506 | + { PCI_VDEVICE(INTEL, 0x0f22), board_ahci }, /* Bay Trail AHCI */ |
507 | + { PCI_VDEVICE(INTEL, 0x0f23), board_ahci }, /* Bay Trail AHCI */ |
508 | + { PCI_VDEVICE(INTEL, 0x22a3), board_ahci }, /* Cherry Trail AHCI */ |
509 | + { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci }, /* Apollo Lake AHCI */ |
510 | |
511 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
512 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
513 | diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c |
514 | index 90fa4ac149db..7e4ef0502796 100644 |
515 | --- a/drivers/block/pktcdvd.c |
516 | +++ b/drivers/block/pktcdvd.c |
517 | @@ -2779,7 +2779,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) |
518 | pd->pkt_dev = MKDEV(pktdev_major, idx); |
519 | ret = pkt_new_dev(pd, dev); |
520 | if (ret) |
521 | - goto out_new_dev; |
522 | + goto out_mem2; |
523 | |
524 | /* inherit events of the host device */ |
525 | disk->events = pd->bdev->bd_disk->events; |
526 | @@ -2797,8 +2797,6 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) |
527 | mutex_unlock(&ctl_mutex); |
528 | return 0; |
529 | |
530 | -out_new_dev: |
531 | - blk_cleanup_queue(disk->queue); |
532 | out_mem2: |
533 | put_disk(disk); |
534 | out_mem: |
535 | diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c |
536 | index 1cb958e199eb..94e914a33a99 100644 |
537 | --- a/drivers/bluetooth/btsdio.c |
538 | +++ b/drivers/bluetooth/btsdio.c |
539 | @@ -31,6 +31,7 @@ |
540 | #include <linux/errno.h> |
541 | #include <linux/skbuff.h> |
542 | |
543 | +#include <linux/mmc/host.h> |
544 | #include <linux/mmc/sdio_ids.h> |
545 | #include <linux/mmc/sdio_func.h> |
546 | |
547 | @@ -291,6 +292,14 @@ static int btsdio_probe(struct sdio_func *func, |
548 | tuple = tuple->next; |
549 | } |
550 | |
551 | + /* BCM43341 devices soldered onto the PCB (non-removable) use an |
552 | + * uart connection for bluetooth, ignore the BT SDIO interface. |
553 | + */ |
554 | + if (func->vendor == SDIO_VENDOR_ID_BROADCOM && |
555 | + func->device == SDIO_DEVICE_ID_BROADCOM_43341 && |
556 | + !mmc_card_is_removable(func->card->host)) |
557 | + return -ENODEV; |
558 | + |
559 | data = devm_kzalloc(&func->dev, sizeof(*data), GFP_KERNEL); |
560 | if (!data) |
561 | return -ENOMEM; |
562 | diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c |
563 | index 693028659ccc..3257647d4f74 100644 |
564 | --- a/drivers/bluetooth/btusb.c |
565 | +++ b/drivers/bluetooth/btusb.c |
566 | @@ -23,6 +23,7 @@ |
567 | |
568 | #include <linux/module.h> |
569 | #include <linux/usb.h> |
570 | +#include <linux/usb/quirks.h> |
571 | #include <linux/firmware.h> |
572 | #include <asm/unaligned.h> |
573 | |
574 | @@ -369,8 +370,8 @@ static const struct usb_device_id blacklist_table[] = { |
575 | #define BTUSB_FIRMWARE_LOADED 7 |
576 | #define BTUSB_FIRMWARE_FAILED 8 |
577 | #define BTUSB_BOOTING 9 |
578 | -#define BTUSB_RESET_RESUME 10 |
579 | -#define BTUSB_DIAG_RUNNING 11 |
580 | +#define BTUSB_DIAG_RUNNING 10 |
581 | +#define BTUSB_OOB_WAKE_ENABLED 11 |
582 | |
583 | struct btusb_data { |
584 | struct hci_dev *hdev; |
585 | @@ -2928,9 +2929,9 @@ static int btusb_probe(struct usb_interface *intf, |
586 | |
587 | /* QCA Rome devices lose their updated firmware over suspend, |
588 | * but the USB hub doesn't notice any status change. |
589 | - * Explicitly request a device reset on resume. |
590 | + * explicitly request a device reset on resume. |
591 | */ |
592 | - set_bit(BTUSB_RESET_RESUME, &data->flags); |
593 | + interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; |
594 | } |
595 | |
596 | #ifdef CONFIG_BT_HCIBTUSB_RTL |
597 | @@ -2941,7 +2942,7 @@ static int btusb_probe(struct usb_interface *intf, |
598 | * but the USB hub doesn't notice any status change. |
599 | * Explicitly request a device reset on resume. |
600 | */ |
601 | - set_bit(BTUSB_RESET_RESUME, &data->flags); |
602 | + interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; |
603 | } |
604 | #endif |
605 | |
606 | @@ -3098,14 +3099,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) |
607 | btusb_stop_traffic(data); |
608 | usb_kill_anchored_urbs(&data->tx_anchor); |
609 | |
610 | - /* Optionally request a device reset on resume, but only when |
611 | - * wakeups are disabled. If wakeups are enabled we assume the |
612 | - * device will stay powered up throughout suspend. |
613 | - */ |
614 | - if (test_bit(BTUSB_RESET_RESUME, &data->flags) && |
615 | - !device_may_wakeup(&data->udev->dev)) |
616 | - data->udev->reset_resume = 1; |
617 | - |
618 | return 0; |
619 | } |
620 | |
621 | diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c |
622 | index 1b2574c4fb97..b167cc634fae 100644 |
623 | --- a/drivers/clocksource/timer-stm32.c |
624 | +++ b/drivers/clocksource/timer-stm32.c |
625 | @@ -16,6 +16,7 @@ |
626 | #include <linux/of_irq.h> |
627 | #include <linux/clk.h> |
628 | #include <linux/reset.h> |
629 | +#include <linux/slab.h> |
630 | |
631 | #define TIM_CR1 0x00 |
632 | #define TIM_DIER 0x0c |
633 | @@ -106,6 +107,10 @@ static int __init stm32_clockevent_init(struct device_node *np) |
634 | unsigned long rate, max_delta; |
635 | int irq, ret, bits, prescaler = 1; |
636 | |
637 | + data = kmemdup(&clock_event_ddata, sizeof(*data), GFP_KERNEL); |
638 | + if (!data) |
639 | + return -ENOMEM; |
640 | + |
641 | clk = of_clk_get(np, 0); |
642 | if (IS_ERR(clk)) { |
643 | ret = PTR_ERR(clk); |
644 | @@ -156,8 +161,8 @@ static int __init stm32_clockevent_init(struct device_node *np) |
645 | |
646 | writel_relaxed(prescaler - 1, data->base + TIM_PSC); |
647 | writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR); |
648 | - writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER); |
649 | writel_relaxed(0, data->base + TIM_SR); |
650 | + writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER); |
651 | |
652 | data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ); |
653 | |
654 | @@ -184,6 +189,7 @@ static int __init stm32_clockevent_init(struct device_node *np) |
655 | err_clk_enable: |
656 | clk_put(clk); |
657 | err_clk_get: |
658 | + kfree(data); |
659 | return ret; |
660 | } |
661 | |
662 | diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c |
663 | index 98468b96c32f..2ca101ac0c17 100644 |
664 | --- a/drivers/crypto/caam/ctrl.c |
665 | +++ b/drivers/crypto/caam/ctrl.c |
666 | @@ -228,12 +228,16 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, |
667 | * without any error (HW optimizations for later |
668 | * CAAM eras), then try again. |
669 | */ |
670 | + if (ret) |
671 | + break; |
672 | + |
673 | rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_IFMASK; |
674 | if ((status && status != JRSTA_SSRC_JUMP_HALT_CC) || |
675 | - !(rdsta_val & (1 << sh_idx))) |
676 | + !(rdsta_val & (1 << sh_idx))) { |
677 | ret = -EAGAIN; |
678 | - if (ret) |
679 | break; |
680 | + } |
681 | + |
682 | dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx); |
683 | /* Clear the contents before recreating the descriptor */ |
684 | memset(desc, 0x00, CAAM_CMD_SZ * 7); |
685 | diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c |
686 | index e0bd578a253a..ebe72a466587 100644 |
687 | --- a/drivers/dma/dmatest.c |
688 | +++ b/drivers/dma/dmatest.c |
689 | @@ -339,7 +339,7 @@ static void dmatest_callback(void *arg) |
690 | { |
691 | struct dmatest_done *done = arg; |
692 | struct dmatest_thread *thread = |
693 | - container_of(arg, struct dmatest_thread, done_wait); |
694 | + container_of(done, struct dmatest_thread, test_done); |
695 | if (!thread->done) { |
696 | done->done = true; |
697 | wake_up_all(done->wait); |
698 | diff --git a/drivers/edac/octeon_edac-lmc.c b/drivers/edac/octeon_edac-lmc.c |
699 | index cda6dab5067a..6b65a102b49d 100644 |
700 | --- a/drivers/edac/octeon_edac-lmc.c |
701 | +++ b/drivers/edac/octeon_edac-lmc.c |
702 | @@ -79,6 +79,7 @@ static void octeon_lmc_edac_poll_o2(struct mem_ctl_info *mci) |
703 | if (!pvt->inject) |
704 | int_reg.u64 = cvmx_read_csr(CVMX_LMCX_INT(mci->mc_idx)); |
705 | else { |
706 | + int_reg.u64 = 0; |
707 | if (pvt->error_type == 1) |
708 | int_reg.s.sec_err = 1; |
709 | if (pvt->error_type == 2) |
710 | diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c |
711 | index 7fdc42e5aac8..74163a928cba 100644 |
712 | --- a/drivers/gpu/drm/i915/intel_dp.c |
713 | +++ b/drivers/gpu/drm/i915/intel_dp.c |
714 | @@ -5063,6 +5063,12 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, |
715 | */ |
716 | final->t8 = 1; |
717 | final->t9 = 1; |
718 | + |
719 | + /* |
720 | + * HW has only a 100msec granularity for t11_t12 so round it up |
721 | + * accordingly. |
722 | + */ |
723 | + final->t11_t12 = roundup(final->t11_t12, 100 * 10); |
724 | } |
725 | |
726 | static void |
727 | diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c |
728 | index e32862ca5223..03cac5731afc 100644 |
729 | --- a/drivers/hid/hid-core.c |
730 | +++ b/drivers/hid/hid-core.c |
731 | @@ -2365,7 +2365,6 @@ static const struct hid_device_id hid_ignore_list[] = { |
732 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, |
733 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, |
734 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 0x0400) }, |
735 | - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 0x0401) }, |
736 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
737 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, |
738 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, |
739 | @@ -2635,6 +2634,17 @@ bool hid_ignore(struct hid_device *hdev) |
740 | strncmp(hdev->name, "www.masterkit.ru MA901", 22) == 0) |
741 | return true; |
742 | break; |
743 | + case USB_VENDOR_ID_ELAN: |
744 | + /* |
745 | + * Many Elan devices have a product id of 0x0401 and are handled |
746 | + * by the elan_i2c input driver. But the ACPI HID ELAN0800 dev |
747 | + * is not (and cannot be) handled by that driver -> |
748 | + * Ignore all 0x0401 devs except for the ELAN0800 dev. |
749 | + */ |
750 | + if (hdev->product == 0x0401 && |
751 | + strncmp(hdev->name, "ELAN0800", 8) != 0) |
752 | + return true; |
753 | + break; |
754 | } |
755 | |
756 | if (hdev->type == HID_TYPE_USBMOUSE && |
757 | diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c |
758 | index ad304eed656d..c61227cfff25 100644 |
759 | --- a/drivers/media/dvb-frontends/ascot2e.c |
760 | +++ b/drivers/media/dvb-frontends/ascot2e.c |
761 | @@ -155,7 +155,9 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv, |
762 | |
763 | static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val) |
764 | { |
765 | - return ascot2e_write_regs(priv, reg, &val, 1); |
766 | + u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
767 | + |
768 | + return ascot2e_write_regs(priv, reg, &tmp, 1); |
769 | } |
770 | |
771 | static int ascot2e_read_regs(struct ascot2e_priv *priv, |
772 | diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c |
773 | index fd0f25ee251f..b97647cd7dc6 100644 |
774 | --- a/drivers/media/dvb-frontends/cxd2841er.c |
775 | +++ b/drivers/media/dvb-frontends/cxd2841er.c |
776 | @@ -261,7 +261,9 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv, |
777 | static int cxd2841er_write_reg(struct cxd2841er_priv *priv, |
778 | u8 addr, u8 reg, u8 val) |
779 | { |
780 | - return cxd2841er_write_regs(priv, addr, reg, &val, 1); |
781 | + u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
782 | + |
783 | + return cxd2841er_write_regs(priv, addr, reg, &tmp, 1); |
784 | } |
785 | |
786 | static int cxd2841er_read_regs(struct cxd2841er_priv *priv, |
787 | diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c |
788 | index dc43c5f6d0ea..e06bcd4b3ddc 100644 |
789 | --- a/drivers/media/dvb-frontends/helene.c |
790 | +++ b/drivers/media/dvb-frontends/helene.c |
791 | @@ -331,7 +331,9 @@ static int helene_write_regs(struct helene_priv *priv, |
792 | |
793 | static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val) |
794 | { |
795 | - return helene_write_regs(priv, reg, &val, 1); |
796 | + u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
797 | + |
798 | + return helene_write_regs(priv, reg, &tmp, 1); |
799 | } |
800 | |
801 | static int helene_read_regs(struct helene_priv *priv, |
802 | diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c |
803 | index 0c089b5986a1..4ebddc895137 100644 |
804 | --- a/drivers/media/dvb-frontends/horus3a.c |
805 | +++ b/drivers/media/dvb-frontends/horus3a.c |
806 | @@ -89,7 +89,9 @@ static int horus3a_write_regs(struct horus3a_priv *priv, |
807 | |
808 | static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val) |
809 | { |
810 | - return horus3a_write_regs(priv, reg, &val, 1); |
811 | + u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
812 | + |
813 | + return horus3a_write_regs(priv, reg, &tmp, 1); |
814 | } |
815 | |
816 | static int horus3a_enter_power_save(struct horus3a_priv *priv) |
817 | diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c |
818 | index cadcae4cff89..ac9d2591bb6f 100644 |
819 | --- a/drivers/media/dvb-frontends/itd1000.c |
820 | +++ b/drivers/media/dvb-frontends/itd1000.c |
821 | @@ -99,8 +99,9 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg) |
822 | |
823 | static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v) |
824 | { |
825 | - int ret = itd1000_write_regs(state, r, &v, 1); |
826 | - state->shadow[r] = v; |
827 | + u8 tmp = v; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
828 | + int ret = itd1000_write_regs(state, r, &tmp, 1); |
829 | + state->shadow[r] = tmp; |
830 | return ret; |
831 | } |
832 | |
833 | diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c |
834 | index fc08429c99b7..7824926a3744 100644 |
835 | --- a/drivers/media/dvb-frontends/mt312.c |
836 | +++ b/drivers/media/dvb-frontends/mt312.c |
837 | @@ -142,7 +142,10 @@ static inline int mt312_readreg(struct mt312_state *state, |
838 | static inline int mt312_writereg(struct mt312_state *state, |
839 | const enum mt312_reg_addr reg, const u8 val) |
840 | { |
841 | - return mt312_write(state, reg, &val, 1); |
842 | + u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
843 | + |
844 | + |
845 | + return mt312_write(state, reg, &tmp, 1); |
846 | } |
847 | |
848 | static inline u32 mt312_div(u32 a, u32 b) |
849 | diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c |
850 | index 3d171b0e00c2..3deddbcaa8b7 100644 |
851 | --- a/drivers/media/dvb-frontends/stb0899_drv.c |
852 | +++ b/drivers/media/dvb-frontends/stb0899_drv.c |
853 | @@ -552,7 +552,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, |
854 | |
855 | int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data) |
856 | { |
857 | - return stb0899_write_regs(state, reg, &data, 1); |
858 | + u8 tmp = data; |
859 | + return stb0899_write_regs(state, reg, &tmp, 1); |
860 | } |
861 | |
862 | /* |
863 | diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c |
864 | index 5add1182c3ca..4746b1e0d637 100644 |
865 | --- a/drivers/media/dvb-frontends/stb6100.c |
866 | +++ b/drivers/media/dvb-frontends/stb6100.c |
867 | @@ -226,12 +226,14 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st |
868 | |
869 | static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data) |
870 | { |
871 | + u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
872 | + |
873 | if (unlikely(reg >= STB6100_NUMREGS)) { |
874 | dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); |
875 | return -EREMOTEIO; |
876 | } |
877 | - data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set; |
878 | - return stb6100_write_reg_range(state, &data, reg, 1); |
879 | + tmp = (tmp & stb6100_template[reg].mask) | stb6100_template[reg].set; |
880 | + return stb6100_write_reg_range(state, &tmp, reg, 1); |
881 | } |
882 | |
883 | |
884 | diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c |
885 | index abc379aea713..94cec81d0a5c 100644 |
886 | --- a/drivers/media/dvb-frontends/stv0367.c |
887 | +++ b/drivers/media/dvb-frontends/stv0367.c |
888 | @@ -804,7 +804,9 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len) |
889 | |
890 | static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) |
891 | { |
892 | - return stv0367_writeregs(state, reg, &data, 1); |
893 | + u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
894 | + |
895 | + return stv0367_writeregs(state, reg, &tmp, 1); |
896 | } |
897 | |
898 | static u8 stv0367_readreg(struct stv0367_state *state, u16 reg) |
899 | diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c |
900 | index 25bdf6e0f963..f0377e2b341b 100644 |
901 | --- a/drivers/media/dvb-frontends/stv090x.c |
902 | +++ b/drivers/media/dvb-frontends/stv090x.c |
903 | @@ -761,7 +761,9 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 |
904 | |
905 | static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data) |
906 | { |
907 | - return stv090x_write_regs(state, reg, &data, 1); |
908 | + u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
909 | + |
910 | + return stv090x_write_regs(state, reg, &tmp, 1); |
911 | } |
912 | |
913 | static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable) |
914 | diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c |
915 | index c611ad210b5c..924f16fee1fb 100644 |
916 | --- a/drivers/media/dvb-frontends/stv6110x.c |
917 | +++ b/drivers/media/dvb-frontends/stv6110x.c |
918 | @@ -97,7 +97,9 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da |
919 | |
920 | static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) |
921 | { |
922 | - return stv6110x_write_regs(stv6110x, reg, &data, 1); |
923 | + u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
924 | + |
925 | + return stv6110x_write_regs(stv6110x, reg, &tmp, 1); |
926 | } |
927 | |
928 | static int stv6110x_init(struct dvb_frontend *fe) |
929 | diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c |
930 | index a9f6bbea6df3..103b9c824f1f 100644 |
931 | --- a/drivers/media/dvb-frontends/ts2020.c |
932 | +++ b/drivers/media/dvb-frontends/ts2020.c |
933 | @@ -369,7 +369,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc, |
934 | gain2 = clamp_t(long, gain2, 0, 13); |
935 | v_agc = clamp_t(long, v_agc, 400, 1100); |
936 | |
937 | - *_gain = -(gain1 * 2330 + |
938 | + *_gain = -((__s64)gain1 * 2330 + |
939 | gain2 * 3500 + |
940 | v_agc * 24 / 10 * 10 + |
941 | 10000); |
942 | @@ -387,7 +387,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc, |
943 | gain3 = clamp_t(long, gain3, 0, 6); |
944 | v_agc = clamp_t(long, v_agc, 600, 1600); |
945 | |
946 | - *_gain = -(gain1 * 2650 + |
947 | + *_gain = -((__s64)gain1 * 2650 + |
948 | gain2 * 3380 + |
949 | gain3 * 2850 + |
950 | v_agc * 176 / 100 * 10 - |
951 | diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c |
952 | index f8c271be196c..0d2bef62ff05 100644 |
953 | --- a/drivers/media/dvb-frontends/zl10039.c |
954 | +++ b/drivers/media/dvb-frontends/zl10039.c |
955 | @@ -138,7 +138,9 @@ static inline int zl10039_writereg(struct zl10039_state *state, |
956 | const enum zl10039_reg_addr reg, |
957 | const u8 val) |
958 | { |
959 | - return zl10039_write(state, reg, &val, 1); |
960 | + const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
961 | + |
962 | + return zl10039_write(state, reg, &tmp, 1); |
963 | } |
964 | |
965 | static int zl10039_init(struct dvb_frontend *fe) |
966 | diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c |
967 | index 0e8fb89896c4..5c4aa247d650 100644 |
968 | --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c |
969 | +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c |
970 | @@ -504,18 +504,23 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, |
971 | |
972 | static int lme2510_return_status(struct dvb_usb_device *d) |
973 | { |
974 | - int ret = 0; |
975 | + int ret; |
976 | u8 *data; |
977 | |
978 | - data = kzalloc(10, GFP_KERNEL); |
979 | + data = kzalloc(6, GFP_KERNEL); |
980 | if (!data) |
981 | return -ENOMEM; |
982 | |
983 | - ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), |
984 | - 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200); |
985 | - info("Firmware Status: %x (%x)", ret , data[2]); |
986 | + ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), |
987 | + 0x06, 0x80, 0x0302, 0x00, |
988 | + data, 0x6, 200); |
989 | + if (ret != 6) |
990 | + ret = -EINVAL; |
991 | + else |
992 | + ret = data[2]; |
993 | + |
994 | + info("Firmware Status: %6ph", data); |
995 | |
996 | - ret = (ret < 0) ? -ENODEV : data[2]; |
997 | kfree(data); |
998 | return ret; |
999 | } |
1000 | @@ -1079,8 +1084,6 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) |
1001 | |
1002 | if (adap->fe[0]) { |
1003 | info("FE Found M88RS2000"); |
1004 | - dvb_attach(ts2020_attach, adap->fe[0], &ts2020_config, |
1005 | - &d->i2c_adap); |
1006 | st->i2c_tuner_gate_w = 5; |
1007 | st->i2c_tuner_gate_r = 5; |
1008 | st->i2c_tuner_addr = 0x60; |
1009 | @@ -1146,17 +1149,18 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) |
1010 | ret = st->tuner_config; |
1011 | break; |
1012 | case TUNER_RS2000: |
1013 | - ret = st->tuner_config; |
1014 | + if (dvb_attach(ts2020_attach, adap->fe[0], |
1015 | + &ts2020_config, &d->i2c_adap)) |
1016 | + ret = st->tuner_config; |
1017 | break; |
1018 | default: |
1019 | break; |
1020 | } |
1021 | |
1022 | - if (ret) |
1023 | + if (ret) { |
1024 | info("TUN Found %s tuner", tun_msg[ret]); |
1025 | - else { |
1026 | - info("TUN No tuner found --- resetting device"); |
1027 | - lme_coldreset(d); |
1028 | + } else { |
1029 | + info("TUN No tuner found"); |
1030 | return -ENODEV; |
1031 | } |
1032 | |
1033 | @@ -1200,6 +1204,7 @@ static int lme2510_get_adapter_count(struct dvb_usb_device *d) |
1034 | static int lme2510_identify_state(struct dvb_usb_device *d, const char **name) |
1035 | { |
1036 | struct lme2510_state *st = d->priv; |
1037 | + int status; |
1038 | |
1039 | usb_reset_configuration(d->udev); |
1040 | |
1041 | @@ -1208,12 +1213,16 @@ static int lme2510_identify_state(struct dvb_usb_device *d, const char **name) |
1042 | |
1043 | st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware; |
1044 | |
1045 | - if (lme2510_return_status(d) == 0x44) { |
1046 | + status = lme2510_return_status(d); |
1047 | + if (status == 0x44) { |
1048 | *name = lme_firmware_switch(d, 0); |
1049 | return COLD; |
1050 | } |
1051 | |
1052 | - return 0; |
1053 | + if (status != 0x47) |
1054 | + return -EINVAL; |
1055 | + |
1056 | + return WARM; |
1057 | } |
1058 | |
1059 | static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, |
1060 | diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c |
1061 | index 9fd43a37154c..b20f03d86e00 100644 |
1062 | --- a/drivers/media/usb/dvb-usb/cxusb.c |
1063 | +++ b/drivers/media/usb/dvb-usb/cxusb.c |
1064 | @@ -820,6 +820,8 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int component, |
1065 | case XC2028_RESET_CLK: |
1066 | deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg); |
1067 | break; |
1068 | + case XC2028_I2C_FLUSH: |
1069 | + break; |
1070 | default: |
1071 | deb_info("%s: unknown command %d, arg %d\n", __func__, |
1072 | command, arg); |
1073 | diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c |
1074 | index caa55402052e..2868766893c8 100644 |
1075 | --- a/drivers/media/usb/dvb-usb/dib0700_devices.c |
1076 | +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c |
1077 | @@ -431,6 +431,7 @@ static int stk7700ph_xc3028_callback(void *ptr, int component, |
1078 | state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); |
1079 | break; |
1080 | case XC2028_RESET_CLK: |
1081 | + case XC2028_I2C_FLUSH: |
1082 | break; |
1083 | default: |
1084 | err("%s: unknown command %d, arg %d\n", __func__, |
1085 | diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c |
1086 | index a61d8fd63c12..a20b60ac66ca 100644 |
1087 | --- a/drivers/media/usb/hdpvr/hdpvr-core.c |
1088 | +++ b/drivers/media/usb/hdpvr/hdpvr-core.c |
1089 | @@ -295,7 +295,7 @@ static int hdpvr_probe(struct usb_interface *interface, |
1090 | /* register v4l2_device early so it can be used for printks */ |
1091 | if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { |
1092 | dev_err(&interface->dev, "v4l2_device_register failed\n"); |
1093 | - goto error; |
1094 | + goto error_free_dev; |
1095 | } |
1096 | |
1097 | mutex_init(&dev->io_mutex); |
1098 | @@ -304,7 +304,7 @@ static int hdpvr_probe(struct usb_interface *interface, |
1099 | dev->usbc_buf = kmalloc(64, GFP_KERNEL); |
1100 | if (!dev->usbc_buf) { |
1101 | v4l2_err(&dev->v4l2_dev, "Out of memory\n"); |
1102 | - goto error; |
1103 | + goto error_v4l2_unregister; |
1104 | } |
1105 | |
1106 | init_waitqueue_head(&dev->wait_buffer); |
1107 | @@ -342,13 +342,13 @@ static int hdpvr_probe(struct usb_interface *interface, |
1108 | } |
1109 | if (!dev->bulk_in_endpointAddr) { |
1110 | v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n"); |
1111 | - goto error; |
1112 | + goto error_put_usb; |
1113 | } |
1114 | |
1115 | /* init the device */ |
1116 | if (hdpvr_device_init(dev)) { |
1117 | v4l2_err(&dev->v4l2_dev, "device init failed\n"); |
1118 | - goto error; |
1119 | + goto error_put_usb; |
1120 | } |
1121 | |
1122 | mutex_lock(&dev->io_mutex); |
1123 | @@ -356,7 +356,7 @@ static int hdpvr_probe(struct usb_interface *interface, |
1124 | mutex_unlock(&dev->io_mutex); |
1125 | v4l2_err(&dev->v4l2_dev, |
1126 | "allocating transfer buffers failed\n"); |
1127 | - goto error; |
1128 | + goto error_put_usb; |
1129 | } |
1130 | mutex_unlock(&dev->io_mutex); |
1131 | |
1132 | @@ -364,7 +364,7 @@ static int hdpvr_probe(struct usb_interface *interface, |
1133 | retval = hdpvr_register_i2c_adapter(dev); |
1134 | if (retval < 0) { |
1135 | v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n"); |
1136 | - goto error; |
1137 | + goto error_free_buffers; |
1138 | } |
1139 | |
1140 | client = hdpvr_register_ir_rx_i2c(dev); |
1141 | @@ -397,13 +397,17 @@ static int hdpvr_probe(struct usb_interface *interface, |
1142 | reg_fail: |
1143 | #if IS_ENABLED(CONFIG_I2C) |
1144 | i2c_del_adapter(&dev->i2c_adapter); |
1145 | +error_free_buffers: |
1146 | #endif |
1147 | + hdpvr_free_buffers(dev); |
1148 | +error_put_usb: |
1149 | + usb_put_dev(dev->udev); |
1150 | + kfree(dev->usbc_buf); |
1151 | +error_v4l2_unregister: |
1152 | + v4l2_device_unregister(&dev->v4l2_dev); |
1153 | +error_free_dev: |
1154 | + kfree(dev); |
1155 | error: |
1156 | - if (dev) { |
1157 | - flush_work(&dev->worker); |
1158 | - /* this frees allocated memory */ |
1159 | - hdpvr_delete(dev); |
1160 | - } |
1161 | return retval; |
1162 | } |
1163 | |
1164 | diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c |
1165 | index dc51dd86377d..48a39222fdf9 100644 |
1166 | --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c |
1167 | +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c |
1168 | @@ -18,8 +18,18 @@ |
1169 | #include <linux/videodev2.h> |
1170 | #include <linux/v4l2-subdev.h> |
1171 | #include <media/v4l2-dev.h> |
1172 | +#include <media/v4l2-fh.h> |
1173 | +#include <media/v4l2-ctrls.h> |
1174 | #include <media/v4l2-ioctl.h> |
1175 | |
1176 | +/* Use the same argument order as copy_in_user */ |
1177 | +#define assign_in_user(to, from) \ |
1178 | +({ \ |
1179 | + typeof(*from) __assign_tmp; \ |
1180 | + \ |
1181 | + get_user(__assign_tmp, from) || put_user(__assign_tmp, to); \ |
1182 | +}) |
1183 | + |
1184 | static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
1185 | { |
1186 | long ret = -ENOIOCTLCMD; |
1187 | @@ -33,131 +43,88 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
1188 | |
1189 | struct v4l2_clip32 { |
1190 | struct v4l2_rect c; |
1191 | - compat_caddr_t next; |
1192 | + compat_caddr_t next; |
1193 | }; |
1194 | |
1195 | struct v4l2_window32 { |
1196 | struct v4l2_rect w; |
1197 | - __u32 field; /* enum v4l2_field */ |
1198 | + __u32 field; /* enum v4l2_field */ |
1199 | __u32 chromakey; |
1200 | compat_caddr_t clips; /* actually struct v4l2_clip32 * */ |
1201 | __u32 clipcount; |
1202 | compat_caddr_t bitmap; |
1203 | + __u8 global_alpha; |
1204 | }; |
1205 | |
1206 | -static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) |
1207 | -{ |
1208 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) || |
1209 | - copy_from_user(&kp->w, &up->w, sizeof(up->w)) || |
1210 | - get_user(kp->field, &up->field) || |
1211 | - get_user(kp->chromakey, &up->chromakey) || |
1212 | - get_user(kp->clipcount, &up->clipcount)) |
1213 | - return -EFAULT; |
1214 | - if (kp->clipcount > 2048) |
1215 | - return -EINVAL; |
1216 | - if (kp->clipcount) { |
1217 | - struct v4l2_clip32 __user *uclips; |
1218 | - struct v4l2_clip __user *kclips; |
1219 | - int n = kp->clipcount; |
1220 | - compat_caddr_t p; |
1221 | - |
1222 | - if (get_user(p, &up->clips)) |
1223 | - return -EFAULT; |
1224 | - uclips = compat_ptr(p); |
1225 | - kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); |
1226 | - kp->clips = kclips; |
1227 | - while (--n >= 0) { |
1228 | - if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) |
1229 | - return -EFAULT; |
1230 | - if (put_user(n ? kclips + 1 : NULL, &kclips->next)) |
1231 | - return -EFAULT; |
1232 | - uclips += 1; |
1233 | - kclips += 1; |
1234 | - } |
1235 | - } else |
1236 | - kp->clips = NULL; |
1237 | - return 0; |
1238 | -} |
1239 | - |
1240 | -static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) |
1241 | -{ |
1242 | - if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) || |
1243 | - put_user(kp->field, &up->field) || |
1244 | - put_user(kp->chromakey, &up->chromakey) || |
1245 | - put_user(kp->clipcount, &up->clipcount)) |
1246 | - return -EFAULT; |
1247 | - return 0; |
1248 | -} |
1249 | - |
1250 | -static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
1251 | -{ |
1252 | - if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) |
1253 | - return -EFAULT; |
1254 | - return 0; |
1255 | -} |
1256 | - |
1257 | -static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp, |
1258 | - struct v4l2_pix_format_mplane __user *up) |
1259 | -{ |
1260 | - if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane))) |
1261 | - return -EFAULT; |
1262 | - return 0; |
1263 | -} |
1264 | - |
1265 | -static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
1266 | -{ |
1267 | - if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) |
1268 | - return -EFAULT; |
1269 | - return 0; |
1270 | -} |
1271 | - |
1272 | -static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp, |
1273 | - struct v4l2_pix_format_mplane __user *up) |
1274 | +static int get_v4l2_window32(struct v4l2_window __user *kp, |
1275 | + struct v4l2_window32 __user *up, |
1276 | + void __user *aux_buf, u32 aux_space) |
1277 | { |
1278 | - if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane))) |
1279 | + struct v4l2_clip32 __user *uclips; |
1280 | + struct v4l2_clip __user *kclips; |
1281 | + compat_caddr_t p; |
1282 | + u32 clipcount; |
1283 | + |
1284 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
1285 | + copy_in_user(&kp->w, &up->w, sizeof(up->w)) || |
1286 | + assign_in_user(&kp->field, &up->field) || |
1287 | + assign_in_user(&kp->chromakey, &up->chromakey) || |
1288 | + assign_in_user(&kp->global_alpha, &up->global_alpha) || |
1289 | + get_user(clipcount, &up->clipcount) || |
1290 | + put_user(clipcount, &kp->clipcount)) |
1291 | return -EFAULT; |
1292 | - return 0; |
1293 | -} |
1294 | + if (clipcount > 2048) |
1295 | + return -EINVAL; |
1296 | + if (!clipcount) |
1297 | + return put_user(NULL, &kp->clips); |
1298 | |
1299 | -static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
1300 | -{ |
1301 | - if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) |
1302 | + if (get_user(p, &up->clips)) |
1303 | return -EFAULT; |
1304 | - return 0; |
1305 | -} |
1306 | - |
1307 | -static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
1308 | -{ |
1309 | - if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) |
1310 | + uclips = compat_ptr(p); |
1311 | + if (aux_space < clipcount * sizeof(*kclips)) |
1312 | return -EFAULT; |
1313 | - return 0; |
1314 | -} |
1315 | - |
1316 | -static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up) |
1317 | -{ |
1318 | - if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format))) |
1319 | + kclips = aux_buf; |
1320 | + if (put_user(kclips, &kp->clips)) |
1321 | return -EFAULT; |
1322 | - return 0; |
1323 | -} |
1324 | |
1325 | -static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up) |
1326 | -{ |
1327 | - if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format))) |
1328 | - return -EFAULT; |
1329 | + while (clipcount--) { |
1330 | + if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) |
1331 | + return -EFAULT; |
1332 | + if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next)) |
1333 | + return -EFAULT; |
1334 | + uclips++; |
1335 | + kclips++; |
1336 | + } |
1337 | return 0; |
1338 | } |
1339 | |
1340 | -static inline int get_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up) |
1341 | +static int put_v4l2_window32(struct v4l2_window __user *kp, |
1342 | + struct v4l2_window32 __user *up) |
1343 | { |
1344 | - if (copy_from_user(kp, up, sizeof(struct v4l2_sdr_format))) |
1345 | + struct v4l2_clip __user *kclips = kp->clips; |
1346 | + struct v4l2_clip32 __user *uclips; |
1347 | + compat_caddr_t p; |
1348 | + u32 clipcount; |
1349 | + |
1350 | + if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) || |
1351 | + assign_in_user(&up->field, &kp->field) || |
1352 | + assign_in_user(&up->chromakey, &kp->chromakey) || |
1353 | + assign_in_user(&up->global_alpha, &kp->global_alpha) || |
1354 | + get_user(clipcount, &kp->clipcount) || |
1355 | + put_user(clipcount, &up->clipcount)) |
1356 | return -EFAULT; |
1357 | - return 0; |
1358 | -} |
1359 | + if (!clipcount) |
1360 | + return 0; |
1361 | |
1362 | -static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up) |
1363 | -{ |
1364 | - if (copy_to_user(up, kp, sizeof(struct v4l2_sdr_format))) |
1365 | + if (get_user(p, &up->clips)) |
1366 | return -EFAULT; |
1367 | + uclips = compat_ptr(p); |
1368 | + while (clipcount--) { |
1369 | + if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c))) |
1370 | + return -EFAULT; |
1371 | + uclips++; |
1372 | + kclips++; |
1373 | + } |
1374 | return 0; |
1375 | } |
1376 | |
1377 | @@ -191,97 +158,158 @@ struct v4l2_create_buffers32 { |
1378 | __u32 reserved[8]; |
1379 | }; |
1380 | |
1381 | -static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) |
1382 | +static int __bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size) |
1383 | +{ |
1384 | + u32 type; |
1385 | + |
1386 | + if (get_user(type, &up->type)) |
1387 | + return -EFAULT; |
1388 | + |
1389 | + switch (type) { |
1390 | + case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1391 | + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: { |
1392 | + u32 clipcount; |
1393 | + |
1394 | + if (get_user(clipcount, &up->fmt.win.clipcount)) |
1395 | + return -EFAULT; |
1396 | + if (clipcount > 2048) |
1397 | + return -EINVAL; |
1398 | + *size = clipcount * sizeof(struct v4l2_clip); |
1399 | + return 0; |
1400 | + } |
1401 | + default: |
1402 | + *size = 0; |
1403 | + return 0; |
1404 | + } |
1405 | +} |
1406 | + |
1407 | +static int bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size) |
1408 | { |
1409 | - if (get_user(kp->type, &up->type)) |
1410 | + if (!access_ok(VERIFY_READ, up, sizeof(*up))) |
1411 | return -EFAULT; |
1412 | + return __bufsize_v4l2_format(up, size); |
1413 | +} |
1414 | |
1415 | - switch (kp->type) { |
1416 | +static int __get_v4l2_format32(struct v4l2_format __user *kp, |
1417 | + struct v4l2_format32 __user *up, |
1418 | + void __user *aux_buf, u32 aux_space) |
1419 | +{ |
1420 | + u32 type; |
1421 | + |
1422 | + if (get_user(type, &up->type) || put_user(type, &kp->type)) |
1423 | + return -EFAULT; |
1424 | + |
1425 | + switch (type) { |
1426 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1427 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1428 | - return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); |
1429 | + return copy_in_user(&kp->fmt.pix, &up->fmt.pix, |
1430 | + sizeof(kp->fmt.pix)) ? -EFAULT : 0; |
1431 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1432 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1433 | - return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp, |
1434 | - &up->fmt.pix_mp); |
1435 | + return copy_in_user(&kp->fmt.pix_mp, &up->fmt.pix_mp, |
1436 | + sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0; |
1437 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1438 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
1439 | - return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); |
1440 | + return get_v4l2_window32(&kp->fmt.win, &up->fmt.win, |
1441 | + aux_buf, aux_space); |
1442 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
1443 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
1444 | - return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); |
1445 | + return copy_in_user(&kp->fmt.vbi, &up->fmt.vbi, |
1446 | + sizeof(kp->fmt.vbi)) ? -EFAULT : 0; |
1447 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
1448 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
1449 | - return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced); |
1450 | + return copy_in_user(&kp->fmt.sliced, &up->fmt.sliced, |
1451 | + sizeof(kp->fmt.sliced)) ? -EFAULT : 0; |
1452 | case V4L2_BUF_TYPE_SDR_CAPTURE: |
1453 | case V4L2_BUF_TYPE_SDR_OUTPUT: |
1454 | - return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr); |
1455 | + return copy_in_user(&kp->fmt.sdr, &up->fmt.sdr, |
1456 | + sizeof(kp->fmt.sdr)) ? -EFAULT : 0; |
1457 | default: |
1458 | - pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n", |
1459 | - kp->type); |
1460 | return -EINVAL; |
1461 | } |
1462 | } |
1463 | |
1464 | -static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) |
1465 | +static int get_v4l2_format32(struct v4l2_format __user *kp, |
1466 | + struct v4l2_format32 __user *up, |
1467 | + void __user *aux_buf, u32 aux_space) |
1468 | { |
1469 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32))) |
1470 | + if (!access_ok(VERIFY_READ, up, sizeof(*up))) |
1471 | return -EFAULT; |
1472 | - return __get_v4l2_format32(kp, up); |
1473 | + return __get_v4l2_format32(kp, up, aux_buf, aux_space); |
1474 | } |
1475 | |
1476 | -static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up) |
1477 | +static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *up, |
1478 | + u32 *size) |
1479 | { |
1480 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) || |
1481 | - copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format))) |
1482 | + if (!access_ok(VERIFY_READ, up, sizeof(*up))) |
1483 | return -EFAULT; |
1484 | - return __get_v4l2_format32(&kp->format, &up->format); |
1485 | + return __bufsize_v4l2_format(&up->format, size); |
1486 | } |
1487 | |
1488 | -static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) |
1489 | +static int get_v4l2_create32(struct v4l2_create_buffers __user *kp, |
1490 | + struct v4l2_create_buffers32 __user *up, |
1491 | + void __user *aux_buf, u32 aux_space) |
1492 | { |
1493 | - if (put_user(kp->type, &up->type)) |
1494 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
1495 | + copy_in_user(kp, up, |
1496 | + offsetof(struct v4l2_create_buffers32, format))) |
1497 | return -EFAULT; |
1498 | + return __get_v4l2_format32(&kp->format, &up->format, |
1499 | + aux_buf, aux_space); |
1500 | +} |
1501 | + |
1502 | +static int __put_v4l2_format32(struct v4l2_format __user *kp, |
1503 | + struct v4l2_format32 __user *up) |
1504 | +{ |
1505 | + u32 type; |
1506 | |
1507 | - switch (kp->type) { |
1508 | + if (get_user(type, &kp->type)) |
1509 | + return -EFAULT; |
1510 | + |
1511 | + switch (type) { |
1512 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1513 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1514 | - return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); |
1515 | + return copy_in_user(&up->fmt.pix, &kp->fmt.pix, |
1516 | + sizeof(kp->fmt.pix)) ? -EFAULT : 0; |
1517 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1518 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1519 | - return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp, |
1520 | - &up->fmt.pix_mp); |
1521 | + return copy_in_user(&up->fmt.pix_mp, &kp->fmt.pix_mp, |
1522 | + sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0; |
1523 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1524 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
1525 | return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); |
1526 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
1527 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
1528 | - return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); |
1529 | + return copy_in_user(&up->fmt.vbi, &kp->fmt.vbi, |
1530 | + sizeof(kp->fmt.vbi)) ? -EFAULT : 0; |
1531 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
1532 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
1533 | - return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced); |
1534 | + return copy_in_user(&up->fmt.sliced, &kp->fmt.sliced, |
1535 | + sizeof(kp->fmt.sliced)) ? -EFAULT : 0; |
1536 | case V4L2_BUF_TYPE_SDR_CAPTURE: |
1537 | case V4L2_BUF_TYPE_SDR_OUTPUT: |
1538 | - return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr); |
1539 | + return copy_in_user(&up->fmt.sdr, &kp->fmt.sdr, |
1540 | + sizeof(kp->fmt.sdr)) ? -EFAULT : 0; |
1541 | default: |
1542 | - pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n", |
1543 | - kp->type); |
1544 | return -EINVAL; |
1545 | } |
1546 | } |
1547 | |
1548 | -static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) |
1549 | +static int put_v4l2_format32(struct v4l2_format __user *kp, |
1550 | + struct v4l2_format32 __user *up) |
1551 | { |
1552 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32))) |
1553 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) |
1554 | return -EFAULT; |
1555 | return __put_v4l2_format32(kp, up); |
1556 | } |
1557 | |
1558 | -static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up) |
1559 | +static int put_v4l2_create32(struct v4l2_create_buffers __user *kp, |
1560 | + struct v4l2_create_buffers32 __user *up) |
1561 | { |
1562 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) || |
1563 | - copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) || |
1564 | - copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved))) |
1565 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
1566 | + copy_in_user(up, kp, |
1567 | + offsetof(struct v4l2_create_buffers32, format)) || |
1568 | + copy_in_user(up->reserved, kp->reserved, sizeof(kp->reserved))) |
1569 | return -EFAULT; |
1570 | return __put_v4l2_format32(&kp->format, &up->format); |
1571 | } |
1572 | @@ -295,25 +323,28 @@ struct v4l2_standard32 { |
1573 | __u32 reserved[4]; |
1574 | }; |
1575 | |
1576 | -static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) |
1577 | +static int get_v4l2_standard32(struct v4l2_standard __user *kp, |
1578 | + struct v4l2_standard32 __user *up) |
1579 | { |
1580 | /* other fields are not set by the user, nor used by the driver */ |
1581 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) || |
1582 | - get_user(kp->index, &up->index)) |
1583 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
1584 | + assign_in_user(&kp->index, &up->index)) |
1585 | return -EFAULT; |
1586 | return 0; |
1587 | } |
1588 | |
1589 | -static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) |
1590 | +static int put_v4l2_standard32(struct v4l2_standard __user *kp, |
1591 | + struct v4l2_standard32 __user *up) |
1592 | { |
1593 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) || |
1594 | - put_user(kp->index, &up->index) || |
1595 | - put_user(kp->id, &up->id) || |
1596 | - copy_to_user(up->name, kp->name, 24) || |
1597 | - copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) || |
1598 | - put_user(kp->framelines, &up->framelines) || |
1599 | - copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32))) |
1600 | - return -EFAULT; |
1601 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
1602 | + assign_in_user(&up->index, &kp->index) || |
1603 | + assign_in_user(&up->id, &kp->id) || |
1604 | + copy_in_user(up->name, kp->name, sizeof(up->name)) || |
1605 | + copy_in_user(&up->frameperiod, &kp->frameperiod, |
1606 | + sizeof(up->frameperiod)) || |
1607 | + assign_in_user(&up->framelines, &kp->framelines) || |
1608 | + copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved))) |
1609 | + return -EFAULT; |
1610 | return 0; |
1611 | } |
1612 | |
1613 | @@ -352,134 +383,186 @@ struct v4l2_buffer32 { |
1614 | __u32 reserved; |
1615 | }; |
1616 | |
1617 | -static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32, |
1618 | - enum v4l2_memory memory) |
1619 | +static int get_v4l2_plane32(struct v4l2_plane __user *up, |
1620 | + struct v4l2_plane32 __user *up32, |
1621 | + enum v4l2_memory memory) |
1622 | { |
1623 | - void __user *up_pln; |
1624 | - compat_long_t p; |
1625 | + compat_ulong_t p; |
1626 | |
1627 | if (copy_in_user(up, up32, 2 * sizeof(__u32)) || |
1628 | - copy_in_user(&up->data_offset, &up32->data_offset, |
1629 | - sizeof(__u32))) |
1630 | + copy_in_user(&up->data_offset, &up32->data_offset, |
1631 | + sizeof(up->data_offset))) |
1632 | return -EFAULT; |
1633 | |
1634 | - if (memory == V4L2_MEMORY_USERPTR) { |
1635 | - if (get_user(p, &up32->m.userptr)) |
1636 | - return -EFAULT; |
1637 | - up_pln = compat_ptr(p); |
1638 | - if (put_user((unsigned long)up_pln, &up->m.userptr)) |
1639 | + switch (memory) { |
1640 | + case V4L2_MEMORY_MMAP: |
1641 | + case V4L2_MEMORY_OVERLAY: |
1642 | + if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset, |
1643 | + sizeof(up32->m.mem_offset))) |
1644 | return -EFAULT; |
1645 | - } else if (memory == V4L2_MEMORY_DMABUF) { |
1646 | - if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int))) |
1647 | + break; |
1648 | + case V4L2_MEMORY_USERPTR: |
1649 | + if (get_user(p, &up32->m.userptr) || |
1650 | + put_user((unsigned long)compat_ptr(p), &up->m.userptr)) |
1651 | return -EFAULT; |
1652 | - } else { |
1653 | - if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset, |
1654 | - sizeof(__u32))) |
1655 | + break; |
1656 | + case V4L2_MEMORY_DMABUF: |
1657 | + if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(up32->m.fd))) |
1658 | return -EFAULT; |
1659 | + break; |
1660 | } |
1661 | |
1662 | return 0; |
1663 | } |
1664 | |
1665 | -static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32, |
1666 | - enum v4l2_memory memory) |
1667 | +static int put_v4l2_plane32(struct v4l2_plane __user *up, |
1668 | + struct v4l2_plane32 __user *up32, |
1669 | + enum v4l2_memory memory) |
1670 | { |
1671 | + unsigned long p; |
1672 | + |
1673 | if (copy_in_user(up32, up, 2 * sizeof(__u32)) || |
1674 | - copy_in_user(&up32->data_offset, &up->data_offset, |
1675 | - sizeof(__u32))) |
1676 | + copy_in_user(&up32->data_offset, &up->data_offset, |
1677 | + sizeof(up->data_offset))) |
1678 | return -EFAULT; |
1679 | |
1680 | - /* For MMAP, driver might've set up the offset, so copy it back. |
1681 | - * USERPTR stays the same (was userspace-provided), so no copying. */ |
1682 | - if (memory == V4L2_MEMORY_MMAP) |
1683 | + switch (memory) { |
1684 | + case V4L2_MEMORY_MMAP: |
1685 | + case V4L2_MEMORY_OVERLAY: |
1686 | if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset, |
1687 | - sizeof(__u32))) |
1688 | + sizeof(up->m.mem_offset))) |
1689 | return -EFAULT; |
1690 | - /* For DMABUF, driver might've set up the fd, so copy it back. */ |
1691 | - if (memory == V4L2_MEMORY_DMABUF) |
1692 | - if (copy_in_user(&up32->m.fd, &up->m.fd, |
1693 | - sizeof(int))) |
1694 | + break; |
1695 | + case V4L2_MEMORY_USERPTR: |
1696 | + if (get_user(p, &up->m.userptr) || |
1697 | + put_user((compat_ulong_t)ptr_to_compat((__force void *)p), |
1698 | + &up32->m.userptr)) |
1699 | + return -EFAULT; |
1700 | + break; |
1701 | + case V4L2_MEMORY_DMABUF: |
1702 | + if (copy_in_user(&up32->m.fd, &up->m.fd, sizeof(up->m.fd))) |
1703 | return -EFAULT; |
1704 | + break; |
1705 | + } |
1706 | |
1707 | return 0; |
1708 | } |
1709 | |
1710 | -static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) |
1711 | +static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *up, u32 *size) |
1712 | { |
1713 | + u32 type; |
1714 | + u32 length; |
1715 | + |
1716 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
1717 | + get_user(type, &up->type) || |
1718 | + get_user(length, &up->length)) |
1719 | + return -EFAULT; |
1720 | + |
1721 | + if (V4L2_TYPE_IS_MULTIPLANAR(type)) { |
1722 | + if (length > VIDEO_MAX_PLANES) |
1723 | + return -EINVAL; |
1724 | + |
1725 | + /* |
1726 | + * We don't really care if userspace decides to kill itself |
1727 | + * by passing a very big length value |
1728 | + */ |
1729 | + *size = length * sizeof(struct v4l2_plane); |
1730 | + } else { |
1731 | + *size = 0; |
1732 | + } |
1733 | + return 0; |
1734 | +} |
1735 | + |
1736 | +static int get_v4l2_buffer32(struct v4l2_buffer __user *kp, |
1737 | + struct v4l2_buffer32 __user *up, |
1738 | + void __user *aux_buf, u32 aux_space) |
1739 | +{ |
1740 | + u32 type; |
1741 | + u32 length; |
1742 | + enum v4l2_memory memory; |
1743 | struct v4l2_plane32 __user *uplane32; |
1744 | struct v4l2_plane __user *uplane; |
1745 | compat_caddr_t p; |
1746 | - int num_planes; |
1747 | int ret; |
1748 | |
1749 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) || |
1750 | - get_user(kp->index, &up->index) || |
1751 | - get_user(kp->type, &up->type) || |
1752 | - get_user(kp->flags, &up->flags) || |
1753 | - get_user(kp->memory, &up->memory) || |
1754 | - get_user(kp->length, &up->length)) |
1755 | - return -EFAULT; |
1756 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
1757 | + assign_in_user(&kp->index, &up->index) || |
1758 | + get_user(type, &up->type) || |
1759 | + put_user(type, &kp->type) || |
1760 | + assign_in_user(&kp->flags, &up->flags) || |
1761 | + get_user(memory, &up->memory) || |
1762 | + put_user(memory, &kp->memory) || |
1763 | + get_user(length, &up->length) || |
1764 | + put_user(length, &kp->length)) |
1765 | + return -EFAULT; |
1766 | |
1767 | - if (V4L2_TYPE_IS_OUTPUT(kp->type)) |
1768 | - if (get_user(kp->bytesused, &up->bytesused) || |
1769 | - get_user(kp->field, &up->field) || |
1770 | - get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || |
1771 | - get_user(kp->timestamp.tv_usec, |
1772 | - &up->timestamp.tv_usec)) |
1773 | + if (V4L2_TYPE_IS_OUTPUT(type)) |
1774 | + if (assign_in_user(&kp->bytesused, &up->bytesused) || |
1775 | + assign_in_user(&kp->field, &up->field) || |
1776 | + assign_in_user(&kp->timestamp.tv_sec, |
1777 | + &up->timestamp.tv_sec) || |
1778 | + assign_in_user(&kp->timestamp.tv_usec, |
1779 | + &up->timestamp.tv_usec)) |
1780 | return -EFAULT; |
1781 | |
1782 | - if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) { |
1783 | - num_planes = kp->length; |
1784 | + if (V4L2_TYPE_IS_MULTIPLANAR(type)) { |
1785 | + u32 num_planes = length; |
1786 | + |
1787 | if (num_planes == 0) { |
1788 | - kp->m.planes = NULL; |
1789 | - /* num_planes == 0 is legal, e.g. when userspace doesn't |
1790 | - * need planes array on DQBUF*/ |
1791 | - return 0; |
1792 | + /* |
1793 | + * num_planes == 0 is legal, e.g. when userspace doesn't |
1794 | + * need planes array on DQBUF |
1795 | + */ |
1796 | + return put_user(NULL, &kp->m.planes); |
1797 | } |
1798 | + if (num_planes > VIDEO_MAX_PLANES) |
1799 | + return -EINVAL; |
1800 | |
1801 | if (get_user(p, &up->m.planes)) |
1802 | return -EFAULT; |
1803 | |
1804 | uplane32 = compat_ptr(p); |
1805 | if (!access_ok(VERIFY_READ, uplane32, |
1806 | - num_planes * sizeof(struct v4l2_plane32))) |
1807 | + num_planes * sizeof(*uplane32))) |
1808 | return -EFAULT; |
1809 | |
1810 | - /* We don't really care if userspace decides to kill itself |
1811 | - * by passing a very big num_planes value */ |
1812 | - uplane = compat_alloc_user_space(num_planes * |
1813 | - sizeof(struct v4l2_plane)); |
1814 | - kp->m.planes = (__force struct v4l2_plane *)uplane; |
1815 | + /* |
1816 | + * We don't really care if userspace decides to kill itself |
1817 | + * by passing a very big num_planes value |
1818 | + */ |
1819 | + if (aux_space < num_planes * sizeof(*uplane)) |
1820 | + return -EFAULT; |
1821 | + |
1822 | + uplane = aux_buf; |
1823 | + if (put_user((__force struct v4l2_plane *)uplane, |
1824 | + &kp->m.planes)) |
1825 | + return -EFAULT; |
1826 | |
1827 | - while (--num_planes >= 0) { |
1828 | - ret = get_v4l2_plane32(uplane, uplane32, kp->memory); |
1829 | + while (num_planes--) { |
1830 | + ret = get_v4l2_plane32(uplane, uplane32, memory); |
1831 | if (ret) |
1832 | return ret; |
1833 | - ++uplane; |
1834 | - ++uplane32; |
1835 | + uplane++; |
1836 | + uplane32++; |
1837 | } |
1838 | } else { |
1839 | - switch (kp->memory) { |
1840 | + switch (memory) { |
1841 | case V4L2_MEMORY_MMAP: |
1842 | - if (get_user(kp->m.offset, &up->m.offset)) |
1843 | + case V4L2_MEMORY_OVERLAY: |
1844 | + if (assign_in_user(&kp->m.offset, &up->m.offset)) |
1845 | return -EFAULT; |
1846 | break; |
1847 | - case V4L2_MEMORY_USERPTR: |
1848 | - { |
1849 | - compat_long_t tmp; |
1850 | + case V4L2_MEMORY_USERPTR: { |
1851 | + compat_ulong_t userptr; |
1852 | |
1853 | - if (get_user(tmp, &up->m.userptr)) |
1854 | - return -EFAULT; |
1855 | - |
1856 | - kp->m.userptr = (unsigned long)compat_ptr(tmp); |
1857 | - } |
1858 | - break; |
1859 | - case V4L2_MEMORY_OVERLAY: |
1860 | - if (get_user(kp->m.offset, &up->m.offset)) |
1861 | + if (get_user(userptr, &up->m.userptr) || |
1862 | + put_user((unsigned long)compat_ptr(userptr), |
1863 | + &kp->m.userptr)) |
1864 | return -EFAULT; |
1865 | break; |
1866 | + } |
1867 | case V4L2_MEMORY_DMABUF: |
1868 | - if (get_user(kp->m.fd, &up->m.fd)) |
1869 | + if (assign_in_user(&kp->m.fd, &up->m.fd)) |
1870 | return -EFAULT; |
1871 | break; |
1872 | } |
1873 | @@ -488,65 +571,70 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user |
1874 | return 0; |
1875 | } |
1876 | |
1877 | -static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) |
1878 | +static int put_v4l2_buffer32(struct v4l2_buffer __user *kp, |
1879 | + struct v4l2_buffer32 __user *up) |
1880 | { |
1881 | + u32 type; |
1882 | + u32 length; |
1883 | + enum v4l2_memory memory; |
1884 | struct v4l2_plane32 __user *uplane32; |
1885 | struct v4l2_plane __user *uplane; |
1886 | compat_caddr_t p; |
1887 | - int num_planes; |
1888 | int ret; |
1889 | |
1890 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) || |
1891 | - put_user(kp->index, &up->index) || |
1892 | - put_user(kp->type, &up->type) || |
1893 | - put_user(kp->flags, &up->flags) || |
1894 | - put_user(kp->memory, &up->memory)) |
1895 | - return -EFAULT; |
1896 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
1897 | + assign_in_user(&up->index, &kp->index) || |
1898 | + get_user(type, &kp->type) || |
1899 | + put_user(type, &up->type) || |
1900 | + assign_in_user(&up->flags, &kp->flags) || |
1901 | + get_user(memory, &kp->memory) || |
1902 | + put_user(memory, &up->memory)) |
1903 | + return -EFAULT; |
1904 | |
1905 | - if (put_user(kp->bytesused, &up->bytesused) || |
1906 | - put_user(kp->field, &up->field) || |
1907 | - put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || |
1908 | - put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) || |
1909 | - copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) || |
1910 | - put_user(kp->sequence, &up->sequence) || |
1911 | - put_user(kp->reserved2, &up->reserved2) || |
1912 | - put_user(kp->reserved, &up->reserved) || |
1913 | - put_user(kp->length, &up->length)) |
1914 | - return -EFAULT; |
1915 | + if (assign_in_user(&up->bytesused, &kp->bytesused) || |
1916 | + assign_in_user(&up->field, &kp->field) || |
1917 | + assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) || |
1918 | + assign_in_user(&up->timestamp.tv_usec, &kp->timestamp.tv_usec) || |
1919 | + copy_in_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) || |
1920 | + assign_in_user(&up->sequence, &kp->sequence) || |
1921 | + assign_in_user(&up->reserved2, &kp->reserved2) || |
1922 | + assign_in_user(&up->reserved, &kp->reserved) || |
1923 | + get_user(length, &kp->length) || |
1924 | + put_user(length, &up->length)) |
1925 | + return -EFAULT; |
1926 | + |
1927 | + if (V4L2_TYPE_IS_MULTIPLANAR(type)) { |
1928 | + u32 num_planes = length; |
1929 | |
1930 | - if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) { |
1931 | - num_planes = kp->length; |
1932 | if (num_planes == 0) |
1933 | return 0; |
1934 | |
1935 | - uplane = (__force struct v4l2_plane __user *)kp->m.planes; |
1936 | + if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes))) |
1937 | + return -EFAULT; |
1938 | if (get_user(p, &up->m.planes)) |
1939 | return -EFAULT; |
1940 | uplane32 = compat_ptr(p); |
1941 | |
1942 | - while (--num_planes >= 0) { |
1943 | - ret = put_v4l2_plane32(uplane, uplane32, kp->memory); |
1944 | + while (num_planes--) { |
1945 | + ret = put_v4l2_plane32(uplane, uplane32, memory); |
1946 | if (ret) |
1947 | return ret; |
1948 | ++uplane; |
1949 | ++uplane32; |
1950 | } |
1951 | } else { |
1952 | - switch (kp->memory) { |
1953 | + switch (memory) { |
1954 | case V4L2_MEMORY_MMAP: |
1955 | - if (put_user(kp->m.offset, &up->m.offset)) |
1956 | + case V4L2_MEMORY_OVERLAY: |
1957 | + if (assign_in_user(&up->m.offset, &kp->m.offset)) |
1958 | return -EFAULT; |
1959 | break; |
1960 | case V4L2_MEMORY_USERPTR: |
1961 | - if (put_user(kp->m.userptr, &up->m.userptr)) |
1962 | - return -EFAULT; |
1963 | - break; |
1964 | - case V4L2_MEMORY_OVERLAY: |
1965 | - if (put_user(kp->m.offset, &up->m.offset)) |
1966 | + if (assign_in_user(&up->m.userptr, &kp->m.userptr)) |
1967 | return -EFAULT; |
1968 | break; |
1969 | case V4L2_MEMORY_DMABUF: |
1970 | - if (put_user(kp->m.fd, &up->m.fd)) |
1971 | + if (assign_in_user(&up->m.fd, &kp->m.fd)) |
1972 | return -EFAULT; |
1973 | break; |
1974 | } |
1975 | @@ -558,7 +646,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user |
1976 | struct v4l2_framebuffer32 { |
1977 | __u32 capability; |
1978 | __u32 flags; |
1979 | - compat_caddr_t base; |
1980 | + compat_caddr_t base; |
1981 | struct { |
1982 | __u32 width; |
1983 | __u32 height; |
1984 | @@ -571,30 +659,33 @@ struct v4l2_framebuffer32 { |
1985 | } fmt; |
1986 | }; |
1987 | |
1988 | -static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) |
1989 | +static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp, |
1990 | + struct v4l2_framebuffer32 __user *up) |
1991 | { |
1992 | - u32 tmp; |
1993 | - |
1994 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) || |
1995 | - get_user(tmp, &up->base) || |
1996 | - get_user(kp->capability, &up->capability) || |
1997 | - get_user(kp->flags, &up->flags) || |
1998 | - copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt))) |
1999 | - return -EFAULT; |
2000 | - kp->base = (__force void *)compat_ptr(tmp); |
2001 | + compat_caddr_t tmp; |
2002 | + |
2003 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
2004 | + get_user(tmp, &up->base) || |
2005 | + put_user((__force void *)compat_ptr(tmp), &kp->base) || |
2006 | + assign_in_user(&kp->capability, &up->capability) || |
2007 | + assign_in_user(&kp->flags, &up->flags) || |
2008 | + copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt))) |
2009 | + return -EFAULT; |
2010 | return 0; |
2011 | } |
2012 | |
2013 | -static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) |
2014 | +static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp, |
2015 | + struct v4l2_framebuffer32 __user *up) |
2016 | { |
2017 | - u32 tmp = (u32)((unsigned long)kp->base); |
2018 | - |
2019 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) || |
2020 | - put_user(tmp, &up->base) || |
2021 | - put_user(kp->capability, &up->capability) || |
2022 | - put_user(kp->flags, &up->flags) || |
2023 | - copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt))) |
2024 | - return -EFAULT; |
2025 | + void *base; |
2026 | + |
2027 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
2028 | + get_user(base, &kp->base) || |
2029 | + put_user(ptr_to_compat(base), &up->base) || |
2030 | + assign_in_user(&up->capability, &kp->capability) || |
2031 | + assign_in_user(&up->flags, &kp->flags) || |
2032 | + copy_in_user(&up->fmt, &kp->fmt, sizeof(kp->fmt))) |
2033 | + return -EFAULT; |
2034 | return 0; |
2035 | } |
2036 | |
2037 | @@ -606,21 +697,26 @@ struct v4l2_input32 { |
2038 | __u32 tuner; /* Associated tuner */ |
2039 | compat_u64 std; |
2040 | __u32 status; |
2041 | - __u32 reserved[4]; |
2042 | + __u32 capabilities; |
2043 | + __u32 reserved[3]; |
2044 | }; |
2045 | |
2046 | -/* The 64-bit v4l2_input struct has extra padding at the end of the struct. |
2047 | - Otherwise it is identical to the 32-bit version. */ |
2048 | -static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up) |
2049 | +/* |
2050 | + * The 64-bit v4l2_input struct has extra padding at the end of the struct. |
2051 | + * Otherwise it is identical to the 32-bit version. |
2052 | + */ |
2053 | +static inline int get_v4l2_input32(struct v4l2_input __user *kp, |
2054 | + struct v4l2_input32 __user *up) |
2055 | { |
2056 | - if (copy_from_user(kp, up, sizeof(struct v4l2_input32))) |
2057 | + if (copy_in_user(kp, up, sizeof(*up))) |
2058 | return -EFAULT; |
2059 | return 0; |
2060 | } |
2061 | |
2062 | -static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up) |
2063 | +static inline int put_v4l2_input32(struct v4l2_input __user *kp, |
2064 | + struct v4l2_input32 __user *up) |
2065 | { |
2066 | - if (copy_to_user(up, kp, sizeof(struct v4l2_input32))) |
2067 | + if (copy_in_user(up, kp, sizeof(*up))) |
2068 | return -EFAULT; |
2069 | return 0; |
2070 | } |
2071 | @@ -644,58 +740,95 @@ struct v4l2_ext_control32 { |
2072 | }; |
2073 | } __attribute__ ((packed)); |
2074 | |
2075 | -/* The following function really belong in v4l2-common, but that causes |
2076 | - a circular dependency between modules. We need to think about this, but |
2077 | - for now this will do. */ |
2078 | - |
2079 | -/* Return non-zero if this control is a pointer type. Currently only |
2080 | - type STRING is a pointer type. */ |
2081 | -static inline int ctrl_is_pointer(u32 id) |
2082 | +/* Return true if this control is a pointer type. */ |
2083 | +static inline bool ctrl_is_pointer(struct file *file, u32 id) |
2084 | { |
2085 | - switch (id) { |
2086 | - case V4L2_CID_RDS_TX_PS_NAME: |
2087 | - case V4L2_CID_RDS_TX_RADIO_TEXT: |
2088 | - return 1; |
2089 | - default: |
2090 | - return 0; |
2091 | + struct video_device *vdev = video_devdata(file); |
2092 | + struct v4l2_fh *fh = NULL; |
2093 | + struct v4l2_ctrl_handler *hdl = NULL; |
2094 | + struct v4l2_query_ext_ctrl qec = { id }; |
2095 | + const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; |
2096 | + |
2097 | + if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) |
2098 | + fh = file->private_data; |
2099 | + |
2100 | + if (fh && fh->ctrl_handler) |
2101 | + hdl = fh->ctrl_handler; |
2102 | + else if (vdev->ctrl_handler) |
2103 | + hdl = vdev->ctrl_handler; |
2104 | + |
2105 | + if (hdl) { |
2106 | + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id); |
2107 | + |
2108 | + return ctrl && ctrl->is_ptr; |
2109 | } |
2110 | + |
2111 | + if (!ops || !ops->vidioc_query_ext_ctrl) |
2112 | + return false; |
2113 | + |
2114 | + return !ops->vidioc_query_ext_ctrl(file, fh, &qec) && |
2115 | + (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD); |
2116 | +} |
2117 | + |
2118 | +static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *up, |
2119 | + u32 *size) |
2120 | +{ |
2121 | + u32 count; |
2122 | + |
2123 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
2124 | + get_user(count, &up->count)) |
2125 | + return -EFAULT; |
2126 | + if (count > V4L2_CID_MAX_CTRLS) |
2127 | + return -EINVAL; |
2128 | + *size = count * sizeof(struct v4l2_ext_control); |
2129 | + return 0; |
2130 | } |
2131 | |
2132 | -static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) |
2133 | +static int get_v4l2_ext_controls32(struct file *file, |
2134 | + struct v4l2_ext_controls __user *kp, |
2135 | + struct v4l2_ext_controls32 __user *up, |
2136 | + void __user *aux_buf, u32 aux_space) |
2137 | { |
2138 | struct v4l2_ext_control32 __user *ucontrols; |
2139 | struct v4l2_ext_control __user *kcontrols; |
2140 | - int n; |
2141 | + u32 count; |
2142 | + u32 n; |
2143 | compat_caddr_t p; |
2144 | |
2145 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) || |
2146 | - get_user(kp->which, &up->which) || |
2147 | - get_user(kp->count, &up->count) || |
2148 | - get_user(kp->error_idx, &up->error_idx) || |
2149 | - copy_from_user(kp->reserved, up->reserved, |
2150 | - sizeof(kp->reserved))) |
2151 | - return -EFAULT; |
2152 | - n = kp->count; |
2153 | - if (n == 0) { |
2154 | - kp->controls = NULL; |
2155 | - return 0; |
2156 | - } |
2157 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
2158 | + assign_in_user(&kp->which, &up->which) || |
2159 | + get_user(count, &up->count) || |
2160 | + put_user(count, &kp->count) || |
2161 | + assign_in_user(&kp->error_idx, &up->error_idx) || |
2162 | + copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved))) |
2163 | + return -EFAULT; |
2164 | + |
2165 | + if (count == 0) |
2166 | + return put_user(NULL, &kp->controls); |
2167 | + if (count > V4L2_CID_MAX_CTRLS) |
2168 | + return -EINVAL; |
2169 | if (get_user(p, &up->controls)) |
2170 | return -EFAULT; |
2171 | ucontrols = compat_ptr(p); |
2172 | - if (!access_ok(VERIFY_READ, ucontrols, |
2173 | - n * sizeof(struct v4l2_ext_control32))) |
2174 | + if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols))) |
2175 | + return -EFAULT; |
2176 | + if (aux_space < count * sizeof(*kcontrols)) |
2177 | return -EFAULT; |
2178 | - kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control)); |
2179 | - kp->controls = (__force struct v4l2_ext_control *)kcontrols; |
2180 | - while (--n >= 0) { |
2181 | + kcontrols = aux_buf; |
2182 | + if (put_user((__force struct v4l2_ext_control *)kcontrols, |
2183 | + &kp->controls)) |
2184 | + return -EFAULT; |
2185 | + |
2186 | + for (n = 0; n < count; n++) { |
2187 | u32 id; |
2188 | |
2189 | if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols))) |
2190 | return -EFAULT; |
2191 | + |
2192 | if (get_user(id, &kcontrols->id)) |
2193 | return -EFAULT; |
2194 | - if (ctrl_is_pointer(id)) { |
2195 | + |
2196 | + if (ctrl_is_pointer(file, id)) { |
2197 | void __user *s; |
2198 | |
2199 | if (get_user(p, &ucontrols->string)) |
2200 | @@ -710,43 +843,55 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext |
2201 | return 0; |
2202 | } |
2203 | |
2204 | -static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) |
2205 | +static int put_v4l2_ext_controls32(struct file *file, |
2206 | + struct v4l2_ext_controls __user *kp, |
2207 | + struct v4l2_ext_controls32 __user *up) |
2208 | { |
2209 | struct v4l2_ext_control32 __user *ucontrols; |
2210 | - struct v4l2_ext_control __user *kcontrols = |
2211 | - (__force struct v4l2_ext_control __user *)kp->controls; |
2212 | - int n = kp->count; |
2213 | + struct v4l2_ext_control __user *kcontrols; |
2214 | + u32 count; |
2215 | + u32 n; |
2216 | compat_caddr_t p; |
2217 | |
2218 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) || |
2219 | - put_user(kp->which, &up->which) || |
2220 | - put_user(kp->count, &up->count) || |
2221 | - put_user(kp->error_idx, &up->error_idx) || |
2222 | - copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved))) |
2223 | - return -EFAULT; |
2224 | - if (!kp->count) |
2225 | - return 0; |
2226 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
2227 | + assign_in_user(&up->which, &kp->which) || |
2228 | + get_user(count, &kp->count) || |
2229 | + put_user(count, &up->count) || |
2230 | + assign_in_user(&up->error_idx, &kp->error_idx) || |
2231 | + copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) || |
2232 | + get_user(kcontrols, &kp->controls)) |
2233 | + return -EFAULT; |
2234 | |
2235 | + if (!count) |
2236 | + return 0; |
2237 | if (get_user(p, &up->controls)) |
2238 | return -EFAULT; |
2239 | ucontrols = compat_ptr(p); |
2240 | - if (!access_ok(VERIFY_WRITE, ucontrols, |
2241 | - n * sizeof(struct v4l2_ext_control32))) |
2242 | + if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols))) |
2243 | return -EFAULT; |
2244 | |
2245 | - while (--n >= 0) { |
2246 | - unsigned size = sizeof(*ucontrols); |
2247 | + for (n = 0; n < count; n++) { |
2248 | + unsigned int size = sizeof(*ucontrols); |
2249 | u32 id; |
2250 | |
2251 | - if (get_user(id, &kcontrols->id)) |
2252 | + if (get_user(id, &kcontrols->id) || |
2253 | + put_user(id, &ucontrols->id) || |
2254 | + assign_in_user(&ucontrols->size, &kcontrols->size) || |
2255 | + copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2, |
2256 | + sizeof(ucontrols->reserved2))) |
2257 | return -EFAULT; |
2258 | - /* Do not modify the pointer when copying a pointer control. |
2259 | - The contents of the pointer was changed, not the pointer |
2260 | - itself. */ |
2261 | - if (ctrl_is_pointer(id)) |
2262 | + |
2263 | + /* |
2264 | + * Do not modify the pointer when copying a pointer control. |
2265 | + * The contents of the pointer was changed, not the pointer |
2266 | + * itself. |
2267 | + */ |
2268 | + if (ctrl_is_pointer(file, id)) |
2269 | size -= sizeof(ucontrols->value64); |
2270 | + |
2271 | if (copy_in_user(ucontrols, kcontrols, size)) |
2272 | return -EFAULT; |
2273 | + |
2274 | ucontrols++; |
2275 | kcontrols++; |
2276 | } |
2277 | @@ -766,18 +911,19 @@ struct v4l2_event32 { |
2278 | __u32 reserved[8]; |
2279 | }; |
2280 | |
2281 | -static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up) |
2282 | +static int put_v4l2_event32(struct v4l2_event __user *kp, |
2283 | + struct v4l2_event32 __user *up) |
2284 | { |
2285 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) || |
2286 | - put_user(kp->type, &up->type) || |
2287 | - copy_to_user(&up->u, &kp->u, sizeof(kp->u)) || |
2288 | - put_user(kp->pending, &up->pending) || |
2289 | - put_user(kp->sequence, &up->sequence) || |
2290 | - put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || |
2291 | - put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) || |
2292 | - put_user(kp->id, &up->id) || |
2293 | - copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32))) |
2294 | - return -EFAULT; |
2295 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
2296 | + assign_in_user(&up->type, &kp->type) || |
2297 | + copy_in_user(&up->u, &kp->u, sizeof(kp->u)) || |
2298 | + assign_in_user(&up->pending, &kp->pending) || |
2299 | + assign_in_user(&up->sequence, &kp->sequence) || |
2300 | + assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) || |
2301 | + assign_in_user(&up->timestamp.tv_nsec, &kp->timestamp.tv_nsec) || |
2302 | + assign_in_user(&up->id, &kp->id) || |
2303 | + copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved))) |
2304 | + return -EFAULT; |
2305 | return 0; |
2306 | } |
2307 | |
2308 | @@ -789,32 +935,35 @@ struct v4l2_edid32 { |
2309 | compat_caddr_t edid; |
2310 | }; |
2311 | |
2312 | -static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up) |
2313 | +static int get_v4l2_edid32(struct v4l2_edid __user *kp, |
2314 | + struct v4l2_edid32 __user *up) |
2315 | { |
2316 | - u32 tmp; |
2317 | - |
2318 | - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) || |
2319 | - get_user(kp->pad, &up->pad) || |
2320 | - get_user(kp->start_block, &up->start_block) || |
2321 | - get_user(kp->blocks, &up->blocks) || |
2322 | - get_user(tmp, &up->edid) || |
2323 | - copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved))) |
2324 | - return -EFAULT; |
2325 | - kp->edid = (__force u8 *)compat_ptr(tmp); |
2326 | + compat_uptr_t tmp; |
2327 | + |
2328 | + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || |
2329 | + assign_in_user(&kp->pad, &up->pad) || |
2330 | + assign_in_user(&kp->start_block, &up->start_block) || |
2331 | + assign_in_user(&kp->blocks, &up->blocks) || |
2332 | + get_user(tmp, &up->edid) || |
2333 | + put_user(compat_ptr(tmp), &kp->edid) || |
2334 | + copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved))) |
2335 | + return -EFAULT; |
2336 | return 0; |
2337 | } |
2338 | |
2339 | -static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up) |
2340 | +static int put_v4l2_edid32(struct v4l2_edid __user *kp, |
2341 | + struct v4l2_edid32 __user *up) |
2342 | { |
2343 | - u32 tmp = (u32)((unsigned long)kp->edid); |
2344 | - |
2345 | - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) || |
2346 | - put_user(kp->pad, &up->pad) || |
2347 | - put_user(kp->start_block, &up->start_block) || |
2348 | - put_user(kp->blocks, &up->blocks) || |
2349 | - put_user(tmp, &up->edid) || |
2350 | - copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved))) |
2351 | - return -EFAULT; |
2352 | + void *edid; |
2353 | + |
2354 | + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || |
2355 | + assign_in_user(&up->pad, &kp->pad) || |
2356 | + assign_in_user(&up->start_block, &kp->start_block) || |
2357 | + assign_in_user(&up->blocks, &kp->blocks) || |
2358 | + get_user(edid, &kp->edid) || |
2359 | + put_user(ptr_to_compat(edid), &up->edid) || |
2360 | + copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved))) |
2361 | + return -EFAULT; |
2362 | return 0; |
2363 | } |
2364 | |
2365 | @@ -830,7 +979,7 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up) |
2366 | #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) |
2367 | #define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32) |
2368 | #define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32) |
2369 | -#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) |
2370 | +#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) |
2371 | #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) |
2372 | #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) |
2373 | #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) |
2374 | @@ -846,22 +995,23 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up) |
2375 | #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) |
2376 | #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) |
2377 | |
2378 | +static int alloc_userspace(unsigned int size, u32 aux_space, |
2379 | + void __user **up_native) |
2380 | +{ |
2381 | + *up_native = compat_alloc_user_space(size + aux_space); |
2382 | + if (!*up_native) |
2383 | + return -ENOMEM; |
2384 | + if (clear_user(*up_native, size)) |
2385 | + return -EFAULT; |
2386 | + return 0; |
2387 | +} |
2388 | + |
2389 | static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2390 | { |
2391 | - union { |
2392 | - struct v4l2_format v2f; |
2393 | - struct v4l2_buffer v2b; |
2394 | - struct v4l2_framebuffer v2fb; |
2395 | - struct v4l2_input v2i; |
2396 | - struct v4l2_standard v2s; |
2397 | - struct v4l2_ext_controls v2ecs; |
2398 | - struct v4l2_event v2ev; |
2399 | - struct v4l2_create_buffers v2crt; |
2400 | - struct v4l2_edid v2edid; |
2401 | - unsigned long vx; |
2402 | - int vi; |
2403 | - } karg; |
2404 | void __user *up = compat_ptr(arg); |
2405 | + void __user *up_native = NULL; |
2406 | + void __user *aux_buf; |
2407 | + u32 aux_space; |
2408 | int compatible_arg = 1; |
2409 | long err = 0; |
2410 | |
2411 | @@ -900,30 +1050,52 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar |
2412 | case VIDIOC_STREAMOFF: |
2413 | case VIDIOC_S_INPUT: |
2414 | case VIDIOC_S_OUTPUT: |
2415 | - err = get_user(karg.vi, (s32 __user *)up); |
2416 | + err = alloc_userspace(sizeof(unsigned int), 0, &up_native); |
2417 | + if (!err && assign_in_user((unsigned int __user *)up_native, |
2418 | + (compat_uint_t __user *)up)) |
2419 | + err = -EFAULT; |
2420 | compatible_arg = 0; |
2421 | break; |
2422 | |
2423 | case VIDIOC_G_INPUT: |
2424 | case VIDIOC_G_OUTPUT: |
2425 | + err = alloc_userspace(sizeof(unsigned int), 0, &up_native); |
2426 | compatible_arg = 0; |
2427 | break; |
2428 | |
2429 | case VIDIOC_G_EDID: |
2430 | case VIDIOC_S_EDID: |
2431 | - err = get_v4l2_edid32(&karg.v2edid, up); |
2432 | + err = alloc_userspace(sizeof(struct v4l2_edid), 0, &up_native); |
2433 | + if (!err) |
2434 | + err = get_v4l2_edid32(up_native, up); |
2435 | compatible_arg = 0; |
2436 | break; |
2437 | |
2438 | case VIDIOC_G_FMT: |
2439 | case VIDIOC_S_FMT: |
2440 | case VIDIOC_TRY_FMT: |
2441 | - err = get_v4l2_format32(&karg.v2f, up); |
2442 | + err = bufsize_v4l2_format(up, &aux_space); |
2443 | + if (!err) |
2444 | + err = alloc_userspace(sizeof(struct v4l2_format), |
2445 | + aux_space, &up_native); |
2446 | + if (!err) { |
2447 | + aux_buf = up_native + sizeof(struct v4l2_format); |
2448 | + err = get_v4l2_format32(up_native, up, |
2449 | + aux_buf, aux_space); |
2450 | + } |
2451 | compatible_arg = 0; |
2452 | break; |
2453 | |
2454 | case VIDIOC_CREATE_BUFS: |
2455 | - err = get_v4l2_create32(&karg.v2crt, up); |
2456 | + err = bufsize_v4l2_create(up, &aux_space); |
2457 | + if (!err) |
2458 | + err = alloc_userspace(sizeof(struct v4l2_create_buffers), |
2459 | + aux_space, &up_native); |
2460 | + if (!err) { |
2461 | + aux_buf = up_native + sizeof(struct v4l2_create_buffers); |
2462 | + err = get_v4l2_create32(up_native, up, |
2463 | + aux_buf, aux_space); |
2464 | + } |
2465 | compatible_arg = 0; |
2466 | break; |
2467 | |
2468 | @@ -931,36 +1103,63 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar |
2469 | case VIDIOC_QUERYBUF: |
2470 | case VIDIOC_QBUF: |
2471 | case VIDIOC_DQBUF: |
2472 | - err = get_v4l2_buffer32(&karg.v2b, up); |
2473 | + err = bufsize_v4l2_buffer(up, &aux_space); |
2474 | + if (!err) |
2475 | + err = alloc_userspace(sizeof(struct v4l2_buffer), |
2476 | + aux_space, &up_native); |
2477 | + if (!err) { |
2478 | + aux_buf = up_native + sizeof(struct v4l2_buffer); |
2479 | + err = get_v4l2_buffer32(up_native, up, |
2480 | + aux_buf, aux_space); |
2481 | + } |
2482 | compatible_arg = 0; |
2483 | break; |
2484 | |
2485 | case VIDIOC_S_FBUF: |
2486 | - err = get_v4l2_framebuffer32(&karg.v2fb, up); |
2487 | + err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0, |
2488 | + &up_native); |
2489 | + if (!err) |
2490 | + err = get_v4l2_framebuffer32(up_native, up); |
2491 | compatible_arg = 0; |
2492 | break; |
2493 | |
2494 | case VIDIOC_G_FBUF: |
2495 | + err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0, |
2496 | + &up_native); |
2497 | compatible_arg = 0; |
2498 | break; |
2499 | |
2500 | case VIDIOC_ENUMSTD: |
2501 | - err = get_v4l2_standard32(&karg.v2s, up); |
2502 | + err = alloc_userspace(sizeof(struct v4l2_standard), 0, |
2503 | + &up_native); |
2504 | + if (!err) |
2505 | + err = get_v4l2_standard32(up_native, up); |
2506 | compatible_arg = 0; |
2507 | break; |
2508 | |
2509 | case VIDIOC_ENUMINPUT: |
2510 | - err = get_v4l2_input32(&karg.v2i, up); |
2511 | + err = alloc_userspace(sizeof(struct v4l2_input), 0, &up_native); |
2512 | + if (!err) |
2513 | + err = get_v4l2_input32(up_native, up); |
2514 | compatible_arg = 0; |
2515 | break; |
2516 | |
2517 | case VIDIOC_G_EXT_CTRLS: |
2518 | case VIDIOC_S_EXT_CTRLS: |
2519 | case VIDIOC_TRY_EXT_CTRLS: |
2520 | - err = get_v4l2_ext_controls32(&karg.v2ecs, up); |
2521 | + err = bufsize_v4l2_ext_controls(up, &aux_space); |
2522 | + if (!err) |
2523 | + err = alloc_userspace(sizeof(struct v4l2_ext_controls), |
2524 | + aux_space, &up_native); |
2525 | + if (!err) { |
2526 | + aux_buf = up_native + sizeof(struct v4l2_ext_controls); |
2527 | + err = get_v4l2_ext_controls32(file, up_native, up, |
2528 | + aux_buf, aux_space); |
2529 | + } |
2530 | compatible_arg = 0; |
2531 | break; |
2532 | case VIDIOC_DQEVENT: |
2533 | + err = alloc_userspace(sizeof(struct v4l2_event), 0, &up_native); |
2534 | compatible_arg = 0; |
2535 | break; |
2536 | } |
2537 | @@ -969,22 +1168,26 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar |
2538 | |
2539 | if (compatible_arg) |
2540 | err = native_ioctl(file, cmd, (unsigned long)up); |
2541 | - else { |
2542 | - mm_segment_t old_fs = get_fs(); |
2543 | + else |
2544 | + err = native_ioctl(file, cmd, (unsigned long)up_native); |
2545 | |
2546 | - set_fs(KERNEL_DS); |
2547 | - err = native_ioctl(file, cmd, (unsigned long)&karg); |
2548 | - set_fs(old_fs); |
2549 | - } |
2550 | + if (err == -ENOTTY) |
2551 | + return err; |
2552 | |
2553 | - /* Special case: even after an error we need to put the |
2554 | - results back for these ioctls since the error_idx will |
2555 | - contain information on which control failed. */ |
2556 | + /* |
2557 | + * Special case: even after an error we need to put the |
2558 | + * results back for these ioctls since the error_idx will |
2559 | + * contain information on which control failed. |
2560 | + */ |
2561 | switch (cmd) { |
2562 | case VIDIOC_G_EXT_CTRLS: |
2563 | case VIDIOC_S_EXT_CTRLS: |
2564 | case VIDIOC_TRY_EXT_CTRLS: |
2565 | - if (put_v4l2_ext_controls32(&karg.v2ecs, up)) |
2566 | + if (put_v4l2_ext_controls32(file, up_native, up)) |
2567 | + err = -EFAULT; |
2568 | + break; |
2569 | + case VIDIOC_S_EDID: |
2570 | + if (put_v4l2_edid32(up_native, up)) |
2571 | err = -EFAULT; |
2572 | break; |
2573 | } |
2574 | @@ -996,44 +1199,46 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar |
2575 | case VIDIOC_S_OUTPUT: |
2576 | case VIDIOC_G_INPUT: |
2577 | case VIDIOC_G_OUTPUT: |
2578 | - err = put_user(((s32)karg.vi), (s32 __user *)up); |
2579 | + if (assign_in_user((compat_uint_t __user *)up, |
2580 | + ((unsigned int __user *)up_native))) |
2581 | + err = -EFAULT; |
2582 | break; |
2583 | |
2584 | case VIDIOC_G_FBUF: |
2585 | - err = put_v4l2_framebuffer32(&karg.v2fb, up); |
2586 | + err = put_v4l2_framebuffer32(up_native, up); |
2587 | break; |
2588 | |
2589 | case VIDIOC_DQEVENT: |
2590 | - err = put_v4l2_event32(&karg.v2ev, up); |
2591 | + err = put_v4l2_event32(up_native, up); |
2592 | break; |
2593 | |
2594 | case VIDIOC_G_EDID: |
2595 | - case VIDIOC_S_EDID: |
2596 | - err = put_v4l2_edid32(&karg.v2edid, up); |
2597 | + err = put_v4l2_edid32(up_native, up); |
2598 | break; |
2599 | |
2600 | case VIDIOC_G_FMT: |
2601 | case VIDIOC_S_FMT: |
2602 | case VIDIOC_TRY_FMT: |
2603 | - err = put_v4l2_format32(&karg.v2f, up); |
2604 | + err = put_v4l2_format32(up_native, up); |
2605 | break; |
2606 | |
2607 | case VIDIOC_CREATE_BUFS: |
2608 | - err = put_v4l2_create32(&karg.v2crt, up); |
2609 | + err = put_v4l2_create32(up_native, up); |
2610 | break; |
2611 | |
2612 | + case VIDIOC_PREPARE_BUF: |
2613 | case VIDIOC_QUERYBUF: |
2614 | case VIDIOC_QBUF: |
2615 | case VIDIOC_DQBUF: |
2616 | - err = put_v4l2_buffer32(&karg.v2b, up); |
2617 | + err = put_v4l2_buffer32(up_native, up); |
2618 | break; |
2619 | |
2620 | case VIDIOC_ENUMSTD: |
2621 | - err = put_v4l2_standard32(&karg.v2s, up); |
2622 | + err = put_v4l2_standard32(up_native, up); |
2623 | break; |
2624 | |
2625 | case VIDIOC_ENUMINPUT: |
2626 | - err = put_v4l2_input32(&karg.v2i, up); |
2627 | + err = put_v4l2_input32(up_native, up); |
2628 | break; |
2629 | } |
2630 | return err; |
2631 | diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c |
2632 | index c52d94c018bb..4510e8a37244 100644 |
2633 | --- a/drivers/media/v4l2-core/v4l2-ioctl.c |
2634 | +++ b/drivers/media/v4l2-core/v4l2-ioctl.c |
2635 | @@ -2862,8 +2862,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, |
2636 | |
2637 | /* Handles IOCTL */ |
2638 | err = func(file, cmd, parg); |
2639 | - if (err == -ENOIOCTLCMD) |
2640 | + if (err == -ENOTTY || err == -ENOIOCTLCMD) { |
2641 | err = -ENOTTY; |
2642 | + goto out; |
2643 | + } |
2644 | + |
2645 | if (err == 0) { |
2646 | if (cmd == VIDIOC_DQBUF) |
2647 | trace_v4l2_dqbuf(video_devdata(file)->minor, parg); |
2648 | diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c |
2649 | index d9fab2222eb3..1a4a790054e4 100644 |
2650 | --- a/drivers/mtd/nand/brcmnand/brcmnand.c |
2651 | +++ b/drivers/mtd/nand/brcmnand/brcmnand.c |
2652 | @@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) |
2653 | if (ctrl->nand_version >= 0x0702) |
2654 | tmp |= ACC_CONTROL_RD_ERASED; |
2655 | tmp &= ~ACC_CONTROL_FAST_PGM_RDIN; |
2656 | - if (ctrl->features & BRCMNAND_HAS_PREFETCH) { |
2657 | - /* |
2658 | - * FIXME: Flash DMA + prefetch may see spurious erased-page ECC |
2659 | - * errors |
2660 | - */ |
2661 | - if (has_flash_dma(ctrl)) |
2662 | - tmp &= ~ACC_CONTROL_PREFETCH; |
2663 | - else |
2664 | - tmp |= ACC_CONTROL_PREFETCH; |
2665 | - } |
2666 | + if (ctrl->features & BRCMNAND_HAS_PREFETCH) |
2667 | + tmp &= ~ACC_CONTROL_PREFETCH; |
2668 | + |
2669 | nand_writereg(ctrl, offs, tmp); |
2670 | |
2671 | return 0; |
2672 | diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c |
2673 | index a77cfd74a92e..21c03086bb7f 100644 |
2674 | --- a/drivers/mtd/nand/nand_base.c |
2675 | +++ b/drivers/mtd/nand/nand_base.c |
2676 | @@ -2320,6 +2320,7 @@ EXPORT_SYMBOL(nand_write_oob_syndrome); |
2677 | static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, |
2678 | struct mtd_oob_ops *ops) |
2679 | { |
2680 | + unsigned int max_bitflips = 0; |
2681 | int page, realpage, chipnr; |
2682 | struct nand_chip *chip = mtd_to_nand(mtd); |
2683 | struct mtd_ecc_stats stats; |
2684 | @@ -2377,6 +2378,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, |
2685 | nand_wait_ready(mtd); |
2686 | } |
2687 | |
2688 | + max_bitflips = max_t(unsigned int, max_bitflips, ret); |
2689 | + |
2690 | readlen -= len; |
2691 | if (!readlen) |
2692 | break; |
2693 | @@ -2402,7 +2405,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, |
2694 | if (mtd->ecc_stats.failed - stats.failed) |
2695 | return -EBADMSG; |
2696 | |
2697 | - return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; |
2698 | + return max_bitflips; |
2699 | } |
2700 | |
2701 | /** |
2702 | diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c |
2703 | index f9b2a771096b..e26c4f880df6 100644 |
2704 | --- a/drivers/mtd/nand/sunxi_nand.c |
2705 | +++ b/drivers/mtd/nand/sunxi_nand.c |
2706 | @@ -1835,8 +1835,14 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd, |
2707 | |
2708 | /* Add ECC info retrieval from DT */ |
2709 | for (i = 0; i < ARRAY_SIZE(strengths); i++) { |
2710 | - if (ecc->strength <= strengths[i]) |
2711 | + if (ecc->strength <= strengths[i]) { |
2712 | + /* |
2713 | + * Update ecc->strength value with the actual strength |
2714 | + * that will be used by the ECC engine. |
2715 | + */ |
2716 | + ecc->strength = strengths[i]; |
2717 | break; |
2718 | + } |
2719 | } |
2720 | |
2721 | if (i >= ARRAY_SIZE(strengths)) { |
2722 | diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c |
2723 | index d1e6931c132f..46913ef25bc0 100644 |
2724 | --- a/drivers/mtd/ubi/block.c |
2725 | +++ b/drivers/mtd/ubi/block.c |
2726 | @@ -99,6 +99,8 @@ struct ubiblock { |
2727 | |
2728 | /* Linked list of all ubiblock instances */ |
2729 | static LIST_HEAD(ubiblock_devices); |
2730 | +static DEFINE_IDR(ubiblock_minor_idr); |
2731 | +/* Protects ubiblock_devices and ubiblock_minor_idr */ |
2732 | static DEFINE_MUTEX(devices_mutex); |
2733 | static int ubiblock_major; |
2734 | |
2735 | @@ -353,8 +355,6 @@ static struct blk_mq_ops ubiblock_mq_ops = { |
2736 | .init_request = ubiblock_init_request, |
2737 | }; |
2738 | |
2739 | -static DEFINE_IDR(ubiblock_minor_idr); |
2740 | - |
2741 | int ubiblock_create(struct ubi_volume_info *vi) |
2742 | { |
2743 | struct ubiblock *dev; |
2744 | @@ -367,14 +367,15 @@ int ubiblock_create(struct ubi_volume_info *vi) |
2745 | /* Check that the volume isn't already handled */ |
2746 | mutex_lock(&devices_mutex); |
2747 | if (find_dev_nolock(vi->ubi_num, vi->vol_id)) { |
2748 | - mutex_unlock(&devices_mutex); |
2749 | - return -EEXIST; |
2750 | + ret = -EEXIST; |
2751 | + goto out_unlock; |
2752 | } |
2753 | - mutex_unlock(&devices_mutex); |
2754 | |
2755 | dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL); |
2756 | - if (!dev) |
2757 | - return -ENOMEM; |
2758 | + if (!dev) { |
2759 | + ret = -ENOMEM; |
2760 | + goto out_unlock; |
2761 | + } |
2762 | |
2763 | mutex_init(&dev->dev_mutex); |
2764 | |
2765 | @@ -439,14 +440,13 @@ int ubiblock_create(struct ubi_volume_info *vi) |
2766 | goto out_free_queue; |
2767 | } |
2768 | |
2769 | - mutex_lock(&devices_mutex); |
2770 | list_add_tail(&dev->list, &ubiblock_devices); |
2771 | - mutex_unlock(&devices_mutex); |
2772 | |
2773 | /* Must be the last step: anyone can call file ops from now on */ |
2774 | add_disk(dev->gd); |
2775 | dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", |
2776 | dev->ubi_num, dev->vol_id, vi->name); |
2777 | + mutex_unlock(&devices_mutex); |
2778 | return 0; |
2779 | |
2780 | out_free_queue: |
2781 | @@ -459,6 +459,8 @@ int ubiblock_create(struct ubi_volume_info *vi) |
2782 | put_disk(dev->gd); |
2783 | out_free_dev: |
2784 | kfree(dev); |
2785 | +out_unlock: |
2786 | + mutex_unlock(&devices_mutex); |
2787 | |
2788 | return ret; |
2789 | } |
2790 | @@ -480,30 +482,36 @@ static void ubiblock_cleanup(struct ubiblock *dev) |
2791 | int ubiblock_remove(struct ubi_volume_info *vi) |
2792 | { |
2793 | struct ubiblock *dev; |
2794 | + int ret; |
2795 | |
2796 | mutex_lock(&devices_mutex); |
2797 | dev = find_dev_nolock(vi->ubi_num, vi->vol_id); |
2798 | if (!dev) { |
2799 | - mutex_unlock(&devices_mutex); |
2800 | - return -ENODEV; |
2801 | + ret = -ENODEV; |
2802 | + goto out_unlock; |
2803 | } |
2804 | |
2805 | /* Found a device, let's lock it so we can check if it's busy */ |
2806 | mutex_lock(&dev->dev_mutex); |
2807 | if (dev->refcnt > 0) { |
2808 | - mutex_unlock(&dev->dev_mutex); |
2809 | - mutex_unlock(&devices_mutex); |
2810 | - return -EBUSY; |
2811 | + ret = -EBUSY; |
2812 | + goto out_unlock_dev; |
2813 | } |
2814 | |
2815 | /* Remove from device list */ |
2816 | list_del(&dev->list); |
2817 | - mutex_unlock(&devices_mutex); |
2818 | - |
2819 | ubiblock_cleanup(dev); |
2820 | mutex_unlock(&dev->dev_mutex); |
2821 | + mutex_unlock(&devices_mutex); |
2822 | + |
2823 | kfree(dev); |
2824 | return 0; |
2825 | + |
2826 | +out_unlock_dev: |
2827 | + mutex_unlock(&dev->dev_mutex); |
2828 | +out_unlock: |
2829 | + mutex_unlock(&devices_mutex); |
2830 | + return ret; |
2831 | } |
2832 | |
2833 | static int ubiblock_resize(struct ubi_volume_info *vi) |
2834 | @@ -632,6 +640,7 @@ static void ubiblock_remove_all(void) |
2835 | struct ubiblock *next; |
2836 | struct ubiblock *dev; |
2837 | |
2838 | + mutex_lock(&devices_mutex); |
2839 | list_for_each_entry_safe(dev, next, &ubiblock_devices, list) { |
2840 | /* The module is being forcefully removed */ |
2841 | WARN_ON(dev->desc); |
2842 | @@ -640,6 +649,7 @@ static void ubiblock_remove_all(void) |
2843 | ubiblock_cleanup(dev); |
2844 | kfree(dev); |
2845 | } |
2846 | + mutex_unlock(&devices_mutex); |
2847 | } |
2848 | |
2849 | int __init ubiblock_init(void) |
2850 | diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c |
2851 | index b5b8cd6f481c..668b46202507 100644 |
2852 | --- a/drivers/mtd/ubi/wl.c |
2853 | +++ b/drivers/mtd/ubi/wl.c |
2854 | @@ -1528,6 +1528,46 @@ static void shutdown_work(struct ubi_device *ubi) |
2855 | } |
2856 | } |
2857 | |
2858 | +/** |
2859 | + * erase_aeb - erase a PEB given in UBI attach info PEB |
2860 | + * @ubi: UBI device description object |
2861 | + * @aeb: UBI attach info PEB |
2862 | + * @sync: If true, erase synchronously. Otherwise schedule for erasure |
2863 | + */ |
2864 | +static int erase_aeb(struct ubi_device *ubi, struct ubi_ainf_peb *aeb, bool sync) |
2865 | +{ |
2866 | + struct ubi_wl_entry *e; |
2867 | + int err; |
2868 | + |
2869 | + e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); |
2870 | + if (!e) |
2871 | + return -ENOMEM; |
2872 | + |
2873 | + e->pnum = aeb->pnum; |
2874 | + e->ec = aeb->ec; |
2875 | + ubi->lookuptbl[e->pnum] = e; |
2876 | + |
2877 | + if (sync) { |
2878 | + err = sync_erase(ubi, e, false); |
2879 | + if (err) |
2880 | + goto out_free; |
2881 | + |
2882 | + wl_tree_add(e, &ubi->free); |
2883 | + ubi->free_count++; |
2884 | + } else { |
2885 | + err = schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false); |
2886 | + if (err) |
2887 | + goto out_free; |
2888 | + } |
2889 | + |
2890 | + return 0; |
2891 | + |
2892 | +out_free: |
2893 | + wl_entry_destroy(ubi, e); |
2894 | + |
2895 | + return err; |
2896 | +} |
2897 | + |
2898 | /** |
2899 | * ubi_wl_init - initialize the WL sub-system using attaching information. |
2900 | * @ubi: UBI device description object |
2901 | @@ -1566,18 +1606,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) |
2902 | list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) { |
2903 | cond_resched(); |
2904 | |
2905 | - e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); |
2906 | - if (!e) |
2907 | + err = erase_aeb(ubi, aeb, false); |
2908 | + if (err) |
2909 | goto out_free; |
2910 | |
2911 | - e->pnum = aeb->pnum; |
2912 | - e->ec = aeb->ec; |
2913 | - ubi->lookuptbl[e->pnum] = e; |
2914 | - if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) { |
2915 | - wl_entry_destroy(ubi, e); |
2916 | - goto out_free; |
2917 | - } |
2918 | - |
2919 | found_pebs++; |
2920 | } |
2921 | |
2922 | @@ -1635,6 +1667,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) |
2923 | ubi_assert(!ubi->lookuptbl[e->pnum]); |
2924 | ubi->lookuptbl[e->pnum] = e; |
2925 | } else { |
2926 | + bool sync = false; |
2927 | + |
2928 | /* |
2929 | * Usually old Fastmap PEBs are scheduled for erasure |
2930 | * and we don't have to care about them but if we face |
2931 | @@ -1644,18 +1678,21 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) |
2932 | if (ubi->lookuptbl[aeb->pnum]) |
2933 | continue; |
2934 | |
2935 | - e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); |
2936 | - if (!e) |
2937 | - goto out_free; |
2938 | + /* |
2939 | + * The fastmap update code might not find a free PEB for |
2940 | + * writing the fastmap anchor to and then reuses the |
2941 | + * current fastmap anchor PEB. When this PEB gets erased |
2942 | + * and a power cut happens before it is written again we |
2943 | + * must make sure that the fastmap attach code doesn't |
2944 | + * find any outdated fastmap anchors, hence we erase the |
2945 | + * outdated fastmap anchor PEBs synchronously here. |
2946 | + */ |
2947 | + if (aeb->vol_id == UBI_FM_SB_VOLUME_ID) |
2948 | + sync = true; |
2949 | |
2950 | - e->pnum = aeb->pnum; |
2951 | - e->ec = aeb->ec; |
2952 | - ubi_assert(!ubi->lookuptbl[e->pnum]); |
2953 | - ubi->lookuptbl[e->pnum] = e; |
2954 | - if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) { |
2955 | - wl_entry_destroy(ubi, e); |
2956 | + err = erase_aeb(ubi, aeb, sync); |
2957 | + if (err) |
2958 | goto out_free; |
2959 | - } |
2960 | } |
2961 | |
2962 | found_pebs++; |
2963 | diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c |
2964 | index b40a074822cf..df63b7d997e8 100644 |
2965 | --- a/drivers/pinctrl/intel/pinctrl-intel.c |
2966 | +++ b/drivers/pinctrl/intel/pinctrl-intel.c |
2967 | @@ -368,6 +368,18 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) |
2968 | writel(value, padcfg0); |
2969 | } |
2970 | |
2971 | +static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) |
2972 | +{ |
2973 | + u32 value; |
2974 | + |
2975 | + /* Put the pad into GPIO mode */ |
2976 | + value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; |
2977 | + /* Disable SCI/SMI/NMI generation */ |
2978 | + value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); |
2979 | + value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); |
2980 | + writel(value, padcfg0); |
2981 | +} |
2982 | + |
2983 | static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, |
2984 | struct pinctrl_gpio_range *range, |
2985 | unsigned pin) |
2986 | @@ -375,7 +387,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, |
2987 | struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
2988 | void __iomem *padcfg0; |
2989 | unsigned long flags; |
2990 | - u32 value; |
2991 | |
2992 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
2993 | |
2994 | @@ -385,13 +396,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, |
2995 | } |
2996 | |
2997 | padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); |
2998 | - /* Put the pad into GPIO mode */ |
2999 | - value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; |
3000 | - /* Disable SCI/SMI/NMI generation */ |
3001 | - value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); |
3002 | - value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); |
3003 | - writel(value, padcfg0); |
3004 | - |
3005 | + intel_gpio_set_gpio_mode(padcfg0); |
3006 | /* Disable TX buffer and enable RX (this will be input) */ |
3007 | __intel_gpio_set_direction(padcfg0, true); |
3008 | |
3009 | @@ -770,6 +775,8 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) |
3010 | |
3011 | raw_spin_lock_irqsave(&pctrl->lock, flags); |
3012 | |
3013 | + intel_gpio_set_gpio_mode(reg); |
3014 | + |
3015 | value = readl(reg); |
3016 | |
3017 | value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV); |
3018 | diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c |
3019 | index 31125a4a2658..d7dcd39fe12c 100644 |
3020 | --- a/drivers/usb/gadget/function/uvc_configfs.c |
3021 | +++ b/drivers/usb/gadget/function/uvc_configfs.c |
3022 | @@ -2140,7 +2140,7 @@ static struct configfs_item_operations uvc_item_ops = { |
3023 | .release = uvc_attr_release, |
3024 | }; |
3025 | |
3026 | -#define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit) \ |
3027 | +#define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ |
3028 | static ssize_t f_uvc_opts_##cname##_show( \ |
3029 | struct config_item *item, char *page) \ |
3030 | { \ |
3031 | @@ -2183,16 +2183,16 @@ end: \ |
3032 | return ret; \ |
3033 | } \ |
3034 | \ |
3035 | -UVC_ATTR(f_uvc_opts_, cname, aname) |
3036 | +UVC_ATTR(f_uvc_opts_, cname, cname) |
3037 | |
3038 | #define identity_conv(x) (x) |
3039 | |
3040 | -UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv, |
3041 | - 16); |
3042 | -UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu, |
3043 | - 3072); |
3044 | -UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv, |
3045 | - 15); |
3046 | +UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv, |
3047 | + kstrtou8, u8, identity_conv, 16); |
3048 | +UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu, |
3049 | + kstrtou16, u16, le16_to_cpu, 3072); |
3050 | +UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv, |
3051 | + kstrtou8, u8, identity_conv, 15); |
3052 | |
3053 | #undef identity_conv |
3054 | |
3055 | diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c |
3056 | index 4874b0f18650..518dfa1047cb 100644 |
3057 | --- a/drivers/watchdog/imx2_wdt.c |
3058 | +++ b/drivers/watchdog/imx2_wdt.c |
3059 | @@ -169,15 +169,21 @@ static int imx2_wdt_ping(struct watchdog_device *wdog) |
3060 | return 0; |
3061 | } |
3062 | |
3063 | -static int imx2_wdt_set_timeout(struct watchdog_device *wdog, |
3064 | - unsigned int new_timeout) |
3065 | +static void __imx2_wdt_set_timeout(struct watchdog_device *wdog, |
3066 | + unsigned int new_timeout) |
3067 | { |
3068 | struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); |
3069 | |
3070 | - wdog->timeout = new_timeout; |
3071 | - |
3072 | regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT, |
3073 | WDOG_SEC_TO_COUNT(new_timeout)); |
3074 | +} |
3075 | + |
3076 | +static int imx2_wdt_set_timeout(struct watchdog_device *wdog, |
3077 | + unsigned int new_timeout) |
3078 | +{ |
3079 | + __imx2_wdt_set_timeout(wdog, new_timeout); |
3080 | + |
3081 | + wdog->timeout = new_timeout; |
3082 | return 0; |
3083 | } |
3084 | |
3085 | @@ -371,7 +377,11 @@ static int imx2_wdt_suspend(struct device *dev) |
3086 | |
3087 | /* The watchdog IP block is running */ |
3088 | if (imx2_wdt_is_running(wdev)) { |
3089 | - imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); |
3090 | + /* |
3091 | + * Don't update wdog->timeout, we'll restore the current value |
3092 | + * during resume. |
3093 | + */ |
3094 | + __imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); |
3095 | imx2_wdt_ping(wdog); |
3096 | } |
3097 | |
3098 | diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
3099 | index 894d56361ea9..a8a1fb40e258 100644 |
3100 | --- a/fs/btrfs/inode.c |
3101 | +++ b/fs/btrfs/inode.c |
3102 | @@ -2063,8 +2063,15 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) |
3103 | goto out; |
3104 | } |
3105 | |
3106 | - btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state, |
3107 | - 0); |
3108 | + ret = btrfs_set_extent_delalloc(inode, page_start, page_end, |
3109 | + &cached_state, 0); |
3110 | + if (ret) { |
3111 | + mapping_set_error(page->mapping, ret); |
3112 | + end_extent_writepage(page, ret, page_start, page_end); |
3113 | + ClearPageChecked(page); |
3114 | + goto out; |
3115 | + } |
3116 | + |
3117 | ClearPageChecked(page); |
3118 | set_page_dirty(page); |
3119 | out: |
3120 | diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c |
3121 | index 5eb04129f938..73360df52ce9 100644 |
3122 | --- a/fs/cifs/cifsencrypt.c |
3123 | +++ b/fs/cifs/cifsencrypt.c |
3124 | @@ -318,9 +318,8 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, |
3125 | { |
3126 | int i; |
3127 | int rc; |
3128 | - char password_with_pad[CIFS_ENCPWD_SIZE]; |
3129 | + char password_with_pad[CIFS_ENCPWD_SIZE] = {0}; |
3130 | |
3131 | - memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); |
3132 | if (password) |
3133 | strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE); |
3134 | |
3135 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
3136 | index 580b3a4ca53a..441d434a48c1 100644 |
3137 | --- a/fs/cifs/connect.c |
3138 | +++ b/fs/cifs/connect.c |
3139 | @@ -1667,7 +1667,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, |
3140 | tmp_end++; |
3141 | if (!(tmp_end < end && tmp_end[1] == delim)) { |
3142 | /* No it is not. Set the password to NULL */ |
3143 | - kfree(vol->password); |
3144 | + kzfree(vol->password); |
3145 | vol->password = NULL; |
3146 | break; |
3147 | } |
3148 | @@ -1705,7 +1705,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, |
3149 | options = end; |
3150 | } |
3151 | |
3152 | - kfree(vol->password); |
3153 | + kzfree(vol->password); |
3154 | /* Now build new password string */ |
3155 | temp_len = strlen(value); |
3156 | vol->password = kzalloc(temp_len+1, GFP_KERNEL); |
3157 | @@ -4159,7 +4159,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) |
3158 | reset_cifs_unix_caps(0, tcon, NULL, vol_info); |
3159 | out: |
3160 | kfree(vol_info->username); |
3161 | - kfree(vol_info->password); |
3162 | + kzfree(vol_info->password); |
3163 | kfree(vol_info); |
3164 | |
3165 | return tcon; |
3166 | diff --git a/fs/cifs/file.c b/fs/cifs/file.c |
3167 | index cf192f9ce254..02e403af9518 100644 |
3168 | --- a/fs/cifs/file.c |
3169 | +++ b/fs/cifs/file.c |
3170 | @@ -3285,20 +3285,18 @@ static const struct vm_operations_struct cifs_file_vm_ops = { |
3171 | |
3172 | int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) |
3173 | { |
3174 | - int rc, xid; |
3175 | + int xid, rc = 0; |
3176 | struct inode *inode = file_inode(file); |
3177 | |
3178 | xid = get_xid(); |
3179 | |
3180 | - if (!CIFS_CACHE_READ(CIFS_I(inode))) { |
3181 | + if (!CIFS_CACHE_READ(CIFS_I(inode))) |
3182 | rc = cifs_zap_mapping(inode); |
3183 | - if (rc) |
3184 | - return rc; |
3185 | - } |
3186 | - |
3187 | - rc = generic_file_mmap(file, vma); |
3188 | - if (rc == 0) |
3189 | + if (!rc) |
3190 | + rc = generic_file_mmap(file, vma); |
3191 | + if (!rc) |
3192 | vma->vm_ops = &cifs_file_vm_ops; |
3193 | + |
3194 | free_xid(xid); |
3195 | return rc; |
3196 | } |
3197 | @@ -3308,16 +3306,16 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) |
3198 | int rc, xid; |
3199 | |
3200 | xid = get_xid(); |
3201 | + |
3202 | rc = cifs_revalidate_file(file); |
3203 | - if (rc) { |
3204 | + if (rc) |
3205 | cifs_dbg(FYI, "Validation prior to mmap failed, error=%d\n", |
3206 | rc); |
3207 | - free_xid(xid); |
3208 | - return rc; |
3209 | - } |
3210 | - rc = generic_file_mmap(file, vma); |
3211 | - if (rc == 0) |
3212 | + if (!rc) |
3213 | + rc = generic_file_mmap(file, vma); |
3214 | + if (!rc) |
3215 | vma->vm_ops = &cifs_file_vm_ops; |
3216 | + |
3217 | free_xid(xid); |
3218 | return rc; |
3219 | } |
3220 | diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c |
3221 | index 5419afea0a36..323d8e34abde 100644 |
3222 | --- a/fs/cifs/misc.c |
3223 | +++ b/fs/cifs/misc.c |
3224 | @@ -99,14 +99,11 @@ sesInfoFree(struct cifs_ses *buf_to_free) |
3225 | kfree(buf_to_free->serverOS); |
3226 | kfree(buf_to_free->serverDomain); |
3227 | kfree(buf_to_free->serverNOS); |
3228 | - if (buf_to_free->password) { |
3229 | - memset(buf_to_free->password, 0, strlen(buf_to_free->password)); |
3230 | - kfree(buf_to_free->password); |
3231 | - } |
3232 | + kzfree(buf_to_free->password); |
3233 | kfree(buf_to_free->user_name); |
3234 | kfree(buf_to_free->domainName); |
3235 | - kfree(buf_to_free->auth_key.response); |
3236 | - kfree(buf_to_free); |
3237 | + kzfree(buf_to_free->auth_key.response); |
3238 | + kzfree(buf_to_free); |
3239 | } |
3240 | |
3241 | struct cifs_tcon * |
3242 | @@ -137,10 +134,7 @@ tconInfoFree(struct cifs_tcon *buf_to_free) |
3243 | } |
3244 | atomic_dec(&tconInfoAllocCount); |
3245 | kfree(buf_to_free->nativeFileSystem); |
3246 | - if (buf_to_free->password) { |
3247 | - memset(buf_to_free->password, 0, strlen(buf_to_free->password)); |
3248 | - kfree(buf_to_free->password); |
3249 | - } |
3250 | + kzfree(buf_to_free->password); |
3251 | kfree(buf_to_free); |
3252 | } |
3253 | |
3254 | diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c |
3255 | index 69b610ad3fdc..94c4c1901222 100644 |
3256 | --- a/fs/cifs/smb2pdu.c |
3257 | +++ b/fs/cifs/smb2pdu.c |
3258 | @@ -585,8 +585,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) |
3259 | } |
3260 | |
3261 | /* check validate negotiate info response matches what we got earlier */ |
3262 | - if (pneg_rsp->Dialect != |
3263 | - cpu_to_le16(tcon->ses->server->vals->protocol_id)) |
3264 | + if (pneg_rsp->Dialect != cpu_to_le16(tcon->ses->server->dialect)) |
3265 | goto vneg_out; |
3266 | |
3267 | if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode)) |
3268 | diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c |
3269 | index 78219d5644e9..d6512cd9ba02 100644 |
3270 | --- a/fs/kernfs/file.c |
3271 | +++ b/fs/kernfs/file.c |
3272 | @@ -275,7 +275,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, |
3273 | { |
3274 | struct kernfs_open_file *of = kernfs_of(file); |
3275 | const struct kernfs_ops *ops; |
3276 | - size_t len; |
3277 | + ssize_t len; |
3278 | char *buf; |
3279 | |
3280 | if (of->atomic_write_len) { |
3281 | diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c |
3282 | index bd81bcf3ffcf..1ac1593aded3 100644 |
3283 | --- a/fs/nfs/direct.c |
3284 | +++ b/fs/nfs/direct.c |
3285 | @@ -787,10 +787,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) |
3286 | |
3287 | spin_lock(&dreq->lock); |
3288 | |
3289 | - if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { |
3290 | - dreq->flags = 0; |
3291 | + if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) |
3292 | dreq->error = hdr->error; |
3293 | - } |
3294 | if (dreq->error == 0) { |
3295 | nfs_direct_good_bytes(dreq, hdr); |
3296 | if (nfs_write_need_commit(hdr)) { |
3297 | diff --git a/fs/nfs/io.c b/fs/nfs/io.c |
3298 | index 1fc5d1ce327e..d18ccc1ce0b5 100644 |
3299 | --- a/fs/nfs/io.c |
3300 | +++ b/fs/nfs/io.c |
3301 | @@ -98,7 +98,7 @@ static void nfs_block_buffered(struct nfs_inode *nfsi, struct inode *inode) |
3302 | { |
3303 | if (!test_bit(NFS_INO_ODIRECT, &nfsi->flags)) { |
3304 | set_bit(NFS_INO_ODIRECT, &nfsi->flags); |
3305 | - nfs_wb_all(inode); |
3306 | + nfs_sync_mapping(inode->i_mapping); |
3307 | } |
3308 | } |
3309 | |
3310 | diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c |
3311 | index c444285bb1b1..f1160cdd4682 100644 |
3312 | --- a/fs/nfs/nfs4idmap.c |
3313 | +++ b/fs/nfs/nfs4idmap.c |
3314 | @@ -567,9 +567,13 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, |
3315 | struct idmap_msg *im; |
3316 | struct idmap *idmap = (struct idmap *)aux; |
3317 | struct key *key = cons->key; |
3318 | - int ret = -ENOMEM; |
3319 | + int ret = -ENOKEY; |
3320 | + |
3321 | + if (!aux) |
3322 | + goto out1; |
3323 | |
3324 | /* msg and im are freed in idmap_pipe_destroy_msg */ |
3325 | + ret = -ENOMEM; |
3326 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
3327 | if (!data) |
3328 | goto out1; |
3329 | diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c |
3330 | index b7a07ba8783a..b8e44746f761 100644 |
3331 | --- a/fs/nfs/pnfs.c |
3332 | +++ b/fs/nfs/pnfs.c |
3333 | @@ -2145,7 +2145,7 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc, |
3334 | nfs_pageio_reset_write_mds(desc); |
3335 | mirror->pg_recoalesce = 1; |
3336 | } |
3337 | - hdr->release(hdr); |
3338 | + hdr->completion_ops->completion(hdr); |
3339 | } |
3340 | |
3341 | static enum pnfs_try_status |
3342 | @@ -2256,7 +2256,7 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, |
3343 | nfs_pageio_reset_read_mds(desc); |
3344 | mirror->pg_recoalesce = 1; |
3345 | } |
3346 | - hdr->release(hdr); |
3347 | + hdr->completion_ops->completion(hdr); |
3348 | } |
3349 | |
3350 | /* |
3351 | diff --git a/fs/nfs/write.c b/fs/nfs/write.c |
3352 | index 9905735463a4..9a3b3820306d 100644 |
3353 | --- a/fs/nfs/write.c |
3354 | +++ b/fs/nfs/write.c |
3355 | @@ -1806,6 +1806,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) |
3356 | set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags); |
3357 | next: |
3358 | nfs_unlock_and_release_request(req); |
3359 | + /* Latency breaker */ |
3360 | + cond_resched(); |
3361 | } |
3362 | nfss = NFS_SERVER(data->inode); |
3363 | if (atomic_long_read(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) |
3364 | diff --git a/fs/nsfs.c b/fs/nsfs.c |
3365 | index 8718af895eab..80fdfad7c215 100644 |
3366 | --- a/fs/nsfs.c |
3367 | +++ b/fs/nsfs.c |
3368 | @@ -90,6 +90,7 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns) |
3369 | return ERR_PTR(-ENOMEM); |
3370 | } |
3371 | d_instantiate(dentry, inode); |
3372 | + dentry->d_flags |= DCACHE_RCUACCESS; |
3373 | dentry->d_fsdata = (void *)ns->ops; |
3374 | d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry); |
3375 | if (d) { |
3376 | diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c |
3377 | index f241b4ee3d8a..a1be6baabca3 100644 |
3378 | --- a/fs/overlayfs/readdir.c |
3379 | +++ b/fs/overlayfs/readdir.c |
3380 | @@ -434,10 +434,14 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, |
3381 | struct dentry *dentry = file->f_path.dentry; |
3382 | struct file *realfile = od->realfile; |
3383 | |
3384 | + /* Nothing to sync for lower */ |
3385 | + if (!OVL_TYPE_UPPER(ovl_path_type(dentry))) |
3386 | + return 0; |
3387 | + |
3388 | /* |
3389 | * Need to check if we started out being a lower dir, but got copied up |
3390 | */ |
3391 | - if (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) { |
3392 | + if (!od->is_upper) { |
3393 | struct inode *inode = file_inode(file); |
3394 | |
3395 | realfile = lockless_dereference(od->upperfile); |
3396 | diff --git a/fs/pipe.c b/fs/pipe.c |
3397 | index 9faecf1b4a27..34345535f63d 100644 |
3398 | --- a/fs/pipe.c |
3399 | +++ b/fs/pipe.c |
3400 | @@ -609,12 +609,17 @@ static unsigned long account_pipe_buffers(struct user_struct *user, |
3401 | |
3402 | static bool too_many_pipe_buffers_soft(unsigned long user_bufs) |
3403 | { |
3404 | - return pipe_user_pages_soft && user_bufs >= pipe_user_pages_soft; |
3405 | + return pipe_user_pages_soft && user_bufs > pipe_user_pages_soft; |
3406 | } |
3407 | |
3408 | static bool too_many_pipe_buffers_hard(unsigned long user_bufs) |
3409 | { |
3410 | - return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard; |
3411 | + return pipe_user_pages_hard && user_bufs > pipe_user_pages_hard; |
3412 | +} |
3413 | + |
3414 | +static bool is_unprivileged_user(void) |
3415 | +{ |
3416 | + return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); |
3417 | } |
3418 | |
3419 | struct pipe_inode_info *alloc_pipe_info(void) |
3420 | @@ -633,12 +638,12 @@ struct pipe_inode_info *alloc_pipe_info(void) |
3421 | |
3422 | user_bufs = account_pipe_buffers(user, 0, pipe_bufs); |
3423 | |
3424 | - if (too_many_pipe_buffers_soft(user_bufs)) { |
3425 | + if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) { |
3426 | user_bufs = account_pipe_buffers(user, pipe_bufs, 1); |
3427 | pipe_bufs = 1; |
3428 | } |
3429 | |
3430 | - if (too_many_pipe_buffers_hard(user_bufs)) |
3431 | + if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user()) |
3432 | goto out_revert_acct; |
3433 | |
3434 | pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer), |
3435 | @@ -1069,7 +1074,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) |
3436 | if (nr_pages > pipe->buffers && |
3437 | (too_many_pipe_buffers_hard(user_bufs) || |
3438 | too_many_pipe_buffers_soft(user_bufs)) && |
3439 | - !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) { |
3440 | + is_unprivileged_user()) { |
3441 | ret = -EPERM; |
3442 | goto out_revert_acct; |
3443 | } |
3444 | diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c |
3445 | index 5c89a07e3d7f..df7e07986ead 100644 |
3446 | --- a/fs/proc/kcore.c |
3447 | +++ b/fs/proc/kcore.c |
3448 | @@ -507,23 +507,15 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) |
3449 | return -EFAULT; |
3450 | } else { |
3451 | if (kern_addr_valid(start)) { |
3452 | - unsigned long n; |
3453 | - |
3454 | /* |
3455 | * Using bounce buffer to bypass the |
3456 | * hardened user copy kernel text checks. |
3457 | */ |
3458 | - memcpy(buf, (char *) start, tsz); |
3459 | - n = copy_to_user(buffer, buf, tsz); |
3460 | - /* |
3461 | - * We cannot distinguish between fault on source |
3462 | - * and fault on destination. When this happens |
3463 | - * we clear too and hope it will trigger the |
3464 | - * EFAULT again. |
3465 | - */ |
3466 | - if (n) { |
3467 | - if (clear_user(buffer + tsz - n, |
3468 | - n)) |
3469 | + if (probe_kernel_read(buf, (void *) start, tsz)) { |
3470 | + if (clear_user(buffer, tsz)) |
3471 | + return -EFAULT; |
3472 | + } else { |
3473 | + if (copy_to_user(buffer, buf, tsz)) |
3474 | return -EFAULT; |
3475 | } |
3476 | } else { |
3477 | diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c |
3478 | index d9f9615bfd71..3979d767a0cb 100644 |
3479 | --- a/fs/ubifs/xattr.c |
3480 | +++ b/fs/ubifs/xattr.c |
3481 | @@ -270,7 +270,8 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum) |
3482 | } |
3483 | |
3484 | static int __ubifs_setxattr(struct inode *host, const char *name, |
3485 | - const void *value, size_t size, int flags) |
3486 | + const void *value, size_t size, int flags, |
3487 | + bool check_lock) |
3488 | { |
3489 | struct inode *inode; |
3490 | struct ubifs_info *c = host->i_sb->s_fs_info; |
3491 | @@ -279,7 +280,8 @@ static int __ubifs_setxattr(struct inode *host, const char *name, |
3492 | union ubifs_key key; |
3493 | int err; |
3494 | |
3495 | - ubifs_assert(inode_is_locked(host)); |
3496 | + if (check_lock) |
3497 | + ubifs_assert(inode_is_locked(host)); |
3498 | |
3499 | if (size > UBIFS_MAX_INO_DATA) |
3500 | return -ERANGE; |
3501 | @@ -548,7 +550,8 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, |
3502 | } |
3503 | strcpy(name, XATTR_SECURITY_PREFIX); |
3504 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); |
3505 | - err = __ubifs_setxattr(inode, name, xattr->value, xattr->value_len, 0); |
3506 | + err = __ubifs_setxattr(inode, name, xattr->value, |
3507 | + xattr->value_len, 0, false); |
3508 | kfree(name); |
3509 | if (err < 0) |
3510 | break; |
3511 | @@ -594,7 +597,8 @@ static int ubifs_xattr_set(const struct xattr_handler *handler, |
3512 | name = xattr_full_name(handler, name); |
3513 | |
3514 | if (value) |
3515 | - return __ubifs_setxattr(inode, name, value, size, flags); |
3516 | + return __ubifs_setxattr(inode, name, value, size, flags, |
3517 | + true); |
3518 | else |
3519 | return __ubifs_removexattr(inode, name); |
3520 | } |
3521 | diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h |
3522 | index cac57358f7af..5203560f992e 100644 |
3523 | --- a/include/crypto/internal/hash.h |
3524 | +++ b/include/crypto/internal/hash.h |
3525 | @@ -88,6 +88,8 @@ static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg) |
3526 | return alg->setkey != shash_no_setkey; |
3527 | } |
3528 | |
3529 | +bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg); |
3530 | + |
3531 | int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn, |
3532 | struct hash_alg_common *alg, |
3533 | struct crypto_instance *inst); |
3534 | diff --git a/include/crypto/poly1305.h b/include/crypto/poly1305.h |
3535 | index 894df59b74e4..d586f741cab5 100644 |
3536 | --- a/include/crypto/poly1305.h |
3537 | +++ b/include/crypto/poly1305.h |
3538 | @@ -30,8 +30,6 @@ struct poly1305_desc_ctx { |
3539 | }; |
3540 | |
3541 | int crypto_poly1305_init(struct shash_desc *desc); |
3542 | -int crypto_poly1305_setkey(struct crypto_shash *tfm, |
3543 | - const u8 *key, unsigned int keylen); |
3544 | unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx, |
3545 | const u8 *src, unsigned int srclen); |
3546 | int crypto_poly1305_update(struct shash_desc *desc, |
3547 | diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h |
3548 | index 3aa56e3104bb..b5b43f94f311 100644 |
3549 | --- a/include/linux/mtd/map.h |
3550 | +++ b/include/linux/mtd/map.h |
3551 | @@ -270,75 +270,67 @@ void map_destroy(struct mtd_info *mtd); |
3552 | #define INVALIDATE_CACHED_RANGE(map, from, size) \ |
3553 | do { if (map->inval_cache) map->inval_cache(map, from, size); } while (0) |
3554 | |
3555 | - |
3556 | -static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2) |
3557 | -{ |
3558 | - int i; |
3559 | - |
3560 | - for (i = 0; i < map_words(map); i++) { |
3561 | - if (val1.x[i] != val2.x[i]) |
3562 | - return 0; |
3563 | - } |
3564 | - |
3565 | - return 1; |
3566 | -} |
3567 | - |
3568 | -static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2) |
3569 | -{ |
3570 | - map_word r; |
3571 | - int i; |
3572 | - |
3573 | - for (i = 0; i < map_words(map); i++) |
3574 | - r.x[i] = val1.x[i] & val2.x[i]; |
3575 | - |
3576 | - return r; |
3577 | -} |
3578 | - |
3579 | -static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2) |
3580 | -{ |
3581 | - map_word r; |
3582 | - int i; |
3583 | - |
3584 | - for (i = 0; i < map_words(map); i++) |
3585 | - r.x[i] = val1.x[i] & ~val2.x[i]; |
3586 | - |
3587 | - return r; |
3588 | -} |
3589 | - |
3590 | -static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2) |
3591 | -{ |
3592 | - map_word r; |
3593 | - int i; |
3594 | - |
3595 | - for (i = 0; i < map_words(map); i++) |
3596 | - r.x[i] = val1.x[i] | val2.x[i]; |
3597 | - |
3598 | - return r; |
3599 | -} |
3600 | - |
3601 | -static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3) |
3602 | -{ |
3603 | - int i; |
3604 | - |
3605 | - for (i = 0; i < map_words(map); i++) { |
3606 | - if ((val1.x[i] & val2.x[i]) != val3.x[i]) |
3607 | - return 0; |
3608 | - } |
3609 | - |
3610 | - return 1; |
3611 | -} |
3612 | - |
3613 | -static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2) |
3614 | -{ |
3615 | - int i; |
3616 | - |
3617 | - for (i = 0; i < map_words(map); i++) { |
3618 | - if (val1.x[i] & val2.x[i]) |
3619 | - return 1; |
3620 | - } |
3621 | - |
3622 | - return 0; |
3623 | -} |
3624 | +#define map_word_equal(map, val1, val2) \ |
3625 | +({ \ |
3626 | + int i, ret = 1; \ |
3627 | + for (i = 0; i < map_words(map); i++) \ |
3628 | + if ((val1).x[i] != (val2).x[i]) { \ |
3629 | + ret = 0; \ |
3630 | + break; \ |
3631 | + } \ |
3632 | + ret; \ |
3633 | +}) |
3634 | + |
3635 | +#define map_word_and(map, val1, val2) \ |
3636 | +({ \ |
3637 | + map_word r; \ |
3638 | + int i; \ |
3639 | + for (i = 0; i < map_words(map); i++) \ |
3640 | + r.x[i] = (val1).x[i] & (val2).x[i]; \ |
3641 | + r; \ |
3642 | +}) |
3643 | + |
3644 | +#define map_word_clr(map, val1, val2) \ |
3645 | +({ \ |
3646 | + map_word r; \ |
3647 | + int i; \ |
3648 | + for (i = 0; i < map_words(map); i++) \ |
3649 | + r.x[i] = (val1).x[i] & ~(val2).x[i]; \ |
3650 | + r; \ |
3651 | +}) |
3652 | + |
3653 | +#define map_word_or(map, val1, val2) \ |
3654 | +({ \ |
3655 | + map_word r; \ |
3656 | + int i; \ |
3657 | + for (i = 0; i < map_words(map); i++) \ |
3658 | + r.x[i] = (val1).x[i] | (val2).x[i]; \ |
3659 | + r; \ |
3660 | +}) |
3661 | + |
3662 | +#define map_word_andequal(map, val1, val2, val3) \ |
3663 | +({ \ |
3664 | + int i, ret = 1; \ |
3665 | + for (i = 0; i < map_words(map); i++) { \ |
3666 | + if (((val1).x[i] & (val2).x[i]) != (val2).x[i]) { \ |
3667 | + ret = 0; \ |
3668 | + break; \ |
3669 | + } \ |
3670 | + } \ |
3671 | + ret; \ |
3672 | +}) |
3673 | + |
3674 | +#define map_word_bitsset(map, val1, val2) \ |
3675 | +({ \ |
3676 | + int i, ret = 0; \ |
3677 | + for (i = 0; i < map_words(map); i++) { \ |
3678 | + if ((val1).x[i] & (val2).x[i]) { \ |
3679 | + ret = 1; \ |
3680 | + break; \ |
3681 | + } \ |
3682 | + } \ |
3683 | + ret; \ |
3684 | +}) |
3685 | |
3686 | static inline map_word map_word_load(struct map_info *map, const void *ptr) |
3687 | { |
3688 | diff --git a/kernel/async.c b/kernel/async.c |
3689 | index d2edd6efec56..d84d4860992e 100644 |
3690 | --- a/kernel/async.c |
3691 | +++ b/kernel/async.c |
3692 | @@ -84,20 +84,24 @@ static atomic_t entry_count; |
3693 | |
3694 | static async_cookie_t lowest_in_progress(struct async_domain *domain) |
3695 | { |
3696 | - struct list_head *pending; |
3697 | + struct async_entry *first = NULL; |
3698 | async_cookie_t ret = ASYNC_COOKIE_MAX; |
3699 | unsigned long flags; |
3700 | |
3701 | spin_lock_irqsave(&async_lock, flags); |
3702 | |
3703 | - if (domain) |
3704 | - pending = &domain->pending; |
3705 | - else |
3706 | - pending = &async_global_pending; |
3707 | + if (domain) { |
3708 | + if (!list_empty(&domain->pending)) |
3709 | + first = list_first_entry(&domain->pending, |
3710 | + struct async_entry, domain_list); |
3711 | + } else { |
3712 | + if (!list_empty(&async_global_pending)) |
3713 | + first = list_first_entry(&async_global_pending, |
3714 | + struct async_entry, global_list); |
3715 | + } |
3716 | |
3717 | - if (!list_empty(pending)) |
3718 | - ret = list_first_entry(pending, struct async_entry, |
3719 | - domain_list)->cookie; |
3720 | + if (first) |
3721 | + ret = first->cookie; |
3722 | |
3723 | spin_unlock_irqrestore(&async_lock, flags); |
3724 | return ret; |
3725 | diff --git a/kernel/relay.c b/kernel/relay.c |
3726 | index 8f18d314a96a..2603e04f55f9 100644 |
3727 | --- a/kernel/relay.c |
3728 | +++ b/kernel/relay.c |
3729 | @@ -611,7 +611,6 @@ struct rchan *relay_open(const char *base_filename, |
3730 | |
3731 | kref_put(&chan->kref, relay_destroy_channel); |
3732 | mutex_unlock(&relay_channels_mutex); |
3733 | - kfree(chan); |
3734 | return NULL; |
3735 | } |
3736 | EXPORT_SYMBOL_GPL(relay_open); |
3737 | diff --git a/kernel/sched/core.c b/kernel/sched/core.c |
3738 | index e5066955cc3a..bce3a7ad4253 100644 |
3739 | --- a/kernel/sched/core.c |
3740 | +++ b/kernel/sched/core.c |
3741 | @@ -5864,6 +5864,19 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd) |
3742 | call_rcu_sched(&old_rd->rcu, free_rootdomain); |
3743 | } |
3744 | |
3745 | +void sched_get_rd(struct root_domain *rd) |
3746 | +{ |
3747 | + atomic_inc(&rd->refcount); |
3748 | +} |
3749 | + |
3750 | +void sched_put_rd(struct root_domain *rd) |
3751 | +{ |
3752 | + if (!atomic_dec_and_test(&rd->refcount)) |
3753 | + return; |
3754 | + |
3755 | + call_rcu_sched(&rd->rcu, free_rootdomain); |
3756 | +} |
3757 | + |
3758 | static int init_rootdomain(struct root_domain *rd) |
3759 | { |
3760 | memset(rd, 0, sizeof(*rd)); |
3761 | diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c |
3762 | index 7a360d6f6798..f6d68ddfa2f3 100644 |
3763 | --- a/kernel/sched/rt.c |
3764 | +++ b/kernel/sched/rt.c |
3765 | @@ -1895,9 +1895,8 @@ static void push_rt_tasks(struct rq *rq) |
3766 | * the rt_loop_next will cause the iterator to perform another scan. |
3767 | * |
3768 | */ |
3769 | -static int rto_next_cpu(struct rq *rq) |
3770 | +static int rto_next_cpu(struct root_domain *rd) |
3771 | { |
3772 | - struct root_domain *rd = rq->rd; |
3773 | int next; |
3774 | int cpu; |
3775 | |
3776 | @@ -1973,19 +1972,24 @@ static void tell_cpu_to_push(struct rq *rq) |
3777 | * Otherwise it is finishing up and an ipi needs to be sent. |
3778 | */ |
3779 | if (rq->rd->rto_cpu < 0) |
3780 | - cpu = rto_next_cpu(rq); |
3781 | + cpu = rto_next_cpu(rq->rd); |
3782 | |
3783 | raw_spin_unlock(&rq->rd->rto_lock); |
3784 | |
3785 | rto_start_unlock(&rq->rd->rto_loop_start); |
3786 | |
3787 | - if (cpu >= 0) |
3788 | + if (cpu >= 0) { |
3789 | + /* Make sure the rd does not get freed while pushing */ |
3790 | + sched_get_rd(rq->rd); |
3791 | irq_work_queue_on(&rq->rd->rto_push_work, cpu); |
3792 | + } |
3793 | } |
3794 | |
3795 | /* Called from hardirq context */ |
3796 | void rto_push_irq_work_func(struct irq_work *work) |
3797 | { |
3798 | + struct root_domain *rd = |
3799 | + container_of(work, struct root_domain, rto_push_work); |
3800 | struct rq *rq; |
3801 | int cpu; |
3802 | |
3803 | @@ -2001,18 +2005,20 @@ void rto_push_irq_work_func(struct irq_work *work) |
3804 | raw_spin_unlock(&rq->lock); |
3805 | } |
3806 | |
3807 | - raw_spin_lock(&rq->rd->rto_lock); |
3808 | + raw_spin_lock(&rd->rto_lock); |
3809 | |
3810 | /* Pass the IPI to the next rt overloaded queue */ |
3811 | - cpu = rto_next_cpu(rq); |
3812 | + cpu = rto_next_cpu(rd); |
3813 | |
3814 | - raw_spin_unlock(&rq->rd->rto_lock); |
3815 | + raw_spin_unlock(&rd->rto_lock); |
3816 | |
3817 | - if (cpu < 0) |
3818 | + if (cpu < 0) { |
3819 | + sched_put_rd(rd); |
3820 | return; |
3821 | + } |
3822 | |
3823 | /* Try the next RT overloaded CPU */ |
3824 | - irq_work_queue_on(&rq->rd->rto_push_work, cpu); |
3825 | + irq_work_queue_on(&rd->rto_push_work, cpu); |
3826 | } |
3827 | #endif /* HAVE_RT_PUSH_IPI */ |
3828 | |
3829 | diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h |
3830 | index cff985feb6e7..f564a1d2c9d5 100644 |
3831 | --- a/kernel/sched/sched.h |
3832 | +++ b/kernel/sched/sched.h |
3833 | @@ -590,6 +590,8 @@ struct root_domain { |
3834 | }; |
3835 | |
3836 | extern struct root_domain def_root_domain; |
3837 | +extern void sched_get_rd(struct root_domain *rd); |
3838 | +extern void sched_put_rd(struct root_domain *rd); |
3839 | |
3840 | #ifdef HAVE_RT_PUSH_IPI |
3841 | extern void rto_push_irq_work_func(struct irq_work *work); |
3842 | diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c |
3843 | index f2826c35e918..fc7c37ad90a0 100644 |
3844 | --- a/kernel/time/posix-timers.c |
3845 | +++ b/kernel/time/posix-timers.c |
3846 | @@ -507,17 +507,22 @@ static struct pid *good_sigevent(sigevent_t * event) |
3847 | { |
3848 | struct task_struct *rtn = current->group_leader; |
3849 | |
3850 | - if ((event->sigev_notify & SIGEV_THREAD_ID ) && |
3851 | - (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || |
3852 | - !same_thread_group(rtn, current) || |
3853 | - (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) |
3854 | + switch (event->sigev_notify) { |
3855 | + case SIGEV_SIGNAL | SIGEV_THREAD_ID: |
3856 | + rtn = find_task_by_vpid(event->sigev_notify_thread_id); |
3857 | + if (!rtn || !same_thread_group(rtn, current)) |
3858 | + return NULL; |
3859 | + /* FALLTHRU */ |
3860 | + case SIGEV_SIGNAL: |
3861 | + case SIGEV_THREAD: |
3862 | + if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) |
3863 | + return NULL; |
3864 | + /* FALLTHRU */ |
3865 | + case SIGEV_NONE: |
3866 | + return task_pid(rtn); |
3867 | + default: |
3868 | return NULL; |
3869 | - |
3870 | - if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && |
3871 | - ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX))) |
3872 | - return NULL; |
3873 | - |
3874 | - return task_pid(rtn); |
3875 | + } |
3876 | } |
3877 | |
3878 | void posix_timers_register_clock(const clockid_t clock_id, |
3879 | @@ -745,8 +750,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) |
3880 | /* interval timer ? */ |
3881 | if (iv.tv64) |
3882 | cur_setting->it_interval = ktime_to_timespec(iv); |
3883 | - else if (!hrtimer_active(timer) && |
3884 | - (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) |
3885 | + else if (!hrtimer_active(timer) && timr->it_sigev_notify != SIGEV_NONE) |
3886 | return; |
3887 | |
3888 | now = timer->base->get_time(); |
3889 | @@ -757,7 +761,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) |
3890 | * expiry is > now. |
3891 | */ |
3892 | if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING || |
3893 | - (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) |
3894 | + timr->it_sigev_notify == SIGEV_NONE)) |
3895 | timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv); |
3896 | |
3897 | remaining = __hrtimer_expires_remaining_adjusted(timer, now); |
3898 | @@ -767,7 +771,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) |
3899 | * A single shot SIGEV_NONE timer must return 0, when |
3900 | * it is expired ! |
3901 | */ |
3902 | - if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) |
3903 | + if (timr->it_sigev_notify != SIGEV_NONE) |
3904 | cur_setting->it_value.tv_nsec = 1; |
3905 | } else |
3906 | cur_setting->it_value = ktime_to_timespec(remaining); |
3907 | @@ -865,7 +869,7 @@ common_timer_set(struct k_itimer *timr, int flags, |
3908 | timr->it.real.interval = timespec_to_ktime(new_setting->it_interval); |
3909 | |
3910 | /* SIGEV_NONE timers are not queued ! See common_timer_get */ |
3911 | - if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { |
3912 | + if (timr->it_sigev_notify == SIGEV_NONE) { |
3913 | /* Setup correct expiry time for relative timers */ |
3914 | if (mode == HRTIMER_MODE_REL) { |
3915 | hrtimer_add_expires(timer, timer->base->get_time()); |
3916 | diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c |
3917 | index 5b8d7189e147..2884fe01cb54 100644 |
3918 | --- a/kernel/trace/ftrace.c |
3919 | +++ b/kernel/trace/ftrace.c |
3920 | @@ -3911,7 +3911,6 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, |
3921 | func_g.type = filter_parse_regex(glob, strlen(glob), |
3922 | &func_g.search, ¬); |
3923 | func_g.len = strlen(func_g.search); |
3924 | - func_g.search = glob; |
3925 | |
3926 | /* we do not support '!' for function probes */ |
3927 | if (WARN_ON(not)) |
3928 | diff --git a/lib/ubsan.c b/lib/ubsan.c |
3929 | index fb0409df1bcf..50d1d5c25deb 100644 |
3930 | --- a/lib/ubsan.c |
3931 | +++ b/lib/ubsan.c |
3932 | @@ -265,14 +265,14 @@ void __ubsan_handle_divrem_overflow(struct overflow_data *data, |
3933 | } |
3934 | EXPORT_SYMBOL(__ubsan_handle_divrem_overflow); |
3935 | |
3936 | -static void handle_null_ptr_deref(struct type_mismatch_data *data) |
3937 | +static void handle_null_ptr_deref(struct type_mismatch_data_common *data) |
3938 | { |
3939 | unsigned long flags; |
3940 | |
3941 | - if (suppress_report(&data->location)) |
3942 | + if (suppress_report(data->location)) |
3943 | return; |
3944 | |
3945 | - ubsan_prologue(&data->location, &flags); |
3946 | + ubsan_prologue(data->location, &flags); |
3947 | |
3948 | pr_err("%s null pointer of type %s\n", |
3949 | type_check_kinds[data->type_check_kind], |
3950 | @@ -281,15 +281,15 @@ static void handle_null_ptr_deref(struct type_mismatch_data *data) |
3951 | ubsan_epilogue(&flags); |
3952 | } |
3953 | |
3954 | -static void handle_missaligned_access(struct type_mismatch_data *data, |
3955 | +static void handle_misaligned_access(struct type_mismatch_data_common *data, |
3956 | unsigned long ptr) |
3957 | { |
3958 | unsigned long flags; |
3959 | |
3960 | - if (suppress_report(&data->location)) |
3961 | + if (suppress_report(data->location)) |
3962 | return; |
3963 | |
3964 | - ubsan_prologue(&data->location, &flags); |
3965 | + ubsan_prologue(data->location, &flags); |
3966 | |
3967 | pr_err("%s misaligned address %p for type %s\n", |
3968 | type_check_kinds[data->type_check_kind], |
3969 | @@ -299,15 +299,15 @@ static void handle_missaligned_access(struct type_mismatch_data *data, |
3970 | ubsan_epilogue(&flags); |
3971 | } |
3972 | |
3973 | -static void handle_object_size_mismatch(struct type_mismatch_data *data, |
3974 | +static void handle_object_size_mismatch(struct type_mismatch_data_common *data, |
3975 | unsigned long ptr) |
3976 | { |
3977 | unsigned long flags; |
3978 | |
3979 | - if (suppress_report(&data->location)) |
3980 | + if (suppress_report(data->location)) |
3981 | return; |
3982 | |
3983 | - ubsan_prologue(&data->location, &flags); |
3984 | + ubsan_prologue(data->location, &flags); |
3985 | pr_err("%s address %p with insufficient space\n", |
3986 | type_check_kinds[data->type_check_kind], |
3987 | (void *) ptr); |
3988 | @@ -315,19 +315,47 @@ static void handle_object_size_mismatch(struct type_mismatch_data *data, |
3989 | ubsan_epilogue(&flags); |
3990 | } |
3991 | |
3992 | -void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, |
3993 | +static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data, |
3994 | unsigned long ptr) |
3995 | { |
3996 | |
3997 | if (!ptr) |
3998 | handle_null_ptr_deref(data); |
3999 | else if (data->alignment && !IS_ALIGNED(ptr, data->alignment)) |
4000 | - handle_missaligned_access(data, ptr); |
4001 | + handle_misaligned_access(data, ptr); |
4002 | else |
4003 | handle_object_size_mismatch(data, ptr); |
4004 | } |
4005 | + |
4006 | +void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, |
4007 | + unsigned long ptr) |
4008 | +{ |
4009 | + struct type_mismatch_data_common common_data = { |
4010 | + .location = &data->location, |
4011 | + .type = data->type, |
4012 | + .alignment = data->alignment, |
4013 | + .type_check_kind = data->type_check_kind |
4014 | + }; |
4015 | + |
4016 | + ubsan_type_mismatch_common(&common_data, ptr); |
4017 | +} |
4018 | EXPORT_SYMBOL(__ubsan_handle_type_mismatch); |
4019 | |
4020 | +void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data, |
4021 | + unsigned long ptr) |
4022 | +{ |
4023 | + |
4024 | + struct type_mismatch_data_common common_data = { |
4025 | + .location = &data->location, |
4026 | + .type = data->type, |
4027 | + .alignment = 1UL << data->log_alignment, |
4028 | + .type_check_kind = data->type_check_kind |
4029 | + }; |
4030 | + |
4031 | + ubsan_type_mismatch_common(&common_data, ptr); |
4032 | +} |
4033 | +EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1); |
4034 | + |
4035 | void __ubsan_handle_nonnull_return(struct nonnull_return_data *data) |
4036 | { |
4037 | unsigned long flags; |
4038 | diff --git a/lib/ubsan.h b/lib/ubsan.h |
4039 | index b2d18d4a53f5..d8b8085e5dac 100644 |
4040 | --- a/lib/ubsan.h |
4041 | +++ b/lib/ubsan.h |
4042 | @@ -36,6 +36,20 @@ struct type_mismatch_data { |
4043 | unsigned char type_check_kind; |
4044 | }; |
4045 | |
4046 | +struct type_mismatch_data_v1 { |
4047 | + struct source_location location; |
4048 | + struct type_descriptor *type; |
4049 | + unsigned char log_alignment; |
4050 | + unsigned char type_check_kind; |
4051 | +}; |
4052 | + |
4053 | +struct type_mismatch_data_common { |
4054 | + struct source_location *location; |
4055 | + struct type_descriptor *type; |
4056 | + unsigned long alignment; |
4057 | + unsigned char type_check_kind; |
4058 | +}; |
4059 | + |
4060 | struct nonnull_arg_data { |
4061 | struct source_location location; |
4062 | struct source_location attr_location; |
4063 | diff --git a/net/dccp/proto.c b/net/dccp/proto.c |
4064 | index b68168fcc06a..9d43c1f40274 100644 |
4065 | --- a/net/dccp/proto.c |
4066 | +++ b/net/dccp/proto.c |
4067 | @@ -259,6 +259,7 @@ int dccp_disconnect(struct sock *sk, int flags) |
4068 | { |
4069 | struct inet_connection_sock *icsk = inet_csk(sk); |
4070 | struct inet_sock *inet = inet_sk(sk); |
4071 | + struct dccp_sock *dp = dccp_sk(sk); |
4072 | int err = 0; |
4073 | const int old_state = sk->sk_state; |
4074 | |
4075 | @@ -278,6 +279,10 @@ int dccp_disconnect(struct sock *sk, int flags) |
4076 | sk->sk_err = ECONNRESET; |
4077 | |
4078 | dccp_clear_xmit_timers(sk); |
4079 | + ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk); |
4080 | + ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); |
4081 | + dp->dccps_hc_rx_ccid = NULL; |
4082 | + dp->dccps_hc_tx_ccid = NULL; |
4083 | |
4084 | __skb_queue_purge(&sk->sk_receive_queue); |
4085 | __skb_queue_purge(&sk->sk_write_queue); |
4086 | diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c |
4087 | index 3f8e6f0b7eb5..dcf03691ebc8 100644 |
4088 | --- a/sound/soc/intel/skylake/skl-nhlt.c |
4089 | +++ b/sound/soc/intel/skylake/skl-nhlt.c |
4090 | @@ -41,7 +41,8 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev) |
4091 | obj = acpi_evaluate_dsm(handle, OSC_UUID, 1, 1, NULL); |
4092 | if (obj && obj->type == ACPI_TYPE_BUFFER) { |
4093 | nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; |
4094 | - nhlt_table = (struct nhlt_acpi_table *) |
4095 | + if (nhlt_ptr->length) |
4096 | + nhlt_table = (struct nhlt_acpi_table *) |
4097 | memremap(nhlt_ptr->min_addr, nhlt_ptr->length, |
4098 | MEMREMAP_WB); |
4099 | ACPI_FREE(obj); |
4100 | diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c |
4101 | index 974915cb4c4f..08bfee447a36 100644 |
4102 | --- a/sound/soc/rockchip/rockchip_i2s.c |
4103 | +++ b/sound/soc/rockchip/rockchip_i2s.c |
4104 | @@ -476,6 +476,7 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg) |
4105 | case I2S_INTCR: |
4106 | case I2S_XFER: |
4107 | case I2S_CLR: |
4108 | + case I2S_TXDR: |
4109 | case I2S_RXDR: |
4110 | case I2S_FIFOLR: |
4111 | case I2S_INTSR: |
4112 | @@ -490,6 +491,9 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) |
4113 | switch (reg) { |
4114 | case I2S_INTSR: |
4115 | case I2S_CLR: |
4116 | + case I2S_FIFOLR: |
4117 | + case I2S_TXDR: |
4118 | + case I2S_RXDR: |
4119 | return true; |
4120 | default: |
4121 | return false; |
4122 | @@ -499,6 +503,8 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) |
4123 | static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg) |
4124 | { |
4125 | switch (reg) { |
4126 | + case I2S_RXDR: |
4127 | + return true; |
4128 | default: |
4129 | return false; |
4130 | } |