1 |
commit: 19741bd3d3d380bb76ef3a795e876d9af3481ea9 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Mar 28 10:53:05 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Mar 28 10:53:05 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=19741bd3 |
7 |
|
8 |
Linux patch 5.17.1 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1000_linux-5.17.1.patch | 1721 +++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 1725 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index c012760e..684989ae 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -43,6 +43,10 @@ EXPERIMENTAL |
21 |
Individual Patch Descriptions: |
22 |
-------------------------------------------------------------------------- |
23 |
|
24 |
+Patch: 1000_linux-5.17.1.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.17.1 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1000_linux-5.17.1.patch b/1000_linux-5.17.1.patch |
33 |
new file mode 100644 |
34 |
index 00000000..bfdbbde3 |
35 |
--- /dev/null |
36 |
+++ b/1000_linux-5.17.1.patch |
37 |
@@ -0,0 +1,1721 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index 7214f075e1f06..34f9f5a9457af 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,7 +1,7 @@ |
43 |
+ # SPDX-License-Identifier: GPL-2.0 |
44 |
+ VERSION = 5 |
45 |
+ PATCHLEVEL = 17 |
46 |
+-SUBLEVEL = 0 |
47 |
++SUBLEVEL = 1 |
48 |
+ EXTRAVERSION = |
49 |
+ NAME = Superb Owl |
50 |
+ |
51 |
+diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h |
52 |
+index c40f06ee8d3ef..ac5a54f57d407 100644 |
53 |
+--- a/arch/csky/include/asm/uaccess.h |
54 |
++++ b/arch/csky/include/asm/uaccess.h |
55 |
+@@ -3,14 +3,13 @@ |
56 |
+ #ifndef __ASM_CSKY_UACCESS_H |
57 |
+ #define __ASM_CSKY_UACCESS_H |
58 |
+ |
59 |
+-#define user_addr_max() \ |
60 |
+- (uaccess_kernel() ? KERNEL_DS.seg : get_fs().seg) |
61 |
++#define user_addr_max() (current_thread_info()->addr_limit.seg) |
62 |
+ |
63 |
+ static inline int __access_ok(unsigned long addr, unsigned long size) |
64 |
+ { |
65 |
+- unsigned long limit = current_thread_info()->addr_limit.seg; |
66 |
++ unsigned long limit = user_addr_max(); |
67 |
+ |
68 |
+- return ((addr < limit) && ((addr + size) < limit)); |
69 |
++ return (size <= limit) && (addr <= (limit - size)); |
70 |
+ } |
71 |
+ #define __access_ok __access_ok |
72 |
+ |
73 |
+diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h |
74 |
+index ef5bfef8d490c..719ba3f3c45cd 100644 |
75 |
+--- a/arch/hexagon/include/asm/uaccess.h |
76 |
++++ b/arch/hexagon/include/asm/uaccess.h |
77 |
+@@ -25,17 +25,17 @@ |
78 |
+ * Returns true (nonzero) if the memory block *may* be valid, false (zero) |
79 |
+ * if it is definitely invalid. |
80 |
+ * |
81 |
+- * User address space in Hexagon, like x86, goes to 0xbfffffff, so the |
82 |
+- * simple MSB-based tests used by MIPS won't work. Some further |
83 |
+- * optimization is probably possible here, but for now, keep it |
84 |
+- * reasonably simple and not *too* slow. After all, we've got the |
85 |
+- * MMU for backup. |
86 |
+ */ |
87 |
++#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) |
88 |
++#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE) |
89 |
+ |
90 |
+-#define __access_ok(addr, size) \ |
91 |
+- ((get_fs().seg == KERNEL_DS.seg) || \ |
92 |
+- (((unsigned long)addr < get_fs().seg) && \ |
93 |
+- (unsigned long)size < (get_fs().seg - (unsigned long)addr))) |
94 |
++static inline int __access_ok(unsigned long addr, unsigned long size) |
95 |
++{ |
96 |
++ unsigned long limit = TASK_SIZE; |
97 |
++ |
98 |
++ return (size <= limit) && (addr <= (limit - size)); |
99 |
++} |
100 |
++#define __access_ok __access_ok |
101 |
+ |
102 |
+ /* |
103 |
+ * When a kernel-mode page fault is taken, the faulting instruction |
104 |
+diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h |
105 |
+index ba670523885c8..60b786eb2254e 100644 |
106 |
+--- a/arch/m68k/include/asm/uaccess.h |
107 |
++++ b/arch/m68k/include/asm/uaccess.h |
108 |
+@@ -12,14 +12,17 @@ |
109 |
+ #include <asm/extable.h> |
110 |
+ |
111 |
+ /* We let the MMU do all checking */ |
112 |
+-static inline int access_ok(const void __user *addr, |
113 |
++static inline int access_ok(const void __user *ptr, |
114 |
+ unsigned long size) |
115 |
+ { |
116 |
+- /* |
117 |
+- * XXX: for !CONFIG_CPU_HAS_ADDRESS_SPACES this really needs to check |
118 |
+- * for TASK_SIZE! |
119 |
+- */ |
120 |
+- return 1; |
121 |
++ unsigned long limit = TASK_SIZE; |
122 |
++ unsigned long addr = (unsigned long)ptr; |
123 |
++ |
124 |
++ if (IS_ENABLED(CONFIG_CPU_HAS_ADDRESS_SPACES) || |
125 |
++ !IS_ENABLED(CONFIG_MMU)) |
126 |
++ return 1; |
127 |
++ |
128 |
++ return (size <= limit) && (addr <= (limit - size)); |
129 |
+ } |
130 |
+ |
131 |
+ /* |
132 |
+diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h |
133 |
+index d2a8ef9f89787..5b6e0e7788f44 100644 |
134 |
+--- a/arch/microblaze/include/asm/uaccess.h |
135 |
++++ b/arch/microblaze/include/asm/uaccess.h |
136 |
+@@ -39,24 +39,13 @@ |
137 |
+ |
138 |
+ # define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) |
139 |
+ |
140 |
+-static inline int access_ok(const void __user *addr, unsigned long size) |
141 |
++static inline int __access_ok(unsigned long addr, unsigned long size) |
142 |
+ { |
143 |
+- if (!size) |
144 |
+- goto ok; |
145 |
++ unsigned long limit = user_addr_max(); |
146 |
+ |
147 |
+- if ((get_fs().seg < ((unsigned long)addr)) || |
148 |
+- (get_fs().seg < ((unsigned long)addr + size - 1))) { |
149 |
+- pr_devel("ACCESS fail at 0x%08x (size 0x%x), seg 0x%08x\n", |
150 |
+- (__force u32)addr, (u32)size, |
151 |
+- (u32)get_fs().seg); |
152 |
+- return 0; |
153 |
+- } |
154 |
+-ok: |
155 |
+- pr_devel("ACCESS OK at 0x%08x (size 0x%x), seg 0x%08x\n", |
156 |
+- (__force u32)addr, (u32)size, |
157 |
+- (u32)get_fs().seg); |
158 |
+- return 1; |
159 |
++ return (size <= limit) && (addr <= (limit - size)); |
160 |
+ } |
161 |
++#define access_ok(addr, size) __access_ok((unsigned long)addr, size) |
162 |
+ |
163 |
+ # define __FIXUP_SECTION ".section .fixup,\"ax\"\n" |
164 |
+ # define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n" |
165 |
+diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h |
166 |
+index d4cbf069dc224..37a40981deb3b 100644 |
167 |
+--- a/arch/nds32/include/asm/uaccess.h |
168 |
++++ b/arch/nds32/include/asm/uaccess.h |
169 |
+@@ -70,9 +70,7 @@ static inline void set_fs(mm_segment_t fs) |
170 |
+ * versions are void (ie, don't return a value as such). |
171 |
+ */ |
172 |
+ |
173 |
+-#define get_user __get_user \ |
174 |
+- |
175 |
+-#define __get_user(x, ptr) \ |
176 |
++#define get_user(x, ptr) \ |
177 |
+ ({ \ |
178 |
+ long __gu_err = 0; \ |
179 |
+ __get_user_check((x), (ptr), __gu_err); \ |
180 |
+@@ -85,6 +83,14 @@ static inline void set_fs(mm_segment_t fs) |
181 |
+ (void)0; \ |
182 |
+ }) |
183 |
+ |
184 |
++#define __get_user(x, ptr) \ |
185 |
++({ \ |
186 |
++ long __gu_err = 0; \ |
187 |
++ const __typeof__(*(ptr)) __user *__p = (ptr); \ |
188 |
++ __get_user_err((x), __p, (__gu_err)); \ |
189 |
++ __gu_err; \ |
190 |
++}) |
191 |
++ |
192 |
+ #define __get_user_check(x, ptr, err) \ |
193 |
+ ({ \ |
194 |
+ const __typeof__(*(ptr)) __user *__p = (ptr); \ |
195 |
+@@ -165,12 +171,18 @@ do { \ |
196 |
+ : "r"(addr), "i"(-EFAULT) \ |
197 |
+ : "cc") |
198 |
+ |
199 |
+-#define put_user __put_user \ |
200 |
++#define put_user(x, ptr) \ |
201 |
++({ \ |
202 |
++ long __pu_err = 0; \ |
203 |
++ __put_user_check((x), (ptr), __pu_err); \ |
204 |
++ __pu_err; \ |
205 |
++}) |
206 |
+ |
207 |
+ #define __put_user(x, ptr) \ |
208 |
+ ({ \ |
209 |
+ long __pu_err = 0; \ |
210 |
+- __put_user_err((x), (ptr), __pu_err); \ |
211 |
++ __typeof__(*(ptr)) __user *__p = (ptr); \ |
212 |
++ __put_user_err((x), __p, __pu_err); \ |
213 |
+ __pu_err; \ |
214 |
+ }) |
215 |
+ |
216 |
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c |
217 |
+index 5b6d1a95776f0..0d01e7f5078c2 100644 |
218 |
+--- a/arch/x86/kernel/acpi/boot.c |
219 |
++++ b/arch/x86/kernel/acpi/boot.c |
220 |
+@@ -1328,6 +1328,17 @@ static int __init disable_acpi_pci(const struct dmi_system_id *d) |
221 |
+ return 0; |
222 |
+ } |
223 |
+ |
224 |
++static int __init disable_acpi_xsdt(const struct dmi_system_id *d) |
225 |
++{ |
226 |
++ if (!acpi_force) { |
227 |
++ pr_notice("%s detected: force use of acpi=rsdt\n", d->ident); |
228 |
++ acpi_gbl_do_not_use_xsdt = TRUE; |
229 |
++ } else { |
230 |
++ pr_notice("Warning: DMI blacklist says broken, but acpi XSDT forced\n"); |
231 |
++ } |
232 |
++ return 0; |
233 |
++} |
234 |
++ |
235 |
+ static int __init dmi_disable_acpi(const struct dmi_system_id *d) |
236 |
+ { |
237 |
+ if (!acpi_force) { |
238 |
+@@ -1451,6 +1462,19 @@ static const struct dmi_system_id acpi_dmi_table[] __initconst = { |
239 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
240 |
+ }, |
241 |
+ }, |
242 |
++ /* |
243 |
++ * Boxes that need ACPI XSDT use disabled due to corrupted tables |
244 |
++ */ |
245 |
++ { |
246 |
++ .callback = disable_acpi_xsdt, |
247 |
++ .ident = "Advantech DAC-BJ01", |
248 |
++ .matches = { |
249 |
++ DMI_MATCH(DMI_SYS_VENDOR, "NEC"), |
250 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Bearlake CRB Board"), |
251 |
++ DMI_MATCH(DMI_BIOS_VERSION, "V1.12"), |
252 |
++ DMI_MATCH(DMI_BIOS_DATE, "02/01/2011"), |
253 |
++ }, |
254 |
++ }, |
255 |
+ {} |
256 |
+ }; |
257 |
+ |
258 |
+diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c |
259 |
+index ea31ae01458b4..dc208f5f5a1f7 100644 |
260 |
+--- a/drivers/acpi/battery.c |
261 |
++++ b/drivers/acpi/battery.c |
262 |
+@@ -59,6 +59,10 @@ MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
263 |
+ |
264 |
+ static const struct acpi_device_id battery_device_ids[] = { |
265 |
+ {"PNP0C0A", 0}, |
266 |
++ |
267 |
++ /* Microsoft Surface Go 3 */ |
268 |
++ {"MSHW0146", 0}, |
269 |
++ |
270 |
+ {"", 0}, |
271 |
+ }; |
272 |
+ |
273 |
+@@ -1148,6 +1152,14 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { |
274 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"), |
275 |
+ }, |
276 |
+ }, |
277 |
++ { |
278 |
++ /* Microsoft Surface Go 3 */ |
279 |
++ .callback = battery_notification_delay_quirk, |
280 |
++ .matches = { |
281 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), |
282 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"), |
283 |
++ }, |
284 |
++ }, |
285 |
+ {}, |
286 |
+ }; |
287 |
+ |
288 |
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c |
289 |
+index 4f64713e9917b..becc198e4c224 100644 |
290 |
+--- a/drivers/acpi/video_detect.c |
291 |
++++ b/drivers/acpi/video_detect.c |
292 |
+@@ -415,6 +415,81 @@ static const struct dmi_system_id video_detect_dmi_table[] = { |
293 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), |
294 |
+ }, |
295 |
+ }, |
296 |
++ /* |
297 |
++ * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a |
298 |
++ * working native and video interface. However the default detection |
299 |
++ * mechanism first registers the video interface before unregistering |
300 |
++ * it again and switching to the native interface during boot. This |
301 |
++ * results in a dangling SBIOS request for backlight change for some |
302 |
++ * reason, causing the backlight to switch to ~2% once per boot on the |
303 |
++ * first power cord connect or disconnect event. Setting the native |
304 |
++ * interface explicitly circumvents this buggy behaviour, by avoiding |
305 |
++ * the unregistering process. |
306 |
++ */ |
307 |
++ { |
308 |
++ .callback = video_detect_force_native, |
309 |
++ .ident = "Clevo NL5xRU", |
310 |
++ .matches = { |
311 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
312 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
313 |
++ }, |
314 |
++ }, |
315 |
++ { |
316 |
++ .callback = video_detect_force_native, |
317 |
++ .ident = "Clevo NL5xRU", |
318 |
++ .matches = { |
319 |
++ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), |
320 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
321 |
++ }, |
322 |
++ }, |
323 |
++ { |
324 |
++ .callback = video_detect_force_native, |
325 |
++ .ident = "Clevo NL5xRU", |
326 |
++ .matches = { |
327 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), |
328 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
329 |
++ }, |
330 |
++ }, |
331 |
++ { |
332 |
++ .callback = video_detect_force_native, |
333 |
++ .ident = "Clevo NL5xRU", |
334 |
++ .matches = { |
335 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
336 |
++ DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), |
337 |
++ }, |
338 |
++ }, |
339 |
++ { |
340 |
++ .callback = video_detect_force_native, |
341 |
++ .ident = "Clevo NL5xRU", |
342 |
++ .matches = { |
343 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
344 |
++ DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), |
345 |
++ }, |
346 |
++ }, |
347 |
++ { |
348 |
++ .callback = video_detect_force_native, |
349 |
++ .ident = "Clevo NL5xNU", |
350 |
++ .matches = { |
351 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
352 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
353 |
++ }, |
354 |
++ }, |
355 |
++ { |
356 |
++ .callback = video_detect_force_native, |
357 |
++ .ident = "Clevo NL5xNU", |
358 |
++ .matches = { |
359 |
++ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), |
360 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
361 |
++ }, |
362 |
++ }, |
363 |
++ { |
364 |
++ .callback = video_detect_force_native, |
365 |
++ .ident = "Clevo NL5xNU", |
366 |
++ .matches = { |
367 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), |
368 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
369 |
++ }, |
370 |
++ }, |
371 |
+ |
372 |
+ /* |
373 |
+ * Desktops which falsely report a backlight and which our heuristics |
374 |
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c |
375 |
+index c30d131da7847..19d5686f8a2a1 100644 |
376 |
+--- a/drivers/bluetooth/btusb.c |
377 |
++++ b/drivers/bluetooth/btusb.c |
378 |
+@@ -405,6 +405,8 @@ static const struct usb_device_id blacklist_table[] = { |
379 |
+ BTUSB_WIDEBAND_SPEECH }, |
380 |
+ |
381 |
+ /* Realtek 8852AE Bluetooth devices */ |
382 |
++ { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK | |
383 |
++ BTUSB_WIDEBAND_SPEECH }, |
384 |
+ { USB_DEVICE(0x0bda, 0xc852), .driver_info = BTUSB_REALTEK | |
385 |
+ BTUSB_WIDEBAND_SPEECH }, |
386 |
+ { USB_DEVICE(0x0bda, 0x385a), .driver_info = BTUSB_REALTEK | |
387 |
+@@ -482,6 +484,8 @@ static const struct usb_device_id blacklist_table[] = { |
388 |
+ /* Additional Realtek 8761BU Bluetooth devices */ |
389 |
+ { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK | |
390 |
+ BTUSB_WIDEBAND_SPEECH }, |
391 |
++ { USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK | |
392 |
++ BTUSB_WIDEBAND_SPEECH }, |
393 |
+ |
394 |
+ /* Additional Realtek 8821AE Bluetooth devices */ |
395 |
+ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, |
396 |
+@@ -2041,6 +2045,8 @@ static int btusb_setup_csr(struct hci_dev *hdev) |
397 |
+ */ |
398 |
+ set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks); |
399 |
+ set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks); |
400 |
++ set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks); |
401 |
++ set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks); |
402 |
+ |
403 |
+ /* Clear the reset quirk since this is not an actual |
404 |
+ * early Bluetooth 1.1 device from CSR. |
405 |
+@@ -2051,7 +2057,7 @@ static int btusb_setup_csr(struct hci_dev *hdev) |
406 |
+ /* |
407 |
+ * Special workaround for these BT 4.0 chip clones, and potentially more: |
408 |
+ * |
409 |
+- * - 0x0134: a Barrot 8041a02 (HCI rev: 0x1012 sub: 0x0810) |
410 |
++ * - 0x0134: a Barrot 8041a02 (HCI rev: 0x0810 sub: 0x1012) |
411 |
+ * - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709) |
412 |
+ * |
413 |
+ * These controllers are really messed-up. |
414 |
+@@ -2080,7 +2086,7 @@ static int btusb_setup_csr(struct hci_dev *hdev) |
415 |
+ if (ret >= 0) |
416 |
+ msleep(200); |
417 |
+ else |
418 |
+- bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround"); |
419 |
++ bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround"); |
420 |
+ |
421 |
+ pm_runtime_forbid(&data->udev->dev); |
422 |
+ |
423 |
+diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c |
424 |
+index b009e7479b702..783d65fc71f07 100644 |
425 |
+--- a/drivers/char/tpm/tpm-chip.c |
426 |
++++ b/drivers/char/tpm/tpm-chip.c |
427 |
+@@ -274,14 +274,6 @@ static void tpm_dev_release(struct device *dev) |
428 |
+ kfree(chip); |
429 |
+ } |
430 |
+ |
431 |
+-static void tpm_devs_release(struct device *dev) |
432 |
+-{ |
433 |
+- struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs); |
434 |
+- |
435 |
+- /* release the master device reference */ |
436 |
+- put_device(&chip->dev); |
437 |
+-} |
438 |
+- |
439 |
+ /** |
440 |
+ * tpm_class_shutdown() - prepare the TPM device for loss of power. |
441 |
+ * @dev: device to which the chip is associated. |
442 |
+@@ -344,7 +336,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, |
443 |
+ chip->dev_num = rc; |
444 |
+ |
445 |
+ device_initialize(&chip->dev); |
446 |
+- device_initialize(&chip->devs); |
447 |
+ |
448 |
+ chip->dev.class = tpm_class; |
449 |
+ chip->dev.class->shutdown_pre = tpm_class_shutdown; |
450 |
+@@ -352,29 +343,12 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, |
451 |
+ chip->dev.parent = pdev; |
452 |
+ chip->dev.groups = chip->groups; |
453 |
+ |
454 |
+- chip->devs.parent = pdev; |
455 |
+- chip->devs.class = tpmrm_class; |
456 |
+- chip->devs.release = tpm_devs_release; |
457 |
+- /* get extra reference on main device to hold on |
458 |
+- * behalf of devs. This holds the chip structure |
459 |
+- * while cdevs is in use. The corresponding put |
460 |
+- * is in the tpm_devs_release (TPM2 only) |
461 |
+- */ |
462 |
+- if (chip->flags & TPM_CHIP_FLAG_TPM2) |
463 |
+- get_device(&chip->dev); |
464 |
+- |
465 |
+ if (chip->dev_num == 0) |
466 |
+ chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR); |
467 |
+ else |
468 |
+ chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num); |
469 |
+ |
470 |
+- chip->devs.devt = |
471 |
+- MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES); |
472 |
+- |
473 |
+ rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num); |
474 |
+- if (rc) |
475 |
+- goto out; |
476 |
+- rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num); |
477 |
+ if (rc) |
478 |
+ goto out; |
479 |
+ |
480 |
+@@ -382,9 +356,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, |
481 |
+ chip->flags |= TPM_CHIP_FLAG_VIRTUAL; |
482 |
+ |
483 |
+ cdev_init(&chip->cdev, &tpm_fops); |
484 |
+- cdev_init(&chip->cdevs, &tpmrm_fops); |
485 |
+ chip->cdev.owner = THIS_MODULE; |
486 |
+- chip->cdevs.owner = THIS_MODULE; |
487 |
+ |
488 |
+ rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE); |
489 |
+ if (rc) { |
490 |
+@@ -396,7 +368,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, |
491 |
+ return chip; |
492 |
+ |
493 |
+ out: |
494 |
+- put_device(&chip->devs); |
495 |
+ put_device(&chip->dev); |
496 |
+ return ERR_PTR(rc); |
497 |
+ } |
498 |
+@@ -445,14 +416,9 @@ static int tpm_add_char_device(struct tpm_chip *chip) |
499 |
+ } |
500 |
+ |
501 |
+ if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) { |
502 |
+- rc = cdev_device_add(&chip->cdevs, &chip->devs); |
503 |
+- if (rc) { |
504 |
+- dev_err(&chip->devs, |
505 |
+- "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n", |
506 |
+- dev_name(&chip->devs), MAJOR(chip->devs.devt), |
507 |
+- MINOR(chip->devs.devt), rc); |
508 |
+- return rc; |
509 |
+- } |
510 |
++ rc = tpm_devs_add(chip); |
511 |
++ if (rc) |
512 |
++ goto err_del_cdev; |
513 |
+ } |
514 |
+ |
515 |
+ /* Make the chip available. */ |
516 |
+@@ -460,6 +426,10 @@ static int tpm_add_char_device(struct tpm_chip *chip) |
517 |
+ idr_replace(&dev_nums_idr, chip, chip->dev_num); |
518 |
+ mutex_unlock(&idr_lock); |
519 |
+ |
520 |
++ return 0; |
521 |
++ |
522 |
++err_del_cdev: |
523 |
++ cdev_device_del(&chip->cdev, &chip->dev); |
524 |
+ return rc; |
525 |
+ } |
526 |
+ |
527 |
+@@ -654,7 +624,7 @@ void tpm_chip_unregister(struct tpm_chip *chip) |
528 |
+ hwrng_unregister(&chip->hwrng); |
529 |
+ tpm_bios_log_teardown(chip); |
530 |
+ if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) |
531 |
+- cdev_device_del(&chip->cdevs, &chip->devs); |
532 |
++ tpm_devs_remove(chip); |
533 |
+ tpm_del_char_device(chip); |
534 |
+ } |
535 |
+ EXPORT_SYMBOL_GPL(tpm_chip_unregister); |
536 |
+diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c |
537 |
+index c08cbb306636b..dc4c0a0a51290 100644 |
538 |
+--- a/drivers/char/tpm/tpm-dev-common.c |
539 |
++++ b/drivers/char/tpm/tpm-dev-common.c |
540 |
+@@ -69,7 +69,13 @@ static void tpm_dev_async_work(struct work_struct *work) |
541 |
+ ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer, |
542 |
+ sizeof(priv->data_buffer)); |
543 |
+ tpm_put_ops(priv->chip); |
544 |
+- if (ret > 0) { |
545 |
++ |
546 |
++ /* |
547 |
++ * If ret is > 0 then tpm_dev_transmit returned the size of the |
548 |
++ * response. If ret is < 0 then tpm_dev_transmit failed and |
549 |
++ * returned an error code. |
550 |
++ */ |
551 |
++ if (ret != 0) { |
552 |
+ priv->response_length = ret; |
553 |
+ mod_timer(&priv->user_read_timer, jiffies + (120 * HZ)); |
554 |
+ } |
555 |
+diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h |
556 |
+index 283f78211c3a7..2163c6ee0d364 100644 |
557 |
+--- a/drivers/char/tpm/tpm.h |
558 |
++++ b/drivers/char/tpm/tpm.h |
559 |
+@@ -234,6 +234,8 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd, |
560 |
+ size_t cmdsiz); |
561 |
+ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf, |
562 |
+ size_t *bufsiz); |
563 |
++int tpm_devs_add(struct tpm_chip *chip); |
564 |
++void tpm_devs_remove(struct tpm_chip *chip); |
565 |
+ |
566 |
+ void tpm_bios_log_setup(struct tpm_chip *chip); |
567 |
+ void tpm_bios_log_teardown(struct tpm_chip *chip); |
568 |
+diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c |
569 |
+index 97e916856cf3e..ffb35f0154c16 100644 |
570 |
+--- a/drivers/char/tpm/tpm2-space.c |
571 |
++++ b/drivers/char/tpm/tpm2-space.c |
572 |
+@@ -58,12 +58,12 @@ int tpm2_init_space(struct tpm_space *space, unsigned int buf_size) |
573 |
+ |
574 |
+ void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space) |
575 |
+ { |
576 |
+- mutex_lock(&chip->tpm_mutex); |
577 |
+- if (!tpm_chip_start(chip)) { |
578 |
++ |
579 |
++ if (tpm_try_get_ops(chip) == 0) { |
580 |
+ tpm2_flush_sessions(chip, space); |
581 |
+- tpm_chip_stop(chip); |
582 |
++ tpm_put_ops(chip); |
583 |
+ } |
584 |
+- mutex_unlock(&chip->tpm_mutex); |
585 |
++ |
586 |
+ kfree(space->context_buf); |
587 |
+ kfree(space->session_buf); |
588 |
+ } |
589 |
+@@ -574,3 +574,68 @@ out: |
590 |
+ dev_err(&chip->dev, "%s: error %d\n", __func__, rc); |
591 |
+ return rc; |
592 |
+ } |
593 |
++ |
594 |
++/* |
595 |
++ * Put the reference to the main device. |
596 |
++ */ |
597 |
++static void tpm_devs_release(struct device *dev) |
598 |
++{ |
599 |
++ struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs); |
600 |
++ |
601 |
++ /* release the master device reference */ |
602 |
++ put_device(&chip->dev); |
603 |
++} |
604 |
++ |
605 |
++/* |
606 |
++ * Remove the device file for exposed TPM spaces and release the device |
607 |
++ * reference. This may also release the reference to the master device. |
608 |
++ */ |
609 |
++void tpm_devs_remove(struct tpm_chip *chip) |
610 |
++{ |
611 |
++ cdev_device_del(&chip->cdevs, &chip->devs); |
612 |
++ put_device(&chip->devs); |
613 |
++} |
614 |
++ |
615 |
++/* |
616 |
++ * Add a device file to expose TPM spaces. Also take a reference to the |
617 |
++ * main device. |
618 |
++ */ |
619 |
++int tpm_devs_add(struct tpm_chip *chip) |
620 |
++{ |
621 |
++ int rc; |
622 |
++ |
623 |
++ device_initialize(&chip->devs); |
624 |
++ chip->devs.parent = chip->dev.parent; |
625 |
++ chip->devs.class = tpmrm_class; |
626 |
++ |
627 |
++ /* |
628 |
++ * Get extra reference on main device to hold on behalf of devs. |
629 |
++ * This holds the chip structure while cdevs is in use. The |
630 |
++ * corresponding put is in the tpm_devs_release. |
631 |
++ */ |
632 |
++ get_device(&chip->dev); |
633 |
++ chip->devs.release = tpm_devs_release; |
634 |
++ chip->devs.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES); |
635 |
++ cdev_init(&chip->cdevs, &tpmrm_fops); |
636 |
++ chip->cdevs.owner = THIS_MODULE; |
637 |
++ |
638 |
++ rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num); |
639 |
++ if (rc) |
640 |
++ goto err_put_devs; |
641 |
++ |
642 |
++ rc = cdev_device_add(&chip->cdevs, &chip->devs); |
643 |
++ if (rc) { |
644 |
++ dev_err(&chip->devs, |
645 |
++ "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n", |
646 |
++ dev_name(&chip->devs), MAJOR(chip->devs.devt), |
647 |
++ MINOR(chip->devs.devt), rc); |
648 |
++ goto err_put_devs; |
649 |
++ } |
650 |
++ |
651 |
++ return 0; |
652 |
++ |
653 |
++err_put_devs: |
654 |
++ put_device(&chip->devs); |
655 |
++ |
656 |
++ return rc; |
657 |
++} |
658 |
+diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c |
659 |
+index a6c78b9c730bc..fa4c350c1bf92 100644 |
660 |
+--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c |
661 |
++++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c |
662 |
+@@ -75,6 +75,13 @@ static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev) |
663 |
+ if (ret) |
664 |
+ goto err; |
665 |
+ |
666 |
++ /* Temporarily set the number of crypto instances to zero to avoid |
667 |
++ * registering the crypto algorithms. |
668 |
++ * This will be removed when the algorithms will support the |
669 |
++ * CRYPTO_TFM_REQ_MAY_BACKLOG flag |
670 |
++ */ |
671 |
++ instances = 0; |
672 |
++ |
673 |
+ for (i = 0; i < instances; i++) { |
674 |
+ val = i; |
675 |
+ bank = i * 2; |
676 |
+diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c |
677 |
+index 7234c4940fae4..67c9588e89df9 100644 |
678 |
+--- a/drivers/crypto/qat/qat_common/qat_crypto.c |
679 |
++++ b/drivers/crypto/qat/qat_common/qat_crypto.c |
680 |
+@@ -161,6 +161,13 @@ int qat_crypto_dev_config(struct adf_accel_dev *accel_dev) |
681 |
+ if (ret) |
682 |
+ goto err; |
683 |
+ |
684 |
++ /* Temporarily set the number of crypto instances to zero to avoid |
685 |
++ * registering the crypto algorithms. |
686 |
++ * This will be removed when the algorithms will support the |
687 |
++ * CRYPTO_TFM_REQ_MAY_BACKLOG flag |
688 |
++ */ |
689 |
++ instances = 0; |
690 |
++ |
691 |
+ for (i = 0; i < instances; i++) { |
692 |
+ val = i; |
693 |
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_BANK_NUM, i); |
694 |
+diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c |
695 |
+index 9bf319be11f60..12641616acd30 100644 |
696 |
+--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c |
697 |
++++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c |
698 |
+@@ -83,6 +83,12 @@ static struct devfreq_dev_profile msm_devfreq_profile = { |
699 |
+ static void msm_devfreq_boost_work(struct kthread_work *work); |
700 |
+ static void msm_devfreq_idle_work(struct kthread_work *work); |
701 |
+ |
702 |
++static bool has_devfreq(struct msm_gpu *gpu) |
703 |
++{ |
704 |
++ struct msm_gpu_devfreq *df = &gpu->devfreq; |
705 |
++ return !!df->devfreq; |
706 |
++} |
707 |
++ |
708 |
+ void msm_devfreq_init(struct msm_gpu *gpu) |
709 |
+ { |
710 |
+ struct msm_gpu_devfreq *df = &gpu->devfreq; |
711 |
+@@ -149,6 +155,9 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu) |
712 |
+ { |
713 |
+ struct msm_gpu_devfreq *df = &gpu->devfreq; |
714 |
+ |
715 |
++ if (!has_devfreq(gpu)) |
716 |
++ return; |
717 |
++ |
718 |
+ devfreq_cooling_unregister(gpu->cooling); |
719 |
+ dev_pm_qos_remove_request(&df->boost_freq); |
720 |
+ dev_pm_qos_remove_request(&df->idle_freq); |
721 |
+@@ -156,16 +165,24 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu) |
722 |
+ |
723 |
+ void msm_devfreq_resume(struct msm_gpu *gpu) |
724 |
+ { |
725 |
+- gpu->devfreq.busy_cycles = 0; |
726 |
+- gpu->devfreq.time = ktime_get(); |
727 |
++ struct msm_gpu_devfreq *df = &gpu->devfreq; |
728 |
+ |
729 |
+- devfreq_resume_device(gpu->devfreq.devfreq); |
730 |
++ if (!has_devfreq(gpu)) |
731 |
++ return; |
732 |
++ |
733 |
++ df->busy_cycles = 0; |
734 |
++ df->time = ktime_get(); |
735 |
++ |
736 |
++ devfreq_resume_device(df->devfreq); |
737 |
+ } |
738 |
+ |
739 |
+ void msm_devfreq_suspend(struct msm_gpu *gpu) |
740 |
+ { |
741 |
+ struct msm_gpu_devfreq *df = &gpu->devfreq; |
742 |
+ |
743 |
++ if (!has_devfreq(gpu)) |
744 |
++ return; |
745 |
++ |
746 |
+ devfreq_suspend_device(df->devfreq); |
747 |
+ |
748 |
+ cancel_idle_work(df); |
749 |
+@@ -185,6 +202,9 @@ void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor) |
750 |
+ struct msm_gpu_devfreq *df = &gpu->devfreq; |
751 |
+ uint64_t freq; |
752 |
+ |
753 |
++ if (!has_devfreq(gpu)) |
754 |
++ return; |
755 |
++ |
756 |
+ freq = get_freq(gpu); |
757 |
+ freq *= factor; |
758 |
+ |
759 |
+@@ -207,7 +227,7 @@ void msm_devfreq_active(struct msm_gpu *gpu) |
760 |
+ struct devfreq_dev_status status; |
761 |
+ unsigned int idle_time; |
762 |
+ |
763 |
+- if (!df->devfreq) |
764 |
++ if (!has_devfreq(gpu)) |
765 |
+ return; |
766 |
+ |
767 |
+ /* |
768 |
+@@ -253,7 +273,7 @@ void msm_devfreq_idle(struct msm_gpu *gpu) |
769 |
+ { |
770 |
+ struct msm_gpu_devfreq *df = &gpu->devfreq; |
771 |
+ |
772 |
+- if (!df->devfreq) |
773 |
++ if (!has_devfreq(gpu)) |
774 |
+ return; |
775 |
+ |
776 |
+ msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), |
777 |
+diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c |
778 |
+index 2de61b63ef91d..48d3c9955f0dd 100644 |
779 |
+--- a/drivers/gpu/drm/virtio/virtgpu_gem.c |
780 |
++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c |
781 |
+@@ -248,6 +248,9 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs) |
782 |
+ { |
783 |
+ u32 i; |
784 |
+ |
785 |
++ if (!objs) |
786 |
++ return; |
787 |
++ |
788 |
+ for (i = 0; i < objs->nents; i++) |
789 |
+ drm_gem_object_put(objs->objs[i]); |
790 |
+ virtio_gpu_array_free(objs); |
791 |
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c |
792 |
+index ff2d099aab218..53dc8d5fede86 100644 |
793 |
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c |
794 |
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c |
795 |
+@@ -696,6 +696,12 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, |
796 |
+ buf_pool->rx_skb[skb_index] = NULL; |
797 |
+ |
798 |
+ datalen = xgene_enet_get_data_len(le64_to_cpu(raw_desc->m1)); |
799 |
++ |
800 |
++ /* strip off CRC as HW isn't doing this */ |
801 |
++ nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0)); |
802 |
++ if (!nv) |
803 |
++ datalen -= 4; |
804 |
++ |
805 |
+ skb_put(skb, datalen); |
806 |
+ prefetch(skb->data - NET_IP_ALIGN); |
807 |
+ skb->protocol = eth_type_trans(skb, ndev); |
808 |
+@@ -717,12 +723,8 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, |
809 |
+ } |
810 |
+ } |
811 |
+ |
812 |
+- nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0)); |
813 |
+- if (!nv) { |
814 |
+- /* strip off CRC as HW isn't doing this */ |
815 |
+- datalen -= 4; |
816 |
++ if (!nv) |
817 |
+ goto skip_jumbo; |
818 |
+- } |
819 |
+ |
820 |
+ slots = page_pool->slots - 1; |
821 |
+ head = page_pool->head; |
822 |
+diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c |
823 |
+index b2400e2417a55..f15e7bd690b5b 100644 |
824 |
+--- a/drivers/net/wireless/ath/regd.c |
825 |
++++ b/drivers/net/wireless/ath/regd.c |
826 |
+@@ -667,14 +667,14 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, |
827 |
+ |
828 |
+ /* |
829 |
+ * Some users have reported their EEPROM programmed with |
830 |
+- * 0x8000 or 0x0 set, this is not a supported regulatory |
831 |
+- * domain but since we have more than one user with it we |
832 |
+- * need a solution for them. We default to 0x64, which is |
833 |
+- * the default Atheros world regulatory domain. |
834 |
++ * 0x8000 set, this is not a supported regulatory domain |
835 |
++ * but since we have more than one user with it we need |
836 |
++ * a solution for them. We default to 0x64, which is the |
837 |
++ * default Atheros world regulatory domain. |
838 |
+ */ |
839 |
+ static void ath_regd_sanitize(struct ath_regulatory *reg) |
840 |
+ { |
841 |
+- if (reg->current_rd != COUNTRY_ERD_FLAG && reg->current_rd != 0) |
842 |
++ if (reg->current_rd != COUNTRY_ERD_FLAG) |
843 |
+ return; |
844 |
+ printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); |
845 |
+ reg->current_rd = 0x64; |
846 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c |
847 |
+index 9575d7373bf27..ac2813ed851c4 100644 |
848 |
+--- a/drivers/net/wireless/ath/wcn36xx/main.c |
849 |
++++ b/drivers/net/wireless/ath/wcn36xx/main.c |
850 |
+@@ -1513,6 +1513,9 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, |
851 |
+ if (iris_node) { |
852 |
+ if (of_device_is_compatible(iris_node, "qcom,wcn3620")) |
853 |
+ wcn->rf_id = RF_IRIS_WCN3620; |
854 |
++ if (of_device_is_compatible(iris_node, "qcom,wcn3660") || |
855 |
++ of_device_is_compatible(iris_node, "qcom,wcn3660b")) |
856 |
++ wcn->rf_id = RF_IRIS_WCN3660; |
857 |
+ if (of_device_is_compatible(iris_node, "qcom,wcn3680")) |
858 |
+ wcn->rf_id = RF_IRIS_WCN3680; |
859 |
+ of_node_put(iris_node); |
860 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h |
861 |
+index fbd0558c2c196..5d3f8f56e5681 100644 |
862 |
+--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h |
863 |
++++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h |
864 |
+@@ -97,6 +97,7 @@ enum wcn36xx_ampdu_state { |
865 |
+ |
866 |
+ #define RF_UNKNOWN 0x0000 |
867 |
+ #define RF_IRIS_WCN3620 0x3620 |
868 |
++#define RF_IRIS_WCN3660 0x3660 |
869 |
+ #define RF_IRIS_WCN3680 0x3680 |
870 |
+ |
871 |
+ static inline void buff_to_be(u32 *buf, size_t len) |
872 |
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c |
873 |
+index 8e2f8275a2535..259e00046a8bd 100644 |
874 |
+--- a/fs/jbd2/transaction.c |
875 |
++++ b/fs/jbd2/transaction.c |
876 |
+@@ -842,27 +842,38 @@ EXPORT_SYMBOL(jbd2_journal_restart); |
877 |
+ */ |
878 |
+ void jbd2_journal_wait_updates(journal_t *journal) |
879 |
+ { |
880 |
+- transaction_t *commit_transaction = journal->j_running_transaction; |
881 |
++ DEFINE_WAIT(wait); |
882 |
+ |
883 |
+- if (!commit_transaction) |
884 |
+- return; |
885 |
++ while (1) { |
886 |
++ /* |
887 |
++ * Note that the running transaction can get freed under us if |
888 |
++ * this transaction is getting committed in |
889 |
++ * jbd2_journal_commit_transaction() -> |
890 |
++ * jbd2_journal_free_transaction(). This can only happen when we |
891 |
++ * release j_state_lock -> schedule() -> acquire j_state_lock. |
892 |
++ * Hence we should everytime retrieve new j_running_transaction |
893 |
++ * value (after j_state_lock release acquire cycle), else it may |
894 |
++ * lead to use-after-free of old freed transaction. |
895 |
++ */ |
896 |
++ transaction_t *transaction = journal->j_running_transaction; |
897 |
+ |
898 |
+- spin_lock(&commit_transaction->t_handle_lock); |
899 |
+- while (atomic_read(&commit_transaction->t_updates)) { |
900 |
+- DEFINE_WAIT(wait); |
901 |
++ if (!transaction) |
902 |
++ break; |
903 |
+ |
904 |
++ spin_lock(&transaction->t_handle_lock); |
905 |
+ prepare_to_wait(&journal->j_wait_updates, &wait, |
906 |
+- TASK_UNINTERRUPTIBLE); |
907 |
+- if (atomic_read(&commit_transaction->t_updates)) { |
908 |
+- spin_unlock(&commit_transaction->t_handle_lock); |
909 |
+- write_unlock(&journal->j_state_lock); |
910 |
+- schedule(); |
911 |
+- write_lock(&journal->j_state_lock); |
912 |
+- spin_lock(&commit_transaction->t_handle_lock); |
913 |
++ TASK_UNINTERRUPTIBLE); |
914 |
++ if (!atomic_read(&transaction->t_updates)) { |
915 |
++ spin_unlock(&transaction->t_handle_lock); |
916 |
++ finish_wait(&journal->j_wait_updates, &wait); |
917 |
++ break; |
918 |
+ } |
919 |
++ spin_unlock(&transaction->t_handle_lock); |
920 |
++ write_unlock(&journal->j_state_lock); |
921 |
++ schedule(); |
922 |
+ finish_wait(&journal->j_wait_updates, &wait); |
923 |
++ write_lock(&journal->j_state_lock); |
924 |
+ } |
925 |
+- spin_unlock(&commit_transaction->t_handle_lock); |
926 |
+ } |
927 |
+ |
928 |
+ /** |
929 |
+@@ -877,8 +888,6 @@ void jbd2_journal_wait_updates(journal_t *journal) |
930 |
+ */ |
931 |
+ void jbd2_journal_lock_updates(journal_t *journal) |
932 |
+ { |
933 |
+- DEFINE_WAIT(wait); |
934 |
+- |
935 |
+ jbd2_might_wait_for_commit(journal); |
936 |
+ |
937 |
+ write_lock(&journal->j_state_lock); |
938 |
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h |
939 |
+index 35c073d44ec5a..5cb095b09a940 100644 |
940 |
+--- a/include/net/bluetooth/hci.h |
941 |
++++ b/include/net/bluetooth/hci.h |
942 |
+@@ -255,6 +255,16 @@ enum { |
943 |
+ * during the hdev->setup vendor callback. |
944 |
+ */ |
945 |
+ HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, |
946 |
++ |
947 |
++ /* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with |
948 |
++ * HCI_FLT_CLEAR_ALL are ignored and event filtering is |
949 |
++ * completely avoided. A subset of the CSR controller |
950 |
++ * clones struggle with this and instantly lock up. |
951 |
++ * |
952 |
++ * Note that devices using this must (separately) disable |
953 |
++ * runtime suspend, because event filtering takes place there. |
954 |
++ */ |
955 |
++ HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, |
956 |
+ }; |
957 |
+ |
958 |
+ /* HCI device flags */ |
959 |
+diff --git a/include/sound/pcm.h b/include/sound/pcm.h |
960 |
+index 36da42cd07748..314f2779cab52 100644 |
961 |
+--- a/include/sound/pcm.h |
962 |
++++ b/include/sound/pcm.h |
963 |
+@@ -401,6 +401,7 @@ struct snd_pcm_runtime { |
964 |
+ wait_queue_head_t tsleep; /* transfer sleep */ |
965 |
+ struct fasync_struct *fasync; |
966 |
+ bool stop_operating; /* sync_stop will be called */ |
967 |
++ struct mutex buffer_mutex; /* protect for buffer changes */ |
968 |
+ |
969 |
+ /* -- private section -- */ |
970 |
+ void *private_data; |
971 |
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h |
972 |
+index c5b45c2f68a15..5678bee7aefee 100644 |
973 |
+--- a/kernel/rcu/tree_plugin.h |
974 |
++++ b/kernel/rcu/tree_plugin.h |
975 |
+@@ -556,16 +556,16 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags) |
976 |
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags); |
977 |
+ } |
978 |
+ |
979 |
+- /* Unboost if we were boosted. */ |
980 |
+- if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) |
981 |
+- rt_mutex_futex_unlock(&rnp->boost_mtx.rtmutex); |
982 |
+- |
983 |
+ /* |
984 |
+ * If this was the last task on the expedited lists, |
985 |
+ * then we need to report up the rcu_node hierarchy. |
986 |
+ */ |
987 |
+ if (!empty_exp && empty_exp_now) |
988 |
+ rcu_report_exp_rnp(rnp, true); |
989 |
++ |
990 |
++ /* Unboost if we were boosted. */ |
991 |
++ if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) |
992 |
++ rt_mutex_futex_unlock(&rnp->boost_mtx.rtmutex); |
993 |
+ } else { |
994 |
+ local_irq_restore(flags); |
995 |
+ } |
996 |
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c |
997 |
+index ab9aa700b6b33..5e93f37c2e04d 100644 |
998 |
+--- a/net/bluetooth/hci_sync.c |
999 |
++++ b/net/bluetooth/hci_sync.c |
1000 |
+@@ -2806,6 +2806,9 @@ static int hci_set_event_filter_sync(struct hci_dev *hdev, u8 flt_type, |
1001 |
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) |
1002 |
+ return 0; |
1003 |
+ |
1004 |
++ if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) |
1005 |
++ return 0; |
1006 |
++ |
1007 |
+ memset(&cp, 0, sizeof(cp)); |
1008 |
+ cp.flt_type = flt_type; |
1009 |
+ |
1010 |
+@@ -2826,6 +2829,13 @@ static int hci_clear_event_filter_sync(struct hci_dev *hdev) |
1011 |
+ if (!hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) |
1012 |
+ return 0; |
1013 |
+ |
1014 |
++ /* In theory the state machine should not reach here unless |
1015 |
++ * a hci_set_event_filter_sync() call succeeds, but we do |
1016 |
++ * the check both for parity and as a future reminder. |
1017 |
++ */ |
1018 |
++ if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) |
1019 |
++ return 0; |
1020 |
++ |
1021 |
+ return hci_set_event_filter_sync(hdev, HCI_FLT_CLEAR_ALL, 0x00, |
1022 |
+ BDADDR_ANY, 0x00); |
1023 |
+ } |
1024 |
+@@ -4825,6 +4835,12 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev) |
1025 |
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) |
1026 |
+ return 0; |
1027 |
+ |
1028 |
++ /* Some fake CSR controllers lock up after setting this type of |
1029 |
++ * filter, so avoid sending the request altogether. |
1030 |
++ */ |
1031 |
++ if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) |
1032 |
++ return 0; |
1033 |
++ |
1034 |
+ /* Always clear event filter when starting */ |
1035 |
+ hci_clear_event_filter_sync(hdev); |
1036 |
+ |
1037 |
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c |
1038 |
+index 26c00ebf4fbae..7f555d2e5357f 100644 |
1039 |
+--- a/net/llc/af_llc.c |
1040 |
++++ b/net/llc/af_llc.c |
1041 |
+@@ -275,6 +275,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
1042 |
+ { |
1043 |
+ struct sock *sk = sock->sk; |
1044 |
+ struct llc_sock *llc = llc_sk(sk); |
1045 |
++ struct net_device *dev = NULL; |
1046 |
+ struct llc_sap *sap; |
1047 |
+ int rc = -EINVAL; |
1048 |
+ |
1049 |
+@@ -286,16 +287,15 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
1050 |
+ goto out; |
1051 |
+ rc = -ENODEV; |
1052 |
+ if (sk->sk_bound_dev_if) { |
1053 |
+- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); |
1054 |
+- if (llc->dev && addr->sllc_arphrd != llc->dev->type) { |
1055 |
+- dev_put(llc->dev); |
1056 |
+- llc->dev = NULL; |
1057 |
++ dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); |
1058 |
++ if (dev && addr->sllc_arphrd != dev->type) { |
1059 |
++ dev_put(dev); |
1060 |
++ dev = NULL; |
1061 |
+ } |
1062 |
+ } else |
1063 |
+- llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); |
1064 |
+- if (!llc->dev) |
1065 |
++ dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); |
1066 |
++ if (!dev) |
1067 |
+ goto out; |
1068 |
+- netdev_tracker_alloc(llc->dev, &llc->dev_tracker, GFP_KERNEL); |
1069 |
+ rc = -EUSERS; |
1070 |
+ llc->laddr.lsap = llc_ui_autoport(); |
1071 |
+ if (!llc->laddr.lsap) |
1072 |
+@@ -304,6 +304,12 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
1073 |
+ sap = llc_sap_open(llc->laddr.lsap, NULL); |
1074 |
+ if (!sap) |
1075 |
+ goto out; |
1076 |
++ |
1077 |
++ /* Note: We do not expect errors from this point. */ |
1078 |
++ llc->dev = dev; |
1079 |
++ netdev_tracker_alloc(llc->dev, &llc->dev_tracker, GFP_KERNEL); |
1080 |
++ dev = NULL; |
1081 |
++ |
1082 |
+ memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN); |
1083 |
+ memcpy(&llc->addr, addr, sizeof(llc->addr)); |
1084 |
+ /* assign new connection to its SAP */ |
1085 |
+@@ -311,6 +317,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
1086 |
+ sock_reset_flag(sk, SOCK_ZAPPED); |
1087 |
+ rc = 0; |
1088 |
+ out: |
1089 |
++ dev_put(dev); |
1090 |
+ return rc; |
1091 |
+ } |
1092 |
+ |
1093 |
+@@ -333,6 +340,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1094 |
+ struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; |
1095 |
+ struct sock *sk = sock->sk; |
1096 |
+ struct llc_sock *llc = llc_sk(sk); |
1097 |
++ struct net_device *dev = NULL; |
1098 |
+ struct llc_sap *sap; |
1099 |
+ int rc = -EINVAL; |
1100 |
+ |
1101 |
+@@ -348,25 +356,27 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1102 |
+ rc = -ENODEV; |
1103 |
+ rcu_read_lock(); |
1104 |
+ if (sk->sk_bound_dev_if) { |
1105 |
+- llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
1106 |
+- if (llc->dev) { |
1107 |
++ dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
1108 |
++ if (dev) { |
1109 |
+ if (is_zero_ether_addr(addr->sllc_mac)) |
1110 |
+- memcpy(addr->sllc_mac, llc->dev->dev_addr, |
1111 |
++ memcpy(addr->sllc_mac, dev->dev_addr, |
1112 |
+ IFHWADDRLEN); |
1113 |
+- if (addr->sllc_arphrd != llc->dev->type || |
1114 |
++ if (addr->sllc_arphrd != dev->type || |
1115 |
+ !ether_addr_equal(addr->sllc_mac, |
1116 |
+- llc->dev->dev_addr)) { |
1117 |
++ dev->dev_addr)) { |
1118 |
+ rc = -EINVAL; |
1119 |
+- llc->dev = NULL; |
1120 |
++ dev = NULL; |
1121 |
+ } |
1122 |
+ } |
1123 |
+- } else |
1124 |
+- llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, |
1125 |
++ } else { |
1126 |
++ dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, |
1127 |
+ addr->sllc_mac); |
1128 |
+- dev_hold_track(llc->dev, &llc->dev_tracker, GFP_ATOMIC); |
1129 |
++ } |
1130 |
++ dev_hold(dev); |
1131 |
+ rcu_read_unlock(); |
1132 |
+- if (!llc->dev) |
1133 |
++ if (!dev) |
1134 |
+ goto out; |
1135 |
++ |
1136 |
+ if (!addr->sllc_sap) { |
1137 |
+ rc = -EUSERS; |
1138 |
+ addr->sllc_sap = llc_ui_autoport(); |
1139 |
+@@ -398,6 +408,12 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1140 |
+ goto out_put; |
1141 |
+ } |
1142 |
+ } |
1143 |
++ |
1144 |
++ /* Note: We do not expect errors from this point. */ |
1145 |
++ llc->dev = dev; |
1146 |
++ netdev_tracker_alloc(llc->dev, &llc->dev_tracker, GFP_KERNEL); |
1147 |
++ dev = NULL; |
1148 |
++ |
1149 |
+ llc->laddr.lsap = addr->sllc_sap; |
1150 |
+ memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN); |
1151 |
+ memcpy(&llc->addr, addr, sizeof(llc->addr)); |
1152 |
+@@ -408,6 +424,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1153 |
+ out_put: |
1154 |
+ llc_sap_put(sap); |
1155 |
+ out: |
1156 |
++ dev_put(dev); |
1157 |
+ release_sock(sk); |
1158 |
+ return rc; |
1159 |
+ } |
1160 |
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c |
1161 |
+index 87a208089caf7..58ff57dc669c4 100644 |
1162 |
+--- a/net/mac80211/cfg.c |
1163 |
++++ b/net/mac80211/cfg.c |
1164 |
+@@ -2148,14 +2148,12 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, |
1165 |
+ const struct mesh_setup *setup) |
1166 |
+ { |
1167 |
+ u8 *new_ie; |
1168 |
+- const u8 *old_ie; |
1169 |
+ struct ieee80211_sub_if_data *sdata = container_of(ifmsh, |
1170 |
+ struct ieee80211_sub_if_data, u.mesh); |
1171 |
+ int i; |
1172 |
+ |
1173 |
+ /* allocate information elements */ |
1174 |
+ new_ie = NULL; |
1175 |
+- old_ie = ifmsh->ie; |
1176 |
+ |
1177 |
+ if (setup->ie_len) { |
1178 |
+ new_ie = kmemdup(setup->ie, setup->ie_len, |
1179 |
+@@ -2165,7 +2163,6 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, |
1180 |
+ } |
1181 |
+ ifmsh->ie_len = setup->ie_len; |
1182 |
+ ifmsh->ie = new_ie; |
1183 |
+- kfree(old_ie); |
1184 |
+ |
1185 |
+ /* now copy the rest of the setup parameters */ |
1186 |
+ ifmsh->mesh_id_len = setup->mesh_id_len; |
1187 |
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c |
1188 |
+index d71a33ae39b35..1f5a0eece0d14 100644 |
1189 |
+--- a/net/netfilter/nf_tables_api.c |
1190 |
++++ b/net/netfilter/nf_tables_api.c |
1191 |
+@@ -9275,17 +9275,23 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) |
1192 |
+ } |
1193 |
+ EXPORT_SYMBOL_GPL(nft_parse_u32_check); |
1194 |
+ |
1195 |
+-static unsigned int nft_parse_register(const struct nlattr *attr) |
1196 |
++static unsigned int nft_parse_register(const struct nlattr *attr, u32 *preg) |
1197 |
+ { |
1198 |
+ unsigned int reg; |
1199 |
+ |
1200 |
+ reg = ntohl(nla_get_be32(attr)); |
1201 |
+ switch (reg) { |
1202 |
+ case NFT_REG_VERDICT...NFT_REG_4: |
1203 |
+- return reg * NFT_REG_SIZE / NFT_REG32_SIZE; |
1204 |
++ *preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE; |
1205 |
++ break; |
1206 |
++ case NFT_REG32_00...NFT_REG32_15: |
1207 |
++ *preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; |
1208 |
++ break; |
1209 |
+ default: |
1210 |
+- return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; |
1211 |
++ return -ERANGE; |
1212 |
+ } |
1213 |
++ |
1214 |
++ return 0; |
1215 |
+ } |
1216 |
+ |
1217 |
+ /** |
1218 |
+@@ -9327,7 +9333,10 @@ int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len) |
1219 |
+ u32 reg; |
1220 |
+ int err; |
1221 |
+ |
1222 |
+- reg = nft_parse_register(attr); |
1223 |
++ err = nft_parse_register(attr, ®); |
1224 |
++ if (err < 0) |
1225 |
++ return err; |
1226 |
++ |
1227 |
+ err = nft_validate_register_load(reg, len); |
1228 |
+ if (err < 0) |
1229 |
+ return err; |
1230 |
+@@ -9382,7 +9391,10 @@ int nft_parse_register_store(const struct nft_ctx *ctx, |
1231 |
+ int err; |
1232 |
+ u32 reg; |
1233 |
+ |
1234 |
+- reg = nft_parse_register(attr); |
1235 |
++ err = nft_parse_register(attr, ®); |
1236 |
++ if (err < 0) |
1237 |
++ return err; |
1238 |
++ |
1239 |
+ err = nft_validate_register_store(ctx, reg, data, type, len); |
1240 |
+ if (err < 0) |
1241 |
+ return err; |
1242 |
+diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c |
1243 |
+index 36e73f9828c50..8af98239655db 100644 |
1244 |
+--- a/net/netfilter/nf_tables_core.c |
1245 |
++++ b/net/netfilter/nf_tables_core.c |
1246 |
+@@ -201,7 +201,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) |
1247 |
+ const struct nft_rule_dp *rule, *last_rule; |
1248 |
+ const struct net *net = nft_net(pkt); |
1249 |
+ const struct nft_expr *expr, *last; |
1250 |
+- struct nft_regs regs; |
1251 |
++ struct nft_regs regs = {}; |
1252 |
+ unsigned int stackptr = 0; |
1253 |
+ struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; |
1254 |
+ bool genbit = READ_ONCE(net->nft.gencursor); |
1255 |
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c |
1256 |
+index 3ee9edf858156..f158f0abd25d8 100644 |
1257 |
+--- a/sound/core/oss/pcm_oss.c |
1258 |
++++ b/sound/core/oss/pcm_oss.c |
1259 |
+@@ -774,6 +774,11 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, |
1260 |
+ |
1261 |
+ if (oss_period_size < 16) |
1262 |
+ return -EINVAL; |
1263 |
++ |
1264 |
++ /* don't allocate too large period; 1MB period must be enough */ |
1265 |
++ if (oss_period_size > 1024 * 1024) |
1266 |
++ return -ENOMEM; |
1267 |
++ |
1268 |
+ runtime->oss.period_bytes = oss_period_size; |
1269 |
+ runtime->oss.period_frames = 1; |
1270 |
+ runtime->oss.periods = oss_periods; |
1271 |
+@@ -1043,10 +1048,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) |
1272 |
+ goto failure; |
1273 |
+ } |
1274 |
+ #endif |
1275 |
+- oss_period_size *= oss_frame_size; |
1276 |
+- |
1277 |
+- oss_buffer_size = oss_period_size * runtime->oss.periods; |
1278 |
+- if (oss_buffer_size < 0) { |
1279 |
++ oss_period_size = array_size(oss_period_size, oss_frame_size); |
1280 |
++ oss_buffer_size = array_size(oss_period_size, runtime->oss.periods); |
1281 |
++ if (oss_buffer_size <= 0) { |
1282 |
+ err = -EINVAL; |
1283 |
+ goto failure; |
1284 |
+ } |
1285 |
+diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c |
1286 |
+index 061ba06bc9262..82e180c776ae1 100644 |
1287 |
+--- a/sound/core/oss/pcm_plugin.c |
1288 |
++++ b/sound/core/oss/pcm_plugin.c |
1289 |
+@@ -62,7 +62,10 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t |
1290 |
+ width = snd_pcm_format_physical_width(format->format); |
1291 |
+ if (width < 0) |
1292 |
+ return width; |
1293 |
+- size = frames * format->channels * width; |
1294 |
++ size = array3_size(frames, format->channels, width); |
1295 |
++ /* check for too large period size once again */ |
1296 |
++ if (size > 1024 * 1024) |
1297 |
++ return -ENOMEM; |
1298 |
+ if (snd_BUG_ON(size % 8)) |
1299 |
+ return -ENXIO; |
1300 |
+ size /= 8; |
1301 |
+diff --git a/sound/core/pcm.c b/sound/core/pcm.c |
1302 |
+index ba4a987ed1c62..edd9849210f2d 100644 |
1303 |
+--- a/sound/core/pcm.c |
1304 |
++++ b/sound/core/pcm.c |
1305 |
+@@ -969,6 +969,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, |
1306 |
+ init_waitqueue_head(&runtime->tsleep); |
1307 |
+ |
1308 |
+ runtime->status->state = SNDRV_PCM_STATE_OPEN; |
1309 |
++ mutex_init(&runtime->buffer_mutex); |
1310 |
+ |
1311 |
+ substream->runtime = runtime; |
1312 |
+ substream->private_data = pcm->private_data; |
1313 |
+@@ -1002,6 +1003,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) |
1314 |
+ } else { |
1315 |
+ substream->runtime = NULL; |
1316 |
+ } |
1317 |
++ mutex_destroy(&runtime->buffer_mutex); |
1318 |
+ kfree(runtime); |
1319 |
+ put_pid(substream->pid); |
1320 |
+ substream->pid = NULL; |
1321 |
+diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c |
1322 |
+index f2090025236b9..a40a35e51fad7 100644 |
1323 |
+--- a/sound/core/pcm_lib.c |
1324 |
++++ b/sound/core/pcm_lib.c |
1325 |
+@@ -1906,9 +1906,11 @@ static int wait_for_avail(struct snd_pcm_substream *substream, |
1326 |
+ if (avail >= runtime->twake) |
1327 |
+ break; |
1328 |
+ snd_pcm_stream_unlock_irq(substream); |
1329 |
++ mutex_unlock(&runtime->buffer_mutex); |
1330 |
+ |
1331 |
+ tout = schedule_timeout(wait_time); |
1332 |
+ |
1333 |
++ mutex_lock(&runtime->buffer_mutex); |
1334 |
+ snd_pcm_stream_lock_irq(substream); |
1335 |
+ set_current_state(TASK_INTERRUPTIBLE); |
1336 |
+ switch (runtime->status->state) { |
1337 |
+@@ -2219,6 +2221,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, |
1338 |
+ |
1339 |
+ nonblock = !!(substream->f_flags & O_NONBLOCK); |
1340 |
+ |
1341 |
++ mutex_lock(&runtime->buffer_mutex); |
1342 |
+ snd_pcm_stream_lock_irq(substream); |
1343 |
+ err = pcm_accessible_state(runtime); |
1344 |
+ if (err < 0) |
1345 |
+@@ -2310,6 +2313,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, |
1346 |
+ if (xfer > 0 && err >= 0) |
1347 |
+ snd_pcm_update_state(substream, runtime); |
1348 |
+ snd_pcm_stream_unlock_irq(substream); |
1349 |
++ mutex_unlock(&runtime->buffer_mutex); |
1350 |
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; |
1351 |
+ } |
1352 |
+ EXPORT_SYMBOL(__snd_pcm_lib_xfer); |
1353 |
+diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c |
1354 |
+index b70ce3b69ab4d..8848d2f3160d8 100644 |
1355 |
+--- a/sound/core/pcm_memory.c |
1356 |
++++ b/sound/core/pcm_memory.c |
1357 |
+@@ -163,19 +163,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, |
1358 |
+ size_t size; |
1359 |
+ struct snd_dma_buffer new_dmab; |
1360 |
+ |
1361 |
++ mutex_lock(&substream->pcm->open_mutex); |
1362 |
+ if (substream->runtime) { |
1363 |
+ buffer->error = -EBUSY; |
1364 |
+- return; |
1365 |
++ goto unlock; |
1366 |
+ } |
1367 |
+ if (!snd_info_get_line(buffer, line, sizeof(line))) { |
1368 |
+ snd_info_get_str(str, line, sizeof(str)); |
1369 |
+ size = simple_strtoul(str, NULL, 10) * 1024; |
1370 |
+ if ((size != 0 && size < 8192) || size > substream->dma_max) { |
1371 |
+ buffer->error = -EINVAL; |
1372 |
+- return; |
1373 |
++ goto unlock; |
1374 |
+ } |
1375 |
+ if (substream->dma_buffer.bytes == size) |
1376 |
+- return; |
1377 |
++ goto unlock; |
1378 |
+ memset(&new_dmab, 0, sizeof(new_dmab)); |
1379 |
+ new_dmab.dev = substream->dma_buffer.dev; |
1380 |
+ if (size > 0) { |
1381 |
+@@ -189,7 +190,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, |
1382 |
+ substream->pcm->card->number, substream->pcm->device, |
1383 |
+ substream->stream ? 'c' : 'p', substream->number, |
1384 |
+ substream->pcm->name, size); |
1385 |
+- return; |
1386 |
++ goto unlock; |
1387 |
+ } |
1388 |
+ substream->buffer_bytes_max = size; |
1389 |
+ } else { |
1390 |
+@@ -201,6 +202,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, |
1391 |
+ } else { |
1392 |
+ buffer->error = -EINVAL; |
1393 |
+ } |
1394 |
++ unlock: |
1395 |
++ mutex_unlock(&substream->pcm->open_mutex); |
1396 |
+ } |
1397 |
+ |
1398 |
+ static inline void preallocate_info_init(struct snd_pcm_substream *substream) |
1399 |
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c |
1400 |
+index a056b3ef3c843..704fdc9ebf911 100644 |
1401 |
+--- a/sound/core/pcm_native.c |
1402 |
++++ b/sound/core/pcm_native.c |
1403 |
+@@ -685,33 +685,40 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, |
1404 |
+ return 0; |
1405 |
+ } |
1406 |
+ |
1407 |
++#if IS_ENABLED(CONFIG_SND_PCM_OSS) |
1408 |
++#define is_oss_stream(substream) ((substream)->oss.oss) |
1409 |
++#else |
1410 |
++#define is_oss_stream(substream) false |
1411 |
++#endif |
1412 |
++ |
1413 |
+ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, |
1414 |
+ struct snd_pcm_hw_params *params) |
1415 |
+ { |
1416 |
+ struct snd_pcm_runtime *runtime; |
1417 |
+- int err, usecs; |
1418 |
++ int err = 0, usecs; |
1419 |
+ unsigned int bits; |
1420 |
+ snd_pcm_uframes_t frames; |
1421 |
+ |
1422 |
+ if (PCM_RUNTIME_CHECK(substream)) |
1423 |
+ return -ENXIO; |
1424 |
+ runtime = substream->runtime; |
1425 |
++ mutex_lock(&runtime->buffer_mutex); |
1426 |
+ snd_pcm_stream_lock_irq(substream); |
1427 |
+ switch (runtime->status->state) { |
1428 |
+ case SNDRV_PCM_STATE_OPEN: |
1429 |
+ case SNDRV_PCM_STATE_SETUP: |
1430 |
+ case SNDRV_PCM_STATE_PREPARED: |
1431 |
++ if (!is_oss_stream(substream) && |
1432 |
++ atomic_read(&substream->mmap_count)) |
1433 |
++ err = -EBADFD; |
1434 |
+ break; |
1435 |
+ default: |
1436 |
+- snd_pcm_stream_unlock_irq(substream); |
1437 |
+- return -EBADFD; |
1438 |
++ err = -EBADFD; |
1439 |
++ break; |
1440 |
+ } |
1441 |
+ snd_pcm_stream_unlock_irq(substream); |
1442 |
+-#if IS_ENABLED(CONFIG_SND_PCM_OSS) |
1443 |
+- if (!substream->oss.oss) |
1444 |
+-#endif |
1445 |
+- if (atomic_read(&substream->mmap_count)) |
1446 |
+- return -EBADFD; |
1447 |
++ if (err) |
1448 |
++ goto unlock; |
1449 |
+ |
1450 |
+ snd_pcm_sync_stop(substream, true); |
1451 |
+ |
1452 |
+@@ -799,16 +806,21 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, |
1453 |
+ if (usecs >= 0) |
1454 |
+ cpu_latency_qos_add_request(&substream->latency_pm_qos_req, |
1455 |
+ usecs); |
1456 |
+- return 0; |
1457 |
++ err = 0; |
1458 |
+ _error: |
1459 |
+- /* hardware might be unusable from this time, |
1460 |
+- so we force application to retry to set |
1461 |
+- the correct hardware parameter settings */ |
1462 |
+- snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); |
1463 |
+- if (substream->ops->hw_free != NULL) |
1464 |
+- substream->ops->hw_free(substream); |
1465 |
+- if (substream->managed_buffer_alloc) |
1466 |
+- snd_pcm_lib_free_pages(substream); |
1467 |
++ if (err) { |
1468 |
++ /* hardware might be unusable from this time, |
1469 |
++ * so we force application to retry to set |
1470 |
++ * the correct hardware parameter settings |
1471 |
++ */ |
1472 |
++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); |
1473 |
++ if (substream->ops->hw_free != NULL) |
1474 |
++ substream->ops->hw_free(substream); |
1475 |
++ if (substream->managed_buffer_alloc) |
1476 |
++ snd_pcm_lib_free_pages(substream); |
1477 |
++ } |
1478 |
++ unlock: |
1479 |
++ mutex_unlock(&runtime->buffer_mutex); |
1480 |
+ return err; |
1481 |
+ } |
1482 |
+ |
1483 |
+@@ -848,26 +860,31 @@ static int do_hw_free(struct snd_pcm_substream *substream) |
1484 |
+ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) |
1485 |
+ { |
1486 |
+ struct snd_pcm_runtime *runtime; |
1487 |
+- int result; |
1488 |
++ int result = 0; |
1489 |
+ |
1490 |
+ if (PCM_RUNTIME_CHECK(substream)) |
1491 |
+ return -ENXIO; |
1492 |
+ runtime = substream->runtime; |
1493 |
++ mutex_lock(&runtime->buffer_mutex); |
1494 |
+ snd_pcm_stream_lock_irq(substream); |
1495 |
+ switch (runtime->status->state) { |
1496 |
+ case SNDRV_PCM_STATE_SETUP: |
1497 |
+ case SNDRV_PCM_STATE_PREPARED: |
1498 |
++ if (atomic_read(&substream->mmap_count)) |
1499 |
++ result = -EBADFD; |
1500 |
+ break; |
1501 |
+ default: |
1502 |
+- snd_pcm_stream_unlock_irq(substream); |
1503 |
+- return -EBADFD; |
1504 |
++ result = -EBADFD; |
1505 |
++ break; |
1506 |
+ } |
1507 |
+ snd_pcm_stream_unlock_irq(substream); |
1508 |
+- if (atomic_read(&substream->mmap_count)) |
1509 |
+- return -EBADFD; |
1510 |
++ if (result) |
1511 |
++ goto unlock; |
1512 |
+ result = do_hw_free(substream); |
1513 |
+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); |
1514 |
+ cpu_latency_qos_remove_request(&substream->latency_pm_qos_req); |
1515 |
++ unlock: |
1516 |
++ mutex_unlock(&runtime->buffer_mutex); |
1517 |
+ return result; |
1518 |
+ } |
1519 |
+ |
1520 |
+@@ -1173,15 +1190,17 @@ struct action_ops { |
1521 |
+ static int snd_pcm_action_group(const struct action_ops *ops, |
1522 |
+ struct snd_pcm_substream *substream, |
1523 |
+ snd_pcm_state_t state, |
1524 |
+- bool do_lock) |
1525 |
++ bool stream_lock) |
1526 |
+ { |
1527 |
+ struct snd_pcm_substream *s = NULL; |
1528 |
+ struct snd_pcm_substream *s1; |
1529 |
+ int res = 0, depth = 1; |
1530 |
+ |
1531 |
+ snd_pcm_group_for_each_entry(s, substream) { |
1532 |
+- if (do_lock && s != substream) { |
1533 |
+- if (s->pcm->nonatomic) |
1534 |
++ if (s != substream) { |
1535 |
++ if (!stream_lock) |
1536 |
++ mutex_lock_nested(&s->runtime->buffer_mutex, depth); |
1537 |
++ else if (s->pcm->nonatomic) |
1538 |
+ mutex_lock_nested(&s->self_group.mutex, depth); |
1539 |
+ else |
1540 |
+ spin_lock_nested(&s->self_group.lock, depth); |
1541 |
+@@ -1209,18 +1228,18 @@ static int snd_pcm_action_group(const struct action_ops *ops, |
1542 |
+ ops->post_action(s, state); |
1543 |
+ } |
1544 |
+ _unlock: |
1545 |
+- if (do_lock) { |
1546 |
+- /* unlock streams */ |
1547 |
+- snd_pcm_group_for_each_entry(s1, substream) { |
1548 |
+- if (s1 != substream) { |
1549 |
+- if (s1->pcm->nonatomic) |
1550 |
+- mutex_unlock(&s1->self_group.mutex); |
1551 |
+- else |
1552 |
+- spin_unlock(&s1->self_group.lock); |
1553 |
+- } |
1554 |
+- if (s1 == s) /* end */ |
1555 |
+- break; |
1556 |
++ /* unlock streams */ |
1557 |
++ snd_pcm_group_for_each_entry(s1, substream) { |
1558 |
++ if (s1 != substream) { |
1559 |
++ if (!stream_lock) |
1560 |
++ mutex_unlock(&s1->runtime->buffer_mutex); |
1561 |
++ else if (s1->pcm->nonatomic) |
1562 |
++ mutex_unlock(&s1->self_group.mutex); |
1563 |
++ else |
1564 |
++ spin_unlock(&s1->self_group.lock); |
1565 |
+ } |
1566 |
++ if (s1 == s) /* end */ |
1567 |
++ break; |
1568 |
+ } |
1569 |
+ return res; |
1570 |
+ } |
1571 |
+@@ -1350,10 +1369,12 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops, |
1572 |
+ |
1573 |
+ /* Guarantee the group members won't change during non-atomic action */ |
1574 |
+ down_read(&snd_pcm_link_rwsem); |
1575 |
++ mutex_lock(&substream->runtime->buffer_mutex); |
1576 |
+ if (snd_pcm_stream_linked(substream)) |
1577 |
+ res = snd_pcm_action_group(ops, substream, state, false); |
1578 |
+ else |
1579 |
+ res = snd_pcm_action_single(ops, substream, state); |
1580 |
++ mutex_unlock(&substream->runtime->buffer_mutex); |
1581 |
+ up_read(&snd_pcm_link_rwsem); |
1582 |
+ return res; |
1583 |
+ } |
1584 |
+@@ -1843,11 +1864,13 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, |
1585 |
+ int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); |
1586 |
+ if (err < 0) |
1587 |
+ return err; |
1588 |
++ snd_pcm_stream_lock_irq(substream); |
1589 |
+ runtime->hw_ptr_base = 0; |
1590 |
+ runtime->hw_ptr_interrupt = runtime->status->hw_ptr - |
1591 |
+ runtime->status->hw_ptr % runtime->period_size; |
1592 |
+ runtime->silence_start = runtime->status->hw_ptr; |
1593 |
+ runtime->silence_filled = 0; |
1594 |
++ snd_pcm_stream_unlock_irq(substream); |
1595 |
+ return 0; |
1596 |
+ } |
1597 |
+ |
1598 |
+@@ -1855,10 +1878,12 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream, |
1599 |
+ snd_pcm_state_t state) |
1600 |
+ { |
1601 |
+ struct snd_pcm_runtime *runtime = substream->runtime; |
1602 |
++ snd_pcm_stream_lock_irq(substream); |
1603 |
+ runtime->control->appl_ptr = runtime->status->hw_ptr; |
1604 |
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
1605 |
+ runtime->silence_size > 0) |
1606 |
+ snd_pcm_playback_silence(substream, ULONG_MAX); |
1607 |
++ snd_pcm_stream_unlock_irq(substream); |
1608 |
+ } |
1609 |
+ |
1610 |
+ static const struct action_ops snd_pcm_action_reset = { |
1611 |
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c |
1612 |
+index 01f296d524ce6..cb60a07d39a8e 100644 |
1613 |
+--- a/sound/pci/ac97/ac97_codec.c |
1614 |
++++ b/sound/pci/ac97/ac97_codec.c |
1615 |
+@@ -938,8 +938,8 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct |
1616 |
+ int codec = kcontrol->private_value & 3; |
1617 |
+ |
1618 |
+ mutex_lock(&ac97->page_mutex); |
1619 |
+- ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); |
1620 |
+- ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); |
1621 |
++ ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); |
1622 |
++ ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); |
1623 |
+ mutex_unlock(&ac97->page_mutex); |
1624 |
+ return 0; |
1625 |
+ } |
1626 |
+diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c |
1627 |
+index 9a678b5cf2855..dab801d9d3b48 100644 |
1628 |
+--- a/sound/pci/cmipci.c |
1629 |
++++ b/sound/pci/cmipci.c |
1630 |
+@@ -298,7 +298,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); |
1631 |
+ #define CM_MICGAINZ 0x01 /* mic boost */ |
1632 |
+ #define CM_MICGAINZ_SHIFT 0 |
1633 |
+ |
1634 |
+-#define CM_REG_MIXER3 0x24 |
1635 |
+ #define CM_REG_AUX_VOL 0x26 |
1636 |
+ #define CM_VAUXL_MASK 0xf0 |
1637 |
+ #define CM_VAUXR_MASK 0x0f |
1638 |
+@@ -3265,7 +3264,7 @@ static int snd_cmipci_probe(struct pci_dev *pci, |
1639 |
+ */ |
1640 |
+ static const unsigned char saved_regs[] = { |
1641 |
+ CM_REG_FUNCTRL1, CM_REG_CHFORMAT, CM_REG_LEGACY_CTRL, CM_REG_MISC_CTRL, |
1642 |
+- CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_MIXER3, CM_REG_PLL, |
1643 |
++ CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_AUX_VOL, CM_REG_PLL, |
1644 |
+ CM_REG_CH0_FRAME1, CM_REG_CH0_FRAME2, |
1645 |
+ CM_REG_CH1_FRAME1, CM_REG_CH1_FRAME2, CM_REG_EXT_MISC, |
1646 |
+ CM_REG_INT_STATUS, CM_REG_INT_HLDCLR, CM_REG_FUNCTRL0, |
1647 |
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
1648 |
+index 3a42457984e98..75ff7e8498b83 100644 |
1649 |
+--- a/sound/pci/hda/patch_realtek.c |
1650 |
++++ b/sound/pci/hda/patch_realtek.c |
1651 |
+@@ -9020,6 +9020,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
1652 |
+ SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), |
1653 |
+ SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), |
1654 |
+ SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), |
1655 |
++ SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), |
1656 |
+ SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), |
1657 |
+ SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), |
1658 |
+ SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
1659 |
+@@ -9103,6 +9104,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
1660 |
+ SND_PCI_QUIRK(0x1558, 0x8561, "Clevo NH[57][0-9][ER][ACDH]Q", ALC269_FIXUP_HEADSET_MIC), |
1661 |
+ SND_PCI_QUIRK(0x1558, 0x8562, "Clevo NH[57][0-9]RZ[Q]", ALC269_FIXUP_DMIC), |
1662 |
+ SND_PCI_QUIRK(0x1558, 0x8668, "Clevo NP50B[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
1663 |
++ SND_PCI_QUIRK(0x1558, 0x866d, "Clevo NP5[05]PN[HJK]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
1664 |
++ SND_PCI_QUIRK(0x1558, 0x867d, "Clevo NP7[01]PN[HJK]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
1665 |
+ SND_PCI_QUIRK(0x1558, 0x8680, "Clevo NJ50LU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
1666 |
+ SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME), |
1667 |
+ SND_PCI_QUIRK(0x1558, 0x8a20, "Clevo NH55DCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
1668 |
+@@ -11067,6 +11070,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
1669 |
+ SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
1670 |
+ SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
1671 |
+ SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2), |
1672 |
++ SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2), |
1673 |
+ SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE), |
1674 |
+ SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50), |
1675 |
+ SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50), |
1676 |
+diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c |
1677 |
+index 2ed92c990b97c..dd9013c476649 100644 |
1678 |
+--- a/sound/soc/sti/uniperif_player.c |
1679 |
++++ b/sound/soc/sti/uniperif_player.c |
1680 |
+@@ -91,7 +91,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) |
1681 |
+ SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player); |
1682 |
+ |
1683 |
+ /* Stop the player */ |
1684 |
+- snd_pcm_stop_xrun(player->substream); |
1685 |
++ snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); |
1686 |
+ } |
1687 |
+ |
1688 |
+ ret = IRQ_HANDLED; |
1689 |
+@@ -105,7 +105,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) |
1690 |
+ SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player); |
1691 |
+ |
1692 |
+ /* Stop the player */ |
1693 |
+- snd_pcm_stop_xrun(player->substream); |
1694 |
++ snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); |
1695 |
+ |
1696 |
+ ret = IRQ_HANDLED; |
1697 |
+ } |
1698 |
+@@ -138,7 +138,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) |
1699 |
+ dev_err(player->dev, "Underflow recovery failed\n"); |
1700 |
+ |
1701 |
+ /* Stop the player */ |
1702 |
+- snd_pcm_stop_xrun(player->substream); |
1703 |
++ snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); |
1704 |
+ |
1705 |
+ ret = IRQ_HANDLED; |
1706 |
+ } |
1707 |
+diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c |
1708 |
+index 136059331211d..065c5f0d1f5f0 100644 |
1709 |
+--- a/sound/soc/sti/uniperif_reader.c |
1710 |
++++ b/sound/soc/sti/uniperif_reader.c |
1711 |
+@@ -65,7 +65,7 @@ static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id) |
1712 |
+ if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) { |
1713 |
+ dev_err(reader->dev, "FIFO error detected\n"); |
1714 |
+ |
1715 |
+- snd_pcm_stop_xrun(reader->substream); |
1716 |
++ snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN); |
1717 |
+ |
1718 |
+ ret = IRQ_HANDLED; |
1719 |
+ } |
1720 |
+diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c |
1721 |
+index 96991ddf5055d..64f5544d0a0aa 100644 |
1722 |
+--- a/sound/usb/mixer_maps.c |
1723 |
++++ b/sound/usb/mixer_maps.c |
1724 |
+@@ -542,6 +542,16 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { |
1725 |
+ .id = USB_ID(0x05a7, 0x40fa), |
1726 |
+ .map = bose_soundlink_map, |
1727 |
+ }, |
1728 |
++ { |
1729 |
++ /* Corsair Virtuoso SE Latest (wired mode) */ |
1730 |
++ .id = USB_ID(0x1b1c, 0x0a3f), |
1731 |
++ .map = corsair_virtuoso_map, |
1732 |
++ }, |
1733 |
++ { |
1734 |
++ /* Corsair Virtuoso SE Latest (wireless mode) */ |
1735 |
++ .id = USB_ID(0x1b1c, 0x0a40), |
1736 |
++ .map = corsair_virtuoso_map, |
1737 |
++ }, |
1738 |
+ { |
1739 |
+ /* Corsair Virtuoso SE (wired mode) */ |
1740 |
+ .id = USB_ID(0x1b1c, 0x0a3d), |
1741 |
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c |
1742 |
+index e447ddd6854cd..d35cf54cab338 100644 |
1743 |
+--- a/sound/usb/mixer_quirks.c |
1744 |
++++ b/sound/usb/mixer_quirks.c |
1745 |
+@@ -3360,9 +3360,10 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, |
1746 |
+ if (unitid == 7 && cval->control == UAC_FU_VOLUME) |
1747 |
+ snd_dragonfly_quirk_db_scale(mixer, cval, kctl); |
1748 |
+ break; |
1749 |
+- /* lowest playback value is muted on C-Media devices */ |
1750 |
+- case USB_ID(0x0d8c, 0x000c): |
1751 |
+- case USB_ID(0x0d8c, 0x0014): |
1752 |
++ /* lowest playback value is muted on some devices */ |
1753 |
++ case USB_ID(0x0d8c, 0x000c): /* C-Media */ |
1754 |
++ case USB_ID(0x0d8c, 0x0014): /* C-Media */ |
1755 |
++ case USB_ID(0x19f7, 0x0003): /* RODE NT-USB */ |
1756 |
+ if (strstr(kctl->id.name, "Playback")) |
1757 |
+ cval->min_mute = 1; |
1758 |
+ break; |