1 |
commit: 524ee762db47f717daad569c3dc7a9bf00eb91aa |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Dec 2 12:17:36 2020 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Dec 2 12:17:36 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=524ee762 |
7 |
|
8 |
Linux patch 4.4.247 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1246_linux-4.4.247.patch | 814 +++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 818 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 4d2691c..87e6840 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -1027,6 +1027,10 @@ Patch: 1245_linux-4.4.246.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 4.4.246 |
23 |
|
24 |
+Patch: 1246_linux-4.4.247.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 4.4.247 |
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/1246_linux-4.4.247.patch b/1246_linux-4.4.247.patch |
33 |
new file mode 100644 |
34 |
index 0000000..75ce3fb |
35 |
--- /dev/null |
36 |
+++ b/1246_linux-4.4.247.patch |
37 |
@@ -0,0 +1,814 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index c42ada4e88466..c493d3ae046f6 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,6 +1,6 @@ |
43 |
+ VERSION = 4 |
44 |
+ PATCHLEVEL = 4 |
45 |
+-SUBLEVEL = 246 |
46 |
++SUBLEVEL = 247 |
47 |
+ EXTRAVERSION = |
48 |
+ NAME = Blurry Fish Butt |
49 |
+ |
50 |
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c |
51 |
+index 2c9a2992863b0..ffc3bc8111b80 100644 |
52 |
+--- a/arch/x86/kernel/cpu/bugs.c |
53 |
++++ b/arch/x86/kernel/cpu/bugs.c |
54 |
+@@ -707,11 +707,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) |
55 |
+ if (boot_cpu_has(X86_FEATURE_IBPB)) { |
56 |
+ setup_force_cpu_cap(X86_FEATURE_USE_IBPB); |
57 |
+ |
58 |
++ spectre_v2_user_ibpb = mode; |
59 |
+ switch (cmd) { |
60 |
+ case SPECTRE_V2_USER_CMD_FORCE: |
61 |
+ case SPECTRE_V2_USER_CMD_PRCTL_IBPB: |
62 |
+ case SPECTRE_V2_USER_CMD_SECCOMP_IBPB: |
63 |
+ static_branch_enable(&switch_mm_always_ibpb); |
64 |
++ spectre_v2_user_ibpb = SPECTRE_V2_USER_STRICT; |
65 |
+ break; |
66 |
+ case SPECTRE_V2_USER_CMD_PRCTL: |
67 |
+ case SPECTRE_V2_USER_CMD_AUTO: |
68 |
+@@ -725,8 +727,6 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) |
69 |
+ pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n", |
70 |
+ static_key_enabled(&switch_mm_always_ibpb) ? |
71 |
+ "always-on" : "conditional"); |
72 |
+- |
73 |
+- spectre_v2_user_ibpb = mode; |
74 |
+ } |
75 |
+ |
76 |
+ /* |
77 |
+diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c |
78 |
+index 85872a08994a1..e9fc0f7df0da8 100644 |
79 |
+--- a/arch/x86/xen/spinlock.c |
80 |
++++ b/arch/x86/xen/spinlock.c |
81 |
+@@ -301,10 +301,20 @@ void xen_init_lock_cpu(int cpu) |
82 |
+ |
83 |
+ void xen_uninit_lock_cpu(int cpu) |
84 |
+ { |
85 |
++ int irq; |
86 |
++ |
87 |
+ if (!xen_pvspin) |
88 |
+ return; |
89 |
+ |
90 |
+- unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); |
91 |
++ /* |
92 |
++ * When booting the kernel with 'mitigations=auto,nosmt', the secondary |
93 |
++ * CPUs are not activated, and lock_kicker_irq is not initialized. |
94 |
++ */ |
95 |
++ irq = per_cpu(lock_kicker_irq, cpu); |
96 |
++ if (irq == -1) |
97 |
++ return; |
98 |
++ |
99 |
++ unbind_from_irqhandler(irq, NULL); |
100 |
+ per_cpu(lock_kicker_irq, cpu) = -1; |
101 |
+ kfree(per_cpu(irq_name, cpu)); |
102 |
+ per_cpu(irq_name, cpu) = NULL; |
103 |
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c |
104 |
+index 9aa57b37381a9..7f66ae1945b24 100644 |
105 |
+--- a/drivers/dma/pl330.c |
106 |
++++ b/drivers/dma/pl330.c |
107 |
+@@ -2634,7 +2634,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, |
108 |
+ * If burst size is smaller than bus width then make sure we only |
109 |
+ * transfer one at a time to avoid a burst stradling an MFIFO entry. |
110 |
+ */ |
111 |
+- if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width) |
112 |
++ if (burst * 8 < pl330->pcfg.data_bus_width) |
113 |
+ desc->rqcfg.brst_len = 1; |
114 |
+ |
115 |
+ desc->bytes_requested = len; |
116 |
+diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c |
117 |
+index 1689568b597d4..12c5d7c96527a 100644 |
118 |
+--- a/drivers/hid/hid-cypress.c |
119 |
++++ b/drivers/hid/hid-cypress.c |
120 |
+@@ -26,19 +26,17 @@ |
121 |
+ #define CP_2WHEEL_MOUSE_HACK 0x02 |
122 |
+ #define CP_2WHEEL_MOUSE_HACK_ON 0x04 |
123 |
+ |
124 |
++#define VA_INVAL_LOGICAL_BOUNDARY 0x08 |
125 |
++ |
126 |
+ /* |
127 |
+ * Some USB barcode readers from cypress have usage min and usage max in |
128 |
+ * the wrong order |
129 |
+ */ |
130 |
+-static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
131 |
++static __u8 *cp_rdesc_fixup(struct hid_device *hdev, __u8 *rdesc, |
132 |
+ unsigned int *rsize) |
133 |
+ { |
134 |
+- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
135 |
+ unsigned int i; |
136 |
+ |
137 |
+- if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) |
138 |
+- return rdesc; |
139 |
+- |
140 |
+ if (*rsize < 4) |
141 |
+ return rdesc; |
142 |
+ |
143 |
+@@ -51,6 +49,40 @@ static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
144 |
+ return rdesc; |
145 |
+ } |
146 |
+ |
147 |
++static __u8 *va_logical_boundary_fixup(struct hid_device *hdev, __u8 *rdesc, |
148 |
++ unsigned int *rsize) |
149 |
++{ |
150 |
++ /* |
151 |
++ * Varmilo VA104M (with VID Cypress and device ID 07B1) incorrectly |
152 |
++ * reports Logical Minimum of its Consumer Control device as 572 |
153 |
++ * (0x02 0x3c). Fix this by setting its Logical Minimum to zero. |
154 |
++ */ |
155 |
++ if (*rsize == 25 && |
156 |
++ rdesc[0] == 0x05 && rdesc[1] == 0x0c && |
157 |
++ rdesc[2] == 0x09 && rdesc[3] == 0x01 && |
158 |
++ rdesc[6] == 0x19 && rdesc[7] == 0x00 && |
159 |
++ rdesc[11] == 0x16 && rdesc[12] == 0x3c && rdesc[13] == 0x02) { |
160 |
++ hid_info(hdev, |
161 |
++ "fixing up varmilo VA104M consumer control report descriptor\n"); |
162 |
++ rdesc[12] = 0x00; |
163 |
++ rdesc[13] = 0x00; |
164 |
++ } |
165 |
++ return rdesc; |
166 |
++} |
167 |
++ |
168 |
++static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
169 |
++ unsigned int *rsize) |
170 |
++{ |
171 |
++ unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
172 |
++ |
173 |
++ if (quirks & CP_RDESC_SWAPPED_MIN_MAX) |
174 |
++ rdesc = cp_rdesc_fixup(hdev, rdesc, rsize); |
175 |
++ if (quirks & VA_INVAL_LOGICAL_BOUNDARY) |
176 |
++ rdesc = va_logical_boundary_fixup(hdev, rdesc, rsize); |
177 |
++ |
178 |
++ return rdesc; |
179 |
++} |
180 |
++ |
181 |
+ static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
182 |
+ struct hid_field *field, struct hid_usage *usage, |
183 |
+ unsigned long **bit, int *max) |
184 |
+@@ -131,6 +163,8 @@ static const struct hid_device_id cp_devices[] = { |
185 |
+ .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, |
186 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), |
187 |
+ .driver_data = CP_2WHEEL_MOUSE_HACK }, |
188 |
++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1), |
189 |
++ .driver_data = VA_INVAL_LOGICAL_BOUNDARY }, |
190 |
+ { } |
191 |
+ }; |
192 |
+ MODULE_DEVICE_TABLE(hid, cp_devices); |
193 |
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h |
194 |
+index 33d2b5948d7fc..773452c6edfab 100644 |
195 |
+--- a/drivers/hid/hid-ids.h |
196 |
++++ b/drivers/hid/hid-ids.h |
197 |
+@@ -279,6 +279,8 @@ |
198 |
+ #define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 |
199 |
+ #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 |
200 |
+ |
201 |
++#define USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1 0X07b1 |
202 |
++ |
203 |
+ #define USB_VENDOR_ID_DATA_MODUL 0x7374 |
204 |
+ #define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201 |
205 |
+ |
206 |
+diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c |
207 |
+index 8efaa88329aa3..83e45d5801a98 100644 |
208 |
+--- a/drivers/hid/hid-sensor-hub.c |
209 |
++++ b/drivers/hid/hid-sensor-hub.c |
210 |
+@@ -473,7 +473,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev, |
211 |
+ return 1; |
212 |
+ |
213 |
+ ptr = raw_data; |
214 |
+- ptr++; /* Skip report id */ |
215 |
++ if (report->id) |
216 |
++ ptr++; /* Skip report id */ |
217 |
+ |
218 |
+ spin_lock_irqsave(&pdata->lock, flags); |
219 |
+ |
220 |
+diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c |
221 |
+index 40ba833381557..59e1f6ea2ede9 100644 |
222 |
+--- a/drivers/infiniband/hw/mthca/mthca_cq.c |
223 |
++++ b/drivers/infiniband/hw/mthca/mthca_cq.c |
224 |
+@@ -811,8 +811,10 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, |
225 |
+ } |
226 |
+ |
227 |
+ mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
228 |
+- if (IS_ERR(mailbox)) |
229 |
++ if (IS_ERR(mailbox)) { |
230 |
++ err = PTR_ERR(mailbox); |
231 |
+ goto err_out_arm; |
232 |
++ } |
233 |
+ |
234 |
+ cq_context = mailbox->buf; |
235 |
+ |
236 |
+@@ -854,9 +856,9 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, |
237 |
+ } |
238 |
+ |
239 |
+ spin_lock_irq(&dev->cq_table.lock); |
240 |
+- if (mthca_array_set(&dev->cq_table.cq, |
241 |
+- cq->cqn & (dev->limits.num_cqs - 1), |
242 |
+- cq)) { |
243 |
++ err = mthca_array_set(&dev->cq_table.cq, |
244 |
++ cq->cqn & (dev->limits.num_cqs - 1), cq); |
245 |
++ if (err) { |
246 |
+ spin_unlock_irq(&dev->cq_table.lock); |
247 |
+ goto err_out_free_mr; |
248 |
+ } |
249 |
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c |
250 |
+index c84c685056b99..6b648339733fa 100644 |
251 |
+--- a/drivers/input/serio/i8042.c |
252 |
++++ b/drivers/input/serio/i8042.c |
253 |
+@@ -125,6 +125,7 @@ module_param_named(unmask_kbd_data, i8042_unmask_kbd_data, bool, 0600); |
254 |
+ MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive data) of normally sanitize-filtered kbd data traffic debug log [pre-condition: i8042.debug=1 enabled]"); |
255 |
+ #endif |
256 |
+ |
257 |
++static bool i8042_present; |
258 |
+ static bool i8042_bypass_aux_irq_test; |
259 |
+ static char i8042_kbd_firmware_id[128]; |
260 |
+ static char i8042_aux_firmware_id[128]; |
261 |
+@@ -343,6 +344,9 @@ int i8042_command(unsigned char *param, int command) |
262 |
+ unsigned long flags; |
263 |
+ int retval; |
264 |
+ |
265 |
++ if (!i8042_present) |
266 |
++ return -1; |
267 |
++ |
268 |
+ spin_lock_irqsave(&i8042_lock, flags); |
269 |
+ retval = __i8042_command(param, command); |
270 |
+ spin_unlock_irqrestore(&i8042_lock, flags); |
271 |
+@@ -1597,12 +1601,15 @@ static int __init i8042_init(void) |
272 |
+ |
273 |
+ err = i8042_platform_init(); |
274 |
+ if (err) |
275 |
+- return err; |
276 |
++ return (err == -ENODEV) ? 0 : err; |
277 |
+ |
278 |
+ err = i8042_controller_check(); |
279 |
+ if (err) |
280 |
+ goto err_platform_exit; |
281 |
+ |
282 |
++ /* Set this before creating the dev to allow i8042_command to work right away */ |
283 |
++ i8042_present = true; |
284 |
++ |
285 |
+ pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); |
286 |
+ if (IS_ERR(pdev)) { |
287 |
+ err = PTR_ERR(pdev); |
288 |
+@@ -1621,6 +1628,9 @@ static int __init i8042_init(void) |
289 |
+ |
290 |
+ static void __exit i8042_exit(void) |
291 |
+ { |
292 |
++ if (!i8042_present) |
293 |
++ return; |
294 |
++ |
295 |
+ platform_device_unregister(i8042_platform_device); |
296 |
+ platform_driver_unregister(&i8042_driver); |
297 |
+ i8042_platform_exit(); |
298 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
299 |
+index 2da1c22946450..250ecbcca019f 100644 |
300 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
301 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
302 |
+@@ -5198,7 +5198,8 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) |
303 |
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) != 0 && |
304 |
+ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) { |
305 |
+ dev_err(&pdev->dev, "System does not support DMA, aborting\n"); |
306 |
+- goto init_err_disable; |
307 |
++ rc = -EIO; |
308 |
++ goto init_err_release; |
309 |
+ } |
310 |
+ |
311 |
+ pci_set_master(pdev); |
312 |
+diff --git a/drivers/nfc/s3fwrn5/i2c.c b/drivers/nfc/s3fwrn5/i2c.c |
313 |
+index c61d8a308da45..779f7a76ecd3d 100644 |
314 |
+--- a/drivers/nfc/s3fwrn5/i2c.c |
315 |
++++ b/drivers/nfc/s3fwrn5/i2c.c |
316 |
+@@ -37,8 +37,8 @@ struct s3fwrn5_i2c_phy { |
317 |
+ struct i2c_client *i2c_dev; |
318 |
+ struct nci_dev *ndev; |
319 |
+ |
320 |
+- unsigned int gpio_en; |
321 |
+- unsigned int gpio_fw_wake; |
322 |
++ int gpio_en; |
323 |
++ int gpio_fw_wake; |
324 |
+ |
325 |
+ struct mutex mutex; |
326 |
+ |
327 |
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c |
328 |
+index b4fbcf4cade8f..36e415487fe53 100644 |
329 |
+--- a/drivers/scsi/libiscsi.c |
330 |
++++ b/drivers/scsi/libiscsi.c |
331 |
+@@ -570,8 +570,8 @@ static void iscsi_complete_task(struct iscsi_task *task, int state) |
332 |
+ if (conn->task == task) |
333 |
+ conn->task = NULL; |
334 |
+ |
335 |
+- if (conn->ping_task == task) |
336 |
+- conn->ping_task = NULL; |
337 |
++ if (READ_ONCE(conn->ping_task) == task) |
338 |
++ WRITE_ONCE(conn->ping_task, NULL); |
339 |
+ |
340 |
+ /* release get from queueing */ |
341 |
+ __iscsi_put_task(task); |
342 |
+@@ -780,6 +780,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, |
343 |
+ task->conn->session->age); |
344 |
+ } |
345 |
+ |
346 |
++ if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK)) |
347 |
++ WRITE_ONCE(conn->ping_task, task); |
348 |
++ |
349 |
+ if (!ihost->workq) { |
350 |
+ if (iscsi_prep_mgmt_task(conn, task)) |
351 |
+ goto free_task; |
352 |
+@@ -987,8 +990,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) |
353 |
+ struct iscsi_nopout hdr; |
354 |
+ struct iscsi_task *task; |
355 |
+ |
356 |
+- if (!rhdr && conn->ping_task) |
357 |
+- return -EINVAL; |
358 |
++ if (!rhdr) { |
359 |
++ if (READ_ONCE(conn->ping_task)) |
360 |
++ return -EINVAL; |
361 |
++ WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK); |
362 |
++ } |
363 |
+ |
364 |
+ memset(&hdr, 0, sizeof(struct iscsi_nopout)); |
365 |
+ hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE; |
366 |
+@@ -1003,11 +1009,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) |
367 |
+ |
368 |
+ task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); |
369 |
+ if (!task) { |
370 |
++ if (!rhdr) |
371 |
++ WRITE_ONCE(conn->ping_task, NULL); |
372 |
+ iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); |
373 |
+ return -EIO; |
374 |
+ } else if (!rhdr) { |
375 |
+ /* only track our nops */ |
376 |
+- conn->ping_task = task; |
377 |
+ conn->last_ping = jiffies; |
378 |
+ } |
379 |
+ |
380 |
+@@ -1020,7 +1027,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task, |
381 |
+ struct iscsi_conn *conn = task->conn; |
382 |
+ int rc = 0; |
383 |
+ |
384 |
+- if (conn->ping_task != task) { |
385 |
++ if (READ_ONCE(conn->ping_task) != task) { |
386 |
+ /* |
387 |
+ * If this is not in response to one of our |
388 |
+ * nops then it must be from userspace. |
389 |
+@@ -1960,7 +1967,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn) |
390 |
+ */ |
391 |
+ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) |
392 |
+ { |
393 |
+- if (conn->ping_task && |
394 |
++ if (READ_ONCE(conn->ping_task) && |
395 |
+ time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + |
396 |
+ (conn->ping_timeout * HZ), jiffies)) |
397 |
+ return 1; |
398 |
+@@ -2095,7 +2102,7 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) |
399 |
+ * Checking the transport already or nop from a cmd timeout still |
400 |
+ * running |
401 |
+ */ |
402 |
+- if (conn->ping_task) { |
403 |
++ if (READ_ONCE(conn->ping_task)) { |
404 |
+ task->have_checked_conn = true; |
405 |
+ rc = BLK_EH_RESET_TIMER; |
406 |
+ goto done; |
407 |
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c |
408 |
+index d7a0a64f64536..e37f6db0dd156 100644 |
409 |
+--- a/drivers/scsi/ufs/ufshcd.c |
410 |
++++ b/drivers/scsi/ufs/ufshcd.c |
411 |
+@@ -5387,11 +5387,7 @@ int ufshcd_shutdown(struct ufs_hba *hba) |
412 |
+ if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba)) |
413 |
+ goto out; |
414 |
+ |
415 |
+- if (pm_runtime_suspended(hba->dev)) { |
416 |
+- ret = ufshcd_runtime_resume(hba); |
417 |
+- if (ret) |
418 |
+- goto out; |
419 |
+- } |
420 |
++ pm_runtime_get_sync(hba->dev); |
421 |
+ |
422 |
+ ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM); |
423 |
+ out: |
424 |
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c |
425 |
+index cbb4414edd71b..c48aca1360c89 100644 |
426 |
+--- a/drivers/target/iscsi/iscsi_target.c |
427 |
++++ b/drivers/target/iscsi/iscsi_target.c |
428 |
+@@ -493,8 +493,7 @@ static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) |
429 |
+ bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD); |
430 |
+ |
431 |
+ spin_lock_bh(&conn->cmd_lock); |
432 |
+- if (!list_empty(&cmd->i_conn_node) && |
433 |
+- !(cmd->se_cmd.transport_state & CMD_T_FABRIC_STOP)) |
434 |
++ if (!list_empty(&cmd->i_conn_node)) |
435 |
+ list_del_init(&cmd->i_conn_node); |
436 |
+ spin_unlock_bh(&conn->cmd_lock); |
437 |
+ |
438 |
+@@ -4228,12 +4227,22 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) |
439 |
+ spin_lock_bh(&conn->cmd_lock); |
440 |
+ list_splice_init(&conn->conn_cmd_list, &tmp_list); |
441 |
+ |
442 |
+- list_for_each_entry(cmd, &tmp_list, i_conn_node) { |
443 |
++ list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) { |
444 |
+ struct se_cmd *se_cmd = &cmd->se_cmd; |
445 |
+ |
446 |
+ if (se_cmd->se_tfo != NULL) { |
447 |
+ spin_lock_irq(&se_cmd->t_state_lock); |
448 |
+- se_cmd->transport_state |= CMD_T_FABRIC_STOP; |
449 |
++ if (se_cmd->transport_state & CMD_T_ABORTED) { |
450 |
++ /* |
451 |
++ * LIO's abort path owns the cleanup for this, |
452 |
++ * so put it back on the list and let |
453 |
++ * aborted_task handle it. |
454 |
++ */ |
455 |
++ list_move_tail(&cmd->i_conn_node, |
456 |
++ &conn->conn_cmd_list); |
457 |
++ } else { |
458 |
++ se_cmd->transport_state |= CMD_T_FABRIC_STOP; |
459 |
++ } |
460 |
+ spin_unlock_irq(&se_cmd->t_state_lock); |
461 |
+ } |
462 |
+ } |
463 |
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c |
464 |
+index 570a76d912503..eca8d04cfb3ec 100644 |
465 |
+--- a/drivers/usb/core/config.c |
466 |
++++ b/drivers/usb/core/config.c |
467 |
+@@ -222,6 +222,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, |
468 |
+ struct usb_host_interface *ifp, int num_ep, |
469 |
+ unsigned char *buffer, int size) |
470 |
+ { |
471 |
++ struct usb_device *udev = to_usb_device(ddev); |
472 |
+ unsigned char *buffer0 = buffer; |
473 |
+ struct usb_endpoint_descriptor *d; |
474 |
+ struct usb_host_endpoint *endpoint; |
475 |
+@@ -263,6 +264,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, |
476 |
+ goto skip_to_next_endpoint_or_interface_descriptor; |
477 |
+ } |
478 |
+ |
479 |
++ /* Ignore blacklisted endpoints */ |
480 |
++ if (udev->quirks & USB_QUIRK_ENDPOINT_BLACKLIST) { |
481 |
++ if (usb_endpoint_is_blacklisted(udev, ifp, d)) { |
482 |
++ dev_warn(ddev, "config %d interface %d altsetting %d has a blacklisted endpoint with address 0x%X, skipping\n", |
483 |
++ cfgno, inum, asnum, |
484 |
++ d->bEndpointAddress); |
485 |
++ goto skip_to_next_endpoint_or_interface_descriptor; |
486 |
++ } |
487 |
++ } |
488 |
++ |
489 |
+ endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; |
490 |
+ ++ifp->desc.bNumEndpoints; |
491 |
+ |
492 |
+diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c |
493 |
+index 7559d96695da6..4c1679cc57425 100644 |
494 |
+--- a/drivers/usb/core/devio.c |
495 |
++++ b/drivers/usb/core/devio.c |
496 |
+@@ -369,11 +369,11 @@ static void snoop_urb(struct usb_device *udev, |
497 |
+ |
498 |
+ if (userurb) { /* Async */ |
499 |
+ if (when == SUBMIT) |
500 |
+- dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, " |
501 |
++ dev_info(&udev->dev, "userurb %px, ep%d %s-%s, " |
502 |
+ "length %u\n", |
503 |
+ userurb, ep, t, d, length); |
504 |
+ else |
505 |
+- dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, " |
506 |
++ dev_info(&udev->dev, "userurb %px, ep%d %s-%s, " |
507 |
+ "actual_length %u status %d\n", |
508 |
+ userurb, ep, t, d, length, |
509 |
+ timeout_or_status); |
510 |
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c |
511 |
+index ca74b67c4450d..34d8cece6dd3b 100644 |
512 |
+--- a/drivers/usb/core/quirks.c |
513 |
++++ b/drivers/usb/core/quirks.c |
514 |
+@@ -195,6 +195,10 @@ static const struct usb_device_id usb_quirk_list[] = { |
515 |
+ /* Guillemot Webcam Hercules Dualpix Exchange*/ |
516 |
+ { USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME }, |
517 |
+ |
518 |
++ /* Guillemot Hercules DJ Console audio card (BZ 208357) */ |
519 |
++ { USB_DEVICE(0x06f8, 0xb000), .driver_info = |
520 |
++ USB_QUIRK_ENDPOINT_BLACKLIST }, |
521 |
++ |
522 |
+ /* Midiman M-Audio Keystation 88es */ |
523 |
+ { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, |
524 |
+ |
525 |
+@@ -344,6 +348,40 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = { |
526 |
+ { } /* terminating entry must be last */ |
527 |
+ }; |
528 |
+ |
529 |
++/* |
530 |
++ * Entries for blacklisted endpoints that should be ignored when parsing |
531 |
++ * configuration descriptors. |
532 |
++ * |
533 |
++ * Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST. |
534 |
++ */ |
535 |
++static const struct usb_device_id usb_endpoint_blacklist[] = { |
536 |
++ { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x01 }, |
537 |
++ { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x81 }, |
538 |
++ { } |
539 |
++}; |
540 |
++ |
541 |
++bool usb_endpoint_is_blacklisted(struct usb_device *udev, |
542 |
++ struct usb_host_interface *intf, |
543 |
++ struct usb_endpoint_descriptor *epd) |
544 |
++{ |
545 |
++ const struct usb_device_id *id; |
546 |
++ unsigned int address; |
547 |
++ |
548 |
++ for (id = usb_endpoint_blacklist; id->match_flags; ++id) { |
549 |
++ if (!usb_match_device(udev, id)) |
550 |
++ continue; |
551 |
++ |
552 |
++ if (!usb_match_one_id_intf(udev, intf, id)) |
553 |
++ continue; |
554 |
++ |
555 |
++ address = id->driver_info; |
556 |
++ if (address == epd->bEndpointAddress) |
557 |
++ return true; |
558 |
++ } |
559 |
++ |
560 |
++ return false; |
561 |
++} |
562 |
++ |
563 |
+ static bool usb_match_any_interface(struct usb_device *udev, |
564 |
+ const struct usb_device_id *id) |
565 |
+ { |
566 |
+diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h |
567 |
+index 6b2f115442838..462a00c749b87 100644 |
568 |
+--- a/drivers/usb/core/usb.h |
569 |
++++ b/drivers/usb/core/usb.h |
570 |
+@@ -31,6 +31,9 @@ extern void usb_deauthorize_interface(struct usb_interface *); |
571 |
+ extern void usb_authorize_interface(struct usb_interface *); |
572 |
+ extern void usb_detect_quirks(struct usb_device *udev); |
573 |
+ extern void usb_detect_interface_quirks(struct usb_device *udev); |
574 |
++extern bool usb_endpoint_is_blacklisted(struct usb_device *udev, |
575 |
++ struct usb_host_interface *intf, |
576 |
++ struct usb_endpoint_descriptor *epd); |
577 |
+ extern int usb_remove_device(struct usb_device *udev); |
578 |
+ |
579 |
+ extern int usb_get_device_descriptor(struct usb_device *dev, |
580 |
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c |
581 |
+index e2451bdb4525d..299412abb1658 100644 |
582 |
+--- a/drivers/video/fbdev/hyperv_fb.c |
583 |
++++ b/drivers/video/fbdev/hyperv_fb.c |
584 |
+@@ -712,7 +712,12 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) |
585 |
+ goto err1; |
586 |
+ } |
587 |
+ |
588 |
+- fb_virt = ioremap(par->mem->start, screen_fb_size); |
589 |
++ /* |
590 |
++ * Map the VRAM cacheable for performance. This is also required for |
591 |
++ * VM Connect to display properly for ARM64 Linux VM, as the host also |
592 |
++ * maps the VRAM cacheable. |
593 |
++ */ |
594 |
++ fb_virt = ioremap_cache(par->mem->start, screen_fb_size); |
595 |
+ if (!fb_virt) |
596 |
+ goto err2; |
597 |
+ |
598 |
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
599 |
+index b1125778b9080..9e1f9910bdf2d 100644 |
600 |
+--- a/fs/btrfs/inode.c |
601 |
++++ b/fs/btrfs/inode.c |
602 |
+@@ -5370,11 +5370,13 @@ no_delete: |
603 |
+ } |
604 |
+ |
605 |
+ /* |
606 |
+- * this returns the key found in the dir entry in the location pointer. |
607 |
++ * Return the key found in the dir entry in the location pointer, fill @type |
608 |
++ * with BTRFS_FT_*, and return 0. |
609 |
++ * |
610 |
+ * If no dir entries were found, location->objectid is 0. |
611 |
+ */ |
612 |
+ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, |
613 |
+- struct btrfs_key *location) |
614 |
++ struct btrfs_key *location, u8 *type) |
615 |
+ { |
616 |
+ const char *name = dentry->d_name.name; |
617 |
+ int namelen = dentry->d_name.len; |
618 |
+@@ -5396,6 +5398,8 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, |
619 |
+ goto out_err; |
620 |
+ |
621 |
+ btrfs_dir_item_key_to_cpu(path->nodes[0], di, location); |
622 |
++ if (!ret) |
623 |
++ *type = btrfs_dir_type(path->nodes[0], di); |
624 |
+ out: |
625 |
+ btrfs_free_path(path); |
626 |
+ return ret; |
627 |
+@@ -5681,19 +5685,25 @@ static struct inode *new_simple_dir(struct super_block *s, |
628 |
+ return inode; |
629 |
+ } |
630 |
+ |
631 |
++static inline u8 btrfs_inode_type(struct inode *inode) |
632 |
++{ |
633 |
++ return btrfs_type_by_mode[(inode->i_mode & S_IFMT) >> S_SHIFT]; |
634 |
++} |
635 |
++ |
636 |
+ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) |
637 |
+ { |
638 |
+ struct inode *inode; |
639 |
+ struct btrfs_root *root = BTRFS_I(dir)->root; |
640 |
+ struct btrfs_root *sub_root = root; |
641 |
+ struct btrfs_key location; |
642 |
++ u8 di_type = 0; |
643 |
+ int index; |
644 |
+ int ret = 0; |
645 |
+ |
646 |
+ if (dentry->d_name.len > BTRFS_NAME_LEN) |
647 |
+ return ERR_PTR(-ENAMETOOLONG); |
648 |
+ |
649 |
+- ret = btrfs_inode_by_name(dir, dentry, &location); |
650 |
++ ret = btrfs_inode_by_name(dir, dentry, &location, &di_type); |
651 |
+ if (ret < 0) |
652 |
+ return ERR_PTR(ret); |
653 |
+ |
654 |
+@@ -5702,6 +5712,18 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) |
655 |
+ |
656 |
+ if (location.type == BTRFS_INODE_ITEM_KEY) { |
657 |
+ inode = btrfs_iget(dir->i_sb, &location, root, NULL); |
658 |
++ if (IS_ERR(inode)) |
659 |
++ return inode; |
660 |
++ |
661 |
++ /* Do extra check against inode mode with di_type */ |
662 |
++ if (btrfs_inode_type(inode) != di_type) { |
663 |
++ btrfs_crit(root->fs_info, |
664 |
++"inode mode mismatch with dir: inode mode=0%o btrfs type=%u dir type=%u", |
665 |
++ inode->i_mode, btrfs_inode_type(inode), |
666 |
++ di_type); |
667 |
++ iput(inode); |
668 |
++ return ERR_PTR(-EUCLEAN); |
669 |
++ } |
670 |
+ return inode; |
671 |
+ } |
672 |
+ |
673 |
+@@ -6315,11 +6337,6 @@ fail: |
674 |
+ return ERR_PTR(ret); |
675 |
+ } |
676 |
+ |
677 |
+-static inline u8 btrfs_inode_type(struct inode *inode) |
678 |
+-{ |
679 |
+- return btrfs_type_by_mode[(inode->i_mode & S_IFMT) >> S_SHIFT]; |
680 |
+-} |
681 |
+- |
682 |
+ /* |
683 |
+ * utility function to add 'inode' into 'parent_inode' with |
684 |
+ * a give name and a given sequence number. |
685 |
+@@ -6904,6 +6921,14 @@ again: |
686 |
+ extent_start = found_key.offset; |
687 |
+ if (found_type == BTRFS_FILE_EXTENT_REG || |
688 |
+ found_type == BTRFS_FILE_EXTENT_PREALLOC) { |
689 |
++ /* Only regular file could have regular/prealloc extent */ |
690 |
++ if (!S_ISREG(inode->i_mode)) { |
691 |
++ ret = -EUCLEAN; |
692 |
++ btrfs_crit(root->fs_info, |
693 |
++ "regular/prealloc extent found for non-regular inode %llu", |
694 |
++ btrfs_ino(inode)); |
695 |
++ goto out; |
696 |
++ } |
697 |
+ extent_end = extent_start + |
698 |
+ btrfs_file_extent_num_bytes(leaf, item); |
699 |
+ } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
700 |
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c |
701 |
+index 734babb6626c4..18e667fbd054d 100644 |
702 |
+--- a/fs/btrfs/qgroup.c |
703 |
++++ b/fs/btrfs/qgroup.c |
704 |
+@@ -462,6 +462,7 @@ next2: |
705 |
+ break; |
706 |
+ } |
707 |
+ out: |
708 |
++ btrfs_free_path(path); |
709 |
+ fs_info->qgroup_flags |= flags; |
710 |
+ if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON)) { |
711 |
+ fs_info->quota_enabled = 0; |
712 |
+@@ -470,7 +471,6 @@ out: |
713 |
+ ret >= 0) { |
714 |
+ ret = qgroup_rescan_init(fs_info, rescan_progress, 0); |
715 |
+ } |
716 |
+- btrfs_free_path(path); |
717 |
+ |
718 |
+ if (ret < 0) { |
719 |
+ ulist_free(fs_info->qgroup_ulist); |
720 |
+diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c |
721 |
+index 054fc0d97131b..5ff676df698f0 100644 |
722 |
+--- a/fs/btrfs/tests/inode-tests.c |
723 |
++++ b/fs/btrfs/tests/inode-tests.c |
724 |
+@@ -235,6 +235,7 @@ static noinline int test_btrfs_get_extent(void) |
725 |
+ return ret; |
726 |
+ } |
727 |
+ |
728 |
++ inode->i_mode = S_IFREG; |
729 |
+ BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; |
730 |
+ BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; |
731 |
+ BTRFS_I(inode)->location.offset = 0; |
732 |
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
733 |
+index 2d10b818399b1..cd1e9411f9269 100644 |
734 |
+--- a/fs/btrfs/volumes.c |
735 |
++++ b/fs/btrfs/volumes.c |
736 |
+@@ -6262,6 +6262,13 @@ static int btrfs_check_chunk_valid(struct btrfs_root *root, |
737 |
+ return -EIO; |
738 |
+ } |
739 |
+ |
740 |
++ if (!is_power_of_2(type & BTRFS_BLOCK_GROUP_PROFILE_MASK) && |
741 |
++ (type & BTRFS_BLOCK_GROUP_PROFILE_MASK) != 0) { |
742 |
++ btrfs_err(root->fs_info, |
743 |
++ "invalid chunk profile flag: 0x%llx, expect 0 or 1 bit set", |
744 |
++ type & BTRFS_BLOCK_GROUP_PROFILE_MASK); |
745 |
++ return -EUCLEAN; |
746 |
++ } |
747 |
+ if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) { |
748 |
+ btrfs_err(root->fs_info, "missing chunk type flag: 0x%llx", type); |
749 |
+ return -EIO; |
750 |
+diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c |
751 |
+index e2ab6d0497f2b..151884b95ee2f 100644 |
752 |
+--- a/fs/efivarfs/inode.c |
753 |
++++ b/fs/efivarfs/inode.c |
754 |
+@@ -10,6 +10,7 @@ |
755 |
+ #include <linux/efi.h> |
756 |
+ #include <linux/fs.h> |
757 |
+ #include <linux/ctype.h> |
758 |
++#include <linux/kmemleak.h> |
759 |
+ #include <linux/slab.h> |
760 |
+ |
761 |
+ #include "internal.h" |
762 |
+@@ -138,6 +139,7 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, |
763 |
+ var->var.VariableName[i] = '\0'; |
764 |
+ |
765 |
+ inode->i_private = var; |
766 |
++ kmemleak_ignore(var); |
767 |
+ |
768 |
+ efivar_entry_add(var, &efivarfs_list); |
769 |
+ d_instantiate(dentry, inode); |
770 |
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c |
771 |
+index 0e4f20377d196..fca235020312d 100644 |
772 |
+--- a/fs/efivarfs/super.c |
773 |
++++ b/fs/efivarfs/super.c |
774 |
+@@ -23,7 +23,6 @@ LIST_HEAD(efivarfs_list); |
775 |
+ static void efivarfs_evict_inode(struct inode *inode) |
776 |
+ { |
777 |
+ clear_inode(inode); |
778 |
+- kfree(inode->i_private); |
779 |
+ } |
780 |
+ |
781 |
+ static const struct super_operations efivarfs_ops = { |
782 |
+diff --git a/fs/proc/self.c b/fs/proc/self.c |
783 |
+index 2dcc2558b3aa7..dffbe533d53fc 100644 |
784 |
+--- a/fs/proc/self.c |
785 |
++++ b/fs/proc/self.c |
786 |
+@@ -24,6 +24,13 @@ static const char *proc_self_follow_link(struct dentry *dentry, void **cookie) |
787 |
+ pid_t tgid = task_tgid_nr_ns(current, ns); |
788 |
+ char *name; |
789 |
+ |
790 |
++ /* |
791 |
++ * Not currently supported. Once we can inherit all of struct pid, |
792 |
++ * we can allow this. |
793 |
++ */ |
794 |
++ if (current->flags & PF_KTHREAD) |
795 |
++ return ERR_PTR(-EOPNOTSUPP); |
796 |
++ |
797 |
+ if (!tgid) |
798 |
+ return ERR_PTR(-ENOENT); |
799 |
+ /* 11 for max length of signed int in decimal + NULL term */ |
800 |
+diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h |
801 |
+index ea4f81c2a6d5e..602dff213bae1 100644 |
802 |
+--- a/include/linux/usb/quirks.h |
803 |
++++ b/include/linux/usb/quirks.h |
804 |
+@@ -59,4 +59,7 @@ |
805 |
+ /* Device needs a pause after every control message. */ |
806 |
+ #define USB_QUIRK_DELAY_CTRL_MSG BIT(13) |
807 |
+ |
808 |
++/* device has blacklisted endpoints */ |
809 |
++#define USB_QUIRK_ENDPOINT_BLACKLIST BIT(15) |
810 |
++ |
811 |
+ #endif /* __LINUX_USB_QUIRKS_H */ |
812 |
+diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h |
813 |
+index c7b1dc713cdd7..9c7f4aad6db66 100644 |
814 |
+--- a/include/scsi/libiscsi.h |
815 |
++++ b/include/scsi/libiscsi.h |
816 |
+@@ -144,6 +144,9 @@ struct iscsi_task { |
817 |
+ void *dd_data; /* driver/transport data */ |
818 |
+ }; |
819 |
+ |
820 |
++/* invalid scsi_task pointer */ |
821 |
++#define INVALID_SCSI_TASK (struct iscsi_task *)-1l |
822 |
++ |
823 |
+ static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) |
824 |
+ { |
825 |
+ return task->unsol_r2t.data_length > task->unsol_r2t.sent; |
826 |
+diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c |
827 |
+index fd460aca36e55..40e4c933b3728 100644 |
828 |
+--- a/tools/perf/util/dwarf-aux.c |
829 |
++++ b/tools/perf/util/dwarf-aux.c |
830 |
+@@ -305,6 +305,7 @@ bool die_is_func_def(Dwarf_Die *dw_die) |
831 |
+ int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr) |
832 |
+ { |
833 |
+ Dwarf_Addr base, end; |
834 |
++ Dwarf_Attribute attr; |
835 |
+ |
836 |
+ if (!addr) |
837 |
+ return -EINVAL; |
838 |
+@@ -312,6 +313,13 @@ int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr) |
839 |
+ if (dwarf_entrypc(dw_die, addr) == 0) |
840 |
+ return 0; |
841 |
+ |
842 |
++ /* |
843 |
++ * Since the dwarf_ranges() will return 0 if there is no |
844 |
++ * DW_AT_ranges attribute, we should check it first. |
845 |
++ */ |
846 |
++ if (!dwarf_attr(dw_die, DW_AT_ranges, &attr)) |
847 |
++ return -ENOENT; |
848 |
++ |
849 |
+ return dwarf_ranges(dw_die, 0, &base, addr, &end) < 0 ? -ENOENT : 0; |
850 |
+ } |
851 |
+ |