6.4.8-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 115/239 RDMA/bnxt_re: add helper function __poll_for_resp
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit 354f5bd985af9515190828bc642ebdf59acea121 ]
This interface will be used if the driver has not enabled interrupt and/or interrupt is disabled for a short period of time. Completion is not possible from interrupt so this interface does self-polling.
Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 44 +++++++++++++++++++++- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 + 2 files changed, 44 insertions(+), 1 deletion(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +43 -1
@@ -260,6 +260,44 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,return 0 ; } +/** +* __poll_for_resp - self poll completion for rcfw command +* @rcfw - rcfw channel instance of rdev +* @cookie - cookie to track the command +* @opcode - rcfw submitted for given opcode +* +* It works same as __wait_for_resp except this function will +* do self polling in sort interval since interrupt is disabled. +* This function can not be called from non-sleepable context. +* +* Returns: +* -ETIMEOUT if command is not completed in specific time interval. +* 0 if command is completed by firmware. +*/ +static int __poll_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie, +u8 opcode) +{ +struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq; +unsigned long issue_time; +u16 cbit; + + cbit = cookie % rcfw->cmdq_depth; + issue_time = jiffies; + +do { +if (test_bit (ERR_DEVICE_DETACHED , &cmdq->flags)) +return bnxt_qplib_map_rc (opcode); + +usleep_range (1000 ,1001 ); + +bnxt_qplib_service_creq (&rcfw->creq.creq_tasklet); +if (!test_bit (cbit, cmdq->cmdq_bitmap)) +return 0 ; +if (jiffies_to_msecs (jiffies - issue_time) >10000 ) +return -ETIMEDOUT ; + }while (true); +}; +static int __send_message_basic_sanity (struct bnxt_qplib_rcfw *rcfw,struct bnxt_qplib_cmdqmsg *msg) {
@@ -328,8 +366,10 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,if (msg->block) rc =__block_for_resp (rcfw, cookie, opcode); -else +else if (atomic_read (&rcfw->rcfw_intr_enabled)) rc =__wait_for_resp (rcfw, cookie, opcode); +else + rc =__poll_for_resp (rcfw, cookie, opcode);if (rc) {/* timed out */ dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x timedout (%d)msec\n",
@@ -798,6 +838,7 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)kfree (creq->irq_name); creq->irq_name =NULL ; creq->requested = false; +atomic_set (&rcfw->rcfw_intr_enabled,0 ); }void bnxt_qplib_disable_rcfw_channel (struct bnxt_qplib_rcfw *rcfw)
@@ -859,6 +900,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, creq->requested = true;bnxt_qplib_ring_nq_db (&creq->creq_db.dbinfo, res->cctx, true); +atomic_inc (&rcfw->rcfw_intr_enabled);return 0 ; }
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +1 -0
@@ -225,6 +225,7 @@ struct bnxt_qplib_rcfw {u64 oos_prev;u32 init_oos_stats;u32 cmdq_depth; +atomic_t rcfw_intr_enabled;struct semaphore rcfw_inflight; };
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 116/239 RDMA/bnxt_re: Fix hang during driver unload
In reply to Greg Kroah-HartmanFrom: Selvin Xavier <[email protected]>
[ Upstream commit 29900bf351e1a7e4643da5c3c3cd9df75c577b88 ]
Driver unload hits a hang during stress testing of load/unload.
stack trace snippet -
tasklet_kill at ffffffff9aabb8b2 bnxt_qplib_nq_stop_irq at ffffffffc0a805fb [bnxt_re] bnxt_qplib_disable_nq at ffffffffc0a80c5b [bnxt_re] bnxt_re_dev_uninit at ffffffffc0a67d15 [bnxt_re] bnxt_re_remove_device at ffffffffc0a6af1d [bnxt_re]
tasklet_kill can hang if the tasklet is scheduled after it is disabled.
Modified the sequences to disable the interrupt first and synchronize irq before disabling the tasklet.
--- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 10 +++++----- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_fp.c +5 -5
@@ -420,19 +420,19 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)if (!nq->requested)return ; -tasklet_disable (&nq->nq_tasklet); + nq->requested = false;/* Mask h/w interrupt */ bnxt_qplib_ring_nq_db (&nq->nq_db.dbinfo, nq->res->cctx, false);/* Sync with last running IRQ handler */ synchronize_irq (nq->msix_vec); -if (kill) -tasklet_kill (&nq->nq_tasklet); -irq_set_affinity_hint (nq->msix_vec,NULL );free_irq (nq->msix_vec, nq);kfree (nq->name); nq->name =NULL ; - nq->requested = false; + +if (kill) +tasklet_kill (&nq->nq_tasklet); +tasklet_disable (&nq->nq_tasklet); }void bnxt_qplib_disable_nq (struct bnxt_qplib_nq *nq)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +4 -5
@@ -826,19 +826,18 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)if (!creq->requested)return ; -tasklet_disable (&creq->creq_tasklet); + creq->requested = false;/* Mask h/w interrupts */ bnxt_qplib_ring_nq_db (&creq->creq_db.dbinfo, rcfw->res->cctx, false);/* Sync with last running IRQ-handler */ synchronize_irq (creq->msix_vec); -if (kill) -tasklet_kill (&creq->creq_tasklet); -free_irq (creq->msix_vec, rcfw);kfree (creq->irq_name); creq->irq_name =NULL ; - creq->requested = false;atomic_set (&rcfw->rcfw_intr_enabled,0 ); +if (kill) +tasklet_kill (&creq->creq_tasklet); +tasklet_disable (&creq->creq_tasklet); }void bnxt_qplib_disable_rcfw_channel (struct bnxt_qplib_rcfw *rcfw)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 117/239 drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb()
In reply to Greg Kroah-HartmanFrom: Gaosheng Cui <[email protected]>
[ Upstream commit 6e8a996563ecbe68e49c49abd4aaeef69f11f2dc ]
The msm_gem_get_vaddr() returns an ERR_PTR() on failure, and a null is catastrophic here, so we should use IS_ERR_OR_NULL() to check the return value.
Patchwork: https://patchwork.freedesktop.org/patch/547712/
--- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +1 -1
@@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit* since we've already mapped it once in * submit_reloc() */ -if (WARN_ON (!ptr)) +if (WARN_ON (IS_ERR_OR_NULL (ptr)))return ;for (i =0 ; i < dwords; i++) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 118/239 drm/msm: Fix hw_fence error path cleanup
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 1cd0787f082e1a179f2b6e749d08daff1a9f6b1b ]
In an error path where the submit is free'd without the job being run, the hw_fence pointer is simply a kzalloc'd block of memory. In this case we should just kfree() it, rather than trying to decrement it's reference count. Fortunately we can tell that this is the case by checking for a zero refcount, since if the job was run, the submit would be holding a reference to the hw_fence.
Patchwork: https://patchwork.freedesktop.org/patch/547088/
--- drivers/gpu/drm/msm/msm_fence.c | 6 ++++++ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_fence.c +6 -0
@@ -191,6 +191,12 @@ msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx) f->fctx = fctx; +/* +* Until this point, the fence was just some pre-allocated memory, +* no-one should have taken a reference to it yet. +*/ +WARN_ON (kref_read (&fence->refcount)); +dma_fence_init (&f->base, &msm_fence_ops, &fctx->spinlock, fctx->context, ++fctx->last_fence); }
drivers/gpu/drm/msm/msm_gem_submit.c +13 -1
@@ -86,7 +86,19 @@ void __msm_gem_submit_destroy(struct kref *kref) }dma_fence_put (submit->user_fence); -dma_fence_put (submit->hw_fence); + +/* +* If the submit is freed before msm_job_run(), then hw_fence is +* just some pre-allocated memory, not a reference counted fence. +* Once the job runs and the hw_fence is initialized, it will +* have a refcount of at least one, since the submit holds a ref +* to the hw_fence. +*/ +if (kref_read (&submit->hw_fence->refcount) ==0 ) { +kfree (submit->hw_fence); + }else { +dma_fence_put (submit->hw_fence); + }put_pid (submit->pid);msm_submitqueue_put (submit->queue);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 119/239 cxl/acpi: Fix a use-after-free in cxl_parse_cfmws()
In reply to Greg Kroah-HartmanFrom: Breno Leitao <[email protected]>
[ Upstream commit 4cf67d3cc9994a59cf77bb9c0ccf9007fe916afe ]
KASAN and KFENCE detected an user-after-free in the CXL driver. This happens in the cxl_decoder_add() fail path. KASAN prints the following error:
BUG: KASAN: slab-use-after-free in cxl_parse_cfmws (drivers/cxl/acpi.c:299)
This happens in cxl_parse_cfmws(), where put_device() is called, releasing cxld, which is accessed later.
Use the local variables in the dev_err() instead of pointing to the released memory. Since the dev_err() is printing a resource, change the open coded print format to use the %pr format specifier.
--- drivers/cxl/acpi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/cxl/acpi.c +1 -2
@@ -296,8 +296,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,else rc =cxl_decoder_autoremove (dev, cxld);if (rc) { -dev_err (dev,"Failed to add decode range [%#llx - %#llx]\n" , - cxld->hpa_range.start, cxld->hpa_range.end); +dev_err (dev,"Failed to add decode range: %pr" , res);return 0 ; } dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n",
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 120/239 cxl/acpi: Return rc instead of 0 in cxl_parse_cfmws()
In reply to Greg Kroah-HartmanFrom: Breno Leitao <[email protected]>
[ Upstream commit 91019b5bc7c2c5e6f676cce80ee6d12b2753d018 ]
Driver initialization returned success (return 0) even if the initialization (cxl_decoder_add() or acpi_table_parse_cedt()) failed.
Return the error instead of swallowing it.
--- drivers/cxl/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cxl/acpi.c +1 -1
@@ -297,7 +297,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg, rc =cxl_decoder_autoremove (dev, cxld);if (rc) {dev_err (dev,"Failed to add decode range: %pr" , res); -return 0 ; +return rc; } dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n", dev_name(&cxld->dev),
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 121/239 ASoC: fsl_spdif: Silence output on stop
In reply to Greg Kroah-HartmanFrom: Matus Gajdos <[email protected]>
[ Upstream commit 0e4c2b6b0c4a4b4014d9424c27e5e79d185229c5 ]
Clear TX registers on stop to prevent the SPDIF interface from sending last written word over and over again.
--- sound/soc/fsl/fsl_spdif.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/fsl/fsl_spdif.c +2 -0
@@ -751,6 +751,8 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream,case SNDRV_PCM_TRIGGER_PAUSE_PUSH :regmap_update_bits (regmap,REG_SPDIF_SCR , dmaen,0 );regmap_update_bits (regmap,REG_SPDIF_SIE , intr,0 ); +regmap_write (regmap,REG_SPDIF_STL ,0x0 ); +regmap_write (regmap,REG_SPDIF_STR ,0x0 );break ;default :return -EINVAL ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 122/239 block: Fix a source code comment in include/uapi/linux/blkzoned.h
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit e0933b526fbfd937c4a8f4e35fcdd49f0e22d411 ]
Fix the symbolic names for zone conditions in the blkzoned.h header file.
--- include/uapi/linux/blkzoned.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
include/uapi/linux/blkzoned.h +5 -5
@@ -51,13 +51,13 @@ enum blk_zone_type {* * The Zone Condition state machine in the ZBC/ZAC standards maps the above * deinitions as: -* - ZC1: Empty | BLK_ZONE_EMPTY +* - ZC1: Empty | BLK_ZONE_COND_EMPTY * - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN * - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN -* - ZC4: Closed | BLK_ZONE_CLOSED -* - ZC5: Full | BLK_ZONE_FULL -* - ZC6: Read Only | BLK_ZONE_READONLY -* - ZC7: Offline | BLK_ZONE_OFFLINE +* - ZC4: Closed | BLK_ZONE_COND_CLOSED +* - ZC5: Full | BLK_ZONE_COND_FULL +* - ZC6: Read Only | BLK_ZONE_COND_READONLY +* - ZC7: Offline | BLK_ZONE_COND_OFFLINE * * Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should * be considered invalid.
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 123/239 smb3: do not set NTLMSSP_VERSION flag for negotiate not auth request
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
[ Upstream commit 19826558210b9102a7d4681c91784d137d60d71b ]
The NTLMSSP_NEGOTIATE_VERSION flag only needs to be sent during the NTLMSSP NEGOTIATE (not the AUTH) request, so filter it out for NTLMSSP AUTH requests. See MS-NLMP 2.2.1.3
This fixes a problem found by the gssntlmssp server.
--- fs/smb/client/sess.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/smb/client/sess.c +3 -1
@@ -1013,6 +1013,7 @@ int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer, } +/* See MS-NLMP 2.2.1.3 */ int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen, struct cifs_ses *ses,
@@ -1047,7 +1048,8 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer, flags = ses->ntlmssp->server_flags |NTLMSSP_REQUEST_TARGET |NTLMSSP_NEGOTIATE_TARGET_INFO |NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED ; - +/* we only send version information in ntlmssp negotiate, so do not set this flag */ + flags = flags & ~NTLMSSP_NEGOTIATE_VERSION ; tmp = *pbuffer +sizeof (AUTHENTICATE_MESSAGE ); sec_blob->NegotiateFlags =cpu_to_le32 (flags);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 124/239 drm/i915: Fix an error handling path in igt_write_huge()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit e354f67733115b4453268f61e6e072e9b1ea7a2f ]
All error handling paths go to 'out', except this one. Be consistent and also branch to 'out' here.
--- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/gem/selftests/huge_pages.c +4 -2
@@ -1190,8 +1190,10 @@ static int igt_write_huge(struct drm_i915_private *i915,* times in succession a possibility by enlarging the permutation array. */ order =i915_random_order (count * count, &prng); -if (!order) -return -ENOMEM ; +if (!order) { + err = -ENOMEM ; + goto out; + } max_page_size =rounddown_pow_of_two (obj->mm.page_sizes.sg); max =div_u64 (max - size, max_page_size);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 125/239 xenbus: check xen_domain in xenbus_probe_initcall
In reply to Greg Kroah-HartmanFrom: Stefano Stabellini <[email protected]>
[ Upstream commit 0d8f7cc8057890db08c54fe610d8a94af59da082 ]
The same way we already do in xenbus_init.
Fixes the following warning:
[ 352.175563] Trying to free already-free IRQ 0 [ 352.177355] WARNING: CPU: 1 PID: 88 at kernel/irq/manage.c:1893 free_irq+0xbf/0x350 [...] [ 352.213951] Call Trace: [ 352.214390] <TASK> [ 352.214717] ? __warn+0x81/0x170 [ 352.215436] ? free_irq+0xbf/0x350 [ 352.215906] ? report_bug+0x10b/0x200 [ 352.216408] ? prb_read_valid+0x17/0x20 [ 352.216926] ? handle_bug+0x44/0x80 [ 352.217409] ? exc_invalid_op+0x13/0x60 [ 352.217932] ? asm_exc_invalid_op+0x16/0x20 [ 352.218497] ? free_irq+0xbf/0x350 [ 352.218979] ? __pfx_xenbus_probe_thread+0x10/0x10 [ 352.219600] xenbus_probe+0x7a/0x80 [ 352.221030] xenbus_probe_thread+0x76/0xc0
--- drivers/xen/xenbus/xenbus_probe.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/xen/xenbus/xenbus_probe.c +3 -0
@@ -811,6 +811,9 @@ static int xenbus_probe_thread(void *unused)static int __init xenbus_probe_initcall (void ) { +if (!xen_domain ()) +return -ENODEV ; +/* * Probe XenBus here in the XS_PV case, and also XS_HVM unless we * need to wait for the platform PCI device to come up or
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 126/239 dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit bae3028799dc4f1109acc4df37c8ff06f2d8f1a0 ]
In the error paths 'bad_stripe_cache' and 'bad_check_reshape', 'reconfig_mutex' is still held after raid_ctr() returns.
--- drivers/md/dm-raid.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/md/dm-raid.c +7 -2
@@ -3271,15 +3271,19 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456 (rs)) { r =rs_set_raid456_stripe_cache (rs); -if (r) +if (r) { +mddev_unlock (&rs->md); goto bad_stripe_cache; + } }/* Now do an early reshape check */ if (test_bit (RT_FLAG_RESHAPE_RS , &rs->runtime_flags)) { r =rs_check_reshape (rs); -if (r) +if (r) { +mddev_unlock (&rs->md); goto bad_check_reshape; + }/* Restore new, ctr requested layout to perform check */ rs_config_restore (rs, &rs_layout);
@@ -3288,6 +3292,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r = rs->md.pers->check_reshape (&rs->md);if (r) { ti->error ="Reshape check failed" ; +mddev_unlock (&rs->md); goto bad_check_reshape; } }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 127/239 dm raid: clean up four equivalent goto tags in raid_ctr()
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit e74c874eabe2e9173a8fbdad616cd89c70eb8ffd ]
There are four equivalent goto tags in raid_ctr(), clean them up to use just one.
There is no functional change and this is preparation to fix raid_ctr()'s unprotected md_stop().
Stable-dep-of: 7d5fff8982a2 ("dm raid: protect md_stop() with 'reconfig_mutex'")
--- drivers/md/dm-raid.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
drivers/md/dm-raid.c +9 -18
@@ -3251,8 +3251,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r =md_start (&rs->md);if (r) { ti->error ="Failed to start raid array" ; -mddev_unlock (&rs->md); - goto bad_md_start; + goto bad_unlock; }/* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
@@ -3260,8 +3259,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r =r5c_journal_mode_set (&rs->md, rs->journal_dev.mode);if (r) { ti->error ="Failed to set raid4/5/6 journal mode" ; -mddev_unlock (&rs->md); - goto bad_journal_mode_set; + goto bad_unlock; } }
@@ -3271,19 +3269,15 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456 (rs)) { r =rs_set_raid456_stripe_cache (rs); -if (r) { -mddev_unlock (&rs->md); - goto bad_stripe_cache; - } +if (r) + goto bad_unlock; }/* Now do an early reshape check */ if (test_bit (RT_FLAG_RESHAPE_RS , &rs->runtime_flags)) { r =rs_check_reshape (rs); -if (r) { -mddev_unlock (&rs->md); - goto bad_check_reshape; - } +if (r) + goto bad_unlock;/* Restore new, ctr requested layout to perform check */ rs_config_restore (rs, &rs_layout);
@@ -3292,8 +3286,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r = rs->md.pers->check_reshape (&rs->md);if (r) { ti->error ="Reshape check failed" ; -mddev_unlock (&rs->md); - goto bad_check_reshape; + goto bad_unlock; } } }
@@ -3304,10 +3297,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)mddev_unlock (&rs->md);return 0 ; -bad_md_start: -bad_journal_mode_set: -bad_stripe_cache: -bad_check_reshape: +bad_unlock: +mddev_unlock (&rs->md);md_stop (&rs->md); bad:raid_set_free (rs);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 128/239 dm raid: protect md_stop() with reconfig_mutex
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit 7d5fff8982a2199d49ec067818af7d84d4f95ca0 ]
__md_stop_writes() and __md_stop() will modify many fields that are protected by 'reconfig_mutex', and all the callers will grab 'reconfig_mutex' except for md_stop().
Also, update md_stop() to make certain 'reconfig_mutex' is held using lockdep_assert_held().
--- drivers/md/dm-raid.c | 4 +++- drivers/md/md.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/md/dm-raid.c +3 -1
@@ -3298,8 +3298,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)return 0 ; bad_unlock: -mddev_unlock (&rs->md);md_stop (&rs->md); +mddev_unlock (&rs->md); bad:raid_set_free (rs);
@@ -3310,7 +3310,9 @@ static void raid_dtr(struct dm_target *ti) {struct raid_set *rs = ti->private; +mddev_lock_nointr (&rs->md);md_stop (&rs->md); +mddev_unlock (&rs->md);raid_set_free (rs); }
drivers/md/md.c +2 -0
@@ -6260,6 +6260,8 @@ static void __md_stop(struct mddev *mddev)void md_stop (struct mddev *mddev) { +lockdep_assert_held (&mddev->reconfig_mutex); +/* stop the array and free an attached data structures. * This is called from dm-raid */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 129/239 drm/amd: Fix an error handling mistake in psp_sw_init()
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit c01aebeef3ce45f696ffa0a1303cea9b34babb45 ]
If the second call to amdgpu_bo_create_kernel() fails, the memory allocated from the first call should be cleared. If the third call fails, the memory from the second call should be cleared.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +3 -3
@@ -491,11 +491,11 @@ static int psp_sw_init(void *handle)return 0 ; failed2: -amdgpu_bo_free_kernel (&psp->fw_pri_bo, - &psp->fw_pri_mc_addr, &psp->fw_pri_buf); -failed1:amdgpu_bo_free_kernel (&psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); +failed1: +amdgpu_bo_free_kernel (&psp->fw_pri_bo, + &psp->fw_pri_mc_addr, &psp->fw_pri_buf);return ret; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 130/239 drm/amd/display: Unlock on error path in dm_handle_mst_sideband_msg_ready_event()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 38ac4e8385ffb275b1837986ca6c16f26ea028c5 ]
This error path needs to unlock the "aconnector->handle_mst_msg_ready" mutex before returning.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1 -1
@@ -706,7 +706,7 @@ void dm_handle_mst_sideband_msg_ready_event(if (retry ==3 ) {DRM_ERROR ("Failed to ack MST event.\n" ); -return ; +break ; }drm_dp_mst_hpd_irq_send_new_request (&aconnector->mst_mgr);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 131/239 RDMA/irdma: Fix op_type reporting in CQEs
In reply to Greg Kroah-HartmanFrom: Sindhu Devale <[email protected]>
[ Upstream commit 3bfb25fa2b5bb9c29681e6ac861808f4be1331a9 ]
The op_type field CQ poll info structure is incorrectly filled in with the queue type as opposed to the op_type received in the CQEs. The wrong opcode could be decoded and returned to the ULP.
Copy the op_type field received in the CQE in the CQ poll info structure.
--- drivers/infiniband/hw/irdma/uk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/irdma/uk.c +1 -1
@@ -1161,7 +1161,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, } wqe_idx = (u32 )FIELD_GET (IRDMA_CQ_WQEIDX , qword3); info->qp_handle = (irdma_qp_handle )(unsigned long )qp; - info->op_type = (u8 )FIELD_GET (IRDMA_CQ_SQ , qword3); + info->op_type = (u8 )FIELD_GET (IRDMACQ_OP , qword3);if (info->q_type ==IRDMA_CQE_QTYPE_RQ ) {u32 array_idx;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 132/239 RDMA/irdma: Report correct WC error
In reply to Greg Kroah-HartmanFrom: Sindhu Devale <[email protected]>
[ Upstream commit ae463563b7a1b7d4a3d0b065b09d37a76b693937 ]
Report the correct WC error if a MW bind is performed on an already valid/bound window.
--- drivers/infiniband/hw/irdma/hw.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/hw/irdma/hw.c +1 -0
@@ -191,6 +191,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp,case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS :case IRDMA_AE_AMP_MWBIND_BIND_DISABLED :case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS : +case IRDMA_AE_AMP_MWBIND_VALID_STAG : qp->flush_code =FLUSH_MW_BIND_ERR ; qp->event_type =IRDMA_QP_EVENT_ACCESS_ERR ;break ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 133/239 drm/msm: Disallow submit with fence id 0
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 1b5d0ddcb34a605835051ae2950d5cfed0373dd8 ]
A fence id of zero is expected to be invalid, and is not removed from the fence_idr table. If userspace is requesting to specify the fence id with the FENCE_SN_IN flag, we need to reject a zero fence id value.
Patchwork: https://patchwork.freedesktop.org/patch/549180/
--- drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_gem_submit.c +1 -1
@@ -902,7 +902,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,* after the job is armed */ if ((args->flags &MSM_SUBMIT_FENCE_SN_IN ) && -idr_find (&queue->fence_idr, args->fence)) { + (!args->fence ||idr_find (&queue->fence_idr, args->fence))) {spin_unlock (&queue->idr_lock);idr_preload_end (); ret = -EINVAL ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 134/239 ublk: fail to start device if queue setup is interrupted
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 53e7d08f6d6e214c40db1f51291bb2975c789dc2 ]
In ublk_ctrl_start_dev(), if wait_for_completion_interruptible() is interrupted by signal, queues aren't setup successfully yet, so we have to fail UBLK_CMD_START_DEV, otherwise kernel oops can be triggered.
Reported by German when working on qemu-storage-deamon which requires single thread ublk daemon.
--- drivers/block/ublk_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/block/ublk_drv.c +2 -1
@@ -1632,7 +1632,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)if (ublksrv_pid <=0 )return -EINVAL ; -wait_for_completion_interruptible (&ub->completion); +if (wait_for_completion_interruptible (&ub->completion) !=0 ) +return -EINTR ;schedule_delayed_work (&ub->monitor_work,UBLK_DAEMON_MONITOR_PERIOD );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 135/239 ublk: fail to recover device if queue setup is interrupted
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 0c0cbd4ebc375ceebc75c89df04b74f215fab23a ]
In ublk_ctrl_end_recovery(), if wait_for_completion_interruptible() is interrupted by signal, queues aren't setup successfully yet, so we have to fail UBLK_CMD_END_USER_RECOVERY, otherwise kernel oops can be triggered.
--- drivers/block/ublk_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/block/ublk_drv.c +3 -1
@@ -2107,7 +2107,9 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,pr_devel ("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n" , __func__, ub->dev_info.nr_hw_queues, header->dev_id);/* wait until new ubq_daemon sending all FETCH_REQ */ -wait_for_completion_interruptible (&ub->completion); +if (wait_for_completion_interruptible (&ub->completion)) +return -EINTR ; +pr_devel ("%s: All new ubq_daemons(nr: %d) are ready, dev id %d\n" , __func__, ub->dev_info.nr_hw_queues, header->dev_id);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 136/239 ublk: return -EINTR if breaking from waiting for existed users in DEL_DEV
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 3e9dce80dbf91972aed972c743f539c396a34312 ]
If user interrupts wait_event_interruptible() in ublk_ctrl_del_dev(), return -EINTR and let user know what happens.
--- drivers/block/ublk_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/block/ublk_drv.c +2 -2
@@ -1909,8 +1909,8 @@ static int ublk_ctrl_del_dev(struct ublk_device **p_ub)* - the device number is freed already, we will not find this * device via ublk_get_device_from_id() */ -wait_event_interruptible (ublk_idr_wq,ublk_idr_freed (idx)); - +if (wait_event_interruptible (ublk_idr_wq,ublk_idr_freed (idx))) +return -EINTR ;return 0 ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 137/239 iommufd: IOMMUFD_DESTROY should not increase the refcount
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 99f98a7c0d6985d5507c8130a981972e4b7b3bdc ]
syzkaller found a race where IOMMUFD_DESTROY increments the refcount:
obj = iommufd_get_object(ucmd->ictx, cmd->id, IOMMUFD_OBJ_ANY);
if (IS_ERR(obj))
return PTR_ERR(obj);
iommufd_ref_to_users(obj);
/* See iommufd_ref_to_users() */
if (!iommufd_object_destroy_user(ucmd->ictx, obj))As part of the sequence to join the two existing primitives together.
Allowing the refcount the be elevated without holding the destroy_rwsem violates the assumption that all temporary refcount elevations are protected by destroy_rwsem. Racing IOMMUFD_DESTROY with iommufd_object_destroy_user() will cause spurious failures:
WARNING: CPU: 0 PID: 3076 at drivers/iommu/iommufd/device.c:477 iommufd_access_destroy+0x18/0x20 drivers/iommu/iommufd/device.c:478 Modules linked in: CPU: 0 PID: 3076 Comm: syz-executor.0 Not tainted 6.3.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/03/2023 RIP: 0010:iommufd_access_destroy+0x18/0x20 drivers/iommu/iommufd/device.c:477 Code: e8 3d 4e 00 00 84 c0 74 01 c3 0f 0b c3 0f 1f 44 00 00 f3 0f 1e fa 48 89 fe 48 8b bf a8 00 00 00 e8 1d 4e 00 00 84 c0 74 01 c3 <0f> 0b c3 0f 1f 44 00 00 41 57 41 56 41 55 4c 8d ae d0 00 00 00 41 RSP: 0018:ffffc90003067e08 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff888109ea0300 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 0000000000000000 RDI: 00000000ffffffff RBP: 0000000000000004 R08: 0000000000000000 R09: ffff88810bbb3500 R10: ffff88810bbb3e48 R11: 0000000000000000 R12: ffffc90003067e88 R13: ffffc90003067ea8 R14: ffff888101249800 R15: 00000000fffffffe FS: 00007ff7254fe6c0(0000) GS:ffff888237c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000555557262da8 CR3: 000000010a6fd000 CR4: 0000000000350ef0 Call Trace: <TASK> iommufd_test_create_access drivers/iommu/iommufd/selftest.c:596 [inline] iommufd_test+0x71c/0xcf0 drivers/iommu/iommufd/selftest.c:813 iommufd_fops_ioctl+0x10f/0x1b0 drivers/iommu/iommufd/main.c:337 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x84/0xc0 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x38/0x80 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
The solution is to not increment the refcount on the IOMMUFD_DESTROY path at all. Instead use the xa_lock to serialize everything. The refcount check == 1 and xa_erase can be done under a single critical region. This avoids the need for any refcount incrementing.
It has the downside that if userspace races destroy with other operations it will get an EBUSY instead of waiting, but this is kind of racing is already dangerous.
--- drivers/iommu/iommufd/device.c | 12 +--- drivers/iommu/iommufd/iommufd_private.h | 15 ++++- drivers/iommu/iommufd/main.c | 78 +++++++++++++++++++------ 3 files changed, 75 insertions(+), 30 deletions(-)
drivers/iommu/iommufd/device.c +3 -9
@@ -109,10 +109,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_bind, IOMMUFD);*/ void iommufd_device_unbind (struct iommufd_device *idev) { -bool was_destroyed; - - was_destroyed =iommufd_object_destroy_user (idev->ictx, &idev->obj); -WARN_ON (!was_destroyed); +iommufd_object_destroy_user (idev->ictx, &idev->obj); }EXPORT_SYMBOL_NS_GPL (iommufd_device_unbind,IOMMUFD );
@@ -382,7 +379,7 @@ void iommufd_device_detach(struct iommufd_device *idev)mutex_unlock (&hwpt->devices_lock);if (hwpt->auto_domain) -iommufd_object_destroy_user (idev->ictx, &hwpt->obj); +iommufd_object_deref_user (idev->ictx, &hwpt->obj);else refcount_dec (&hwpt->obj.users);
@@ -456,10 +453,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_access_create, IOMMUFD);*/ void iommufd_access_destroy (struct iommufd_access *access) { -bool was_destroyed; - - was_destroyed =iommufd_object_destroy_user (access->ictx, &access->obj); -WARN_ON (!was_destroyed); +iommufd_object_destroy_user (access->ictx, &access->obj); }EXPORT_SYMBOL_NS_GPL (iommufd_access_destroy,IOMMUFD );
drivers/iommu/iommufd/iommufd_private.h +13 -2
@@ -176,8 +176,19 @@ void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx, struct iommufd_object *obj);void iommufd_object_finalize (struct iommufd_ctx *ictx,struct iommufd_object *obj); -bool iommufd_object_destroy_user (struct iommufd_ctx *ictx, -struct iommufd_object *obj); +void __iommufd_object_destroy_user (struct iommufd_ctx *ictx, +struct iommufd_object *obj,bool allow_fail); +static inline void iommufd_object_destroy_user (struct iommufd_ctx *ictx, +struct iommufd_object *obj) +{ +__iommufd_object_destroy_user (ictx, obj, false); +} +static inline void iommufd_object_deref_user (struct iommufd_ctx *ictx, +struct iommufd_object *obj) +{ +__iommufd_object_destroy_user (ictx, obj, true); +} +struct iommufd_object *_iommufd_object_alloc (struct iommufd_ctx *ictx,size_t size,enum iommufd_object_type type);
drivers/iommu/iommufd/main.c +59 -19
108 lines not on this page · raw message
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 138/239 tmpfs: fix Documentation of noswap and huge mount options
In reply to Greg Kroah-HartmanFrom: Hugh Dickins <[email protected]>
[ Upstream commit 253e5df8b8f0145adb090f57c6f4e6efa52d738e ]
The noswap mount option is surely not one of the three options for sizing:
move its description down.
The huge= mount option does not accept numeric values: those are just in an internal enum. Delete those numbers, and follow the manpage text more closely (but there's not yet any fadvise() or fcntl() which applies here).
/sys/kernel/mm/transparent_hugepage/shmem_enabled is hard to describe, and barely relevant to mounting a tmpfs: just refer to transhuge.rst (while still using the words deny and force, to help as informal reminders).
--- Documentation/filesystems/tmpfs.rst | 47 ++++++++++++----------------- 1 file changed, 20 insertions(+), 27 deletions(-)
Documentation/filesystems/tmpfs.rst +20 -27
@@ -84,8 +84,6 @@ nr_inodes The maximum number of inodes for this instance. The default is half of the number of your physical RAM pages, or (on a machine with highmem) the number of lowmem RAM pages, whichever is the lower. -noswap Disables swap. Remounts must respect the original settings. - By default swap is enabled. ========= ============================================================ These parameters accept a suffix k, m or g for kilo, mega and giga and
@@ -99,36 +97,31 @@ mount with such options, since it allows any user with write access to use up all the memory on the machine; but enhances the scalability of that instance in a system with many CPUs making intensive use of it. +tmpfs blocks may be swapped out, when there is a shortage of memory. +tmpfs has a mount option to disable its use of swap: + +====== =========================================================== +noswap Disables swap. Remounts must respect the original settings. + By default swap is enabled. +====== =========================================================== + tmpfs also supports Transparent Huge Pages which requires a kernel configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge supported for your system (has_transparent_hugepage(), which is architecture specific). The mount options for this are: -====== ============================================================ -huge=0 never: disables huge pages for the mount -huge=1 always: enables huge pages for the mount -huge=2 within_size: only allocate huge pages if the page will be - fully within i_size, also respect fadvise()/madvise() hints. -huge=3 advise: only allocate huge pages if requested with - fadvise()/madvise() -====== ============================================================ - -There is a sysfs file which you can also use to control system wide THP -configuration for all tmpfs mounts, the file is: - -/sys/kernel/mm/transparent_hugepage/shmem_enabled - -This sysfs file is placed on top of THP sysfs directory and so is registered -by THP code. It is however only used to control all tmpfs mounts with one -single knob. Since it controls all tmpfs mounts it should only be used either -for emergency or testing purposes. The values you can set for shmem_enabled are: - -== ============================================================ --1 deny: disables huge on shm_mnt and all mounts, for - emergency use --2 force: enables huge on shm_mnt and all mounts, w/o needing - option, for testing -== ============================================================ +================ ============================================================== +huge=never Do not allocate huge pages. This is the default. +huge=always Attempt to allocate huge page every time a new page is needed. +huge=within_size Only allocate huge page if it will be fully within i_size. + Also respect madvise(2) hints. +huge=advise Only allocate huge page if requested with madvise(2). +================ ============================================================== + +See also Documentation/admin-guide/mm/transhuge.rst, which describes the +sysfs file /sys/kernel/mm/transparent_hugepage/shmem_enabled: which can +be used to deny huge pages on all tmpfs mounts in an emergency, or to +force huge pages on all tmpfs mounts for testing. tmpfs has a mount option to set the NUMA memory allocation policy for all files in that instance (if CONFIG_NUMA is enabled) - which can be
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 139/239 ata: pata_ns87415: mark ns87560_tf_read static
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 3fc2febb0f8ffae354820c1772ec008733237cfa ]
The global function triggers a warning because of the missing prototype
drivers/ata/pata_ns87415.c:263:6: warning: no previous prototype for 'ns87560_tf_read' [-Wmissing-prototypes]
263 | void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
There are no other references to this, so just make it static.
--- drivers/ata/pata_ns87415.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/pata_ns87415.c +1 -1
@@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap)* LOCKING: * Inherited from caller. */ -void ns87560_tf_read (struct ata_port *ap,struct ata_taskfile *tf) +static void ns87560_tf_read (struct ata_port *ap,struct ata_taskfile *tf) {struct ata_ioports *ioaddr = &ap->ioaddr;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 140/239 ring-buffer: Fix wrong stat of cpu_buffer->read
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
[ Upstream commit 2d093282b0d4357373497f65db6a05eb0c28b7c8 ]
When pages are removed in rb_remove_pages(), 'cpu_buffer->read' is set to 0 in order to make sure any read iterators reset themselves. However, this will mess 'entries' stating, see following steps:
# cd /sys/kernel/tracing/
# 1. Enlarge ring buffer prepare for later reducing:
# echo 20 > per_cpu/cpu0/buffer_size_kb
# 2. Write a log into ring buffer of cpu0:
# taskset -c 0 echo "hello1" > trace_marker
# 3. Read the log:
# cat per_cpu/cpu0/trace_pipe
<...>-332 [000] ..... 62.406844: tracing_mark_write: hello1
# 4. Stop reading and see the stats, now 0 entries, and 1 event readed:
# cat per_cpu/cpu0/stats
entries: 0
[...]
read events: 1
# 5. Reduce the ring buffer
# echo 7 > per_cpu/cpu0/buffer_size_kb
# 6. Now entries became unexpected 1 because actually no entries!!!
# cat per_cpu/cpu0/stats
entries: 1
[...]
read events: 0To fix it, introduce 'page_removed' field to count total removed pages since last reset, then use it to let read iterators reset themselves instead of changing the 'read' pointer.
--- kernel/trace/ring_buffer.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
kernel/trace/ring_buffer.c +12 -10
@@ -523,6 +523,8 @@ struct ring_buffer_per_cpu {rb_time_t before_stamp;u64 event_stamp[MAX_NEST ];u64 read_stamp; +/* pages removed since last reset */ +unsigned long pages_removed;/* ring buffer pages to update, > 0 to add, < 0 to remove */ long nr_pages_to_update;struct list_head new_pages;/* new pages to add */
@@ -558,6 +560,7 @@ struct ring_buffer_iter {struct buffer_page *head_page;struct buffer_page *cache_reader_page;unsigned long cache_read; +unsigned long cache_pages_removed;u64 read_stamp;u64 page_stamp;struct ring_buffer_event *event;
@@ -1956,6 +1959,8 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) to_remove =rb_list_head (to_remove)->next; head_bit |= (unsigned long )to_remove &RB_PAGE_HEAD ; } +/* Read iterators need to reset themselves when some pages removed */ + cpu_buffer->pages_removed += nr_removed; next_page =rb_list_head (to_remove)->next;
@@ -1977,12 +1982,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) cpu_buffer->head_page =list_entry (next_page, struct buffer_page, list); -/* -* change read pointer to make sure any read iterators reset -* themselves -*/ - cpu_buffer->read =0 ; -/* pages are removed, resume tracing and then free the pages */ atomic_dec (&cpu_buffer->record_disabled);raw_spin_unlock_irq (&cpu_buffer->reader_lock);
@@ -4392,6 +4391,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) iter->cache_reader_page = iter->head_page; iter->cache_read = cpu_buffer->read; + iter->cache_pages_removed = cpu_buffer->pages_removed;if (iter->head) { iter->read_stamp = cpu_buffer->read_stamp;
@@ -4846,12 +4846,13 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) buffer = cpu_buffer->buffer;/* -* Check if someone performed a consuming read to -* the buffer. A consuming read invalidates the iterator -* and we need to reset the iterator in this case. +* Check if someone performed a consuming read to the buffer +* or removed some pages from the buffer. In these cases, +* iterator was invalidated and we need to reset it. */ if (unlikely (iter->cache_read != cpu_buffer->read || - iter->cache_reader_page != cpu_buffer->reader_page)) + iter->cache_reader_page != cpu_buffer->reader_page || + iter->cache_pages_removed != cpu_buffer->pages_removed))rb_iter_reset (iter); again:
@@ -5295,6 +5296,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) cpu_buffer->last_overrun =0 ;rb_head_page_activate (cpu_buffer); + cpu_buffer->pages_removed =0 ; }/* Must have disabled the cpu buffer then done a synchronize_rcu */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 141/239 tracing: Fix warning in trace_buffered_event_disable()
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
[ Upstream commit dea499781a1150d285c62b26659f62fb00824fce ]
Warning happened in trace_buffered_event_disable() at
WARN_ON_ONCE(!trace_buffered_event_ref)
Call Trace: ? __warn+0xa5/0x1b0 ? trace_buffered_event_disable+0x189/0x1b0 __ftrace_event_enable_disable+0x19e/0x3e0 free_probe_data+0x3b/0xa0 unregister_ftrace_function_probe_func+0x6b8/0x800 event_enable_func+0x2f0/0x3d0 ftrace_process_regex.isra.0+0x12d/0x1b0 ftrace_filter_write+0xe6/0x140 vfs_write+0x1c9/0x6f0 [...]
The cause of the warning is in __ftrace_event_enable_disable(), trace_buffered_event_enable() was called once while trace_buffered_event_disable() was called twice. Reproduction script show as below, for analysis, see the comments:
```
#!/bin/bash
cd /sys/kernel/tracing/
# 1. Register a 'disable_event' command, then:
# 1) SOFT_DISABLED_BIT was set;
# 2) trace_buffered_event_enable() was called first time;
echo 'cmdline_proc_show:disable_event:initcall:initcall_finish' > \
set_ftrace_filter
# 2. Enable the event registered, then:
# 1) SOFT_DISABLED_BIT was cleared;
# 2) trace_buffered_event_disable() was called first time;
echo 1 > events/initcall/initcall_finish/enable
# 3. Try to call into cmdline_proc_show(), then SOFT_DISABLED_BIT was
# set again!!!
cat /proc/cmdline
# 4. Unregister the 'disable_event' command, then:
# 1) SOFT_DISABLED_BIT was cleared again;
# 2) trace_buffered_event_disable() was called second time!!!
echo '!cmdline_proc_show:disable_event:initcall:initcall_finish' > \
set_ftrace_filter
```To fix it, IIUC, we can change to call trace_buffered_event_enable() at fist time soft-mode enabled, and call trace_buffered_event_disable() at last time soft-mode disabled.
--- kernel/trace/trace_events.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
kernel/trace/trace_events.c +4 -10
@@ -611,7 +611,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, {struct trace_event_call *call = file->event_call;struct trace_array *tr = file->tr; -unsigned long file_flags = file->flags;int ret =0 ;int disable;
@@ -635,6 +634,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,break ; disable = file->flags &EVENT_FILE_FL_SOFT_DISABLED ;clear_bit (EVENT_FILE_FL_SOFT_MODE_BIT , &file->flags); +/* Disable use of trace_buffered_event */ +trace_buffered_event_disable (); }else disable = !(file->flags &EVENT_FILE_FL_SOFT_MODE );
@@ -673,6 +674,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,if (atomic_inc_return (&file->sm_ref) >1 )break ;set_bit (EVENT_FILE_FL_SOFT_MODE_BIT , &file->flags); +/* Enable use of trace_buffered_event */ +trace_buffered_event_enable (); }if (!(file->flags &EVENT_FILE_FL_ENABLED )) {
@@ -712,15 +715,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,break ; } -/* Enable or disable use of trace_buffered_event */ -if ((file_flags &EVENT_FILE_FL_SOFT_DISABLED ) != - (file->flags &EVENT_FILE_FL_SOFT_DISABLED )) { -if (file->flags &EVENT_FILE_FL_SOFT_DISABLED ) -trace_buffered_event_enable (); -else -trace_buffered_event_disable (); - } -return ret; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 142/239 Revert "usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()"
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit a8291be6b5dd465c22af229483dbac543a91e24e upstream.
This reverts commit f08aa7c80dac27ee00fa6827f447597d2fba5465.
The reverted commit was based on static analysis and a misunderstanding of how PTR_ERR() and NULLs are supposed to work. When a function returns both pointer errors and NULL then normally the NULL means "continue operating without a feature because it was deliberately turned off". The NULL should not be treated as a failure. If a driver cannot work when that feature is disabled then the KConfig should enforce that the function cannot return NULL. We should not need to test for it.
In this driver, the bug means that probe cannot succeed when CONFIG_PM is disabled.
--- drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/gadget/udc/tegra-xudc.c +4 -4
@@ -3718,15 +3718,15 @@ static int tegra_xudc_powerdomain_init(sint err; xudc->genpd_dev_device =dev_pm_domain_attach_by_name (dev,"dev" ); -if (IS_ERR_OR_NULL (xudc->genpd_dev_device)) { - err =PTR_ERR (xudc->genpd_dev_device) ? : -ENODATA ; +if (IS_ERR (xudc->genpd_dev_device)) { + err =PTR_ERR (xudc->genpd_dev_device);dev_err (dev,"failed to get device power domain: %d\n" , err);return err; } xudc->genpd_dev_ss =dev_pm_domain_attach_by_name (dev,"ss" ); -if (IS_ERR_OR_NULL (xudc->genpd_dev_ss)) { - err =PTR_ERR (xudc->genpd_dev_ss) ? : -ENODATA ; +if (IS_ERR (xudc->genpd_dev_ss)) { + err =PTR_ERR (xudc->genpd_dev_ss);dev_err (dev,"failed to get SuperSpeed power domain: %d\n" , err);return err; }
Greg Kroah-Hartman
maintainerPATCH 143/239 usb: gadget: call usb_gadget_check_config() to verify UDC capability
In reply to Greg Kroah-HartmanFrom: Frank Li <[email protected]>
commit f4fc01af5b640bc39bd9403b5fd855345a2ad5f8 upstream.
The legacy gadget driver omitted calling usb_gadget_check_config() to ensure that the USB device controller (UDC) has adequate resources, including sufficient endpoint numbers and types, to support the given configuration.
Previously, usb_add_config() was solely invoked by the legacy gadget driver. Adds the necessary usb_gadget_check_config() after the bind() operation to fix the issue.
--- drivers/usb/gadget/composite.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/gadget/composite.c +4 -0
@@ -1125,6 +1125,10 @@ int usb_add_config(struct usb_composite_ goto done; status =bind (config); + +if (status ==0 ) + status =usb_gadget_check_config (cdev->gadget); +if (status <0 ) {while (!list_empty (&config->functions)) {struct usb_function *f;
Greg Kroah-Hartman
maintainerPATCH 144/239 USB: gadget: Fix the memory leak in raw_gadget driver
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
commit 83e30f2bf86ef7c38fbd476ed81a88522b620628 upstream.
Currently, increasing raw_dev->count happens before invoke the raw_queue_event(), if the raw_queue_event() return error, invoke raw_release() will not trigger the dev_free() to be called.
[ 268.905865][ T5067] raw-gadget.0 gadget.0: failed to queue event [ 268.912053][ T5067] udc dummy_udc.0: failed to start USB Raw Gadget: -12 [ 268.918885][ T5067] raw-gadget.0: probe of gadget.0 failed with error -12 [ 268.925956][ T5067] UDC core: USB Raw Gadget: couldn't find an available UDC or it's busy [ 268.934657][ T5067] misc raw-gadget: fail, usb_gadget_register_driver returned -16
BUG: memory leak [<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [<ffffffff8347eb55>] kmalloc include/linux/slab.h:582 [inline] [<ffffffff8347eb55>] kzalloc include/linux/slab.h:703 [inline] [<ffffffff8347eb55>] dev_new drivers/usb/gadget/legacy/raw_gadget.c:191 [inline] [<ffffffff8347eb55>] raw_open+0x45/0x110 drivers/usb/gadget/legacy/raw_gadget.c:385 [<ffffffff827d1d09>] misc_open+0x1a9/0x1f0 drivers/char/misc.c:165 [<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [<ffffffff8347cd2f>] kmalloc include/linux/slab.h:582 [inline] [<ffffffff8347cd2f>] raw_ioctl_init+0xdf/0x410 drivers/usb/gadget/legacy/raw_gadget.c:460 [<ffffffff8347dfe9>] raw_ioctl+0x5f9/0x1120 drivers/usb/gadget/legacy/raw_gadget.c:1250 [<ffffffff81685173>] vfs_ioctl fs/ioctl.c:51 [inline] [<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [<ffffffff833ecc6a>] kmalloc include/linux/slab.h:582 [inline] [<ffffffff833ecc6a>] kzalloc include/linux/slab.h:703 [inline] [<ffffffff833ecc6a>] dummy_alloc_request+0x5a/0xe0 drivers/usb/gadget/udc/dummy_hcd.c:665 [<ffffffff833e9132>] usb_ep_alloc_request+0x22/0xd0 drivers/usb/gadget/udc/core.c:196 [<ffffffff8347f13d>] gadget_bind+0x6d/0x370 drivers/usb/gadget/legacy/raw_gadget.c:292
This commit therefore invoke kref_get() under the condition that raw_queue_event() return success.
--- drivers/usb/gadget/legacy/raw_gadget.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/gadget/legacy/raw_gadget.c +6 -4
@@ -310,13 +310,15 @@ static int gadget_bind(struct usb_gadget *gadget, dev->eps_num = i;spin_unlock_irqrestore (&dev->lock, flags); -/* Matches kref_put() in gadget_unbind(). */ -kref_get (&dev->count); - ret =raw_queue_event (dev,USB_RAW_EVENT_CONNECT ,0 ,NULL ); -if (ret <0 ) +if (ret <0 ) {dev_err (&gadget->dev,"failed to queue event\n" ); +set_gadget_data (gadget,NULL ); +return ret; + } +/* Matches kref_put() in gadget_unbind(). */ +kref_get (&dev->count);return ret; }
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 145/239 usb: gadget: core: remove unbalanced mutex_unlock in usb_gadget_activate
In reply to Greg Kroah-HartmanFrom: Michael Grzeschik <[email protected]>
commit 6237390644fb92b81f5262877fe545d0d2c7b5d7 upstream.
Commit 286d9975a838 ("usb: gadget: udc: core: Prevent soft_connect_store() race") introduced one extra mutex_unlock of connect_lock in the usb_gadget_active function.
--- drivers/usb/gadget/udc/core.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/gadget/udc/core.c +0 -1
@@ -878,7 +878,6 @@ int usb_gadget_activate(struct usb_gadge*/ if (gadget->connected) ret =usb_gadget_connect_locked (gadget); -mutex_unlock (&gadget->udc->connect_lock); unlock:mutex_unlock (&gadget->udc->connect_lock);
Greg Kroah-Hartman
maintainerPATCH 146/239 KVM: Grab a reference to KVM for VM and vCPU stats file descriptors
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit eed3013faa401aae662398709410a59bb0646e32 upstream.
Grab a reference to KVM prior to installing VM and vCPU stats file descriptors to ensure the underlying VM and vCPU objects are not freed until the last reference to any and all stats fds are dropped.
Note, the stats paths manually invoke fd_install() and so don't need to grab a reference before creating the file.
Message-Id: <[email protected]>
--- virt/kvm/kvm_main.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
virt/kvm/kvm_main.c +24 -0
@@ -4047,8 +4047,17 @@ static ssize_t kvm_vcpu_stats_read(struc sizeof(vcpu->stat), user_buffer, size, offset); } +static int kvm_vcpu_stats_release (struct inode *inode,struct file *file) +{ +struct kvm_vcpu *vcpu = file->private_data; + +kvm_put_kvm (vcpu->kvm); +return 0 ; +} +static const struct file_operations kvm_vcpu_stats_fops = { .read = kvm_vcpu_stats_read, + .release = kvm_vcpu_stats_release, .llseek = noop_llseek, };
@@ -4069,6 +4078,9 @@ static int kvm_vcpu_ioctl_get_stats_fd(sput_unused_fd (fd);return PTR_ERR (file); } + +kvm_get_kvm (vcpu->kvm); + file->f_mode |=FMODE_PREAD ;fd_install (fd, file);
@@ -4712,8 +4724,17 @@ static ssize_t kvm_vm_stats_read(struct sizeof(kvm->stat), user_buffer, size, offset); } +static int kvm_vm_stats_release (struct inode *inode,struct file *file) +{ +struct kvm *kvm = file->private_data; + +kvm_put_kvm (kvm); +return 0 ; +} +static const struct file_operations kvm_vm_stats_fops = { .read = kvm_vm_stats_read, + .release = kvm_vm_stats_release, .llseek = noop_llseek, };
@@ -4732,6 +4753,9 @@ static int kvm_vm_ioctl_get_stats_fd(strput_unused_fd (fd);return PTR_ERR (file); } + +kvm_get_kvm (kvm); + file->f_mode |=FMODE_PREAD ;fd_install (fd, file);
Greg Kroah-Hartman
maintainerPATCH 147/239 KVM: VMX: Dont fudge CR0 and CR4 for restricted L2 guest
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit c4abd7352023aa96114915a0bb2b88016a425cda upstream.
Stuff CR0 and/or CR4 to be compliant with a restricted guest if and only if KVM itself is not configured to utilize unrestricted guests, i.e. don't stuff CR0/CR4 for a restricted L2 that is running as the guest of an unrestricted L1. Any attempt to VM-Enter a restricted guest with invalid CR0/CR4 values should fail, i.e. in a nested scenario, KVM (as L0) should never observe a restricted L2 with incompatible CR0/CR4, since nested VM-Enter from L1 should have failed.
And if KVM does observe an active, restricted L2 with incompatible state, e.g. due to a KVM bug, fudging CR0/CR4 instead of letting VM-Enter fail does more harm than good, as KVM will often neglect to undo the side effects, e.g. won't clear rmode.vm86_active on nested VM-Exit, and thus the damage can easily spill over to L1. On the other hand, letting VM-Enter fail due to bad guest state is more likely to contain the damage to L2 as KVM relies on hardware to perform most guest state consistency checks, i.e. KVM needs to be able to reflect a failed nested VM-Enter into L1 irrespective of (un)restricted guest behavior.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/vmx.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
arch/x86/kvm/vmx/vmx.c +9 -4
@@ -1503,6 +1503,11 @@ void vmx_set_rflags(struct kvm_vcpu *vcpstruct vcpu_vmx *vmx =to_vmx (vcpu);unsigned long old_rflags; +/* +* Unlike CR0 and CR4, RFLAGS handling requires checking if the vCPU +* is an unrestricted guest in order to mark L2 as needing emulation +* if L1 runs L2 as a restricted guest. +*/ if (is_unrestricted_guest (vcpu)) {kvm_register_mark_available (vcpu,VCPU_EXREG_RFLAGS ); vmx->rflags = rflags;
@@ -3238,7 +3243,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, old_cr0_pg =kvm_read_cr0_bits (vcpu,X86_CR0_PG ); hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF ); -if (is_unrestricted_guest (vcpu)) +if (enable_unrestricted_guest) hw_cr0 |=KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST ;else { hw_cr0 |=KVM_VM_CR0_ALWAYS_ON ;
@@ -3266,7 +3271,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, }#endif -if (enable_ept && !is_unrestricted_guest (vcpu)) { +if (enable_ept && !enable_unrestricted_guest) {/* * Ensure KVM has an up-to-date snapshot of the guest's CR3. If * the below code _enables_ CR3 exiting, vmx_cache_reg() will
@@ -3397,7 +3402,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu,unsigned long hw_cr4; hw_cr4 = (cr4_read_shadow () &X86_CR4_MCE ) | (cr4 & ~X86_CR4_MCE ); -if (is_unrestricted_guest (vcpu)) +if (enable_unrestricted_guest) hw_cr4 |=KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST ;else if (vmx->rmode.vm86_active) hw_cr4 |=KVM_RMODE_VM_CR4_ALWAYS_ON ;
@@ -3417,7 +3422,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, vcpu->arch.cr4 = cr4;kvm_register_mark_available (vcpu,VCPU_EXREG_CR4 ); -if (!is_unrestricted_guest (vcpu)) { +if (!enable_unrestricted_guest) {if (enable_ept) {if (!is_paging (vcpu)) { hw_cr4 &= ~X86_CR4_PAE ;
Greg Kroah-Hartman
maintainerPATCH 148/239 KVM: x86: Disallow KVM_SET_SREGS{2} if incoming CR0 is invalid
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 26a0652cb453c72f6aab0974bc4939e9b14f886b upstream.
Reject KVM_SET_SREGS{2} with -EINVAL if the incoming CR0 is invalid, e.g. due to setting bits 63:32, illegal combinations, or to a value that isn't allowed in VMX (non-)root mode. The VMX checks in particular are "fun" as failure to disallow Real Mode for an L2 that is configured with unrestricted guest disabled, when KVM itself has unrestricted guest enabled, will result in KVM forcing VM86 mode to virtual Real Mode for L2, but then fail to unwind the related metadata when synthesizing a nested VM-Exit back to L1 (which has unrestricted guest enabled).
Opportunistically fix a benign typo in the prototype for is_valid_cr4().
Message-Id: <[email protected]>
--- arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/svm/svm.c | 6 ++++++ arch/x86/kvm/vmx/vmx.c | 28 +++++++++++++++++++++------- arch/x86/kvm/x86.c | 34 ++++++++++++++++++++++------------ 5 files changed, 52 insertions(+), 20 deletions(-)
arch/x86/include/asm/kvm-x86-ops.h +1 -0
@@ -37,6 +37,7 @@ KVM_X86_OP(get_segment) KVM_X86_OP(get_cpl) KVM_X86_OP(set_segment) KVM_X86_OP(get_cs_db_l_bits) +KVM_X86_OP(is_valid_cr0) KVM_X86_OP(set_cr0) KVM_X86_OP_OPTIONAL(post_set_cr3) KVM_X86_OP(is_valid_cr4)
arch/x86/include/asm/kvm_host.h +2 -1
@@ -1566,9 +1566,10 @@ struct kvm_x86_ops {void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg);void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu,int *db,int *l); +bool (*is_valid_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*post_set_cr3)(struct kvm_vcpu *vcpu,unsigned long cr3); -bool (*is_valid_cr4)(struct kvm_vcpu *vcpu,unsigned long cr0); +bool (*is_valid_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);int (*set_efer)(struct kvm_vcpu *vcpu,u64 efer);void (*get_idt)(struct kvm_vcpu *vcpu,struct desc_ptr *dt);
arch/x86/kvm/svm/svm.c +6 -0
@@ -1799,6 +1799,11 @@ static void sev_post_set_cr3(struct kvm_ } } +static bool svm_is_valid_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) +{ +return true; +} +void svm_set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) {struct vcpu_svm *svm =to_svm (vcpu);
@@ -4838,6 +4843,7 @@ static struct kvm_x86_ops svm_x86_ops __ .set_segment = svm_set_segment, .get_cpl = svm_get_cpl, .get_cs_db_l_bits = svm_get_cs_db_l_bits, + .is_valid_cr0 = svm_is_valid_cr0, .set_cr0 = svm_set_cr0, .post_set_cr3 = sev_post_set_cr3, .is_valid_cr4 = svm_is_valid_cr4,
arch/x86/kvm/vmx/vmx.c +21 -7
@@ -3045,6 +3045,15 @@ static void enter_rmode(struct kvm_vcpustruct vcpu_vmx *vmx =to_vmx (vcpu);struct kvm_vmx *kvm_vmx =to_kvm_vmx (vcpu->kvm); +/* +* KVM should never use VM86 to virtualize Real Mode when L2 is active, +* as using VM86 is unnecessary if unrestricted guest is enabled, and +* if unrestricted guest is disabled, VM-Enter (from L1) with CR0.PG=0 +* should VM-Fail and KVM should reject userspace attempts to stuff +* CR0.PG=0 when L2 is active. +*/ +WARN_ON_ONCE (is_guest_mode (vcpu)); +vmx_get_segment (vcpu, &vmx->rmode.segs[VCPU_SREG_TR ],VCPU_SREG_TR );vmx_get_segment (vcpu, &vmx->rmode.segs[VCPU_SREG_ES ],VCPU_SREG_ES );vmx_get_segment (vcpu, &vmx->rmode.segs[VCPU_SREG_DS ],VCPU_SREG_DS );
@@ -3234,6 +3243,17 @@ void ept_save_pdptrs(struct kvm_vcpu *vc#define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \ CPU_BASED_CR3_STORE_EXITING) +static bool vmx_is_valid_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) +{ +if (is_guest_mode (vcpu)) +return nested_guest_cr0_valid (vcpu, cr0); + +if (to_vmx (vcpu)->nested.vmxon) +return nested_host_cr0_valid (vcpu, cr0); + +return true; +} +void vmx_set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) {struct vcpu_vmx *vmx =to_vmx (vcpu);
@@ -5372,18 +5392,11 @@ static int handle_set_cr0(struct kvm_vcp val = (val & ~vmcs12->cr0_guest_host_mask) | (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); -if (!nested_guest_cr0_valid (vcpu, val)) -return 1 ; -if (kvm_set_cr0 (vcpu, val))return 1 ;vmcs_writel (CR0_READ_SHADOW , orig_val);return 0 ; }else { -if (to_vmx (vcpu)->nested.vmxon && - !nested_host_cr0_valid (vcpu, val)) -return 1 ; -return kvm_set_cr0 (vcpu, val); } }
@@ -8165,6 +8178,7 @@ static struct kvm_x86_ops vmx_x86_ops __ .set_segment = vmx_set_segment, .get_cpl = vmx_get_cpl, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, + .is_valid_cr0 = vmx_is_valid_cr0, .set_cr0 = vmx_set_cr0, .is_valid_cr4 = vmx_is_valid_cr4, .set_cr4 = vmx_set_cr4,
arch/x86/kvm/x86.c +22 -12
@@ -906,6 +906,22 @@ int load_pdptrs(struct kvm_vcpu *vcpu, u }EXPORT_SYMBOL_GPL (load_pdptrs); +static bool kvm_is_valid_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) +{ +#ifdef CONFIG_X86_64 +if (cr0 &0xffffffff00000000UL ) +return false; +#endif + +if ((cr0 &X86_CR0_NW ) && !(cr0 &X86_CR0_CD )) +return false; + +if ((cr0 &X86_CR0_PG ) && !(cr0 &X86_CR0_PE )) +return false; + +return static_call (kvm_x86_is_valid_cr0)(vcpu, cr0); +} +void kvm_post_set_cr0 (struct kvm_vcpu *vcpu,unsigned long old_cr0,unsigned long cr0) {/*
@@ -952,20 +968,13 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, u {unsigned long old_cr0 =kvm_read_cr0 (vcpu); - cr0 |=X86_CR0_ET ; - -#ifdef CONFIG_X86_64 -if (cr0 &0xffffffff00000000UL ) +if (!kvm_is_valid_cr0 (vcpu, cr0))return 1 ; -#endif - - cr0 &= ~CR0_RESERVED_BITS ; -if ((cr0 &X86_CR0_NW ) && !(cr0 &X86_CR0_CD )) -return 1 ; + cr0 |=X86_CR0_ET ; -if ((cr0 &X86_CR0_PG ) && !(cr0 &X86_CR0_PE )) -return 1 ; +/* Write to CR0 reserved bits are ignored, even on Intel. */ + cr0 &= ~CR0_RESERVED_BITS ;#ifdef CONFIG_X86_64 if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
@@ -11461,7 +11470,8 @@ static bool kvm_is_valid_sregs(struct kvreturn false; } -return kvm_is_valid_cr4 (vcpu, sregs->cr4); +return kvm_is_valid_cr4 (vcpu, sregs->cr4) && +kvm_is_valid_cr0 (vcpu, sregs->cr0); } static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
Greg Kroah-Hartman
maintainerPATCH 149/239 serial: qcom-geni: drop bogus runtime pm state update
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 4dd8752a14ca0303fbdf0a6c68ff65f0a50bd2fa upstream.
The runtime PM state should not be changed by drivers that do not implement runtime PM even if it happens to work around a bug in PM core.
With the wake irq arming now fixed, drop the bogus runtime PM state update which left the device in active state (and could potentially prevent a parent device from suspending).
--- drivers/tty/serial/qcom_geni_serial.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +0 -7
@@ -1676,13 +1676,6 @@ static int qcom_geni_serial_probe(structif (ret)return ret; -/* -* Set pm_runtime status as ACTIVE so that wakeup_irq gets -* enabled/disabled from dev_pm_arm_wake_irq during system -* suspend/resume respectively. -*/ -pm_runtime_set_active (&pdev->dev); -if (port->wakeup_irq >0 ) {device_init_wakeup (&pdev->dev, true); ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
Greg Kroah-Hartman
maintainerPATCH 150/239 tty: serial: sh-sci: Fix sleeping in atomic context
In reply to Greg Kroah-HartmanFrom: Biju Das <[email protected]>
commit 57c984f6fe20ebb9306d6e8c09b4f67fe63298c6 upstream.
Fix sleeping in atomic context warning as reported by the Smatch static checker tool by replacing disable_irq->disable_irq_nosync.
Reported by: Dan Carpenter <[email protected]>
--- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/sh-sci.c +1 -1
@@ -590,7 +590,7 @@ static void sci_start_tx(struct uart_port *port) dma_submit_error(s->cookie_tx)) {if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)/* Switch irq from SCIF to DMA */ -disable_irq (s->irqs[SCIx_TXI_IRQ]); +disable_irq_nosync (s->irqs[SCIx_TXI_IRQ]); s->cookie_tx =0 ;schedule_work (&s->work_tx);
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 151/239 serial: 8250_dw: Preserve original value of DLF register
In reply to Greg Kroah-HartmanFrom: Ruihong Luo <[email protected]>
commit 748c5ea8b8796ae8ee80b8d3a3d940570b588d59 upstream.
Preserve the original value of the Divisor Latch Fraction (DLF) register. When the DLF register is modified without preservation, it can disrupt the baudrate settings established by firmware or bootloader, leading to data corruption and the generation of unreadable or distorted characters.
--- drivers/tty/serial/8250/8250_dwlib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/tty/serial/8250/8250_dwlib.c +4 -2
@@ -244,7 +244,7 @@ void dw8250_setup_port(struct uart_portstruct dw8250_port_data *pd = p->private_data;struct dw8250_data *data =to_dw8250_data (pd);struct uart_8250_port *up =up_to_u8250p (p); -u32 reg; +u32 reg, old_dlf; pd->hw_rs485_support =dw8250_detect_rs485_hw (p);if (pd->hw_rs485_support) {
@@ -270,9 +270,11 @@ void dw8250_setup_port(struct uart_portdev_dbg (p->dev,"Designware UART version %c.%c%c\n" , (reg >>24 ) &0xff , (reg >>16 ) &0xff , (reg >>8 ) &0xff ); +/* Preserve value written by firmware or bootloader */ + old_dlf =dw8250_readl_ext (p,DW_UART_DLF );dw8250_writel_ext (p,DW_UART_DLF , ~0U ); reg =dw8250_readl_ext (p,DW_UART_DLF ); -dw8250_writel_ext (p,DW_UART_DLF ,0 ); +dw8250_writel_ext (p,DW_UART_DLF , old_dlf);if (reg) { pd->dlf_size =fls (reg);
Greg Kroah-Hartman
maintainerPATCH 152/239 serial: sifive: Fix sifive_serial_console_setup() section
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
commit 9b8fef6345d5487137d4193bb0a0eae2203c284e upstream.
This function is called indirectly from the platform driver probe function. Even if the driver is built in, it may be probed after free_initmem() due to deferral or unbinding/binding via sysfs. Thus the function cannot be marked as __init.
--- drivers/tty/serial/sifive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/sifive.c +1 -1
@@ -811,7 +811,7 @@ static void sifive_serial_console_write(local_irq_restore (flags); } -static int __init sifive_serial_console_setup (struct console *co,char *options) +static int sifive_serial_console_setup (struct console *co,char *options) {struct sifive_serial_port *ssp;int baud =SIFIVE_DEFAULT_BAUD_RATE ;
Greg Kroah-Hartman
maintainerPATCH 153/239 USB: serial: option: support Quectel EM060K_128
In reply to Greg Kroah-HartmanFrom: Jerry Meng <[email protected]>
commit 4f7cab49cecee16120d27c1734cfdf3d6c0e5329 upstream.
EM060K_128 is EM060K's sub-model, having the same name "Quectel EM060K-GL"
MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL
T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0128 Rev= 5.04 S: Manufacturer=Quectel S: Product=Quectel EM060K-GL S: SerialNumber=f6fa08b6 C:* #Ifs= 8 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E: Ad=8f(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/option.c +4 -0
@@ -251,6 +251,7 @@ static void option_instat_callback(struc#define QUECTEL_PRODUCT_EM061K_LTA 0x0123#define QUECTEL_PRODUCT_EM061K_LMS 0x0124#define QUECTEL_PRODUCT_EC25 0x0125 +#define QUECTEL_PRODUCT_EM060K_128 0x0128#define QUECTEL_PRODUCT_EG91 0x0191#define QUECTEL_PRODUCT_EG95 0x0195#define QUECTEL_PRODUCT_BG96 0x0296
@@ -1197,6 +1198,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) },
Greg Kroah-Hartman
maintainerPATCH 154/239 USB: serial: option: add Quectel EC200A module support
In reply to Greg Kroah-HartmanFrom: Mohsen Tahmasebi <[email protected]>
commit 857ea9005806e2a458016880278f98715873e977 upstream.
Add Quectel EC200A "DIAG, AT, MODEM":
0x6005: ECM / RNDIS + DIAG + AT + MODEM
T: Bus=01 Lev=01 Prnt=02 Port=05 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=6005 Rev=03.18 S: Manufacturer=Android S: Product=Android S: SerialNumber=0000 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -269,6 +269,7 @@ static void option_instat_callback(struc#define QUECTEL_PRODUCT_RM520N 0x0801#define QUECTEL_PRODUCT_EC200U 0x0901#define QUECTEL_PRODUCT_EC200S_CN 0x6002 +#define QUECTEL_PRODUCT_EC200A 0x6005#define QUECTEL_PRODUCT_EM061K_LWW 0x6008#define QUECTEL_PRODUCT_EM061K_LCN 0x6009#define QUECTEL_PRODUCT_EC200T 0x6026
@@ -1229,6 +1230,7 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */ .driver_info = ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
Greg Kroah-Hartman
maintainerPATCH 155/239 USB: serial: simple: add Kaufmann RKS+CAN VCP
In reply to Greg Kroah-HartmanFrom: Oliver Neukum <[email protected]>
commit dd92c8a1f99bcd166204ffc219ea5a23dd65d64f upstream.
Add the device and product ID for this CAN bus interface / license dongle. The device is usable either directly from user space or can be attached to a kernel CAN interface with slcan_attach.
--- drivers/usb/serial/usb-serial-simple.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/serial/usb-serial-simple.c +7 -0
@@ -63,6 +63,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) }DEVICE (google,GOOGLE_IDS ); +/* KAUFMANN RKS+CAN VCP */ +#define KAUFMANN_IDS () \ + { USB_DEVICE(0x16d0, 0x0870) } +DEVICE (kaufmann,KAUFMANN_IDS ); +/* Libtransistor USB console */ #define LIBTRANSISTOR_IDS () \ { USB_DEVICE(0x1209, 0x8b00) }
@@ -124,6 +129,7 @@ static struct usb_serial_driver * const &funsoft_device, &flashloader_device, &google_device, + &kaufmann_device, &libtransistor_device, &vivopay_device, &moto_modem_device,
@@ -142,6 +148,7 @@ static const struct usb_device_id id_tabFUNSOFT_IDS (),FLASHLOADER_IDS (),GOOGLE_IDS (), +KAUFMANN_IDS (),LIBTRANSISTOR_IDS (),VIVOPAY_IDS (), MOTO_IDS(),
Greg Kroah-Hartman
maintainerPATCH 156/239 USB: serial: simple: sort driver entries
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit d245aedc00775c4d7265a9f4522cc4e1fd34d102 upstream.
Sort the driver symbols alphabetically in order to make it more obvious where new driver entries should be added.
--- drivers/usb/serial/usb-serial-simple.c | 66 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-)
drivers/usb/serial/usb-serial-simple.c +33 -33
@@ -38,16 +38,6 @@ static struct usb_serial_driver vendor## { USB_DEVICE(0x0a21, 0x8001) } /* MMT-7305WW */DEVICE (carelink,CARELINK_IDS ); -/* ZIO Motherboard USB driver */ -#define ZIO_IDS () \ - { USB_DEVICE(0x1CBE, 0x0103) } -DEVICE (zio,ZIO_IDS ); - -/* Funsoft Serial USB driver */ -#define FUNSOFT_IDS () \ - { USB_DEVICE(0x1404, 0xcddc) } -DEVICE (funsoft,FUNSOFT_IDS ); -/* Infineon Flashloader driver */ #define FLASHLOADER_IDS () \ { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
@@ -55,6 +45,11 @@ DEVICE(funsoft, FUNSOFT_IDS); { USB_DEVICE(0x8087, 0x0801) }DEVICE (flashloader,FLASHLOADER_IDS ); +/* Funsoft Serial USB driver */ +#define FUNSOFT_IDS () \ + { USB_DEVICE(0x1404, 0xcddc) } +DEVICE (funsoft,FUNSOFT_IDS ); +/* Google Serial USB SubClass */ #define GOOGLE_IDS () \ { USB_VENDOR_AND_INTERFACE_INFO(0x18d1, \
@@ -63,6 +58,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) }DEVICE (google,GOOGLE_IDS ); +/* HP4x (48/49) Generic Serial driver */ +#define HP4X_IDS () \ + { USB_DEVICE(0x03f0, 0x0121) } +DEVICE (hp4x,HP4X_IDS ); +/* KAUFMANN RKS+CAN VCP */ #define KAUFMANN_IDS () \ { USB_DEVICE(0x16d0, 0x0870) }
@@ -73,11 +73,6 @@ DEVICE(kaufmann, KAUFMANN_IDS); { USB_DEVICE(0x1209, 0x8b00) }DEVICE (libtransistor,LIBTRANSISTOR_IDS ); -/* ViVOpay USB Serial Driver */ -#define VIVOPAY_IDS () \ - { USB_DEVICE(0x1d5f, 0x1004) }/* ViVOpay 8800 */ -DEVICE (vivopay,VIVOPAY_IDS ); -/* Motorola USB Phone driver */ #define MOTO_IDS () \ { USB_DEVICE(0x05c6, 0x3197) },/* unknown Motorola phone */ \
@@ -106,10 +101,10 @@ DEVICE(nokia, NOKIA_IDS); { USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */DEVICE_N (novatel_gps,NOVATEL_IDS ,3 ); -/* HP4x (48/49) Generic Serial driver */ -#define HP4X_IDS () \ - { USB_DEVICE(0x03f0, 0x0121) } -DEVICE (hp4x,HP4X_IDS ); +/* Siemens USB/MPI adapter */ +#define SIEMENS_IDS () \ + { USB_DEVICE(0x908, 0x0004) } +DEVICE (siemens_mpi,SIEMENS_IDS );/* Suunto ANT+ USB Driver */ #define SUUNTO_IDS () \
@@ -117,47 +112,52 @@ DEVICE(hp4x, HP4X_IDS); { USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */DEVICE (suunto,SUUNTO_IDS ); -/* Siemens USB/MPI adapter */ -#define SIEMENS_IDS () \ - { USB_DEVICE(0x908, 0x0004) } -DEVICE (siemens_mpi,SIEMENS_IDS ); +/* ViVOpay USB Serial Driver */ +#define VIVOPAY_IDS () \ + { USB_DEVICE(0x1d5f, 0x1004) }/* ViVOpay 8800 */ +DEVICE (vivopay,VIVOPAY_IDS ); + +/* ZIO Motherboard USB driver */ +#define ZIO_IDS () \ + { USB_DEVICE(0x1CBE, 0x0103) } +DEVICE (zio,ZIO_IDS );/* All of the above structures mushed into two lists */ static struct usb_serial_driver *const serial_drivers[] = { &carelink_device, - &zio_device, - &funsoft_device, &flashloader_device, + &funsoft_device, &google_device, + &hp4x_device, &kaufmann_device, &libtransistor_device, - &vivopay_device, &moto_modem_device, &motorola_tetra_device, &nokia_device, &novatel_gps_device, - &hp4x_device, - &suunto_device, &siemens_mpi_device, + &suunto_device, + &vivopay_device, + &zio_device,NULL };static const struct usb_device_id id_table[] = {CARELINK_IDS (), -ZIO_IDS (), -FUNSOFT_IDS (),FLASHLOADER_IDS (), +FUNSOFT_IDS (),GOOGLE_IDS (), +HP4X_IDS (),KAUFMANN_IDS (),LIBTRANSISTOR_IDS (), -VIVOPAY_IDS (),MOTO_IDS (),MOTOROLA_TETRA_IDS (),NOKIA_IDS (),NOVATEL_IDS (), -HP4X_IDS (), -SUUNTO_IDS (),SIEMENS_IDS (), +SUUNTO_IDS (), +VIVOPAY_IDS (), +ZIO_IDS (), { }, };MODULE_DEVICE_TABLE (usb, id_table);
Greg Kroah-Hartman
maintainerPATCH 157/239 can: gs_usb: gs_can_close(): add missing set of CAN state to CAN_STATE_STOPPED
In reply to Greg Kroah-HartmanFrom: Marc Kleine-Budde <[email protected]>
commit f8a2da6ec2417cca169fa85a8ab15817bccbb109 upstream.
After an initial link up the CAN device is in ERROR-ACTIVE mode. Due to a missing CAN_STATE_STOPPED in gs_can_close() it doesn't change to STOPPED after a link down:
| ip link set dev can0 up | ip link set dev can0 down | ip --details link show can0 | 13: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10 | link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0 | can state ERROR-ACTIVE restart-ms 1000
Add missing assignment of CAN_STATE_STOPPED in gs_can_close().
--- drivers/net/can/usb/gs_usb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/can/usb/gs_usb.c +2 -0
@@ -1030,6 +1030,8 @@ static int gs_can_close(struct net_devicusb_kill_anchored_urbs (&dev->tx_submitted);atomic_set (&dev->active_tx_urbs,0 ); + dev->can.state =CAN_STATE_STOPPED ; +/* reset the device */ rc =gs_cmd_reset (dev);if (rc <0 )
Greg Kroah-Hartman
maintainerPATCH 158/239 TIOCSTI: always enable for CAP_SYS_ADMIN
In reply to Greg Kroah-HartmanFrom: Samuel Thibault <[email protected]>
commit 690c8b804ad2eafbd35da5d3c95ad325ca7d5061 upstream.
83efeeeb3d04 ("tty: Allow TIOCSTI to be disabled") broke BRLTTY's ability to simulate keypresses on the console, thus effectively breaking braille keyboards of blind users.
This restores the TIOCSTI feature for CAP_SYS_ADMIN processes, which BRLTTY is, thus fixing braille keyboards without re-opening the security issue.
--- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/tty_io.c +1 -1
@@ -2276,7 +2276,7 @@ static int tiocsti(struct tty_struct *ttchar ch, mbz =0 ;struct tty_ldisc *ld; -if (!tty_legacy_tiocsti) +if (!tty_legacy_tiocsti && !capable (CAP_SYS_ADMIN ))return -EIO ;if ((current->signal->tty != tty) && !capable (CAP_SYS_ADMIN ))
Greg Kroah-Hartman
maintainerPATCH 159/239 usb: typec: Set port->pd before adding device for typec_port
In reply to Greg Kroah-HartmanFrom: Kyle Tso <[email protected]>
commit b33ebb2415e7e0a55ee3d049c2890d3a3e3805b6 upstream.
When calling device_add in the registration of typec_port, it will do the NULL check on usb_power_delivery handle in typec_port for the visibility of the device attributes. It is always NULL because port->pd is set in typec_port_set_usb_power_delivery which is later than the device_add call.
Set port->pd before device_add and only link the device after that.
--- drivers/usb/typec/class.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/typec/class.c +3 -1
@@ -2288,6 +2288,8 @@ struct typec_port *typec_register_port(sreturn ERR_PTR (ret); } + port->pd = cap->pd; + ret =device_add (&port->dev);if (ret) {dev_err (parent,"failed to register port (%d)\n" , ret);
@@ -2295,7 +2297,7 @@ struct typec_port *typec_register_port(sreturn ERR_PTR (ret); } - ret =typec_port_set_usb_power_delivery (port, cap->pd); + ret =usb_power_delivery_link_device (port->pd, &port->dev);if (ret) {dev_err (&port->dev,"failed to link pd\n" );device_unregister (&port->dev);
Greg Kroah-Hartman
maintainerPATCH 160/239 usb: typec: Iterate pds array when showing the pd list
In reply to Greg Kroah-HartmanFrom: Kyle Tso <[email protected]>
commit 4b642dc9829507e4afabc03d32a18abbdb192c5e upstream.
The pointers of each usb_power_delivery handles are stored in "pds" array returned from the pd_get ops but not in the adjacent memory calculated from "pd". Get the handles from "pds" array directly instead of deriving them from "pd".
--- drivers/usb/typec/class.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/usb/typec/class.c +5 -6
@@ -1277,8 +1277,7 @@ static ssize_t select_usb_power_delivery {struct typec_port *port =to_typec_port (dev);struct usb_power_delivery **pds; -struct usb_power_delivery *pd; -int ret =0 ; +int i, ret =0 ;if (!port->ops || !port->ops->pd_get)return -EOPNOTSUPP ;
@@ -1287,11 +1286,11 @@ static ssize_t select_usb_power_deliveryif (!pds)return 0 ; -for (pd = pds[0 ]; pd; pd++) { -if (pd == port->pd) - ret +=sysfs_emit (buf + ret,"[%s] " ,dev_name (&pd->dev)); +for (i =0 ; pds[i]; i++) { +if (pds[i] == port->pd) + ret +=sysfs_emit (buf + ret,"[%s] " ,dev_name (&pds[i]->dev));else - ret +=sysfs_emit (buf + ret,"%s " ,dev_name (&pd->dev)); + ret +=sysfs_emit (buf + ret,"%s " ,dev_name (&pds[i]->dev)); } buf[ret -1 ] ='\n' ;
Greg Kroah-Hartman
maintainerPATCH 161/239 usb: typec: Use sysfs_emit_at when concatenating the string
In reply to Greg Kroah-HartmanFrom: Kyle Tso <[email protected]>
commit 609fded3f91972ada551c141c5d04a71704f8967 upstream.
The buffer address used in sysfs_emit should be aligned to PAGE_SIZE. Use sysfs_emit_at instead to offset the buffer.
--- drivers/usb/typec/class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/typec/class.c +2 -2
@@ -1288,9 +1288,9 @@ static ssize_t select_usb_power_deliveryfor (i =0 ; pds[i]; i++) {if (pds[i] == port->pd) - ret +=sysfs_emit (buf + ret,"[%s] " ,dev_name (&pds[i]->dev)); + ret +=sysfs_emit_at (buf, ret,"[%s] " ,dev_name (&pds[i]->dev));else - ret +=sysfs_emit (buf + ret,"%s " ,dev_name (&pds[i]->dev)); + ret +=sysfs_emit_at (buf, ret,"%s " ,dev_name (&pds[i]->dev)); } buf[ret -1 ] ='\n' ;
Greg Kroah-Hartman
maintainerPATCH 162/239 Revert "usb: dwc3: core: Enable AutoRetry feature in the controller"
In reply to Greg Kroah-HartmanFrom: Jakub Vanek <[email protected]>
commit 734ae15ab95a18d3d425fc9cb38b7a627d786f08 upstream.
This reverts commit b138e23d3dff90c0494925b4c1874227b81bddf7.
AutoRetry has been found to sometimes cause controller freezes when communicating with buggy USB devices.
This controller feature allows the controller in host mode to send non-terminating/burst retry ACKs instead of terminating retry ACKs to devices when a transaction error (CRC error or overflow) occurs.
Unfortunately, if the USB device continues to respond with a CRC error, the controller will not complete endpoint-related commands while it keeps trying to auto-retry. [3] The xHCI driver will notice this once it tries to abort the transfer using a Stop Endpoint command and does not receive a completion in time. [1]
This situation is reported to dmesg:
[sda] tag#29 uas_eh_abort_handler 0 uas-tag 1 inflight: CMD IN [sda] tag#29 CDB: opcode=0x28 28 00 00 69 42 80 00 00 48 00
xhci-hcd: xHCI host not responding to stop endpoint command
xhci-hcd: xHCI host controller not responding, assume dead
xhci-hcd: HC died; cleaning up
Some users observed this problem on an Odroid HC2 with the JMS578 USB3-to-SATA bridge. The issue can be triggered by starting a read-heavy workload on an attached SSD. After a while, the host controller would die and the SSD would disappear from the system. [1]
Further analysis by Synopsys determined that controller revisions other than the one in Odroid HC2 are also affected by this. The recommended solution was to disable AutoRetry altogether. This change does not have a noticeable performance impact. [2]
Revert the enablement commit. This will keep the AutoRetry bit in the default state configured during SoC design [2].
--- drivers/usb/dwc3/core.c | 16 ---------------- drivers/usb/dwc3/core.h | 3 --- 2 files changed, 19 deletions(-)
drivers/usb/dwc3/core.c +0 -16
@@ -1209,22 +1209,6 @@ static int dwc3_core_init(struct dwc3 *ddwc3_writel (dwc->regs,DWC3_GUCTL1 , reg); } -if (dwc->dr_mode ==USB_DR_MODE_HOST || - dwc->dr_mode ==USB_DR_MODE_OTG ) { - reg =dwc3_readl (dwc->regs,DWC3_GUCTL ); - -/* -* Enable Auto retry Feature to make the controller operating in -* Host mode on seeing transaction errors(CRC errors or internal -* overrun scenerios) on IN transfers to reply to the device -* with a non-terminating retry ACK (i.e, an ACK transcation -* packet with Retry=1 & Nump != 0) -*/ - reg |=DWC3_GUCTL_HSTINAUTORETRY ; - -dwc3_writel (dwc->regs,DWC3_GUCTL , reg); - } -/* * Must config both number of packets and max burst settings to enable * RX and/or TX threshold.
drivers/usb/dwc3/core.h +0 -3
@@ -254,9 +254,6 @@#define DWC3_GCTL_GBLHIBERNATIONEN BIT(1)#define DWC3_GCTL_DSBLCLKGTNG BIT(0) -/* Global User Control Register */ -#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) -/* Global User Control 1 Register */ #define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31)#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
Greg Kroah-Hartman
maintainerPATCH 163/239 usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy
In reply to Greg Kroah-HartmanFrom: Gratian Crisan <[email protected]>
commit b32b8f2b9542d8039f5468303a6ca78c1b5611a5 upstream.
Hardware based on the Bay Trail / BYT SoCs require an external ULPI phy for USB device-mode. The phy chip usually has its 'reset' and 'chip select' lines connected to GPIOs described by ACPI fwnodes in the DSDT table.
Because of hardware with missing ACPI resources for the 'reset' and 'chip select' GPIOs commit 5741022cbdf3 ("usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources") introduced a fallback gpiod_lookup_table with hard-coded mappings for Bay Trail devices.
However there are existing Bay Trail based devices, like the National Instruments cRIO-903x series, where the phy chip has its 'reset' and 'chip-select' lines always asserted in hardware via resistor pull-ups. On this hardware the phy chip is always enabled and the ACPI dsdt table is missing information not only for the 'chip-select' and 'reset' lines but also for the BYT GPIO controller itself "INT33FC".
With the introduction of the gpiod_lookup_table initializing the USB device-mode on these hardware now errors out. The error comes from the gpiod_get_optional() calls in dwc3_pci_quirks() which will now return an -ENOENT error due to the missing ACPI entry for the INT33FC gpio controller used in the aforementioned table.
This hardware used to work before because gpiod_get_optional() will return NULL instead of -ENOENT if no GPIO has been assigned to the requested function. The dwc3_pci_quirks() code for setting the 'cs' and 'reset' GPIOs was then skipped (due to the NULL return). This is the correct behavior in cases where the phy chip is hardwired and there are no GPIOs to control.
Since the gpiod_lookup_table relies on the presence of INT33FC fwnode in ACPI tables only add the table if we know the entry for the INT33FC gpio controller is present. This allows Bay Trail based devices with hardwired dwc3 ULPI phys to continue working.
--- drivers/usb/dwc3/dwc3-pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/dwc3/dwc3-pci.c +4 -2
@@ -233,10 +233,12 @@ static int dwc3_pci_quirks(struct dwc3_p/* * A lot of BYT devices lack ACPI resource entries for -* the GPIOs, add a fallback mapping to the reference +* the GPIOs. If the ACPI entry for the GPIO controller +* is present add a fallback mapping to the reference * design GPIOs which all boards seem to use. */ -gpiod_add_lookup_table (&platform_bytcr_gpios); +if (acpi_dev_present ("INT33FC" ,NULL ,-1 )) +gpiod_add_lookup_table (&platform_bytcr_gpios);/* * These GPIOs will turn on the USB2 PHY. Note that we have to
Greg Kroah-Hartman
maintainerPATCH 164/239 usb: dwc3: dont reset device side if dwc3 was configured as host-only
In reply to Greg Kroah-HartmanFrom: Jisheng Zhang <[email protected]>
commit e835c0a4e23c38531dcee5ef77e8d1cf462658c7 upstream.
Commit c4a5153e87fd ("usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode") replaces check for HOST only dr_mode with current_dr_role. But during booting, the current_dr_role isn't initialized, thus the device side reset is always issued even if dwc3 was configured as host-only. What's more, on some platforms with host only dwc3, aways issuing device side reset by accessing device register block can cause kernel panic.
--- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/dwc3/core.c +2 -2
@@ -277,9 +277,9 @@ int dwc3_core_soft_reset(struct dwc3 *dw/* * We're resetting only the device side because, if we're in host mode, * XHCI driver will reset the host block. If dwc3 was configured for -* host-only mode, then we can return early. +* host-only mode or current role is host, then we can return early. */ -if (dwc->current_dr_role ==DWC3_GCTL_PRTCAP_HOST ) +if (dwc->dr_mode ==USB_DR_MODE_HOST || dwc->current_dr_role ==DWC3_GCTL_PRTCAP_HOST )return 0 ; reg =dwc3_readl (dwc->regs,DWC3_DCTL );
Greg Kroah-Hartman
maintainerPATCH 165/239 usb: misc: ehset: fix wrong if condition
In reply to Greg Kroah-HartmanFrom: Xu Yang <[email protected]>
commit 7f2327666a9080e428166964e37548b0168cd5e9 upstream.
A negative number from ret means the host controller had failed to send usb message and 0 means succeed. Therefore, the if logic is wrong here and this patch will fix it.
--- drivers/usb/misc/ehset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/misc/ehset.c +4 -4
@@ -77,7 +77,7 @@ static int ehset_probe(struct usb_interfswitch (test_pid) {case TEST_SE0_NAK_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
@@ -86,7 +86,7 @@ static int ehset_probe(struct usb_interfbreak ;case TEST_J_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
@@ -95,7 +95,7 @@ static int ehset_probe(struct usb_interfbreak ;case TEST_K_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
@@ -104,7 +104,7 @@ static int ehset_probe(struct usb_interfbreak ;case TEST_PACKET_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
Greg Kroah-Hartman
maintainerPATCH 166/239 usb: ohci-at91: Fix the unhandle interrupt when resume
In reply to Greg Kroah-HartmanFrom: Guiting Shen <[email protected]>
commit c55afcbeaa7a6f4fffdbc999a9bf3f0b29a5186f upstream.
The ohci_hcd_at91_drv_suspend() sets ohci->rh_state to OHCI_RH_HALTED when suspend which will let the ohci_irq() skip the interrupt after resume. And nobody to handle this interrupt.
According to the comment in ohci_hcd_at91_drv_suspend(), it need to reset when resume from suspend(MEM) to fix by setting "hibernated" argument of ohci_resume().
--- drivers/usb/host/ohci-at91.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/usb/host/ohci-at91.c +7 -1
@@ -673,7 +673,13 @@ ohci_hcd_at91_drv_resume(struct device *else at91_start_clock (ohci_at91); -ohci_resume (hcd, false); +/* +* According to the comment in ohci_hcd_at91_drv_suspend() +* we need to do a reset if the 48Mhz clock was stopped, +* that is, if ohci_at91->wakeup is clear. Tell ohci_resume() +* to reset in this case by setting its "hibernated" flag. +*/ +ohci_resume (hcd, !ohci_at91->wakeup);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 167/239 USB: quirks: add quirk for Focusrite Scarlett
In reply to Greg Kroah-HartmanFrom: Łukasz Bartosik <[email protected]>
commit 9dc162e22387080e2d06de708b89920c0e158c9a upstream.
The Focusrite Scarlett audio device does not behave correctly during resumes. Below is what happens during every resume (captured with Beagle 5000):
<Suspend>
<Resume>
<Reset>/<Chirp J>/<Tiny J>
<Reset/Target disconnected>
<High Speed>
The Scarlett disconnects and is enumerated again.
However from time to time it drops completely off the USB bus during resume. Below is captured occurrence of such an event:
<Suspend>
<Resume>
<Reset>/<Chirp J>/<Tiny J>
<Reset>/<Chirp K>/<Tiny K>
<High Speed>
<Corrupted packet>
<Reset/Target disconnected>
To fix the condition a user has to unplug and plug the device again.
With USB_QUIRK_RESET_RESUME applied ("usbcore.quirks=1235:8211:b") for the Scarlett audio device the issue still reproduces.
Applying USB_QUIRK_DISCONNECT_SUSPEND ("usbcore.quirks=1235:8211:m") fixed the issue and the Scarlett audio device didn't drop off the USB bus for ~5000 suspend/resume cycles where originally issue reproduced in ~100 or less suspend/resume cycles.
--- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/core/quirks.c +4 -0
@@ -436,6 +436,10 @@ static const struct usb_device_id usb_qu/* novation SoundControl XL */ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Focusrite Scarlett Solo USB */ + { USB_DEVICE(0x1235, 0x8211), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, + /* Huawei 4G LTE module */ { USB_DEVICE(0x12d1, 0x15bb), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND },
Greg Kroah-Hartman
maintainerPATCH 168/239 usb: cdns3: fix incorrect calculation of ep_buf_size when more than one config
In reply to Greg Kroah-HartmanFrom: Frank Li <[email protected]>
commit 2627335a1329a0d39d8d277994678571c4f21800 upstream.
Previously, the cdns3_gadget_check_config() function in the cdns3 driver mistakenly calculated the ep_buf_size by considering only one configuration's endpoint information because "claimed" will be clear after call usb_gadget_check_config().
The fix involves checking the private flags EP_CLAIMED instead of relying on the "claimed" flag.
--- drivers/usb/cdns3/cdns3-gadget.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/cdns3/cdns3-gadget.c +3 -1
@@ -3012,12 +3012,14 @@ static int cdns3_gadget_udc_stop(structstatic int cdns3_gadget_check_config (struct usb_gadget *gadget) {struct cdns3_device *priv_dev =gadget_to_cdns3_device (gadget); +struct cdns3_endpoint *priv_ep;struct usb_ep *ep;int n_in =0 ;int total;list_for_each_entry (ep, &gadget->ep_list, ep_list) { -if (ep->claimed && (ep->address &USB_DIR_IN )) + priv_ep =ep_to_cdns3_ep (ep); +if ((priv_ep->flags &EP_CLAIMED ) && (ep->address &USB_DIR_IN )) n_in++; }
Greg Kroah-Hartman
maintainerPATCH 169/239 usb: xhci-mtk: set the dma max_seg_size
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit 9fd10829a9eb482e192a845675ecc5480e0bfa10 upstream.
Allow devices to have dma operations beyond 64K, and avoid warnings such as:
DMA-API: xhci-mtk 11200000.usb: mapping sg segment longer than device claims to support [len=98304] [max=65536]
--- drivers/usb/host/xhci-mtk.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/host/xhci-mtk.c +1 -0
@@ -592,6 +592,7 @@ static int xhci_mtk_probe(struct platfor }device_init_wakeup (dev, true); +dma_set_max_seg_size (dev,UINT_MAX ); xhci =hcd_to_xhci (hcd); xhci->main_hcd = hcd;
Greg Kroah-Hartman
maintainerPATCH 170/239 Revert "usb: xhci: tegra: Fix error check"
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 288b4fa1798e3637a9304c6e90a93d900e02369c upstream.
This reverts commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f.
The reverted commit was based on static analysis and a misunderstanding of how PTR_ERR() and NULLs are supposed to work. When a function returns both pointer errors and NULL then normally the NULL means "continue operating without a feature because it was deliberately turned off". The NULL should not be treated as a failure. If a driver cannot work when that feature is disabled then the KConfig should enforce that the function cannot return NULL. We should not need to test for it.
In this code, the patch means that certain tegra_xusb_probe() will fail if the firmware supports power-domains but CONFIG_PM is disabled.
--- drivers/usb/host/xhci-tegra.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/host/xhci-tegra.c +4 -4
@@ -1145,15 +1145,15 @@ static int tegra_xusb_powerdomain_init(sint err; tegra->genpd_dev_host =dev_pm_domain_attach_by_name (dev,"xusb_host" ); -if (IS_ERR_OR_NULL (tegra->genpd_dev_host)) { - err =PTR_ERR (tegra->genpd_dev_host) ? : -ENODATA ; +if (IS_ERR (tegra->genpd_dev_host)) { + err =PTR_ERR (tegra->genpd_dev_host);dev_err (dev,"failed to get host pm-domain: %d\n" , err);return err; } tegra->genpd_dev_ss =dev_pm_domain_attach_by_name (dev,"xusb_ss" ); -if (IS_ERR_OR_NULL (tegra->genpd_dev_ss)) { - err =PTR_ERR (tegra->genpd_dev_ss) ? : -ENODATA ; +if (IS_ERR (tegra->genpd_dev_ss)) { + err =PTR_ERR (tegra->genpd_dev_ss);dev_err (dev,"failed to get superspeed pm-domain: %d\n" , err);return err; }
Greg Kroah-Hartman
maintainerPATCH 171/239 Documentation: security-bugs.rst: update preferences when dealing with the linux-distros group
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 4fee0915e649bd0cea56dece6d96f8f4643df33c upstream.
Because the linux-distros group forces reporters to release information about reported bugs, and they impose arbitrary deadlines in having those bugs fixed despite not actually being kernel developers, the kernel security team recommends not interacting with them at all as this just causes confusion and the early-release of reported security problems.
--- Documentation/process/security-bugs.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
Documentation/process/security-bugs.rst +11 -13
@@ -63,20 +63,18 @@ information submitted to the security li of the report are treated confidentially even after the embargo has been lifted, in perpetuity. -Coordination ------------- +Coordination with other groups +------------------------------ -Fixes for sensitive bugs, such as those that might lead to privilege -escalations, may need to be coordinated with the private -<[email protected]> mailing list so that distribution vendors -are well prepared to issue a fixed kernel upon public disclosure of the -upstream fix. Distros will need some time to test the proposed patch and -will generally request at least a few days of embargo, and vendor update -publication prefers to happen Tuesday through Thursday. When appropriate, -the security team can assist with this coordination, or the reporter can -include linux-distros from the start. In this case, remember to prefix -the email Subject line with "[vs]" as described in the linux-distros wiki: -<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists> +The kernel security team strongly recommends that reporters of potential +security issues NEVER contact the "linux-distros" mailing list until +AFTER discussing it with the kernel security team. Do not Cc: both +lists at once. You may contact the linux-distros mailing list after a +fix has been agreed on and you fully understand the requirements that +doing so will impose on you and the kernel community. + +The different lists have different goals and the linux-distros rules do +not contribute to actually fixing any potential security problems. CVE assignment --------------
Greg Kroah-Hartman
maintainerPATCH 172/239 Documentation: security-bugs.rst: clarify CVE handling
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 3c1897ae4b6bc7cc586eda2feaa2cd68325ec29c upstream.
The kernel security team does NOT assign CVEs, so document that properly and provide the "if you want one, ask MITRE for it" response that we give on a weekly basis in the document, so we don't have to constantly say it to everyone who asks.
--- Documentation/process/security-bugs.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
Documentation/process/security-bugs.rst +6 -7
@@ -79,13 +79,12 @@ not contribute to actually fixing any potential security problems. CVE assignment -------------- -The security team does not normally assign CVEs, nor do we require them -for reports or fixes, as this can needlessly complicate the process and -may delay the bug handling. If a reporter wishes to have a CVE identifier -assigned ahead of public disclosure, they will need to contact the private -linux-distros list, described above. When such a CVE identifier is known -before a patch is provided, it is desirable to mention it in the commit -message if the reporter agrees. +The security team does not assign CVEs, nor do we require them for +reports or fixes, as this can needlessly complicate the process and may +delay the bug handling. If a reporter wishes to have a CVE identifier +assigned, they should find one by themselves, for example by contacting +MITRE directly. However under no circumstances will a patch inclusion +be delayed to wait for a CVE identifier to arrive. Non-disclosure agreements -------------------------
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 173/239 staging: r8712: Fix memory leak in _r8712_init_xmit_priv()
In reply to Greg Kroah-HartmanFrom: Larry Finger <[email protected]>
commit ac83631230f77dda94154ed0ebfd368fc81c70a3 upstream.
In the above mentioned routine, memory is allocated in several places. If the first succeeds and a later one fails, the routine will leak memory. This patch fixes commit 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel"). A potential memory leak in r8712_xmit_resource_alloc() is also addressed.
--- drivers/staging/rtl8712/rtl871x_xmit.c | 43 ++++++++++++++++++++++++++------- drivers/staging/rtl8712/xmit_linux.c | 6 ++++ 2 files changed, 40 insertions(+), 9 deletions(-)
drivers/staging/rtl8712/rtl871x_xmit.c +34 -9
@@ -21,6 +21,7 @@#include "osdep_intf.h" #include "usb_ops.h" +#include <linux/usb.h> #include <linux/ieee80211.h> static const u8 P802_1H_OUI [P80211_OUI_LEN ] = {0x00 ,0x00 ,0xf8 };
@@ -55,6 +56,7 @@ int _r8712_init_xmit_priv(struct xmit_prsint i;struct xmit_buf *pxmitbuf;struct xmit_frame *pxframe; +int j;memset ((unsigned char *)pxmitpriv,0 ,sizeof (struct xmit_priv ));spin_lock_init (&pxmitpriv->lock);
@@ -117,11 +119,8 @@ int _r8712_init_xmit_priv(struct xmit_pr_init_queue (&pxmitpriv->pending_xmitbuf_queue); pxmitpriv->pallocated_xmitbuf =kmalloc (NR_XMITBUFF *sizeof (struct xmit_buf ) +4 ,GFP_ATOMIC ); -if (!pxmitpriv->pallocated_xmitbuf) { -kfree (pxmitpriv->pallocated_frame_buf); - pxmitpriv->pallocated_frame_buf =NULL ; -return -ENOMEM ; - } +if (!pxmitpriv->pallocated_xmitbuf) + goto clean_up_frame_buf; pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf +4 - ((addr_t)(pxmitpriv->pallocated_xmitbuf) &3 ); pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
@@ -129,13 +128,17 @@ int _r8712_init_xmit_priv(struct xmit_prINIT_LIST_HEAD (&pxmitbuf->list); pxmitbuf->pallocated_buf =kmalloc (MAX_XMITBUF_SZ +XMITBUF_ALIGN_SZ ,GFP_ATOMIC ); -if (!pxmitbuf->pallocated_buf) -return -ENOMEM ; +if (!pxmitbuf->pallocated_buf) { + j =0 ; + goto clean_up_alloc_buf; + } pxmitbuf->pbuf = pxmitbuf->pallocated_buf +XMITBUF_ALIGN_SZ - ((addr_t) (pxmitbuf->pallocated_buf) & (XMITBUF_ALIGN_SZ -1 )); -if (r8712_xmit_resource_alloc (padapter, pxmitbuf)) -return -ENOMEM ; +if (r8712_xmit_resource_alloc (padapter, pxmitbuf)) { + j =1 ; + goto clean_up_alloc_buf; + }list_add_tail (&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue)); pxmitbuf++;
@@ -146,6 +149,28 @@ int _r8712_init_xmit_priv(struct xmit_prinit_hwxmits (pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);tasklet_setup (&pxmitpriv->xmit_tasklet, r8712_xmit_bh);return 0 ; + +clean_up_alloc_buf: +if (j) { +/* failure happened in r8712_xmit_resource_alloc() +* delete extra pxmitbuf->pallocated_buf +*/ +kfree (pxmitbuf->pallocated_buf); + } +for (j =0 ; j < i; j++) { +int k; + + pxmitbuf--;/* reset pointer */ +kfree (pxmitbuf->pallocated_buf); +for (k =0 ; k <8 ; k++)/* delete xmit urb's */ +usb_free_urb (pxmitbuf->pxmit_urb[k]); + } +kfree (pxmitpriv->pallocated_xmitbuf); + pxmitpriv->pallocated_xmitbuf =NULL ; +clean_up_frame_buf: +kfree (pxmitpriv->pallocated_frame_buf); + pxmitpriv->pallocated_frame_buf =NULL ; +return -ENOMEM ; }void _free_xmit_priv (struct xmit_priv *pxmitpriv)
drivers/staging/rtl8712/xmit_linux.c +6 -0
@@ -112,6 +112,12 @@ int r8712_xmit_resource_alloc(struct _adfor (i =0 ; i <8 ; i++) { pxmitbuf->pxmit_urb[i] =usb_alloc_urb (0 ,GFP_KERNEL );if (!pxmitbuf->pxmit_urb[i]) { +int k; + +for (k = i -1 ; k >=0 ; k--) { +/* handle allocation errors part way through loop */ +usb_free_urb (pxmitbuf->pxmit_urb[k]); + }netdev_err (padapter->pnetdev,"pxmitbuf->pxmit_urb[i] == NULL\n" );return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 174/239 staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext()
In reply to Greg Kroah-HartmanFrom: Zhang Shurong <[email protected]>
commit 5f1c7031e044cb2fba82836d55cc235e2ad619dc upstream.
The "exc->key_len" is a u16 that comes from the user. If it's over IW_ENCODING_TOKEN_MAX (64) that could lead to memory corruption.
--- drivers/staging/ks7010/ks_wlan_net.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/staging/ks7010/ks_wlan_net.c +4 -2
@@ -1583,8 +1583,10 @@ static int ks_wlan_set_encode_ext(struct commit |=SME_WEP_FLAG ; }if (enc->key_len) { -memcpy (&key->key_val[0 ], &enc->key[0 ], enc->key_len); - key->key_len = enc->key_len; +int key_len =clamp_val (enc->key_len,0 ,IW_ENCODING_TOKEN_MAX ); + +memcpy (&key->key_val[0 ], &enc->key[0 ], key_len); + key->key_len = key_len; commit |= (SME_WEP_VAL1 << index); }break ;
Greg Kroah-Hartman
maintainerPATCH 175/239 tty: n_gsm: fix UAF in gsm_cleanup_mux
In reply to Greg Kroah-HartmanFrom: Chaoyuan Peng <[email protected]>
commit 9b9c8195f3f0d74a826077fc1c01b9ee74907239 upstream.
In gsm_cleanup_mux() the 'gsm->dlci' pointer was not cleaned properly, leaving it a dangling pointer after gsm_dlci_release.
This leads to use-after-free where 'gsm->dlci[0]' are freed and accessed by the subsequent gsm_cleanup_mux().
Such is the case in the following call trace:
<TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e3/0x2cb lib/dump_stack.c:106 print_address_description+0x63/0x3b0 mm/kasan/report.c:248 __kasan_report mm/kasan/report.c:434 [inline] kasan_report+0x16b/0x1c0 mm/kasan/report.c:451 gsm_cleanup_mux+0x76a/0x850 drivers/tty/n_gsm.c:2397 gsm_config drivers/tty/n_gsm.c:2653 [inline] gsmld_ioctl+0xaae/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb </TASK> Allocated by task 3501: kasan_save_stack mm/kasan/common.c:38 [inline] kasan_set_track mm/kasan/common.c:46 [inline] set_alloc_info mm/kasan/common.c:434 [inline] ____kasan_kmalloc+0xba/0xf0 mm/kasan/common.c:513 kasan_kmalloc include/linux/kasan.h:264 [inline] kmem_cache_alloc_trace+0x143/0x290 mm/slub.c:3247 kmalloc include/linux/slab.h:591 [inline] kzalloc include/linux/slab.h:721 [inline] gsm_dlci_alloc+0x53/0x3a0 drivers/tty/n_gsm.c:1932 gsm_activate_mux+0x1c/0x330 drivers/tty/n_gsm.c:2438 gsm_config drivers/tty/n_gsm.c:2677 [inline] gsmld_ioctl+0xd46/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb Freed by task 3501: kasan_save_stack mm/kasan/common.c:38 [inline] kasan_set_track+0x4b/0x80 mm/kasan/common.c:46 kasan_set_free_info+0x1f/0x40 mm/kasan/generic.c:360 ____kasan_slab_free+0xd8/0x120 mm/kasan/common.c:366 kasan_slab_free include/linux/kasan.h:230 [inline] slab_free_hook mm/slub.c:1705 [inline] slab_free_freelist_hook+0xdd/0x160 mm/slub.c:1731 slab_free mm/slub.c:3499 [inline] kfree+0xf1/0x270 mm/slub.c:4559 dlci_put drivers/tty/n_gsm.c:1988 [inline] gsm_dlci_release drivers/tty/n_gsm.c:2021 [inline] gsm_cleanup_mux+0x574/0x850 drivers/tty/n_gsm.c:2415 gsm_config drivers/tty/n_gsm.c:2653 [inline] gsmld_ioctl+0xaae/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb
--- drivers/tty/n_gsm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/tty/n_gsm.c +3 -1
@@ -3070,8 +3070,10 @@ static void gsm_cleanup_mux(struct gsm_m gsm->has_devices = false; }for (i =NUM_DLCI -1 ; i >=0 ; i--) -if (gsm->dlci[i]) +if (gsm->dlci[i]) {gsm_dlci_release (gsm->dlci[i]); + gsm->dlci[i] =NULL ; + }mutex_unlock (&gsm->mutex);/* Now wipe the queues */ tty_ldisc_flush (gsm->tty);
Greg Kroah-Hartman
maintainerPATCH 176/239 Revert "xhci: add quirk for host controllers that dont update endpoint DCS"
In reply to Greg Kroah-HartmanFrom: Oliver Neukum <[email protected]>
commit 5bef4b3cb95a5b883dfec8b3ffc0d671323d55bb upstream.
This reverts commit 5255660b208aebfdb71d574f3952cf48392f4306.
This quirk breaks at least the following hardware:
0b:00.0 0c03: 1106:3483 (rev 01) (prog-if 30 [XHCI])
Subsystem: 1106:3483
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 66
Region 0: Memory at fb400000 (64-bit, non-prefetchable) [size=4K]
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/4 Maskable- 64bit+
Address: 00000000fee007b8 Data: 0000
Capabilities: [c4] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 89W
DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <2us, L1 <16us
ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp-
LnkCtl: ASPM Disabled; RCB 64 bytes, Disabled- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 5GT/s, Width x1
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range B, TimeoutDis+ NROPrPrP- LTR-
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix- EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit- FRS- TPHComp- ExtTPHComp-
AtomicOpsCap: 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- LTR- 10BitTagReq- OBFF Disabled,
AtomicOpsCtl: ReqEn-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS- Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest- Retimer- 2Retimers- CrosslinkRes: unsupported
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
Kernel driver in use: xhci_hcd
Kernel modules: xhci_pci
with the quirk enabled it fails early with
[ 0.754373] pci 0000:0b:00.0: xHCI HW did not halt within 32000 usec status = 0x1000 [ 0.754419] pci 0000:0b:00.0: quirk_usb_early_handoff+0x0/0x7a0 took 31459 usecs [ 2.228048] xhci_hcd 0000:0b:00.0: xHCI Host Controller [ 2.228053] xhci_hcd 0000:0b:00.0: new USB bus registered, assigned bus number 7 [ 2.260073] xhci_hcd 0000:0b:00.0: Host halt failed, -110 [ 2.260079] xhci_hcd 0000:0b:00.0: can't setup: -110 [ 2.260551] xhci_hcd 0000:0b:00.0: USB bus 7 deregistered [ 2.260624] xhci_hcd 0000:0b:00.0: init 0000:0b:00.0 fail, -110 [ 2.260639] xhci_hcd: probe of 0000:0b:00.0 failed with error -110
The hardware in question is an external PCIe card. It looks to me like the quirk needs to be narrowed down. But this needs information about the hardware showing the issue this quirk is to fix. So for now a clean revert.
--- drivers/usb/host/xhci-pci.c | 4 +--- drivers/usb/host/xhci-ring.c | 25 +------------------------ 2 files changed, 2 insertions(+), 27 deletions(-)
drivers/usb/host/xhci-pci.c +1 -3
@@ -486,10 +486,8 @@ static void xhci_pci_quirks(struct devic pdev->device == 0x3432) xhci->quirks |=XHCI_BROKEN_STREAMS ; -if (pdev->vendor ==PCI_VENDOR_ID_VIA && pdev->device ==0x3483 ) { +if (pdev->vendor ==PCI_VENDOR_ID_VIA && pdev->device ==0x3483 ) xhci->quirks |=XHCI_LPM_SUPPORT ; - xhci->quirks |=XHCI_EP_CTX_BROKEN_DCS ; - }if (pdev->vendor ==PCI_VENDOR_ID_ASMEDIA && pdev->device ==PCI_DEVICE_ID_ASMEDIA_1042_XHCI ) {
drivers/usb/host/xhci-ring.c +1 -24
@@ -592,11 +592,8 @@ static int xhci_move_dequeue_past_td(strstruct xhci_ring *ep_ring;struct xhci_command *cmd;struct xhci_segment *new_seg; -struct xhci_segment *halted_seg =NULL ;union xhci_trb *new_deq;int new_cycle; -union xhci_trb *halted_trb; -int index =0 ;dma_addr_t addr;u64 hw_dequeue;bool cycle_found = false;
@@ -634,27 +631,7 @@ static int xhci_move_dequeue_past_td(str hw_dequeue =xhci_get_hw_deq (xhci, dev, ep_index, stream_id); new_seg = ep_ring->deq_seg; new_deq = ep_ring->dequeue; - -/* -* Quirk: xHC write-back of the DCS field in the hardware dequeue -* pointer is wrong - use the cycle state of the TRB pointed to by -* the dequeue pointer. -*/ -if (xhci->quirks &XHCI_EP_CTX_BROKEN_DCS && - !(ep->ep_state &EP_HAS_STREAMS )) - halted_seg =trb_in_td (xhci, td->start_seg, - td->first_trb, td->last_trb, - hw_dequeue & ~0xf , false); -if (halted_seg) { - index = ((dma_addr_t)(hw_dequeue & ~0xf ) - halted_seg->dma) / -sizeof (*halted_trb); - halted_trb = &halted_seg->trbs[index]; - new_cycle = halted_trb->generic.field[3 ] &0x1 ; -xhci_dbg (xhci,"Endpoint DCS = %d TRB index = %d cycle = %d\n" , - (u8)(hw_dequeue &0x1 ), index, new_cycle); - }else { - new_cycle = hw_dequeue &0x1 ; - } + new_cycle = hw_dequeue &0x1 ;/* * We want to find the pointer, segment and cycle state of the new trb
Greg Kroah-Hartman
maintainerPATCH 177/239 ALSA: hda/realtek: Support ASUS G713PV laptop
In reply to Greg Kroah-HartmanFrom: Pavel Asyutchenko <[email protected]>
commit 8019a4ab3d80c7af391a646cccff953753fc025f upstream.
This laptop has CS35L41 amp connected via I2C.
With this patch speakers begin to work if the
missing _DSD properties are added to ACPI tables.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9628,6 +9628,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x1c92 ,"ASUS ROG Strix G15" ,ALC285_FIXUP_ASUS_G533Z_PINS ),SND_PCI_QUIRK (0x1043 ,0x1caf ,"ASUS G634JYR/JZR" ,ALC285_FIXUP_ASUS_HEADSET_MIC ),SND_PCI_QUIRK (0x1043 ,0x1ccd ,"ASUS X555UB" ,ALC256_FIXUP_ASUS_MIC ), +SND_PCI_QUIRK (0x1043 ,0x1d1f ,"ASUS ROG Strix G17 2023 (G713PV)" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x1043 ,0x1d42 ,"ASUS Zephyrus G14 2022" ,ALC289_FIXUP_ASUS_GA401 ),SND_PCI_QUIRK (0x1043 ,0x1d4e ,"ASUS TM420" ,ALC256_FIXUP_ASUS_HPE ), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2),
Greg Kroah-Hartman
maintainerPATCH 178/239 ALSA: hda/relatek: Enable Mute LED on HP 250 G8
In reply to Greg Kroah-HartmanFrom: Luka Guzenko <[email protected]>
commit d510acb610e6aa07a04b688236868b2a5fd60deb upstream.
This HP Notebook used ALC236 codec with COEF 0x07 idx 1 controlling the mute LED. Enable already existing quirk for this device.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9502,6 +9502,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x880d ,"HP EliteBook 830 G8 Notebook PC" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8811 ,"HP Spectre x360 15-eb1xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ),SND_PCI_QUIRK (0x103c ,0x8812 ,"HP Spectre x360 15-eb1xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ), +SND_PCI_QUIRK (0x103c ,0x881d ,"HP 250 G8 Notebook PC" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x8846 ,"HP EliteBook 850 G8 Notebook PC" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8847 ,"HP EliteBook x360 830 G8 Notebook PC" ,ALC285_FIXUP_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 179/239 hwmon: (k10temp) Enable AMD3255 Proc to show negative temperature
In reply to Greg Kroah-HartmanFrom: Baskaran Kannan <[email protected]>
commit e146503ac68418859fb063a3a0cd9ec93bc52238 upstream.
Industrial processor i3255 supports temperatures -40 deg celcius to 105 deg Celcius. The current implementation of k10temp_read_temp rounds off any negative temperatures to '0'. To fix this, the following changes have been made.
A flag 'disp_negative' is added to struct k10temp_data to support AMD i3255 processors. Flag 'disp_negative' is set if 3255 processor is found during k10temp_probe. Flag 'disp_negative' is used to determine whether to round off negative temperatures to '0' in k10temp_read_temp.
--- drivers/hwmon/k10temp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/hwmon/k10temp.c +15 -2
@@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);#define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19)#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16) +/* +* AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius. +* Use the model name to identify 3255 CPUs and set a flag to display negative temperature. +* Do not round off to zero for negative Tctl or Tdie values if the flag is set +*/ +#define AMD_I3255_STR "3255" +struct k10temp_data {struct pci_dev *pdev;void (*read_htcreg)(struct pci_dev *pdev,u32 *regval);
@@ -86,6 +93,7 @@ struct k10temp_data {u32 show_temp;bool is_zen;u32 ccd_offset; +bool disp_negative; };#define TCTL_BIT 0
@@ -204,12 +212,12 @@ static int k10temp_read_temp(struct deviswitch (channel) {case 0 :/* Tctl */ *val =get_raw_temp (data); -if (*val <0 ) +if (*val <0 && !data->disp_negative) *val =0 ;break ;case 1 :/* Tdie */ *val =get_raw_temp (data) - data->temp_offset; -if (*val <0 ) +if (*val <0 && !data->disp_negative) *val =0 ;break ; case 2 ... 13: /* Tccd{1-12} */
@@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev data->pdev = pdev; data->show_temp |=BIT (TCTL_BIT );/* Always show Tctl */ +if (boot_cpu_data.x86 ==0x17 && +strstr (boot_cpu_data.x86_model_id,AMD_I3255_STR )) { + data->disp_negative = true; + } +if (boot_cpu_data.x86 ==0x15 && ((boot_cpu_data.x86_model &0xf0 ) ==0x60 || (boot_cpu_data.x86_model &0xf0 ) ==0x70 )) {
Greg Kroah-Hartman
maintainerPATCH 180/239 hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled
In reply to Greg Kroah-HartmanFrom: Gilles Buloz <[email protected]>
commit 54685abe660a59402344d5045ce08c43c6a5ac42 upstream.
Because of hex value 0x46 used instead of decimal 46, the temp6 (PECI1) temperature is always declared visible and then displayed even if disabled in the chip
--- drivers/hwmon/nct7802.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/nct7802.c +1 -1
@@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(sif (index >=38 && index <46 && !(reg &0x01 ))/* PECI 0 */ return 0 ; -if (index >=0x46 && (!(reg &0x02 )))/* PECI 1 */ +if (index >=46 && !(reg &0x02 ))/* PECI 1 */ return 0 ;return attr->mode;
Greg Kroah-Hartman
maintainerPATCH 181/239 hwmon: (aquacomputer_d5next) Fix incorrect PWM value readout
In reply to Greg Kroah-HartmanFrom: Aleksa Savic <[email protected]>
commit a746b3689546da27125da9ccaea62b1dbaaf927c upstream.
Commit 662d20b3a5af ("hwmon: (aquacomputer_d5next) Add support for temperature sensor offsets") changed aqc_get_ctrl_val() to return the value through a parameter instead of through the return value, but didn't fix up a case that relied on the old behavior. Fix it to use the proper received value and not the return code.
--- drivers/hwmon/aquacomputer_d5next.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/aquacomputer_d5next.c +1 -1
@@ -969,7 +969,7 @@ static int aqc_read(struct device *dev,if (ret <0 )return ret; - *val =aqc_percent_to_pwm (ret); + *val =aqc_percent_to_pwm (*val);break ; }break ;
Greg Kroah-Hartman
maintainerPATCH 182/239 hwmon: (pmbus_core) Fix pmbus_is_enabled()
In reply to Greg Kroah-HartmanFrom: Patrick Rudolph <[email protected]>
commit 55aab08f1856894d7d47d0ee23abbb4bc4854345 upstream.
Refactor pmbus_is_enabled() to return the status without any additional processing as it is already done in _pmbus_is_enabled().
--- drivers/hwmon/pmbus/pmbus_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/pmbus/pmbus_core.c +1 -1
@@ -2768,7 +2768,7 @@ static int __maybe_unused pmbus_is_enabled(struct device *dev, u8 page) ret =_pmbus_is_enabled (dev, page);mutex_unlock (&data->update_lock); -return !!(ret &PB_OPERATION_CONTROL_ON ); +return ret; }#define to_dev_attr (_dev_attr) \
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 183/239 hwmon: (pmbus_core) Fix NULL pointer dereference
In reply to Greg Kroah-HartmanFrom: Patrick Rudolph <[email protected]>
commit 0bd66784274a287beada2933c2c0fa3a0ddae0d7 upstream.
Pass i2c_client to _pmbus_is_enabled to drop the assumption that a regulator device is passed in.
This will fix the issue of a NULL pointer dereference when called from _pmbus_get_flags.
--- drivers/hwmon/pmbus/pmbus_core.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/hwmon/pmbus/pmbus_core.c +8 -7
@@ -2745,9 +2745,8 @@ static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] }, }; -static int _pmbus_is_enabled (struct device *dev,u8 page) +static int _pmbus_is_enabled (struct i2c_client *client,u8 page) { -struct i2c_client *client =to_i2c_client (dev->parent);int ret; ret =_pmbus_read_byte_data (client, page,PMBUS_OPERATION );
@@ -2758,14 +2757,13 @@ static int _pmbus_is_enabled(struct device *dev, u8 page)return !!(ret &PB_OPERATION_CONTROL_ON ); } -static int __maybe_unused pmbus_is_enabled (struct device *dev,u8 page) +static int __maybe_unused pmbus_is_enabled (struct i2c_client *client,u8 page) { -struct i2c_client *client =to_i2c_client (dev->parent);struct pmbus_data *data =i2c_get_clientdata (client);int ret;mutex_lock (&data->update_lock); - ret =_pmbus_is_enabled (dev, page); + ret =_pmbus_is_enabled (client, page);mutex_unlock (&data->update_lock);return ret;
@@ -2844,7 +2842,7 @@ static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flagif (status <0 )return status; -if (_pmbus_is_enabled (dev, page)) { +if (_pmbus_is_enabled (client, page)) {if (status &PB_STATUS_OFF ) { *flags |=REGULATOR_ERROR_FAIL ; *event |=REGULATOR_EVENT_FAIL ;
@@ -2898,7 +2896,10 @@ static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsi#if IS_ENABLED (CONFIG_REGULATOR )static int pmbus_regulator_is_enabled (struct regulator_dev *rdev) { -return pmbus_is_enabled (rdev_get_dev (rdev),rdev_get_id (rdev)); +struct device *dev =rdev_get_dev (rdev); +struct i2c_client *client =to_i2c_client (dev->parent); + +return pmbus_is_enabled (client,rdev_get_id (rdev)); }static int _pmbus_regulator_on_off (struct regulator_dev *rdev,bool enable)
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 184/239 hwmon: (pmbus_core) Fix Deadlock in pmbus_regulator_get_status
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
commit b84000f2274520f73ac9dc59fd9403260b61c4e7 upstream.
pmbus_regulator_get_status() acquires update_lock. pmbus_regulator_get_error_flags() acquires it again, resulting in an immediate deadlock.
Call _pmbus_get_flags() from pmbus_regulator_get_status() directly to avoid the problem.
--- drivers/hwmon/pmbus/pmbus_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/hwmon/pmbus/pmbus_core.c +2 -1
@@ -2946,6 +2946,7 @@ static int pmbus_regulator_get_status(ststruct pmbus_data *data =i2c_get_clientdata (client);u8 page =rdev_get_id (rdev);int status, ret; +int event;mutex_lock (&data->update_lock); status =pmbus_get_status (client, page,PMBUS_STATUS_WORD );
@@ -2965,7 +2966,7 @@ static int pmbus_regulator_get_status(st goto unlock; } - ret =pmbus_regulator_get_error_flags (rdev, &status); + ret =_pmbus_get_flags (data,rdev_get_id (rdev), &status, &event, false);if (ret) goto unlock;
Greg Kroah-Hartman
maintainerPATCH 185/239 btrfs: zoned: do not enable async discard
In reply to Greg Kroah-HartmanFrom: Naohiro Aota <[email protected]>
commit 95ca6599a589ee84c69f02d0e1d928c8d1367fb1 upstream.
The zoned mode need to reset a zone before using it. We rely on btrfs's original discard functionality (discarding unused block group range) to do the resetting.
While the commit 63a7cb130718 ("btrfs: auto enable discard=async when possible") made the discard done in an async manner, a zoned reset do not need to be async, as it is fast enough.
Even worth, delaying zone rests prevents using those zones again. So, let's disable async discard on the zoned mode.
--- fs/btrfs/disk-io.c | 7 ++++++- fs/btrfs/zoned.c | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-)
fs/btrfs/disk-io.c +6 -1
@@ -3692,11 +3692,16 @@ int __cold open_ctree(struct super_block* For devices supporting discard turn on discard=async automatically, * unless it's already set or disabled. This could be turned off by * nodiscard for the same mount. +* +* The zoned mode piggy backs on the discard functionality for +* resetting a zone. There is no reason to delay the zone reset as it is +* fast enough. So, do not enable async discard for zoned mode. */ if (!(btrfs_test_opt (fs_info,DISCARD_SYNC ) ||btrfs_test_opt (fs_info,DISCARD_ASYNC ) ||btrfs_test_opt (fs_info,NODISCARD )) && - fs_info->fs_devices->discardable) { + fs_info->fs_devices->discardable && + !btrfs_is_zoned (fs_info)) {btrfs_set_and_info (fs_info,DISCARD_ASYNC ,"auto enabling async discard" ); }
fs/btrfs/zoned.c +3 -0
@@ -804,6 +804,9 @@ int btrfs_check_mountopts_zoned(struct breturn -EINVAL ; } +btrfs_clear_and_info (info,DISCARD_ASYNC , +"zoned: async discard ignored and disabled for zoned mode" ); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 186/239 btrfs: account block group tree when calculating global reserve size
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 8dbfc14fc736eb701089aff09645c3d4ad3decb1 upstream.
When using the block group tree feature, this tree is a critical tree just like the extent, csum and free space trees, and just like them it uses the delayed refs block reserve.
So take into account the block group tree, and its current size, when calculating the size for the global reserve.
--- fs/btrfs/block-rsv.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/btrfs/block-rsv.c +5 -0
@@ -349,6 +349,11 @@ void btrfs_update_global_block_rsv(struc }read_unlock (&fs_info->global_root_lock); +if (btrfs_fs_compat_ro (fs_info,BLOCK_GROUP_TREE )) { + num_bytes +=btrfs_root_used (&fs_info->block_group_root->root_item); + min_items++; + } +/* * But we also want to reserve enough space so we can do the fallback * global reserve for an unlink, which is an additional
Greg Kroah-Hartman
maintainerPATCH 187/239 btrfs: check if the transaction was aborted at btrfs_wait_for_commit()
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit bf7ecbe9875061bf3fce1883e3b26b77f847d1e8 upstream.
At btrfs_wait_for_commit() we wait for a transaction to finish and then always return 0 (success) without checking if it was aborted, in which case the transaction didn't happen due to some critical error. Fix this by checking if the transaction was aborted.
--- fs/btrfs/transaction.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/transaction.c +1 -0
@@ -933,6 +933,7 @@ int btrfs_wait_for_commit(struct btrfs_f }wait_for_commit (cur_trans,TRANS_STATE_COMPLETED ); + ret = cur_trans->aborted;btrfs_put_transaction (cur_trans); out:return ret;
Greg Kroah-Hartman
maintainerPATCH 188/239 btrfs: check for commit error at btrfs_attach_transaction_barrier()
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit b28ff3a7d7e97456fd86b68d24caa32e1cfa7064 upstream.
btrfs_attach_transaction_barrier() is used to get a handle pointing to the current running transaction if the transaction has not started its commit yet (its state is < TRANS_STATE_COMMIT_START). If the transaction commit has started, then we wait for the transaction to commit and finish before returning - however we completely ignore if the transaction was aborted due to some error during its commit, we simply return ERR_PT(-ENOENT), which makes the caller assume everything is fine and no errors happened.
This could make an fsync return success (0) to user space when in fact we had a transaction abort and the target inode changes were therefore not persisted.
Fix this by checking for the return value from btrfs_wait_for_commit(), and if it returned an error, return it back to the caller.
--- fs/btrfs/transaction.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +7 -2
@@ -828,8 +828,13 @@ btrfs_attach_transaction_barrier(struct trans =start_transaction (root,0 ,TRANS_ATTACH ,BTRFS_RESERVE_NO_FLUSH , true); -if (trans ==ERR_PTR (-ENOENT )) -btrfs_wait_for_commit (root->fs_info,0 ); +if (trans ==ERR_PTR (-ENOENT )) { +int ret; + + ret =btrfs_wait_for_commit (root->fs_info,0 ); +if (ret) +return ERR_PTR (ret); + }return trans; }
Greg Kroah-Hartman
maintainerPATCH 189/239 x86/MCE/AMD: Decrement threshold_bank refcount when removing threshold blocks
In reply to Greg Kroah-HartmanFrom: Yazen Ghannam <[email protected]>
commit 3ba2e83334bed2b1980b59734e6e84dfaf96026c upstream.
AMD systems from Family 10h to 16h share MCA bank 4 across multiple CPUs. Therefore, the threshold_bank structure for bank 4, and its threshold_block structures, will be initialized once at boot time. And the kobject for the shared bank will be added to each of the CPUs that share it. Furthermore, the threshold_blocks for the shared bank will be added again to the bank's kobject. These additions will increase the refcount for the bank's kobject.
For example, a shared bank with two blocks and shared across two CPUs will be set up like this:
CPU0 init
bank create and add; bank refcount = 1; threshold_create_bank()
block 0 init and add; bank refcount = 2; allocate_threshold_blocks() block 1 init and add; bank refcount = 3; allocate_threshold_blocks()
CPU1 init
bank add; bank refcount = 3; threshold_create_bank()
block 0 add; bank refcount = 4; __threshold_add_blocks() block 1 add; bank refcount = 5; __threshold_add_blocks()
Currently in threshold_remove_bank(), if the bank is shared then __threshold_remove_blocks() is called. Here the shared bank's kobject and the bank's blocks' kobjects are deleted. This is done on the first call even while the structures are still shared. Subsequent calls from other CPUs that share the structures will attempt to delete the kobjects.
During kobject_del(), kobject->sd is removed. If the kobject is not part of a kset with default_groups, then subsequent kobject_del() calls seem safe even with kobject->sd == NULL.
Originally, the AMD MCA thresholding structures did not use default_groups. And so the above behavior was not apparent.
However, a recent change implemented default_groups for the thresholding structures. Therefore, kobject_del() will go down the sysfs_remove_groups() code path. In this case, the first kobject_del() may succeed and remove kobject->sd. But subsequent kobject_del() calls will give a WARNing in kernfs_remove_by_name_ns() since kobject->sd == NULL.
Use kobject_put() on the shared bank's kobject when "removing" blocks. This decrements the bank's refcount while keeping kobjects enabled until the bank is no longer shared. At that point, kobject_put() will be called on the blocks which drives their refcount to 0 and deletes them and also decrementing the bank's refcount. And finally kobject_put() will be called on the bank driving its refcount to 0 and deleting it.
The same example above:
CPU1 shutdown
bank is shared; bank refcount = 5; threshold_remove_bank()
block 0 put parent bank; bank refcount = 4; __threshold_remove_blocks() block 1 put parent bank; bank refcount = 3; __threshold_remove_blocks()
CPU0 shutdown
bank is no longer shared; bank refcount = 3; threshold_remove_bank()
block 0 put block; bank refcount = 2; deallocate_threshold_blocks() block 1 put block; bank refcount = 1; deallocate_threshold_blocks()
put bank; bank refcount = 0; threshold_remove_bank()
--- arch/x86/kernel/cpu/mce/amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +2 -2
@@ -1259,10 +1259,10 @@ static void __threshold_remove_blocks(ststruct threshold_block *pos =NULL ;struct threshold_block *tmp =NULL ; -kobject_del (b->kobj); +kobject_put (b->kobj);list_for_each_entry_safe (pos, tmp, &b->blocks->miscj, miscj) -kobject_del (&pos->kobj); +kobject_put (b->kobj); }static void threshold_remove_bank (struct threshold_bank *bank)
Greg Kroah-Hartman
maintainerPATCH 190/239 x86/cpu: Enable STIBP on AMD if Automatic IBRS is enabled
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit fd470a8beed88440b160d690344fbae05a0b9b1b upstream.
Unlike Intel's Enhanced IBRS feature, AMD's Automatic IBRS does not provide protection to processes running at CPL3/user mode, see section "Extended Feature Enable Register (EFER)" in the APM v2 at
https://bugzilla.kernel.org/attachment.cgi?id=304652
Explicitly enable STIBP to protect against cross-thread CPL3 branch target injections on systems with Automatic IBRS enabled.
Also update the relevant documentation.
--- Documentation/admin-guide/hw-vuln/spectre.rst | 11 +++++++---- arch/x86/kernel/cpu/bugs.c | 15 +++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-)
Documentation/admin-guide/hw-vuln/spectre.rst +7 -4
@@ -484,11 +484,14 @@ Spectre variant 2 Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at boot, by setting the IBRS bit, and they're automatically protected against - Spectre v2 variant attacks, including cross-thread branch target injections - on SMT systems (STIBP). In other words, eIBRS enables STIBP too. + Spectre v2 variant attacks. - Legacy IBRS systems clear the IBRS bit on exit to userspace and - therefore explicitly enable STIBP for that + On Intel's enhanced IBRS systems, this includes cross-thread branch target + injections on SMT systems (STIBP). In other words, Intel eIBRS enables + STIBP, too. + + AMD Automatic IBRS does not protect userspace, and Legacy IBRS systems clear + the IBRS bit on exit to userspace, therefore both explicitly enable STIBP. The retpoline mitigation is turned on by default on vulnerable CPUs. It can be forced on or off by the administrator
arch/x86/kernel/cpu/bugs.c +9 -6
@@ -1199,19 +1199,21 @@ spectre_v2_user_select_mitigation(void) }/* -* If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP +* If no STIBP, Intel enhanced IBRS is enabled, or SMT impossible, STIBP * is not required. * -* Enhanced IBRS also protects against cross-thread branch target +* Intel's Enhanced IBRS also protects against cross-thread branch target * injection in user-mode as the IBRS bit remains always set which * implicitly enables cross-thread protections. However, in legacy IBRS * mode, the IBRS bit is set only on kernel entry and cleared on return -* to userspace. This disables the implicit cross-thread protection, -* so allow for STIBP to be selected in that case. +* to userspace. AMD Automatic IBRS also does not protect userspace. +* These modes therefore disable the implicit cross-thread protection, +* so allow for STIBP to be selected in those cases. */ if (!boot_cpu_has (X86_FEATURE_STIBP ) || !smt_possible || -spectre_v2_in_eibrs_mode (spectre_v2_enabled)) + (spectre_v2_in_eibrs_mode (spectre_v2_enabled) && + !boot_cpu_has (X86_FEATURE_AUTOIBRS )))return ;/*
@@ -2343,7 +2345,8 @@ static ssize_t mmio_stale_data_show_statstatic char *stibp_state (void ) { -if (spectre_v2_in_eibrs_mode (spectre_v2_enabled)) +if (spectre_v2_in_eibrs_mode (spectre_v2_enabled) && + !boot_cpu_has (X86_FEATURE_AUTOIBRS ))return "" ;switch (spectre_v2_user_stibp) {
Greg Kroah-Hartman
maintainerPATCH 191/239 file: always lock position for FMODE_ATOMIC_POS
In reply to Greg Kroah-HartmanFrom: Christian Brauner <[email protected]>
commit 20ea1e7d13c1b544fe67c4a8dc3943bb1ab33e6f upstream.
The pidfd_getfd() system call allows a caller with ptrace_may_access() abilities on another process to steal a file descriptor from this process. This system call is used by debuggers, container runtimes, system call supervisors, networking proxies etc. So while it is a special interest system call it is used in common tools.
That ability ends up breaking our long-time optimization in fdget_pos(), which "knew" that if we had exclusive access to the file descriptor nobody else could access it, and we didn't need the lock for the file position.
That check for file_count(file) was always fairly subtle - it depended on __fdget() not incrementing the file count for single-threaded processes and thus included that as part of the rule - but it did mean that we didn't need to take the lock in all those traditional unix process contexts.
So it's sad to see this go, and I'd love to have some way to re-instate the optimization. At the same time, the lock obviously isn't ever contended in the case we optimized, so all we were optimizing away is the atomics and the cacheline dirtying. Let's see if anybody even notices that the optimization is gone.
--- fs/file.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/file.c +2 -4
@@ -1042,10 +1042,8 @@ unsigned long __fdget_pos(unsigned int fstruct file *file = (struct file *)(v & ~3 );if (file && (file->f_mode &FMODE_ATOMIC_POS )) { -if (file_count (file) >1 ) { - v |=FDPUT_POS_UNLOCK ; -mutex_lock (&file->f_pos_lock); - } + v |=FDPUT_POS_UNLOCK ; +mutex_lock (&file->f_pos_lock); }return v; }
Greg Kroah-Hartman
maintainerPATCH 192/239 nfsd: Remove incorrect check in nfsd4_validate_stateid
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit f75546f58a70da5cfdcec5a45ffc377885ccbee8 upstream.
If the client is calling TEST_STATEID, then it is because some event occurred that requires it to check all the stateids for validity and call FREE_STATEID on the ones that have been revoked. In this case, either the stateid exists in the list of stateids associated with that nfs4_client, in which case it should be tested, or it does not. There are no additional conditions to be considered.
--- fs/nfsd/nfs4state.c | 2 -- 1 file changed, 2 deletions(-)
fs/nfsd/nfs4state.c +0 -2
@@ -6341,8 +6341,6 @@ static __be32 nfsd4_validate_stateid(strif (ZERO_STATEID (stateid) ||ONE_STATEID (stateid) ||CLOSE_STATEID (stateid))return status; -if (!same_clid (&stateid->si_opaque.so_clid, &cl->cl_clientid)) -return status;spin_lock (&cl->cl_lock); s =find_stateid_locked (cl, stateid);if (!s)
Greg Kroah-Hartman
maintainerPATCH 193/239 ksmbd: check if a mount point is crossed during path lookup
In reply to Greg Kroah-HartmanFrom: Namjae Jeon <[email protected]>
commit 2b57a4322b1b14348940744fdc02f9a86cbbdbeb upstream.
Since commit 74d7970febf7 ("ksmbd: fix racy issue from using ->d_parent and ->d_name"), ksmbd can not lookup cross mount points. If last component is a cross mount point during path lookup, check if it is crossed to follow it down. And allow path lookup to cross a mount point when a crossmnt parameter is set to 'yes' in smb.conf.
--- fs/smb/server/ksmbd_netlink.h | 3 +- fs/smb/server/smb2pdu.c | 27 +++++++++++-------- fs/smb/server/vfs.c | 58 +++++++++++++++++++++++------------------- fs/smb/server/vfs.h | 4 +- 4 files changed, 53 insertions(+), 39 deletions(-)
fs/smb/server/ksmbd_netlink.h +2 -1
@@ -352,7 +352,8 @@ enum KSMBD_TREE_CONN_STATUS {#define KSMBD_SHARE_FLAG_STREAMS BIT(11)#define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS BIT(12)#define KSMBD_SHARE_FLAG_ACL_XATTR BIT(13) -#define KSMBD_SHARE_FLAG_UPDATE BIT(14) +#define KSMBD_SHARE_FLAG_UPDATE BIT(14) +#define KSMBD_SHARE_FLAG_CROSSMNT BIT(15)/* * Tree connect request flags.
fs/smb/server/smb2pdu.c +16 -11
@@ -2467,8 +2467,9 @@ static void smb2_update_xattrs(struct ks } } -static int smb2_creat (struct ksmbd_work *work,struct path *path,char *name, -int open_flags,umode_t posix_mode,bool is_dir) +static int smb2_creat (struct ksmbd_work *work,struct path *parent_path, +struct path *path,char *name,int open_flags, +umode_t posix_mode,bool is_dir) {struct ksmbd_tree_connect *tcon = work->tcon;struct ksmbd_share_config *share = tcon->share_conf;
@@ -2495,7 +2496,7 @@ static int smb2_creat(struct ksmbd_workreturn rc; } - rc =ksmbd_vfs_kern_path_locked (work, name,0 , path,0 ); + rc =ksmbd_vfs_kern_path_locked (work, name,0 , parent_path, path,0 );if (rc) {pr_err ("cannot get linux path (%s), err = %d\n" , name, rc);
@@ -2565,7 +2566,7 @@ int smb2_open(struct ksmbd_work *work)struct ksmbd_tree_connect *tcon = work->tcon;struct smb2_create_req *req;struct smb2_create_rsp *rsp; -struct path path; +struct path path, parent_path;struct ksmbd_share_config *share = tcon->share_conf;struct ksmbd_file *fp =NULL ;struct file *filp =NULL ;
@@ -2786,7 +2787,8 @@ int smb2_open(struct ksmbd_work *work) goto err_out1; } - rc =ksmbd_vfs_kern_path_locked (work, name,LOOKUP_NO_SYMLINKS , &path,1 ); + rc =ksmbd_vfs_kern_path_locked (work, name,LOOKUP_NO_SYMLINKS , + &parent_path, &path,1 );if (!rc) { file_present = true;
@@ -2908,7 +2910,8 @@ int smb2_open(struct ksmbd_work *work)/*create file if not present */ if (!file_present) { - rc =smb2_creat (work, &path, name, open_flags, posix_mode, + rc =smb2_creat (work, &parent_path, &path, name, open_flags, + posix_mode, req->CreateOptions &FILE_DIRECTORY_FILE_LE );if (rc) {if (rc == -ENOENT ) {
@@ -3323,8 +3326,9 @@ int smb2_open(struct ksmbd_work *work) err_out:if (file_present || created) { -inode_unlock (d_inode (path.dentry->d_parent)); -dput (path.dentry); +inode_unlock (d_inode (parent_path.dentry)); +path_put (&path); +path_put (&parent_path); }ksmbd_revert_fsids (work); err_out1:
@@ -5547,7 +5551,7 @@ static int smb2_create_link(struct ksmbd struct nls_table *local_nls) {char *link_name =NULL , *target_name =NULL , *pathname =NULL ; -struct path path; +struct path path, parent_path;bool file_present = false;int rc;
@@ -5577,7 +5581,7 @@ static int smb2_create_link(struct ksmbdksmbd_debug (SMB ,"target name is %s\n" , target_name); rc =ksmbd_vfs_kern_path_locked (work, link_name,LOOKUP_NO_SYMLINKS , - &path,0 ); + &parent_path, &path,0 );if (rc) {if (rc != -ENOENT ) goto out;
@@ -5607,8 +5611,9 @@ static int smb2_create_link(struct ksmbd rc = -EINVAL ; out:if (file_present) { -inode_unlock (d_inode (path.dentry->d_parent)); +inode_unlock (d_inode (parent_path.dentry));path_put (&path); +path_put (&parent_path); }if (!IS_ERR (link_name))kfree (link_name);
fs/smb/server/vfs.c +33 -25
136 lines not on this page · raw message
fs/smb/server/vfs.h +2 -2
@@ -115,8 +115,8 @@ int ksmbd_vfs_xattr_stream_name(char *stint ksmbd_vfs_remove_xattr (struct mnt_idmap *idmap,const struct path *path,char *attr_name);int ksmbd_vfs_kern_path_locked (struct ksmbd_work *work,char *name, -unsigned int flags,struct path *path, -bool caseless); +unsigned int flags,struct path *parent_path, +struct path *path,bool caseless); struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, const char *name, unsigned int flags,
Greg Kroah-Hartman
maintainerPATCH 194/239 ACPI/IORT: Remove erroneous id_count check in iort_node_get_rmr_info()
In reply to Greg Kroah-HartmanFrom: Guanghui Feng <[email protected]>
commit 003e6b56d780095a9adc23efc9cb4b4b4717169b upstream.
According to the ARM IORT specifications DEN 0049 issue E, the "Number of IDs" field in the ID mapping format reports the number of IDs in the mapping range minus one.
In iort_node_get_rmr_info(), we erroneously skip ID mappings whose "Number of IDs" equal to 0, resulting in valid mapping nodes with a single ID to map being skipped, which is wrong.
Fix iort_node_get_rmr_info() by removing the bogus id_count check.
--- drivers/acpi/arm64/iort.c | 3 --- 1 file changed, 3 deletions(-)
drivers/acpi/arm64/iort.c +0 -3
@@ -1006,9 +1006,6 @@ static void iort_node_get_rmr_info(strucfor (i =0 ; i < node->mapping_count; i++, map++) {struct acpi_iort_node *parent; -if (!map->id_count) -continue ; - parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, map->output_reference);if (parent != iommu)
Greg Kroah-Hartman
maintainerPATCH 195/239 tpm_tis: Explicitly check for error code
In reply to Greg Kroah-HartmanFrom: Alexander Steffen <[email protected]>
commit 513253f8c293c0c8bd46d09d337fc892bf8f9f48 upstream.
recv_data either returns the number of received bytes, or a negative value representing an error code. Adding the return value directly to the total number of received bytes therefore looks a little weird, since it might add a negative error code to a sum of bytes.
The following check for size < expected usually makes the function return ETIME in that case, so it does not cause too many problems in practice. But to make the code look cleaner and because the caller might still be interested in the original error code, explicitly check for the presence of an error code and pass that through.
--- drivers/char/tpm/tpm_tis_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/char/tpm/tpm_tis_core.c +7 -2
@@ -366,8 +366,13 @@ static int tpm_tis_recv(struct tpm_chip goto out; } - size +=recv_data (chip, &buf[TPM_HEADER_SIZE ], - expected -TPM_HEADER_SIZE ); + rc =recv_data (chip, &buf[TPM_HEADER_SIZE ], + expected -TPM_HEADER_SIZE ); +if (rc <0 ) { + size = rc; + goto out; + } + size += rc;if (size < expected) {dev_err (&chip->dev,"Unable to read remainder of result\n" ); size = -ETIME ;
Greg Kroah-Hartman
maintainerPATCH 196/239 irq-bcm6345-l1: Do not assume a fixed block to cpu mapping
In reply to Greg Kroah-HartmanFrom: Jonas Gorski <[email protected]>
[ Upstream commit 55ad24857341c36616ecc1d9580af5626c226cf1 ]
The irq to block mapping is fixed, and interrupts from the first block will always be routed to the first parent IRQ. But the parent interrupts themselves can be routed to any available CPU.
This is used by the bootloader to map the first parent interrupt to the boot CPU, regardless wether the boot CPU is the first one or the second one.
When booting from the second CPU, the assumption that the first block's IRQ is mapped to the first CPU breaks, and the system hangs because interrupts do not get routed correctly.
Fix this by passing the appropriate bcm6434_l1_cpu to the interrupt handler instead of the chip itself, so the handler always has the right block.
--- drivers/irqchip/irq-bcm6345-l1.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/irqchip/irq-bcm6345-l1.c +5 -9
@@ -82,6 +82,7 @@ struct bcm6345_l1_chip { };struct bcm6345_l1_cpu { +struct bcm6345_l1_chip *intc;void __iomem *map_base;unsigned int parent_irq;u32 enable_cache[];
@@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc,static void bcm6345_l1_irq_handle (struct irq_desc *desc) { -struct bcm6345_l1_chip *intc =irq_desc_get_handler_data (desc); -struct bcm6345_l1_cpu *cpu; +struct bcm6345_l1_cpu *cpu =irq_desc_get_handler_data (desc); +struct bcm6345_l1_chip *intc = cpu->intc;struct irq_chip *chip =irq_desc_get_chip (desc);unsigned int idx; -#ifdef CONFIG_SMP - cpu = intc->cpus[cpu_logical_map (smp_processor_id ())]; -#else - cpu = intc->cpus[0 ]; -#endif -chained_irq_enter (chip, desc);for (idx =0 ; idx < intc->n_words; idx++) {
@@ -253,6 +248,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,if (!cpu)return -ENOMEM ; + cpu->intc = intc; cpu->map_base =ioremap (res.start, sz);if (!cpu->map_base)return -ENOMEM ;
@@ -271,7 +267,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,return -EINVAL ; }irq_set_chained_handler_and_data (cpu->parent_irq, - bcm6345_l1_irq_handle, intc); + bcm6345_l1_irq_handle, cpu);return 0 ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 197/239 irqchip/gic-v4.1: Properly lock VPEs when doing a directLPI invalidation
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
[ Upstream commit 926846a703cbf5d0635cc06e67d34b228746554b ]
We normally rely on the irq_to_cpuid_[un]lock() primitives to make sure nothing will change col->idx while performing a LPI invalidation.
However, these primitives do not cover VPE doorbells, and we have some open-coded locking for that. Unfortunately, this locking is pretty bogus.
Instead, extend the above primitives to cover VPE doorbells and convert the whole thing to it.
--- drivers/irqchip/irq-gic-v3-its.c | 75 ++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 29 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +46 -29
@@ -273,13 +273,23 @@ static void vpe_to_cpuid_unlock(struct its_vpe *vpe, unsigned long flags)raw_spin_unlock_irqrestore (&vpe->vpe_lock, flags); } +static struct irq_chip its_vpe_irq_chip; +static int irq_to_cpuid_lock (struct irq_data *d,unsigned long *flags) { -struct its_vlpi_map *map =get_vlpi_map (d); +struct its_vpe *vpe =NULL ;int cpu; -if (map) { - cpu =vpe_to_cpuid_lock (map->vpe, flags); +if (d->chip == &its_vpe_irq_chip) { + vpe =irq_data_get_irq_chip_data (d); + }else { +struct its_vlpi_map *map =get_vlpi_map (d); +if (map) + vpe = map->vpe; + } + +if (vpe) { + cpu =vpe_to_cpuid_lock (vpe, flags); }else {/* Physical LPIs are already locked via the irq_desc lock */ struct its_device *its_dev =irq_data_get_irq_chip_data (d);
@@ -293,10 +303,18 @@ static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags)static void irq_to_cpuid_unlock (struct irq_data *d,unsigned long flags) { -struct its_vlpi_map *map =get_vlpi_map (d); +struct its_vpe *vpe =NULL ; + +if (d->chip == &its_vpe_irq_chip) { + vpe =irq_data_get_irq_chip_data (d); + }else { +struct its_vlpi_map *map =get_vlpi_map (d); +if (map) + vpe = map->vpe; + } -if (map) -vpe_to_cpuid_unlock (map->vpe, flags); +if (vpe) +vpe_to_cpuid_unlock (vpe, flags); }static struct its_collection *valid_col (struct its_collection *col)
@@ -1433,14 +1451,29 @@ static void wait_for_syncr(void __iomem *rdbase)cpu_relax (); } -static void direct_lpi_inv (struct irq_data *d) +static void __direct_lpi_inv (struct irq_data *d,u64 val) { -struct its_vlpi_map *map =get_vlpi_map (d);void __iomem *rdbase;unsigned long flags; -u64 val;int cpu; +/* Target the redistributor this LPI is currently routed to */ + cpu =irq_to_cpuid_lock (d, &flags); +raw_spin_lock (&gic_data_rdist_cpu (cpu)->rd_lock); + + rdbase =per_cpu_ptr (gic_rdists->rdist, cpu)->rd_base; +gic_write_lpir (val, rdbase +GICR_INVLPIR ); +wait_for_syncr (rdbase); + +raw_spin_unlock (&gic_data_rdist_cpu (cpu)->rd_lock); +irq_to_cpuid_unlock (d, flags); +} + +static void direct_lpi_inv (struct irq_data *d) +{ +struct its_vlpi_map *map =get_vlpi_map (d); +u64 val; +if (map) {struct its_device *its_dev =irq_data_get_irq_chip_data (d);
@@ -1453,15 +1486,7 @@ static void direct_lpi_inv(struct irq_data *d) val = d->hwirq; } -/* Target the redistributor this LPI is currently routed to */ - cpu =irq_to_cpuid_lock (d, &flags); -raw_spin_lock (&gic_data_rdist_cpu (cpu)->rd_lock); - rdbase =per_cpu_ptr (gic_rdists->rdist, cpu)->rd_base; -gic_write_lpir (val, rdbase +GICR_INVLPIR ); - -wait_for_syncr (rdbase); -raw_spin_unlock (&gic_data_rdist_cpu (cpu)->rd_lock); -irq_to_cpuid_unlock (d, flags); +__direct_lpi_inv (d, val); }static void lpi_update_config (struct irq_data *d,u8 clr,u8 set)
@@ -3952,18 +3977,10 @@ static void its_vpe_send_inv(struct irq_data *d) {struct its_vpe *vpe =irq_data_get_irq_chip_data (d); -if (gic_rdists->has_direct_lpi) { -void __iomem *rdbase; - -/* Target the redistributor this VPE is currently known on */ -raw_spin_lock (&gic_data_rdist_cpu (vpe->col_idx)->rd_lock); - rdbase =per_cpu_ptr (gic_rdists->rdist, vpe->col_idx)->rd_base; -gic_write_lpir (d->parent_data->hwirq, rdbase +GICR_INVLPIR ); -wait_for_syncr (rdbase); -raw_spin_unlock (&gic_data_rdist_cpu (vpe->col_idx)->rd_lock); - }else { +if (gic_rdists->has_direct_lpi) +__direct_lpi_inv (d, d->parent_data->hwirq); +else its_vpe_send_cmd (vpe, its_send_inv); - } }static void its_vpe_mask_irq (struct irq_data *d)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 198/239 locking/rtmutex: Fix task->pi_waiters integrity
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit f7853c34241807bb97673a5e97719123be39a09e ]
Henry reported that rt_mutex_adjust_prio_check() has an ordering problem and puts the lie to the comment in [7]. Sharing the sort key between lock->waiters and owner->pi_waiters *does* create problems, since unlike what the comment claims, holding [L] is insufficient.
Notably, consider:
A
/ \
M1 M2
| |
B CThat is, task A owns both M1 and M2, B and C block on them. In this case a concurrent chain walk (B & C) will modify their resp. sort keys in [7] while holding M1->wait_lock and M2->wait_lock. So holding [L] is meaningless, they're different Ls.
This then gives rise to a race condition between [7] and [11], where the requeue of pi_waiters will observe an inconsistent tree order.
B C
(holds M1->wait_lock, (holds M2->wait_lock,
holds B->pi_lock) holds A->pi_lock)
[7] waiter_update_prio(); ... [8] raw_spin_unlock(B->pi_lock); ... [10] raw_spin_lock(A->pi_lock);
[11] rt_mutex_enqueue_pi(); // observes inconsistent A->pi_waiters // tree order
Fixing this means either extending the range of the owner lock from [10-13] to [6-13], with the immediate problem that this means [6-8] hold both blocked and owner locks, or duplicating the sort key.
Since the locking in chain walk is horrible enough without having to consider pi_lock nesting rules, duplicate the sort key instead.
By giving each tree their own sort key, the above race becomes harmless, if C sees B at the old location, then B will correct things (if they need correcting) when it walks up the chain and reaches A.
--- kernel/locking/rtmutex.c | 170 +++++++++++++++++++++----------- kernel/locking/rtmutex_api.c | 2 +- kernel/locking/rtmutex_common.h | 47 ++++++--- kernel/locking/ww_mutex.h | 12 +-- 4 files changed, 155 insertions(+), 76 deletions(-)
kernel/locking/rtmutex.c +114 -56
@@ -333,21 +333,43 @@ static __always_inline int __waiter_prio(struct task_struct *task)return prio; } +/* +* Update the waiter->tree copy of the sort keys. +*/ static __always_inline voidwaiter_update_prio (struct rt_mutex_waiter *waiter,struct task_struct *task) { - waiter->prio =__waiter_prio (task); - waiter->deadline = task->dl.deadline; +lockdep_assert_held (&waiter->lock->wait_lock); +lockdep_assert (RB_EMPTY_NODE (&waiter->tree.entry)); + + waiter->tree.prio =__waiter_prio (task); + waiter->tree.deadline = task->dl.deadline; +} + +/* +* Update the waiter->pi_tree copy of the sort keys (from the tree copy). +*/ +static __always_inline void +waiter_clone_prio (struct rt_mutex_waiter *waiter,struct task_struct *task) +{ +lockdep_assert_held (&waiter->lock->wait_lock); +lockdep_assert_held (&task->pi_lock); +lockdep_assert (RB_EMPTY_NODE (&waiter->pi_tree.entry)); + + waiter->pi_tree.prio = waiter->tree.prio; + waiter->pi_tree.deadline = waiter->tree.deadline; }/* -* Only use with rt_mutex_waiter_{less,equal}() +* Only use with rt_waiter_node_{less,equal}() */ +#define task_to_waiter_node (p) \ + &(struct rt_waiter_node){ .prio = __waiter_prio(p), .deadline = (p)->dl.deadline }#define task_to_waiter (p) \ - &(struct rt_mutex_waiter){ .prio = __waiter_prio(p), .deadline = (p)->dl.deadline } + &(struct rt_mutex_waiter){ .tree = *task_to_waiter_node(p) } -static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left, -struct rt_mutex_waiter *right) +static __always_inline int rt_waiter_node_less(struct rt_waiter_node *left, +struct rt_waiter_node *right) {if (left->prio < right->prio)return 1 ;
@@ -364,8 +386,8 @@ static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left,return 0 ; } -static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left, -struct rt_mutex_waiter *right) +static __always_inline int rt_waiter_node_equal(struct rt_waiter_node *left, +struct rt_waiter_node *right) {if (left->prio != right->prio)return 0 ;
@@ -385,7 +407,7 @@ static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left,static inline bool rt_mutex_steal (struct rt_mutex_waiter *waiter,struct rt_mutex_waiter *top_waiter) { -if (rt_mutex_waiter_less (waiter, top_waiter)) +if (rt_waiter_node_less (&waiter->tree, &top_waiter->tree))return true;#ifdef RT_MUTEX_BUILD_SPINLOCKS
@@ -393,30 +415,30 @@ static inline bool rt_mutex_steal(struct rt_mutex_waiter *waiter,* Note that RT tasks are excluded from same priority (lateral) * steals to prevent the introduction of an unbounded latency. */ -if (rt_prio (waiter->prio) ||dl_prio (waiter->prio)) +if (rt_prio (waiter->tree.prio) ||dl_prio (waiter->tree.prio))return false; -return rt_mutex_waiter_equal (waiter, top_waiter); +return rt_waiter_node_equal (&waiter->tree, &top_waiter->tree);#else return false;#endif }#define __node_2_waiter (node) \ - rb_entry((node), struct rt_mutex_waiter, tree_entry) + rb_entry((node), struct rt_mutex_waiter, tree.entry) static __always_inline bool __waiter_less(struct rb_node *a, const struct rb_node *b) {struct rt_mutex_waiter *aw =__node_2_waiter (a);struct rt_mutex_waiter *bw =__node_2_waiter (b); -if (rt_mutex_waiter_less (aw, bw)) +if (rt_waiter_node_less (&aw->tree, &bw->tree))return 1 ;if (!build_ww_mutex ())return 0 ; -if (rt_mutex_waiter_less (bw, aw)) +if (rt_waiter_node_less (&bw->tree, &aw->tree))return 0 ;/* NOTE: relies on waiter->ww_ctx being set before insertion */
@@ -434,48 +456,58 @@ static __always_inline bool __waiter_less(struct rb_node *a, const struct rb_nod static __always_inline voidrt_mutex_enqueue (struct rt_mutex_base *lock,struct rt_mutex_waiter *waiter) { -rb_add_cached (&waiter->tree_entry, &lock->waiters, __waiter_less); +lockdep_assert_held (&lock->wait_lock); + +rb_add_cached (&waiter->tree.entry, &lock->waiters, __waiter_less); } static __always_inline voidrt_mutex_dequeue (struct rt_mutex_base *lock,struct rt_mutex_waiter *waiter) { -if (RB_EMPTY_NODE (&waiter->tree_entry)) +lockdep_assert_held (&lock->wait_lock); + +if (RB_EMPTY_NODE (&waiter->tree.entry))return ; -rb_erase_cached (&waiter->tree_entry, &lock->waiters); -RB_CLEAR_NODE (&waiter->tree_entry); +rb_erase_cached (&waiter->tree.entry, &lock->waiters); +RB_CLEAR_NODE (&waiter->tree.entry); } -#define __node_2_pi_waiter (node) \ - rb_entry((node), struct rt_mutex_waiter, pi_tree_entry) +#define __node_2_rt_node (node) \ + rb_entry((node), struct rt_waiter_node, entry) -static __always_inline bool -__pi_waiter_less (struct rb_node *a,const struct rb_node *b) +static __always_inline bool __pi_waiter_less(struct rb_node *a, const struct rb_node *b) { -return rt_mutex_waiter_less (__node_2_pi_waiter (a),__node_2_pi_waiter (b)); +return rt_waiter_node_less (__node_2_rt_node (a),__node_2_rt_node (b)); } static __always_inline voidrt_mutex_enqueue_pi (struct task_struct *task,struct rt_mutex_waiter *waiter) { -rb_add_cached (&waiter->pi_tree_entry, &task->pi_waiters, __pi_waiter_less); +lockdep_assert_held (&task->pi_lock); + +rb_add_cached (&waiter->pi_tree.entry, &task->pi_waiters, __pi_waiter_less); } static __always_inline voidrt_mutex_dequeue_pi (struct task_struct *task,struct rt_mutex_waiter *waiter) { -if (RB_EMPTY_NODE (&waiter->pi_tree_entry)) +lockdep_assert_held (&task->pi_lock); + +if (RB_EMPTY_NODE (&waiter->pi_tree.entry))return ; -rb_erase_cached (&waiter->pi_tree_entry, &task->pi_waiters); -RB_CLEAR_NODE (&waiter->pi_tree_entry); +rb_erase_cached (&waiter->pi_tree.entry, &task->pi_waiters); +RB_CLEAR_NODE (&waiter->pi_tree.entry); } -static __always_inline void rt_mutex_adjust_prio(struct task_struct *p) +static __always_inline void rt_mutex_adjust_prio(struct rt_mutex_base *lock, +struct task_struct *p) {struct task_struct *pi_task =NULL ; +lockdep_assert_held (&lock->wait_lock); +lockdep_assert (rt_mutex_owner (lock) == p);lockdep_assert_held (&p->pi_lock);if (task_has_pi_waiters (p))
@@ -571,9 +603,14 @@ static __always_inline struct rt_mutex_base *task_blocked_on_lock(struct task_st* Chain walk basics and protection scope * * [R] refcount on task -* [P] task->pi_lock held +* [Pn] task->pi_lock held * [L] rtmutex->wait_lock held * +* Normal locking order: +* +* rtmutex->wait_lock +* task->pi_lock +* * Step Description Protected by * function arguments: * @task [R]
@@ -588,27 +625,32 @@ static __always_inline struct rt_mutex_base *task_blocked_on_lock(struct task_st* again: * loop_sanity_check(); * retry: -* [1] lock(task->pi_lock); [R] acquire [P] -* [2] waiter = task->pi_blocked_on; [P] -* [3] check_exit_conditions_1(); [P] -* [4] lock = waiter->lock; [P] -* [5] if (!try_lock(lock->wait_lock)) { [P] try to acquire [L] -* unlock(task->pi_lock); release [P] +* [1] lock(task->pi_lock); [R] acquire [P1] +* [2] waiter = task->pi_blocked_on; [P1] +* [3] check_exit_conditions_1(); [P1] +* [4] lock = waiter->lock; [P1] +* [5] if (!try_lock(lock->wait_lock)) { [P1] try to acquire [L] +* unlock(task->pi_lock); release [P1] * goto retry; * } -* [6] check_exit_conditions_2(); [P] + [L] -* [7] requeue_lock_waiter(lock, waiter); [P] + [L] -* [8] unlock(task->pi_lock); release [P] +* [6] check_exit_conditions_2(); [P1] + [L] +* [7] requeue_lock_waiter(lock, waiter); [P1] + [L] +* [8] unlock(task->pi_lock); release [P1] * put_task_struct(task); release [R] * [9] check_exit_conditions_3(); [L] * [10] task = owner(lock); [L] * get_task_struct(task); [L] acquire [R] -* lock(task->pi_lock); [L] acquire [P] -* [11] requeue_pi_waiter(tsk, waiters(lock));[P] + [L] -* [12] check_exit_conditions_4(); [P] + [L] -* [13] unlock(task->pi_lock); release [P] +* lock(task->pi_lock); [L] acquire [P2] +* [11] requeue_pi_waiter(tsk, waiters(lock));[P2] + [L] +* [12] check_exit_conditions_4(); [P2] + [L] +* [13] unlock(task->pi_lock); release [P2] * unlock(lock->wait_lock); release [L] * goto again; +* +* Where P1 is the blocking task and P2 is the lock owner; going up one step +* the owner becomes the next blocked task etc.. +* +* */ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, enum rtmutex_chainwalk chwalk,
@@ -756,7 +798,7 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,* enabled we continue, but stop the requeueing in the chain * walk. */ -if (rt_mutex_waiter_equal (waiter,task_to_waiter (task))) { +if (rt_waiter_node_equal (&waiter->tree,task_to_waiter_node (task))) {if (!detect_deadlock) goto out_unlock_pi;else
@@ -764,13 +806,18 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, }/* -* [4] Get the next lock +* [4] Get the next lock; per holding task->pi_lock we can't unblock +* and guarantee @lock's existence. */ lock = waiter->lock;/* * [5] We need to trylock here as we are holding task->pi_lock, * which is the reverse lock order versus the other rtmutex * operations. +* +* Per the above, holding task->pi_lock guarantees lock exists, so +* inverting this lock order is infeasible from a life-time +* perspective. */ if (!raw_spin_trylock (&lock->wait_lock)) {raw_spin_unlock_irq (&task->pi_lock);
@@ -874,17 +921,18 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,* or * * DL CBS enforcement advancing the effective deadline. -* -* Even though pi_waiters also uses these fields, and that tree is only -* updated in [11], we can do this here, since we hold [L], which -* serializes all pi_waiters access and rb_erase() does not care about -* the values of the node being removed. */ waiter_update_prio (waiter, task);rt_mutex_enqueue (lock, waiter); -/* [8] Release the task */ +/* +* [8] Release the (blocking) task in preparation for +* taking the owner task in [10]. +* +* Since we hold lock->waiter_lock, task cannot unblock, even if we +* release task->pi_lock. +*/ raw_spin_unlock (&task->pi_lock);put_task_struct (task);
@@ -908,7 +956,12 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,return 0 ; } -/* [10] Grab the next task, i.e. the owner of @lock */ +/* +* [10] Grab the next task, i.e. the owner of @lock +* +* Per holding lock->wait_lock and checking for !owner above, there +* must be an owner and it cannot go away. +*/ task =get_task_struct (rt_mutex_owner (lock));raw_spin_lock (&task->pi_lock);
@@ -921,8 +974,9 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,* and adjust the priority of the owner. */ rt_mutex_dequeue_pi (task, prerequeue_top_waiter); +waiter_clone_prio (waiter, task);rt_mutex_enqueue_pi (task, waiter); -rt_mutex_adjust_prio (task); +rt_mutex_adjust_prio (lock, task); }else if (prerequeue_top_waiter == waiter) {/*
@@ -937,8 +991,9 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,*/ rt_mutex_dequeue_pi (task, waiter); waiter =rt_mutex_top_waiter (lock); +waiter_clone_prio (waiter, task);rt_mutex_enqueue_pi (task, waiter); -rt_mutex_adjust_prio (task); +rt_mutex_adjust_prio (lock, task); }else {/* * Nothing changed. No need to do any priority
@@ -1154,6 +1209,7 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock, waiter->task = task; waiter->lock = lock;waiter_update_prio (waiter, task); +waiter_clone_prio (waiter, task);/* Get the top priority waiter on the lock */ if (rt_mutex_has_waiters (lock))
@@ -1187,7 +1243,7 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock,rt_mutex_dequeue_pi (owner, top_waiter);rt_mutex_enqueue_pi (owner, waiter); -rt_mutex_adjust_prio (owner); +rt_mutex_adjust_prio (lock, owner);if (owner->pi_blocked_on) chain_walk =1 ; }else if (rt_mutex_cond_detect_deadlock (waiter, chwalk)) {
@@ -1234,6 +1290,8 @@ static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh, {struct rt_mutex_waiter *waiter; +lockdep_assert_held (&lock->wait_lock); +raw_spin_lock (¤t->pi_lock); waiter =rt_mutex_top_waiter (lock);
@@ -1246,7 +1304,7 @@ static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh,* task unblocks. */ rt_mutex_dequeue_pi (current, waiter); -rt_mutex_adjust_prio (current); +rt_mutex_adjust_prio (lock, current);/* * As we are waking up the top waiter, and the waiter stays
@@ -1482,7 +1540,7 @@ static void __sched remove_waiter(struct rt_mutex_base *lock,if (rt_mutex_has_waiters (lock))rt_mutex_enqueue_pi (owner,rt_mutex_top_waiter (lock)); -rt_mutex_adjust_prio (owner); +rt_mutex_adjust_prio (lock, owner);/* Store the lock on which owner is blocked or NULL */ next_lock =task_blocked_on_lock (owner);
kernel/locking/rtmutex_api.c +1 -1
@@ -459,7 +459,7 @@ void __sched rt_mutex_adjust_pi(struct task_struct *task)raw_spin_lock_irqsave (&task->pi_lock, flags); waiter = task->pi_blocked_on; -if (!waiter ||rt_mutex_waiter_equal (waiter,task_to_waiter (task))) { +if (!waiter ||rt_waiter_node_equal (&waiter->tree,task_to_waiter_node (task))) {raw_spin_unlock_irqrestore (&task->pi_lock, flags);return ; }
kernel/locking/rtmutex_common.h +34 -13
92 lines not on this page · raw message
kernel/locking/ww_mutex.h +6 -6
@@ -96,25 +96,25 @@ __ww_waiter_first(struct rt_mutex *lock)struct rb_node *n =rb_first (&lock->rtmutex.waiters.rb_root);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); }static inline struct rt_mutex_waiter *__ww_waiter_next (struct rt_mutex *lock,struct rt_mutex_waiter *w) { -struct rb_node *n =rb_next (&w->tree_entry); +struct rb_node *n =rb_next (&w->tree.entry);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); }static inline struct rt_mutex_waiter *__ww_waiter_prev (struct rt_mutex *lock,struct rt_mutex_waiter *w) { -struct rb_node *n =rb_prev (&w->tree_entry); +struct rb_node *n =rb_prev (&w->tree.entry);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); } static inline struct rt_mutex_waiter *
@@ -123,7 +123,7 @@ __ww_waiter_last(struct rt_mutex *lock)struct rb_node *n =rb_last (&lock->rtmutex.waiters.rb_root);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); } static inline void
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 199/239 proc/vmcore: fix signedness bug in read_from_oldmem()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 641db40f3afe7998011bfabc726dba3e698f8196 upstream.
The bug is the error handling:
if (tmp < nr_bytes) {"tmp" can hold negative error codes but because "nr_bytes" is type size_t the negative error codes are treated as very high positive values (success). Fix this by changing "nr_bytes" to type ssize_t. The "nr_bytes" variable is used to store values between 1 and PAGE_SIZE and they can fit in ssize_t without any issue.
--- fs/proc/vmcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/proc/vmcore.c +1 -1
@@ -132,7 +132,7 @@ ssize_t read_from_oldmem(struct iov_iter u64 *ppos, bool encrypted) {unsigned long pfn, offset; -size_t nr_bytes; +ssize_t nr_bytes;ssize_t read =0 , tmp;int idx;
Greg Kroah-Hartman
maintainerPATCH 200/239 xen: speed up grant-table reclaim
In reply to Greg Kroah-HartmanFrom: Demi Marie Obenour <[email protected]>
commit c04e9894846c663f3278a414f34416e6e45bbe68 upstream.
When a grant entry is still in use by the remote domain, Linux must put it on a deferred list. Normally, this list is very short, because the PV network and block protocols expect the backend to unmap the grant first. However, Qubes OS's GUI protocol is subject to the constraints of the X Window System, and as such winds up with the frontend unmapping the window first. As a result, the list can grow very large, resulting in a massive memory leak and eventual VM freeze.
To partially solve this problem, make the number of entries that the VM will attempt to free at each iteration tunable. The default is still 10, but it can be overridden via a module parameter.
This is Cc: stable because (when combined with appropriate userspace changes) it fixes a severe performance and stability problem for Qubes OS users.
--- Documentation/ABI/testing/sysfs-module | 11 +++++++++ drivers/xen/grant-table.c | 40 +++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 11 deletions(-)
Documentation/ABI/testing/sysfs-module +11 -0
@@ -60,3 +60,14 @@ Description: Module taint flags: C staging driver module E unsigned module == ===================== + +What: /sys/module/grant_table/parameters/free_per_iteration +Date: July 2023 +KernelVersion: 6.5 but backported to all supported stable branches +Contact: Xen developer discussion <[email protected]> +Description: Read and write number of grant entries to attempt to free per iteration. + + Note: Future versions of Xen and Linux may provide a better + interface for controlling the rate of deferred grant reclaim + or may not need it at all. +Users: Qubes OS (https://www.qubes-os.org)
drivers/xen/grant-table.c +29 -11
@@ -498,14 +498,21 @@ static LIST_HEAD(deferred_list);static void gnttab_handle_deferred (struct timer_list *); static DEFINE_TIMER(deferred_timer, gnttab_handle_deferred); +static atomic64_t deferred_count; +static atomic64_t leaked_count; +static unsigned int free_per_iteration =10 ; +module_param (free_per_iteration, uint,0600 ); +static void gnttab_handle_deferred (struct timer_list *unused) { -unsigned int nr =10 ; +unsigned int nr =READ_ONCE (free_per_iteration); +const bool ignore_limit = nr ==0 ;struct deferred_entry *first =NULL ;unsigned long flags; +size_t freed =0 ;spin_lock_irqsave (&gnttab_list_lock, flags); -while (nr--) { +while ((ignore_limit || nr--) && !list_empty (&deferred_list)) {struct deferred_entry *entry =list_first_entry (&deferred_list, struct deferred_entry, list);
@@ -515,10 +522,14 @@ static void gnttab_handle_deferred(struclist_del (&entry->list);spin_unlock_irqrestore (&gnttab_list_lock, flags);if (_gnttab_end_foreign_access_ref (entry->ref)) { +uint64_t ret =atomic64_dec_return (&deferred_count); +put_free_entry (entry->ref); -pr_debug ("freeing g.e. %#x (pfn %#lx)\n" , - entry->ref,page_to_pfn (entry->page)); +pr_debug ("freeing g.e. %#x (pfn %#lx), %llu remaining\n" , + entry->ref,page_to_pfn (entry->page), + (unsigned long long )ret);put_page (entry->page); + freed++;kfree (entry); entry =NULL ; }else {
@@ -530,21 +541,22 @@ static void gnttab_handle_deferred(strucspin_lock_irqsave (&gnttab_list_lock, flags);if (entry)list_add_tail (&entry->list, &deferred_list); -else if (list_empty (&deferred_list)) -break ; } -if (!list_empty (&deferred_list) && !timer_pending (&deferred_timer)) { +if (list_empty (&deferred_list)) +WARN_ON (atomic64_read (&deferred_count)); +else if (!timer_pending (&deferred_timer)) { deferred_timer.expires = jiffies +HZ ;add_timer (&deferred_timer); }spin_unlock_irqrestore (&gnttab_list_lock, flags); +pr_debug ("Freed %zu references" , freed); }static void gnttab_add_deferred (grant_ref_t ref,struct page *page) {struct deferred_entry *entry;gfp_t gfp = (in_atomic () ||irqs_disabled ()) ?GFP_ATOMIC :GFP_KERNEL ; -const char *what =KERN_WARNING "leaking" ; +uint64_t leaked, deferred; entry =kmalloc (sizeof (*entry), gfp);if (!page) {
@@ -567,10 +579,16 @@ static void gnttab_add_deferred(grant_readd_timer (&deferred_timer); }spin_unlock_irqrestore (&gnttab_list_lock, flags); - what =KERN_DEBUG "deferring" ; + deferred =atomic64_inc_return (&deferred_count); + leaked =atomic64_read (&leaked_count); +pr_debug ("deferring g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n" , + ref, page ?page_to_pfn (page) :-1 , deferred, leaked); + }else { + deferred =atomic64_read (&deferred_count); + leaked =atomic64_inc_return (&leaked_count); +pr_warn ("leaking g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n" , + ref, page ?page_to_pfn (page) :-1 , deferred, leaked); } -printk ("%s g.e. %#x (pfn %#lx)\n" , - what, ref, page ?page_to_pfn (page) :-1 ); }int gnttab_try_end_foreign_access (grant_ref_t ref)
Greg Kroah-Hartman
maintainerPATCH 201/239 virtio-net: fix race between set queues and probe
In reply to Greg Kroah-HartmanFrom: Jason Wang <[email protected]>
commit 25266128fe16d5632d43ada34c847d7b8daba539 upstream.
A race were found where set_channels could be called after registering but before virtnet_set_queues() in virtnet_probe(). Fixing this by moving the virtnet_set_queues() before netdevice registering. While at it, use _virtnet_set_queues() to avoid holding rtnl as the device is not even registered at that time.
--- drivers/net/virtio_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/virtio_net.c +2 -2
@@ -4110,6 +4110,8 @@ static int virtnet_probe(struct virtio_dif (vi->has_rss || vi->has_rss_hash_report)virtnet_init_default_rss (vi); +_virtnet_set_queues (vi, vi->curr_queue_pairs); +/* serialize netdev register + virtio_device_ready() with ndo_open() */ rtnl_lock ();
@@ -4148,8 +4150,6 @@ static int virtnet_probe(struct virtio_d goto free_unregister_netdev; } -virtnet_set_queues (vi, vi->curr_queue_pairs); -/* Assume link up if device can't report link status, otherwise get link status from config. */ netif_carrier_off (dev);
Greg Kroah-Hartman
maintainerPATCH 202/239 net: ipa: only reset hashed tables when supported
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
commit e11ec2b868af2b351c6c1e2e50eb711cc5423a10 upstream.
Last year, the code that manages GSI channel transactions switched from using spinlock-protected linked lists to using indexes into the ring buffer used for a channel. Recently, Google reported seeing transaction reference count underflows occasionally during shutdown.
Doug Anderson found a way to reproduce the issue reliably, and bisected the issue to the commit that eliminated the linked lists and the lock. The root cause was ultimately determined to be related to unused transactions being committed as part of the modem shutdown cleanup activity. Unused transactions are not normally expected (except in error cases).
The modem uses some ranges of IPA-resident memory, and whenever it shuts down we zero those ranges. In ipa_filter_reset_table() a transaction is allocated to zero modem filter table entries. If hashing is not supported, hashed table memory should not be zeroed. But currently nothing prevents that, and the result is an unused transaction. Something similar occurs when we zero routing table entries for the modem.
By preventing any attempt to clear hashed tables when hashing is not supported, the reference count underflow is avoided in this case.
Note that there likely remains an issue with properly freeing unused transactions (if they occur due to errors). This patch addresses only the underflows that Google originally reported.
--- drivers/net/ipa/ipa_table.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/net/ipa/ipa_table.c +11 -9
@@ -273,16 +273,15 @@ static int ipa_filter_reset(struct ipa *if (ret)return ret; - ret =ipa_filter_reset_table (ipa, true, false, modem); -if (ret) + ret =ipa_filter_reset_table (ipa, false, true, modem); +if (ret || !ipa_table_hash_support (ipa))return ret; - ret =ipa_filter_reset_table (ipa, false, true, modem); + ret =ipa_filter_reset_table (ipa, true, false, modem);if (ret)return ret; - ret =ipa_filter_reset_table (ipa, true, true, modem); -return ret; +return ipa_filter_reset_table (ipa, true, true, modem); }/* The AP routes and modem routes are each contiguous within the
@@ -291,12 +290,13 @@ static int ipa_filter_reset(struct ipa ** */ static int ipa_route_reset (struct ipa *ipa,bool modem) { +bool hash_support =ipa_table_hash_support (ipa);u32 modem_route_count = ipa->modem_route_count;struct gsi_trans *trans;u16 first;u16 count; - trans =ipa_cmd_trans_alloc (ipa,4 ); + trans =ipa_cmd_trans_alloc (ipa, hash_support ?4 :2 );if (!trans) { dev_err(&ipa->pdev->dev, "no transaction for %s route reset\n",
@@ -313,10 +313,12 @@ static int ipa_route_reset(struct ipa *i }ipa_table_reset_add (trans, false, false, false, first, count); -ipa_table_reset_add (trans, false, true, false, first, count); -ipa_table_reset_add (trans, false, false, true, first, count); -ipa_table_reset_add (trans, false, true, true, first, count); + +if (hash_support) { +ipa_table_reset_add (trans, false, true, false, first, count); +ipa_table_reset_add (trans, false, true, true, first, count); + }gsi_trans_commit_wait (trans);
Greg Kroah-Hartman
maintainerPATCH 203/239 net: dsa: qca8k: enable use_single_write for qca8xxx
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit 2c39dd025da489cf87d26469d9f5ff19715324a0 upstream.
The qca8xxx switch supports 2 way to write reg values, a slow way using mdio and a fast way by sending specially crafted mgmt packet to read/write reg.
The fast way can support up to 32 bytes of data as eth packet are used to send/receive.
This correctly works for almost the entire regmap of the switch but with the use of some kernel selftests for dsa drivers it was found a funny and interesting hw defect/limitation.
For some specific reg, bulk write won't work and will result in writing only part of the requested regs resulting in half data written. This was especially hard to track and discover due to the total strangeness of the problem and also by the specific regs where this occurs.
This occurs in the specific regs of the ATU table, where multiple entry needs to be written to compose the entire entry.
It was discovered that with a bulk write of 12 bytes on QCA8K_REG_ATU_DATA0 only QCA8K_REG_ATU_DATA0 and QCA8K_REG_ATU_DATA2 were written, but QCA8K_REG_ATU_DATA1 was always zero. Tcpdump was used to make sure the specially crafted packet was correct and this was confirmed.
The problem was hard to track as the lack of QCA8K_REG_ATU_DATA1 resulted in an entry somehow possible as the first bytes of the mac address are set in QCA8K_REG_ATU_DATA0 and the entry type is set in QCA8K_REG_ATU_DATA2.
Funlly enough writing QCA8K_REG_ATU_DATA1 results in the same problem with QCA8K_REG_ATU_DATA2 empty and QCA8K_REG_ATU_DATA1 and QCA8K_REG_ATU_FUNC correctly written.
A speculation on the problem might be that there are some kind of indirection internally when accessing these regs and they can't be accessed all together, due to the fact that it's really a table mapped somewhere in the switch SRAM.
Even more funny is the fact that every other reg was tested with all kind of combination and they are not affected by this problem. Read operation was also tested and always worked so it's not affected by this problem.
The problem is not present if we limit writing a single reg at times.
To handle this hardware defect, enable use_single_write so that bulk api can correctly split the write in multiple different operation effectively reverting to a non-bulk write.
--- drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/dsa/qca/qca8k-8xxx.c +5 -2
@@ -576,8 +576,11 @@ static struct regmap_config qca8k_regmap_config = { .rd_table = &qca8k_readable_table, .disable_locking = true, /* Locking is handled by qca8k read/write */ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ - .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */ - .max_raw_write = 32, + .max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */ +/* ATU regs suffer from a bug where some data are not correctly +* written. Disable bulk write to correctly write ATU entry. +*/ + .use_single_write = true, }; static int
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 204/239 net: dsa: qca8k: fix search_and_insert wrong handling of new rule
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit 80248d4160894d7e40b04111bdbaa4ff93fc4bd7 upstream.
On inserting a mdb entry, fdb_search_and_insert is used to add a port to the qca8k target entry in the FDB db.
A FDB entry can't be modified so it needs to be removed and insert again with the new values.
To detect if an entry already exist, the SEARCH operation is used and we check the aging of the entry. If the entry is not 0, the entry exist and we proceed to delete it.
Current code have 2 main problem:
- The condition to check if the FDB entry exist is wrong and should be the opposite.
- When a FDB entry doesn't exist, aging was never actually set to the STATIC value resulting in allocating an invalid entry.
Fix both problem by adding aging support to the function, calling the function with STATIC as aging by default and finally by correct the condition to check if the entry actually exist.
--- drivers/net/dsa/qca/qca8k-common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/dsa/qca/qca8k-common.c +6 -3
@@ -244,7 +244,7 @@ void qca8k_fdb_flush(struct qca8k_priv * }static int qca8k_fdb_search_and_insert (struct qca8k_priv *priv,u8 port_mask, -const u8 *mac,u16 vid) +const u8 *mac,u16 vid,u8 aging) {struct qca8k_fdb fdb = {0 };int ret;
@@ -261,10 +261,12 @@ static int qca8k_fdb_search_and_insert(s goto exit;/* Rule exist. Delete first */ -if (!fdb.aging) { +if (fdb.aging) { ret =qca8k_fdb_access (priv,QCA8K_FDB_PURGE ,-1 );if (ret) goto exit; + }else { + fdb.aging = aging; }/* Add port to fdb portmask */
@@ -810,7 +812,8 @@ int qca8k_port_mdb_add(struct dsa_switchconst u8 *addr = mdb->addr;u16 vid = mdb->vid; -return qca8k_fdb_search_and_insert (priv,BIT (port), addr, vid); +return qca8k_fdb_search_and_insert (priv,BIT (port), addr, vid, +QCA8K_ATU_STATUS_STATIC ); } int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
Greg Kroah-Hartman
maintainerPATCH 205/239 net: dsa: qca8k: fix broken search_and_del
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit ae70dcb9d9ecaf7d9836d3e1b5bef654d7ef5680 upstream.
On deleting an MDB entry for a port, fdb_search_and_del is used. An FDB entry can't be modified so it needs to be deleted and readded again with the new portmap (and the port deleted as requested)
We use the SEARCH operator to search the entry to edit by vid and mac address and then we check the aging if we actually found an entry.
Currently the code suffer from a bug where the searched fdb entry is never read again with the found values (if found) resulting in the code always returning -EINVAL as aging was always 0.
Fix this by correctly read the fdb entry after it was searched.
--- drivers/net/dsa/qca/qca8k-common.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/dsa/qca/qca8k-common.c +4 -0
@@ -293,6 +293,10 @@ static int qca8k_fdb_search_and_del(struif (ret <0 ) goto exit; + ret =qca8k_fdb_read (priv, &fdb); +if (ret <0 ) + goto exit; +/* Rule doesn't exist. Why delete? */ if (!fdb.aging) { ret = -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 206/239 net: dsa: qca8k: fix mdb add/del case with 0 VID
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit dfd739f182b00b02bd7470ed94d112684cc04fa2 upstream.
The qca8k switch doesn't support using 0 as VID and require a default VID to be always set. MDB add/del function doesn't currently handle this and are currently setting the default VID.
Fix this by correctly handling this corner case and internally use the default VID for VID 0 case.
--- drivers/net/dsa/qca/qca8k-common.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/dsa/qca/qca8k-common.c +6 -0
@@ -816,6 +816,9 @@ int qca8k_port_mdb_add(struct dsa_switchconst u8 *addr = mdb->addr;u16 vid = mdb->vid; +if (!vid) + vid =QCA8K_PORT_VID_DEF ; +return qca8k_fdb_search_and_insert (priv,BIT (port), addr, vid,QCA8K_ATU_STATUS_STATIC ); }
@@ -828,6 +831,9 @@ int qca8k_port_mdb_del(struct dsa_switchconst u8 *addr = mdb->addr;u16 vid = mdb->vid; +if (!vid) + vid =QCA8K_PORT_VID_DEF ; +return qca8k_fdb_search_and_del (priv,BIT (port), addr, vid); }
Greg Kroah-Hartman
maintainerPATCH 207/239 io_uring: gate iowait schedule on having pending requests
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 7b72d661f1f2f950ab8c12de7e2bc48bdac8ed69 upstream.
A previous commit made all cqring waits marked as iowait, as a way to improve performance for short schedules with pending IO. However, for use cases that have a special reaper thread that does nothing but wait on events on the ring, this causes a cosmetic issue where we know have one core marked as being "busy" with 100% iowait.
While this isn't a grave issue, it is confusing to users. Rather than always mark us as being in iowait, gate setting of current->in_iowait to 1 by whether or not the waiting task has pending requests.
--- io_uring/io_uring.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
io_uring/io_uring.c +17 -6
@@ -2579,11 +2579,20 @@ int io_run_task_work_sig(struct io_ring_return 0 ; } +static bool current_pending_io (void ) +{ +struct io_uring_task *tctx = current->io_uring; + +if (!tctx) +return false; +return percpu_counter_read_positive (&tctx->inflight); +} +/* when returns >0, the caller should retry */ static inline int io_cqring_wait_schedule (struct io_ring_ctx *ctx,struct io_wait_queue *iowq) { -int token, ret; +int io_wait, ret;if (unlikely (READ_ONCE (ctx->check_cq)))return 1 ;
@@ -2597,17 +2606,19 @@ static inline int io_cqring_wait_schedulreturn 0 ;/* -* Use io_schedule_prepare/finish, so cpufreq can take into account -* that the task is waiting for IO - turns out to be important for low -* QD IO. +* Mark us as being in io_wait if we have pending requests, so cpufreq +* can take into account that the task is waiting for IO - turns out +* to be important for low QD IO. */ - token =io_schedule_prepare (); + io_wait = current->in_iowait; +if (current_pending_io ()) + current->in_iowait =1 ; ret =0 ;if (iowq->timeout ==KTIME_MAX )schedule ();else if (!schedule_hrtimeout (&iowq->timeout,HRTIMER_MODE_ABS )) ret = -ETIME ; -io_schedule_finish (token); + current->in_iowait = io_wait;return ret; }
Greg Kroah-Hartman
maintainerPATCH 208/239 iommufd: Set end correctly when doing batch carry
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
commit b7c822fa6b7701b17e139f1c562fc24135880ed4 upstream.
Even though the test suite covers this it somehow became obscured that this wasn't working.
The test iommufd_ioas.mock_domain.access_domain_destory would blow up rarely.
end should be set to 1 because this just pushed an item, the carry, to the pfns list.
Sometimes the test would blow up with:
BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP CPU: 5 PID: 584 Comm: iommufd Not tainted 6.5.0-rc1-dirty #1236 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:batch_unpin+0xa2/0x100 [iommufd] Code: 17 48 81 fe ff ff 07 00 77 70 48 8b 15 b7 be 97 e2 48 85 d2 74 14 48 8b 14 fa 48 85 d2 74 0b 40 0f b6 f6 48 c1 e6 04 48 01 f2 <48> 8b 3a 48 c1 e0 06 89 ca 48 89 de 48 83 e7 f0 48 01 c7 e8 96 dc RSP: 0018:ffffc90001677a58 EFLAGS: 00010246 RAX: 00007f7e2646f000 RBX: 0000000000000000 RCX: 0000000000000001 RDX: 0000000000000000 RSI: 00000000fefc4c8d RDI: 0000000000fefc4c RBP: ffffc90001677a80 R08: 0000000000000048 R09: 0000000000000200 R10: 0000000000030b98 R11: ffffffff81f3bb40 R12: 0000000000000001 R13: ffff888101f75800 R14: ffffc90001677ad0 R15: 00000000000001fe FS: 00007f9323679740(0000) GS:ffff8881ba540000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000105ede003 CR4: 00000000003706a0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? show_regs+0x5c/0x70 ? __die+0x1f/0x60 ? page_fault_oops+0x15d/0x440 ? lock_release+0xbc/0x240 ? exc_page_fault+0x4a4/0x970 ? asm_exc_page_fault+0x27/0x30 ? batch_unpin+0xa2/0x100 [iommufd] ? batch_unpin+0xba/0x100 [iommufd] __iopt_area_unfill_domain+0x198/0x430 [iommufd] ? __mutex_lock+0x8c/0xb80 ? __mutex_lock+0x6aa/0xb80 ? xa_erase+0x28/0x30 ? iopt_table_remove_domain+0x162/0x320 [iommufd] ? lock_release+0xbc/0x240 iopt_area_unfill_domain+0xd/0x10 [iommufd] iopt_table_remove_domain+0x195/0x320 [iommufd] iommufd_hw_pagetable_destroy+0xb3/0x110 [iommufd] iommufd_object_destroy_user+0x8e/0xf0 [iommufd] iommufd_device_detach+0xc5/0x140 [iommufd] iommufd_selftest_destroy+0x1f/0x70 [iommufd] iommufd_object_destroy_user+0x8e/0xf0 [iommufd] iommufd_destroy+0x3a/0x50 [iommufd] iommufd_fops_ioctl+0xfb/0x170 [iommufd] __x64_sys_ioctl+0x40d/0x9a0 do_syscall_64+0x3c/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0
--- drivers/iommu/iommufd/pages.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/iommufd/pages.c +1 -1
@@ -297,7 +297,7 @@ static void batch_clear_carry(struct pfn batch->pfns[0 ] = batch->pfns[batch->end -1 ] + (batch->npfns[batch->end -1 ] - keep_pfns); batch->npfns[0 ] = keep_pfns; - batch->end =0 ; + batch->end =1 ; }static void batch_skip_carry (struct pfn_batch *batch,unsigned int skip_pfns)
Greg Kroah-Hartman
maintainerPATCH 209/239 selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 3bcbc20942db5d738221cca31a928efc09827069 upstream.
To allow running rseq and KVM's rseq selftests as statically linked binaries, initialize the various "trampoline" pointers to point directly at the expect glibc symbols, and skip the dlysm() lookups if the rseq size is non-zero, i.e. the binary is statically linked *and* the libc registered its own rseq.
Define weak versions of the symbols so as not to break linking against libc versions that don't support rseq in any capacity.
The KVM selftests in particular are often statically linked so that they can be run on targets with very limited runtime environments, i.e. test machines.
Message-Id: <[email protected]>
--- tools/testing/selftests/rseq/rseq.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
tools/testing/selftests/rseq/rseq.c +22 -6
@@ -34,9 +34,17 @@#include "../kselftest.h" #include "rseq.h" -static const ptrdiff_t *libc_rseq_offset_p; -static const unsigned int *libc_rseq_size_p; -static const unsigned int *libc_rseq_flags_p; +/* +* Define weak versions to play nice with binaries that are statically linked +* against a libc that doesn't support registering its own rseq. +*/ +__weak ptrdiff_t __rseq_offset; +__weak unsigned int __rseq_size; +__weak unsigned int __rseq_flags; + +static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; +static const unsigned int *libc_rseq_size_p = &__rseq_size; +static const unsigned int *libc_rseq_flags_p = &__rseq_flags;/* Offset from the thread pointer to the rseq area. */ ptrdiff_t rseq_offset;
@@ -155,9 +163,17 @@ unsigned int get_rseq_feature_size(void)static __attribute__((constructor))void rseq_init (void ) { - libc_rseq_offset_p =dlsym (RTLD_NEXT ,"__rseq_offset" ); - libc_rseq_size_p =dlsym (RTLD_NEXT ,"__rseq_size" ); - libc_rseq_flags_p =dlsym (RTLD_NEXT ,"__rseq_flags" ); +/* +* If the libc's registered rseq size isn't already valid, it may be +* because the binary is dynamically linked and not necessarily due to +* libc not having registered a restartable sequence. Try to find the +* symbols if that's the case. +*/ +if (!*libc_rseq_size_p) { + libc_rseq_offset_p =dlsym (RTLD_NEXT ,"__rseq_offset" ); + libc_rseq_size_p =dlsym (RTLD_NEXT ,"__rseq_size" ); + libc_rseq_flags_p =dlsym (RTLD_NEXT ,"__rseq_flags" ); + }if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && *libc_rseq_size_p !=0 ) {/* rseq registration owned by glibc */
Greg Kroah-Hartman
maintainerPATCH 210/239 selftests: mptcp: join: only check for ip6tables if needed
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 016e7ba47f33064fbef8c4307a2485d2669dfd03 upstream.
If 'iptables-legacy' is available, 'ip6tables-legacy' command will be used instead of 'ip6tables'. So no need to look if 'ip6tables' is available in this case.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +1 -3
@@ -156,9 +156,7 @@ check_tools() elif ! iptables -V &> /dev/null; then echo "SKIP: Could not run all tests without iptables tool" exit $ksft_skip - fi - - if ! ip6tables -V &> /dev/null; then + elif ! ip6tables -V &> /dev/null; then echo "SKIP: Could not run all tests without ip6tables tool" exit $ksft_skip fi
Greg Kroah-Hartman
maintainerPATCH 211/239 soundwire: fix enumeration completion
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit c40d6b3249b11d60e09d81530588f56233d9aa44 upstream.
The soundwire subsystem uses two completion structures that allow drivers to wait for soundwire device to become enumerated on the bus and initialised by their drivers, respectively.
The code implementing the signalling is currently broken as it does not signal all current and future waiters and also uses the wrong reinitialisation function, which can potentially lead to memory corruption if there are still waiters on the queue.
Not signalling future waiters specifically breaks sound card probe deferrals as codec drivers can not tell that the soundwire device is already attached when being reprobed. Some codec runtime PM implementations suffer from similar problems as waiting for enumeration during resume can also timeout despite the device already having been enumerated.
--- drivers/soundwire/bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/soundwire/bus.c +4 -4
@@ -908,8 +908,8 @@ static void sdw_modify_slave_status(stru"initializing enumeration and init completion for Slave %d\n" , slave->dev_num); -init_completion (&slave->enumeration_complete); -init_completion (&slave->initialization_complete); +reinit_completion (&slave->enumeration_complete); +reinit_completion (&slave->initialization_complete); }else if ((status ==SDW_SLAVE_ATTACHED ) && (slave->status ==SDW_SLAVE_UNATTACHED )) {
@@ -917,7 +917,7 @@ static void sdw_modify_slave_status(stru"signaling enumeration completion for Slave %d\n" , slave->dev_num); -complete (&slave->enumeration_complete); +complete_all (&slave->enumeration_complete); } slave->status = status;mutex_unlock (&bus->bus_lock);
@@ -1941,7 +1941,7 @@ int sdw_handle_slave_status(struct sdw_b"signaling initialization completion for Slave %d\n" , slave->dev_num); -complete (&slave->initialization_complete); +complete_all (&slave->initialization_complete);/* * If the manager became pm_runtime active, the peripherals will be
Greg Kroah-Hartman
maintainerPATCH 212/239 Revert "um: Use swap() to make code cleaner"
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit dddfa05eb58076ad60f9a66e7155a5b3502b2dd5 upstream.
This reverts commit 9b0da3f22307af693be80f5d3a89dc4c7f360a85.
The sigio.c is clearly user space code which is handled by arch/um/scripts/Makefile.rules (see USER_OBJS rule).
The above mentioned commit simply broke this agreement, we may not use Linux kernel internal headers in them without thorough thinking.
Hence, revert the wrong commit.
--- arch/um/os-Linux/sigio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
arch/um/os-Linux/sigio.c +4 -3
@@ -3,7 +3,6 @@* Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) */ -#include <linux/minmax.h> #include <unistd.h> #include <errno.h> #include <fcntl.h>
@@ -51,7 +50,7 @@ static struct pollfds all_sigio_fds;static int write_sigio_thread (void *unused) { -struct pollfds *fds; +struct pollfds *fds, tmp;struct pollfd *p;int i, n, respond_fd;char c;
@@ -78,7 +77,9 @@ static int write_sigio_thread(void *unus"write_sigio_thread : " "read on socket failed, " "err = %d\n", errno); -swap (current_poll, next_poll); + tmp = current_poll; + current_poll = next_poll; + next_poll = tmp; respond_fd = sigio_private[1 ]; }else {
Greg Kroah-Hartman
maintainerPATCH 213/239 LoongArch: Fix return value underflow in exception path
In reply to Greg Kroah-HartmanFrom: WANG Rui <[email protected]>
commit e66d511fc92201ba481392e54896f1aeadfcf0e9 upstream.
This patch fixes an underflow issue in the return value within the exception path, specifically at .Llt8 when the remaining length is less than 8 bytes.
--- arch/loongarch/lib/clear_user.S | 3 ++- arch/loongarch/lib/copy_user.S | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
arch/loongarch/lib/clear_user.S +2 -1
@@ -108,6 +108,7 @@ SYM_FUNC_START(__clear_user_fast) addi.d a3, a2, -8 bgeu a0, a3, .Llt8 15: st.d zero, a0, 0 + addi.d a0, a0, 8 .Llt8: 16: st.d zero, a2, -8
@@ -188,7 +189,7 @@ SYM_FUNC_START(__clear_user_fast) _asm_extable 13b, .L_fixup_handle_0 _asm_extable 14b, .L_fixup_handle_1 _asm_extable 15b, .L_fixup_handle_0 - _asm_extable 16b, .L_fixup_handle_1 + _asm_extable 16b, .L_fixup_handle_0 _asm_extable 17b, .L_fixup_handle_s0 _asm_extable 18b, .L_fixup_handle_s0 _asm_extable 19b, .L_fixup_handle_s0
arch/loongarch/lib/copy_user.S +2 -1
@@ -136,6 +136,7 @@ SYM_FUNC_START(__copy_user_fast) bgeu a1, a4, .Llt8 30: ld.d t0, a1, 0 31: st.d t0, a0, 0 + addi.d a0, a0, 8 .Llt8: 32: ld.d t0, a3, -8
@@ -246,7 +247,7 @@ SYM_FUNC_START(__copy_user_fast) _asm_extable 30b, .L_fixup_handle_0 _asm_extable 31b, .L_fixup_handle_0 _asm_extable 32b, .L_fixup_handle_0 - _asm_extable 33b, .L_fixup_handle_1 + _asm_extable 33b, .L_fixup_handle_0 _asm_extable 34b, .L_fixup_handle_s0 _asm_extable 35b, .L_fixup_handle_s0 _asm_extable 36b, .L_fixup_handle_s0
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 214/239 LoongArch: BPF: Fix check condition to call lu32id in move_imm()
In reply to Greg Kroah-HartmanFrom: Tiezhu Yang <[email protected]>
commit 4eece7e6de94d833c8aeed2f438faf487cbf94ff upstream.
As the code comment says, the initial aim is to reduce one instruction in some corner cases, if bit[51:31] is all 0 or all 1, no need to call lu32id. That is to say, it should call lu32id only if bit[51:31] is not all 0 and not all 1. The current code always call lu32id, the result is right but the logic is unexpected and wrong, fix it.
--- arch/loongarch/net/bpf_jit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/loongarch/net/bpf_jit.h +1 -1
@@ -150,7 +150,7 @@ static inline void move_imm(struct jit_c* no need to call lu32id to do a new filled operation. */ imm_51_31 = (imm >>31 ) &0x1fffff ; -if (imm_51_31 !=0 || imm_51_31 !=0x1fffff ) { +if (imm_51_31 !=0 && imm_51_31 !=0x1fffff ) {/* lu32id rd, imm_51_32 */ imm_51_32 = (imm >>32 ) &0xfffff ;emit_insn (ctx, lu32id, rd, imm_51_32);
Greg Kroah-Hartman
maintainerPATCH 215/239 LoongArch: BPF: Enable bpf_probe_read{, str}() on LoongArch
In reply to Greg Kroah-HartmanFrom: Chenguang Zhao <[email protected]>
commit de0e30bee86d0f99c696a1fea34474e556a946ec upstream.
Currently nettrace does not work on LoongArch due to missing bpf_probe_read{,str}() support, with the error message:
ERROR: failed to load kprobe-based eBPF
ERROR: failed to load kprobe-based bpf
According to commit 0ebeea8ca8a4d1d ("bpf: Restrict bpf_probe_read{, str}() only to archs where they work"), we only need to select CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE to add said support, because LoongArch does have non-overlapping address ranges for kernel and userspace.
--- arch/loongarch/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/loongarch/Kconfig +1 -0
@@ -12,6 +12,7 @@ config LOONGARCH select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_INLINE_READ_LOCK if !PREEMPTION
Greg Kroah-Hartman
maintainerPATCH 216/239 9p: fix ignored return value in v9fs_dir_release
In reply to Greg Kroah-HartmanFrom: Dominique Martinet <[email protected]>
commit eee4a119e96c2f58cfd1b6d4de42095abc5f8877 upstream.
retval from filemap_fdatawrite was immediately overwritten by the following p9_fid_put: preserve any error in fdatawrite if there was any first.
This fixes the following scan-build warning:fs/9p/vfs_dir.c:220:4: warning: Value stored to 'retval' is never read [deadcode.DeadStores]
retval = filemap_fdatawrite(inode->i_mapping);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- fs/9p/vfs_dir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/9p/vfs_dir.c +3 -2
@@ -208,7 +208,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)struct p9_fid *fid;__le32 version;loff_t i_size; -int retval =0 ; +int retval =0 , put_err; fid = filp->private_data; p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
@@ -221,7 +221,8 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)spin_lock (&inode->i_lock);hlist_del (&fid->ilist);spin_unlock (&inode->i_lock); - retval =p9_fid_put (fid); + put_err =p9_fid_put (fid); + retval = retval <0 ? retval : put_err; }if ((filp->f_mode &FMODE_WRITE )) {
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 217/239 fs/9p: remove unnecessary and overrestrictive check
In reply to Greg Kroah-HartmanFrom: Eric Van Hensbergen <[email protected]>
commit 75b396821cb71164dac3a1ad51dda4781ea8dbad upstream.
This eliminates a check for shared that was overrestrictive and prevented read-only mmaps when writeback caches weren't enabled.
--- fs/9p/vfs_file.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/9p/vfs_file.c +1 -3
@@ -483,9 +483,7 @@ v9fs_file_mmap(struct file *filp, structp9_debug (P9_DEBUG_MMAP ,"filp :%p\n" , filp);if (!(v9ses->cache &CACHE_WRITEBACK )) { -p9_debug (P9_DEBUG_CACHE ,"(no mmap mode)" ); -if (vma->vm_flags &VM_MAYSHARE ) -return -ENODEV ; +p9_debug (P9_DEBUG_CACHE ,"(read-only mmap mode)" );invalidate_inode_pages2 (filp->f_mapping);return generic_file_readonly_mmap (filp, vma); }
Greg Kroah-Hartman
maintainerPATCH 218/239 fs/9p: fix typo in comparison logic for cache mode
In reply to Greg Kroah-HartmanFrom: Eric Van Hensbergen <[email protected]>
commit 878cb3e0337d7c3096aee301a2a3cd358dc8aa81 upstream.
There appears to be a typo in the comparison statement for the logic which sets a file's cache mode based on mount flags.
--- fs/9p/fid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/9p/fid.h +1 -1
@@ -57,7 +57,7 @@ static inline void v9fs_fid_add_modes(st (s_flags & V9FS_DIRECT_IO) || (f_flags & O_DIRECT)) { fid->mode |=P9L_DIRECT ;/* no read or write cache */ } else if ((!(s_cache & CACHE_WRITEBACK)) || - (f_flags & O_DSYNC) | (s_flags & V9FS_SYNC)) { + (f_flags & O_DSYNC) || (s_flags & V9FS_SYNC)) { fid->mode |=P9L_NOWRITECACHE ; } }
Greg Kroah-Hartman
maintainerPATCH 219/239 fs/9p: fix type mismatch in file cache mode helper
In reply to Greg Kroah-HartmanFrom: Eric Van Hensbergen <[email protected]>
commit 09430aba3a9ffd986834614a3406a13588170bde upstream.
There were two flags (s_flags and s_cache) which had incorrect signed type in the parameters of the file cache mode helper function.
--- fs/9p/fid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/9p/fid.h +2 -2
@@ -46,8 +46,8 @@ static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)* NOTE: these are set after open so only reflect 9p client not * underlying file system on server. */ -static inline void v9fs_fid_add_modes (struct p9_fid *fid,int s_flags, -int s_cache,unsigned int f_flags) +static inline void v9fs_fid_add_modes (struct p9_fid *fid,unsigned int s_flags, +unsigned int s_cache,unsigned int f_flags) {if (fid->qid.type !=P9_QTFILE )return ;
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 220/239 fs/9p: remove unnecessary invalidate_inode_pages2
In reply to Greg Kroah-HartmanFrom: Eric Van Hensbergen <[email protected]>
commit 350cd9b959757e7c571f45fab29d116d5f67cbff upstream.
There was an invalidate_inode_pages2 added to readonly mmap path that is unnecessary since that path is only entered when writeback cache is disabled on mount.
--- fs/9p/vfs_file.c | 1 - 1 file changed, 1 deletion(-)
fs/9p/vfs_file.c +0 -1
@@ -484,7 +484,6 @@ v9fs_file_mmap(struct file *filp, structif (!(v9ses->cache &CACHE_WRITEBACK )) {p9_debug (P9_DEBUG_CACHE ,"(read-only mmap mode)" ); -invalidate_inode_pages2 (filp->f_mapping);return generic_file_readonly_mmap (filp, vma); }
Greg Kroah-Hartman
maintainerPATCH 221/239 s390/dasd: fix hanging device after quiesce/resume
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 05f1d8ed03f547054efbc4d29bb7991c958ede95 upstream.
Quiesce and resume are functions that tell the DASD driver to stop/resume issuing I/Os to a specific DASD.
On resume dasd_schedule_block_bh() is called to kick handling of IO requests again. This does unfortunately not cover internal requests which are used for path verification for example.
This could lead to a hanging device when a path event or anything else that triggers internal requests occurs on a quiesced device.
Fix by also calling dasd_schedule_device_bh() which triggers handling of internal requests on resume.
--- drivers/s390/block/dasd_ioctl.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/block/dasd_ioctl.c +1 -0
@@ -131,6 +131,7 @@ static int dasd_ioctl_resume(struct dasdspin_unlock_irqrestore (get_ccwdev_lock (base->cdev), flags);dasd_schedule_block_bh (block); +dasd_schedule_device_bh (base);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 222/239 s390/dasd: print copy pair message only for the correct error
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 856d8e3c633b183df23549ce760ae84478a7098d upstream.
The DASD driver has certain types of requests that might be rejected by the storage server or z/VM because they are not supported. Since the missing support of the command is not a real issue there is no user visible kernel error message for this.
For copy pair setups there is a specific error that IO is not allowed on secondary devices. This error case is explicitly handled and an error message is printed.
The code checking for the error did use a bitwise 'and' that is used to check for specific bits. But in this case the whole sense byte has to match.
This leads to the problem that the copy pair related error message is erroneously printed for other error cases that are usually not reported. This might heavily confuse users and lead to follow on actions that might disrupt application processing.
Fix by checking the sense byte for the exact value and not single bits.
--- drivers/s390/block/dasd_3990_erp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/block/dasd_3990_erp.c +1 -1
@@ -1050,7 +1050,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_redev_err (&device->cdev->dev,"An I/O request was rejected" " because writing is inhibited\n" ); erp =dasd_3990_erp_cleanup (erp,DASD_CQR_FAILED ); - }else if (sense[7 ] &SNS7_INVALID_ON_SEC ) { + }else if (sense[7 ] ==SNS7_INVALID_ON_SEC ) {dev_err (&device->cdev->dev,"An I/O request was rejected on a copy pair secondary device\n" );/* suppress dump of sense data for this error */ set_bit (DASD_CQR_SUPPRESS_CR , &erp->refers->flags);
Greg Kroah-Hartman
maintainerPATCH 223/239 mptcp: more accurate NL event generation
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
commit 21d9b73a7d5241905367098d260a3c68b811da32 upstream.
Currently the mptcp code generate a "new listener" event even if the actual listen() syscall fails. Address the issue moving the event generation call under the successful branch.
--- net/mptcp/protocol.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/mptcp/protocol.c +1 -2
@@ -3717,10 +3717,9 @@ static int mptcp_listen(struct socket *sif (!err) {sock_prot_inuse_add (sock_net (sk), sk->sk_prot,1 );mptcp_copy_inaddrs (sk, ssock->sk); +mptcp_event_pm_listener (ssock->sk,MPTCP_EVENT_LISTENER_CREATED ); } -mptcp_event_pm_listener (ssock->sk,MPTCP_EVENT_LISTENER_CREATED ); - unlock:release_sock (sk);return err;
Greg Kroah-Hartman
maintainerPATCH 224/239 ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit f061e2be8689057cb4ec0dbffa9f03e1a23cdcb2 upstream.
The WM8904_ADC_TEST_0 register is modified as part of updating the OSR controls but does not have a cache default, leading to errors when we try to modify these controls in cache only mode with no prior read:
wm8904 3-001a: ASoC: error at snd_soc_component_update_bits on wm8904.3-001a for register: [0x000000c6] -16
Add a read of the register to probe() to fill the cache and avoid both the error messages and the misconfiguration of the chip which will result.
--- sound/soc/codecs/wm8904.c | 3 +++ 1 file changed, 3 insertions(+)
sound/soc/codecs/wm8904.c +3 -0
@@ -2308,6 +2308,9 @@ static int wm8904_i2c_probe(struct i2c_cregmap_update_bits (wm8904->regmap,WM8904_BIAS_CONTROL_0 ,WM8904_POBCTRL ,0 ); +/* Fill the cache for the ADC test register */ +regmap_read (wm8904->regmap,WM8904_ADC_TEST_0 , &val); +/* Can leave the device powered off until we need it */ regcache_cache_only (wm8904->regmap, true);regulator_bulk_disable (ARRAY_SIZE (wm8904->supplies), wm8904->supplies);
Greg Kroah-Hartman
maintainerPATCH 225/239 arm64/sme: Set new vector length before reallocating
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit 05d881b85b48c7ac6a7c92ce00aa916c4a84d052 upstream.
As part of fixing the allocation of the buffer for SVE state when changing SME vector length we introduced an immediate reallocation of the SVE state, this is also done when changing the SVE vector length for consistency. Unfortunately this reallocation is done prior to writing the new vector length to the task struct, meaning the allocation is done with the old vector length and can lead to memory corruption due to an undersized buffer being used.
Move the update of the vector length before the allocation to ensure that the new vector length is taken into account.
For some reason this isn't triggering any problems when running tests on the arm64 fixes branch (even after repeated tries) but is triggering issues very often after merge into mainline.
--- arch/arm64/kernel/fpsimd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/fpsimd.c +2 -2
@@ -917,6 +917,8 @@ int vec_set_vector_length(struct task_stif (task == current)put_cpu_fpsimd_context (); +task_set_vl (task, type, vl); +/* * Free the changed states if they are not in use, SME will be * reallocated to the correct size on next use and we just
@@ -931,8 +933,6 @@ int vec_set_vector_length(struct task_stif (free_sme)sme_free (task); -task_set_vl (task, type, vl); - out:update_tsk_thread_flag (task,vec_vl_inherit_flag (type), flags &PR_SVE_VL_INHERIT );
Greg Kroah-Hartman
maintainerPATCH 226/239 PM: sleep: wakeirq: fix wake irq arming
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 8527beb12087238d4387607597b4020bc393c4b4 upstream.
The decision whether to enable a wake irq during suspend can not be done based on the runtime PM state directly as a driver may use wake irqs without implementing runtime PM. Such drivers specifically leave the state set to the default 'suspended' and the wake irq is thus never enabled at suspend.
Add a new wake irq flag to track whether a dedicated wake irq has been enabled at runtime suspend and therefore must not be enabled at system suspend.
Note that pm_runtime_enabled() can not be used as runtime PM is always disabled during late suspend.
--- drivers/base/power/power.h | 1 + drivers/base/power/wakeirq.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-)
drivers/base/power/power.h +1 -0
@@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct#define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ WAKE_IRQ_DEDICATED_MANAGED | \ WAKE_IRQ_DEDICATED_REVERSE) +#define WAKE_IRQ_DEDICATED_ENABLED BIT(3)struct wake_irq {struct device *dev;
drivers/base/power/wakeirq.c +8 -4
@@ -314,8 +314,10 @@ void dev_pm_enable_wake_irq_check(structreturn ; enable: -if (!can_change_status || !(wirq->status &WAKE_IRQ_DEDICATED_REVERSE )) +if (!can_change_status || !(wirq->status &WAKE_IRQ_DEDICATED_REVERSE )) {enable_irq (wirq->irq); + wirq->status |=WAKE_IRQ_DEDICATED_ENABLED ; + } }/**
@@ -336,8 +338,10 @@ void dev_pm_disable_wake_irq_check(strucif (cond_disable && (wirq->status &WAKE_IRQ_DEDICATED_REVERSE ))return ; -if (wirq->status &WAKE_IRQ_DEDICATED_MANAGED ) +if (wirq->status &WAKE_IRQ_DEDICATED_MANAGED ) { + wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED ;disable_irq_nosync (wirq->irq); + } }/**
@@ -376,7 +380,7 @@ void dev_pm_arm_wake_irq(struct wake_irqif (device_may_wakeup (wirq->dev)) {if (wirq->status &WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended (wirq->dev)) + !(wirq->status &WAKE_IRQ_DEDICATED_ENABLED ))enable_irq (wirq->irq);enable_irq_wake (wirq->irq);
@@ -399,7 +403,7 @@ void dev_pm_disarm_wake_irq(struct wake_disable_irq_wake (wirq->irq);if (wirq->status &WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended (wirq->dev)) + !(wirq->status &WAKE_IRQ_DEDICATED_ENABLED ))disable_irq_nosync (wirq->irq); } }
Greg Kroah-Hartman
maintainerPATCH 227/239 thermal: of: fix double-free on unregistration
In reply to Greg Kroah-HartmanFrom: Ahmad Fatoum <[email protected]>
commit ac4436a5b20e0ef1f608a9ef46c08d5d142f8da6 upstream.
Since commit 3d439b1a2ad3 ("thermal/core: Alloc-copy-free the thermal zone parameters structure"), thermal_zone_device_register() allocates a copy of the tzp argument and frees it when unregistering, so thermal_of_zone_register() now ends up leaking its original tzp and double-freeing the tzp copy. Fix this by locating tzp on stack instead.
--- drivers/thermal/thermal_of.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-)
drivers/thermal/thermal_of.c +6 -21
@@ -238,17 +238,13 @@ static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdelreturn 0 ; } -static struct thermal_zone_params *thermal_of_parameters_init (struct device_node *np) +static void thermal_of_parameters_init (struct device_node *np, +struct thermal_zone_params *tzp) { -struct thermal_zone_params *tzp;int coef[2 ];int ncoef =ARRAY_SIZE (coef);int prop, ret; - tzp =kzalloc (sizeof (*tzp),GFP_KERNEL ); -if (!tzp) -return ERR_PTR (-ENOMEM ); - tzp->no_hwmon = true;if (!of_property_read_u32 (np,"sustainable-power" , &prop))
@@ -267,8 +263,6 @@ static struct thermal_zone_params *thermal_of_parameters_init(struct device_node tzp->slope = coef[0 ]; tzp->offset = coef[1 ]; - -return tzp; }static struct device_node *thermal_of_zone_get_by_name (struct thermal_zone_device *tz)
@@ -442,13 +436,11 @@ static int thermal_of_unbind(struct thermal_zone_device *tz,static void thermal_of_zone_unregister (struct thermal_zone_device *tz) {struct thermal_trip *trips = tz->trips; -struct thermal_zone_params *tzp = tz->tzp;struct thermal_zone_device_ops *ops = tz->ops;thermal_zone_device_disable (tz);thermal_zone_device_unregister (tz);kfree (trips); -kfree (tzp);kfree (ops); }
@@ -477,7 +469,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * {struct thermal_zone_device *tz;struct thermal_trip *trips; -struct thermal_zone_params *tzp; +struct thermal_zone_params tzp = {};struct thermal_zone_device_ops *of_ops;struct device_node *np;int delay, pdelay;
@@ -509,12 +501,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * goto out_kfree_trips; } - tzp =thermal_of_parameters_init (np); -if (IS_ERR (tzp)) { - ret =PTR_ERR (tzp); -pr_err ("Failed to initialize parameter from %pOFn: %d\n" , np, ret); - goto out_kfree_trips; - } +thermal_of_parameters_init (np, &tzp); of_ops->bind = thermal_of_bind; of_ops->unbind = thermal_of_unbind;
@@ -522,12 +509,12 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * mask =GENMASK_ULL ((ntrips) -1 ,0 ); tz =thermal_zone_device_register_with_trips (np->name, trips, ntrips, - mask, data, of_ops, tzp, + mask, data, of_ops, &tzp, pdelay, delay);if (IS_ERR (tz)) { ret =PTR_ERR (tz);pr_err ("Failed to register thermal zone %pOFn: %d\n" , np, ret); - goto out_kfree_tzp; + goto out_kfree_trips; } ret =thermal_zone_device_enable (tz);
@@ -540,8 +527,6 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *return tz; -out_kfree_tzp: -kfree (tzp); out_kfree_trips:kfree (trips); out_kfree_of_ops:
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 228/239 ceph: never send metrics if disable_send_metrics is set
In reply to Greg Kroah-HartmanFrom: Xiubo Li <[email protected]>
commit 50164507f6b7b7ed85d8c3ac0266849fbd908db7 upstream.
Even the 'disable_send_metrics' is true so when the session is being opened it will always trigger to send the metric for the first time.
--- fs/ceph/metric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ceph/metric.c +1 -1
@@ -208,7 +208,7 @@ static void metric_delayed_work(struct wstruct ceph_mds_client *mdsc = container_of(m, struct ceph_mds_client, metric); -if (mdsc->stopping) +if (mdsc->stopping || disable_send_metrics)return ;if (!m->session || !check_session_state (m->session)) {
Greg Kroah-Hartman
maintainerPATCH 229/239 drm/i915/dpt: Use shmem for dpt objects
In reply to Greg Kroah-HartmanFrom: Radhakrishna Sripada <[email protected]>
commit 3844ed5e78823eebb5f0f1edefc403310693d402 upstream.
Dpt objects that are created from internal get evicted when there is memory pressure and do not get restored when pinned during scanout. The pinned page table entries look corrupted and programming the display engine with the incorrect pte's result in DE throwing pipe faults.
Create DPT objects from shmem and mark the object as dirty when pinning so that the object is restored when shrinker evicts an unpinned buffer object.
v2: Unconditionally mark the dpt objects dirty during pinning(Chris).
--- drivers/gpu/drm/i915/display/intel_dpt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_dpt.c +3 -1
@@ -166,6 +166,8 @@ struct i915_vma *intel_dpt_pin(struct i9i915_vma_get (vma); } + dpt->obj->mm.dirty = true; +atomic_dec (&i915->gpu_error.pending_fb_pin);intel_runtime_pm_put (&i915->runtime_pm, wakeref);
@@ -261,7 +263,7 @@ intel_dpt_create(struct intel_framebuffe dpt_obj =i915_gem_object_create_stolen (i915, size);if (IS_ERR (dpt_obj) && !HAS_LMEM (i915)) {drm_dbg_kms (&i915->drm,"Allocating dpt from smem\n" ); - dpt_obj =i915_gem_object_create_internal (i915, size); + dpt_obj =i915_gem_object_create_shmem (i915, size); }if (IS_ERR (dpt_obj))return ERR_CAST (dpt_obj);
Greg Kroah-Hartman
maintainerPATCH 230/239 dm cache policy smq: ensure IO doesnt prevent cleaner policy progress
In reply to Greg Kroah-HartmanFrom: Joe Thornber <[email protected]>
commit 1e4ab7b4c881cf26c1c72b3f56519e03475486fb upstream.
When using the cleaner policy to decommission the cache, there is never any writeback started from the cache as it is constantly delayed due to normal I/O keeping the device busy. Meaning @idle=false was always being passed to clean_target_met()
Fix this by adding a specific 'cleaner' flag that is set when the cleaner policy is configured. This flag serves to always allow the cleaner's writeback work to be queued until the cache is decommissioned (even if the cache isn't idle).
--- drivers/md/dm-cache-policy-smq.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
drivers/md/dm-cache-policy-smq.c +18 -10
@@ -857,7 +857,13 @@ struct smq_policy {struct background_tracker *bg_work; -bool migrations_allowed; + bool migrations_allowed:1; + +/* +* If this is set the policy will try and clean the whole cache +* even if the device is not idle. +*/ + bool cleaner:1; };/*----------------------------------------------------------------*/
@@ -1138,7 +1144,7 @@ static bool clean_target_met(struct smq_* Cache entries may not be populated. So we cannot rely on the * size of the clean queue. */ -if (idle) { +if (idle || mq->cleaner) {/* * We'd like to clean everything. */
@@ -1722,11 +1728,9 @@ static void calc_hotspot_params(sector_t *hotspot_block_size /=2u ; } -static struct dm_cache_policy *__smq_create (dm_cblock_t cache_size, -sector_t origin_size, -sector_t cache_block_size, -bool mimic_mq, -bool migrations_allowed) +static struct dm_cache_policy * +__smq_create (dm_cblock_t cache_size,sector_t origin_size,sector_t cache_block_size, +bool mimic_mq,bool migrations_allowed,bool cleaner) {unsigned int i;unsigned int nr_sentinels_per_queue =2u *NR_CACHE_LEVELS ;
@@ -1813,6 +1817,7 @@ static struct dm_cache_policy *__smq_cre goto bad_btracker; mq->migrations_allowed = migrations_allowed; + mq->cleaner = cleaner;return &mq->policy;
@@ -1836,21 +1841,24 @@ static struct dm_cache_policy *smq_creatsector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, false, true); + return __smq_create(cache_size, origin_size, cache_block_size, +false ,true ,false ); }static struct dm_cache_policy *mq_create (dm_cblock_t cache_size,sector_t origin_size,sector_t cache_block_size) { -return __smq_create (cache_size, origin_size, cache_block_size, true, true); +return __smq_create (cache_size, origin_size, cache_block_size, + true, true, false); }static struct dm_cache_policy *cleaner_create (dm_cblock_t cache_size,sector_t origin_size,sector_t cache_block_size) { -return __smq_create (cache_size, origin_size, cache_block_size, false, false); +return __smq_create (cache_size, origin_size, cache_block_size, + false, false, true); }/*----------------------------------------------------------------*/
Greg Kroah-Hartman
maintainerPATCH 231/239 rbd: make get_lock_owner_info() return a single locker or NULL
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit f38cb9d9c2045dad16eead4a2e1aedfddd94603b upstream.
Make the "num_lockers can be only 0 or 1" assumption explicit and simplify the API by getting rid of output parameters in preparation for calling get_lock_owner_info() twice before blocklisting.
--- drivers/block/rbd.c | 84 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 33 deletions(-)
drivers/block/rbd.c +51 -33
@@ -3849,10 +3849,17 @@ static void wake_lock_waiters(struct rbdlist_splice_tail_init (&rbd_dev->acquiring_list, &rbd_dev->running_list); } -static int get_lock_owner_info (struct rbd_device *rbd_dev, -struct ceph_locker **lockers,u32 *num_lockers) +static void free_locker (struct ceph_locker *locker) +{ +if (locker) +ceph_free_lockers (locker,1 ); +} + +static struct ceph_locker *get_lock_owner_info (struct rbd_device *rbd_dev) {struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; +struct ceph_locker *lockers; +u32 num_lockers;u8 lock_type;char *lock_tag;int ret;
@@ -3861,39 +3868,45 @@ static int get_lock_owner_info(struct rb ret =ceph_cls_lock_info (osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME , - &lock_type, &lock_tag, lockers, num_lockers); -if (ret) -return ret; + &lock_type, &lock_tag, &lockers, &num_lockers); +if (ret) { +rbd_warn (rbd_dev,"failed to retrieve lockers: %d" , ret); +return ERR_PTR (ret); + } -if (*num_lockers ==0 ) { +if (num_lockers ==0 ) {dout ("%s rbd_dev %p no lockers detected\n" , __func__, rbd_dev); + lockers =NULL ; goto out; }if (strcmp (lock_tag,RBD_LOCK_TAG )) {rbd_warn (rbd_dev,"locked by external mechanism, tag %s" , lock_tag); - ret = -EBUSY ; - goto out; + goto err_busy; }if (lock_type ==CEPH_CLS_LOCK_SHARED ) {rbd_warn (rbd_dev,"shared lock type detected" ); - ret = -EBUSY ; - goto out; + goto err_busy; } -if (strncmp ((*lockers)[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX , +WARN_ON (num_lockers !=1 ); +if (strncmp (lockers[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX ,strlen (RBD_LOCK_COOKIE_PREFIX ))) {rbd_warn (rbd_dev,"locked by external mechanism, cookie %s" , - (*lockers)[0 ].id.cookie); - ret = -EBUSY ; - goto out; + lockers[0 ].id.cookie); + goto err_busy; } out:kfree (lock_tag); -return ret; +return lockers; + +err_busy: +kfree (lock_tag); +ceph_free_lockers (lockers, num_lockers); +return ERR_PTR (-EBUSY ); } static int find_watcher(struct rbd_device *rbd_dev,
@@ -3947,51 +3960,56 @@ out:static int rbd_try_lock (struct rbd_device *rbd_dev) {struct ceph_client *client = rbd_dev->rbd_client->client; -struct ceph_locker *lockers; -u32 num_lockers; +struct ceph_locker *locker;int ret;for (;;) { + locker =NULL ; + ret =rbd_lock (rbd_dev);if (ret != -EBUSY ) -return ret; + goto out;/* determine if the current lock holder is still alive */ - ret =get_lock_owner_info (rbd_dev, &lockers, &num_lockers); -if (ret) -return ret; - -if (num_lockers ==0 ) + locker =get_lock_owner_info (rbd_dev); +if (IS_ERR (locker)) { + ret =PTR_ERR (locker); + locker =NULL ; + goto out; + } +if (!locker) goto again; - ret =find_watcher (rbd_dev, lockers); + ret =find_watcher (rbd_dev, locker);if (ret) goto out;/* request lock or error */ rbd_warn (rbd_dev,"breaking header lock owned by %s%llu" , -ENTITY_NAME (lockers[0 ].id.name)); +ENTITY_NAME (locker->id.name)); ret =ceph_monc_blocklist_add (&client->monc, - &lockers[0 ].info.addr); + &locker->info.addr);if (ret) { -rbd_warn (rbd_dev,"blocklist of %s%llu failed: %d" , -ENTITY_NAME (lockers[0 ].id.name), ret); +rbd_warn (rbd_dev,"failed to blocklist %s%llu: %d" , +ENTITY_NAME (locker->id.name), ret); goto out; } ret =ceph_cls_break_lock (&client->osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME , - lockers[0 ].id.cookie, - &lockers[0 ].id.name); -if (ret && ret != -ENOENT ) + locker->id.cookie, &locker->id.name); +if (ret && ret != -ENOENT ) { +rbd_warn (rbd_dev,"failed to break header lock: %d" , + ret); goto out; + } again: -ceph_free_lockers (lockers, num_lockers); +free_locker (locker); } out: -ceph_free_lockers (lockers, num_lockers); +free_locker (locker);return ret; }
Greg Kroah-Hartman
maintainerPATCH 232/239 rbd: harden get_lock_owner_info() a bit
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit 8ff2c64c9765446c3cef804fb99da04916603e27 upstream.
- we want the exclusive lock type, so test for it directly
- use sscanf() to actually parse the lock cookie and avoid admitting invalid handles
- bail if locker has a blank address
--- drivers/block/rbd.c | 21 +++++++++++++++------ net/ceph/messenger.c | 1 + 2 files changed, 16 insertions(+), 6 deletions(-)
drivers/block/rbd.c +15 -6
@@ -3862,10 +3862,9 @@ static struct ceph_locker *get_lock_owneu32 num_lockers;u8 lock_type;char *lock_tag; +u64 handle;int ret; -dout ("%s rbd_dev %p\n" , __func__, rbd_dev); - ret =ceph_cls_lock_info (osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME , &lock_type, &lock_tag, &lockers, &num_lockers);
@@ -3886,18 +3885,28 @@ static struct ceph_locker *get_lock_owne goto err_busy; } -if (lock_type ==CEPH_CLS_LOCK_SHARED ) { -rbd_warn (rbd_dev,"shared lock type detected" ); +if (lock_type !=CEPH_CLS_LOCK_EXCLUSIVE ) { +rbd_warn (rbd_dev,"incompatible lock type detected" ); goto err_busy; }WARN_ON (num_lockers !=1 ); -if (strncmp (lockers[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX , -strlen (RBD_LOCK_COOKIE_PREFIX ))) { + ret =sscanf (lockers[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX " %llu" , + &handle); +if (ret !=1 ) {rbd_warn (rbd_dev,"locked by external mechanism, cookie %s" , lockers[0 ].id.cookie); goto err_busy; } +if (ceph_addr_is_blank (&lockers[0 ].info.addr)) { +rbd_warn (rbd_dev,"locker has a blank address" ); + goto err_busy; + } + +dout ("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n" , + __func__, rbd_dev,ENTITY_NAME (lockers[0 ].id.name), + &lockers[0 ].info.addr.in_addr, +le32_to_cpu (lockers[0 ].info.addr.nonce), handle); out:kfree (lock_tag);
net/ceph/messenger.c +1 -0
@@ -1123,6 +1123,7 @@ bool ceph_addr_is_blank(const struct cepreturn true; } } +EXPORT_SYMBOL (ceph_addr_is_blank);int ceph_addr_port (const struct ceph_entity_addr *addr) {
Greg Kroah-Hartman
maintainerPATCH 233/239 rbd: retrieve and check lock owner twice before blocklisting
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit 588159009d5b7a09c3e5904cffddbe4a4e170301 upstream.
An attempt to acquire exclusive lock can race with the current lock owner closing the image:
1. lock is held by client123, rbd_lock() returns -EBUSY
2. get_lock_owner_info() returns client123 instance details
3. client123 closes the image, lock is released
4. find_watcher() returns 0 as there is no matching watcher anymore
5. client123 instance gets erroneously blocklisted
Particularly impacted is mirror snapshot scheduler in snapshot-based mirroring since it happens to open and close images a lot (images are opened only for as long as it takes to take the next mirror snapshot, the same client instance is used for all images).
To reduce the potential for erroneous blocklisting, retrieve the lock owner again after find_watcher() returns 0. If it's still there, make sure it matches the previously detected lock owner.
--- drivers/block/rbd.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
drivers/block/rbd.c +23 -2
@@ -3849,6 +3849,15 @@ static void wake_lock_waiters(struct rbdlist_splice_tail_init (&rbd_dev->acquiring_list, &rbd_dev->running_list); } +static bool locker_equal (const struct ceph_locker *lhs, +const struct ceph_locker *rhs) +{ +return lhs->id.name.type == rhs->id.name.type && + lhs->id.name.num == rhs->id.name.num && + !strcmp (lhs->id.cookie, rhs->id.cookie) && +ceph_addr_equal_no_type (&lhs->info.addr, &rhs->info.addr); +} +static void free_locker (struct ceph_locker *locker) {if (locker)
@@ -3969,11 +3978,11 @@ out:static int rbd_try_lock (struct rbd_device *rbd_dev) {struct ceph_client *client = rbd_dev->rbd_client->client; -struct ceph_locker *locker; +struct ceph_locker *locker, *refreshed_locker;int ret;for (;;) { - locker =NULL ; + locker = refreshed_locker =NULL ; ret =rbd_lock (rbd_dev);if (ret != -EBUSY )
@@ -3993,6 +4002,16 @@ static int rbd_try_lock(struct rbd_devicif (ret) goto out;/* request lock or error */ + refreshed_locker =get_lock_owner_info (rbd_dev); +if (IS_ERR (refreshed_locker)) { + ret =PTR_ERR (refreshed_locker); + refreshed_locker =NULL ; + goto out; + } +if (!refreshed_locker || + !locker_equal (locker, refreshed_locker)) + goto again; +rbd_warn (rbd_dev,"breaking header lock owned by %s%llu" ,ENTITY_NAME (locker->id.name));
@@ -4014,10 +4033,12 @@ static int rbd_try_lock(struct rbd_devic } again: +free_locker (refreshed_locker);free_locker (locker); } out: +free_locker (refreshed_locker);free_locker (locker);return ret; }
Greg Kroah-Hartman
maintainerPATCH 234/239 mm: lock VMA in dup_anon_vma() before setting ->anon_vma
In reply to Greg Kroah-HartmanFrom: Jann Horn <[email protected]>
commit d8ab9f7b644a2c9b64de405c1953c905ff219dc9 upstream.
When VMAs are merged, dup_anon_vma() is called with dst pointing to the VMA that is being expanded to cover the area previously occupied by another VMA. This currently happens while dst is not write-locked.
This means that, in the src->anon_vma && !dst->anon_vma case, as soon as the assignment dst->anon_vma = src->anon_vma has happened, concurrent page faults can happen on dst under the per-VMA lock. This is already icky in itself, since such page faults can now install pages into dst that are attached to an anon_vma that is not yet tied back to the anon_vma with an anon_vma_chain. But if anon_vma_clone() fails due to an out-of-memory error, things get much worse: anon_vma_clone() then reverts dst->anon_vma back to NULL, and dst remains completely unconnected to the anon_vma, even though we can have pages in the area covered by dst that point to the anon_vma.
This means the anon_vma of such pages can be freed while the pages are still mapped into userspace, which leads to UAF when a helper like folio_lock_anon_vma_read() tries to look up the anon_vma of such a page.
This theoretically is a security bug, but I believe it is really hard to actually trigger as an unprivileged user because it requires that you can make an order-0 GFP_KERNEL allocation fail, and the page allocator tries pretty hard to prevent that.
I think doing the vma_start_write() call inside dup_anon_vma() is the most straightforward fix for now.
For a kernel-assisted reproducer, see the notes section of the patch mail.
--- mm/mmap.c | 1 + 1 file changed, 1 insertion(+)
mm/mmap.c +1 -0
@@ -647,6 +647,7 @@ static inline int dup_anon_vma(struct vm* anon pages imported. */ if (src->anon_vma && !dst->anon_vma) { +vma_start_write (dst); dst->anon_vma = src->anon_vma;return anon_vma_clone (dst, src); }
Greg Kroah-Hartman
maintainerPATCH 235/239 mm: fix memory ordering for mm_lock_seq and vm_lock_seq
In reply to Greg Kroah-HartmanFrom: Jann Horn <[email protected]>
commit b1f02b95758d05b799731d939e76a0bd6da312db upstream.
mm->mm_lock_seq effectively functions as a read/write lock; therefore it must be used with acquire/release semantics.
A specific example is the interaction between userfaultfd_register() and lock_vma_under_rcu().
userfaultfd_register() does the following from the point where it changes a VMA's flags to the point where concurrent readers are permitted again (in a simple scenario where only a single private VMA is accessed and no merging/splitting is involved):
userfaultfd_register
userfaultfd_set_vm_flags
vm_flags_reset
vma_start_write
down_write(&vma->vm_lock->lock)
vma->vm_lock_seq = mm_lock_seq [marks VMA as busy]
up_write(&vma->vm_lock->lock)
vm_flags_init
[sets VM_UFFD_* in __vm_flags]
vma->vm_userfaultfd_ctx.ctx = ctx
mmap_write_unlock
vma_end_write_all
WRITE_ONCE(mm->mm_lock_seq, mm->mm_lock_seq + 1) [unlocks VMA]There are no memory barriers in between the __vm_flags update and the mm->mm_lock_seq update that unlocks the VMA, so the unlock can be reordered to above the vm_flags_init() call, which means from the perspective of a concurrent reader, a VMA can be marked as a userfaultfd VMA while it is not VMA-locked. That's bad, we definitely need a store-release for the unlock operation.
The non-atomic write to vma->vm_lock_seq in vma_start_write() is mostly fine because all accesses to vma->vm_lock_seq that matter are always protected by the VMA lock. There is a racy read in vma_start_read() though that can tolerate false-positives, so we should be using WRITE_ONCE() to keep things tidy and data-race-free (including for KCSAN).
On the other side, lock_vma_under_rcu() works as follows in the relevant region for locking and userfaultfd check:
lock_vma_under_rcu
vma_start_read
vma->vm_lock_seq == READ_ONCE(vma->vm_mm->mm_lock_seq) [early bailout]
down_read_trylock(&vma->vm_lock->lock)
vma->vm_lock_seq == READ_ONCE(vma->vm_mm->mm_lock_seq) [main check]
userfaultfd_armed
checks vma->vm_flags & __VM_UFFD_FLAGSHere, the interesting aspect is how far down the mm->mm_lock_seq read can be reordered - if this read is reordered down below the vma->vm_flags access, this could cause lock_vma_under_rcu() to partly operate on information that was read while the VMA was supposed to be locked. To prevent this kind of downwards bleeding of the mm->mm_lock_seq read, we need to read it with a load-acquire.
Some of the comment wording is based on suggestions by Suren.
BACKPORT WARNING: One of the functions changed by this patch (which I've written against Linus' tree) is vma_try_start_write(), but this function no longer exists in mm/mm-everything. I don't know whether the merged version of this patch will be ordered before or after the patch that removes vma_try_start_write(). If you're backporting this patch to a tree with vma_try_start_write(), make sure this patch changes that function.
--- include/linux/mm.h | 29 +++++++++++++++++++++++------ include/linux/mm_types.h | 28 ++++++++++++++++++++++++++++ include/linux/mmap_lock.h | 10 ++++++++-- 3 files changed, 59 insertions(+), 8 deletions(-)
include/linux/mm.h +23 -6
@@ -641,8 +641,14 @@ static inline void vma_numab_state_free(struct vm_area_struct *vma) {}*/ static inline bool vma_start_read (struct vm_area_struct *vma) { -/* Check before locking. A race might cause false locked result. */ -if (vma->vm_lock_seq ==READ_ONCE (vma->vm_mm->mm_lock_seq)) +/* +* Check before locking. A race might cause false locked result. +* We can use READ_ONCE() for the mm_lock_seq here, and don't need +* ACQUIRE semantics, because this is just a lockless check whose result +* we don't rely on for anything - the mm_lock_seq read against which we +* need ordering is below. +*/ +if (READ_ONCE (vma->vm_lock_seq) ==READ_ONCE (vma->vm_mm->mm_lock_seq))return false;if (unlikely (down_read_trylock (&vma->vm_lock->lock) ==0 ))
@@ -653,8 +659,13 @@ static inline bool vma_start_read(struct vm_area_struct *vma)* False unlocked result is impossible because we modify and check * vma->vm_lock_seq under vma->vm_lock protection and mm->mm_lock_seq * modification invalidates all existing locks. +* +* We must use ACQUIRE semantics for the mm_lock_seq so that if we are +* racing with vma_end_write_all(), we only start reading from the VMA +* after it has been unlocked. +* This pairs with RELEASE semantics in vma_end_write_all(). */ -if (unlikely (vma->vm_lock_seq ==READ_ONCE (vma->vm_mm->mm_lock_seq))) { +if (unlikely (vma->vm_lock_seq ==smp_load_acquire (&vma->vm_mm->mm_lock_seq))) {up_read (&vma->vm_lock->lock);return false; }
@@ -676,7 +687,7 @@ static bool __is_vma_write_locked(struct vm_area_struct *vma, int *mm_lock_seq)* current task is holding mmap_write_lock, both vma->vm_lock_seq and * mm->mm_lock_seq can't be concurrently modified. */ - *mm_lock_seq =READ_ONCE (vma->vm_mm->mm_lock_seq); + *mm_lock_seq = vma->vm_mm->mm_lock_seq;return (vma->vm_lock_seq == *mm_lock_seq); }
@@ -688,7 +699,13 @@ static inline void vma_start_write(struct vm_area_struct *vma)return ;down_write (&vma->vm_lock->lock); - vma->vm_lock_seq = mm_lock_seq; +/* +* We should use WRITE_ONCE() here because we can have concurrent reads +* from the early lockless pessimistic check in vma_start_read(). +* We don't really care about the correctness of that early check, but +* we should use WRITE_ONCE() for cleanliness and to keep KCSAN happy. +*/ +WRITE_ONCE (vma->vm_lock_seq, mm_lock_seq);up_write (&vma->vm_lock->lock); }
@@ -702,7 +719,7 @@ static inline bool vma_try_start_write(struct vm_area_struct *vma)if (!down_write_trylock (&vma->vm_lock->lock))return false; - vma->vm_lock_seq = mm_lock_seq; +WRITE_ONCE (vma->vm_lock_seq, mm_lock_seq);up_write (&vma->vm_lock->lock);return true; }
include/linux/mm_types.h +28 -0
@@ -514,6 +514,20 @@ struct vm_area_struct { };#ifdef CONFIG_PER_VMA_LOCK +/* +* Can only be written (using WRITE_ONCE()) while holding both: +* - mmap_lock (in write mode) +* - vm_lock->lock (in write mode) +* Can be read reliably while holding one of: +* - mmap_lock (in read or write mode) +* - vm_lock->lock (in read or write mode) +* Can be read unreliably (using READ_ONCE()) for pessimistic bailout +* while holding nothing (except RCU to keep the VMA struct allocated). +* +* This sequence counter is explicitly allowed to overflow; sequence +* counter reuse can only lead to occasional unnecessary use of the +* slowpath. +*/ int vm_lock_seq;struct vma_lock *vm_lock;
@@ -679,6 +693,20 @@ struct mm_struct {* by mmlist_lock */ #ifdef CONFIG_PER_VMA_LOCK +/* +* This field has lock-like semantics, meaning it is sometimes +* accessed with ACQUIRE/RELEASE semantics. +* Roughly speaking, incrementing the sequence number is +* equivalent to releasing locks on VMAs; reading the sequence +* number can be part of taking a read lock on a VMA. +* +* Can be modified under write mmap_lock using RELEASE +* semantics. +* Can be read with no other protection when holding write +* mmap_lock. +* Can be read with ACQUIRE semantics if not holding write +* mmap_lock. +*/ int mm_lock_seq;#endif
include/linux/mmap_lock.h +8 -2
@@ -76,8 +76,14 @@ static inline void mmap_assert_write_locked(struct mm_struct *mm)static inline void vma_end_write_all (struct mm_struct *mm) {mmap_assert_write_locked (mm); -/* No races during update due to exclusive mmap_lock being held */ -WRITE_ONCE (mm->mm_lock_seq, mm->mm_lock_seq +1 ); +/* +* Nobody can concurrently modify mm->mm_lock_seq due to exclusive +* mmap_lock being held. +* We need RELEASE semantics here to ensure that preceding stores into +* the VMA take effect before we unlock it with this store. +* Pairs with ACQUIRE semantics in vma_start_read(). +*/ +smp_store_release (&mm->mm_lock_seq, mm->mm_lock_seq +1 ); }#else static inline void vma_end_write_all (struct mm_struct *mm) {}
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 236/239 mm/memory-failure: fix hardware poison check in unpoison_memory()
In reply to Greg Kroah-HartmanFrom: Sidhartha Kumar <[email protected]>
commit 6c54312f9689fbe27c70db5d42eebd29d04b672e upstream.
It was pointed out[1] that using folio_test_hwpoison() is wrong as we need to check the indiviual page that has poison. folio_test_hwpoison() only checks the head page so go back to using PageHWPoison().
User-visible effects include existing hwpoison-inject tests possibly failing as unpoisoning a single subpage could lead to unpoisoning an entire folio. Memory unpoisoning could also not work as expected as the function will break early due to only checking the head page and not the actually poisoned subpage.
[1]: https://lore.kernel.org/lkml/[email protected]/
--- mm/memory-failure.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memory-failure.c +1 -1
@@ -2490,7 +2490,7 @@ int unpoison_memory(unsigned long pfn) goto unlock_mutex; } -if (!folio_test_hwpoison (folio)) { +if (!PageHWPoison (p)) {unpoison_pr_info ("Unpoison: Page was already unpoisoned %#lx\n" , pfn, &unpoison_rs); goto unlock_mutex;
Greg Kroah-Hartman
maintainerPATCH 237/239 mm/mempolicy: Take VMA lock before replacing policy
In reply to Greg Kroah-HartmanFrom: Jann Horn <[email protected]>
commit 6c21e066f9256ea1df6f88768f6ae1080b7cf509 upstream.
mbind() calls down into vma_replace_policy() without taking the per-VMA locks, replaces the VMA's vma->vm_policy pointer, and frees the old policy. That's bad; a concurrent page fault might still be using the old policy (in vma_alloc_folio()), resulting in use-after-free.
Normally this will manifest as a use-after-free read first, but it can result in memory corruption, including because vma_alloc_folio() can call mpol_cond_put() on the freed policy, which conditionally changes the policy's refcount member.
This bug is specific to CONFIG_NUMA, but it does also affect non-NUMA systems as long as the kernel was built with CONFIG_NUMA.
--- mm/mempolicy.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
mm/mempolicy.c +14 -1
@@ -384,8 +384,10 @@ void mpol_rebind_mm(struct mm_struct *mmVMA_ITERATOR (vmi, mm,0 );mmap_write_lock (mm); -for_each_vma (vmi, vma) +for_each_vma (vmi, vma) { +vma_start_write (vma);mpol_rebind_policy (vma->vm_policy, new); + }mmap_write_unlock (mm); }
@@ -765,6 +767,8 @@ static int vma_replace_policy(struct vm_struct mempolicy *old;struct mempolicy *new; +vma_assert_write_locked (vma); + pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n", vma->vm_start, vma->vm_end, vma->vm_pgoff, vma->vm_ops, vma->vm_file,
@@ -1313,6 +1317,14 @@ static long do_mbind(unsigned long startif (err) goto mpol_out; +/* +* Lock the VMAs before scanning for pages to migrate, to ensure we don't +* miss a concurrently inserted page. +*/ +vma_iter_init (&vmi, mm, start); +for_each_vma_range (vmi, vma, end) +vma_start_write (vma); + ret =queue_pages_range (mm, start, end, nmask, flags |MPOL_MF_INVERT , &pagelist);
@@ -1538,6 +1550,7 @@ SYSCALL_DEFINE4(set_mempolicy_home_node,break ; } +vma_start_write (vma); new->home_node = home_node; err =mbind_range (&vmi, vma, &prev, start, end, new);mpol_put (new);
Greg Kroah-Hartman
maintainerPATCH 238/239 dma-buf: keep the signaling time of merged fences v3
In reply to Greg Kroah-HartmanFrom: Christian König <[email protected]>
commit f781f661e8c99b0cb34129f2e374234d61864e77 upstream.
Some Android CTS is testing if the signaling time keeps consistent during merges.
v2: use the current time if the fence is still in the signaling path and the timestamp not yet available.
v3: improve comment, fix one more case to use the correct timestamp
--- drivers/dma-buf/dma-fence-unwrap.c | 26 ++++++++++++++++++++++---- drivers/dma-buf/dma-fence.c | 5 +++-- drivers/gpu/drm/drm_syncobj.c | 2 +- include/linux/dma-fence.h | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-)
drivers/dma-buf/dma-fence-unwrap.c +22 -4
@@ -66,18 +66,36 @@ struct dma_fence *__dma_fence_unwrap_mer {struct dma_fence_array *result;struct dma_fence *tmp, **array; +ktime_t timestamp;unsigned int i;size_t count; count =0 ; + timestamp =ns_to_ktime (0 );for (i =0 ; i < num_fences; ++i) { -dma_fence_unwrap_for_each (tmp, &iter[i], fences[i]) -if (!dma_fence_is_signaled (tmp)) +dma_fence_unwrap_for_each (tmp, &iter[i], fences[i]) { +if (!dma_fence_is_signaled (tmp)) { ++count; + }else if (test_bit (DMA_FENCE_FLAG_TIMESTAMP_BIT , + &tmp->flags)) { +if (ktime_after (tmp->timestamp, timestamp)) + timestamp = tmp->timestamp; + }else { +/* +* Use the current time if the fence is +* currently signaling. +*/ + timestamp =ktime_get (); + } + } } +/* +* If we couldn't find a pending fence just return a private signaled +* fence with the timestamp of the last signaled one. +*/ if (count ==0 ) -return dma_fence_get_stub (); +return dma_fence_allocate_private_stub (timestamp); array =kmalloc_array (count,sizeof (*array),GFP_KERNEL );if (!array)
@@ -138,7 +156,7 @@ restart: }while (tmp);if (count ==0 ) { - tmp =dma_fence_get_stub (); + tmp =dma_fence_allocate_private_stub (ktime_get ()); goto return_tmp; }
drivers/dma-buf/dma-fence.c +3 -2
@@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub);/** * dma_fence_allocate_private_stub - return a private, signaled fence +* @timestamp: timestamp when the fence was signaled * * Return a newly allocated and signaled stub fence. */ -struct dma_fence *dma_fence_allocate_private_stub (void ) +struct dma_fence *dma_fence_allocate_private_stub (ktime_t timestamp) {struct dma_fence *fence;
@@ -169,7 +170,7 @@ struct dma_fence *dma_fence_allocate_priset_bit (DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT , &fence->flags); -dma_fence_signal (fence); +dma_fence_signal_timestamp (fence, timestamp);return fence; }
drivers/gpu/drm/drm_syncobj.c +1 -1
@@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence)*/ static int drm_syncobj_assign_null_handle (struct drm_syncobj *syncobj) { -struct dma_fence *fence =dma_fence_allocate_private_stub (); +struct dma_fence *fence =dma_fence_allocate_private_stub (ktime_get ());if (IS_ERR (fence))return PTR_ERR (fence);
include/linux/dma-fence.h +1 -1
@@ -606,7 +606,7 @@ static inline signed long dma_fence_waitvoid dma_fence_set_deadline (struct dma_fence *fence,ktime_t deadline);struct dma_fence *dma_fence_get_stub (void ); -struct dma_fence *dma_fence_allocate_private_stub (void ); +struct dma_fence *dma_fence_allocate_private_stub (ktime_t timestamp);u64 dma_fence_context_alloc (unsigned num);extern const struct dma_fence_ops dma_fence_array_ops;
Greg Kroah-Hartman
maintainerPATCH 239/239 dma-buf: fix an error pointer vs NULL bug
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 00ae1491f970acc454be0df63f50942d94825860 upstream.
Smatch detected potential error pointer dereference.
drivers/gpu/drm/drm_syncobj.c:888 drm_syncobj_transfer_to_timeline()
error: 'fence' dereferencing possible ERR_PTR()
The error pointer comes from dma_fence_allocate_private_stub(). One caller expected error pointers and one expected NULL pointers. Change it to return NULL and update the caller which expected error pointers, drm_syncobj_assign_null_handle(), to check for NULL instead.
--- drivers/dma-buf/dma-fence.c | 2 +- drivers/gpu/drm/drm_syncobj.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/dma-buf/dma-fence.c +1 -1
@@ -160,7 +160,7 @@ struct dma_fence *dma_fence_allocate_pri fence =kzalloc (sizeof (*fence),GFP_KERNEL );if (fence ==NULL ) -return ERR_PTR (-ENOMEM ); +return NULL ; dma_fence_init(fence, &dma_fence_stub_ops,
drivers/gpu/drm/drm_syncobj.c +2 -2
@@ -355,8 +355,8 @@ static int drm_syncobj_assign_null_handl {struct dma_fence *fence =dma_fence_allocate_private_stub (ktime_get ()); -if (IS_ERR (fence)) -return PTR_ERR (fence); +if (!fence) +return -ENOMEM ;drm_syncobj_replace_fence (syncobj, fence);dma_fence_put (fence);
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.4:
11 builds: 11 pass, 0 fail
28 boots: 28 pass, 0 fail
120 tests: 120 pass, 0 failLinux version: 6.4.8-rc1-g2c273bf138a4
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Thanks,
Conor.
Hello,
Quoted 5 lines · On Tue, 1 Aug 2023 11:17:44 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.
This rc kernel passes DAMON functionality test[1] on my test machine. Attaching the test results summary below. Please note that I retrieved the kernel from linux-stable-rc tree[2].
[1] https://github.com/awslabs/damon-tests/tree/next/corr
[2] 2c273bf138a4 ("Linux 6.4.8-rc1")
Thanks,
SJ
[...]
---
ok 1 selftests: damon: debugfs_attrs.sh
ok 2 selftests: damon: debugfs_schemes.sh
ok 3 selftests: damon: debugfs_target_ids.sh
ok 4 selftests: damon: debugfs_empty_targets.sh
ok 5 selftests: damon: debugfs_huge_count_read_write.sh
ok 6 selftests: damon: debugfs_duplicate_context_creation.sh
ok 7 selftests: damon: debugfs_rm_non_contexts.sh
ok 8 selftests: damon: sysfs.sh
ok 9 selftests: damon: sysfs_update_removed_scheme_dir.sh
ok 10 selftests: damon: reclaim.sh
ok 11 selftests: damon: lru_sort.sh
ok 1 selftests: damon-tests: kunit.sh
ok 2 selftests: damon-tests: huge_count_read_write.sh
ok 3 selftests: damon-tests: buffer_overflow.sh
ok 4 selftests: damon-tests: rm_contexts.sh
ok 5 selftests: damon-tests: record_null_deref.sh
ok 6 selftests: damon-tests: dbgfs_target_ids_read_before_terminate_race.sh ok 7 selftests: damon-tests: dbgfs_target_ids_pid_leak.sh
ok 8 selftests: damon-tests: damo_tests.sh
ok 9 selftests: damon-tests: masim-record.sh
ok 10 selftests: damon-tests: build_i386.sh
ok 11 selftests: damon-tests: build_m68k.sh
ok 12 selftests: damon-tests: build_arm64.sh
ok 13 selftests: damon-tests: build_i386_idle_flag.sh
ok 14 selftests: damon-tests: build_i386_highpte.sh
ok 15 selftests: damon-tests: build_nomemcg.sh
PASS
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.thanks,
greg k-h
Following kselftest build regression found,
selftests/rseq: Play nice with binaries statically linked against
glibc 2.35+
commit 3bcbc20942db5d738221cca31a928efc09827069 upstream.
To allow running rseq and KVM's rseq selftests as statically linked binaries, initialize the various "trampoline" pointers to point directly at the expect glibc symbols, and skip the dlysm() lookups if the rseq size is non-zero, i.e. the binary is statically linked *and* the libc registered its own rseq.
Define weak versions of the symbols so as not to break linking against libc versions that don't support rseq in any capacity.
The KVM selftests in particular are often statically linked so that they can be run on targets with very limited runtime environments, i.e. test machines.
compatibility with glibc-2.35")
Message-Id: <[email protected]>
Build log:
----
x86_64-linux-gnu-gcc -O2 -Wall -g -I./ -isystem /home/tuxbuild/.cache/tuxmake/builds/1/build/usr/include -L/home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/rseq
-Wl,-rpath=./ -shared -fPIC rseq.c -lpthread -ldl -o/home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/rseq/librseq.so rseq.c:41:1: error: unknown type name '__weak'
41 | __weak ptrdiff_t __rseq_offset;
| ^~~~~~
rseq.c:41:18: error: expected '=', ',', ';', 'asm' or '__attribute__'
before '__rseq_offset'
41 | __weak ptrdiff_t __rseq_offset;
| ^~~~~~~~~~~~~
rseq.c:42:7: error: expected ';' before 'unsigned'
42 | __weak unsigned int __rseq_size;
| ^~~~~~~~~
| ;
rseq.c:43:7: error: expected ';' before 'unsigned'
43 | __weak unsigned int __rseq_flags;
| ^~~~~~~~~
| ;
rseq.c:45:47: error: '__rseq_offset' undeclared here (not in a
function); did you mean 'rseq_offset'?
45 | static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset;
| ^~~~~~~~~~~~~
| rseq_offsetmake[3]: Leaving directory 'tools/testing/selftests/rseq'
Links:
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2TNSVjRCfcIaJWQNkPwDQ9jn2ls/build.log
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.4.y/build/v6.4.7-240-g2c273bf138a4/testrun/18770115/suite/kselftest-rseq/test/shardfile-rseq/details/
--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 79 lines · Naresh Kamboju
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.thanks,
greg k-h
Following kselftest build regression found,
selftests/rseq: Play nice with binaries statically linked against
glibc 2.35+
commit3bcbc20942db5d738221cca31a928efc09827069upstream.To allow running rseq and KVM's rseq selftests as statically linked binaries, initialize the various "trampoline" pointers to point directly at the expect glibc symbols, and skip the
dlysm()lookups if the rseq size is non-zero, i.e. the binary is statically linked *and* the libc registered its own rseq.Define weak versions of the symbols so as not to break linking against libc versions that don't support rseq in any capacity.
The KVM selftests in particular are often statically linked so that they can be run on targets with very limited runtime environments, i.e. test machines.
Fixes 233e667e1ae3 ("selftests/rseq: Uplift rseq selftests forcompatibility with glibc-2.35")
Cc Aaron Lewis <[email protected]>Signed-off-by Sean Christopherson <[email protected]>Message-Id: <[email protected]>
Signed-off-by Paolo Bonzini <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>Build log:
----
x86_64-linux-gnu-gcc -O2 -Wall -g -I./ -isystem/home/tuxbuild/.cache/tuxmake/builds/1/build/usr/include(quoted diff) +0
-2-L/home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/rseq -Wl,-rpath=./ -shared -fPIC rseq.c -lpthread -ldl -o
/home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/rseq/librseq.sorseq.c:41:1: error: unknown type name '__weak'41 | __weak ptrdiff_t __rseq_offset; | ^~~~~~ rseq.c:41:18: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__rseq_offset' 41 | __weak ptrdiff_t __rseq_offset; | ^~~~~~~~~~~~~ rseq.c:42:7: error: expected ';' before 'unsigned' 42 | __weak unsigned int __rseq_size; | ^~~~~~~~~ | ; rseq.c:43:7: error: expected ';' before 'unsigned' 43 | __weak unsigned int __rseq_flags; | ^~~~~~~~~ | ; rseq.c:45:47: error: '__rseq_offset' undeclared here (not in a function); did you mean 'rseq_offset'? 45 | static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; | ^~~~~~~~~~~~~ | rseq_offset
Quoted 7 lines
make[3]: Leaving directory '
tools/testing/selftests/rseq'Links:
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2TNSVjRCfcIaJWQNkPwDQ9jn2ls/build.log
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.4.y/build/v6.4.7-240-g2c273bf138a4/testrun/18770115/suite/kselftest-rseq/test/shardfile-rseq/details/
Odd this didn't also show up in 6.1. I'll go drop the offending commit for now.
thanks,
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.4.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully compiled and installed bindeb-pkgs on my computer (Acer Aspire E15, Intel Core i3 Haswell). No noticeable regressions.
Signature · 1 line
An old man doll... just what I always wanted! - Clara