1 |
commit: e6bafe6f98124c8afbf342d9c8503d8b19bdd3e5 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Mar 28 10:58:41 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Mar 28 10:58:41 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e6bafe6f |
7 |
|
8 |
Linux patch 5.4.188 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1187_linux-5.4.188.patch | 1264 ++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 1268 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 4c62caea..0cc3f59a 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -791,6 +791,10 @@ Patch: 1186_linux-5.4.187.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.4.187 |
23 |
|
24 |
+Patch: 1187_linux-5.4.188.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.4.188 |
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/1187_linux-5.4.188.patch b/1187_linux-5.4.188.patch |
33 |
new file mode 100644 |
34 |
index 00000000..43de3071 |
35 |
--- /dev/null |
36 |
+++ b/1187_linux-5.4.188.patch |
37 |
@@ -0,0 +1,1264 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index d07421bc5c2fb..8684857148066 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,7 +1,7 @@ |
43 |
+ # SPDX-License-Identifier: GPL-2.0 |
44 |
+ VERSION = 5 |
45 |
+ PATCHLEVEL = 4 |
46 |
+-SUBLEVEL = 187 |
47 |
++SUBLEVEL = 188 |
48 |
+ EXTRAVERSION = |
49 |
+ NAME = Kleptomaniac Octopus |
50 |
+ |
51 |
+diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h |
52 |
+index 8916ad9f9f139..e205b1db8c807 100644 |
53 |
+--- a/arch/nds32/include/asm/uaccess.h |
54 |
++++ b/arch/nds32/include/asm/uaccess.h |
55 |
+@@ -71,9 +71,7 @@ static inline void set_fs(mm_segment_t fs) |
56 |
+ * versions are void (ie, don't return a value as such). |
57 |
+ */ |
58 |
+ |
59 |
+-#define get_user __get_user \ |
60 |
+- |
61 |
+-#define __get_user(x, ptr) \ |
62 |
++#define get_user(x, ptr) \ |
63 |
+ ({ \ |
64 |
+ long __gu_err = 0; \ |
65 |
+ __get_user_check((x), (ptr), __gu_err); \ |
66 |
+@@ -86,6 +84,14 @@ static inline void set_fs(mm_segment_t fs) |
67 |
+ (void)0; \ |
68 |
+ }) |
69 |
+ |
70 |
++#define __get_user(x, ptr) \ |
71 |
++({ \ |
72 |
++ long __gu_err = 0; \ |
73 |
++ const __typeof__(*(ptr)) __user *__p = (ptr); \ |
74 |
++ __get_user_err((x), __p, (__gu_err)); \ |
75 |
++ __gu_err; \ |
76 |
++}) |
77 |
++ |
78 |
+ #define __get_user_check(x, ptr, err) \ |
79 |
+ ({ \ |
80 |
+ const __typeof__(*(ptr)) __user *__p = (ptr); \ |
81 |
+@@ -166,12 +172,18 @@ do { \ |
82 |
+ : "r"(addr), "i"(-EFAULT) \ |
83 |
+ : "cc") |
84 |
+ |
85 |
+-#define put_user __put_user \ |
86 |
++#define put_user(x, ptr) \ |
87 |
++({ \ |
88 |
++ long __pu_err = 0; \ |
89 |
++ __put_user_check((x), (ptr), __pu_err); \ |
90 |
++ __pu_err; \ |
91 |
++}) |
92 |
+ |
93 |
+ #define __put_user(x, ptr) \ |
94 |
+ ({ \ |
95 |
+ long __pu_err = 0; \ |
96 |
+- __put_user_err((x), (ptr), __pu_err); \ |
97 |
++ __typeof__(*(ptr)) __user *__p = (ptr); \ |
98 |
++ __put_user_err((x), __p, __pu_err); \ |
99 |
+ __pu_err; \ |
100 |
+ }) |
101 |
+ |
102 |
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c |
103 |
+index 4137a7342d687..7b75658b7e9ac 100644 |
104 |
+--- a/arch/x86/kernel/acpi/boot.c |
105 |
++++ b/arch/x86/kernel/acpi/boot.c |
106 |
+@@ -1339,6 +1339,17 @@ static int __init disable_acpi_pci(const struct dmi_system_id *d) |
107 |
+ return 0; |
108 |
+ } |
109 |
+ |
110 |
++static int __init disable_acpi_xsdt(const struct dmi_system_id *d) |
111 |
++{ |
112 |
++ if (!acpi_force) { |
113 |
++ pr_notice("%s detected: force use of acpi=rsdt\n", d->ident); |
114 |
++ acpi_gbl_do_not_use_xsdt = TRUE; |
115 |
++ } else { |
116 |
++ pr_notice("Warning: DMI blacklist says broken, but acpi XSDT forced\n"); |
117 |
++ } |
118 |
++ return 0; |
119 |
++} |
120 |
++ |
121 |
+ static int __init dmi_disable_acpi(const struct dmi_system_id *d) |
122 |
+ { |
123 |
+ if (!acpi_force) { |
124 |
+@@ -1463,6 +1474,19 @@ static const struct dmi_system_id acpi_dmi_table[] __initconst = { |
125 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
126 |
+ }, |
127 |
+ }, |
128 |
++ /* |
129 |
++ * Boxes that need ACPI XSDT use disabled due to corrupted tables |
130 |
++ */ |
131 |
++ { |
132 |
++ .callback = disable_acpi_xsdt, |
133 |
++ .ident = "Advantech DAC-BJ01", |
134 |
++ .matches = { |
135 |
++ DMI_MATCH(DMI_SYS_VENDOR, "NEC"), |
136 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Bearlake CRB Board"), |
137 |
++ DMI_MATCH(DMI_BIOS_VERSION, "V1.12"), |
138 |
++ DMI_MATCH(DMI_BIOS_DATE, "02/01/2011"), |
139 |
++ }, |
140 |
++ }, |
141 |
+ {} |
142 |
+ }; |
143 |
+ |
144 |
+diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c |
145 |
+index 4e0aea5f008e3..974c2df13da1d 100644 |
146 |
+--- a/drivers/acpi/battery.c |
147 |
++++ b/drivers/acpi/battery.c |
148 |
+@@ -77,6 +77,10 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); |
149 |
+ |
150 |
+ static const struct acpi_device_id battery_device_ids[] = { |
151 |
+ {"PNP0C0A", 0}, |
152 |
++ |
153 |
++ /* Microsoft Surface Go 3 */ |
154 |
++ {"MSHW0146", 0}, |
155 |
++ |
156 |
+ {"", 0}, |
157 |
+ }; |
158 |
+ |
159 |
+@@ -1403,6 +1407,14 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { |
160 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"), |
161 |
+ }, |
162 |
+ }, |
163 |
++ { |
164 |
++ /* Microsoft Surface Go 3 */ |
165 |
++ .callback = battery_notification_delay_quirk, |
166 |
++ .matches = { |
167 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), |
168 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"), |
169 |
++ }, |
170 |
++ }, |
171 |
+ {}, |
172 |
+ }; |
173 |
+ |
174 |
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c |
175 |
+index e7978d983b263..de4142723ff48 100644 |
176 |
+--- a/drivers/acpi/video_detect.c |
177 |
++++ b/drivers/acpi/video_detect.c |
178 |
+@@ -372,6 +372,81 @@ static const struct dmi_system_id video_detect_dmi_table[] = { |
179 |
+ DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"), |
180 |
+ }, |
181 |
+ }, |
182 |
++ /* |
183 |
++ * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a |
184 |
++ * working native and video interface. However the default detection |
185 |
++ * mechanism first registers the video interface before unregistering |
186 |
++ * it again and switching to the native interface during boot. This |
187 |
++ * results in a dangling SBIOS request for backlight change for some |
188 |
++ * reason, causing the backlight to switch to ~2% once per boot on the |
189 |
++ * first power cord connect or disconnect event. Setting the native |
190 |
++ * interface explicitly circumvents this buggy behaviour, by avoiding |
191 |
++ * the unregistering process. |
192 |
++ */ |
193 |
++ { |
194 |
++ .callback = video_detect_force_native, |
195 |
++ .ident = "Clevo NL5xRU", |
196 |
++ .matches = { |
197 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
198 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
199 |
++ }, |
200 |
++ }, |
201 |
++ { |
202 |
++ .callback = video_detect_force_native, |
203 |
++ .ident = "Clevo NL5xRU", |
204 |
++ .matches = { |
205 |
++ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), |
206 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
207 |
++ }, |
208 |
++ }, |
209 |
++ { |
210 |
++ .callback = video_detect_force_native, |
211 |
++ .ident = "Clevo NL5xRU", |
212 |
++ .matches = { |
213 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), |
214 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
215 |
++ }, |
216 |
++ }, |
217 |
++ { |
218 |
++ .callback = video_detect_force_native, |
219 |
++ .ident = "Clevo NL5xRU", |
220 |
++ .matches = { |
221 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
222 |
++ DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), |
223 |
++ }, |
224 |
++ }, |
225 |
++ { |
226 |
++ .callback = video_detect_force_native, |
227 |
++ .ident = "Clevo NL5xRU", |
228 |
++ .matches = { |
229 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
230 |
++ DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), |
231 |
++ }, |
232 |
++ }, |
233 |
++ { |
234 |
++ .callback = video_detect_force_native, |
235 |
++ .ident = "Clevo NL5xNU", |
236 |
++ .matches = { |
237 |
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), |
238 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
239 |
++ }, |
240 |
++ }, |
241 |
++ { |
242 |
++ .callback = video_detect_force_native, |
243 |
++ .ident = "Clevo NL5xNU", |
244 |
++ .matches = { |
245 |
++ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), |
246 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
247 |
++ }, |
248 |
++ }, |
249 |
++ { |
250 |
++ .callback = video_detect_force_native, |
251 |
++ .ident = "Clevo NL5xNU", |
252 |
++ .matches = { |
253 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), |
254 |
++ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
255 |
++ }, |
256 |
++ }, |
257 |
+ |
258 |
+ /* |
259 |
+ * Desktops which falsely report a backlight and which our heuristics |
260 |
+diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c |
261 |
+index 1784530b8387b..b99e1941c52c9 100644 |
262 |
+--- a/drivers/char/tpm/tpm-dev-common.c |
263 |
++++ b/drivers/char/tpm/tpm-dev-common.c |
264 |
+@@ -70,7 +70,13 @@ static void tpm_dev_async_work(struct work_struct *work) |
265 |
+ ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer, |
266 |
+ sizeof(priv->data_buffer)); |
267 |
+ tpm_put_ops(priv->chip); |
268 |
+- if (ret > 0) { |
269 |
++ |
270 |
++ /* |
271 |
++ * If ret is > 0 then tpm_dev_transmit returned the size of the |
272 |
++ * response. If ret is < 0 then tpm_dev_transmit failed and |
273 |
++ * returned an error code. |
274 |
++ */ |
275 |
++ if (ret != 0) { |
276 |
+ priv->response_length = ret; |
277 |
+ mod_timer(&priv->user_read_timer, jiffies + (120 * HZ)); |
278 |
+ } |
279 |
+diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c |
280 |
+index 97e916856cf3e..d2225020e4d2c 100644 |
281 |
+--- a/drivers/char/tpm/tpm2-space.c |
282 |
++++ b/drivers/char/tpm/tpm2-space.c |
283 |
+@@ -58,12 +58,12 @@ int tpm2_init_space(struct tpm_space *space, unsigned int buf_size) |
284 |
+ |
285 |
+ void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space) |
286 |
+ { |
287 |
+- mutex_lock(&chip->tpm_mutex); |
288 |
+- if (!tpm_chip_start(chip)) { |
289 |
++ |
290 |
++ if (tpm_try_get_ops(chip) == 0) { |
291 |
+ tpm2_flush_sessions(chip, space); |
292 |
+- tpm_chip_stop(chip); |
293 |
++ tpm_put_ops(chip); |
294 |
+ } |
295 |
+- mutex_unlock(&chip->tpm_mutex); |
296 |
++ |
297 |
+ kfree(space->context_buf); |
298 |
+ kfree(space->session_buf); |
299 |
+ } |
300 |
+diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c |
301 |
+index 3852d31ce0a4b..37a9f969c59cd 100644 |
302 |
+--- a/drivers/crypto/qat/qat_common/qat_crypto.c |
303 |
++++ b/drivers/crypto/qat/qat_common/qat_crypto.c |
304 |
+@@ -170,6 +170,14 @@ int qat_crypto_dev_config(struct adf_accel_dev *accel_dev) |
305 |
+ goto err; |
306 |
+ if (adf_cfg_section_add(accel_dev, "Accelerator0")) |
307 |
+ goto err; |
308 |
++ |
309 |
++ /* Temporarily set the number of crypto instances to zero to avoid |
310 |
++ * registering the crypto algorithms. |
311 |
++ * This will be removed when the algorithms will support the |
312 |
++ * CRYPTO_TFM_REQ_MAY_BACKLOG flag |
313 |
++ */ |
314 |
++ instances = 0; |
315 |
++ |
316 |
+ for (i = 0; i < instances; i++) { |
317 |
+ val = i; |
318 |
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_BANK_NUM, i); |
319 |
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c |
320 |
+index cc8031ae9aa3f..ce4e617a6ec49 100644 |
321 |
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c |
322 |
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c |
323 |
+@@ -696,6 +696,12 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, |
324 |
+ buf_pool->rx_skb[skb_index] = NULL; |
325 |
+ |
326 |
+ datalen = xgene_enet_get_data_len(le64_to_cpu(raw_desc->m1)); |
327 |
++ |
328 |
++ /* strip off CRC as HW isn't doing this */ |
329 |
++ nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0)); |
330 |
++ if (!nv) |
331 |
++ datalen -= 4; |
332 |
++ |
333 |
+ skb_put(skb, datalen); |
334 |
+ prefetch(skb->data - NET_IP_ALIGN); |
335 |
+ skb->protocol = eth_type_trans(skb, ndev); |
336 |
+@@ -717,12 +723,8 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, |
337 |
+ } |
338 |
+ } |
339 |
+ |
340 |
+- nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0)); |
341 |
+- if (!nv) { |
342 |
+- /* strip off CRC as HW isn't doing this */ |
343 |
+- datalen -= 4; |
344 |
++ if (!nv) |
345 |
+ goto skip_jumbo; |
346 |
+- } |
347 |
+ |
348 |
+ slots = page_pool->slots - 1; |
349 |
+ head = page_pool->head; |
350 |
+diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c |
351 |
+index 6586378cacb05..a7ab6dab0f32d 100644 |
352 |
+--- a/drivers/nfc/st21nfca/se.c |
353 |
++++ b/drivers/nfc/st21nfca/se.c |
354 |
+@@ -321,6 +321,11 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, |
355 |
+ return -ENOMEM; |
356 |
+ |
357 |
+ transaction->aid_len = skb->data[1]; |
358 |
++ |
359 |
++ /* Checking if the length of the AID is valid */ |
360 |
++ if (transaction->aid_len > sizeof(transaction->aid)) |
361 |
++ return -EINVAL; |
362 |
++ |
363 |
+ memcpy(transaction->aid, &skb->data[2], |
364 |
+ transaction->aid_len); |
365 |
+ |
366 |
+@@ -330,6 +335,11 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, |
367 |
+ return -EPROTO; |
368 |
+ |
369 |
+ transaction->params_len = skb->data[transaction->aid_len + 3]; |
370 |
++ |
371 |
++ /* Total size is allocated (skb->len - 2) minus fixed array members */ |
372 |
++ if (transaction->params_len > ((skb->len - 2) - sizeof(struct nfc_evt_transaction))) |
373 |
++ return -EINVAL; |
374 |
++ |
375 |
+ memcpy(transaction->params, skb->data + |
376 |
+ transaction->aid_len + 4, transaction->params_len); |
377 |
+ |
378 |
+diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c |
379 |
+index 3c3f387936e80..30086ae03605f 100644 |
380 |
+--- a/drivers/staging/fbtft/fb_st7789v.c |
381 |
++++ b/drivers/staging/fbtft/fb_st7789v.c |
382 |
+@@ -76,6 +76,8 @@ enum st7789v_command { |
383 |
+ */ |
384 |
+ static int init_display(struct fbtft_par *par) |
385 |
+ { |
386 |
++ par->fbtftops.reset(par); |
387 |
++ |
388 |
+ /* turn off sleep mode */ |
389 |
+ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); |
390 |
+ mdelay(120); |
391 |
+diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c |
392 |
+index 3517883b5cdb9..a31163547fbaa 100644 |
393 |
+--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c |
394 |
++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c |
395 |
+@@ -216,6 +216,10 @@ static void int3400_notify(acpi_handle handle, |
396 |
+ thermal_prop[4] = NULL; |
397 |
+ kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE, |
398 |
+ thermal_prop); |
399 |
++ kfree(thermal_prop[0]); |
400 |
++ kfree(thermal_prop[1]); |
401 |
++ kfree(thermal_prop[2]); |
402 |
++ kfree(thermal_prop[3]); |
403 |
+ break; |
404 |
+ default: |
405 |
+ /* Ignore unknown notification codes sent to INT3400 device */ |
406 |
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c |
407 |
+index 662937472e9bd..79ad6b2c96082 100644 |
408 |
+--- a/fs/nfsd/filecache.c |
409 |
++++ b/fs/nfsd/filecache.c |
410 |
+@@ -44,6 +44,17 @@ struct nfsd_fcache_bucket { |
411 |
+ |
412 |
+ static DEFINE_PER_CPU(unsigned long, nfsd_file_cache_hits); |
413 |
+ |
414 |
++struct nfsd_fcache_disposal { |
415 |
++ struct list_head list; |
416 |
++ struct work_struct work; |
417 |
++ struct net *net; |
418 |
++ spinlock_t lock; |
419 |
++ struct list_head freeme; |
420 |
++ struct rcu_head rcu; |
421 |
++}; |
422 |
++ |
423 |
++struct workqueue_struct *nfsd_filecache_wq __read_mostly; |
424 |
++ |
425 |
+ static struct kmem_cache *nfsd_file_slab; |
426 |
+ static struct kmem_cache *nfsd_file_mark_slab; |
427 |
+ static struct nfsd_fcache_bucket *nfsd_file_hashtbl; |
428 |
+@@ -52,32 +63,21 @@ static long nfsd_file_lru_flags; |
429 |
+ static struct fsnotify_group *nfsd_file_fsnotify_group; |
430 |
+ static atomic_long_t nfsd_filecache_count; |
431 |
+ static struct delayed_work nfsd_filecache_laundrette; |
432 |
++static DEFINE_SPINLOCK(laundrette_lock); |
433 |
++static LIST_HEAD(laundrettes); |
434 |
+ |
435 |
+-enum nfsd_file_laundrette_ctl { |
436 |
+- NFSD_FILE_LAUNDRETTE_NOFLUSH = 0, |
437 |
+- NFSD_FILE_LAUNDRETTE_MAY_FLUSH |
438 |
+-}; |
439 |
++static void nfsd_file_gc(void); |
440 |
+ |
441 |
+ static void |
442 |
+-nfsd_file_schedule_laundrette(enum nfsd_file_laundrette_ctl ctl) |
443 |
++nfsd_file_schedule_laundrette(void) |
444 |
+ { |
445 |
+ long count = atomic_long_read(&nfsd_filecache_count); |
446 |
+ |
447 |
+ if (count == 0 || test_bit(NFSD_FILE_SHUTDOWN, &nfsd_file_lru_flags)) |
448 |
+ return; |
449 |
+ |
450 |
+- /* Be more aggressive about scanning if over the threshold */ |
451 |
+- if (count > NFSD_FILE_LRU_THRESHOLD) |
452 |
+- mod_delayed_work(system_wq, &nfsd_filecache_laundrette, 0); |
453 |
+- else |
454 |
+- schedule_delayed_work(&nfsd_filecache_laundrette, NFSD_LAUNDRETTE_DELAY); |
455 |
+- |
456 |
+- if (ctl == NFSD_FILE_LAUNDRETTE_NOFLUSH) |
457 |
+- return; |
458 |
+- |
459 |
+- /* ...and don't delay flushing if we're out of control */ |
460 |
+- if (count >= NFSD_FILE_LRU_LIMIT) |
461 |
+- flush_delayed_work(&nfsd_filecache_laundrette); |
462 |
++ queue_delayed_work(system_wq, &nfsd_filecache_laundrette, |
463 |
++ NFSD_LAUNDRETTE_DELAY); |
464 |
+ } |
465 |
+ |
466 |
+ static void |
467 |
+@@ -260,8 +260,6 @@ nfsd_file_do_unhash(struct nfsd_file *nf) |
468 |
+ nfsd_reset_boot_verifier(net_generic(nf->nf_net, nfsd_net_id)); |
469 |
+ --nfsd_file_hashtbl[nf->nf_hashval].nfb_count; |
470 |
+ hlist_del_rcu(&nf->nf_node); |
471 |
+- if (!list_empty(&nf->nf_lru)) |
472 |
+- list_lru_del(&nfsd_file_lru, &nf->nf_lru); |
473 |
+ atomic_long_dec(&nfsd_filecache_count); |
474 |
+ } |
475 |
+ |
476 |
+@@ -270,6 +268,8 @@ nfsd_file_unhash(struct nfsd_file *nf) |
477 |
+ { |
478 |
+ if (test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { |
479 |
+ nfsd_file_do_unhash(nf); |
480 |
++ if (!list_empty(&nf->nf_lru)) |
481 |
++ list_lru_del(&nfsd_file_lru, &nf->nf_lru); |
482 |
+ return true; |
483 |
+ } |
484 |
+ return false; |
485 |
+@@ -316,7 +316,9 @@ nfsd_file_put(struct nfsd_file *nf) |
486 |
+ |
487 |
+ set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); |
488 |
+ if (nfsd_file_put_noref(nf) == 1 && is_hashed && unused) |
489 |
+- nfsd_file_schedule_laundrette(NFSD_FILE_LAUNDRETTE_MAY_FLUSH); |
490 |
++ nfsd_file_schedule_laundrette(); |
491 |
++ if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT) |
492 |
++ nfsd_file_gc(); |
493 |
+ } |
494 |
+ |
495 |
+ struct nfsd_file * |
496 |
+@@ -357,6 +359,58 @@ nfsd_file_dispose_list_sync(struct list_head *dispose) |
497 |
+ flush_delayed_fput(); |
498 |
+ } |
499 |
+ |
500 |
++static void |
501 |
++nfsd_file_list_remove_disposal(struct list_head *dst, |
502 |
++ struct nfsd_fcache_disposal *l) |
503 |
++{ |
504 |
++ spin_lock(&l->lock); |
505 |
++ list_splice_init(&l->freeme, dst); |
506 |
++ spin_unlock(&l->lock); |
507 |
++} |
508 |
++ |
509 |
++static void |
510 |
++nfsd_file_list_add_disposal(struct list_head *files, struct net *net) |
511 |
++{ |
512 |
++ struct nfsd_fcache_disposal *l; |
513 |
++ |
514 |
++ rcu_read_lock(); |
515 |
++ list_for_each_entry_rcu(l, &laundrettes, list) { |
516 |
++ if (l->net == net) { |
517 |
++ spin_lock(&l->lock); |
518 |
++ list_splice_tail_init(files, &l->freeme); |
519 |
++ spin_unlock(&l->lock); |
520 |
++ queue_work(nfsd_filecache_wq, &l->work); |
521 |
++ break; |
522 |
++ } |
523 |
++ } |
524 |
++ rcu_read_unlock(); |
525 |
++} |
526 |
++ |
527 |
++static void |
528 |
++nfsd_file_list_add_pernet(struct list_head *dst, struct list_head *src, |
529 |
++ struct net *net) |
530 |
++{ |
531 |
++ struct nfsd_file *nf, *tmp; |
532 |
++ |
533 |
++ list_for_each_entry_safe(nf, tmp, src, nf_lru) { |
534 |
++ if (nf->nf_net == net) |
535 |
++ list_move_tail(&nf->nf_lru, dst); |
536 |
++ } |
537 |
++} |
538 |
++ |
539 |
++static void |
540 |
++nfsd_file_dispose_list_delayed(struct list_head *dispose) |
541 |
++{ |
542 |
++ LIST_HEAD(list); |
543 |
++ struct nfsd_file *nf; |
544 |
++ |
545 |
++ while(!list_empty(dispose)) { |
546 |
++ nf = list_first_entry(dispose, struct nfsd_file, nf_lru); |
547 |
++ nfsd_file_list_add_pernet(&list, dispose, nf->nf_net); |
548 |
++ nfsd_file_list_add_disposal(&list, nf->nf_net); |
549 |
++ } |
550 |
++} |
551 |
++ |
552 |
+ /* |
553 |
+ * Note this can deadlock with nfsd_file_cache_purge. |
554 |
+ */ |
555 |
+@@ -403,18 +457,40 @@ out_skip: |
556 |
+ return LRU_SKIP; |
557 |
+ } |
558 |
+ |
559 |
+-static void |
560 |
+-nfsd_file_lru_dispose(struct list_head *head) |
561 |
++static unsigned long |
562 |
++nfsd_file_lru_walk_list(struct shrink_control *sc) |
563 |
+ { |
564 |
+- while(!list_empty(head)) { |
565 |
+- struct nfsd_file *nf = list_first_entry(head, |
566 |
+- struct nfsd_file, nf_lru); |
567 |
+- list_del_init(&nf->nf_lru); |
568 |
++ LIST_HEAD(head); |
569 |
++ struct nfsd_file *nf; |
570 |
++ unsigned long ret; |
571 |
++ |
572 |
++ if (sc) |
573 |
++ ret = list_lru_shrink_walk(&nfsd_file_lru, sc, |
574 |
++ nfsd_file_lru_cb, &head); |
575 |
++ else |
576 |
++ ret = list_lru_walk(&nfsd_file_lru, |
577 |
++ nfsd_file_lru_cb, |
578 |
++ &head, LONG_MAX); |
579 |
++ list_for_each_entry(nf, &head, nf_lru) { |
580 |
+ spin_lock(&nfsd_file_hashtbl[nf->nf_hashval].nfb_lock); |
581 |
+ nfsd_file_do_unhash(nf); |
582 |
+ spin_unlock(&nfsd_file_hashtbl[nf->nf_hashval].nfb_lock); |
583 |
+- nfsd_file_put_noref(nf); |
584 |
+ } |
585 |
++ nfsd_file_dispose_list_delayed(&head); |
586 |
++ return ret; |
587 |
++} |
588 |
++ |
589 |
++static void |
590 |
++nfsd_file_gc(void) |
591 |
++{ |
592 |
++ nfsd_file_lru_walk_list(NULL); |
593 |
++} |
594 |
++ |
595 |
++static void |
596 |
++nfsd_file_gc_worker(struct work_struct *work) |
597 |
++{ |
598 |
++ nfsd_file_gc(); |
599 |
++ nfsd_file_schedule_laundrette(); |
600 |
+ } |
601 |
+ |
602 |
+ static unsigned long |
603 |
+@@ -426,12 +502,7 @@ nfsd_file_lru_count(struct shrinker *s, struct shrink_control *sc) |
604 |
+ static unsigned long |
605 |
+ nfsd_file_lru_scan(struct shrinker *s, struct shrink_control *sc) |
606 |
+ { |
607 |
+- LIST_HEAD(head); |
608 |
+- unsigned long ret; |
609 |
+- |
610 |
+- ret = list_lru_shrink_walk(&nfsd_file_lru, sc, nfsd_file_lru_cb, &head); |
611 |
+- nfsd_file_lru_dispose(&head); |
612 |
+- return ret; |
613 |
++ return nfsd_file_lru_walk_list(sc); |
614 |
+ } |
615 |
+ |
616 |
+ static struct shrinker nfsd_file_shrinker = { |
617 |
+@@ -493,7 +564,7 @@ nfsd_file_close_inode(struct inode *inode) |
618 |
+ |
619 |
+ __nfsd_file_close_inode(inode, hashval, &dispose); |
620 |
+ trace_nfsd_file_close_inode(inode, hashval, !list_empty(&dispose)); |
621 |
+- nfsd_file_dispose_list(&dispose); |
622 |
++ nfsd_file_dispose_list_delayed(&dispose); |
623 |
+ } |
624 |
+ |
625 |
+ /** |
626 |
+@@ -509,16 +580,11 @@ static void |
627 |
+ nfsd_file_delayed_close(struct work_struct *work) |
628 |
+ { |
629 |
+ LIST_HEAD(head); |
630 |
++ struct nfsd_fcache_disposal *l = container_of(work, |
631 |
++ struct nfsd_fcache_disposal, work); |
632 |
+ |
633 |
+- list_lru_walk(&nfsd_file_lru, nfsd_file_lru_cb, &head, LONG_MAX); |
634 |
+- |
635 |
+- if (test_and_clear_bit(NFSD_FILE_LRU_RESCAN, &nfsd_file_lru_flags)) |
636 |
+- nfsd_file_schedule_laundrette(NFSD_FILE_LAUNDRETTE_NOFLUSH); |
637 |
+- |
638 |
+- if (!list_empty(&head)) { |
639 |
+- nfsd_file_lru_dispose(&head); |
640 |
+- flush_delayed_fput(); |
641 |
+- } |
642 |
++ nfsd_file_list_remove_disposal(&head, l); |
643 |
++ nfsd_file_dispose_list(&head); |
644 |
+ } |
645 |
+ |
646 |
+ static int |
647 |
+@@ -579,6 +645,10 @@ nfsd_file_cache_init(void) |
648 |
+ if (nfsd_file_hashtbl) |
649 |
+ return 0; |
650 |
+ |
651 |
++ nfsd_filecache_wq = alloc_workqueue("nfsd_filecache", 0, 0); |
652 |
++ if (!nfsd_filecache_wq) |
653 |
++ goto out; |
654 |
++ |
655 |
+ nfsd_file_hashtbl = kcalloc(NFSD_FILE_HASH_SIZE, |
656 |
+ sizeof(*nfsd_file_hashtbl), GFP_KERNEL); |
657 |
+ if (!nfsd_file_hashtbl) { |
658 |
+@@ -632,7 +702,7 @@ nfsd_file_cache_init(void) |
659 |
+ spin_lock_init(&nfsd_file_hashtbl[i].nfb_lock); |
660 |
+ } |
661 |
+ |
662 |
+- INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_delayed_close); |
663 |
++ INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker); |
664 |
+ out: |
665 |
+ return ret; |
666 |
+ out_notifier: |
667 |
+@@ -648,6 +718,8 @@ out_err: |
668 |
+ nfsd_file_mark_slab = NULL; |
669 |
+ kfree(nfsd_file_hashtbl); |
670 |
+ nfsd_file_hashtbl = NULL; |
671 |
++ destroy_workqueue(nfsd_filecache_wq); |
672 |
++ nfsd_filecache_wq = NULL; |
673 |
+ goto out; |
674 |
+ } |
675 |
+ |
676 |
+@@ -686,6 +758,88 @@ nfsd_file_cache_purge(struct net *net) |
677 |
+ } |
678 |
+ } |
679 |
+ |
680 |
++static struct nfsd_fcache_disposal * |
681 |
++nfsd_alloc_fcache_disposal(struct net *net) |
682 |
++{ |
683 |
++ struct nfsd_fcache_disposal *l; |
684 |
++ |
685 |
++ l = kmalloc(sizeof(*l), GFP_KERNEL); |
686 |
++ if (!l) |
687 |
++ return NULL; |
688 |
++ INIT_WORK(&l->work, nfsd_file_delayed_close); |
689 |
++ l->net = net; |
690 |
++ spin_lock_init(&l->lock); |
691 |
++ INIT_LIST_HEAD(&l->freeme); |
692 |
++ return l; |
693 |
++} |
694 |
++ |
695 |
++static void |
696 |
++nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l) |
697 |
++{ |
698 |
++ rcu_assign_pointer(l->net, NULL); |
699 |
++ cancel_work_sync(&l->work); |
700 |
++ nfsd_file_dispose_list(&l->freeme); |
701 |
++ kfree_rcu(l, rcu); |
702 |
++} |
703 |
++ |
704 |
++static void |
705 |
++nfsd_add_fcache_disposal(struct nfsd_fcache_disposal *l) |
706 |
++{ |
707 |
++ spin_lock(&laundrette_lock); |
708 |
++ list_add_tail_rcu(&l->list, &laundrettes); |
709 |
++ spin_unlock(&laundrette_lock); |
710 |
++} |
711 |
++ |
712 |
++static void |
713 |
++nfsd_del_fcache_disposal(struct nfsd_fcache_disposal *l) |
714 |
++{ |
715 |
++ spin_lock(&laundrette_lock); |
716 |
++ list_del_rcu(&l->list); |
717 |
++ spin_unlock(&laundrette_lock); |
718 |
++} |
719 |
++ |
720 |
++static int |
721 |
++nfsd_alloc_fcache_disposal_net(struct net *net) |
722 |
++{ |
723 |
++ struct nfsd_fcache_disposal *l; |
724 |
++ |
725 |
++ l = nfsd_alloc_fcache_disposal(net); |
726 |
++ if (!l) |
727 |
++ return -ENOMEM; |
728 |
++ nfsd_add_fcache_disposal(l); |
729 |
++ return 0; |
730 |
++} |
731 |
++ |
732 |
++static void |
733 |
++nfsd_free_fcache_disposal_net(struct net *net) |
734 |
++{ |
735 |
++ struct nfsd_fcache_disposal *l; |
736 |
++ |
737 |
++ rcu_read_lock(); |
738 |
++ list_for_each_entry_rcu(l, &laundrettes, list) { |
739 |
++ if (l->net != net) |
740 |
++ continue; |
741 |
++ nfsd_del_fcache_disposal(l); |
742 |
++ rcu_read_unlock(); |
743 |
++ nfsd_free_fcache_disposal(l); |
744 |
++ return; |
745 |
++ } |
746 |
++ rcu_read_unlock(); |
747 |
++} |
748 |
++ |
749 |
++int |
750 |
++nfsd_file_cache_start_net(struct net *net) |
751 |
++{ |
752 |
++ return nfsd_alloc_fcache_disposal_net(net); |
753 |
++} |
754 |
++ |
755 |
++void |
756 |
++nfsd_file_cache_shutdown_net(struct net *net) |
757 |
++{ |
758 |
++ nfsd_file_cache_purge(net); |
759 |
++ nfsd_free_fcache_disposal_net(net); |
760 |
++} |
761 |
++ |
762 |
+ void |
763 |
+ nfsd_file_cache_shutdown(void) |
764 |
+ { |
765 |
+@@ -712,6 +866,8 @@ nfsd_file_cache_shutdown(void) |
766 |
+ nfsd_file_mark_slab = NULL; |
767 |
+ kfree(nfsd_file_hashtbl); |
768 |
+ nfsd_file_hashtbl = NULL; |
769 |
++ destroy_workqueue(nfsd_filecache_wq); |
770 |
++ nfsd_filecache_wq = NULL; |
771 |
+ } |
772 |
+ |
773 |
+ static bool |
774 |
+@@ -881,7 +1037,8 @@ open_file: |
775 |
+ nfsd_file_hashtbl[hashval].nfb_maxcount = max(nfsd_file_hashtbl[hashval].nfb_maxcount, |
776 |
+ nfsd_file_hashtbl[hashval].nfb_count); |
777 |
+ spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock); |
778 |
+- atomic_long_inc(&nfsd_filecache_count); |
779 |
++ if (atomic_long_inc_return(&nfsd_filecache_count) >= NFSD_FILE_LRU_THRESHOLD) |
780 |
++ nfsd_file_gc(); |
781 |
+ |
782 |
+ nf->nf_mark = nfsd_file_mark_find_or_create(nf); |
783 |
+ if (nf->nf_mark) |
784 |
+diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h |
785 |
+index 851d9abf54c25..79a7d6808d979 100644 |
786 |
+--- a/fs/nfsd/filecache.h |
787 |
++++ b/fs/nfsd/filecache.h |
788 |
+@@ -51,6 +51,8 @@ struct nfsd_file { |
789 |
+ int nfsd_file_cache_init(void); |
790 |
+ void nfsd_file_cache_purge(struct net *); |
791 |
+ void nfsd_file_cache_shutdown(void); |
792 |
++int nfsd_file_cache_start_net(struct net *net); |
793 |
++void nfsd_file_cache_shutdown_net(struct net *net); |
794 |
+ void nfsd_file_put(struct nfsd_file *nf); |
795 |
+ struct nfsd_file *nfsd_file_get(struct nfsd_file *nf); |
796 |
+ void nfsd_file_close_inode_sync(struct inode *inode); |
797 |
+diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c |
798 |
+index 155a4e43b24ee..d63cdda1782d4 100644 |
799 |
+--- a/fs/nfsd/nfssvc.c |
800 |
++++ b/fs/nfsd/nfssvc.c |
801 |
+@@ -394,13 +394,18 @@ static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cre |
802 |
+ nn->lockd_up = 1; |
803 |
+ } |
804 |
+ |
805 |
+- ret = nfs4_state_start_net(net); |
806 |
++ ret = nfsd_file_cache_start_net(net); |
807 |
+ if (ret) |
808 |
+ goto out_lockd; |
809 |
++ ret = nfs4_state_start_net(net); |
810 |
++ if (ret) |
811 |
++ goto out_filecache; |
812 |
+ |
813 |
+ nn->nfsd_net_up = true; |
814 |
+ return 0; |
815 |
+ |
816 |
++out_filecache: |
817 |
++ nfsd_file_cache_shutdown_net(net); |
818 |
+ out_lockd: |
819 |
+ if (nn->lockd_up) { |
820 |
+ lockd_down(net); |
821 |
+@@ -415,7 +420,7 @@ static void nfsd_shutdown_net(struct net *net) |
822 |
+ { |
823 |
+ struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
824 |
+ |
825 |
+- nfsd_file_cache_purge(net); |
826 |
++ nfsd_file_cache_shutdown_net(net); |
827 |
+ nfs4_state_shutdown_net(net); |
828 |
+ if (nn->lockd_up) { |
829 |
+ lockd_down(net); |
830 |
+diff --git a/include/net/esp.h b/include/net/esp.h |
831 |
+index 117652eb6ea32..465e38890ee98 100644 |
832 |
+--- a/include/net/esp.h |
833 |
++++ b/include/net/esp.h |
834 |
+@@ -4,6 +4,8 @@ |
835 |
+ |
836 |
+ #include <linux/skbuff.h> |
837 |
+ |
838 |
++#define ESP_SKB_FRAG_MAXSIZE (PAGE_SIZE << SKB_FRAG_PAGE_ORDER) |
839 |
++ |
840 |
+ struct ip_esp_hdr; |
841 |
+ |
842 |
+ static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb) |
843 |
+diff --git a/include/net/sock.h b/include/net/sock.h |
844 |
+index 079b5f6f13d81..7f213cfcb3cc6 100644 |
845 |
+--- a/include/net/sock.h |
846 |
++++ b/include/net/sock.h |
847 |
+@@ -2583,6 +2583,9 @@ extern int sysctl_optmem_max; |
848 |
+ extern __u32 sysctl_wmem_default; |
849 |
+ extern __u32 sysctl_rmem_default; |
850 |
+ |
851 |
++ |
852 |
++/* On 32bit arches, an skb frag is limited to 2^15 */ |
853 |
++#define SKB_FRAG_PAGE_ORDER get_order(32768) |
854 |
+ DECLARE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key); |
855 |
+ |
856 |
+ static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto) |
857 |
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h |
858 |
+index a71a4a272515d..2c127d438fe0a 100644 |
859 |
+--- a/kernel/rcu/tree_plugin.h |
860 |
++++ b/kernel/rcu/tree_plugin.h |
861 |
+@@ -523,16 +523,17 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags) |
862 |
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags); |
863 |
+ } |
864 |
+ |
865 |
+- /* Unboost if we were boosted. */ |
866 |
+- if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) |
867 |
+- rt_mutex_futex_unlock(&rnp->boost_mtx); |
868 |
+- |
869 |
+ /* |
870 |
+ * If this was the last task on the expedited lists, |
871 |
+ * then we need to report up the rcu_node hierarchy. |
872 |
+ */ |
873 |
+ if (!empty_exp && empty_exp_now) |
874 |
+ rcu_report_exp_rnp(rnp, true); |
875 |
++ |
876 |
++ /* Unboost if we were boosted. */ |
877 |
++ if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) |
878 |
++ rt_mutex_futex_unlock(&rnp->boost_mtx); |
879 |
++ |
880 |
+ } else { |
881 |
+ local_irq_restore(flags); |
882 |
+ } |
883 |
+diff --git a/net/core/sock.c b/net/core/sock.c |
884 |
+index 57b7a10703c36..c84f68bff7f58 100644 |
885 |
+--- a/net/core/sock.c |
886 |
++++ b/net/core/sock.c |
887 |
+@@ -2355,8 +2355,6 @@ static void sk_leave_memory_pressure(struct sock *sk) |
888 |
+ } |
889 |
+ } |
890 |
+ |
891 |
+-/* On 32bit arches, an skb frag is limited to 2^15 */ |
892 |
+-#define SKB_FRAG_PAGE_ORDER get_order(32768) |
893 |
+ DEFINE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key); |
894 |
+ |
895 |
+ /** |
896 |
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c |
897 |
+index 00210e55b4cd1..ef20f550d2f81 100644 |
898 |
+--- a/net/ipv4/esp4.c |
899 |
++++ b/net/ipv4/esp4.c |
900 |
+@@ -277,6 +277,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * |
901 |
+ struct page *page; |
902 |
+ struct sk_buff *trailer; |
903 |
+ int tailen = esp->tailen; |
904 |
++ unsigned int allocsz; |
905 |
+ |
906 |
+ /* this is non-NULL only with UDP Encapsulation */ |
907 |
+ if (x->encap) { |
908 |
+@@ -286,6 +287,10 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * |
909 |
+ return err; |
910 |
+ } |
911 |
+ |
912 |
++ allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES); |
913 |
++ if (allocsz > ESP_SKB_FRAG_MAXSIZE) |
914 |
++ goto cow; |
915 |
++ |
916 |
+ if (!skb_cloned(skb)) { |
917 |
+ if (tailen <= skb_tailroom(skb)) { |
918 |
+ nfrags = 1; |
919 |
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c |
920 |
+index 7a739f16d82b2..79f117e33b80e 100644 |
921 |
+--- a/net/ipv6/esp6.c |
922 |
++++ b/net/ipv6/esp6.c |
923 |
+@@ -230,6 +230,11 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info |
924 |
+ struct page *page; |
925 |
+ struct sk_buff *trailer; |
926 |
+ int tailen = esp->tailen; |
927 |
++ unsigned int allocsz; |
928 |
++ |
929 |
++ allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES); |
930 |
++ if (allocsz > ESP_SKB_FRAG_MAXSIZE) |
931 |
++ goto cow; |
932 |
+ |
933 |
+ if (!skb_cloned(skb)) { |
934 |
+ if (tailen <= skb_tailroom(skb)) { |
935 |
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
936 |
+index 918a9520d1f17..3606796009572 100644 |
937 |
+--- a/net/ipv6/ip6_output.c |
938 |
++++ b/net/ipv6/ip6_output.c |
939 |
+@@ -1429,8 +1429,8 @@ static int __ip6_append_data(struct sock *sk, |
940 |
+ sizeof(struct frag_hdr) : 0) + |
941 |
+ rt->rt6i_nfheader_len; |
942 |
+ |
943 |
+- if (mtu < fragheaderlen || |
944 |
+- ((mtu - fragheaderlen) & ~7) + fragheaderlen < sizeof(struct frag_hdr)) |
945 |
++ if (mtu <= fragheaderlen || |
946 |
++ ((mtu - fragheaderlen) & ~7) + fragheaderlen <= sizeof(struct frag_hdr)) |
947 |
+ goto emsgsize; |
948 |
+ |
949 |
+ maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - |
950 |
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c |
951 |
+index 0b3adf7594ffe..3b1ea89a340e3 100644 |
952 |
+--- a/net/llc/af_llc.c |
953 |
++++ b/net/llc/af_llc.c |
954 |
+@@ -276,6 +276,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
955 |
+ { |
956 |
+ struct sock *sk = sock->sk; |
957 |
+ struct llc_sock *llc = llc_sk(sk); |
958 |
++ struct net_device *dev = NULL; |
959 |
+ struct llc_sap *sap; |
960 |
+ int rc = -EINVAL; |
961 |
+ |
962 |
+@@ -287,14 +288,14 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
963 |
+ goto out; |
964 |
+ rc = -ENODEV; |
965 |
+ if (sk->sk_bound_dev_if) { |
966 |
+- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); |
967 |
+- if (llc->dev && addr->sllc_arphrd != llc->dev->type) { |
968 |
+- dev_put(llc->dev); |
969 |
+- llc->dev = NULL; |
970 |
++ dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); |
971 |
++ if (dev && addr->sllc_arphrd != dev->type) { |
972 |
++ dev_put(dev); |
973 |
++ dev = NULL; |
974 |
+ } |
975 |
+ } else |
976 |
+- llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); |
977 |
+- if (!llc->dev) |
978 |
++ dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); |
979 |
++ if (!dev) |
980 |
+ goto out; |
981 |
+ rc = -EUSERS; |
982 |
+ llc->laddr.lsap = llc_ui_autoport(); |
983 |
+@@ -304,6 +305,11 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
984 |
+ sap = llc_sap_open(llc->laddr.lsap, NULL); |
985 |
+ if (!sap) |
986 |
+ goto out; |
987 |
++ |
988 |
++ /* Note: We do not expect errors from this point. */ |
989 |
++ llc->dev = dev; |
990 |
++ dev = NULL; |
991 |
++ |
992 |
+ memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN); |
993 |
+ memcpy(&llc->addr, addr, sizeof(llc->addr)); |
994 |
+ /* assign new connection to its SAP */ |
995 |
+@@ -311,6 +317,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
996 |
+ sock_reset_flag(sk, SOCK_ZAPPED); |
997 |
+ rc = 0; |
998 |
+ out: |
999 |
++ dev_put(dev); |
1000 |
+ return rc; |
1001 |
+ } |
1002 |
+ |
1003 |
+@@ -333,6 +340,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1004 |
+ struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; |
1005 |
+ struct sock *sk = sock->sk; |
1006 |
+ struct llc_sock *llc = llc_sk(sk); |
1007 |
++ struct net_device *dev = NULL; |
1008 |
+ struct llc_sap *sap; |
1009 |
+ int rc = -EINVAL; |
1010 |
+ |
1011 |
+@@ -348,25 +356,26 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1012 |
+ rc = -ENODEV; |
1013 |
+ rcu_read_lock(); |
1014 |
+ if (sk->sk_bound_dev_if) { |
1015 |
+- llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
1016 |
+- if (llc->dev) { |
1017 |
++ dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
1018 |
++ if (dev) { |
1019 |
+ if (is_zero_ether_addr(addr->sllc_mac)) |
1020 |
+- memcpy(addr->sllc_mac, llc->dev->dev_addr, |
1021 |
++ memcpy(addr->sllc_mac, dev->dev_addr, |
1022 |
+ IFHWADDRLEN); |
1023 |
+- if (addr->sllc_arphrd != llc->dev->type || |
1024 |
++ if (addr->sllc_arphrd != dev->type || |
1025 |
+ !ether_addr_equal(addr->sllc_mac, |
1026 |
+- llc->dev->dev_addr)) { |
1027 |
++ dev->dev_addr)) { |
1028 |
+ rc = -EINVAL; |
1029 |
+- llc->dev = NULL; |
1030 |
++ dev = NULL; |
1031 |
+ } |
1032 |
+ } |
1033 |
+- } else |
1034 |
+- llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, |
1035 |
++ } else { |
1036 |
++ dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, |
1037 |
+ addr->sllc_mac); |
1038 |
+- if (llc->dev) |
1039 |
+- dev_hold(llc->dev); |
1040 |
++ } |
1041 |
++ if (dev) |
1042 |
++ dev_hold(dev); |
1043 |
+ rcu_read_unlock(); |
1044 |
+- if (!llc->dev) |
1045 |
++ if (!dev) |
1046 |
+ goto out; |
1047 |
+ if (!addr->sllc_sap) { |
1048 |
+ rc = -EUSERS; |
1049 |
+@@ -399,6 +408,11 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1050 |
+ goto out_put; |
1051 |
+ } |
1052 |
+ } |
1053 |
++ |
1054 |
++ /* Note: We do not expect errors from this point. */ |
1055 |
++ llc->dev = dev; |
1056 |
++ dev = NULL; |
1057 |
++ |
1058 |
+ llc->laddr.lsap = addr->sllc_sap; |
1059 |
+ memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN); |
1060 |
+ memcpy(&llc->addr, addr, sizeof(llc->addr)); |
1061 |
+@@ -409,6 +423,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) |
1062 |
+ out_put: |
1063 |
+ llc_sap_put(sap); |
1064 |
+ out: |
1065 |
++ dev_put(dev); |
1066 |
+ release_sock(sk); |
1067 |
+ return rc; |
1068 |
+ } |
1069 |
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c |
1070 |
+index 1b50bbf030ed8..16f37fd0ac0e5 100644 |
1071 |
+--- a/net/mac80211/cfg.c |
1072 |
++++ b/net/mac80211/cfg.c |
1073 |
+@@ -1949,13 +1949,11 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, |
1074 |
+ const struct mesh_setup *setup) |
1075 |
+ { |
1076 |
+ u8 *new_ie; |
1077 |
+- const u8 *old_ie; |
1078 |
+ struct ieee80211_sub_if_data *sdata = container_of(ifmsh, |
1079 |
+ struct ieee80211_sub_if_data, u.mesh); |
1080 |
+ |
1081 |
+ /* allocate information elements */ |
1082 |
+ new_ie = NULL; |
1083 |
+- old_ie = ifmsh->ie; |
1084 |
+ |
1085 |
+ if (setup->ie_len) { |
1086 |
+ new_ie = kmemdup(setup->ie, setup->ie_len, |
1087 |
+@@ -1965,7 +1963,6 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, |
1088 |
+ } |
1089 |
+ ifmsh->ie_len = setup->ie_len; |
1090 |
+ ifmsh->ie = new_ie; |
1091 |
+- kfree(old_ie); |
1092 |
+ |
1093 |
+ /* now copy the rest of the setup parameters */ |
1094 |
+ ifmsh->mesh_id_len = setup->mesh_id_len; |
1095 |
+diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c |
1096 |
+index 96c74c4c71762..ceb0ef437e23e 100644 |
1097 |
+--- a/net/netfilter/nf_tables_core.c |
1098 |
++++ b/net/netfilter/nf_tables_core.c |
1099 |
+@@ -153,7 +153,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) |
1100 |
+ struct nft_rule *const *rules; |
1101 |
+ const struct nft_rule *rule; |
1102 |
+ const struct nft_expr *expr, *last; |
1103 |
+- struct nft_regs regs; |
1104 |
++ struct nft_regs regs = {}; |
1105 |
+ unsigned int stackptr = 0; |
1106 |
+ struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; |
1107 |
+ bool genbit = READ_ONCE(net->nft.gencursor); |
1108 |
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c |
1109 |
+index 841c0a12cc929..ad4e0af2d0d03 100644 |
1110 |
+--- a/sound/core/oss/pcm_oss.c |
1111 |
++++ b/sound/core/oss/pcm_oss.c |
1112 |
+@@ -774,6 +774,11 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, |
1113 |
+ |
1114 |
+ if (oss_period_size < 16) |
1115 |
+ return -EINVAL; |
1116 |
++ |
1117 |
++ /* don't allocate too large period; 1MB period must be enough */ |
1118 |
++ if (oss_period_size > 1024 * 1024) |
1119 |
++ return -ENOMEM; |
1120 |
++ |
1121 |
+ runtime->oss.period_bytes = oss_period_size; |
1122 |
+ runtime->oss.period_frames = 1; |
1123 |
+ runtime->oss.periods = oss_periods; |
1124 |
+@@ -1045,10 +1050,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) |
1125 |
+ goto failure; |
1126 |
+ } |
1127 |
+ #endif |
1128 |
+- oss_period_size *= oss_frame_size; |
1129 |
+- |
1130 |
+- oss_buffer_size = oss_period_size * runtime->oss.periods; |
1131 |
+- if (oss_buffer_size < 0) { |
1132 |
++ oss_period_size = array_size(oss_period_size, oss_frame_size); |
1133 |
++ oss_buffer_size = array_size(oss_period_size, runtime->oss.periods); |
1134 |
++ if (oss_buffer_size <= 0) { |
1135 |
+ err = -EINVAL; |
1136 |
+ goto failure; |
1137 |
+ } |
1138 |
+diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c |
1139 |
+index da400da1fafe6..8b7bbabeea24b 100644 |
1140 |
+--- a/sound/core/oss/pcm_plugin.c |
1141 |
++++ b/sound/core/oss/pcm_plugin.c |
1142 |
+@@ -61,7 +61,10 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t |
1143 |
+ } |
1144 |
+ if ((width = snd_pcm_format_physical_width(format->format)) < 0) |
1145 |
+ return width; |
1146 |
+- size = frames * format->channels * width; |
1147 |
++ size = array3_size(frames, format->channels, width); |
1148 |
++ /* check for too large period size once again */ |
1149 |
++ if (size > 1024 * 1024) |
1150 |
++ return -ENOMEM; |
1151 |
+ if (snd_BUG_ON(size % 8)) |
1152 |
+ return -ENXIO; |
1153 |
+ size /= 8; |
1154 |
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c |
1155 |
+index 0c5b7a54ca81c..dbe9a65cc1d45 100644 |
1156 |
+--- a/sound/core/pcm_native.c |
1157 |
++++ b/sound/core/pcm_native.c |
1158 |
+@@ -1656,21 +1656,25 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) |
1159 |
+ int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); |
1160 |
+ if (err < 0) |
1161 |
+ return err; |
1162 |
++ snd_pcm_stream_lock_irq(substream); |
1163 |
+ runtime->hw_ptr_base = 0; |
1164 |
+ runtime->hw_ptr_interrupt = runtime->status->hw_ptr - |
1165 |
+ runtime->status->hw_ptr % runtime->period_size; |
1166 |
+ runtime->silence_start = runtime->status->hw_ptr; |
1167 |
+ runtime->silence_filled = 0; |
1168 |
++ snd_pcm_stream_unlock_irq(substream); |
1169 |
+ return 0; |
1170 |
+ } |
1171 |
+ |
1172 |
+ static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state) |
1173 |
+ { |
1174 |
+ struct snd_pcm_runtime *runtime = substream->runtime; |
1175 |
++ snd_pcm_stream_lock_irq(substream); |
1176 |
+ runtime->control->appl_ptr = runtime->status->hw_ptr; |
1177 |
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
1178 |
+ runtime->silence_size > 0) |
1179 |
+ snd_pcm_playback_silence(substream, ULONG_MAX); |
1180 |
++ snd_pcm_stream_unlock_irq(substream); |
1181 |
+ } |
1182 |
+ |
1183 |
+ static const struct action_ops snd_pcm_action_reset = { |
1184 |
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c |
1185 |
+index 66f6c3bf08e31..6fb192a94762f 100644 |
1186 |
+--- a/sound/pci/ac97/ac97_codec.c |
1187 |
++++ b/sound/pci/ac97/ac97_codec.c |
1188 |
+@@ -938,8 +938,8 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct |
1189 |
+ int codec = kcontrol->private_value & 3; |
1190 |
+ |
1191 |
+ mutex_lock(&ac97->page_mutex); |
1192 |
+- ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); |
1193 |
+- ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); |
1194 |
++ ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); |
1195 |
++ ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); |
1196 |
+ mutex_unlock(&ac97->page_mutex); |
1197 |
+ return 0; |
1198 |
+ } |
1199 |
+diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c |
1200 |
+index df720881eb991..db9d89ba36587 100644 |
1201 |
+--- a/sound/pci/cmipci.c |
1202 |
++++ b/sound/pci/cmipci.c |
1203 |
+@@ -302,7 +302,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); |
1204 |
+ #define CM_MICGAINZ 0x01 /* mic boost */ |
1205 |
+ #define CM_MICGAINZ_SHIFT 0 |
1206 |
+ |
1207 |
+-#define CM_REG_MIXER3 0x24 |
1208 |
+ #define CM_REG_AUX_VOL 0x26 |
1209 |
+ #define CM_VAUXL_MASK 0xf0 |
1210 |
+ #define CM_VAUXR_MASK 0x0f |
1211 |
+@@ -3310,7 +3309,7 @@ static void snd_cmipci_remove(struct pci_dev *pci) |
1212 |
+ */ |
1213 |
+ static unsigned char saved_regs[] = { |
1214 |
+ CM_REG_FUNCTRL1, CM_REG_CHFORMAT, CM_REG_LEGACY_CTRL, CM_REG_MISC_CTRL, |
1215 |
+- CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_MIXER3, CM_REG_PLL, |
1216 |
++ CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_AUX_VOL, CM_REG_PLL, |
1217 |
+ CM_REG_CH0_FRAME1, CM_REG_CH0_FRAME2, |
1218 |
+ CM_REG_CH1_FRAME1, CM_REG_CH1_FRAME2, CM_REG_EXT_MISC, |
1219 |
+ CM_REG_INT_STATUS, CM_REG_INT_HLDCLR, CM_REG_FUNCTRL0, |
1220 |
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
1221 |
+index c03448ea8a203..d201043d661c1 100644 |
1222 |
+--- a/sound/pci/hda/patch_realtek.c |
1223 |
++++ b/sound/pci/hda/patch_realtek.c |
1224 |
+@@ -8183,6 +8183,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
1225 |
+ SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), |
1226 |
+ SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), |
1227 |
+ SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), |
1228 |
++ SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), |
1229 |
+ SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), |
1230 |
+ SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), |
1231 |
+ SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
1232 |
+@@ -10201,6 +10202,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
1233 |
+ SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
1234 |
+ SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
1235 |
+ SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2), |
1236 |
++ SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2), |
1237 |
+ SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE), |
1238 |
+ SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50), |
1239 |
+ SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50), |
1240 |
+diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c |
1241 |
+index 2ed92c990b97c..dd9013c476649 100644 |
1242 |
+--- a/sound/soc/sti/uniperif_player.c |
1243 |
++++ b/sound/soc/sti/uniperif_player.c |
1244 |
+@@ -91,7 +91,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) |
1245 |
+ SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player); |
1246 |
+ |
1247 |
+ /* Stop the player */ |
1248 |
+- snd_pcm_stop_xrun(player->substream); |
1249 |
++ snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); |
1250 |
+ } |
1251 |
+ |
1252 |
+ ret = IRQ_HANDLED; |
1253 |
+@@ -105,7 +105,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) |
1254 |
+ SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player); |
1255 |
+ |
1256 |
+ /* Stop the player */ |
1257 |
+- snd_pcm_stop_xrun(player->substream); |
1258 |
++ snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); |
1259 |
+ |
1260 |
+ ret = IRQ_HANDLED; |
1261 |
+ } |
1262 |
+@@ -138,7 +138,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) |
1263 |
+ dev_err(player->dev, "Underflow recovery failed\n"); |
1264 |
+ |
1265 |
+ /* Stop the player */ |
1266 |
+- snd_pcm_stop_xrun(player->substream); |
1267 |
++ snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); |
1268 |
+ |
1269 |
+ ret = IRQ_HANDLED; |
1270 |
+ } |
1271 |
+diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c |
1272 |
+index 136059331211d..065c5f0d1f5f0 100644 |
1273 |
+--- a/sound/soc/sti/uniperif_reader.c |
1274 |
++++ b/sound/soc/sti/uniperif_reader.c |
1275 |
+@@ -65,7 +65,7 @@ static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id) |
1276 |
+ if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) { |
1277 |
+ dev_err(reader->dev, "FIFO error detected\n"); |
1278 |
+ |
1279 |
+- snd_pcm_stop_xrun(reader->substream); |
1280 |
++ snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN); |
1281 |
+ |
1282 |
+ ret = IRQ_HANDLED; |
1283 |
+ } |
1284 |
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c |
1285 |
+index d926869c031b1..1f7c80541d03b 100644 |
1286 |
+--- a/sound/usb/mixer_quirks.c |
1287 |
++++ b/sound/usb/mixer_quirks.c |
1288 |
+@@ -2370,9 +2370,10 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, |
1289 |
+ if (unitid == 7 && cval->control == UAC_FU_VOLUME) |
1290 |
+ snd_dragonfly_quirk_db_scale(mixer, cval, kctl); |
1291 |
+ break; |
1292 |
+- /* lowest playback value is muted on C-Media devices */ |
1293 |
+- case USB_ID(0x0d8c, 0x000c): |
1294 |
+- case USB_ID(0x0d8c, 0x0014): |
1295 |
++ /* lowest playback value is muted on some devices */ |
1296 |
++ case USB_ID(0x0d8c, 0x000c): /* C-Media */ |
1297 |
++ case USB_ID(0x0d8c, 0x0014): /* C-Media */ |
1298 |
++ case USB_ID(0x19f7, 0x0003): /* RODE NT-USB */ |
1299 |
+ if (strstr(kctl->id.name, "Playback")) |
1300 |
+ cval->min_mute = 1; |
1301 |
+ break; |