Contents of /trunk/kernel-alx-legacy/patches-4.9/0144-4.9.45-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: 32601 byte(s)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 32601 byte(s)
-added kerenl-alx-legacy pkg
1 | diff --git a/Makefile b/Makefile |
2 | index 3e95dfdbe572..ccd6d91f616e 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 9 |
8 | -SUBLEVEL = 44 |
9 | +SUBLEVEL = 45 |
10 | EXTRAVERSION = |
11 | NAME = Roaring Lionus |
12 | |
13 | diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h |
14 | index afa23b057def..1fb023076dfc 100644 |
15 | --- a/arch/arm64/include/asm/elf.h |
16 | +++ b/arch/arm64/include/asm/elf.h |
17 | @@ -114,10 +114,10 @@ |
18 | |
19 | /* |
20 | * This is the base location for PIE (ET_DYN with INTERP) loads. On |
21 | - * 64-bit, this is raised to 4GB to leave the entire 32-bit address |
22 | + * 64-bit, this is above 4GB to leave the entire 32-bit address |
23 | * space open for things that want to use the area for 32-bit pointers. |
24 | */ |
25 | -#define ELF_ET_DYN_BASE 0x100000000UL |
26 | +#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3) |
27 | |
28 | #ifndef __ASSEMBLY__ |
29 | |
30 | diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c |
31 | index b249c2fb99c8..1c141d50fbc6 100644 |
32 | --- a/arch/powerpc/kernel/process.c |
33 | +++ b/arch/powerpc/kernel/process.c |
34 | @@ -359,7 +359,8 @@ void enable_kernel_vsx(void) |
35 | |
36 | cpumsr = msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); |
37 | |
38 | - if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) { |
39 | + if (current->thread.regs && |
40 | + (current->thread.regs->msr & (MSR_VSX|MSR_VEC|MSR_FP))) { |
41 | check_if_tm_restore_required(current); |
42 | /* |
43 | * If a thread has already been reclaimed then the |
44 | @@ -383,7 +384,7 @@ void flush_vsx_to_thread(struct task_struct *tsk) |
45 | { |
46 | if (tsk->thread.regs) { |
47 | preempt_disable(); |
48 | - if (tsk->thread.regs->msr & MSR_VSX) { |
49 | + if (tsk->thread.regs->msr & (MSR_VSX|MSR_VEC|MSR_FP)) { |
50 | BUG_ON(tsk != current); |
51 | giveup_vsx(tsk); |
52 | } |
53 | diff --git a/arch/x86/crypto/sha1_avx2_x86_64_asm.S b/arch/x86/crypto/sha1_avx2_x86_64_asm.S |
54 | index 1cd792db15ef..1eab79c9ac48 100644 |
55 | --- a/arch/x86/crypto/sha1_avx2_x86_64_asm.S |
56 | +++ b/arch/x86/crypto/sha1_avx2_x86_64_asm.S |
57 | @@ -117,11 +117,10 @@ |
58 | .set T1, REG_T1 |
59 | .endm |
60 | |
61 | -#define K_BASE %r8 |
62 | #define HASH_PTR %r9 |
63 | +#define BLOCKS_CTR %r8 |
64 | #define BUFFER_PTR %r10 |
65 | #define BUFFER_PTR2 %r13 |
66 | -#define BUFFER_END %r11 |
67 | |
68 | #define PRECALC_BUF %r14 |
69 | #define WK_BUF %r15 |
70 | @@ -205,14 +204,14 @@ |
71 | * blended AVX2 and ALU instruction scheduling |
72 | * 1 vector iteration per 8 rounds |
73 | */ |
74 | - vmovdqu ((i * 2) + PRECALC_OFFSET)(BUFFER_PTR), W_TMP |
75 | + vmovdqu (i * 2)(BUFFER_PTR), W_TMP |
76 | .elseif ((i & 7) == 1) |
77 | - vinsertf128 $1, (((i-1) * 2)+PRECALC_OFFSET)(BUFFER_PTR2),\ |
78 | + vinsertf128 $1, ((i-1) * 2)(BUFFER_PTR2),\ |
79 | WY_TMP, WY_TMP |
80 | .elseif ((i & 7) == 2) |
81 | vpshufb YMM_SHUFB_BSWAP, WY_TMP, WY |
82 | .elseif ((i & 7) == 4) |
83 | - vpaddd K_XMM(K_BASE), WY, WY_TMP |
84 | + vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP |
85 | .elseif ((i & 7) == 7) |
86 | vmovdqu WY_TMP, PRECALC_WK(i&~7) |
87 | |
88 | @@ -255,7 +254,7 @@ |
89 | vpxor WY, WY_TMP, WY_TMP |
90 | .elseif ((i & 7) == 7) |
91 | vpxor WY_TMP2, WY_TMP, WY |
92 | - vpaddd K_XMM(K_BASE), WY, WY_TMP |
93 | + vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP |
94 | vmovdqu WY_TMP, PRECALC_WK(i&~7) |
95 | |
96 | PRECALC_ROTATE_WY |
97 | @@ -291,7 +290,7 @@ |
98 | vpsrld $30, WY, WY |
99 | vpor WY, WY_TMP, WY |
100 | .elseif ((i & 7) == 7) |
101 | - vpaddd K_XMM(K_BASE), WY, WY_TMP |
102 | + vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP |
103 | vmovdqu WY_TMP, PRECALC_WK(i&~7) |
104 | |
105 | PRECALC_ROTATE_WY |
106 | @@ -446,6 +445,16 @@ |
107 | |
108 | .endm |
109 | |
110 | +/* Add constant only if (%2 > %3) condition met (uses RTA as temp) |
111 | + * %1 + %2 >= %3 ? %4 : 0 |
112 | + */ |
113 | +.macro ADD_IF_GE a, b, c, d |
114 | + mov \a, RTA |
115 | + add $\d, RTA |
116 | + cmp $\c, \b |
117 | + cmovge RTA, \a |
118 | +.endm |
119 | + |
120 | /* |
121 | * macro implements 80 rounds of SHA-1, for multiple blocks with s/w pipelining |
122 | */ |
123 | @@ -463,13 +472,16 @@ |
124 | lea (2*4*80+32)(%rsp), WK_BUF |
125 | |
126 | # Precalc WK for first 2 blocks |
127 | - PRECALC_OFFSET = 0 |
128 | + ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 2, 64 |
129 | .set i, 0 |
130 | .rept 160 |
131 | PRECALC i |
132 | .set i, i + 1 |
133 | .endr |
134 | - PRECALC_OFFSET = 128 |
135 | + |
136 | + /* Go to next block if needed */ |
137 | + ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 3, 128 |
138 | + ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128 |
139 | xchg WK_BUF, PRECALC_BUF |
140 | |
141 | .align 32 |
142 | @@ -479,8 +491,8 @@ _loop: |
143 | * we use K_BASE value as a signal of a last block, |
144 | * it is set below by: cmovae BUFFER_PTR, K_BASE |
145 | */ |
146 | - cmp K_BASE, BUFFER_PTR |
147 | - jne _begin |
148 | + test BLOCKS_CTR, BLOCKS_CTR |
149 | + jnz _begin |
150 | .align 32 |
151 | jmp _end |
152 | .align 32 |
153 | @@ -512,10 +524,10 @@ _loop0: |
154 | .set j, j+2 |
155 | .endr |
156 | |
157 | - add $(2*64), BUFFER_PTR /* move to next odd-64-byte block */ |
158 | - cmp BUFFER_END, BUFFER_PTR /* is current block the last one? */ |
159 | - cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */ |
160 | - |
161 | + /* Update Counter */ |
162 | + sub $1, BLOCKS_CTR |
163 | + /* Move to the next block only if needed*/ |
164 | + ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 4, 128 |
165 | /* |
166 | * rounds |
167 | * 60,62,64,66,68 |
168 | @@ -532,8 +544,8 @@ _loop0: |
169 | UPDATE_HASH 12(HASH_PTR), D |
170 | UPDATE_HASH 16(HASH_PTR), E |
171 | |
172 | - cmp K_BASE, BUFFER_PTR /* is current block the last one? */ |
173 | - je _loop |
174 | + test BLOCKS_CTR, BLOCKS_CTR |
175 | + jz _loop |
176 | |
177 | mov TB, B |
178 | |
179 | @@ -575,10 +587,10 @@ _loop2: |
180 | .set j, j+2 |
181 | .endr |
182 | |
183 | - add $(2*64), BUFFER_PTR2 /* move to next even-64-byte block */ |
184 | - |
185 | - cmp BUFFER_END, BUFFER_PTR2 /* is current block the last one */ |
186 | - cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */ |
187 | + /* update counter */ |
188 | + sub $1, BLOCKS_CTR |
189 | + /* Move to the next block only if needed*/ |
190 | + ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128 |
191 | |
192 | jmp _loop3 |
193 | _loop3: |
194 | @@ -641,19 +653,12 @@ _loop3: |
195 | |
196 | avx2_zeroupper |
197 | |
198 | - lea K_XMM_AR(%rip), K_BASE |
199 | - |
200 | + /* Setup initial values */ |
201 | mov CTX, HASH_PTR |
202 | mov BUF, BUFFER_PTR |
203 | - lea 64(BUF), BUFFER_PTR2 |
204 | - |
205 | - shl $6, CNT /* mul by 64 */ |
206 | - add BUF, CNT |
207 | - add $64, CNT |
208 | - mov CNT, BUFFER_END |
209 | |
210 | - cmp BUFFER_END, BUFFER_PTR2 |
211 | - cmovae K_BASE, BUFFER_PTR2 |
212 | + mov BUF, BUFFER_PTR2 |
213 | + mov CNT, BLOCKS_CTR |
214 | |
215 | xmm_mov BSWAP_SHUFB_CTL(%rip), YMM_SHUFB_BSWAP |
216 | |
217 | diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c |
218 | index f960a043cdeb..fc61739150e7 100644 |
219 | --- a/arch/x86/crypto/sha1_ssse3_glue.c |
220 | +++ b/arch/x86/crypto/sha1_ssse3_glue.c |
221 | @@ -201,7 +201,7 @@ asmlinkage void sha1_transform_avx2(u32 *digest, const char *data, |
222 | |
223 | static bool avx2_usable(void) |
224 | { |
225 | - if (false && avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) |
226 | + if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) |
227 | && boot_cpu_has(X86_FEATURE_BMI1) |
228 | && boot_cpu_has(X86_FEATURE_BMI2)) |
229 | return true; |
230 | diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S |
231 | index ef766a358b37..e7b0e7ff4c58 100644 |
232 | --- a/arch/x86/entry/entry_64.S |
233 | +++ b/arch/x86/entry/entry_64.S |
234 | @@ -1215,6 +1215,8 @@ ENTRY(nmi) |
235 | * other IST entries. |
236 | */ |
237 | |
238 | + ASM_CLAC |
239 | + |
240 | /* Use %rdx as our temp variable throughout */ |
241 | pushq %rdx |
242 | |
243 | diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h |
244 | index c152db2ab687..b31761ecce63 100644 |
245 | --- a/arch/x86/include/asm/elf.h |
246 | +++ b/arch/x86/include/asm/elf.h |
247 | @@ -247,11 +247,11 @@ extern int force_personality32; |
248 | |
249 | /* |
250 | * This is the base location for PIE (ET_DYN with INTERP) loads. On |
251 | - * 64-bit, this is raised to 4GB to leave the entire 32-bit address |
252 | + * 64-bit, this is above 4GB to leave the entire 32-bit address |
253 | * space open for things that want to use the area for 32-bit pointers. |
254 | */ |
255 | #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \ |
256 | - 0x100000000UL) |
257 | + (TASK_SIZE / 3 * 2)) |
258 | |
259 | /* This yields a mask that user programs can use to figure out what |
260 | instruction set this CPU supports. This could be done in user space, |
261 | diff --git a/block/blk-mq-pci.c b/block/blk-mq-pci.c |
262 | index 966c2169762e..ee9d3d958fbe 100644 |
263 | --- a/block/blk-mq-pci.c |
264 | +++ b/block/blk-mq-pci.c |
265 | @@ -36,12 +36,18 @@ int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev) |
266 | for (queue = 0; queue < set->nr_hw_queues; queue++) { |
267 | mask = pci_irq_get_affinity(pdev, queue); |
268 | if (!mask) |
269 | - return -EINVAL; |
270 | + goto fallback; |
271 | |
272 | for_each_cpu(cpu, mask) |
273 | set->mq_map[cpu] = queue; |
274 | } |
275 | |
276 | return 0; |
277 | + |
278 | +fallback: |
279 | + WARN_ON_ONCE(set->nr_hw_queues > 1); |
280 | + for_each_possible_cpu(cpu) |
281 | + set->mq_map[cpu] = 0; |
282 | + return 0; |
283 | } |
284 | EXPORT_SYMBOL_GPL(blk_mq_pci_map_queues); |
285 | diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c |
286 | index 9908597c5209..f11d62de2272 100644 |
287 | --- a/drivers/block/xen-blkfront.c |
288 | +++ b/drivers/block/xen-blkfront.c |
289 | @@ -2112,9 +2112,9 @@ static int blkfront_resume(struct xenbus_device *dev) |
290 | /* |
291 | * Get the bios in the request so we can re-queue them. |
292 | */ |
293 | - if (req_op(shadow[i].request) == REQ_OP_FLUSH || |
294 | - req_op(shadow[i].request) == REQ_OP_DISCARD || |
295 | - req_op(shadow[i].request) == REQ_OP_SECURE_ERASE || |
296 | + if (req_op(shadow[j].request) == REQ_OP_FLUSH || |
297 | + req_op(shadow[j].request) == REQ_OP_DISCARD || |
298 | + req_op(shadow[j].request) == REQ_OP_SECURE_ERASE || |
299 | shadow[j].request->cmd_flags & REQ_FUA) { |
300 | /* |
301 | * Flush operations don't contain bios, so |
302 | diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c |
303 | index 7868765a70c5..b54af97a20bb 100644 |
304 | --- a/drivers/crypto/ixp4xx_crypto.c |
305 | +++ b/drivers/crypto/ixp4xx_crypto.c |
306 | @@ -1074,7 +1074,7 @@ static int aead_perform(struct aead_request *req, int encrypt, |
307 | req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags, |
308 | &crypt->icv_rev_aes); |
309 | if (unlikely(!req_ctx->hmac_virt)) |
310 | - goto free_buf_src; |
311 | + goto free_buf_dst; |
312 | if (!encrypt) { |
313 | scatterwalk_map_and_copy(req_ctx->hmac_virt, |
314 | req->src, cryptlen, authsize, 0); |
315 | @@ -1089,10 +1089,10 @@ static int aead_perform(struct aead_request *req, int encrypt, |
316 | BUG_ON(qmgr_stat_overflow(SEND_QID)); |
317 | return -EINPROGRESS; |
318 | |
319 | -free_buf_src: |
320 | - free_buf_chain(dev, req_ctx->src, crypt->src_buf); |
321 | free_buf_dst: |
322 | free_buf_chain(dev, req_ctx->dst, crypt->dst_buf); |
323 | +free_buf_src: |
324 | + free_buf_chain(dev, req_ctx->src, crypt->src_buf); |
325 | crypt->ctl_flags = CTL_FLAG_UNUSED; |
326 | return -ENOMEM; |
327 | } |
328 | diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c |
329 | index da5458dfb1e3..98d4e515587a 100644 |
330 | --- a/drivers/input/mouse/elan_i2c_core.c |
331 | +++ b/drivers/input/mouse/elan_i2c_core.c |
332 | @@ -1235,6 +1235,10 @@ static const struct acpi_device_id elan_acpi_id[] = { |
333 | { "ELAN0100", 0 }, |
334 | { "ELAN0600", 0 }, |
335 | { "ELAN0605", 0 }, |
336 | + { "ELAN0608", 0 }, |
337 | + { "ELAN0605", 0 }, |
338 | + { "ELAN0609", 0 }, |
339 | + { "ELAN060B", 0 }, |
340 | { "ELAN1000", 0 }, |
341 | { } |
342 | }; |
343 | diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c |
344 | index 28b26c80f4cf..056507099725 100644 |
345 | --- a/drivers/irqchip/irq-atmel-aic-common.c |
346 | +++ b/drivers/irqchip/irq-atmel-aic-common.c |
347 | @@ -142,9 +142,9 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root) |
348 | struct device_node *np; |
349 | void __iomem *regs; |
350 | |
351 | - np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc"); |
352 | + np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc"); |
353 | if (!np) |
354 | - np = of_find_compatible_node(root, NULL, |
355 | + np = of_find_compatible_node(NULL, NULL, |
356 | "atmel,at91sam9x5-rtc"); |
357 | |
358 | if (!np) |
359 | @@ -196,7 +196,6 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches) |
360 | return; |
361 | |
362 | match = of_match_node(matches, root); |
363 | - of_node_put(root); |
364 | |
365 | if (match) { |
366 | void (*fixup)(struct device_node *) = match->data; |
367 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c |
368 | index 2f260c63c383..49a27dc46e5e 100644 |
369 | --- a/drivers/net/usb/qmi_wwan.c |
370 | +++ b/drivers/net/usb/qmi_wwan.c |
371 | @@ -876,6 +876,7 @@ static const struct usb_device_id products[] = { |
372 | {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */ |
373 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ |
374 | {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ |
375 | + {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */ |
376 | {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ |
377 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ |
378 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
379 | diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c |
380 | index 5c63b920b471..ed92c1254cff 100644 |
381 | --- a/drivers/parisc/dino.c |
382 | +++ b/drivers/parisc/dino.c |
383 | @@ -956,7 +956,7 @@ static int __init dino_probe(struct parisc_device *dev) |
384 | |
385 | dino_dev->hba.dev = dev; |
386 | dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); |
387 | - dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ |
388 | + dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND; |
389 | spin_lock_init(&dino_dev->dinosaur_pen); |
390 | dino_dev->hba.iommu = ccio_get_iommu(dev); |
391 | |
392 | diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c |
393 | index 2776cfe64c09..ef9cf4a21afe 100644 |
394 | --- a/drivers/usb/core/usb-acpi.c |
395 | +++ b/drivers/usb/core/usb-acpi.c |
396 | @@ -127,6 +127,22 @@ static enum usb_port_connect_type usb_acpi_get_connect_type(acpi_handle handle, |
397 | */ |
398 | #define USB_ACPI_LOCATION_VALID (1 << 31) |
399 | |
400 | +static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent, |
401 | + int raw) |
402 | +{ |
403 | + struct acpi_device *adev; |
404 | + |
405 | + if (!parent) |
406 | + return NULL; |
407 | + |
408 | + list_for_each_entry(adev, &parent->children, node) { |
409 | + if (acpi_device_adr(adev) == raw) |
410 | + return adev; |
411 | + } |
412 | + |
413 | + return acpi_find_child_device(parent, raw, false); |
414 | +} |
415 | + |
416 | static struct acpi_device *usb_acpi_find_companion(struct device *dev) |
417 | { |
418 | struct usb_device *udev; |
419 | @@ -174,8 +190,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev) |
420 | int raw; |
421 | |
422 | raw = usb_hcd_find_raw_port_number(hcd, port1); |
423 | - adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev), |
424 | - raw, false); |
425 | + |
426 | + adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev), |
427 | + raw); |
428 | + |
429 | if (!adev) |
430 | return NULL; |
431 | } else { |
432 | @@ -186,7 +204,9 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev) |
433 | return NULL; |
434 | |
435 | acpi_bus_get_device(parent_handle, &adev); |
436 | - adev = acpi_find_child_device(adev, port1, false); |
437 | + |
438 | + adev = usb_acpi_find_port(adev, port1); |
439 | + |
440 | if (!adev) |
441 | return NULL; |
442 | } |
443 | diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c |
444 | index 4da69dbf7dca..1bdd02a6d6ac 100644 |
445 | --- a/drivers/xen/biomerge.c |
446 | +++ b/drivers/xen/biomerge.c |
447 | @@ -10,8 +10,7 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, |
448 | unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page)); |
449 | unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page)); |
450 | |
451 | - return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && |
452 | - ((bfn1 == bfn2) || ((bfn1+1) == bfn2)); |
453 | + return bfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == bfn2; |
454 | #else |
455 | /* |
456 | * XXX: Add support for merging bio_vec when using different page |
457 | diff --git a/include/linux/memblock.h b/include/linux/memblock.h |
458 | index e8fba68e5d03..4024af00b137 100644 |
459 | --- a/include/linux/memblock.h |
460 | +++ b/include/linux/memblock.h |
461 | @@ -64,6 +64,7 @@ extern bool movable_node_enabled; |
462 | #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK |
463 | #define __init_memblock __meminit |
464 | #define __initdata_memblock __meminitdata |
465 | +void memblock_discard(void); |
466 | #else |
467 | #define __init_memblock |
468 | #define __initdata_memblock |
469 | @@ -77,8 +78,6 @@ phys_addr_t memblock_find_in_range_node(phys_addr_t size, phys_addr_t align, |
470 | int nid, ulong flags); |
471 | phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end, |
472 | phys_addr_t size, phys_addr_t align); |
473 | -phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr); |
474 | -phys_addr_t get_allocated_memblock_memory_regions_info(phys_addr_t *addr); |
475 | void memblock_allow_resize(void); |
476 | int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid); |
477 | int memblock_add(phys_addr_t base, phys_addr_t size); |
478 | @@ -112,6 +111,9 @@ void __next_mem_range_rev(u64 *idx, int nid, ulong flags, |
479 | void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start, |
480 | phys_addr_t *out_end); |
481 | |
482 | +void __memblock_free_early(phys_addr_t base, phys_addr_t size); |
483 | +void __memblock_free_late(phys_addr_t base, phys_addr_t size); |
484 | + |
485 | /** |
486 | * for_each_mem_range - iterate through memblock areas from type_a and not |
487 | * included in type_b. Or just type_a if type_b is NULL. |
488 | diff --git a/include/linux/pid.h b/include/linux/pid.h |
489 | index 23705a53abba..97b745ddece5 100644 |
490 | --- a/include/linux/pid.h |
491 | +++ b/include/linux/pid.h |
492 | @@ -8,7 +8,9 @@ enum pid_type |
493 | PIDTYPE_PID, |
494 | PIDTYPE_PGID, |
495 | PIDTYPE_SID, |
496 | - PIDTYPE_MAX |
497 | + PIDTYPE_MAX, |
498 | + /* only valid to __task_pid_nr_ns() */ |
499 | + __PIDTYPE_TGID |
500 | }; |
501 | |
502 | /* |
503 | diff --git a/include/linux/sched.h b/include/linux/sched.h |
504 | index 14f58cf06054..a4d0afc009a7 100644 |
505 | --- a/include/linux/sched.h |
506 | +++ b/include/linux/sched.h |
507 | @@ -2132,31 +2132,8 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) |
508 | return tsk->tgid; |
509 | } |
510 | |
511 | -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
512 | - |
513 | -static inline pid_t task_tgid_vnr(struct task_struct *tsk) |
514 | -{ |
515 | - return pid_vnr(task_tgid(tsk)); |
516 | -} |
517 | - |
518 | |
519 | static inline int pid_alive(const struct task_struct *p); |
520 | -static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) |
521 | -{ |
522 | - pid_t pid = 0; |
523 | - |
524 | - rcu_read_lock(); |
525 | - if (pid_alive(tsk)) |
526 | - pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); |
527 | - rcu_read_unlock(); |
528 | - |
529 | - return pid; |
530 | -} |
531 | - |
532 | -static inline pid_t task_ppid_nr(const struct task_struct *tsk) |
533 | -{ |
534 | - return task_ppid_nr_ns(tsk, &init_pid_ns); |
535 | -} |
536 | |
537 | static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, |
538 | struct pid_namespace *ns) |
539 | @@ -2181,6 +2158,33 @@ static inline pid_t task_session_vnr(struct task_struct *tsk) |
540 | return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); |
541 | } |
542 | |
543 | +static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) |
544 | +{ |
545 | + return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns); |
546 | +} |
547 | + |
548 | +static inline pid_t task_tgid_vnr(struct task_struct *tsk) |
549 | +{ |
550 | + return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL); |
551 | +} |
552 | + |
553 | +static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) |
554 | +{ |
555 | + pid_t pid = 0; |
556 | + |
557 | + rcu_read_lock(); |
558 | + if (pid_alive(tsk)) |
559 | + pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); |
560 | + rcu_read_unlock(); |
561 | + |
562 | + return pid; |
563 | +} |
564 | + |
565 | +static inline pid_t task_ppid_nr(const struct task_struct *tsk) |
566 | +{ |
567 | + return task_ppid_nr_ns(tsk, &init_pid_ns); |
568 | +} |
569 | + |
570 | /* obsolete, do not use */ |
571 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) |
572 | { |
573 | diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c |
574 | index 0d302a87f21b..690e1e3c59f7 100644 |
575 | --- a/kernel/audit_watch.c |
576 | +++ b/kernel/audit_watch.c |
577 | @@ -457,13 +457,15 @@ void audit_remove_watch_rule(struct audit_krule *krule) |
578 | list_del(&krule->rlist); |
579 | |
580 | if (list_empty(&watch->rules)) { |
581 | + /* |
582 | + * audit_remove_watch() drops our reference to 'parent' which |
583 | + * can get freed. Grab our own reference to be safe. |
584 | + */ |
585 | + audit_get_parent(parent); |
586 | audit_remove_watch(watch); |
587 | - |
588 | - if (list_empty(&parent->watches)) { |
589 | - audit_get_parent(parent); |
590 | + if (list_empty(&parent->watches)) |
591 | fsnotify_destroy_mark(&parent->mark, audit_watch_group); |
592 | - audit_put_parent(parent); |
593 | - } |
594 | + audit_put_parent(parent); |
595 | } |
596 | } |
597 | |
598 | diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c |
599 | index 077c87f40f4d..f30110e1b8c9 100644 |
600 | --- a/kernel/irq/chip.c |
601 | +++ b/kernel/irq/chip.c |
602 | @@ -895,13 +895,15 @@ EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name); |
603 | |
604 | void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) |
605 | { |
606 | - unsigned long flags; |
607 | + unsigned long flags, trigger, tmp; |
608 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); |
609 | |
610 | if (!desc) |
611 | return; |
612 | irq_settings_clr_and_set(desc, clr, set); |
613 | |
614 | + trigger = irqd_get_trigger_type(&desc->irq_data); |
615 | + |
616 | irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU | |
617 | IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT); |
618 | if (irq_settings_has_no_balance_set(desc)) |
619 | @@ -913,7 +915,11 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) |
620 | if (irq_settings_is_level(desc)) |
621 | irqd_set(&desc->irq_data, IRQD_LEVEL); |
622 | |
623 | - irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc)); |
624 | + tmp = irq_settings_get_trigger_mask(desc); |
625 | + if (tmp != IRQ_TYPE_NONE) |
626 | + trigger = tmp; |
627 | + |
628 | + irqd_set(&desc->irq_data, trigger); |
629 | |
630 | irq_put_desc_unlock(desc, flags); |
631 | } |
632 | diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c |
633 | index 1a9abc1c8ea0..259a22aa9934 100644 |
634 | --- a/kernel/irq/ipi.c |
635 | +++ b/kernel/irq/ipi.c |
636 | @@ -165,7 +165,7 @@ irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu) |
637 | struct irq_data *data = irq_get_irq_data(irq); |
638 | struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL; |
639 | |
640 | - if (!data || !ipimask || cpu > nr_cpu_ids) |
641 | + if (!data || !ipimask || cpu >= nr_cpu_ids) |
642 | return INVALID_HWIRQ; |
643 | |
644 | if (!cpumask_test_cpu(cpu, ipimask)) |
645 | @@ -195,7 +195,7 @@ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data, |
646 | if (!chip->ipi_send_single && !chip->ipi_send_mask) |
647 | return -EINVAL; |
648 | |
649 | - if (cpu > nr_cpu_ids) |
650 | + if (cpu >= nr_cpu_ids) |
651 | return -EINVAL; |
652 | |
653 | if (dest) { |
654 | diff --git a/kernel/pid.c b/kernel/pid.c |
655 | index f66162f2359b..693a64385d59 100644 |
656 | --- a/kernel/pid.c |
657 | +++ b/kernel/pid.c |
658 | @@ -526,8 +526,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, |
659 | if (!ns) |
660 | ns = task_active_pid_ns(current); |
661 | if (likely(pid_alive(task))) { |
662 | - if (type != PIDTYPE_PID) |
663 | + if (type != PIDTYPE_PID) { |
664 | + if (type == __PIDTYPE_TGID) |
665 | + type = PIDTYPE_PID; |
666 | task = task->group_leader; |
667 | + } |
668 | nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); |
669 | } |
670 | rcu_read_unlock(); |
671 | @@ -536,12 +539,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, |
672 | } |
673 | EXPORT_SYMBOL(__task_pid_nr_ns); |
674 | |
675 | -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) |
676 | -{ |
677 | - return pid_nr_ns(task_tgid(tsk), ns); |
678 | -} |
679 | -EXPORT_SYMBOL(task_tgid_nr_ns); |
680 | - |
681 | struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) |
682 | { |
683 | return ns_of_pid(task_pid(tsk)); |
684 | diff --git a/mm/memblock.c b/mm/memblock.c |
685 | index 68849d0ead09..ccec42c12ba8 100644 |
686 | --- a/mm/memblock.c |
687 | +++ b/mm/memblock.c |
688 | @@ -297,31 +297,27 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u |
689 | } |
690 | |
691 | #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK |
692 | - |
693 | -phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info( |
694 | - phys_addr_t *addr) |
695 | -{ |
696 | - if (memblock.reserved.regions == memblock_reserved_init_regions) |
697 | - return 0; |
698 | - |
699 | - *addr = __pa(memblock.reserved.regions); |
700 | - |
701 | - return PAGE_ALIGN(sizeof(struct memblock_region) * |
702 | - memblock.reserved.max); |
703 | -} |
704 | - |
705 | -phys_addr_t __init_memblock get_allocated_memblock_memory_regions_info( |
706 | - phys_addr_t *addr) |
707 | +/** |
708 | + * Discard memory and reserved arrays if they were allocated |
709 | + */ |
710 | +void __init memblock_discard(void) |
711 | { |
712 | - if (memblock.memory.regions == memblock_memory_init_regions) |
713 | - return 0; |
714 | + phys_addr_t addr, size; |
715 | |
716 | - *addr = __pa(memblock.memory.regions); |
717 | + if (memblock.reserved.regions != memblock_reserved_init_regions) { |
718 | + addr = __pa(memblock.reserved.regions); |
719 | + size = PAGE_ALIGN(sizeof(struct memblock_region) * |
720 | + memblock.reserved.max); |
721 | + __memblock_free_late(addr, size); |
722 | + } |
723 | |
724 | - return PAGE_ALIGN(sizeof(struct memblock_region) * |
725 | - memblock.memory.max); |
726 | + if (memblock.memory.regions == memblock_memory_init_regions) { |
727 | + addr = __pa(memblock.memory.regions); |
728 | + size = PAGE_ALIGN(sizeof(struct memblock_region) * |
729 | + memblock.memory.max); |
730 | + __memblock_free_late(addr, size); |
731 | + } |
732 | } |
733 | - |
734 | #endif |
735 | |
736 | /** |
737 | diff --git a/mm/memory.c b/mm/memory.c |
738 | index 9bf3da0d0e14..d064caff9d7d 100644 |
739 | --- a/mm/memory.c |
740 | +++ b/mm/memory.c |
741 | @@ -3635,8 +3635,18 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, |
742 | * further. |
743 | */ |
744 | if (unlikely((current->flags & PF_KTHREAD) && !(ret & VM_FAULT_ERROR) |
745 | - && test_bit(MMF_UNSTABLE, &vma->vm_mm->flags))) |
746 | + && test_bit(MMF_UNSTABLE, &vma->vm_mm->flags))) { |
747 | + |
748 | + /* |
749 | + * We are going to enforce SIGBUS but the PF path might have |
750 | + * dropped the mmap_sem already so take it again so that |
751 | + * we do not break expectations of all arch specific PF paths |
752 | + * and g-u-p |
753 | + */ |
754 | + if (ret & VM_FAULT_RETRY) |
755 | + down_read(&vma->vm_mm->mmap_sem); |
756 | ret = VM_FAULT_SIGBUS; |
757 | + } |
758 | |
759 | return ret; |
760 | } |
761 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
762 | index 23471526d424..a8ab5e73dc61 100644 |
763 | --- a/mm/mempolicy.c |
764 | +++ b/mm/mempolicy.c |
765 | @@ -926,11 +926,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, |
766 | *policy |= (pol->flags & MPOL_MODE_FLAGS); |
767 | } |
768 | |
769 | - if (vma) { |
770 | - up_read(¤t->mm->mmap_sem); |
771 | - vma = NULL; |
772 | - } |
773 | - |
774 | err = 0; |
775 | if (nmask) { |
776 | if (mpol_store_user_nodemask(pol)) { |
777 | diff --git a/mm/migrate.c b/mm/migrate.c |
778 | index 6850f62998cd..821623fc7091 100644 |
779 | --- a/mm/migrate.c |
780 | +++ b/mm/migrate.c |
781 | @@ -40,6 +40,7 @@ |
782 | #include <linux/mmu_notifier.h> |
783 | #include <linux/page_idle.h> |
784 | #include <linux/page_owner.h> |
785 | +#include <linux/ptrace.h> |
786 | |
787 | #include <asm/tlbflush.h> |
788 | |
789 | @@ -1663,7 +1664,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, |
790 | const int __user *, nodes, |
791 | int __user *, status, int, flags) |
792 | { |
793 | - const struct cred *cred = current_cred(), *tcred; |
794 | struct task_struct *task; |
795 | struct mm_struct *mm; |
796 | int err; |
797 | @@ -1687,14 +1687,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, |
798 | |
799 | /* |
800 | * Check if this process has the right to modify the specified |
801 | - * process. The right exists if the process has administrative |
802 | - * capabilities, superuser privileges or the same |
803 | - * userid as the target process. |
804 | + * process. Use the regular "ptrace_may_access()" checks. |
805 | */ |
806 | - tcred = __task_cred(task); |
807 | - if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) && |
808 | - !uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) && |
809 | - !capable(CAP_SYS_NICE)) { |
810 | + if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) { |
811 | rcu_read_unlock(); |
812 | err = -EPERM; |
813 | goto out; |
814 | diff --git a/mm/nobootmem.c b/mm/nobootmem.c |
815 | index 487dad610731..ab998125f04d 100644 |
816 | --- a/mm/nobootmem.c |
817 | +++ b/mm/nobootmem.c |
818 | @@ -146,22 +146,6 @@ static unsigned long __init free_low_memory_core_early(void) |
819 | NULL) |
820 | count += __free_memory_core(start, end); |
821 | |
822 | -#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK |
823 | - { |
824 | - phys_addr_t size; |
825 | - |
826 | - /* Free memblock.reserved array if it was allocated */ |
827 | - size = get_allocated_memblock_reserved_regions_info(&start); |
828 | - if (size) |
829 | - count += __free_memory_core(start, start + size); |
830 | - |
831 | - /* Free memblock.memory array if it was allocated */ |
832 | - size = get_allocated_memblock_memory_regions_info(&start); |
833 | - if (size) |
834 | - count += __free_memory_core(start, start + size); |
835 | - } |
836 | -#endif |
837 | - |
838 | return count; |
839 | } |
840 | |
841 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
842 | index 9419aa4e5441..2abf8d5f0ad4 100644 |
843 | --- a/mm/page_alloc.c |
844 | +++ b/mm/page_alloc.c |
845 | @@ -1587,6 +1587,10 @@ void __init page_alloc_init_late(void) |
846 | /* Reinit limits that are based on free pages after the kernel is up */ |
847 | files_maxfiles_init(); |
848 | #endif |
849 | +#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK |
850 | + /* Discard memblock private memory */ |
851 | + memblock_discard(); |
852 | +#endif |
853 | |
854 | for_each_populated_zone(zone) |
855 | set_zone_contiguous(zone); |
856 | diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c |
857 | index 02bcf00c2492..008299b7f78f 100644 |
858 | --- a/net/netfilter/nf_conntrack_extend.c |
859 | +++ b/net/netfilter/nf_conntrack_extend.c |
860 | @@ -53,7 +53,11 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, |
861 | |
862 | rcu_read_lock(); |
863 | t = rcu_dereference(nf_ct_ext_types[id]); |
864 | - BUG_ON(t == NULL); |
865 | + if (!t) { |
866 | + rcu_read_unlock(); |
867 | + return NULL; |
868 | + } |
869 | + |
870 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); |
871 | len = off + t->len + var_alloc_len; |
872 | alloc_size = t->alloc_size + var_alloc_len; |
873 | @@ -88,7 +92,10 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, |
874 | |
875 | rcu_read_lock(); |
876 | t = rcu_dereference(nf_ct_ext_types[id]); |
877 | - BUG_ON(t == NULL); |
878 | + if (!t) { |
879 | + rcu_read_unlock(); |
880 | + return NULL; |
881 | + } |
882 | |
883 | newoff = ALIGN(old->len, t->align); |
884 | newlen = newoff + t->len + var_alloc_len; |
885 | @@ -175,6 +182,6 @@ void nf_ct_extend_unregister(struct nf_ct_ext_type *type) |
886 | RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); |
887 | update_alloc_size(type); |
888 | mutex_unlock(&nf_ct_ext_type_mutex); |
889 | - rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
890 | + synchronize_rcu(); |
891 | } |
892 | EXPORT_SYMBOL_GPL(nf_ct_extend_unregister); |
893 | diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c |
894 | index f3b1d7f50b81..67c4c68ce041 100644 |
895 | --- a/sound/core/seq/seq_clientmgr.c |
896 | +++ b/sound/core/seq/seq_clientmgr.c |
897 | @@ -1502,16 +1502,11 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, |
898 | static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) |
899 | { |
900 | struct snd_seq_queue_info *info = arg; |
901 | - int result; |
902 | struct snd_seq_queue *q; |
903 | |
904 | - result = snd_seq_queue_alloc(client->number, info->locked, info->flags); |
905 | - if (result < 0) |
906 | - return result; |
907 | - |
908 | - q = queueptr(result); |
909 | - if (q == NULL) |
910 | - return -EINVAL; |
911 | + q = snd_seq_queue_alloc(client->number, info->locked, info->flags); |
912 | + if (IS_ERR(q)) |
913 | + return PTR_ERR(q); |
914 | |
915 | info->queue = q->queue; |
916 | info->locked = q->locked; |
917 | @@ -1521,7 +1516,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) |
918 | if (!info->name[0]) |
919 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); |
920 | strlcpy(q->name, info->name, sizeof(q->name)); |
921 | - queuefree(q); |
922 | + snd_use_lock_free(&q->use_lock); |
923 | |
924 | return 0; |
925 | } |
926 | diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c |
927 | index 450c5187eecb..79e0c5604ef8 100644 |
928 | --- a/sound/core/seq/seq_queue.c |
929 | +++ b/sound/core/seq/seq_queue.c |
930 | @@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void) |
931 | static void queue_use(struct snd_seq_queue *queue, int client, int use); |
932 | |
933 | /* allocate a new queue - |
934 | - * return queue index value or negative value for error |
935 | + * return pointer to new queue or ERR_PTR(-errno) for error |
936 | + * The new queue's use_lock is set to 1. It is the caller's responsibility to |
937 | + * call snd_use_lock_free(&q->use_lock). |
938 | */ |
939 | -int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) |
940 | +struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) |
941 | { |
942 | struct snd_seq_queue *q; |
943 | |
944 | q = queue_new(client, locked); |
945 | if (q == NULL) |
946 | - return -ENOMEM; |
947 | + return ERR_PTR(-ENOMEM); |
948 | q->info_flags = info_flags; |
949 | queue_use(q, client, 1); |
950 | + snd_use_lock_use(&q->use_lock); |
951 | if (queue_list_add(q) < 0) { |
952 | + snd_use_lock_free(&q->use_lock); |
953 | queue_delete(q); |
954 | - return -ENOMEM; |
955 | + return ERR_PTR(-ENOMEM); |
956 | } |
957 | - return q->queue; |
958 | + return q; |
959 | } |
960 | |
961 | /* delete a queue - queue must be owned by the client */ |
962 | diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h |
963 | index 30c8111477f6..719093489a2c 100644 |
964 | --- a/sound/core/seq/seq_queue.h |
965 | +++ b/sound/core/seq/seq_queue.h |
966 | @@ -71,7 +71,7 @@ void snd_seq_queues_delete(void); |
967 | |
968 | |
969 | /* create new queue (constructor) */ |
970 | -int snd_seq_queue_alloc(int client, int locked, unsigned int flags); |
971 | +struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags); |
972 | |
973 | /* delete queue (destructor) */ |
974 | int snd_seq_queue_delete(int client, int queueid); |
975 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
976 | index 4703caea56b2..d09c28c1deaf 100644 |
977 | --- a/sound/usb/mixer.c |
978 | +++ b/sound/usb/mixer.c |
979 | @@ -542,6 +542,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, |
980 | |
981 | if (size < sizeof(scale)) |
982 | return -ENOMEM; |
983 | + if (cval->min_mute) |
984 | + scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE; |
985 | scale[2] = cval->dBmin; |
986 | scale[3] = cval->dBmax; |
987 | if (copy_to_user(_tlv, scale, sizeof(scale))) |
988 | diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h |
989 | index 3417ef347e40..2b4b067646ab 100644 |
990 | --- a/sound/usb/mixer.h |
991 | +++ b/sound/usb/mixer.h |
992 | @@ -64,6 +64,7 @@ struct usb_mixer_elem_info { |
993 | int cached; |
994 | int cache_val[MAX_CHANNELS]; |
995 | u8 initialized; |
996 | + u8 min_mute; |
997 | void *private_data; |
998 | }; |
999 | |
1000 | diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c |
1001 | index 04991b009132..5d2fc5f58bfe 100644 |
1002 | --- a/sound/usb/mixer_quirks.c |
1003 | +++ b/sound/usb/mixer_quirks.c |
1004 | @@ -1873,6 +1873,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, |
1005 | if (unitid == 7 && cval->control == UAC_FU_VOLUME) |
1006 | snd_dragonfly_quirk_db_scale(mixer, cval, kctl); |
1007 | break; |
1008 | + /* lowest playback value is muted on C-Media devices */ |
1009 | + case USB_ID(0x0d8c, 0x000c): |
1010 | + case USB_ID(0x0d8c, 0x0014): |
1011 | + if (strstr(kctl->id.name, "Playback")) |
1012 | + cval->min_mute = 1; |
1013 | + break; |
1014 | } |
1015 | } |
1016 | |
1017 | diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c |
1018 | index eb4b9f7a571e..95c2749ac8a3 100644 |
1019 | --- a/sound/usb/quirks.c |
1020 | +++ b/sound/usb/quirks.c |
1021 | @@ -1142,6 +1142,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) |
1022 | case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ |
1023 | case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ |
1024 | case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ |
1025 | + case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ |
1026 | case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ |
1027 | case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */ |
1028 | case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */ |