5.10.36-rc1 review
Subsystems (7)
Greg Kroah-Hartman
maintainerPATCH 145/299 drm/amd/display: Fix UBSAN warning for not a valid value for type _Bool
In reply to Greg Kroah-HartmanFrom: Anson Jacob <[email protected]>
[ Upstream commit 6a30a92997eee49554f72b462dce90abe54a496f ]
[Why]dc_cursor_position do not initialise position.translate_by_source when crtc or plane->state->fb is NULL. UBSAN caught this error in dce110_set_cursor_position, as the value was garbage.
[How]
Initialise dc_cursor_position structure elements to 0 in handle_cursor_update before calling get_cursor_position.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -5
@@ -6800,10 +6800,6 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,int x, y;int xorigin =0 , yorigin =0 ; - position->enable = false; - position->x =0 ; - position->y =0 ; -if (!crtc || !plane->state->fb)return 0 ;
@@ -6850,7 +6846,7 @@ static void handle_cursor_update(struct drm_plane *plane,struct dm_crtc_state *crtc_state = crtc ?to_dm_crtc_state (crtc->state) :NULL ;struct amdgpu_crtc *amdgpu_crtc =to_amdgpu_crtc (crtc);uint64_t address = afb ? afb->address :0 ; -struct dc_cursor_position position; +struct dc_cursor_position position = {0 };struct dc_cursor_attributes attributes;int ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 146/299 drm/amd/display: DCHUB underflow counter increasing in some scenarios
In reply to Greg Kroah-HartmanFrom: Aric Cyr <[email protected]>
[ Upstream commit 4710430a779e6077d81218ac768787545bff8c49 ]
[Why]
When unplugging a display, the underflow counter can be seen to increase because PSTATE switch is allowed even when some planes are not blanked.
[How]
Check that all planes are not active instead of all streams before allowing PSTATE change.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +3 -1
@@ -240,6 +240,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,bool force_reset = false;bool update_uclk = false;bool p_state_change_support; +int total_plane_count;if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present)return ;
@@ -280,7 +281,8 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz; clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; - p_state_change_support = new_clocks->p_state_change_support || (display_count ==0 ); + total_plane_count =clk_mgr_helper_get_active_plane_cnt (dc, context); + p_state_change_support = new_clocks->p_state_change_support || (total_plane_count ==0 );if (should_update_pstate_support (safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { clk_mgr_base->clks.p_state_change_support = p_state_change_support;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 147/299 drm/amd/display: fix dml prefetch validation
In reply to Greg Kroah-HartmanFrom: Dmytro Laktyushkin <[email protected]>
[ Upstream commit 8ee0fea4baf90e43efe2275de208a7809f9985bc ]
Incorrect variable used, missing initialization during validation.
--- drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c | 1 + drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 1 + 2 files changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +1 -0
@@ -3437,6 +3437,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;for (i =0 ; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] =dml_min ( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +1 -0
@@ -3510,6 +3510,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;for (i =0 ; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] =dml_min ( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 148/299 scsi: qla2xxx: Always check the return value of qla24xx_get_isp_stats()
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit a2b2cc660822cae08c351c7f6b452bfd1330a4f7 ]
This patch fixes the following Coverity warning:
CID 361199 (#1 of 1): Unchecked return value (CHECKED_RETURN)
3. check_return: Calling qla24xx_get_isp_stats without checking return value (as is done elsewhere 4 out of 5 times).
--- drivers/scsi/qla2xxx/qla_attr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_attr.c +7 -1
@@ -2855,6 +2855,8 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) vha->qla_stats.jiffies_at_last_reset =get_jiffies_64 ();if (IS_FWI2_CAPABLE (ha)) { +int rval; + stats =dma_alloc_coherent (&ha->pdev->dev,sizeof (*stats), &stats_dma,GFP_KERNEL );if (!stats) {
@@ -2864,7 +2866,11 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) }/* reset firmware statistics */ -qla24xx_get_isp_stats (base_vha, stats, stats_dma,BIT_0 ); + rval =qla24xx_get_isp_stats (base_vha, stats, stats_dma,BIT_0 ); +if (rval !=QLA_SUCCESS ) +ql_log (ql_log_warn, vha,0x70de , +"Resetting ISP statistics failed: rval = %d\n" , + rval);dma_free_coherent (&ha->pdev->dev,sizeof (*stats), stats, stats_dma);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 149/299 drm/vkms: fix misuse of WARN_ON
In reply to Greg Kroah-HartmanFrom: Dmitry Vyukov <[email protected]>
[ Upstream commit b4142fc4d52d051d4d8df1fb6c569e5b445d369e ]
vkms_vblank_simulate() uses WARN_ON for timing-dependent condition (timer overrun). This is a mis-use of WARN_ON, WARN_ON must be used to denote kernel bugs. Use pr_warn() instead.
--- drivers/gpu/drm/vkms/vkms_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/vkms/vkms_crtc.c +2 -1
@@ -18,7 +18,8 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) ret_overrun =hrtimer_forward_now (&output->vblank_hrtimer, output->period_ns); -WARN_ON (ret_overrun !=1 ); +if (ret_overrun !=1 ) +pr_warn ("%s: vblank timer overrun\n" , __func__);spin_lock (&output->lock); ret =drm_crtc_handle_vblank (crtc);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 150/299 scsi: qla2xxx: Fix use after free in bsg
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
[ Upstream commit 2ce35c0821afc2acd5ee1c3f60d149f8b2520ce8 ]
On bsg command completion, bsg_job_done() was called while qla driver continued to access the bsg_job buffer. bsg_job_done() would free up resources that ended up being reused by other task while the driver continued to access the buffers. As a result, driver was reading garbage data.
localhost kernel: BUG: KASAN: use-after-free in sg_next+0x64/0x80 localhost kernel: Read of size 8 at addr ffff8883228a3330 by task swapper/26/0 localhost kernel:
localhost kernel: CPU: 26 PID: 0 Comm: swapper/26 Kdump:
loaded Tainted: G OE --------- - - 4.18.0-193.el8.x86_64+debug #1
localhost kernel: Hardware name: HP ProLiant DL360
Gen9/ProLiant DL360 Gen9, BIOS P89 08/12/2016
localhost kernel: Call Trace:
localhost kernel: <IRQ>
localhost kernel: dump_stack+0x9a/0xf0
localhost kernel: print_address_description.cold.3+0x9/0x23b localhost kernel: kasan_report.cold.4+0x65/0x95
localhost kernel: debug_dma_unmap_sg.part.12+0x10d/0x2d0 localhost kernel: qla2x00_bsg_sp_free+0xaf6/0x1010 [qla2xxx]
--- drivers/scsi/qla2xxx/qla_bsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_bsg.c +2 -1
@@ -24,10 +24,11 @@ void qla2x00_bsg_job_done(srb_t *sp, int res)struct bsg_job *bsg_job = sp->u.bsg_job;struct fc_bsg_reply *bsg_reply = bsg_job->reply; + sp->free (sp); + bsg_reply->result = res;bsg_job_done (bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); - sp->free (sp); }void qla2x00_bsg_sp_free (srb_t *sp)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 151/299 mmc: sdhci-esdhc-imx: validate pinctrl before use it
In reply to Greg Kroah-HartmanFrom: Peng Fan <[email protected]>
[ Upstream commit f410ee0aa2df050a9505f5c261953e9b18e21206 ]
When imx_data->pinctrl is not a valid pointer, pinctrl_lookup_state will trigger kernel panic.
When we boot Dual OS on Jailhouse hypervisor, we let the 1st Linux to configure pinmux ready for the 2nd OS, so the 2nd OS not have pinctrl settings.
Similar to this commit b62eee9f804e ("mmc: sdhci-esdhc-imx: no fail when no pinctrl available").
--- drivers/mmc/host/sdhci-esdhc-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/sdhci-esdhc-imx.c +1 -1
@@ -1504,7 +1504,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,mmc_of_parse_voltage (np, &host->ocr_mask); -if (esdhc_is_usdhc (imx_data)) { +if (esdhc_is_usdhc (imx_data) && !IS_ERR (imx_data->pinctrl)) { imx_data->pins_100mhz =pinctrl_lookup_state (imx_data->pinctrl,ESDHC_PINCTRL_STATE_100MHZ ); imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 152/299 mmc: sdhci-pci: Add PCI IDs for Intel LKF
In reply to Greg Kroah-HartmanFrom: Adrian Hunter <[email protected]>
[ Upstream commit ee629112be8b4eff71d4d3d108a28bc7dc877e13 ]
Add PCI IDs for Intel LKF eMMC and SD card host controllers.
--- drivers/mmc/host/sdhci-pci-core.c | 2 ++ drivers/mmc/host/sdhci-pci.h | 2 ++ 2 files changed, 4 insertions(+)
drivers/mmc/host/sdhci-pci-core.c +2 -0
@@ -1930,6 +1930,8 @@ static const struct pci_device_id pci_ids[] = {SDHCI_PCI_DEVICE (INTEL ,CMLH_SD , intel_byt_sd),SDHCI_PCI_DEVICE (INTEL ,JSL_EMMC , intel_glk_emmc),SDHCI_PCI_DEVICE (INTEL ,JSL_SD , intel_byt_sd), +SDHCI_PCI_DEVICE (INTEL ,LKF_EMMC , intel_glk_emmc), +SDHCI_PCI_DEVICE (INTEL ,LKF_SD , intel_byt_sd),SDHCI_PCI_DEVICE (O2 ,8120 , o2),SDHCI_PCI_DEVICE (O2 ,8220 , o2), SDHCI_PCI_DEVICE(O2, 8221, o2),
drivers/mmc/host/sdhci-pci.h +2 -0
@@ -57,6 +57,8 @@#define PCI_DEVICE_ID_INTEL_CMLH_SD 0x06f5#define PCI_DEVICE_ID_INTEL_JSL_EMMC 0x4dc4#define PCI_DEVICE_ID_INTEL_JSL_SD 0x4df8 +#define PCI_DEVICE_ID_INTEL_LKF_EMMC 0x98c4 +#define PCI_DEVICE_ID_INTEL_LKF_SD 0x98f8#define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000#define PCI_DEVICE_ID_VIA_95D0 0x95d0
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 153/299 mmc: sdhci-brcmstb: Remove CQE quirk
In reply to Greg Kroah-HartmanFrom: Al Cooper <[email protected]>
[ Upstream commit f0bdf98fab058efe7bf49732f70a0f26d1143154 ]
Remove the CQHCI_QUIRK_SHORT_TXFR_DESC_SZ quirk because the latest chips have this fixed and earlier chips have other CQE problems that prevent the feature from being enabled.
--- drivers/mmc/host/sdhci-brcmstb.c | 1 - 1 file changed, 1 deletion(-)
drivers/mmc/host/sdhci-brcmstb.c +0 -1
@@ -199,7 +199,6 @@ static int sdhci_brcmstb_add_host(struct sdhci_host *host,if (dma64) {dev_dbg (mmc_dev (host->mmc),"Using 64 bit DMA\n" ); cq_host->caps |=CQHCI_TASK_DESC_SZ_128 ; - cq_host->quirks |=CQHCI_QUIRK_SHORT_TXFR_DESC_SZ ; } ret =cqhci_init (cq_host, host->mmc, dma64);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 154/299 ata: ahci: Disable SXS for Hisilicon Kunpeng920
In reply to Greg Kroah-HartmanFrom: Xingui Yang <[email protected]>
[ Upstream commit 234e6d2c18f5b080cde874483c4c361f3ae7cffe ]
On Hisilicon Kunpeng920, ESP is set to 1 by default for all ports of SATA controller. In some scenarios, some ports are not external SATA ports, and it cause disks connected to these ports to be identified as removable disks. So disable the SXS capability on the software side to prevent users from mistakenly considering non-removable disks as removable disks and performing related operations.
--- drivers/ata/ahci.c | 5 +++++ drivers/ata/ahci.h | 1 + drivers/ata/libahci.c | 5 +++++ 3 files changed, 11 insertions(+)
drivers/ata/ahci.c +5 -0
@@ -1772,6 +1772,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) hpriv->flags |=AHCI_HFLAG_NO_DEVSLP ;#ifdef CONFIG_ARM64 +if (pdev->vendor ==PCI_VENDOR_ID_HUAWEI && + pdev->device ==0xa235 && + pdev->revision <0x30 ) + hpriv->flags |=AHCI_HFLAG_NO_SXS ; +if (pdev->vendor ==0x177d && pdev->device ==0xa01c ) hpriv->irq_handler = ahci_thunderx_irq_handler;#endif
drivers/ata/ahci.h +1 -0
@@ -242,6 +242,7 @@ enum {suspend/resume */ AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = (1 <<27 ),/* ignore -EOPNOTSUPP from phy_power_on() */ + AHCI_HFLAG_NO_SXS = (1 << 28), /* SXS not supported *//* ap->flags bits */
drivers/ata/libahci.c +5 -0
@@ -493,6 +493,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) cap |=HOST_CAP_ALPM ; } +if ((cap &HOST_CAP_SXS ) && (hpriv->flags &AHCI_HFLAG_NO_SXS )) { +dev_info (dev,"controller does not support SXS, disabling CAP_SXS\n" ); + cap &= ~HOST_CAP_SXS ; + } +if (hpriv->force_port_map && port_map != hpriv->force_port_map) {dev_info (dev,"forcing port_map 0x%x -> 0x%x\n" , port_map, hpriv->force_port_map);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 155/299 drm/komeda: Fix bit check to import to value of proper type
In reply to Greg Kroah-HartmanFrom: Carsten Haitzler <[email protected]>
[ Upstream commit be3e477effba636ad25dcd244db264c6cd5c1f36 ]
KASAN found this problem. find_first_bit() expects to look at a pointer pointing to a long, but we look at a u32 - this is going to be an issue with endianness but, KSAN already flags this as out-of-bounds stack reads. This fixes it by just importing inot a local long.
--- .../drm/arm/display/include/malidp_utils.h | 3 --- .../drm/arm/display/komeda/komeda_pipeline.c | 16 +++++++++++----- .../display/komeda/komeda_pipeline_state.c | 19 +++++++++++-------- 3 files changed, 22 insertions(+), 16 deletions(-)
drivers/gpu/drm/arm/display/include/malidp_utils.h +0 -3
@@ -13,9 +13,6 @@#define has_bit (nr, mask) (BIT(nr) & (mask))#define has_bits (bits, mask) (((bits) & (mask)) == (bits)) -#define dp_for_each_set_bit (bit, mask) \ - for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8) -#define dp_wait_cond (__cond, __tries, __min_range, __max_range) \ ({ \ int num_tries = __tries; \
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c +11 -5
@@ -46,8 +46,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev, {struct komeda_component *c;int i; +unsigned long avail_comps = pipe->avail_comps; -dp_for_each_set_bit (i, pipe->avail_comps) { +for_each_set_bit (i, &avail_comps,32 ) { c =komeda_pipeline_get_component (pipe, i);komeda_component_destroy (mdev, c); }
@@ -246,6 +247,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe) {struct komeda_component *c;int id; +unsigned long avail_comps = pipe->avail_comps; DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n", pipe->id, pipe->n_layers, pipe->n_scalers,
@@ -257,7 +259,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe) pipe->of_output_links[1 ] ? pipe->of_output_links[1]->full_name : "none"); -dp_for_each_set_bit (id, pipe->avail_comps) { +for_each_set_bit (id, &avail_comps,32 ) { c =komeda_pipeline_get_component (pipe, id);komeda_component_dump (c);
@@ -269,8 +271,9 @@ static void komeda_component_verify_inputs(struct komeda_component *c)struct komeda_pipeline *pipe = c->pipeline;struct komeda_component *input;int id; +unsigned long supported_inputs = c->supported_inputs; -dp_for_each_set_bit (id, c->supported_inputs) { +for_each_set_bit (id, &supported_inputs,32 ) { input =komeda_pipeline_get_component (pipe, id);if (!input) { c->supported_inputs &= ~(BIT (id));
@@ -301,8 +304,9 @@ static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)struct komeda_component *c;struct komeda_layer *layer;int i, id; +unsigned long avail_comps = pipe->avail_comps; -dp_for_each_set_bit (id, pipe->avail_comps) { +for_each_set_bit (id, &avail_comps,32 ) { c =komeda_pipeline_get_component (pipe, id);komeda_component_verify_inputs (c); }
@@ -354,13 +358,15 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe, {struct komeda_component *c;u32 id; +unsigned long avail_comps;seq_printf (sf,"\n======== Pipeline-%d ==========\n" , pipe->id);if (pipe->funcs && pipe->funcs->dump_register) pipe->funcs->dump_register (pipe, sf); -dp_for_each_set_bit (id, pipe->avail_comps) { + avail_comps = pipe->avail_comps; +for_each_set_bit (id, &avail_comps,32 ) { c =komeda_pipeline_get_component (pipe, id);seq_printf (sf,"\n------%s------\n" , c->name);
drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +11 -8
@@ -1231,14 +1231,15 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,struct komeda_pipeline_state *old =priv_to_pipe_st (pipe->obj.state);struct komeda_component_state *c_st;struct komeda_component *c; -u32 disabling_comps, id; +u32 id; +unsigned long disabling_comps;WARN_ON (!old); disabling_comps = (~new->active_comps) & old->active_comps;/* unbound all disabling component */ -dp_for_each_set_bit (id, disabling_comps) { +for_each_set_bit (id, &disabling_comps,32 ) { c =komeda_pipeline_get_component (pipe, id); c_st =komeda_component_get_state_and_set_user (c, drm_st,NULL , new->crtc);
@@ -1286,7 +1287,8 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,struct komeda_pipeline_state *old;struct komeda_component *c;struct komeda_component_state *c_st; -u32 id, disabling_comps =0 ; +u32 id; +unsigned long disabling_comps; old =komeda_pipeline_get_old_state (pipe, old_state);
@@ -1296,10 +1298,10 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe, disabling_comps = old->active_comps & pipe->standalone_disabled_comps; -DRM_DEBUG_ATOMIC ("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%x.\n" , +DRM_DEBUG_ATOMIC ("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%lx.\n" , pipe->id, old->active_comps, disabling_comps); -dp_for_each_set_bit (id, disabling_comps) { +for_each_set_bit (id, &disabling_comps,32 ) { c =komeda_pipeline_get_component (pipe, id); c_st =priv_to_comp_st (c->obj.state);
@@ -1330,16 +1332,17 @@ void komeda_pipeline_update(struct komeda_pipeline *pipe,struct komeda_pipeline_state *new =priv_to_pipe_st (pipe->obj.state);struct komeda_pipeline_state *old;struct komeda_component *c; -u32 id, changed_comps =0 ; +u32 id; +unsigned long changed_comps; old =komeda_pipeline_get_old_state (pipe, old_state); changed_comps = new->active_comps | old->active_comps; -DRM_DEBUG_ATOMIC ("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n" , +DRM_DEBUG_ATOMIC ("PIPE%d: active_comps: 0x%x, changed: 0x%lx.\n" , pipe->id, new->active_comps, changed_comps); -dp_for_each_set_bit (id, changed_comps) { +for_each_set_bit (id, &changed_comps,32 ) { c =komeda_pipeline_get_component (pipe, id);if (new->active_comps &BIT (c->id))
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 156/299 nvmet: return proper error code from discovery ctrl
In reply to Greg Kroah-HartmanFrom: Hou Pu <[email protected]>
[ Upstream commit 79695dcd9ad4463a82def7f42960e6d7baa76f0b ]
Return NVME_SC_INVALID_FIELD from discovery controller like normal controller when executing identify or get log page command.
--- drivers/nvme/target/discovery.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/nvme/target/discovery.c +4 -2
@@ -177,12 +177,14 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req)if (req->cmd->get_log_page.lid !=NVME_LOG_DISC ) { req->error_loc = offsetof(struct nvme_get_log_page_command , lid); - status =NVME_SC_INVALID_OPCODE |NVME_SC_DNR ; + status =NVME_SC_INVALID_FIELD |NVME_SC_DNR ; goto out; }/* Spec requires dword aligned offsets */ if (offset &0x3 ) { + req->error_loc = + offsetof(struct nvme_get_log_page_command , lpo); status =NVME_SC_INVALID_FIELD |NVME_SC_DNR ; goto out; }
@@ -249,7 +251,7 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)if (req->cmd->identify.cns !=NVME_ID_CNS_CTRL ) { req->error_loc = offsetof(struct nvme_identify , cns); - status =NVME_SC_INVALID_OPCODE |NVME_SC_DNR ; + status =NVME_SC_INVALID_FIELD |NVME_SC_DNR ; goto out; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 157/299 selftests/resctrl: Enable gcc checks to detect buffer overflows
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit a9d26a302dea29eb84f491b1340a57e56c631a71 ]
David reported a buffer overflow error in the check_results() function of the cmt unit test and he suggested enabling _FORTIFY_SOURCE gcc compiler option to automatically detect any such errors.
Feature Test Macros man page describes_FORTIFY_SOURCE as below
"Defining this macro causes some lightweight checks to be performed to detect some buffer overflow errors when employing various string and memory manipulation functions (for example, memcpy, memset, stpcpy, strcpy, strncpy, strcat, strncat, sprintf, snprintf, vsprintf, vsnprintf, gets, and wide character variants thereof). For some functions, argument consistency is checked; for example, a check is made that open has been supplied with a mode argument when the specified flags include O_CREAT. Not all problems are detected, just some common cases.
If _FORTIFY_SOURCE is set to 1, with compiler optimization level 1 (gcc -O1) and above, checks that shouldn't change the behavior of conforming programs are performed.
With _FORTIFY_SOURCE set to 2, some more checking is added, but some conforming programs might fail.
Some of the checks can be performed at compile time (via macros logic implemented in header files), and result in compiler warnings; other checks take place at run time, and result in a run-time error if the check fails.
Use of this macro requires compiler support, available with gcc since version 4.0."
Fix the buffer overflow error in the check_results() function of the cmt unit test and enable _FORTIFY_SOURCE gcc check to catch any future buffer overflow errors.
--- tools/testing/selftests/resctrl/Makefile | 2 +- tools/testing/selftests/resctrl/cqm_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/resctrl/Makefile +1 -1
@@ -1,5 +1,5 @@ CC = $(CROSS_COMPILE)gcc -CFLAGS = -g -Wall +CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 SRCS=$(wildcard *.c) OBJS=$(SRCS:.c=.o)
tools/testing/selftests/resctrl/cqm_test.c +1 -1
@@ -86,7 +86,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits)return errno; } -while (fgets (temp,1024 , fp)) { +while (fgets (temp,sizeof (temp), fp)) {char *token =strtok (temp,":\t" );int fields =0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 158/299 selftests/resctrl: Fix compilation issues for global variables
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit 8236c51d85a64643588505a6791e022cc8d84864 ]
Reinette reported following compilation issue on Fedora 32, gcc version 10.1.1
/usr/bin/ld: cqm_test.o:<src_dir>/cqm_test.c:22: multiple definition of `cache_size'; cat_test.o:<src_dir>/cat_test.c:23: first defined here
The same issue is reported for long_mask, cbm_mask, count_of_bits etc variables as well. Compiler isn't happy because these variables are defined globally in two .c files namely cqm_test.c and cat_test.c and the compiler during compilation finds that the variable is already defined (multiple definition error).
Taking a closer look at the usage of these variables reveals that these variables are used only locally in functions such as cqm_resctrl_val() (defined in cqm_test.c) and cat_perf_miss_val() (defined in cat_test.c). These variables are not shared between those functions. So, there is no need for these variables to be global. Hence, fix this issue by making them static variables.
--- tools/testing/selftests/resctrl/cat_test.c | 10 +++++----- tools/testing/selftests/resctrl/cqm_test.c | 10 +++++----- tools/testing/selftests/resctrl/resctrl.h | 2 +- tools/testing/selftests/resctrl/resctrlfs.c | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-)
tools/testing/selftests/resctrl/cat_test.c +5 -5
@@ -17,10 +17,10 @@#define MAX_DIFF_PERCENT 4#define MAX_DIFF 1000000 -int count_of_bits; -char cbm_mask[256 ]; -unsigned long long_mask; -unsigned long cache_size; +static int count_of_bits; +static char cbm_mask[256 ]; +static unsigned long long_mask; +static unsigned long cache_size;/* * Change schemata. Write schemata to specified
@@ -136,7 +136,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)return -1 ;/* Get default cbm mask for L3/L2 cache */ - ret =get_cbm_mask (cache_type); + ret =get_cbm_mask (cache_type, cbm_mask);if (ret)return ret;
tools/testing/selftests/resctrl/cqm_test.c +5 -5
@@ -16,10 +16,10 @@#define MAX_DIFF 2000000#define MAX_DIFF_PERCENT 15 -int count_of_bits; -char cbm_mask[256 ]; -unsigned long long_mask; -unsigned long cache_size; +static int count_of_bits; +static char cbm_mask[256 ]; +static unsigned long long_mask; +static unsigned long cache_size;static int cqm_setup (int num, ...) {
@@ -125,7 +125,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd)if (!validate_resctrl_feature_request ("cqm" ))return -1 ; - ret =get_cbm_mask ("L3" ); + ret =get_cbm_mask ("L3" , cbm_mask);if (ret)return ret;
tools/testing/selftests/resctrl/resctrl.h +1 -1
@@ -92,7 +92,7 @@ void tests_cleanup(void);void mbm_test_cleanup (void );int mba_schemata_change (int cpu_no,char *bw_report,char **benchmark_cmd);void mba_test_cleanup (void ); -int get_cbm_mask (char *cache_type); +int get_cbm_mask (char *cache_type,char *cbm_mask);int get_cache_size (int cpu_no,char *cache_type,unsigned long *cache_size);void ctrlc_handler (int signum,siginfo_t *info,void *ptr);int cat_val (struct resctrl_val_param *param);
tools/testing/selftests/resctrl/resctrlfs.c +5 -5
@@ -49,8 +49,6 @@ static int find_resctrl_mount(char *buffer)return -ENOENT ; } -char cbm_mask[256 ]; -/* * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl * @mum_resctrlfs: Should the resctrl FS be remounted?
@@ -205,16 +203,18 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size)/* * get_cbm_mask - Get cbm mask for given cache * @cache_type: Cache level L2/L3 -* -* Mask is stored in cbm_mask which is global variable. +* @cbm_mask: cbm_mask returned as a string * * Return: = 0 on success, < 0 on failure. */ -int get_cbm_mask (char *cache_type) +int get_cbm_mask (char *cache_type,char *cbm_mask) {char cbm_mask_path[1024 ];FILE *fp; +if (!cbm_mask) +return -1 ; +sprintf (cbm_mask_path,"%s/%s/cbm_mask" ,CBM_MASK_PATH , cache_type); fp =fopen (cbm_mask_path,"r" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 159/299 selftests/resctrl: Fix compilation issues for other global variables
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit 896016d2ad051811ff9c9c087393adc063322fbc ]
Reinette reported following compilation issue on Fedora 32, gcc version 10.1.1
/usr/bin/ld: resctrl_tests.o:<src_dir>/resctrl.h:65: multiple definition of `bm_pid'; cache.o:<src_dir>/resctrl.h:65: first defined here
Other variables are ppid, tests_run, llc_occup_path, is_amd. Compiler isn't happy because these variables are defined globally in two .c files but are not declared as extern.
To fix issues for the global variables, declare them as extern.
Chang Log:
- Split this patch from v4's patch 1 (Shuah).
--- tools/testing/selftests/resctrl/resctrl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/testing/selftests/resctrl/resctrl.h +4 -4
@@ -62,11 +62,11 @@ struct resctrl_val_param {int (*setup)(int num, ...); }; -pid_t bm_pid, ppid; -int tests_run; +extern pid_t bm_pid, ppid; +extern int tests_run; -char llc_occup_path[1024 ]; -bool is_amd; +extern char llc_occup_path[1024 ]; +extern bool is_amd;bool check_resctrlfs_support (void );int filter_dmesg (void );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 160/299 selftests/resctrl: Clean up resctrl features check
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit 2428673638ea28fa93d2a38b1c3e8d70122b00ee ]
Checking resctrl features call strcmp() to compare feature strings (e.g. "mba", "cat" etc). The checkings are error prone and don't have good coding style. Define the constant strings in macros and call strncmp() to solve the potential issues.
--- tools/testing/selftests/resctrl/cache.c | 8 +++---- tools/testing/selftests/resctrl/cat_test.c | 2 +- tools/testing/selftests/resctrl/cqm_test.c | 2 +- tools/testing/selftests/resctrl/fill_buf.c | 4 ++-- tools/testing/selftests/resctrl/mba_test.c | 2 +- tools/testing/selftests/resctrl/mbm_test.c | 2 +- tools/testing/selftests/resctrl/resctrl.h | 5 +++++ .../testing/selftests/resctrl/resctrl_tests.c | 12 +++++----- tools/testing/selftests/resctrl/resctrl_val.c | 22 +++++++++---------- tools/testing/selftests/resctrl/resctrlfs.c | 17 +++++++------- 10 files changed, 41 insertions(+), 35 deletions(-)
tools/testing/selftests/resctrl/cache.c +4 -4
@@ -182,7 +182,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)/* * Measure cache miss from perf. */ -if (!strcmp (param->resctrl_val,"cat" )) { +if (!strncmp (param->resctrl_val,CAT_STR ,sizeof (CAT_STR ))) { ret =get_llc_perf (&llc_perf_miss);if (ret <0 )return ret;
@@ -192,7 +192,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)/* * Measure llc occupancy from resctrl. */ -if (!strcmp (param->resctrl_val,"cqm" )) { +if (!strncmp (param->resctrl_val,CQM_STR ,sizeof (CQM_STR ))) { ret =get_llc_occu_resctrl (&llc_occu_resc);if (ret <0 )return ret;
@@ -234,7 +234,7 @@ int cat_val(struct resctrl_val_param *param)if (ret)return ret; -if ((strcmp (resctrl_val,"cat" ) ==0 )) { +if (!strncmp (resctrl_val,CAT_STR ,sizeof (CAT_STR ))) { ret =initialize_llc_perf ();if (ret)return ret;
@@ -242,7 +242,7 @@ int cat_val(struct resctrl_val_param *param)/* Test runs until the callback setup() tells the test to stop. */ while (1 ) { -if (strcmp (resctrl_val,"cat" ) ==0 ) { +if (!strncmp (resctrl_val,CAT_STR ,sizeof (CAT_STR ))) { ret = param->setup (1 , param);if (ret) { ret =0 ;
tools/testing/selftests/resctrl/cat_test.c +1 -1
@@ -164,7 +164,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)return -1 ;struct resctrl_val_param param = { - .resctrl_val ="cat" , + .resctrl_val =CAT_STR , .cpu_no = cpu_no, .mum_resctrlfs =0 , .setup = cat_setup,
tools/testing/selftests/resctrl/cqm_test.c +1 -1
@@ -145,7 +145,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd) }struct resctrl_val_param param = { - .resctrl_val ="cqm" , + .resctrl_val =CQM_STR , .ctrlgrp ="c1" , .mongrp ="m1" , .cpu_no = cpu_no,
tools/testing/selftests/resctrl/fill_buf.c +2 -2
@@ -115,7 +115,7 @@ static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,while (1 ) { ret =fill_one_span_read (start_ptr, end_ptr); -if (!strcmp (resctrl_val,"cat" )) +if (!strncmp (resctrl_val,CAT_STR ,sizeof (CAT_STR )))break ; }
@@ -134,7 +134,7 @@ static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr, {while (1 ) {fill_one_span_write (start_ptr, end_ptr); -if (!strcmp (resctrl_val,"cat" )) +if (!strncmp (resctrl_val,CAT_STR ,sizeof (CAT_STR )))break ; }
tools/testing/selftests/resctrl/mba_test.c +1 -1
@@ -141,7 +141,7 @@ void mba_test_cleanup(void)int mba_schemata_change (int cpu_no,char *bw_report,char **benchmark_cmd) {struct resctrl_val_param param = { - .resctrl_val ="mba" , + .resctrl_val =MBA_STR , .ctrlgrp ="c1" , .mongrp ="m1" , .cpu_no = cpu_no,
tools/testing/selftests/resctrl/mbm_test.c +1 -1
@@ -114,7 +114,7 @@ void mbm_test_cleanup(void)int mbm_bw_change (int span,int cpu_no,char *bw_report,char **benchmark_cmd) {struct resctrl_val_param param = { - .resctrl_val ="mbm" , + .resctrl_val =MBM_STR , .ctrlgrp ="c1" , .mongrp ="m1" , .span = span,
tools/testing/selftests/resctrl/resctrl.h +5 -0
@@ -62,6 +62,11 @@ struct resctrl_val_param {int (*setup)(int num, ...); }; +#define MBM_STR "mbm" +#define MBA_STR "mba" +#define CQM_STR "cqm" +#define CAT_STR "cat" +extern pid_t bm_pid, ppid;extern int tests_run;
tools/testing/selftests/resctrl/resctrl_tests.c +6 -6
@@ -85,13 +85,13 @@ int main(int argc, char **argv) cqm_test = false; cat_test = false;while (token) { -if (!strcmp (token,"mbm" )) { +if (!strncmp (token,MBM_STR ,sizeof (MBM_STR ))) { mbm_test = true; - }else if (!strcmp (token,"mba" )) { + }else if (!strncmp (token,MBA_STR ,sizeof (MBA_STR ))) { mba_test = true; - }else if (!strcmp (token,"cqm" )) { + }else if (!strncmp (token,CQM_STR ,sizeof (CQM_STR ))) { cqm_test = true; - }else if (!strcmp (token,"cat" )) { + }else if (!strncmp (token,CAT_STR ,sizeof (CAT_STR ))) { cat_test = true; }else {printf ("invalid argument\n" );
@@ -161,7 +161,7 @@ int main(int argc, char **argv)if (!is_amd && mbm_test) {printf ("# Starting MBM BW change ...\n" );if (!has_ben) -sprintf (benchmark_cmd[5 ],"%s" ,"mba" ); +sprintf (benchmark_cmd[5 ],"%s" ,MBA_STR ); res =mbm_bw_change (span, cpu_no, bw_report, benchmark_cmd);printf ("%sok MBM: bw change\n" , res ?"not " :"" );mbm_test_cleanup ();
@@ -181,7 +181,7 @@ int main(int argc, char **argv)if (cqm_test) {printf ("# Starting CQM test ...\n" );if (!has_ben) -sprintf (benchmark_cmd[5 ],"%s" ,"cqm" ); +sprintf (benchmark_cmd[5 ],"%s" ,CQM_STR ); res =cqm_resctrl_val (cpu_no, no_of_bits, benchmark_cmd);printf ("%sok CQM: test\n" , res ?"not " :"" );cqm_test_cleanup ();
tools/testing/selftests/resctrl/resctrl_val.c +11 -11
@@ -397,10 +397,10 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,return ; } -if (strcmp (resctrl_val,"mbm" ) ==0 ) +if (!strncmp (resctrl_val,MBM_STR ,sizeof (MBM_STR )))set_mbm_path (ctrlgrp, mongrp, resource_id); -if ((strcmp (resctrl_val,"mba" ) ==0 )) { +if (!strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR ))) {if (ctrlgrp)sprintf (mbm_total_path,CON_MBM_LOCAL_BYTES_PATH ,RESCTRL_PATH , ctrlgrp, resource_id);
@@ -524,7 +524,7 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp,return ; } -if (strcmp (resctrl_val,"cqm" ) ==0 ) +if (!strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR )))set_cqm_path (ctrlgrp, mongrp, resource_id); }
@@ -579,8 +579,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)if (strcmp (param->filename,"" ) ==0 )sprintf (param->filename,"stdio" ); -if ((strcmp (resctrl_val,"mba" )) ==0 || - (strcmp (resctrl_val,"mbm" )) ==0 ) { +if (!strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR )) || + !strncmp (resctrl_val,MBM_STR ,sizeof (MBM_STR ))) { ret =validate_bw_report_request (param->bw_report);if (ret)return ret;
@@ -674,15 +674,15 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)if (ret) goto out; -if ((strcmp (resctrl_val,"mbm" ) ==0 ) || - (strcmp (resctrl_val,"mba" ) ==0 )) { +if (!strncmp (resctrl_val,MBM_STR ,sizeof (MBM_STR )) || + !strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR ))) { ret =initialize_mem_bw_imc ();if (ret) goto out;initialize_mem_bw_resctrl (param->ctrlgrp, param->mongrp, param->cpu_no, resctrl_val); - }else if (strcmp (resctrl_val,"cqm" ) ==0 ) + }else if (!strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR )))initialize_llc_occu_resctrl (param->ctrlgrp, param->mongrp, param->cpu_no, resctrl_val);
@@ -710,8 +710,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)/* Test runs until the callback setup() tells the test to stop. */ while (1 ) { -if ((strcmp (resctrl_val,"mbm" ) ==0 ) || - (strcmp (resctrl_val,"mba" ) ==0 )) { +if (!strncmp (resctrl_val,MBM_STR ,sizeof (MBM_STR )) || + !strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR ))) { ret = param->setup (1 , param);if (ret) { ret =0 ;
@@ -721,7 +721,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ret =measure_vals (param, &bw_resc_start);if (ret)break ; - }else if (strcmp (resctrl_val,"cqm" ) ==0 ) { + }else if (!strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR ))) { ret = param->setup (1 , param);if (ret) { ret =0 ;
tools/testing/selftests/resctrl/resctrlfs.c +9 -8
@@ -334,7 +334,7 @@ void run_benchmark(int signum, siginfo_t *info, void *ucontext) operation =atoi (benchmark_cmd[4 ]);sprintf (resctrl_val,"%s" , benchmark_cmd[5 ]); -if (strcmp (resctrl_val,"cqm" ) !=0 ) +if (strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR ))) buffer_span = span *MB ;else buffer_span = span;
@@ -459,8 +459,8 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, goto out;/* Create mon grp and write pid into it for "mbm" and "cqm" test */ -if ((strcmp (resctrl_val,"cqm" ) ==0 ) || - (strcmp (resctrl_val,"mbm" ) ==0 )) { +if (!strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR )) || + !strncmp (resctrl_val,MBM_STR ,sizeof (MBM_STR ))) {if (strlen (mongrp)) {sprintf (monitorgroup_p,"%s/mon_groups" , controlgroup);sprintf (monitorgroup,"%s/%s" , monitorgroup_p, mongrp);
@@ -505,9 +505,9 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)int resource_id, ret =0 ;FILE *fp; -if ((strcmp (resctrl_val,"mba" ) !=0 ) && - (strcmp (resctrl_val,"cat" ) !=0 ) && - (strcmp (resctrl_val,"cqm" ) !=0 )) +if (strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR )) && +strncmp (resctrl_val,CAT_STR ,sizeof (CAT_STR )) && +strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR )))return -ENOENT ;if (!schemata) {
@@ -528,9 +528,10 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)else sprintf (controlgroup,"%s/schemata" ,RESCTRL_PATH ); -if (!strcmp (resctrl_val,"cat" ) || !strcmp (resctrl_val,"cqm" )) +if (!strncmp (resctrl_val,CAT_STR ,sizeof (CAT_STR )) || + !strncmp (resctrl_val,CQM_STR ,sizeof (CQM_STR )))sprintf (schema,"%s%d%c%s" ,"L3:" , resource_id,'=' , schemata); -if (strcmp (resctrl_val,"mba" ) ==0 ) +if (!strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR )))sprintf (schema,"%s%d%c%s" ,"MB:" , resource_id,'=' , schemata); fp =fopen (controlgroup,"w" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 161/299 selftests/resctrl: Fix missing options "-n" and "-p"
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit d7af3d0d515cbdf63b6c3398a3c15ecb1bc2bd38 ]
resctrl test suite accepts command line arguments (like -b, -t, -n and -p) as documented in the help. But passing -n and -p throws an invalid option error. This happens because -n and -p are missing in the list of characters that getopt() recognizes as valid arguments. Hence, they are treated as invalid options.
Fix this by adding them to the list of characters that getopt() recognizes as valid arguments. Please note that the main() function already has the logic to deal with the values passed as part of these arguments and hence no changes are needed there.
--- tools/testing/selftests/resctrl/resctrl_tests.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/resctrl/resctrl_tests.c +1 -1
@@ -73,7 +73,7 @@ int main(int argc, char **argv) } } -while ((c =getopt (argc_new, argv,"ht:b:" )) !=-1 ) { +while ((c =getopt (argc_new, argv,"ht:b:n:p:" )) !=-1 ) {char *token;switch (c) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 162/299 selftests/resctrl: Use resctrl/info for feature detection
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit ee0415681eb661efa1eb2db7acc263f2c7df1e23 ]
Resctrl test suite before running any unit test (like cmt, cat, mbm and mba) should first check if the feature is enabled (by kernel and not just supported by H/W) on the platform or not. validate_resctrl_feature_request() is supposed to do that. This function intends to grep for relevant flags in /proc/cpuinfo but there are several issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from /proc/cpuinfo. But, fgrep() can only return a string with maximum of 255 characters and hence the complete cpu flags are never returned.
2. The substring search logic is also busted. If strstr() finds requested resctrl feature in the cpu flags, it returns pointer to the first occurrence. But, the logic negates the return value of strstr() and hence validate_resctrl_feature_request() returns false if the feature is present in the cpu flags and returns true if the feature is not present.
3. validate_resctrl_feature_request() checks if a resctrl feature is reported in /proc/cpuinfo flags or not. Having a cpu flag means that the H/W supports the feature, but it doesn't mean that the kernel enabled it. A user could selectively enable only a subset of resctrl features using kernel command line arguments. Hence, /proc/cpuinfo isn't a reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the right place to check if a resctrl feature is enabled or not, a more appropriate place is /sys/fs/resctrl/info directory. Change validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and check if /sys/fs/resctrl/info/L3_MON/mon_features has mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2 variants can be added later.
--- tools/testing/selftests/resctrl/resctrl.h | 6 ++- tools/testing/selftests/resctrl/resctrlfs.c | 52 ++++++++++++++++----- 2 files changed, 46 insertions(+), 12 deletions(-)
tools/testing/selftests/resctrl/resctrl.h +5 -1
@@ -28,6 +28,10 @@#define RESCTRL_PATH "/sys/fs/resctrl"#define PHYS_ID_PATH "/sys/devices/system/cpu/cpu"#define CBM_MASK_PATH "/sys/fs/resctrl/info" +#define L3_PATH "/sys/fs/resctrl/info/L3" +#define MB_PATH "/sys/fs/resctrl/info/MB" +#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON" +#define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features"#define PARENT_EXIT (err_msg) \ do { \
@@ -79,7 +83,7 @@ int remount_resctrlfs(bool mum_resctrlfs);int get_resource_id (int cpu_no,int *resource_id);int umount_resctrlfs (void );int validate_bw_report_request (char *bw_report); -bool validate_resctrl_feature_request (char *resctrl_val); +bool validate_resctrl_feature_request (const char *resctrl_val);char *fgrep (FILE *inf,const char *str);int taskset_benchmark (pid_t bm_pid,int cpu_no);void run_benchmark (int signum,siginfo_t *info,void *ucontext);
tools/testing/selftests/resctrl/resctrlfs.c +41 -11
67 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 163/299 selftests/resctrl: Fix incorrect parsing of iMC counters
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit d81343b5eedf84be71a4313e8fd073d0c510afcf ]
iMC (Integrated Memory Controller) counters are usually at "/sys/bus/event_source/devices/" and are named as "uncore_imc_<n>". num_of_imcs() function tries to count number of such iMC counters so that it could appropriately initialize required number of perf_attr structures that could be used to read these iMC counters.
num_of_imcs() function assumes that all the directories under this path that start with "uncore_imc" are iMC counters. But, on some systems there could be directories named as "uncore_imc_free_running" which aren't iMC counters. Trying to read from such directories will result in "not found file" errors and MBM/MBA tests will fail.
Hence, fix the logic in num_of_imcs() such that it looks at the first character after "uncore_imc_" to check if it's a numerical digit or not. If it's a digit then the directory represents an iMC counter, else, skip the directory.
--- tools/testing/selftests/resctrl/resctrl_val.c | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
tools/testing/selftests/resctrl/resctrl_val.c +20 -2
@@ -221,8 +221,8 @@ static int read_from_imc_dir(char *imc_dir, int count)*/ static int num_of_imcs (void ) { +char imc_dir[512 ], *temp;unsigned int count =0 ; -char imc_dir[512 ];struct dirent *ep;int ret;DIR *dp;
@@ -230,7 +230,25 @@ static int num_of_imcs(void) dp =opendir (DYN_PMU_PATH );if (dp) {while ((ep =readdir (dp))) { -if (strstr (ep->d_name,UNCORE_IMC )) { + temp =strstr (ep->d_name,UNCORE_IMC ); +if (!temp) +continue ; + +/* +* imc counters are named as "uncore_imc_<n>", hence +* increment the pointer to point to <n>. Note that +* sizeof(UNCORE_IMC) would count for null character as +* well and hence the last underscore character in +* uncore_imc'_' need not be counted. +*/ + temp = temp +sizeof (UNCORE_IMC ); + +/* +* Some directories under "DYN_PMU_PATH" could have +* names like "uncore_imc_free_running", hence, check if +* first character is a numerical digit or not. +*/ +if (temp[0 ] >='0' && temp[0 ] <='9' ) {sprintf (imc_dir,"%s/%s/" ,DYN_PMU_PATH , ep->d_name); ret =read_from_imc_dir (imc_dir, count);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 164/299 selftests/resctrl: Fix checking for < 0 for unsigned values
In reply to Greg Kroah-HartmanFrom: Fenghua Yu <[email protected]>
[ Upstream commit 1205b688c92558a04d8dd4cbc2b213e0fceba5db ]
Dan reported following static checker warnings
tools/testing/selftests/resctrl/resctrl_val.c:545 measure_vals()
warn: 'bw_imc' unsigned <= 0
tools/testing/selftests/resctrl/resctrl_val.c:549 measure_vals()
warn: 'bw_resc_end' unsigned <= 0
These warnings are reported because
1. measure_vals() declares 'bw_imc' and 'bw_resc_end' as unsigned long variables
2. Return value of get_mem_bw_imc() and get_mem_bw_resctrl() are assigned to 'bw_imc' and 'bw_resc_end' respectively
3. The returned values are checked for <= 0 to see if the calls failed
Checking for < 0 for an unsigned value doesn't make any sense.
Fix this issue by changing the implementation of get_mem_bw_imc() and get_mem_bw_resctrl() such that they now accept reference to a variable and set the variable appropriately upon success and return 0, else return < 0 on error.
--- tools/testing/selftests/resctrl/resctrl_val.c | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-)
tools/testing/selftests/resctrl/resctrl_val.c +23 -18
@@ -300,9 +300,9 @@ static int initialize_mem_bw_imc(void)* Memory B/W utilized by a process on a socket can be calculated using * iMC counters. Perf events are used to read these counters. * -* Return: >= 0 on success. < 0 on failure. +* Return: = 0 on success. < 0 on failure. */ -static float get_mem_bw_imc (int cpu_no,char *bw_report) +static int get_mem_bw_imc (int cpu_no,char *bw_report,float *bw_imc) {float reads, writes, of_mul_read, of_mul_write;int imc, j, ret;
@@ -373,13 +373,18 @@ static float get_mem_bw_imc(int cpu_no, char *bw_report)close (imc_counters_config[imc][WRITE ].fd); } -if (strcmp (bw_report,"reads" ) ==0 ) -return reads; +if (strcmp (bw_report,"reads" ) ==0 ) { + *bw_imc = reads; +return 0 ; + } -if (strcmp (bw_report,"writes" ) ==0 ) -return writes; +if (strcmp (bw_report,"writes" ) ==0 ) { + *bw_imc = writes; +return 0 ; + } -return (reads + writes); + *bw_imc = reads + writes; +return 0 ; }void set_mbm_path (const char *ctrlgrp,const char *mongrp,int resource_id)
@@ -438,9 +443,8 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,* 1. If con_mon grp is given, then read from it * 2. If con_mon grp is not given, then read from root con_mon grp */ -static unsigned long get_mem_bw_resctrl (void ) +static int get_mem_bw_resctrl (unsigned long *mbm_total) { -unsigned long mbm_total =0 ;FILE *fp; fp =fopen (mbm_total_path,"r" );
@@ -449,7 +453,7 @@ static unsigned long get_mem_bw_resctrl(void)return -1 ; } -if (fscanf (fp,"%lu" , &mbm_total) <=0 ) { +if (fscanf (fp,"%lu" , mbm_total) <=0 ) {perror ("Could not get mbm local bytes" );fclose (fp);
@@ -457,7 +461,7 @@ static unsigned long get_mem_bw_resctrl(void) }fclose (fp); -return mbm_total; +return 0 ; }pid_t bm_pid, ppid;
@@ -549,7 +553,8 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp,static int measure_vals (struct resctrl_val_param *param,unsigned long *bw_resc_start) { -unsigned long bw_imc, bw_resc, bw_resc_end; +unsigned long bw_resc, bw_resc_end; +float bw_imc;int ret;/*
@@ -559,13 +564,13 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)* Compare the two values to validate resctrl value. * It takes 1sec to measure the data. */ - bw_imc =get_mem_bw_imc (param->cpu_no, param->bw_report); -if (bw_imc <=0 ) -return bw_imc; + ret =get_mem_bw_imc (param->cpu_no, param->bw_report, &bw_imc); +if (ret <0 ) +return ret; - bw_resc_end =get_mem_bw_resctrl (); -if (bw_resc_end <=0 ) -return bw_resc_end; + ret =get_mem_bw_resctrl (&bw_resc_end); +if (ret <0 ) +return ret; bw_resc = (bw_resc_end - *bw_resc_start) /MB ; ret =print_results_bw (param->filename, bm_pid, bw_imc, bw_resc);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 165/299 power: supply: cpcap-charger: Add usleep to cpcap charger to avoid usb plug bounce
In reply to Greg Kroah-HartmanFrom: Carl Philipp Klemm <[email protected]>
[ Upstream commit 751faedf06e895a17e985a88ef5b6364ffd797ed ]
Adds 80000 us sleep when the usb cable is plugged in to hopefully avoid bouncing contacts.
Upon pluging in the usb cable vbus will bounce for some time, causing cpcap to dissconnect charging due to detecting an undervoltage condition. This is a scope of vbus on xt894 while quickly inserting the usb cable with firm force, probed at the far side of the usb socket and vbus loaded with approx 1k:
http://uvos.xyz/maserati/usbplug.jpg.
As can clearly be seen, vbus is all over the place for the first 15 ms or so with a small blip at ~40 ms this causes the cpcap to trip up and disable charging again.
The delay helps cpcap_usb_detect avoid the worst of this. It is, however, still not ideal as strong vibrations can cause the issue to reapear any time during charging. I have however not been able to cause the device to stop charging due to this in practice as it is hard to vibrate the device such that the vbus pins start bouncing again but cpcap_usb_detect is not called again due to a detected disconnect/reconnect event.
--- drivers/power/supply/cpcap-charger.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/power/supply/cpcap-charger.c +3 -0
@@ -633,6 +633,9 @@ static void cpcap_usb_detect(struct work_struct *work)return ; } +/* Delay for 80ms to avoid vbus bouncing when usb cable is plugged in */ +usleep_range (80000 ,120000 ); +/* Throttle chrgcurr2 interrupt for charger done and retry */ switch (ddata->state) {case CPCAP_CHARGER_CHARGING :
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 166/299 scsi: smartpqi: Use host-wide tag space
In reply to Greg Kroah-HartmanFrom: Don Brace <[email protected]>
[ Upstream commit c6d3ee209b9e863c6251f72101511340451ca324 ]
Correct SCSI midlayer sending more requests than exposed host queue depth causing firmware ASSERT and lockup issues by enabling host-wide tags.
Note: This also results in better performance.
--- drivers/scsi/smartpqi/smartpqi_init.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/smartpqi/smartpqi_init.c +1 -0
@@ -6601,6 +6601,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) shost->irq =pci_irq_vector (ctrl_info->pci_dev,0 ); shost->unique_id = shost->irq; shost->nr_hw_queues = ctrl_info->num_queue_groups; + shost->host_tagset =1 ; shost->hostdata[0 ] = (unsigned long )ctrl_info; rc =scsi_add_host (shost, &ctrl_info->pci_dev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 167/299 scsi: smartpqi: Correct request leakage during reset operations
In reply to Greg Kroah-HartmanFrom: Murthy Bhat <[email protected]>
[ Upstream commit b622a601a13ae5974c5b0aeecb990c224b8db0d9 ]
While failing queued I/Os in TMF path, there was a request leak and hence stale entries in request pool with ref count being non-zero. In shutdown path we have a BUG_ON to catch stuck I/O either in firmware or in the driver. The stale requests caused a system crash. The I/O request pool leakage also lead to a significant performance drop.
--- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/scsi/smartpqi/smartpqi_init.c +4 -0
@@ -5491,6 +5491,8 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,list_del (&io_request->request_list_entry);set_host_byte (scmd,DID_RESET ); +pqi_free_io_request (io_request); +scsi_dma_unmap (scmd);pqi_scsi_done (scmd); }
@@ -5527,6 +5529,8 @@ static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info)list_del (&io_request->request_list_entry);set_host_byte (scmd,DID_RESET ); +pqi_free_io_request (io_request); +scsi_dma_unmap (scmd);pqi_scsi_done (scmd); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 168/299 scsi: smartpqi: Add new PCI IDs
In reply to Greg Kroah-HartmanFrom: Kevin Barnett <[email protected]>
[ Upstream commit 75fbeacca3ad30835e903002dba98dd909b4dfff ]
Add support for newer hardware.
--- drivers/scsi/smartpqi/smartpqi_init.c | 156 ++++++++++++++++++++++++++ 1 file changed, 156 insertions(+)
drivers/scsi/smartpqi/smartpqi_init.c +156 -0
@@ -8226,6 +8226,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x152d ,0x8a37 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x193d ,0x8460 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x193d ,0x1104 )
@@ -8298,6 +8302,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1bd4 ,0x004f ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1bd4 ,0x0051 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1bd4 ,0x0052 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1bd4 ,0x0053 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1bd4 ,0x0054 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x19e5 ,0xd227 )
@@ -8458,6 +8478,122 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,PCI_VENDOR_ID_ADAPTEC2 ,0x1380 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1400 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1402 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1410 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1411 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1412 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1420 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1430 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1440 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1441 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1450 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1452 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1460 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1461 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1462 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1470 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1471 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1472 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1480 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1490 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x1491 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14a0 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14a1 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14b0 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14b1 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14c0 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14c1 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14d0 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14e0 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_ADAPTEC2 ,0x14f0 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,PCI_VENDOR_ID_ADVANTECH ,0x8312 )
@@ -8522,6 +8658,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,PCI_VENDOR_ID_HP ,0x1001 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +PCI_VENDOR_ID_HP ,0x1002 ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,PCI_VENDOR_ID_HP ,0x1100 )
@@ -8530,6 +8670,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,PCI_VENDOR_ID_HP ,0x1101 ) }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1590 ,0x0294 ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1590 ,0x02db ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1590 ,0x02dc ) + }, + { +PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f , +0x1590 ,0x032e ) + }, {PCI_DEVICE_SUB (PCI_VENDOR_ID_ADAPTEC2 ,0x028f ,0x1d8d ,0x0800 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 169/299 scsi: scsi_dh_alua: Remove check for ASC 24h in alua_rtpg()
In reply to Greg Kroah-HartmanFrom: Ewan D. Milne <[email protected]>
[ Upstream commit bc3f2b42b70eb1b8576e753e7d0e117bbb674496 ]
Some arrays return ILLEGAL_REQUEST with ASC 00h if they don't support the RTPG extended header so remove the check for INVALID FIELD IN CDB.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +3 -2
@@ -565,10 +565,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)* even though it shouldn't according to T10. * The retry without rtpg_ext_hdr_req set * handles this. +* Note: some arrays return a sense key of ILLEGAL_REQUEST +* with ASC 00h if they don't support the extended header. */ if (!(pg->flags &ALUA_RTPG_EXT_HDR_UNSUPP ) && - sense_hdr.sense_key ==ILLEGAL_REQUEST && - sense_hdr.asc ==0x24 && sense_hdr.ascq ==0 ) { + sense_hdr.sense_key ==ILLEGAL_REQUEST ) { pg->flags |=ALUA_RTPG_EXT_HDR_UNSUPP ; goto retry; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 170/299 media: em28xx: fix memory leak
In reply to Greg Kroah-HartmanFrom: Muhammad Usama Anjum <[email protected]>
[ Upstream commit 0ae10a7dc8992ee682ff0b1752ff7c83d472eef1 ]
If some error occurs, URB buffers should also be freed. If they aren't freed with the dvb here, the em28xx_dvb_fini call doesn't frees the URB buffers as dvb is set to NULL. The function in which error occurs should do all the cleanup for the allocations it had done.
Tested the patch with the reproducer provided by syzbot. This patch fixes the memleak.
--- drivers/media/usb/em28xx/em28xx-dvb.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/usb/em28xx/em28xx-dvb.c +1 -0
@@ -1984,6 +1984,7 @@ ret:return result; out_free: +em28xx_uninit_usb_xfer (dev,EM28XX_DIGITAL_MODE );kfree (dvb); dev->dvb =NULL ; goto ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 171/299 media: vivid: update EDID
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
[ Upstream commit 443ec4bbc6116f6f492a7a1282bfd8422c862158 ]
The EDID had a few mistakes as reported by edid-decode:
Block 1, CTA-861 Extension Block:
Video Data Block: For improved preferred timing interoperability, set 'Native detailed modes' to 1. Video Capability Data Block: S_PT is equal to S_IT and S_CE, so should be set to 0 instead.
Fixed those.
--- drivers/media/test-drivers/vivid/vivid-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/test-drivers/vivid/vivid-core.c +3 -3
@@ -205,13 +205,13 @@ static const u8 vivid_hdmi_edid[256] = {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x7b , -0x02 ,0x03 ,0x3f ,0xf0 ,0x51 ,0x61 ,0x60 ,0x5f , +0x02 ,0x03 ,0x3f ,0xf1 ,0x51 ,0x61 ,0x60 ,0x5f ,0x5e ,0x5d ,0x10 ,0x1f ,0x04 ,0x13 ,0x22 ,0x21 ,0x20 ,0x05 ,0x14 ,0x02 ,0x11 ,0x01 ,0x23 ,0x09 ,0x07 ,0x07 ,0x83 ,0x01 ,0x00 ,0x00 ,0x6d ,0x03 ,0x0c ,0x00 ,0x10 ,0x00 ,0x00 ,0x3c ,0x21 ,0x00 ,0x60 ,0x01 ,0x02 ,0x03 ,0x67 ,0xd8 ,0x5d ,0xc4 , -0x01 ,0x78 ,0x00 ,0x00 ,0xe2 ,0x00 ,0xea ,0xe3 , +0x01 ,0x78 ,0x00 ,0x00 ,0xe2 ,0x00 ,0xca ,0xe3 ,0x05 ,0x00 ,0x00 ,0xe3 ,0x06 ,0x01 ,0x00 ,0x4d ,0xd0 ,0x00 ,0xa0 ,0xf0 ,0x70 ,0x3e ,0x80 ,0x30 , 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00,
@@ -220,7 +220,7 @@ static const u8 vivid_hdmi_edid[256] = {0x00 ,0x00 ,0x1a ,0x1a ,0x1d ,0x00 ,0x80 ,0x51 ,0xd0 ,0x1c ,0x20 ,0x40 ,0x80 ,0x35 ,0x00 ,0xc0 ,0x1c ,0x32 ,0x00 ,0x00 ,0x1c ,0x00 ,0x00 ,0x00 , - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, }; static int vidioc_querycap(struct file *file, void *priv,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 172/299 drm/msm/dp: Fix incorrect NULL check kbot warnings in DP driver
In reply to Greg Kroah-HartmanFrom: Abhinav Kumar <[email protected]>
[ Upstream commit 7d649cfe0314aad2ba18042885ab9de2f13ad809 ]
Fix an incorrect NULL check reported by kbot in the MSM DP driver
smatch warnings:drivers/gpu/drm/msm/dp/dp_hpd.c:37 dp_hpd_connect()
error: we previously assumed 'hpd_priv->dp_cb' could be null (see line 37)
--- drivers/gpu/drm/msm/dp/dp_hpd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/dp/dp_hpd.c +2 -2
@@ -34,8 +34,8 @@ int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd) dp_usbpd->hpd_high = hpd; -if (!hpd_priv->dp_cb && !hpd_priv->dp_cb->configure - && !hpd_priv->dp_cb->disconnect) { +if (!hpd_priv->dp_cb || !hpd_priv->dp_cb->configure + || !hpd_priv->dp_cb->disconnect) {pr_err ("hpd dp_cb not initialized\n" );return -EINVAL ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 173/299 clk: socfpga: arria10: Fix memory leak of socfpga_clk on error return
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 657d4d1934f75a2d978c3cf2086495eaa542e7a9 ]
There is an error return path that is not kfree'ing socfpga_clk leading to a memory leak. Fix this by adding in the missing kfree call.
Addresses-Coverity: ("Resource leak")
--- drivers/clk/socfpga/clk-gate-a10.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/socfpga/clk-gate-a10.c +1 -0
@@ -146,6 +146,7 @@ static void __init __socfpga_gate_init(struct device_node *node,if (IS_ERR (socfpga_clk->sys_mgr_base_addr)) {pr_err ("%s: failed to find altr,sys-mgr regmap!\n" , __func__); +kfree (socfpga_clk);return ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 174/299 power: supply: generic-adc-battery: fix possible use-after-free in gab_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit b6cfa007b3b229771d9588970adb4ab3e0487f49 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/power/supply/generic-adc-battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/generic-adc-battery.c +1 -1
@@ -382,7 +382,7 @@ static int gab_remove(struct platform_device *pdev) }kfree (adc_bat->psy_desc.properties); -cancel_delayed_work (&adc_bat->bat_work); +cancel_delayed_work_sync (&adc_bat->bat_work);return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 175/299 power: supply: s3c_adc_battery: fix possible use-after-free in s3c_adc_bat_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 68ae256945d2abe9036a7b68af4cc65aff79d5b7 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/power/supply/s3c_adc_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/s3c_adc_battery.c +1 -1
@@ -394,7 +394,7 @@ static int s3c_adc_bat_remove(struct platform_device *pdev)gpio_free (pdata->gpio_charge_finished); } -cancel_delayed_work (&bat_work); +cancel_delayed_work_sync (&bat_work);if (pdata->exit) pdata->exit ();
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 176/299 media: tc358743: fix possible use-after-free in tc358743_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 6107a4fdf8554a7aa9488bdc835bb010062fa8a9 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/media/i2c/tc358743.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/tc358743.c +1 -1
@@ -2193,7 +2193,7 @@ static int tc358743_remove(struct i2c_client *client)del_timer_sync (&state->timer);flush_work (&state->work_i2c_poll); } -cancel_delayed_work (&state->delayed_work_enable_hotplug); +cancel_delayed_work_sync (&state->delayed_work_enable_hotplug);cec_unregister_adapter (state->cec_adap);v4l2_async_unregister_subdev (sd);v4l2_device_unregister_subdev (sd);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 177/299 media: adv7604: fix possible use-after-free in adv76xx_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit fa56f5f1fe31c2050675fa63b84963ebd504a5b3 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/media/i2c/adv7604.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/adv7604.c +1 -1
@@ -3616,7 +3616,7 @@ static int adv76xx_remove(struct i2c_client *client)io_write (sd,0x6e ,0 );io_write (sd,0x73 ,0 ); -cancel_delayed_work (&state->delayed_work_enable_hotplug); +cancel_delayed_work_sync (&state->delayed_work_enable_hotplug);v4l2_async_unregister_subdev (sd);media_entity_cleanup (&sd->entity);adv76xx_unregister_clients (to_state (sd));
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 178/299 media: i2c: adv7511-v4l2: fix possible use-after-free in adv7511_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 2c9541720c66899adf6f3600984cf3ef151295ad ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/media/i2c/adv7511-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/adv7511-v4l2.c +1 -1
@@ -1964,7 +1964,7 @@ static int adv7511_remove(struct i2c_client *client)adv7511_set_isr (sd, false);adv7511_init_setup (sd); -cancel_delayed_work (&state->edid_handler); +cancel_delayed_work_sync (&state->edid_handler);i2c_unregister_device (state->i2c_edid);i2c_unregister_device (state->i2c_cec);i2c_unregister_device (state->i2c_pktmem);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 179/299 media: i2c: tda1997: Fix possible use-after-free in tda1997x_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 7f820ab5d4eebfe2d970d32a76ae496a6c286f0f ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/media/i2c/tda1997x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/tda1997x.c +1 -1
@@ -2804,7 +2804,7 @@ static int tda1997x_remove(struct i2c_client *client)media_entity_cleanup (&sd->entity);v4l2_ctrl_handler_free (&state->hdl);regulator_bulk_disable (TDA1997X_NUM_SUPPLIES , state->supplies); -cancel_delayed_work (&state->delayed_work_enable_hpd); +cancel_delayed_work_sync (&state->delayed_work_enable_hpd);mutex_destroy (&state->page_lock);mutex_destroy (&state->lock);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 180/299 media: i2c: adv7842: fix possible use-after-free in adv7842_remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 4a15275b6a18597079f18241c87511406575179a ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
--- drivers/media/i2c/adv7842.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/adv7842.c +1 -1
@@ -3586,7 +3586,7 @@ static int adv7842_remove(struct i2c_client *client)struct adv7842_state *state =to_state (sd);adv7842_irq_enable (sd, false); -cancel_delayed_work (&state->delayed_work_enable_hotplug); +cancel_delayed_work_sync (&state->delayed_work_enable_hotplug);v4l2_device_unregister_subdev (sd);media_entity_cleanup (&sd->entity);adv7842_unregister_clients (sd);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 181/299 media: platform: sti: Fix runtime PM imbalance in regs_show
In reply to Greg Kroah-HartmanFrom: Dinghao Liu <[email protected]>
[ Upstream commit 69306a947b3ae21e0d1cbfc9508f00fec86c7297 ]
pm_runtime_get_sync() will increase the runtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error.
--- drivers/media/platform/sti/bdisp/bdisp-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/sti/bdisp/bdisp-debug.c +1 -1
@@ -480,7 +480,7 @@ static int regs_show(struct seq_file *s, void *data)int ret;unsigned int i; - ret =pm_runtime_get_sync (bdisp->dev); + ret =pm_runtime_resume_and_get (bdisp->dev);if (ret <0 ) {seq_puts (s,"Cannot wake up IP\n" );return 0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 182/299 media: sun8i-di: Fix runtime PM imbalance in deinterlace_start_streaming
In reply to Greg Kroah-HartmanFrom: Dinghao Liu <[email protected]>
[ Upstream commit f1995d5e43cf897f63b4d7a7f84a252d891ae820 ]
pm_runtime_get_sync() will increase the runtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error.
--- drivers/media/platform/sunxi/sun8i-di/sun8i-di.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +1 -1
@@ -589,7 +589,7 @@ static int deinterlace_start_streaming(struct vb2_queue *vq, unsigned int count)int ret;if (V4L2_TYPE_IS_OUTPUT (vq->type)) { - ret =pm_runtime_get_sync (dev); + ret =pm_runtime_resume_and_get (dev);if (ret <0 ) {dev_err (dev,"Failed to enable module\n" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 183/299 media: dvb-usb: fix memory leak in dvb_usb_adapter_init
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit b7cd0da982e3043f2eec7235ac5530cb18d6af1d ]
syzbot reported memory leak in dvb-usb. The problem was in invalid error handling in dvb_usb_adapter_init().
for (n = 0; n < d->props.num_adapters; n++) {
....
if ((ret = dvb_usb_adapter_stream_init(adap)) ||
(ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
(ret = dvb_usb_adapter_frontend_init(adap))) {
return ret;
}
...
d->num_adapters_initialized++;...
}
In case of error in dvb_usb_adapter_dvb_init() or dvb_usb_adapter_dvb_init() d->num_adapters_initialized won't be incremented, but dvb_usb_adapter_exit() relies on it:
for (n = 0; n < d->num_adapters_initialized; n++)
So, allocated objects won't be freed.
--- drivers/media/usb/dvb-usb/dvb-usb-init.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/media/usb/dvb-usb/dvb-usb-init.c +16 -4
@@ -79,11 +79,17 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) } } -if ((ret =dvb_usb_adapter_stream_init (adap)) || - (ret =dvb_usb_adapter_dvb_init (adap, adapter_nrs)) || - (ret =dvb_usb_adapter_frontend_init (adap))) { + ret =dvb_usb_adapter_stream_init (adap); +if (ret)return ret; - } + + ret =dvb_usb_adapter_dvb_init (adap, adapter_nrs); +if (ret) + goto dvb_init_err; + + ret =dvb_usb_adapter_frontend_init (adap); +if (ret) + goto frontend_init_err;/* use exclusive FE lock if there is multiple shared FEs */ if (adap->fe_adap[1 ].fe)
@@ -103,6 +109,12 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) }return 0 ; + +frontend_init_err: +dvb_usb_adapter_dvb_exit (adap); +dvb_init_err: +dvb_usb_adapter_stream_exit (adap); +return ret; }static int dvb_usb_adapter_exit (struct dvb_usb_device *d)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 184/299 media: gscpa/stv06xx: fix memory leak
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
[ Upstream commit 4f4e6644cd876c844cdb3bea2dd7051787d5ae25 ]
For two of the supported sensors the stv06xx driver allocates memory which is stored in sd->sensor_priv. This memory is freed on a disconnect, but if the probe() fails, then it isn't freed and so this leaks memory.
Add a new probe_error() op that drivers can use to free any allocated memory in case there was a probe failure.
Thanks to Pavel Skripkin <[email protected]> for discovering the cause of the memory leak.
--- drivers/media/usb/gspca/gspca.c | 2 ++ drivers/media/usb/gspca/gspca.h | 1 + drivers/media/usb/gspca/stv06xx/stv06xx.c | 9 +++++++++ 3 files changed, 12 insertions(+)
drivers/media/usb/gspca/gspca.c +2 -0
@@ -1576,6 +1576,8 @@ out:#endif v4l2_ctrl_handler_free (gspca_dev->vdev.ctrl_handler);v4l2_device_unregister (&gspca_dev->v4l2_dev); +if (sd_desc->probe_error) + sd_desc->probe_error (gspca_dev);kfree (gspca_dev->usb_buf);kfree (gspca_dev);return ret;
drivers/media/usb/gspca/gspca.h +1 -0
@@ -105,6 +105,7 @@ struct sd_desc {cam_cf_op config;/* called on probe */ cam_op init;/* called on probe and resume */ cam_op init_controls;/* called on probe */ +cam_v_op probe_error;/* called if probe failed, do cleanup here */ cam_op start;/* called on stream on after URBs creation */ cam_pkt_op pkt_scan;/* optional operations */
drivers/media/usb/gspca/stv06xx/stv06xx.c +9 -0
@@ -529,12 +529,21 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,static int stv06xx_config (struct gspca_dev *gspca_dev,const struct usb_device_id *id); +static void stv06xx_probe_error (struct gspca_dev *gspca_dev) +{ +struct sd *sd = (struct sd *)gspca_dev; + +kfree (sd->sensor_priv); + sd->sensor_priv =NULL ; +} +/* sub-driver description */ static const struct sd_desc sd_desc = { .name =MODULE_NAME , .config = stv06xx_config, .init = stv06xx_init, .init_controls = stv06xx_init_controls, + .probe_error = stv06xx_probe_error, .start = stv06xx_start, .stopN = stv06xx_stopN, .pkt_scan = stv06xx_pkt_scan,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 185/299 sched/fair: Ignore percpu threads for imbalance pulls
In reply to Greg Kroah-HartmanFrom: Lingutla Chandrasekhar <[email protected]>
[ Upstream commit 9bcb959d05eeb564dfc9cac13a59843a4fb2edf2 ]
During load balance, LBF_SOME_PINNED will be set if any candidate task cannot be detached due to CPU affinity constraints. This can result in setting env->sd->parent->sgc->group_imbalance, which can lead to a group being classified as group_imbalanced (rather than any of the other, lower group_type) when balancing at a higher level.
In workloads involving a single task per CPU, LBF_SOME_PINNED can often be set due to per-CPU kthreads being the only other runnable tasks on any given rq. This results in changing the group classification during load-balance at higher levels when in reality there is nothing that can be done for this affinity constraint: per-CPU kthreads, as the name implies, don't get to move around (modulo hotplug shenanigans).
It's not as clear for userspace tasks - a task could be in an N-CPU cpuset with N-1 offline CPUs, making it an "accidental" per-CPU task rather than an intended one. KTHREAD_IS_PER_CPU gives us an indisputable signal which we can leverage here to not set LBF_SOME_PINNED.
Note that the aforementioned classification to group_imbalance (when nothing can be done) is especially problematic on big.LITTLE systems, which have a topology the likes of:
DIE [ ]
MC [ ][ ]
0 1 2 3
L L B B arch_scale_cpu_capacity(L) < arch_scale_cpu_capacity(B)
Here, setting LBF_SOME_PINNED due to a per-CPU kthread when balancing at MC level on CPUs [0-1] will subsequently prevent CPUs [2-3] from classifying the [0-1] group as group_misfit_task when balancing at DIE level. Thus, if CPUs [0-1] are running CPU-bound (misfit) tasks, ill-timed per-CPU kthreads can significantly delay the upgmigration of said misfit tasks. Systems relying on ASYM_PACKING are likely to face similar issues.
--- kernel/sched/fair.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/sched/fair.c +4 -0
@@ -7552,6 +7552,10 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)if (throttled_lb_pair (task_group (p), env->src_cpu, env->dst_cpu))return 0 ; +/* Disregard pcpu kthreads; they are where they need to be. */ +if ((p->flags &PF_KTHREAD ) &&kthread_is_per_cpu (p)) +return 0 ; +if (!cpumask_test_cpu (env->dst_cpu, p->cpus_ptr)) {int cpu;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 186/299 drm/msm/mdp5: Configure PP_SYNC_HEIGHT to double the vtotal
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit 2ad52bdb220de5ab348098e3482b01235d15a842 ]
Leaving this at a close-to-maximum register value 0xFFF0 means it takes very long for the MDSS to generate a software vsync interrupt when the hardware TE interrupt doesn't arrive. Configuring this to double the vtotal (like some downstream kernels) leads to a frame to take at most twice before the vsync signal, until hardware TE comes up.
In this case the hardware interrupt responsible for providing this signal - "disp-te" gpio - is not hooked up to the mdp5 vsync/pp logic at all. This solves severe panel update issues observed on at least the Xperia Loire and Tone series, until said gpio is properly hooked up to an irq.
--- drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +9 -1
@@ -49,9 +49,17 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN; cfg |=MDP5_PP_SYNC_CONFIG_VSYNC_COUNT (vclks_line); +/* +* Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on +* the vsync_clk equating to roughly half the desired panel refresh rate. +* This is only necessary as stability fallback if interrupts from the +* panel arrive too late or not at all, but is currently used by default +* because these panel interrupts are not wired up yet. +*/ mdp5_write (mdp5_kms,REG_MDP5_PP_SYNC_CONFIG_VSYNC (pp_id), cfg);mdp5_write (mdp5_kms, -REG_MDP5_PP_SYNC_CONFIG_HEIGHT (pp_id),0xfff0 ); +REG_MDP5_PP_SYNC_CONFIG_HEIGHT (pp_id), (2 * mode->vtotal)); +mdp5_write (mdp5_kms,REG_MDP5_PP_VSYNC_INIT_VAL (pp_id), mode->vdisplay);mdp5_write (mdp5_kms,REG_MDP5_PP_RD_PTR_IRQ (pp_id), mode->vdisplay +1 );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 187/299 drm/msm/mdp5: Do not multiply vclk line count by 100
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit 377569f82ea8228c421cef4da33e056a900b58ca ]
Neither vtotal nor drm_mode_vrefresh contain a value that is premultiplied by 100 making the x100 variable name incorrect and resulting in vclks_line to become 100 times larger than it is supposed to be. The hardware counts 100 clockticks too many before tearcheck, leading to severe panel issues on at least the Sony Xperia lineup.
This is likely an artifact from the original MDSS DSI panel driver where the calculation [1] corrected for a premultiplied reference framerate by 100 [2]. It does not appear that the above values were ever premultiplied in the history of the DRM MDP5 driver.
With this change applied the value written to the SYNC_CONFIG_VSYNC register is now identical to downstream kernels.
[1]: https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c?h=LA.UM.8.6.c26-02400-89xx.0#n288
[2]: https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/video/msm/mdss/mdss_dsi_panel.c?h=LA.UM.8.6.c26-02400-89xx.0#n1648
--- drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +4 -4
@@ -20,7 +20,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, {struct mdp5_kms *mdp5_kms =get_kms (encoder);struct device *dev = encoder->dev->dev; -u32 total_lines_x100, vclks_line, cfg; +u32 total_lines, vclks_line, cfg;long vsync_clk_speed;struct mdp5_hw_mixer *mixer =mdp5_crtc_get_mixer (encoder->crtc);int pp_id = mixer->pp;
@@ -30,8 +30,8 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,return -EINVAL ; } - total_lines_x100 = mode->vtotal *drm_mode_vrefresh (mode); -if (!total_lines_x100) { + total_lines = mode->vtotal *drm_mode_vrefresh (mode); +if (!total_lines) {DRM_DEV_ERROR (dev,"%s: vtotal(%d) or vrefresh(%d) is 0\n" , __func__, mode->vtotal,drm_mode_vrefresh (mode));return -EINVAL ;
@@ -43,7 +43,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, vsync_clk_speed);return -EINVAL ; } - vclks_line = vsync_clk_speed *100 / total_lines_x100; + vclks_line = vsync_clk_speed / total_lines; cfg =MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN |MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 188/299 drm/amdgpu/ttm: Fix memory leak userptr pages
In reply to Greg Kroah-HartmanFrom: Daniel Gomez <[email protected]>
[ Upstream commit 0f6f9dd490d524930081a6ef1d60171ce39220b9 ]
If userptr pages have been pinned but not bounded, they remain uncleared.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +3 -3
@@ -1254,13 +1254,13 @@ static void amdgpu_ttm_backend_unbind(struct ttm_bo_device *bdev,struct amdgpu_ttm_tt *gtt = (void *)ttm;int r; -if (!gtt->bound) -return ; -/* if the pages have userptr pinning then clear that first */ if (gtt->userptr)amdgpu_ttm_tt_unpin_userptr (bdev, ttm); +if (!gtt->bound) +return ; +if (gtt->offset ==AMDGPU_BO_INVALID_OFFSET )return ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 189/299 drm/radeon/ttm: Fix memory leak userptr pages
In reply to Greg Kroah-HartmanFrom: Daniel Gomez <[email protected]>
[ Upstream commit 5aeaa43e0ef1006320c077cbc49f4a8229ca3460 ]
If userptr pages have been pinned but not bounded, they remain uncleared.
--- drivers/gpu/drm/radeon/radeon_ttm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_ttm.c +3 -2
@@ -566,13 +566,14 @@ static void radeon_ttm_backend_unbind(struct ttm_bo_device *bdev, struct ttm_ttstruct radeon_ttm_tt *gtt = (void *)ttm;struct radeon_device *rdev =radeon_get_rdev (bdev); +if (gtt->userptr) +radeon_ttm_tt_unpin_userptr (bdev, ttm); +if (!gtt->bound)return ;radeon_gart_unbind (rdev, gtt->offset, ttm->num_pages); -if (gtt->userptr) -radeon_ttm_tt_unpin_userptr (bdev, ttm); gtt->bound = false; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 190/299 drm/amd/display: Fix debugfs link_settings entry
In reply to Greg Kroah-HartmanFrom: Fangzhi Zuo <[email protected]>
[ Upstream commit c006a1c00de29e8cdcde1d0254ac23433ed3fee9 ]
1. Catch invalid link_rate and link_count settings
2. Call dc interface to overwrite preferred link settings, and wait until next stream update to apply the new settings.
--- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +8 -7
@@ -150,7 +150,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,* * --- to get dp configuration * -* cat link_settings +* cat /sys/kernel/debug/dri/0/DP-x/link_settings * * It will list current, verified, reported, preferred dp configuration. * current -- for current video mode
@@ -163,7 +163,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,* echo <lane_count> <link_rate> > link_settings * * for example, to force to 2 lane, 2.7GHz, -* echo 4 0xa > link_settings +* echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings * * spread_spectrum could not be changed dynamically. *
@@ -171,7 +171,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,* done. please check link settings after force operation to see if HW get * programming. * -* cat link_settings +* cat /sys/kernel/debug/dri/0/DP-x/link_settings * * check current and preferred settings. *
@@ -255,7 +255,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,int max_param_num =2 ;uint8_t param_nums =0 ;long param[2 ]; -bool valid_input = false; +bool valid_input = true;if (size ==0 )return -EINVAL ;
@@ -282,9 +282,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,case LANE_COUNT_ONE :case LANE_COUNT_TWO :case LANE_COUNT_FOUR : - valid_input = true;break ;default : + valid_input = false;break ; }
@@ -294,9 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,case LINK_RATE_RBR2 :case LINK_RATE_HIGH2 :case LINK_RATE_HIGH3 : - valid_input = true;break ;default : + valid_input = false;break ; }
@@ -310,10 +310,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,* spread spectrum will not be changed */ prefer_link_settings.link_spread = link->cur_link_settings.link_spread; + prefer_link_settings.use_link_rate_set = false; prefer_link_settings.lane_count = param[0 ]; prefer_link_settings.link_rate = param[1 ]; -dc_link_set_preferred_link_settings (dc, &prefer_link_settings, link); +dc_link_set_preferred_training_settings (dc, &prefer_link_settings,NULL , link, true);kfree (wr_buf);return size;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 191/299 drm/amd/display: Fix UBSAN: shift-out-of-bounds warning
In reply to Greg Kroah-HartmanFrom: Anson Jacob <[email protected]>
[ Upstream commit 54718747a6e1037317a8b3610c3be40621b2b75e ]
[Why]
On NAVI14 CONFIG_UBSAN reported shift-out-of-bounds at display_rq_dlg_calc_20v2.c:304:38
rq_param->misc.rq_c.blk256_height is 0 when chroma(*_c) is invalid. dml_log2 returns -1023 for log2(0), although log2(0) is undefined.
Which ended up as:rq_param->dlg.rq_c.swath_height = 1 << -1023
[How]
Fix applied on all dml versions.
1. Ensure dml_log2 is only called if the argument is greater than 0.
2. Subtract req128_l/req128_c from log2_swath_height_l/log2_swath_height_c only when it is greater than 0.
--- .../dc/dml/dcn20/display_rq_dlg_calc_20.c | 28 +++++++++++++++---- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 28 +++++++++++++++---- .../dc/dml/dcn21/display_rq_dlg_calc_21.c | 28 +++++++++++++++---- .../dc/dml/dcn30/display_rq_dlg_calc_30.c | 28 +++++++++++++++---- .../display/dc/dml/dml1_display_rq_dlg_calc.c | 28 +++++++++++++++---- 5 files changed, 115 insertions(+), 25 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +23 -5
@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,if (surf_linear) { log2_swath_height_l =0 ; log2_swath_height_c =0 ; - }else if (!surf_vert) { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_height) - req128_c; }else { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_width) - req128_c; +unsigned int swath_height_l; +unsigned int swath_height_c; + +if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + }else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + +if (swath_height_l >0 ) + log2_swath_height_l =dml_log2 (swath_height_l); + +if (req128_l && log2_swath_height_l >0 ) + log2_swath_height_l -=1 ; + +if (swath_height_c >0 ) + log2_swath_height_c =dml_log2 (swath_height_c); + +if (req128_c && log2_swath_height_c >0 ) + log2_swath_height_c -=1 ; } + rq_param->dlg.rq_l.swath_height =1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height =1 << log2_swath_height_c;
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +23 -5
@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,if (surf_linear) { log2_swath_height_l =0 ; log2_swath_height_c =0 ; - }else if (!surf_vert) { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_height) - req128_c; }else { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_width) - req128_c; +unsigned int swath_height_l; +unsigned int swath_height_c; + +if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + }else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + +if (swath_height_l >0 ) + log2_swath_height_l =dml_log2 (swath_height_l); + +if (req128_l && log2_swath_height_l >0 ) + log2_swath_height_l -=1 ; + +if (swath_height_c >0 ) + log2_swath_height_c =dml_log2 (swath_height_c); + +if (req128_c && log2_swath_height_c >0 ) + log2_swath_height_c -=1 ; } + rq_param->dlg.rq_l.swath_height =1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height =1 << log2_swath_height_c;
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +23 -5
@@ -277,13 +277,31 @@ static void handle_det_buf_split(if (surf_linear) { log2_swath_height_l =0 ; log2_swath_height_c =0 ; - }else if (!surf_vert) { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_height) - req128_c; }else { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_width) - req128_c; +unsigned int swath_height_l; +unsigned int swath_height_c; + +if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + }else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + +if (swath_height_l >0 ) + log2_swath_height_l =dml_log2 (swath_height_l); + +if (req128_l && log2_swath_height_l >0 ) + log2_swath_height_l -=1 ; + +if (swath_height_c >0 ) + log2_swath_height_c =dml_log2 (swath_height_c); + +if (req128_c && log2_swath_height_c >0 ) + log2_swath_height_c -=1 ; } + rq_param->dlg.rq_l.swath_height =1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height =1 << log2_swath_height_c;
drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +23 -5
@@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,if (surf_linear) { log2_swath_height_l =0 ; log2_swath_height_c =0 ; - }else if (!surf_vert) { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_height) - req128_c; }else { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_width) - req128_c; +unsigned int swath_height_l; +unsigned int swath_height_c; + +if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + }else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + +if (swath_height_l >0 ) + log2_swath_height_l =dml_log2 (swath_height_l); + +if (req128_l && log2_swath_height_l >0 ) + log2_swath_height_l -=1 ; + +if (swath_height_c >0 ) + log2_swath_height_c =dml_log2 (swath_height_c); + +if (req128_c && log2_swath_height_c >0 ) + log2_swath_height_c -=1 ; } + rq_param->dlg.rq_l.swath_height =1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height =1 << log2_swath_height_c;
drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +23 -5
@@ -344,13 +344,31 @@ static void handle_det_buf_split(if (surf_linear) { log2_swath_height_l =0 ; log2_swath_height_c =0 ; - }else if (!surf_vert) { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_height) - req128_c; }else { - log2_swath_height_l =dml_log2 (rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c =dml_log2 (rq_param->misc.rq_c.blk256_width) - req128_c; +unsigned int swath_height_l; +unsigned int swath_height_c; + +if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + }else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + +if (swath_height_l >0 ) + log2_swath_height_l =dml_log2 (swath_height_l); + +if (req128_l && log2_swath_height_l >0 ) + log2_swath_height_l -=1 ; + +if (swath_height_c >0 ) + log2_swath_height_c =dml_log2 (swath_height_c); + +if (req128_c && log2_swath_height_c >0 ) + log2_swath_height_c -=1 ; } + rq_param->dlg.rq_l.swath_height =1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height =1 << log2_swath_height_c;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 192/299 drm/amdkfd: Fix cat debugfs hang_hws file causes system crash bug
In reply to Greg Kroah-HartmanFrom: Qu Huang <[email protected]>
[ Upstream commit d73610211eec8aa027850982b1a48980aa1bc96e ]
Here is the system crash log:
[ 1272.884438] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1272.884444] IP: [< (null)>] (null) [ 1272.884447] PGD 825b09067 PUD 8267c8067 PMD 0 [ 1272.884452] Oops: 0010 [#1] SMP [ 1272.884509] CPU: 13 PID: 3485 Comm: cat Kdump: loaded Tainted: G [ 1272.884515] task: ffff9a38dbd4d140 ti: ffff9a37cd3b8000 task.ti: ffff9a37cd3b8000 [ 1272.884517] RIP: 0010:[<0000000000000000>] [< (null)>] (null) [ 1272.884520] RSP: 0018:ffff9a37cd3bbe68 EFLAGS: 00010203 [ 1272.884522] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000014d5f [ 1272.884524] RDX: fffffffffffffff4 RSI: 0000000000000001 RDI: ffff9a38aca4d200 [ 1272.884526] RBP: ffff9a37cd3bbed0 R08: ffff9a38dcd5f1a0 R09: ffff9a31ffc07300 [ 1272.884527] R10: ffff9a31ffc07300 R11: ffffffffaddd5e9d R12: ffff9a38b4e0fb00 [ 1272.884529] R13: 0000000000000001 R14: ffff9a37cd3bbf18 R15: ffff9a38aca4d200 [ 1272.884532] FS: 00007feccaa67740(0000) GS:ffff9a38dcd40000(0000) knlGS:0000000000000000 [ 1272.884534] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1272.884536] CR2: 0000000000000000 CR3: 00000008267c0000 CR4: 00000000003407e0 [ 1272.884537] Call Trace: [ 1272.884544] [<ffffffffade68940>] ? seq_read+0x130/0x440 [ 1272.884548] [<ffffffffade40f8f>] vfs_read+0x9f/0x170 [ 1272.884552] [<ffffffffade41e4f>] SyS_read+0x7f/0xf0 [ 1272.884557] [<ffffffffae374ddb>] system_call_fastpath+0x22/0x27 [ 1272.884558] Code: Bad RIP value. [ 1272.884562] RIP [< (null)>] (null) [ 1272.884564] RSP <ffff9a37cd3bbe68> [ 1272.884566] CR2: 0000000000000000
--- drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c +6 -1
@@ -33,6 +33,11 @@ static int kfd_debugfs_open(struct inode *inode, struct file *file)return single_open (file, show,NULL ); } +static int kfd_debugfs_hang_hws_read (struct seq_file *m,void *data) +{ +seq_printf (m,"echo gpu_id > hang_hws\n" ); +return 0 ; +}static ssize_t kfd_debugfs_hang_hws_write (struct file *file,const char __user *user_buf,size_t size,loff_t *ppos)
@@ -94,7 +99,7 @@ void kfd_debugfs_init(void)debugfs_create_file ("rls" ,S_IFREG |0444 , debugfs_root, kfd_debugfs_rls_by_device, &kfd_debugfs_fops);debugfs_create_file ("hang_hws" ,S_IFREG |0200 , debugfs_root, -NULL , &kfd_debugfs_hang_hws_fops); + kfd_debugfs_hang_hws_read, &kfd_debugfs_hang_hws_fops); }void kfd_debugfs_fini (void )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 193/299 amdgpu: avoid incorrect %hu format string
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 7d98d416c2cc1c1f7d9508e887de4630e521d797 ]
clang points out that the %hu format string does not match the type of the variables here:
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c:263:7: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat]
version_major, version_minor);
^~~~~~~~~~~~~
include/drm/drm_print.h:498:19: note: expanded from macro 'DRM_ERROR'
__drm_err(fmt, ##__VA_ARGS__)
~~~ ^~~~~~~~~~~Change it to a regular %u, the same way a previous patch did for another instance of the same warning.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +1 -1
@@ -259,7 +259,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)if ((adev->asic_type ==CHIP_POLARIS10 || adev->asic_type ==CHIP_POLARIS11 ) && (adev->uvd.fw_version <FW_1_66_16 )) -DRM_ERROR ("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n" , +DRM_ERROR ("POLARIS10/11 UVD firmware version %u.%u is too old.\n" , version_major, version_minor); }else {unsigned int enc_major, enc_minor, dec_minor;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 194/299 drm/amd/display: Try YCbCr420 color when YCbCr444 fails
In reply to Greg Kroah-HartmanFrom: Werner Sembach <[email protected]>
[ Upstream commit 68eb3ae3c63708f823aeeb63bb15197c727bd9bf ]
When encoder validation of a display mode fails, retry with less bandwidth heavy YCbCr420 color mode, if available. This enables some HDMI 1.4 setups to support 4k60Hz output, which previously failed silently.
On some setups, while the monitor and the gpu support display modes with pixel clocks of up to 600MHz, the link encoder might not. This prevents YCbCr444 and RGB encoding for 4k60Hz, but YCbCr420 encoding might still be possible. However, which color mode is used is decided before the link encoder capabilities are checked. This patch fixes the problem by retrying to find a display mode with YCbCr420 enforced and using it, if it is valid.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +9 -0
@@ -5328,6 +5328,15 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector, }while (stream ==NULL && requested_bpc >=6 ); +if (dc_result ==DC_FAIL_ENC_VALIDATE && !aconnector->force_yuv420_output) { +DRM_DEBUG_KMS ("Retry forcing YCbCr420 encoding\n" ); + + aconnector->force_yuv420_output = true; + stream =create_validate_stream_for_sink (aconnector, drm_mode, + dm_state, old_stream); + aconnector->force_yuv420_output = false; + } +return stream; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 195/299 drm/amdgpu: fix NULL pointer dereference
In reply to Greg Kroah-HartmanFrom: Guchun Chen <[email protected]>
[ Upstream commit 3c3dc654333f6389803cdcaf03912e94173ae510 ]
ttm->sg needs to be checked before accessing its child member.
Call Trace: amdgpu_ttm_backend_destroy+0x12/0x70 [amdgpu] ttm_bo_cleanup_memtype_use+0x3a/0x60 [ttm] ttm_bo_release+0x17d/0x300 [ttm] amdgpu_bo_unref+0x1a/0x30 [amdgpu] amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x78b/0x8b0 [amdgpu] kfd_ioctl_alloc_memory_of_gpu+0x118/0x220 [amdgpu] kfd_ioctl+0x222/0x400 [amdgpu] ? kfd_dev_is_large_bar+0x90/0x90 [amdgpu] __x64_sys_ioctl+0x8e/0xd0 ? __context_tracking_exit+0x52/0x90 do_syscall_64+0x33/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f97f264d317 Code: b3 66 90 48 8b 05 71 4b 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 41 4b 2d 00 f7 d8 64 89 01 48 RSP: 002b:00007ffdb402c338 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f97f3cc63a0 RCX: 00007f97f264d317 RDX: 00007ffdb402c380 RSI: 00000000c0284b16 RDI: 0000000000000003 RBP: 00007ffdb402c380 R08: 00007ffdb402c428 R09: 00000000c4000004 R10: 00000000c4000004 R11: 0000000000000246 R12: 00000000c0284b16 R13: 0000000000000003 R14: 00007f97f3cc63a0 R15: 00007f8836200000
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +1 -1
@@ -1034,7 +1034,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_bo_device *bdev, DMA_BIDIRECTIONAL :DMA_TO_DEVICE ;/* double check that we don't free the table twice */ -if (!ttm->sg->sgl) +if (!ttm->sg || !ttm->sg->sgl)return ;/* unmap the pages mapped to the device */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 196/299 scsi: lpfc: Fix crash when a REG_RPI mailbox fails triggering a LOGO response
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit fffd18ec6579c2d9c72b212169259062fe747888 ]
Fix a crash caused by a double put on the node when the driver completed an ACC for an unsolicted abort on the same node. The second put was executed by lpfc_nlp_not_used() and is wrong because the completion routine executes the nlp_put when the iocbq was released. Additionally, the driver is issuing a LOGO then immediately calls lpfc_nlp_set_state to put the node into NPR. This call does nothing.
Remove the lpfc_nlp_not_used call and additional set_state in the completion routine. Remove the lpfc_nlp_set_state post issue_logo. Isn't necessary.
--- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 -- drivers/scsi/lpfc/lpfc_sli.c | 1 - 2 files changed, 3 deletions(-)
drivers/scsi/lpfc/lpfc_nportdisc.c +0 -2
@@ -1984,8 +1984,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, ndlp->nlp_last_elscmd =ELS_CMD_PLOGI ;lpfc_issue_els_logo (vport, ndlp,0 ); - ndlp->nlp_prev_state =NLP_STE_REG_LOGIN_ISSUE ; -lpfc_nlp_set_state (vport, ndlp,NLP_STE_NPR_NODE );return ndlp->nlp_state; }
drivers/scsi/lpfc/lpfc_sli.c +0 -1
@@ -17836,7 +17836,6 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba,if (cmd_iocbq) { ndlp = (struct lpfc_nodelist *)cmd_iocbq->context1;lpfc_nlp_put (ndlp); -lpfc_nlp_not_used (ndlp);lpfc_sli_release_iocbq (phba, cmd_iocbq); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 197/299 scsi: lpfc: Fix error handling for mailboxes completed in MBX_POLL mode
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 304ee43238fed517faa123e034b593905b8679f8 ]
In SLI-4, when performing a mailbox command with MBX_POLL, the driver uses the BMBX register to send the command rather than the MQ. A flag is set indicating the BMBX register is active and saves the mailbox job struct (mboxq) in the mbox_active element of the adapter. The routine then waits for completion or timeout. The mailbox job struct is not freed by the routine. In cases of timeout, the adapter will be reset. The lpfc_sli_mbox_sys_flush() routine will clean up the mbox in preparation for the reset. It clears the BMBX active flag and marks the job structure as MBX_NOT_FINISHED. But, it never frees the mboxq job structure. Expectation in both normal completion and timeout cases is that the issuer of the mbx command will free the structure. Unfortunately, not all calling paths are freeing the memory in cases of error.
All calling paths were looked at and updated, if missing, to free the mboxq memory regardless of completion status.
--- drivers/scsi/lpfc/lpfc_attr.c | 75 +++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_init.c | 9 ++--- drivers/scsi/lpfc/lpfc_sli.c | 42 ++++++++++---------- 3 files changed, 70 insertions(+), 56 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +45 -30
@@ -1690,8 +1690,7 @@ lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)lpfc_printf_log (phba,KERN_ERR ,LOG_MBOX ,"0071 Set trunk mode failed with status: %d" , rc); -if (rc !=MBX_TIMEOUT ) -mempool_free (mbox, phba->mbox_mem_pool); +mempool_free (mbox, phba->mbox_mem_pool);return 0 ; }
@@ -6780,15 +6779,19 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->ctx_buf =NULL ; pmboxq->vport = vport; -if (vport->fc_flag &FC_OFFLINE_MODE ) +if (vport->fc_flag &FC_OFFLINE_MODE ) { rc =lpfc_sli_issue_mbox (phba, pmboxq,MBX_POLL ); -else - rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); - -if (rc !=MBX_SUCCESS ) { -if (rc !=MBX_TIMEOUT ) +if (rc !=MBX_SUCCESS ) {mempool_free (pmboxq, phba->mbox_mem_pool); -return NULL ; +return NULL ; + } + }else { + rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); +if (rc !=MBX_SUCCESS ) { +if (rc !=MBX_TIMEOUT ) +mempool_free (pmboxq, phba->mbox_mem_pool); +return NULL ; + } }memset (hs,0 ,sizeof (struct fc_host_statistics ));
@@ -6812,15 +6815,19 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->ctx_buf =NULL ; pmboxq->vport = vport; -if (vport->fc_flag &FC_OFFLINE_MODE ) +if (vport->fc_flag &FC_OFFLINE_MODE ) { rc =lpfc_sli_issue_mbox (phba, pmboxq,MBX_POLL ); -else - rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); - -if (rc !=MBX_SUCCESS ) { -if (rc !=MBX_TIMEOUT ) +if (rc !=MBX_SUCCESS ) {mempool_free (pmboxq, phba->mbox_mem_pool); -return NULL ; +return NULL ; + } + }else { + rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); +if (rc !=MBX_SUCCESS ) { +if (rc !=MBX_TIMEOUT ) +mempool_free (pmboxq, phba->mbox_mem_pool); +return NULL ; + } } hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
@@ -6893,15 +6900,19 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmboxq->vport = vport;if ((vport->fc_flag &FC_OFFLINE_MODE ) || - (!(psli->sli_flag &LPFC_SLI_ACTIVE ))) + (!(psli->sli_flag &LPFC_SLI_ACTIVE ))) { rc =lpfc_sli_issue_mbox (phba, pmboxq,MBX_POLL ); -else - rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); - -if (rc !=MBX_SUCCESS ) { -if (rc !=MBX_TIMEOUT ) +if (rc !=MBX_SUCCESS ) {mempool_free (pmboxq, phba->mbox_mem_pool); -return ; +return ; + } + }else { + rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); +if (rc !=MBX_SUCCESS ) { +if (rc !=MBX_TIMEOUT ) +mempool_free (pmboxq, phba->mbox_mem_pool); +return ; + } }memset (pmboxq,0 ,sizeof (LPFC_MBOXQ_t));
@@ -6911,15 +6922,19 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmboxq->vport = vport;if ((vport->fc_flag &FC_OFFLINE_MODE ) || - (!(psli->sli_flag &LPFC_SLI_ACTIVE ))) + (!(psli->sli_flag &LPFC_SLI_ACTIVE ))) { rc =lpfc_sli_issue_mbox (phba, pmboxq,MBX_POLL ); -else +if (rc !=MBX_SUCCESS ) { +mempool_free (pmboxq, phba->mbox_mem_pool); +return ; + } + }else { rc =lpfc_sli_issue_mbox_wait (phba, pmboxq, phba->fc_ratov *2 ); - -if (rc !=MBX_SUCCESS ) { -if (rc !=MBX_TIMEOUT ) -mempool_free ( pmboxq, phba->mbox_mem_pool); -return ; +if (rc !=MBX_SUCCESS ) { +if (rc !=MBX_TIMEOUT ) +mempool_free (pmboxq, phba->mbox_mem_pool); +return ; + } } lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
drivers/scsi/lpfc/lpfc_init.c +3 -6
@@ -9636,8 +9636,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)"3250 QUERY_FW_CFG mailbox failed with status " "x%x add_status x%x, mbx status x%x\n" , shdr_status, shdr_add_status, rc); -if (rc !=MBX_TIMEOUT ) -mempool_free (mboxq, phba->mbox_mem_pool); +mempool_free (mboxq, phba->mbox_mem_pool); rc = -ENXIO ; goto out_error; }
@@ -9653,8 +9652,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)"ulp1_mode:x%x\n" , phba->sli4_hba.fw_func_mode, phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode); -if (rc !=MBX_TIMEOUT ) -mempool_free (mboxq, phba->mbox_mem_pool); +mempool_free (mboxq, phba->mbox_mem_pool);/* * Set up HBA Event Queues (EQs)
@@ -10252,8 +10250,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) shdr_status =bf_get (lpfc_mbox_hdr_status, &shdr->response); shdr_add_status =bf_get (lpfc_mbox_hdr_add_status, &shdr->response); -if (rc !=MBX_TIMEOUT ) -mempool_free (mboxq, phba->mbox_mem_pool); +mempool_free (mboxq, phba->mbox_mem_pool);if (shdr_status || shdr_add_status || rc) {lpfc_printf_log (phba,KERN_ERR ,LOG_TRACE_EVENT , "0495 SLI_FUNCTION_RESET mailbox "
drivers/scsi/lpfc/lpfc_sli.c +22 -20
90 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 198/299 scsi: lpfc: Remove unsupported mbox PORT_CAPABILITIES logic
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit b62232ba8caccaf1954e197058104a6478fac1af ]
SLI-4 does not contain a PORT_CAPABILITIES mailbox command (only SLI-3 does, and SLI-3 doesn't use it), yet there are SLI-4 code paths that have code to issue the command. The command will always fail.
Remove the code for the mailbox command and leave only the resulting "failure path" logic.
--- drivers/scsi/lpfc/lpfc_crtn.h | 3 - drivers/scsi/lpfc/lpfc_hw4.h | 174 +--------------------------------- drivers/scsi/lpfc/lpfc_init.c | 103 +------------------- drivers/scsi/lpfc/lpfc_mbox.c | 36 ------- 4 files changed, 3 insertions(+), 313 deletions(-)
drivers/scsi/lpfc/lpfc_crtn.h +0 -3
@@ -55,9 +55,6 @@ void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,void lpfc_unreg_vpi (struct lpfc_hba *,uint16_t ,LPFC_MBOXQ_t *);void lpfc_init_link (struct lpfc_hba *,LPFC_MBOXQ_t *,uint32_t ,uint32_t );void lpfc_request_features (struct lpfc_hba *,struct lpfcMboxq *); -void lpfc_supported_pages (struct lpfcMboxq *); -void lpfc_pc_sli4_params (struct lpfcMboxq *); -int lpfc_pc_sli4_params_get (struct lpfc_hba *,LPFC_MBOXQ_t *);int lpfc_sli4_mbox_rsrc_extent (struct lpfc_hba *,struct lpfcMboxq *,uint16_t ,uint16_t ,bool );int lpfc_get_sli4_parameters (struct lpfc_hba *,LPFC_MBOXQ_t *);
drivers/scsi/lpfc/lpfc_hw4.h +1 -173
198 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_init.c +2 -101
127 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_mbox.c +0 -36
@@ -2624,39 +2624,3 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) resume_rpi->event_tag = ndlp->phba->fc_eventTag; } -/** -* lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages -* mailbox command. -* @mbox: pointer to lpfc mbox command to initialize. -* -* The PORT_CAPABILITIES supported pages mailbox command is issued to -* retrieve the particular feature pages supported by the port. -**/ -void -lpfc_supported_pages (struct lpfcMboxq *mbox) -{ -struct lpfc_mbx_supp_pages *supp_pages; - -memset (mbox,0 ,sizeof (*mbox)); - supp_pages = &mbox->u.mqe.un.supp_pages; -bf_set (lpfc_mqe_command, &mbox->u.mqe,MBX_PORT_CAPABILITIES ); -bf_set (cpn, supp_pages,LPFC_SUPP_PAGES ); -} - -/** -* lpfc_pc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params mbox cmd. -* @mbox: pointer to lpfc mbox command to initialize. -* -* The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to -* retrieve the particular SLI4 features supported by the port. -**/ -void -lpfc_pc_sli4_params (struct lpfcMboxq *mbox) -{ -struct lpfc_mbx_pc_sli4_params *sli4_params; - -memset (mbox,0 ,sizeof (*mbox)); - sli4_params = &mbox->u.mqe.un.sli4_params; -bf_set (lpfc_mqe_command, &mbox->u.mqe,MBX_PORT_CAPABILITIES ); -bf_set (cpn, sli4_params,LPFC_SLI4_PARAMETERS ); -}
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 199/299 mfd: intel-m10-bmc: Fix the register access range
In reply to Greg Kroah-HartmanFrom: Xu Yilun <[email protected]>
[ Upstream commit d9b326b2c3673f939941806146aee38e5c635fd0 ]
This patch fixes the max register address of MAX 10 BMC. The range 0x20000000 ~ 0x200000fc are for control registers of the QSPI flash controller, which are not accessible to host.
--- include/linux/mfd/intel-m10-bmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/mfd/intel-m10-bmc.h +1 -1
@@ -11,7 +11,7 @@#define M10BMC_LEGACY_SYS_BASE 0x300400#define M10BMC_SYS_BASE 0x300800 -#define M10BMC_MEM_END 0x200000fc +#define M10BMC_MEM_END 0x1fffffff/* Register offset of system registers */ #define NIOS2_FW_VERSION 0x0
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 200/299 mfd: da9063: Support SMBus and I2C mode
In reply to Greg Kroah-HartmanFrom: Hubert Streidl <[email protected]>
[ Upstream commit 586478bfc9f7e16504d6f64cf18bcbdf6fd0cbc9 ]
By default the PMIC DA9063 2-wire interface is SMBus compliant. This means the PMIC will automatically reset the interface when the clock signal ceases for more than the SMBus timeout of 35 ms.
If the I2C driver / device is not capable of creating atomic I2C transactions, a context change can cause a ceasing of the clock signal. This can happen if for example a real-time thread is scheduled. Then the DA9063 in SMBus mode will reset the 2-wire interface. Subsequently a write message could end up in the wrong register. This could cause unpredictable system behavior.
The DA9063 PMIC also supports an I2C compliant mode for the 2-wire interface. This mode does not reset the interface when the clock signal ceases. Thus the problem depicted above does not occur.
This patch tests for the bus functionality "I2C_FUNC_I2C". It can reasonably be assumed that the bus cannot obey SMBus timings if this functionality is set. SMBus commands most probably are emulated in this case which is prone to the latency issue described above.
This patch enables the I2C bus mode if I2C_FUNC_I2C is set or otherwise keeps the default SMBus mode.
--- drivers/mfd/da9063-i2c.c | 10 ++++++++++ include/linux/mfd/da9063/registers.h | 3 +++ 2 files changed, 13 insertions(+)
drivers/mfd/da9063-i2c.c +10 -0
@@ -442,6 +442,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c,return ret; } +/* If SMBus is not available and only I2C is possible, enter I2C mode */ +if (i2c_check_functionality (i2c->adapter,I2C_FUNC_I2C )) { + ret =regmap_clear_bits (da9063->regmap,DA9063_REG_CONFIG_J , +DA9063_TWOWIRE_TO ); +if (ret <0 ) { +dev_err (da9063->dev,"Failed to set Two-Wire Bus Mode.\n" ); +return -EIO ; + } + } +return da9063_device_init (da9063, i2c->irq); }
include/linux/mfd/da9063/registers.h +3 -0
@@ -1037,6 +1037,9 @@#define DA9063_NONKEY_PIN_AUTODOWN 0x02#define DA9063_NONKEY_PIN_AUTOFLPRT 0x03 +/* DA9063_REG_CONFIG_J (addr=0x10F) */ +#define DA9063_TWOWIRE_TO 0x40 +/* DA9063_REG_MON_REG_5 (addr=0x116) */ #define DA9063_MON_A8_IDX_MASK 0x07#define DA9063_MON_A8_IDX_NONE 0x00
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 201/299 mfd: arizona: Fix rumtime PM imbalance on error
In reply to Greg Kroah-HartmanFrom: Dinghao Liu <[email protected]>
[ Upstream commit fe6df2b48043bbe1e852b2320501d3b169363c35 ]
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error.
--- drivers/mfd/arizona-irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mfd/arizona-irq.c +1 -1
@@ -100,7 +100,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)unsigned int val;int ret; - ret =pm_runtime_get_sync (arizona->dev); + ret =pm_runtime_resume_and_get (arizona->dev);if (ret <0 ) {dev_err (arizona->dev,"Failed to resume device: %d\n" , ret);return IRQ_NONE ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 202/299 scsi: libfc: Fix a format specifier
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit 90d6697810f06aceea9de71ad836a8c7669789cd ]
Since the 'mfs' member has been declared as 'u32' in include/scsi/libfc.h, use the %u format specifier instead of %hu. This patch fixes the following clang compiler warning:
warning: format specifies type
'unsigned short' but the argument has type 'u32' (aka 'unsigned int')
[-Wformat]
"lport->mfs:%hu\n", mfs, lport->mfs);
~~~ ^~~~~~~~~~
%u--- drivers/scsi/libfc/fc_lport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/libfc/fc_lport.c +1 -1
@@ -1731,7 +1731,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,if (mfs <FC_SP_MIN_MAX_PAYLOAD || mfs >FC_SP_MAX_MAX_PAYLOAD ) {FC_LPORT_DBG (lport,"FLOGI bad mfs:%hu response, " -"lport->mfs:%hu\n" , mfs, lport->mfs); +"lport->mfs:%u\n" , mfs, lport->mfs);fc_lport_error (lport, fp); goto out; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 203/299 perf: Rework perf_event_exit_event()
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit ef54c1a476aef7eef26fe13ea10dc090952c00f8 ]
Make perf_event_exit_event() more robust, such that we can use it from other contexts. Specifically the up and coming remove_on_exec.
For this to work we need to address a few issues. Remove_on_exec will not destroy the entire context, so we cannot rely on TASK_TOMBSTONE to disable event_function_call() and we thus have to use perf_remove_from_context().
When using perf_remove_from_context(), there's two races to consider. The first is against close(), where we can have concurrent tear-down of the event. The second is against child_list iteration, which should not find a half baked event.
To address this, teach perf_remove_from_context() to special case !ctx->is_active and about DETACH_CHILD.
--- include/linux/perf_event.h | 1 + kernel/events/core.c | 142 +++++++++++++++++++++---------------- 2 files changed, 80 insertions(+), 63 deletions(-)
include/linux/perf_event.h +1 -0
@@ -607,6 +607,7 @@ struct swevent_hlist {#define PERF_ATTACH_TASK_DATA 0x08#define PERF_ATTACH_ITRACE 0x10#define PERF_ATTACH_SCHED_CB 0x20 +#define PERF_ATTACH_CHILD 0x40struct perf_cgroup ;struct perf_buffer ;
kernel/events/core.c +79 -63
209 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 204/299 sched,fair: Alternative sched_slice()
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 0c2de3f054a59f15e01804b75a04355c48de628c ]
The current sched_slice() seems to have issues; there's two possible things that could be improved:
- the 'nr_running' used for __sched_period() is daft when cgroups are considered. Using the RQ wide h_nr_running seems like a much more consistent number.
- (esp) cgroups can slice it real fine, which makes for easy over-scheduling, ensure min_gran is what the name says.
--- kernel/sched/fair.c | 12 +++++++++++- kernel/sched/features.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-)
kernel/sched/fair.c +11 -1
@@ -700,7 +700,13 @@ static u64 __sched_period(unsigned long nr_running)*/ static u64 sched_slice (struct cfs_rq *cfs_rq,struct sched_entity *se) { -u64 slice =__sched_period (cfs_rq->nr_running + !se->on_rq); +unsigned int nr_running = cfs_rq->nr_running; +u64 slice; + +if (sched_feat (ALT_PERIOD )) + nr_running =rq_of (cfs_rq)->cfs.h_nr_running; + + slice =__sched_period (nr_running + !se->on_rq);for_each_sched_entity (se) {struct load_weight *load;
@@ -717,6 +723,10 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) } slice =__calc_delta (slice, se->load.weight, load); } + +if (sched_feat (BASE_SLICE )) + slice =max (slice, (u64 )sysctl_sched_min_granularity); +return slice; }
kernel/sched/features.h +3 -0
@@ -90,3 +90,6 @@ SCHED_FEAT(WA_BIAS, true)*/ SCHED_FEAT(UTIL_EST, true) SCHED_FEAT(UTIL_EST_FASTUP, true) + +SCHED_FEAT(ALT_PERIOD, true) +SCHED_FEAT (BASE_SLICE , true)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 205/299 block/rnbd-clt: Fix missing a memory free when unloading the module
In reply to Greg Kroah-HartmanFrom: Gioh Kim <[email protected]>
[ Upstream commit 12b06533104e802df73c1fbe159437c19933d6c0 ]
When unloading the rnbd-clt module, it does not free a memory including the filename of the symbolic link to /sys/block/rnbdX.
It is found by kmemleak as below.
unreferenced object 0xffff9f1a83d3c740 (size 16):
comm "bash", pid 736, jiffies 4295179665 (age 9841.310s) hex dump (first 16 bytes):
21 64 65 76 21 6e 75 6c 6c 62 30 40 62 6c 61 00 !dev!nullb0@bla.
backtrace:
[<0000000039f0c55e>] 0xffffffffc0456c24
[<000000001aab9513>] kernfs_fop_write+0xcf/0x1c0
[<00000000db5aa4b3>] vfs_write+0xdb/0x1d0
[<000000007a2e2207>] ksys_write+0x65/0xe0
[<00000000055e280a>] do_syscall_64+0x50/0x1b0
[<00000000c2b51831>] entry_SYSCALL_64_after_hwframe+0x49/0xbe--- drivers/block/rnbd/rnbd-clt-sysfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/block/rnbd/rnbd-clt-sysfs.c +7 -3
@@ -433,10 +433,14 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev)* i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because * of sysfs link already was removed already. */ -if (dev->blk_symlink_name &&try_module_get (THIS_MODULE )) { -sysfs_remove_link (rnbd_devs_kobj, dev->blk_symlink_name); +if (dev->blk_symlink_name) { +if (try_module_get (THIS_MODULE )) { +sysfs_remove_link (rnbd_devs_kobj, dev->blk_symlink_name); +module_put (THIS_MODULE ); + } +/* It should be freed always. */ kfree (dev->blk_symlink_name); -module_put (THIS_MODULE ); + dev->blk_symlink_name =NULL ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 206/299 s390/archrandom: add parameter check for s390_arch_random_generate
In reply to Greg Kroah-HartmanFrom: Harald Freudenberger <[email protected]>
[ Upstream commit 28096067686c5a5cbd4c35b079749bd805df5010 ]
A review of the code showed, that this function which is exposed within the whole kernel should do a parameter check for the amount of bytes requested. If this requested bytes is too high an unsigned int overflow could happen causing this function to try to memcpy a really big memory chunk.
This is not a security issue as there are only two invocations of this function from arch/s390/include/asm/archrandom.h and both are not exposed to userland.
--- arch/s390/crypto/arch_random.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/s390/crypto/arch_random.c +4 -0
@@ -53,6 +53,10 @@ static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer);bool s390_arch_random_generate (u8 *buf,unsigned int nbytes) { +/* max hunk is ARCH_RNG_BUF_SIZE */ +if (nbytes >ARCH_RNG_BUF_SIZE ) +return false; +/* lock rng buffer */ if (!spin_trylock (&arch_rng_lock))return false;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 207/299 sched,psi: Handle potential task count underflow bugs more gracefully
In reply to Greg Kroah-HartmanFrom: Charan Teja Reddy <[email protected]>
[ Upstream commit 9d10a13d1e4c349b76f1c675a874a7f981d6d3b4 ]
psi_group_cpu->tasks, represented by the unsigned int, stores the number of tasks that could be stalled on a psi resource(io/mem/cpu). Decrementing these counters at zero leads to wrapping which further leads to the psi_group_cpu->state_mask is being set with the respective pressure state. This could result into the unnecessary time sampling for the pressure state thus cause the spurious psi events. This can further lead to wrong actions being taken at the user land based on these psi events.
Though psi_bug is set under these conditions but that just for debug purpose. Fix it by decrementing the ->tasks count only when it is non-zero.
--- kernel/sched/psi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/sched/psi.c +3 -2
@@ -711,14 +711,15 @@ static void psi_group_change(struct psi_group *group, int cpu,for (t =0 , m = clear; m; m &= ~(1 << t), t++) {if (!(m & (1 << t)))continue ; -if (groupc->tasks[t] ==0 && !psi_bug) { +if (groupc->tasks[t]) { + groupc->tasks[t]--; + }else if (!psi_bug) {printk_deferred (KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u %u] clear=%x set=%x\n" , cpu, t, groupc->tasks[0 ], groupc->tasks[1 ], groupc->tasks[2 ], groupc->tasks[3 ], clear, set); psi_bug =1 ; } - groupc->tasks[t]--; }for (t =0 ; set; set &= ~(1 << t), t++)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 208/299 power: supply: cpcap-battery: fix invalid usage of list cursor
In reply to Greg Kroah-HartmanFrom: Guangqing Zhu <[email protected]>
[ Upstream commit d0a43c12ee9f57ddb284272187bd18726c2c2c98 ]
Fix invalid usage of a list_for_each_entry in cpcap_battery_irq_thread(). Empty list or fully traversed list points to list head, which is not NULL (and before the first element containing real data).
--- drivers/power/supply/cpcap-battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/cpcap-battery.c +1 -1
@@ -626,7 +626,7 @@ static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)break ; } -if (!d) +if (list_entry_is_head (d, &ddata->irq_list, node))return IRQ_NONE ; latest =cpcap_battery_latest (ddata);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 209/299 ALSA: emu8000: Fix a use after free in snd_emu8000_create_mixer
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
commit 1c98f574403dbcf2eb832d5535a10d967333ef2d upstream.
Our code analyzer reported a uaf.
In snd_emu8000_create_mixer, the callee snd_ctl_add(..,emu->controls[i]) calls snd_ctl_add_replace(.., kcontrol,..). Inside snd_ctl_add_replace(), if error happens, kcontrol will be freed by snd_ctl_free_one(kcontrol). Then emu->controls[i] points to a freed memory, and the execution comes to __error branch of snd_emu8000_create_mixer. The freed emu->controls[i] is used in snd_ctl_remove(card, emu->controls[i]).
My patch set emu->controls[i] to NULL if snd_ctl_add() failed to avoid the uaf.
--- sound/isa/sb/emu8000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/isa/sb/emu8000.c +3 -1
@@ -1029,8 +1029,10 @@ snd_emu8000_create_mixer(struct snd_cardmemset (emu->controls,0 ,sizeof (emu->controls));for (i =0 ; i <EMU8000_NUM_CONTROLS ; i++) { -if ((err =snd_ctl_add (card, emu->controls[i] =snd_ctl_new1 (mixer_defs[i], emu))) <0 ) +if ((err =snd_ctl_add (card, emu->controls[i] =snd_ctl_new1 (mixer_defs[i], emu))) <0 ) { + emu->controls[i] =NULL ; goto __error; + } }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 210/299 ALSA: hda/conexant: Re-order CX5066 quirk table entries
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 2e6a731296be9d356fdccee9fb6ae345dad96438 upstream.
Just re-order the cx5066_fixups[] entries for HP devices for avoiding the oversight of the duplicated or unapplied item in future. No functional changes.
Also Cc-to-stable for the further patch applications.
--- sound/pci/hda/patch_conexant.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
sound/pci/hda/patch_conexant.c +7 -7
@@ -930,18 +930,18 @@ static const struct snd_pci_quirk cxt506SND_PCI_QUIRK (0x103c ,0x8079 ,"HP EliteBook 840 G3" ,CXT_FIXUP_HP_DOCK ),SND_PCI_QUIRK (0x103c ,0x807C ,"HP EliteBook 820 G3" ,CXT_FIXUP_HP_DOCK ),SND_PCI_QUIRK (0x103c ,0x80FD ,"HP ProBook 640 G2" ,CXT_FIXUP_HP_DOCK ), -SND_PCI_QUIRK (0x103c ,0x828c ,"HP EliteBook 840 G4" ,CXT_FIXUP_HP_DOCK ), -SND_PCI_QUIRK (0x103c ,0x83b2 ,"HP EliteBook 840 G5" ,CXT_FIXUP_HP_DOCK ), -SND_PCI_QUIRK (0x103c ,0x83b3 ,"HP EliteBook 830 G5" ,CXT_FIXUP_HP_DOCK ), -SND_PCI_QUIRK (0x103c ,0x83d3 ,"HP ProBook 640 G4" ,CXT_FIXUP_HP_DOCK ), -SND_PCI_QUIRK (0x103c ,0x8174 ,"HP Spectre x360" ,CXT_FIXUP_HP_SPECTRE ),SND_PCI_QUIRK (0x103c ,0x8115 ,"HP Z1 Gen3" ,CXT_FIXUP_HP_GATE_MIC ),SND_PCI_QUIRK (0x103c ,0x814f ,"HP ZBook 15u G3" ,CXT_FIXUP_MUTE_LED_GPIO ), +SND_PCI_QUIRK (0x103c ,0x8174 ,"HP Spectre x360" ,CXT_FIXUP_HP_SPECTRE ),SND_PCI_QUIRK (0x103c ,0x822e ,"HP ProBook 440 G4" ,CXT_FIXUP_MUTE_LED_GPIO ), -SND_PCI_QUIRK (0x103c ,0x836e ,"HP ProBook 455 G5" ,CXT_FIXUP_MUTE_LED_GPIO ), -SND_PCI_QUIRK (0x103c ,0x837f ,"HP ProBook 470 G5" ,CXT_FIXUP_MUTE_LED_GPIO ), +SND_PCI_QUIRK (0x103c ,0x828c ,"HP EliteBook 840 G4" ,CXT_FIXUP_HP_DOCK ),SND_PCI_QUIRK (0x103c ,0x8299 ,"HP 800 G3 SFF" ,CXT_FIXUP_HP_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x103c ,0x829a ,"HP 800 G3 DM" ,CXT_FIXUP_HP_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x103c ,0x836e ,"HP ProBook 455 G5" ,CXT_FIXUP_MUTE_LED_GPIO ), +SND_PCI_QUIRK (0x103c ,0x837f ,"HP ProBook 470 G5" ,CXT_FIXUP_MUTE_LED_GPIO ), +SND_PCI_QUIRK (0x103c ,0x83b2 ,"HP EliteBook 840 G5" ,CXT_FIXUP_HP_DOCK ), +SND_PCI_QUIRK (0x103c ,0x83b3 ,"HP EliteBook 830 G5" ,CXT_FIXUP_HP_DOCK ), +SND_PCI_QUIRK (0x103c ,0x83d3 ,"HP ProBook 640 G4" ,CXT_FIXUP_HP_DOCK ),SND_PCI_QUIRK (0x103c ,0x8402 ,"HP ProBook 645 G4" ,CXT_FIXUP_MUTE_LED_GPIO ),SND_PCI_QUIRK (0x103c ,0x8427 ,"HP ZBook Studio G5" ,CXT_FIXUP_HP_ZBOOK_MUTE_LED ), SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
Greg Kroah-Hartman
maintainerPATCH 211/299 ALSA: sb: Fix two use after free in snd_sb_qsound_build
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
commit 4fb44dd2c1dda18606348acdfdb97e8759dde9df upstream.
In snd_sb_qsound_build, snd_ctl_add(..,p->qsound_switch...) and snd_ctl_add(..,p->qsound_space..) are called. But the second arguments of snd_ctl_add() could be freed via snd_ctl_add_replace() ->snd_ctl_free_one(). After the error code is returned, snd_sb_qsound_destroy(p) is called in __error branch.
But in snd_sb_qsound_destroy(), the freed p->qsound_switch and p->qsound_space are still used by snd_ctl_remove().
My patch set p->qsound_switch and p->qsound_space to NULL if snd_ctl_add() failed to avoid the uaf bugs. But these codes need to further be improved with the code style.
--- sound/isa/sb/sb16_csp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
sound/isa/sb/sb16_csp.c +6 -2
@@ -1045,10 +1045,14 @@ static int snd_sb_qsound_build(struct snspin_lock_init (&p->q_lock); -if ((err =snd_ctl_add (card, p->qsound_switch =snd_ctl_new1 (&snd_sb_qsound_switch, p))) <0 ) +if ((err =snd_ctl_add (card, p->qsound_switch =snd_ctl_new1 (&snd_sb_qsound_switch, p))) <0 ) { + p->qsound_switch =NULL ; goto __error; -if ((err =snd_ctl_add (card, p->qsound_space =snd_ctl_new1 (&snd_sb_qsound_space, p))) <0 ) + } +if ((err =snd_ctl_add (card, p->qsound_space =snd_ctl_new1 (&snd_sb_qsound_space, p))) <0 ) { + p->qsound_space =NULL ; goto __error; + }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 212/299 ALSA: usb-audio: Explicitly set up the clock selector
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit d2e8f641257d0d3af6e45d6ac2d6f9d56b8ea964 upstream.
In the current code, we have some assumption that the audio clock selector has been set up implicitly and don't want to touch it unless it's really needed for the fallback autoclock setup. This works for most devices but some seem having a problem. Partially this was covered for the devices with a single connector at the initialization phase (commit 086b957cc17f "ALSA: usb-audio: Skip the clock selector inquiry for single connections"), but also there are cases where the wrong clock set up is kept silently. The latter seems to be the cause of the noises on Behringer devices.
In this patch, we explicitly set up the audio clock selector whenever the appropriate node is found.
--- sound/usb/clock.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
sound/usb/clock.c +14 -4
@@ -296,7 +296,7 @@ static int __uac_clock_find_source(struc selector =snd_usb_find_clock_selector (chip->ctrl_intf, entity_id);if (selector) { -int ret, i, cur; +int ret, i, cur, err;/* the entity ID we are looking for is a selector. * find out what it currently selects */
@@ -318,13 +318,17 @@ static int __uac_clock_find_source(struc ret =__uac_clock_find_source (chip, fmt, selector->baCSourceID[ret -1 ], visited, validate); +if (ret >0 ) { + err =uac_clock_selector_set_val (chip, entity_id, cur); +if (err <0 ) +return err; + } +if (!validate || ret >0 || !chip->autoclock)return ret;/* The current clock source is invalid, try others. */ for (i =1 ; i <= selector->bNrInPins; i++) { -int err; -if (i == cur)continue ;
@@ -390,7 +394,7 @@ static int __uac3_clock_find_source(stru selector =snd_usb_find_clock_selector_v3 (chip->ctrl_intf, entity_id);if (selector) { -int ret, i, cur; +int ret, i, cur, err;/* the entity ID we are looking for is a selector. * find out what it currently selects */
@@ -412,6 +416,12 @@ static int __uac3_clock_find_source(stru ret =__uac3_clock_find_source (chip, fmt, selector->baCSourceID[ret -1 ], visited, validate); +if (ret >0 ) { + err =uac_clock_selector_set_val (chip, entity_id, cur); +if (err <0 ) +return err; + } +if (!validate || ret >0 || !chip->autoclock)return ret;
Greg Kroah-Hartman
maintainerPATCH 213/299 ALSA: usb-audio: Add dB range mapping for Sennheiser Communications Headset PC 8
In reply to Greg Kroah-HartmanFrom: Timo Gurr <[email protected]>
commit ab2165e2e6ed17345ffa8ee88ca764e8788ebcd7 upstream.
The decibel volume range contains a negative maximum value resulting in pipewire complaining about the device and effectivly having no sound output. The wrong values also resulted in the headset sounding muted already at a mixer level of about ~25%.
PipeWire BugLink: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1049
--- sound/usb/mixer_maps.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
sound/usb/mixer_maps.c +12 -0
@@ -337,6 +337,13 @@ static const struct usbmix_name_map bose { 0 } /* terminator */ }; +/* Sennheiser Communications Headset [PC 8], the dB value is reported as -6 negative maximum */ +static const struct usbmix_dB_map sennheiser_pc8_dB = {-9500 ,0 }; +static const struct usbmix_name_map sennheiser_pc8_map[] = { + {9 ,NULL , .dB = &sennheiser_pc8_dB }, + {0 }/* terminator */ +}; +/* * Dell usb dock with ALC4020 codec had a firmware problem where it got * screwed up when zero volume is passed; just skip it as a workaround
@@ -593,6 +600,11 @@ static const struct usbmix_ctl_map usbmi .id = USB_ID(0x17aa, 0x1046), .map = lenovo_p620_rear_map, }, + { +/* Sennheiser Communications Headset [PC 8] */ + .id = USB_ID(0x1395, 0x0025), + .map = sennheiser_pc8_map, + }, { 0 } /* terminator */ };
Greg Kroah-Hartman
maintainerPATCH 214/299 ALSA: hda/realtek: fix mute/micmute LEDs for HP ProBook 445 G7
In reply to Greg Kroah-HartmanFrom: Jonas Witschel <[email protected]>
commit 75b62ab65d2715ce6ff0794033d61ab9dc4a2dfc upstream.
The HP ProBook 445 G7 (17T32ES) uses ALC236. Like ALC236_FIXUP_HP_GPIO_LED, COEF index 0x34 bit 5 is used to control the playback mute LED, but the microphone mute LED is controlled using pin VREF instead of a COEF index.
AlsaInfo: https://alsa-project.org/db/?f=0d3f4d1af39cc359f9fea9b550727ee87e5cf45a
--- sound/pci/hda/patch_realtek.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
sound/pci/hda/patch_realtek.c +25 -0
@@ -4438,6 +4438,25 @@ static void alc236_fixup_hp_mute_led(stralc236_fixup_hp_coef_micmute_led (codec, fix, action); } +static void alc236_fixup_hp_micmute_led_vref (struct hda_codec *codec, +const struct hda_fixup *fix,int action) +{ +struct alc_spec *spec = codec->spec; + +if (action ==HDA_FIXUP_ACT_PRE_PROBE ) { + spec->cap_mute_led_nid =0x1a ; +snd_hda_gen_add_micmute_led_cdev (codec, vref_micmute_led_set); + codec->power_filter = led_power_filter; + } +} + +static void alc236_fixup_hp_mute_led_micmute_vref (struct hda_codec *codec, +const struct hda_fixup *fix,int action) +{ +alc236_fixup_hp_mute_led_coefbit (codec, fix, action); +alc236_fixup_hp_micmute_led_vref (codec, fix, action); +} +#if IS_REACHABLE (CONFIG_INPUT )static void gpio2_mic_hotkey_event (struct hda_codec *codec,struct hda_jack_callback *event)
@@ -6400,6 +6419,7 @@ enum {ALC285_FIXUP_HP_MUTE_LED ,ALC236_FIXUP_HP_GPIO_LED ,ALC236_FIXUP_HP_MUTE_LED , +ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ,ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET ,ALC295_FIXUP_ASUS_MIC_NO_PRESENCE , ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
@@ -7646,6 +7666,10 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_mute_led, }, + [ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_micmute_vref, + }, [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb []) {
@@ -8063,6 +8087,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x869d ,"HP" ,ALC236_FIXUP_HP_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x8724 ,"HP EliteBook 850 G7" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8729 ,"HP" ,ALC285_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x8730 ,"HP ProBook 445 G7" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ),SND_PCI_QUIRK (0x103c ,0x8736 ,"HP" ,ALC285_FIXUP_HP_GPIO_AMP_INIT ),SND_PCI_QUIRK (0x103c ,0x8760 ,"HP" ,ALC285_FIXUP_HP_MUTE_LED ), SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
Greg Kroah-Hartman
maintainerPATCH 215/299 ALSA: hda/realtek: GA503 use same quirks as GA401
In reply to Greg Kroah-HartmanFrom: Luke D Jones <[email protected]>
commit 76fae6185f5456865ff1bcb647709d44fd987eb6 upstream.
The GA503 has almost exactly the same default setup as the GA401 model with the same issues. The GA401 quirks solve all the issues so we will use the full quirk chain.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -8138,6 +8138,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x1ccd ,"ASUS X555UB" ,ALC256_FIXUP_ASUS_MIC ),SND_PCI_QUIRK (0x1043 ,0x1d4e ,"ASUS TM420" ,ALC256_FIXUP_ASUS_HPE ),SND_PCI_QUIRK (0x1043 ,0x1e11 ,"ASUS Zephyrus G15" ,ALC289_FIXUP_ASUS_GA502 ), +SND_PCI_QUIRK (0x1043 ,0x1e8e ,"ASUS Zephyrus G15" ,ALC289_FIXUP_ASUS_GA401 ),SND_PCI_QUIRK (0x1043 ,0x1f11 ,"ASUS Zephyrus G14" ,ALC289_FIXUP_ASUS_GA401 ),SND_PCI_QUIRK (0x1043 ,0x1881 ,"ASUS Zephyrus S/M" ,ALC294_FIXUP_ASUS_GX502_PINS ), SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Greg Kroah-Hartman
maintainerPATCH 216/299 ALSA: hda/realtek: fix mic boost on Intel NUC 8
In reply to Greg Kroah-HartmanFrom: Phil Calvin <[email protected]>
commit d1ee66c5d3c5a0498dd5e3f2af5b8c219a98bba5 upstream.
Fix two bugs with the Intel HDA Realtek ALC233 sound codec present in Intel NUC NUC8i7BEH and probably a few other similar NUC models.
These codecs advertise a 4-level microphone input boost amplifier on pin 0x19, but the highest two boost settings do not work correctly, and produce only low analog noise that does not seem to contain any discernible signal. There is an existing fixup for this exact problem but for a different PCI subsystem ID, so we re-use that logic.
Changing the boost level also triggers a DC spike in the input signal that bleeds off over about a second and overwhelms any input during that time. Thankfully, the existing fixup has the side effect of making the boost control show up in userspace as a mute/unmute switch, and this keeps (e.g.) PulseAudio from fiddling with it during normal input volume adjustments.
Finally, the NUC hardware has built-in inverted stereo mics. This patch also enables the usual fixup for this so the two channels cancel noise instead of the actual signal.
[ Re-ordered the quirk entry point by tiwai ]
--- sound/pci/hda/patch_realtek.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
sound/pci/hda/patch_realtek.c +13 -0
@@ -6435,6 +6435,8 @@ enum {ALC269_FIXUP_LEMOTE_A1802 ,ALC269_FIXUP_LEMOTE_A190X ,ALC256_FIXUP_INTEL_NUC8_RUGGED , +ALC233_FIXUP_INTEL_NUC8_DMIC , +ALC233_FIXUP_INTEL_NUC8_BOOST ,ALC256_FIXUP_INTEL_NUC10 ,ALC255_FIXUP_XIAOMI_HEADSET_MIC , ALC274_FIXUP_HP_MIC,
@@ -7156,6 +7158,16 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc233_fixup_lenovo_line2_mic_hotkey, }, + [ALC233_FIXUP_INTEL_NUC8_DMIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic, + .chained = true, + .chain_id = ALC233_FIXUP_INTEL_NUC8_BOOST, + }, + [ALC233_FIXUP_INTEL_NUC8_BOOST] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost + }, [ALC255_FIXUP_DELL_SPK_NOISE] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_disable_aamix,
@@ -8305,6 +8317,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x10ec ,0x118c ,"Medion EE4254 MD62100" ,ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE ),SND_PCI_QUIRK (0x1c06 ,0x2013 ,"Lemote A1802" ,ALC269_FIXUP_LEMOTE_A1802 ),SND_PCI_QUIRK (0x1c06 ,0x2015 ,"Lemote A190X" ,ALC269_FIXUP_LEMOTE_A190X ), +SND_PCI_QUIRK (0x8086 ,0x2074 ,"Intel NUC 8" ,ALC233_FIXUP_INTEL_NUC8_DMIC ),SND_PCI_QUIRK (0x8086 ,0x2080 ,"Intel NUC 8 Rugged" ,ALC256_FIXUP_INTEL_NUC8_RUGGED ), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
Greg Kroah-Hartman
maintainerPATCH 217/299 ALSA: hda/realtek - Headset Mic issue on HP platform
In reply to Greg Kroah-HartmanFrom: Kailang Yang <[email protected]>
commit 1c9d9dfd2d254211cb37b1513b1da3e6835b8f00 upstream.
Boot with plugged headset, the Headset Mic will be gone.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -8087,6 +8087,8 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x221c ,"HP EliteBook 755 G2" ,ALC280_FIXUP_HP_HEADSET_MIC ),SND_PCI_QUIRK (0x103c ,0x802e ,"HP Z240 SFF" ,ALC221_FIXUP_HP_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x103c ,0x802f ,"HP Z240" ,ALC221_FIXUP_HP_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x103c ,0x8077 ,"HP" ,ALC256_FIXUP_HP_HEADSET_MIC ), +SND_PCI_QUIRK (0x103c ,0x8158 ,"HP" ,ALC256_FIXUP_HP_HEADSET_MIC ),SND_PCI_QUIRK (0x103c ,0x820d ,"HP Pavilion 15" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ),SND_PCI_QUIRK (0x103c ,0x8256 ,"HP" ,ALC221_FIXUP_HP_FRONT_MIC ), SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Greg Kroah-Hartman
maintainerPATCH 218/299 ALSA: hda/realtek: fix static noise on ALC285 Lenovo laptops
In reply to Greg Kroah-HartmanFrom: Sami Loone <[email protected]>
commit 9bbb94e57df135ef61bef075d9c99b8d9e89e246 upstream.
Remove a duplicate vendor+subvendor pin fixup entry as one is masking the other and making it unreachable. Consider the more specific newcomer as a second chance instead.
The generic entry is made less strict to also match for laptops with slightly different 0x12 pin configuration. Tested on Lenovo Yoga 6 (AMD) where 0x12 is 0x40000000.
--- sound/pci/hda/patch_realtek.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
sound/pci/hda/patch_realtek.c +4 -5
@@ -8774,12 +8774,7 @@ static const struct snd_hda_pin_quirk al {0x12, 0x90a60130}, {0x19, 0x03a11020}, {0x21, 0x0321101f}), -SND_HDA_PIN_QUIRK (0x10ec0285 ,0x17aa ,"Lenovo" ,ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK , - {0x14, 0x90170110}, - {0x19, 0x04a11040}, - {0x21, 0x04211020}),SND_HDA_PIN_QUIRK (0x10ec0285 ,0x17aa ,"Lenovo" ,ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE , - {0x12, 0x90a60130}, {0x14, 0x90170110}, {0x19, 0x04a11040}, {0x21, 0x04211020}),
@@ -8950,6 +8945,10 @@ static const struct snd_hda_pin_quirk alSND_HDA_PIN_QUIRK (0x10ec0274 ,0x1028 ,"Dell" ,ALC274_FIXUP_DELL_AIO_LINEOUT_VERB , {0x19, 0x40000000}, {0x1a, 0x40000000}), +SND_HDA_PIN_QUIRK (0x10ec0285 ,0x17aa ,"Lenovo" ,ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK , + {0x14, 0x90170110}, + {0x19, 0x04a11040}, + {0x21, 0x04211020}), {} };
Greg Kroah-Hartman
maintainerPATCH 219/299 ALSA: hda/realtek: Add quirk for Intel Clevo PCx0Dx
In reply to Greg Kroah-HartmanFrom: Eckhart Mohr <[email protected]>
commit 970e3012c04c96351c413f193a9c909e6d871ce2 upstream.
This applies a SND_PCI_QUIRK(...) to the Clevo PCx0Dx barebones. This fix enables audio output over the headset jack and ensures that a microphone connected via the headset combo jack is correctly recognized when pluged in.
[ Rearranged the list entries in a sorted order -- tiwai ]
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -2552,8 +2552,10 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1558 ,0x65d1 ,"Clevo PB51[ER][CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x65d2 ,"Clevo PB51R[CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x65e1 ,"Clevo PB51[ED][DF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ), +SND_PCI_QUIRK (0x1558 ,0x65e5 ,"Clevo PC50D[PRS](?:-D|-G)?" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x67d1 ,"Clevo PB71[ER][CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x67e1 ,"Clevo PB71[DE][CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ), +SND_PCI_QUIRK (0x1558 ,0x67e5 ,"Clevo PC70D[PRS](?:-D|-G)?" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x70d1 ,"Clevo PC70[ER][CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x7714 ,"Clevo X170" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
Greg Kroah-Hartman
maintainerPATCH 220/299 tools/power/turbostat: Fix turbostat for AMD Zen CPUs
In reply to Greg Kroah-HartmanFrom: Bas Nieuwenhuizen <[email protected]>
commit 301b1d3a9104f4f3a8ab4171cf88d0f55d632b41 upstream.
It was reported that on Zen+ system turbostat started exiting, which was tracked down to the MSR_PKG_ENERGY_STAT read failing because offset_to_idx wasn't returning a non-negative index.
This patch combined the modification from Bingsong Si and
Bas Nieuwenhuizen and addd the MSR to the index system as alternative for MSR_PKG_ENERGY_STATUS.
--- tools/power/x86/turbostat/turbostat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
tools/power/x86/turbostat/turbostat.c +6 -2
@@ -297,7 +297,10 @@ int idx_to_offset(int idx)switch (idx) {case IDX_PKG_ENERGY : - offset =MSR_PKG_ENERGY_STATUS ; +if (do_rapl &RAPL_AMD_F17H ) + offset =MSR_PKG_ENERGY_STAT ; +else + offset =MSR_PKG_ENERGY_STATUS ;break ;case IDX_DRAM_ENERGY : offset =MSR_DRAM_ENERGY_STATUS ;
@@ -326,6 +329,7 @@ int offset_to_idx(int offset)switch (offset) {case MSR_PKG_ENERGY_STATUS : +case MSR_PKG_ENERGY_STAT : idx =IDX_PKG_ENERGY ;break ;case MSR_DRAM_ENERGY_STATUS :
@@ -353,7 +357,7 @@ int idx_valid(int idx) {switch (idx) {case IDX_PKG_ENERGY : -return do_rapl &RAPL_PKG ; +return do_rapl & (RAPL_PKG |RAPL_AMD_F17H );case IDX_DRAM_ENERGY :return do_rapl &RAPL_DRAM ;case IDX_PP0_ENERGY :
Greg Kroah-Hartman
maintainerPATCH 221/299 btrfs: fix race when picking most recent mod log operation for an old root
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
[ Upstream commit f9690f426b2134cc3e74bfc5d9dfd6a4b2ca5281 ]
Commit dbcc7d57bffc0c ("btrfs: fix race when cloning extent buffer during rewind of an old root"), fixed a race when we need to rewind the extent buffer of an old root. It was caused by picking a new mod log operation for the extent buffer while getting a cloned extent buffer with an outdated number of items (off by -1), because we cloned the extent buffer without locking it first.
However there is still another similar race, but in the opposite direction. The cloned extent buffer has a number of items that does not match the number of tree mod log operations that are going to be replayed. This is because right after we got the last (most recent) tree mod log operation to replay and before locking and cloning the extent buffer, another task adds a new pointer to the extent buffer, which results in adding a new tree mod log operation and incrementing the number of items in the extent buffer. So after cloning we have mismatch between the number of items in the extent buffer and the number of mod log operations we are going to apply to it. This results in hitting a BUG_ON() that produces the following stack trace:
------------[ cut here ]------------
kernel BUG at fs/btrfs/tree-mod-log.c:675!
invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 3 PID: 4811 Comm: crawl_1215 Tainted: G W 5.12.0-7d1efdf501f8-misc-next+ #99
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:tree_mod_log_rewind+0x3b1/0x3c0
Code: 05 48 8d 74 10 (...)
RSP: 0018:ffffc90001027090 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff8880a8514600 RCX: ffffffffaa9e59b6
RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8880a851462c
RBP: ffffc900010270e0 R08: 00000000000000c0 R09: ffffed1004333417
R10: ffff88802199a0b7 R11: ffffed1004333416 R12: 000000000000000e
R13: ffff888135af8748 R14: ffff88818766ff00 R15: ffff8880a851462c
FS: 00007f29acf62700(0000) GS:ffff8881f2200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f0e6013f718 CR3: 000000010d42e003 CR4: 0000000000170ee0
Call Trace:
btrfs_get_old_root+0x16a/0x5c0
? lock_downgrade+0x400/0x400
btrfs_search_old_slot+0x192/0x520
? btrfs_search_slot+0x1090/0x1090
? free_extent_buffer.part.61+0xd7/0x140
? free_extent_buffer+0x13/0x20
resolve_indirect_refs+0x3e9/0xfc0
? lock_downgrade+0x400/0x400
? __kasan_check_read+0x11/0x20
? add_prelim_ref.part.11+0x150/0x150
? lock_downgrade+0x400/0x400
? __kasan_check_read+0x11/0x20
? lock_acquired+0xbb/0x620
? __kasan_check_write+0x14/0x20
? do_raw_spin_unlock+0xa8/0x140
? rb_insert_color+0x340/0x360
? prelim_ref_insert+0x12d/0x430
find_parent_nodes+0x5c3/0x1830
? stack_trace_save+0x87/0xb0
? resolve_indirect_refs+0xfc0/0xfc0
? fs_reclaim_acquire+0x67/0xf0
? __kasan_check_read+0x11/0x20
? lockdep_hardirqs_on_prepare+0x210/0x210
? fs_reclaim_acquire+0x67/0xf0
? __kasan_check_read+0x11/0x20
? ___might_sleep+0x10f/0x1e0
? __kasan_kmalloc+0x9d/0xd0
? trace_hardirqs_on+0x55/0x120
btrfs_find_all_roots_safe+0x142/0x1e0
? find_parent_nodes+0x1830/0x1830
? trace_hardirqs_on+0x55/0x120
? ulist_free+0x1f/0x30
? btrfs_inode_flags_to_xflags+0x50/0x50
iterate_extent_inodes+0x20e/0x580
? tree_backref_for_extent+0x230/0x230
? release_extent_buffer+0x225/0x280
? read_extent_buffer+0xdd/0x110
? lock_downgrade+0x400/0x400
? __kasan_check_read+0x11/0x20
? lock_acquired+0xbb/0x620
? __kasan_check_write+0x14/0x20
? do_raw_spin_unlock+0xa8/0x140
? _raw_spin_unlock+0x22/0x30
? release_extent_buffer+0x225/0x280
iterate_inodes_from_logical+0x129/0x170
? iterate_inodes_from_logical+0x129/0x170
? btrfs_inode_flags_to_xflags+0x50/0x50
? iterate_extent_inodes+0x580/0x580
? __vmalloc_node+0x92/0xb0
? init_data_container+0x34/0xb0
? init_data_container+0x34/0xb0
? kvmalloc_node+0x60/0x80
btrfs_ioctl_logical_to_ino+0x158/0x230
btrfs_ioctl+0x2038/0x4360
? __kasan_check_write+0x14/0x20
? mmput+0x3b/0x220
? btrfs_ioctl_get_supported_features+0x30/0x30
? __kasan_check_read+0x11/0x20
? __kasan_check_read+0x11/0x20
? lock_release+0xc8/0x650
? __might_fault+0x64/0xd0
? __kasan_check_read+0x11/0x20
? lock_downgrade+0x400/0x400
? lockdep_hardirqs_on_prepare+0x210/0x210
? lockdep_hardirqs_on_prepare+0x13/0x210
? _raw_spin_unlock_irqrestore+0x51/0x63
? __kasan_check_read+0x11/0x20
? do_vfs_ioctl+0xfc/0x9d0
? ioctl_file_clone+0xe0/0xe0
? lock_downgrade+0x400/0x400
? lockdep_hardirqs_on_prepare+0x210/0x210
? __kasan_check_read+0x11/0x20
? lock_release+0xc8/0x650
? __task_pid_nr_ns+0xd3/0x250
? __kasan_check_read+0x11/0x20
? __fget_files+0x160/0x230
? __fget_light+0xf2/0x110
__x64_sys_ioctl+0xc3/0x100
do_syscall_64+0x37/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f29ae85b427
Code: 00 00 90 48 8b (...)
RSP: 002b:00007f29acf5fcf8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f29acf5ff40 RCX: 00007f29ae85b427
RDX: 00007f29acf5ff48 RSI: 00000000c038943b RDI: 0000000000000003
RBP: 0000000001000000 R08: 0000000000000000 R09: 00007f29acf60120
R10: 00005640d5fc7b00 R11: 0000000000000246 R12: 0000000000000003
R13: 00007f29acf5ff48 R14: 00007f29acf5ff40 R15: 00007f29acf5fef8
Modules linked in:
---[ end trace 85e5fce078dfbe04 ]--- (gdb) l *(tree_mod_log_rewind+0x3b1)
0xffffffff819e5b21 is in tree_mod_log_rewind (fs/btrfs/tree-mod-log.c:675).
670 * the modification. As we're going backwards, we do the 671 * opposite of each operation here. 672 */
673 switch (tm->op) {
674 case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING:
675 BUG_ON(tm->slot < n);
676 fallthrough;
677 case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING:
678 case BTRFS_MOD_LOG_KEY_REMOVE:
679 btrfs_set_node_key(eb, &tm->key, tm->slot);
(gdb) quit
The following steps explain in more detail how it happens:
1) We have one tree mod log user (through fiemap or the logical ino ioctl), with a sequence number of 1, so we have fs_info->tree_mod_seq == 1. This is task A;
2) Another task is at ctree.c:balance_level() and we have eb X currently as the root of the tree, and we promote its single child, eb Y, as the new root.
Then, at ctree.c:balance_level(), we call:
ret = btrfs_tree_mod_log_insert_root(root->node, child, true);
3) At btrfs_tree_mod_log_insert_root() we create a tree mod log operation of type BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING, with a ->logical field pointing to ebX->start. We only have one item in eb X, so we create only one tree mod log operation, and store in the "tm_list" array;
4) Then, still at btrfs_tree_mod_log_insert_root(), we create a tree mod log element of operation type BTRFS_MOD_LOG_ROOT_REPLACE, ->logical set to ebY->start, ->old_root.logical set to ebX->start, ->old_root.level set to the level of eb X and ->generation set to the generation of eb X;
5) Then btrfs_tree_mod_log_insert_root() calls tree_mod_log_free_eb() with "tm_list" as argument. After that, tree_mod_log_free_eb() calls tree_mod_log_insert(). This inserts the mod log operation of type BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING from step 3 into the rbtree with a sequence number of 2 (and fs_info->tree_mod_seq set to 2);
6) Then, after inserting the "tm_list" single element into the tree mod log rbtree, the BTRFS_MOD_LOG_ROOT_REPLACE element is inserted, which gets the sequence number 3 (and fs_info->tree_mod_seq set to 3);
7) Back to ctree.c:balance_level(), we free eb X by calling btrfs_free_tree_block() on it. Because eb X was created in the current transaction, has no other references and writeback did not happen for it, we add it back to the free space cache/tree;
8) Later some other task B allocates the metadata extent from eb X, since it is marked as free space in the space cache/tree, and uses it as a node for some other btree;
9) The tree mod log user task calls btrfs_search_old_slot(), which calls btrfs_get_old_root(), and finally that calls tree_mod_log_oldest_root() with time_seq == 1 and eb_root == eb Y;
10) The first iteration of the while loop finds the tree mod log element with sequence number 3, for the logical address of eb Y and of type BTRFS_MOD_LOG_ROOT_REPLACE;
11) Because the operation type is BTRFS_MOD_LOG_ROOT_REPLACE, we don't
break out of the loop, and set root_logical to point to
tm->old_root.logical, which corresponds to the logical address of
eb X;12) On the next iteration of the while loop, the call to tree_mod_log_search_oldest() returns the smallest tree mod log element for the logical address of eb X, which has a sequence number of 2, an operation type of BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING and corresponds to the old slot 0 of eb X (eb X had only 1 item in it before being freed at step 7);
13) We then break out of the while loop and return the tree mod log operation of type BTRFS_MOD_LOG_ROOT_REPLACE (eb Y), and not the one for slot 0 of eb X, to btrfs_get_old_root();
14) At btrfs_get_old_root(), we process the BTRFS_MOD_LOG_ROOT_REPLACE operation and set "logical" to the logical address of eb X, which was the old root. We then call tree_mod_log_search() passing it the logical address of eb X and time_seq == 1;
15) But before calling tree_mod_log_search(), task B locks eb X, adds a key to eb X, which results in adding a tree mod log operation of type BTRFS_MOD_LOG_KEY_ADD, with a sequence number of 4, to the tree mod log, and increments the number of items in eb X from 0 to 1. Now fs_info->tree_mod_seq has a value of 4;
16) Task A then calls tree_mod_log_search(), which returns the most recent tree mod log operation for eb X, which is the one just added by task B at the previous step, with a sequence number of 4, a type of BTRFS_MOD_LOG_KEY_ADD and for slot 0;
17) Before task A locks and clones eb X, task A adds another key to eb X, which results in adding a new BTRFS_MOD_LOG_KEY_ADD mod log operation, with a sequence number of 5, for slot 1 of eb X, increments the number of items in eb X from 1 to 2, and unlocks eb X.
Now fs_info->tree_mod_seq has a value of 5;
18) Task A then locks eb X and clones it. The clone has a value of 2 for the number of items and the pointer "tm" points to the tree mod log operation with sequence number 4, not the most recent one with a sequence number of 5, so there is mismatch between the number of mod log operations that are going to be applied to the cloned version of eb X and the number of items in the clone;
19) Task A then calls tree_mod_log_rewind() with the clone of eb X, the tree mod log operation with sequence number 4 and a type of BTRFS_MOD_LOG_KEY_ADD, and time_seq == 1;
20) At tree_mod_log_rewind(), we set the local variable "n" with a value of 2, which is the number of items in the clone of eb X.
Then in the first iteration of the while loop, we process the mod log operation with sequence number 4, which is targeted at slot 0 and has a type of BTRFS_MOD_LOG_KEY_ADD. This results in decrementing "n" from 2 to 1.
Then we pick the next tree mod log operation for eb X, which is the tree mod log operation with a sequence number of 2, a type of BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING and for slot 0, it is the one added in step 5 to the tree mod log tree.
We go back to the top of the loop to process this mod log operation, and because its slot is 0 and "n" has a value of 1, we hit the BUG_ON:
(...)
switch (tm->op) {
case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING:
BUG_ON(tm->slot < n); fallthrough;
(...)
Fix this by checking for a more recent tree mod log operation after locking and cloning the extent buffer of the old root node, and use it as the first operation to apply to the cloned extent buffer when rewinding it.
Stable backport notes: due to moved code and renames, in =< 5.11 the change should be applied to ctree.c:get_old_root.
--- fs/btrfs/ctree.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
fs/btrfs/ctree.c +20 -0
@@ -1367,10 +1367,30 @@ get_old_root(struct btrfs_root *root, u64 time_seq)"failed to read tree block %llu from get_old_root" , logical); }else { +struct tree_mod_elem *tm2; +btrfs_tree_read_lock (old); eb =btrfs_clone_extent_buffer (old); +/* +* After the lookup for the most recent tree mod operation +* above and before we locked and cloned the extent buffer +* 'old', a new tree mod log operation may have been added. +* So lookup for a more recent one to make sure the number +* of mod log operations we replay is consistent with the +* number of items we have in the cloned extent buffer, +* otherwise we can hit a BUG_ON when rewinding the extent +* buffer. +*/ + tm2 =tree_mod_log_search (fs_info, logical, time_seq);btrfs_tree_read_unlock (old);free_extent_buffer (old); +ASSERT (tm2); +ASSERT (tm2 == tm || tm2->seq > tm->seq); +if (!tm2 || tm2->seq < tm->seq) { +free_extent_buffer (eb); +return NULL ; + } + tm = tm2; } }else if (old_root) { eb_root_owner =btrfs_header_owner (eb_root);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 222/299 arm64/vdso: Discard .note.gnu.property sections in vDSO
In reply to Greg Kroah-HartmanFrom: Bill Wendling <[email protected]>
[ Upstream commit 388708028e6937f3fc5fc19aeeb847f8970f489c ]
The arm64 assembler in binutils 2.32 and above generates a program property note in a note section, .note.gnu.property, to encode used x86 ISAs and features. But the kernel linker script only contains a single NOTE segment:
PHDRS
{
text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
note PT_NOTE FLAGS(4); /* PF_R */
}The NOTE segment generated by the vDSO linker script is aligned to 4 bytes. But the .note.gnu.property section must be aligned to 8 bytes on arm64.
$ readelf -n vdso64.so
Displaying notes found in: .note
Owner Data size Description
Linux 0x00000004 Unknown note type: (0x00000000)
description data: 06 00 00 00 readelf: Warning: note with invalid namesz and/or descsz found at offset 0x20
readelf: Warning: type: 0x78, namesize: 0x00000100, descsize: 0x756e694c, alignment: 8
Since the note.gnu.property section in the vDSO is not checked by the dynamic linker, discard the .note.gnu.property sections in the vDSO.
Similar to commit 4caffe6a28d31 ("x86/vdso: Discard .note.gnu.property sections in vDSO"), but for arm64.
--- arch/arm64/kernel/vdso/vdso.lds.S | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm64/kernel/vdso/vdso.lds.S +7 -1
@@ -31,6 +31,13 @@ SECTIONS .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } + /* + * Discard .note.gnu.property sections which are unused and have + * different alignment requirement from vDSO note sections. + */ + /DISCARD/ : { + *(.note.GNU-stack .note.gnu.property) + } .note : { *(.note.*) } :text :note . = ALIGN(16);
@@ -51,7 +58,6 @@ SECTIONS PROVIDE(end = .); /DISCARD/ : { - *(.note.GNU-stack) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 223/299 Makefile: Move -Wno-unused-but-set-variable out of GCC only block
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 885480b084696331bea61a4f7eba10652999a9c1 upstream.
Currently, -Wunused-but-set-variable is only supported by GCC so it is disabled unconditionally in a GCC only block (it is enabled with W=1). clang currently has its implementation for this warning in review so preemptively move this statement out of the GCC only block and wrap it with cc-disable-warning so that both compilers function the same.
--- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Makefile +4 -4
@@ -775,16 +775,16 @@ KBUILD_CFLAGS += -Wno-gnu KBUILD_CFLAGS += -mno-global-merge else -# These warnings generated too much noise in a regular build. -# Use make W=1 to enable them (see scripts/Makefile.extrawarn) -KBUILD_CFLAGS += -Wno-unused-but-set-variable - # Warn about unmarked fall-throughs in switch statement. # Disabled for clang while comment to attribute conversion happens and # https://github.com/ClangBuiltLinux/linux/issues/636 is discussed. KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,) endif +# These warnings generated too much noise in a regular build. +# Use make W=1 to enable them (see scripts/Makefile.extrawarn) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) + KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
Greg Kroah-Hartman
maintainerPATCH 224/299 fs: fix reporting supported extra file attributes for statx()
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 5afa7e8b70d65819245fece61a65fd753b4aae33 upstream.
statx(2) notes that any attribute that is not indicated as supported by stx_attributes_mask has no usable value. Commits 801e523796004 ("fs: move generic stat response attr handling to vfs_getattr_nosec") and 712b2698e4c02 ("fs/stat: Define DAX statx attribute") sets STATX_ATTR_AUTOMOUNT and STATX_ATTR_DAX, respectively, without setting stx_attributes_mask, which can cause xfstests generic/532 to fail.
Fix this in the same way as commit 1b9598c8fb99 ("xfs: fix reporting supported extra file attributes for statx()")
--- fs/stat.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/stat.c +8 -0
@@ -77,12 +77,20 @@ int vfs_getattr_nosec(const struct path/* SB_NOATIME means filesystem supplies dummy atime value */ if (inode->i_sb->s_flags &SB_NOATIME ) stat->result_mask &= ~STATX_ATIME ; + +/* +* Note: If you add another clause to set an attribute flag, please +* update attributes_mask below. +*/ if (IS_AUTOMOUNT (inode)) stat->attributes |=STATX_ATTR_AUTOMOUNT ;if (IS_DAX (inode)) stat->attributes |=STATX_ATTR_DAX ; + stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT | +STATX_ATTR_DAX ); +if (inode->i_op->getattr)return inode->i_op->getattr (path, stat, request_mask, query_flags);
Greg Kroah-Hartman
maintainerPATCH 225/299 virtiofs: fix memory leak in virtio_fs_probe()
In reply to Greg Kroah-HartmanFrom: Luis Henriques <[email protected]>
commit c79c5e0178922a9e092ec8fed026750f39dcaef4 upstream.
When accidentally passing twice the same tag to qemu, kmemleak ended up reporting a memory leak in virtiofs. Also, looking at the log I saw the following error (that's when I realised the duplicated tag):
virtiofs: probe of virtio5 failed with error -17
Here's the kmemleak log for reference:
unreferenced object 0xffff888103d47800 (size 1024):
comm "systemd-udevd", pid 118, jiffies 4294893780 (age 18.340s) hex dump (first 32 bytes):
00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N..........
ff ff ff ff ff ff ff ff 80 90 02 a0 ff ff ff ff ................
backtrace:
[<000000000ebb87c1>] virtio_fs_probe+0x171/0x7ae [virtiofs]
[<00000000f8aca419>] virtio_dev_probe+0x15f/0x210
[<000000004d6baf3c>] really_probe+0xea/0x430
[<00000000a6ceeac8>] device_driver_attach+0xa8/0xb0
[<00000000196f47a7>] __driver_attach+0x98/0x140
[<000000000b20601d>] bus_for_each_dev+0x7b/0xc0
[<00000000399c7b7f>] bus_add_driver+0x11b/0x1f0
[<0000000032b09ba7>] driver_register+0x8f/0xe0
[<00000000cdd55998>] 0xffffffffa002c013
[<000000000ea196a2>] do_one_initcall+0x64/0x2e0
[<0000000008f727ce>] do_init_module+0x5c/0x260
[<000000003cdedab6>] __do_sys_finit_module+0xb5/0x120
[<00000000ad2f48c6>] do_syscall_64+0x33/0x40
[<00000000809526b5>] entry_SYSCALL_64_after_hwframe+0x44/0xae--- fs/fuse/virtio_fs.c | 1 + 1 file changed, 1 insertion(+)
fs/fuse/virtio_fs.c +1 -0
@@ -896,6 +896,7 @@ static int virtio_fs_probe(struct virtio out_vqs: vdev->config->reset (vdev);virtio_fs_cleanup_vqs (vdev, fs); +kfree (fs->vqs); out: vdev->priv =NULL ;
Greg Kroah-Hartman
maintainerPATCH 226/299 kcsan, debugfs: Move debugfs file creation out of early init
In reply to Greg Kroah-HartmanFrom: Marco Elver <[email protected]>
commit e36299efe7d749976fbdaaf756dee6ef32543c2c upstream.
Commit 56348560d495 ("debugfs: do not attempt to create a new file before the filesystem is initalized") forbids creating new debugfs files until debugfs is fully initialized. This means that KCSAN's debugfs file creation, which happened at the end of __init(), no longer works. And was apparently never supposed to work!
However, there is no reason to create KCSAN's debugfs file so early. This commit therefore moves its creation to a late_initcall() callback.
--- kernel/kcsan/core.c | 2 -- kernel/kcsan/debugfs.c | 4 +++- kernel/kcsan/kcsan.h | 5 ----- 3 files changed, 3 insertions(+), 8 deletions(-)
kernel/kcsan/core.c +0 -2
@@ -639,8 +639,6 @@ void __init kcsan_init(void)BUG_ON (!in_task ()); -kcsan_debugfs_init (); -for_each_possible_cpu (cpu)per_cpu (kcsan_rand_state, cpu) = (u32 )get_cycles ();
kernel/kcsan/debugfs.c +3 -1
@@ -261,7 +261,9 @@ static const struct file_operations debu .release = single_release }; -void __init kcsan_debugfs_init (void ) +static void __init kcsan_debugfs_init (void ) {debugfs_create_file ("kcsan" ,0644 ,NULL ,NULL , &debugfs_ops); } + +late_initcall (kcsan_debugfs_init);
kernel/kcsan/kcsan.h +0 -5
@@ -31,11 +31,6 @@ void kcsan_save_irqtrace(struct task_strvoid kcsan_restore_irqtrace (struct task_struct *task);/* -* Initialize debugfs file. -*/ -void kcsan_debugfs_init (void ); - -/* * Statistics counters displayed via debugfs; should only be modified in * slow-paths. */
Greg Kroah-Hartman
maintainerPATCH 227/299 ubifs: Only check replay with inode type to judge if inode linked
In reply to Greg Kroah-HartmanFrom: Guochun Mao <[email protected]>
commit 3e903315790baf4a966436e7f32e9c97864570ac upstream.
Conside the following case, it just write a big file into flash, when complete writing, delete the file, and then power off promptly. Next time power on, we'll get a replay list like:
...
LEB 1105:211344 len 4144 deletion 0 sqnum 428783 key type 1 inode 80 LEB 15:233544 len 160 deletion 1 sqnum 428785 key type 0 inode 80 LEB 1105:215488 len 4144 deletion 0 sqnum 428787 key type 1 inode 80
...
In the replay list, data nodes' deletion are 0, and the inode node's deletion is 1. In current logic, the file's dentry will be removed, but inode and the flash space it occupied will be reserved. User will see that much free space been disappeared.
We only need to check the deletion value of the following inode type node of the replay entry.
--- fs/ubifs/replay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ubifs/replay.c +2 -1
@@ -223,7 +223,8 @@ static bool inode_still_linked(struct ub*/ list_for_each_entry_reverse (r, &c->replay_list, list) {ubifs_assert (c, r->sqnum >= rino->sqnum); -if (key_inum (c, &r->key) ==key_inum (c, &rino->key)) +if (key_inum (c, &r->key) ==key_inum (c, &rino->key) && +key_type (c, &r->key) ==UBIFS_INO_KEY )return r->deletion ==0 ; }
Greg Kroah-Hartman
maintainerPATCH 228/299 f2fs: fix error handling in f2fs_end_enable_verity()
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 3c0315424f5e3d2a4113c7272367bee1e8e6a174 upstream.
f2fs didn't properly clean up if verity failed to be enabled on a file:
- It left verity metadata (pages past EOF) in the page cache, which would be exposed to userspace if the file was later extended.
- It didn't truncate the verity metadata at all (either from cache or from disk) if an error occurred while setting the verity bit.
Fix these bugs by adding a call to truncate_inode_pages() and ensuring that we truncate the verity metadata (both from cache and from disk) in all error paths. Also rework the code to cleanly separate the success path from the error paths, which makes it much easier to understand.
Finally, log a message if f2fs_truncate() fails, since it might otherwise fail silently.
--- fs/f2fs/verity.c | 79 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 23 deletions(-)
fs/f2fs/verity.c +56 -23
@@ -152,40 +152,73 @@ static int f2fs_end_enable_verity(struct size_t desc_size, u64 merkle_tree_size) {struct inode *inode =file_inode (filp); +struct f2fs_sb_info *sbi =F2FS_I_SB (inode);u64 desc_pos =f2fs_verity_metadata_pos (inode) + merkle_tree_size;struct fsverity_descriptor_location dloc = { .version =cpu_to_le32 (F2FS_VERIFY_VER ), .size =cpu_to_le32 (desc_size), .pos =cpu_to_le64 (desc_pos), }; -int err =0 ; +int err =0 , err2 =0 ; -if (desc !=NULL ) { -/* Succeeded; write the verity descriptor. */ - err =pagecache_write (inode, desc, desc_size, desc_pos); - -/* Write all pages before clearing FI_VERITY_IN_PROGRESS. */ -if (!err) - err =filemap_write_and_wait (inode->i_mapping); - } - -/* If we failed, truncate anything we wrote past i_size. */ -if (desc ==NULL || err) -f2fs_truncate (inode); +/* +* If an error already occurred (which fs/verity/ signals by passing +* desc == NULL), then only clean-up is needed. +*/ +if (desc ==NULL ) + goto cleanup; + +/* Append the verity descriptor. */ + err =pagecache_write (inode, desc, desc_size, desc_pos); +if (err) + goto cleanup; + +/* +* Write all pages (both data and verity metadata). Note that this must +* happen before clearing FI_VERITY_IN_PROGRESS; otherwise pages beyond +* i_size won't be written properly. For crash consistency, this also +* must happen before the verity inode flag gets persisted. +*/ + err =filemap_write_and_wait (inode->i_mapping); +if (err) + goto cleanup; + +/* Set the verity xattr. */ + err =f2fs_setxattr (inode,F2FS_XATTR_INDEX_VERITY , +F2FS_XATTR_NAME_VERITY , &dloc,sizeof (dloc), +NULL ,XATTR_CREATE ); +if (err) + goto cleanup; + +/* Finally, set the verity inode flag. */ +file_set_verity (inode); +f2fs_set_inode_flags (inode); +f2fs_mark_inode_dirty_sync (inode, true);clear_inode_flag (inode,FI_VERITY_IN_PROGRESS ); +return 0 ; -if (desc !=NULL && !err) { - err =f2fs_setxattr (inode,F2FS_XATTR_INDEX_VERITY , -F2FS_XATTR_NAME_VERITY , &dloc,sizeof (dloc), -NULL ,XATTR_CREATE ); -if (!err) { -file_set_verity (inode); -f2fs_set_inode_flags (inode); -f2fs_mark_inode_dirty_sync (inode, true); - } +cleanup: +/* +* Verity failed to be enabled, so clean up by truncating any verity +* metadata that was written beyond i_size (both from cache and from +* disk) and clearing FI_VERITY_IN_PROGRESS. +* +* Taking i_gc_rwsem[WRITE] is needed to stop f2fs garbage collection +* from re-instantiating cached pages we are truncating (since unlike +* normal file accesses, garbage collection isn't limited by i_size). +*/ +down_write (&F2FS_I (inode)->i_gc_rwsem[WRITE ]); +truncate_inode_pages (inode->i_mapping, inode->i_size); + err2 =f2fs_truncate (inode); +if (err2) { +f2fs_err (sbi,"Truncating verity metadata failed (errno=%d)" , + err2); +set_sbi_flag (sbi,SBI_NEED_FSCK ); } -return err; +up_write (&F2FS_I (inode)->i_gc_rwsem[WRITE ]); +clear_inode_flag (inode,FI_VERITY_IN_PROGRESS ); +return err ?: err2; } static int f2fs_get_verity_descriptor(struct inode *inode, void *buf,
Greg Kroah-Hartman
maintainerPATCH 229/299 f2fs: fix to avoid out-of-bounds memory access
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
commit b862676e371715456c9dade7990c8004996d0d9e upstream.
butt3rflyh4ck <[email protected]> reported a bug found by syzkaller fuzzer with custom modifications in 5.12.0-rc3+ [1]:
dump_stack+0xfa/0x151 lib/dump_stack.c:120 print_address_description.constprop.0.cold+0x82/0x32c mm/kasan/report.c:232 __kasan_report mm/kasan/report.c:399 [inline] kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:416 f2fs_test_bit fs/f2fs/f2fs.h:2572 [inline] current_nat_addr fs/f2fs/node.h:213 [inline] get_next_nat_page fs/f2fs/node.c:123 [inline] __flush_nat_entry_set fs/f2fs/node.c:2888 [inline] f2fs_flush_nat_entries+0x258e/0x2960 fs/f2fs/node.c:2991 f2fs_write_checkpoint+0x1372/0x6a70 fs/f2fs/checkpoint.c:1640 f2fs_issue_checkpoint+0x149/0x410 fs/f2fs/checkpoint.c:1807 f2fs_sync_fs+0x20f/0x420 fs/f2fs/super.c:1454 __sync_filesystem fs/sync.c:39 [inline] sync_filesystem fs/sync.c:67 [inline] sync_filesystem+0x1b5/0x260 fs/sync.c:48 generic_shutdown_super+0x70/0x370 fs/super.c:448 kill_block_super+0x97/0xf0 fs/super.c:1394
The root cause is, if nat entry in checkpoint journal area is corrupted, e.g. nid of journalled nat entry exceeds max nid value, during checkpoint, once it tries to flush nat journal to NAT area, get_next_nat_page() may access out-of-bounds memory on nat_bitmap due to it uses wrong nid value as bitmap offset.
[1] https://lore.kernel.org/lkml/CAFcO6XOMWdr8pObek6eN6-fs58KG9doRFadgJj-FnF-1x43s2g@mail.gmail.com/T/#u
--- fs/f2fs/node.c | 3 +++ 1 file changed, 3 insertions(+)
fs/f2fs/node.c +3 -0
@@ -2781,6 +2781,9 @@ static void remove_nats_in_journal(strucstruct f2fs_nat_entry raw_ne;nid_t nid =le32_to_cpu (nid_in_journal (journal, i)); +if (f2fs_check_nid_range (sbi, nid)) +continue ; + raw_ne =nat_in_journal (journal, i); ne =__lookup_nat_cache (nm_i, nid);
Greg Kroah-Hartman
maintainerPATCH 230/299 mlxsw: spectrum_mr: Update egress RIF list before routes action
In reply to Greg Kroah-HartmanFrom: Ido Schimmel <[email protected]>
commit cbaf3f6af9c268caf558c8e7ec52bcb35c5455dd upstream.
Each multicast route that is forwarding packets (as opposed to trapping them) points to a list of egress router interfaces (RIFs) through which packets are replicated.
A route's action can transition from trap to forward when a RIF is created for one of the route's egress virtual interfaces (eVIF). When this happens, the route's action is first updated and only later the list of egress RIFs is committed to the device.
This results in the route pointing to an invalid list. In case the list pointer is out of range (due to uninitialized memory), the device will complain:
mlxsw_spectrum2 0000:06:00.0: EMAD reg access failed (tid=5733bf490000905c,reg_id=300f(pefa),type=write,status=7(bad parameter))
Fix this by first committing the list of egress RIFs to the device and only later update the route's action.
Note that a fix is not needed in the reverse function (i.e., mlxsw_sp_mr_route_evif_unresolve()), as there the route's action is first updated and only later the RIF is removed from the list.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +15 -15
@@ -535,6 +535,16 @@ mlxsw_sp_mr_route_evif_resolve(struct mlu16 erif_index =0 ;int err; +/* Add the eRIF */ +if (mlxsw_sp_mr_vif_valid (rve->mr_vif)) { + erif_index =mlxsw_sp_rif_index (rve->mr_vif->rif); + err = mr->mr_ops->route_erif_add (mlxsw_sp, + rve->mr_route->route_priv, + erif_index); +if (err) +return err; + } +/* Update the route action, as the new eVIF can be a tunnel or a pimreg * device which will require updating the action. */
@@ -544,17 +554,7 @@ mlxsw_sp_mr_route_evif_resolve(struct ml rve->mr_route->route_priv, route_action);if (err) -return err; - } - -/* Add the eRIF */ -if (mlxsw_sp_mr_vif_valid (rve->mr_vif)) { - erif_index =mlxsw_sp_rif_index (rve->mr_vif->rif); - err = mr->mr_ops->route_erif_add (mlxsw_sp, - rve->mr_route->route_priv, - erif_index); -if (err) - goto err_route_erif_add; + goto err_route_action_update; }/* Update the minimum MTU */
@@ -572,14 +572,14 @@ mlxsw_sp_mr_route_evif_resolve(struct mlreturn 0 ; err_route_min_mtu_update: -if (mlxsw_sp_mr_vif_valid (rve->mr_vif)) - mr->mr_ops->route_erif_del (mlxsw_sp, rve->mr_route->route_priv, - erif_index); -err_route_erif_add:if (route_action != rve->mr_route->route_action) mr->mr_ops->route_action_update (mlxsw_sp, rve->mr_route->route_priv, rve->mr_route->route_action); +err_route_action_update: +if (mlxsw_sp_mr_vif_valid (rve->mr_vif)) + mr->mr_ops->route_erif_del (mlxsw_sp, rve->mr_route->route_priv, + erif_index);return err; }
Greg Kroah-Hartman
maintainerPATCH 231/299 openvswitch: fix stack OOB read while fragmenting IPv4 packets
In reply to Greg Kroah-HartmanFrom: Davide Caratti <[email protected]>
commit 7c0ea5930c1c211931819d83cfb157bff1539a4c upstream.
running openvswitch on kernels built with KASAN, it's possible to see the following splat while testing fragmentation of IPv4 packets:
BUG: KASAN: stack-out-of-bounds in ip_do_fragment+0x1b03/0x1f60 Read of size 1 at addr ffff888112fc713c by task handler2/1367 CPU: 0 PID: 1367 Comm: handler2 Not tainted 5.12.0-rc6+ #418 Hardware name: Red Hat KVM, BIOS 1.11.1-4.module+el8.1.0+4066+0f1aadab 04/01/2014 Call Trace: dump_stack+0x92/0xc1 print_address_description.constprop.7+0x1a/0x150 kasan_report.cold.13+0x7f/0x111 ip_do_fragment+0x1b03/0x1f60 ovs_fragment+0x5bf/0x840 [openvswitch] do_execute_actions+0x1bd5/0x2400 [openvswitch] ovs_execute_actions+0xc8/0x3d0 [openvswitch] ovs_packet_cmd_execute+0xa39/0x1150 [openvswitch] genl_family_rcv_msg_doit.isra.15+0x227/0x2d0 genl_rcv_msg+0x287/0x490 netlink_rcv_skb+0x120/0x380 genl_rcv+0x24/0x40 netlink_unicast+0x439/0x630 netlink_sendmsg+0x719/0xbf0 sock_sendmsg+0xe2/0x110 ____sys_sendmsg+0x5ba/0x890 ___sys_sendmsg+0xe9/0x160 __sys_sendmsg+0xd3/0x170 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f957079db07 Code: c3 66 90 41 54 41 89 d4 55 48 89 f5 53 89 fb 48 83 ec 10 e8 eb ec ff ff 44 89 e2 48 89 ee 89 df 41 89 c0 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 48 89 44 24 08 e8 24 ed ff ff 48 RSP: 002b:00007f956ce35a50 EFLAGS: 00000293 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000000000000019 RCX: 00007f957079db07 RDX: 0000000000000000 RSI: 00007f956ce35ae0 RDI: 0000000000000019 RBP: 00007f956ce35ae0 R08: 0000000000000000 R09: 00007f9558006730 R10: 0000000000000000 R11: 0000000000000293 R12: 0000000000000000 R13: 00007f956ce37308 R14: 00007f956ce35f80 R15: 00007f956ce35ae0 The buggy address belongs to the page: page:00000000af2a1d93 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x112fc7 flags: 0x17ffffc0000000() raw: 0017ffffc0000000 0000000000000000 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected
addr ffff888112fc713c is located in stack of task handler2/1367 at offset 180 in frame:
ovs_fragment+0x0/0x840 [openvswitch]
this frame has 2 objects:
[32, 144) 'ovs_dst'
[192, 424) 'ovs_rt'
Memory state around the buggy address:
ffff888112fc7000: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888112fc7080: 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00
>ffff888112fc7100: 00 00 00 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00
^
ffff888112fc7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888112fc7200: 00 00 00 00 00 00 f2 f2 f2 00 00 00 00 00 00 00for IPv4 packets, ovs_fragment() uses a temporary struct dst_entry. Then, in the following call graph:
ip_do_fragment()
ip_skb_dst_mtu()
ip_dst_mtu_maybe_forward()
ip_mtu_locked()the pointer to struct dst_entry is used as pointer to struct rtable: this turns the access to struct members like rt_mtu_locked into an OOB read in the stack. Fix this changing the temporary variable used for IPv4 packets in ovs_fragment(), similarly to what is done for IPv6 few lines below.
--- net/openvswitch/actions.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/openvswitch/actions.c +4 -4
@@ -827,17 +827,17 @@ static void ovs_fragment(struct net *net }if (key->eth.type ==htons (ETH_P_IP )) { -struct dst_entry ovs_dst; +struct rtable ovs_rt = {0 };unsigned long orig_dst;prepare_frag (vport, skb, orig_network_offset,ovs_key_mac_proto (key)); -dst_init (&ovs_dst, &ovs_dst_ops,NULL ,1 , +dst_init (&ovs_rt.dst, &ovs_dst_ops,NULL ,1 ,DST_OBSOLETE_NONE ,DST_NOCOUNT ); - ovs_dst.dev = vport->dev; + ovs_rt.dst.dev = vport->dev; orig_dst = skb->_skb_refdst; -skb_dst_set_noref (skb, &ovs_dst); +skb_dst_set_noref (skb, &ovs_rt.dst);IPCB (skb)->frag_max_size = mru;ip_do_fragment (net, skb->sk, skb, ovs_vport_output);
Greg Kroah-Hartman
maintainerPATCH 232/299 ACPI: GTDT: Dont corrupt interrupt mappings on watchdow probe failure
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit 1ecd5b129252249b9bc03d7645a7bda512747277 upstream.
When failing the driver probe because of invalid firmware properties, the GTDT driver unmaps the interrupt that it mapped earlier.
However, it never checks whether the mapping of the interrupt actially succeeded. Even more, should the firmware report an illegal interrupt number that overlaps with the GIC SGI range, this can result in an IPI being unmapped, and subsequent fireworks (as reported by Dann Frazier).
Rework the driver to have a slightly saner behaviour and actually check whether the interrupt has been mapped before unmapping things.
--- drivers/acpi/arm64/gtdt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/acpi/arm64/gtdt.c +6 -4
@@ -329,7 +329,7 @@ static int __init gtdt_import_sbsa_gwdt( int index) {struct platform_device *pdev; -int irq =map_gt_gsi (wd->timer_interrupt, wd->timer_flags); +int irq;/* * According to SBSA specification the size of refresh and control
@@ -338,7 +338,7 @@ static int __init gtdt_import_sbsa_gwdt(struct resource res[] = {DEFINE_RES_MEM (wd->control_frame_address,SZ_4K ),DEFINE_RES_MEM (wd->refresh_frame_address,SZ_4K ), -DEFINE_RES_IRQ (irq), + {}, };int nr_res =ARRAY_SIZE (res);
@@ -348,10 +348,11 @@ static int __init gtdt_import_sbsa_gwdt(if (!(wd->refresh_frame_address && wd->control_frame_address)) {pr_err (FW_BUG "failed to get the Watchdog base address.\n" ); -acpi_unregister_gsi (wd->timer_interrupt);return -EINVAL ; } + irq =map_gt_gsi (wd->timer_interrupt, wd->timer_flags); + res[2 ] = (struct resource )DEFINE_RES_IRQ (irq);if (irq <=0 ) {pr_warn ("failed to map the Watchdog interrupt.\n" ); nr_res--;
@@ -364,7 +365,8 @@ static int __init gtdt_import_sbsa_gwdt(*/ pdev =platform_device_register_simple ("sbsa-gwdt" , index, res, nr_res);if (IS_ERR (pdev)) { -acpi_unregister_gsi (wd->timer_interrupt); +if (irq >0 ) +acpi_unregister_gsi (wd->timer_interrupt);return PTR_ERR (pdev); }
Greg Kroah-Hartman
maintainerPATCH 233/299 NFS: fs_context: validate UDP retrans to prevent shift out-of-bounds
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit c09f11ef35955785f92369e25819bf0629df2e59 upstream.
Fix shift out-of-bounds in xprt_calc_majortimeo(). This is caused by a garbage timeout (retrans) mount option being passed to nfs mount, in this case from syzkaller.
If the protocol is XPRT_TRANSPORT_UDP, then 'retrans' is a shift value for a 64-bit long integer, so 'retrans' cannot be >= 64. If it is >= 64, fail the mount and return an error.
--- fs/nfs/fs_context.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
fs/nfs/fs_context.c +12 -0
@@ -938,6 +938,15 @@ static int nfs23_parse_monolithic(struct sizeof(mntfh->data) - mntfh->size);/* +* for proto == XPRT_TRANSPORT_UDP, which is what uses +* to_exponential, implying shift: limit the shift value +* to BITS_PER_LONG (majortimeo is unsigned long) +*/ +if (!(data->flags &NFS_MOUNT_TCP ))/* this will be UDP */ +if (data->retrans >=64 )/* shift value is too large */ + goto out_invalid_data; + +/* * Translate to nfs_fs_context, which nfs_fill_super * can deal with. */
@@ -1037,6 +1046,9 @@ out_no_address: out_invalid_fh:return nfs_invalf (fc,"NFS: invalid root filehandle" ); + +out_invalid_data: +return nfs_invalf (fc,"NFS: invalid binary mount data" ); }#if IS_ENABLED (CONFIG_NFS_V4 )
Greg Kroah-Hartman
maintainerPATCH 234/299 NFS: Dont discard pNFS layout segments that are marked for return
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit 39fd01863616964f009599e50ca5c6ea9ebf88d6 upstream.
If the pNFS layout segment is marked with the NFS_LSEG_LAYOUTRETURN flag, then the assumption is that it has some reporting requirement to perform through a layoutreturn (e.g. flexfiles layout stats or error information).
--- fs/nfs/pnfs.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/nfs/pnfs.c +5 -0
@@ -2470,6 +2470,9 @@ pnfs_mark_matching_lsegs_return(struct passert_spin_locked (&lo->plh_inode->i_lock); +if (test_bit (NFS_LAYOUT_RETURN_REQUESTED , &lo->plh_flags)) + tmp_list = &lo->plh_return_segs; +list_for_each_entry_safe (lseg, next, &lo->plh_segs, pls_list)if (pnfs_match_lseg_recall (lseg, return_range, seq)) { dprintk("%s: marking lseg %p iomode %d "
@@ -2477,6 +2480,8 @@ pnfs_mark_matching_lsegs_return(struct p lseg, lseg->pls_range.iomode, lseg->pls_range.offset, lseg->pls_range.length); +if (test_bit (NFS_LSEG_LAYOUTRETURN , &lseg->pls_flags)) + tmp_list = &lo->plh_return_segs;if (mark_lseg_invalid (lseg, tmp_list))continue ; remaining++;
Greg Kroah-Hartman
maintainerPATCH 235/299 NFSv4: Dont discard segments marked for return in _pnfs_return_layout()
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit de144ff4234f935bd2150108019b5d87a90a8a96 upstream.
If the pNFS layout segment is marked with the NFS_LSEG_LAYOUTRETURN flag, then the assumption is that it has some reporting requirement to perform through a layoutreturn (e.g. flexfiles layout stats or error information).
--- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/pnfs.c +1 -1
@@ -1344,7 +1344,7 @@ _pnfs_return_layout(struct inode *ino) } valid_layout =pnfs_layout_is_valid (lo);pnfs_clear_layoutcommit (ino, &tmp_list); -pnfs_mark_matching_lsegs_invalid (lo, &tmp_list,NULL ,0 ); +pnfs_mark_matching_lsegs_return (lo, &tmp_list,NULL ,0 );if (NFS_SERVER (ino)->pnfs_curr_ld->return_range) {struct pnfs_layout_range range = {
Greg Kroah-Hartman
maintainerPATCH 236/299 Input: ili210x - add missing negation for touch indication on ili210x
In reply to Greg Kroah-HartmanFrom: Hansem Ro <[email protected]>
commit ac05a8a927e5a1027592d8f98510a511dadeed14 upstream.
This adds the negation needed for proper finger detection on Ilitek ili2107/ili210x. This fixes polling issues (on Amazon Kindle Fire) caused by returning false for the cooresponding finger on the touchscreen.
--- drivers/input/touchscreen/ili210x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/touchscreen/ili210x.c +1 -1
@@ -87,7 +87,7 @@ static bool ili210x_touchdata_to_coords( unsigned int *x, unsigned int *y, unsigned int *z) { - if (touchdata[0] & BIT(finger)) + if (!(touchdata[0] & BIT(finger))) return false; *x =get_unaligned_be16 (touchdata +1 + (finger *4 ) +0 );
Greg Kroah-Hartman
maintainerPATCH 237/299 jffs2: Fix kasan slab-out-of-bounds problem
In reply to Greg Kroah-HartmanFrom: lizhe <[email protected]>
commit 960b9a8a7676b9054d8b46a2c7db52a0c8766b56 upstream.
KASAN report a slab-out-of-bounds problem. The logs are listed below. It is because in function jffs2_scan_dirent_node, we alloc "checkedlen+1" bytes for fd->name and we check crc with length rd->nsize. If checkedlen is less than rd->nsize, it will cause the slab-out-of-bounds problem.
jffs2: Dirent at *** has zeroes in name. Truncating to %d char
==================================================================
BUG: KASAN: slab-out-of-bounds in crc32_le+0x1ce/0x260 at addr ffff8800842cf2d1
Read of size 1 by task test_JFFS2/915
=============================================================================
BUG kmalloc-64 (Tainted: G B O ): kasan: bad access detected
-----------------------------------------------------------------------------
INFO: Allocated in jffs2_alloc_full_dirent+0x2a/0x40 age=0 cpu=1 pid=915
___slab_alloc+0x580/0x5f0
__slab_alloc.isra.24+0x4e/0x64
__kmalloc+0x170/0x300
jffs2_alloc_full_dirent+0x2a/0x40
jffs2_scan_eraseblock+0x1ca4/0x3b64
jffs2_scan_medium+0x285/0xfe0
jffs2_do_mount_fs+0x5fb/0x1bbc
jffs2_do_fill_super+0x245/0x6f0
jffs2_fill_super+0x287/0x2e0
mount_mtd_aux.isra.0+0x9a/0x144
mount_mtd+0x222/0x2f0
jffs2_mount+0x41/0x60
mount_fs+0x63/0x230
vfs_kern_mount.part.6+0x6c/0x1f4
do_mount+0xae8/0x1940
SyS_mount+0x105/0x1d0
INFO: Freed in jffs2_free_full_dirent+0x22/0x40 age=27 cpu=1 pid=915
__slab_free+0x372/0x4e4
kfree+0x1d4/0x20c
jffs2_free_full_dirent+0x22/0x40
jffs2_build_remove_unlinked_inode+0x17a/0x1e4
jffs2_do_mount_fs+0x1646/0x1bbc
jffs2_do_fill_super+0x245/0x6f0
jffs2_fill_super+0x287/0x2e0
mount_mtd_aux.isra.0+0x9a/0x144
mount_mtd+0x222/0x2f0
jffs2_mount+0x41/0x60
mount_fs+0x63/0x230
vfs_kern_mount.part.6+0x6c/0x1f4
do_mount+0xae8/0x1940
SyS_mount+0x105/0x1d0
entry_SYSCALL_64_fastpath+0x1e/0x97
Call Trace:
[<ffffffff815befef>] dump_stack+0x59/0x7e
[<ffffffff812d1d65>] print_trailer+0x125/0x1b0
[<ffffffff812d82c8>] object_err+0x34/0x40
[<ffffffff812dadef>] kasan_report.part.1+0x21f/0x534
[<ffffffff81132401>] ? vprintk+0x2d/0x40
[<ffffffff815f1ee2>] ? crc32_le+0x1ce/0x260
[<ffffffff812db41a>] kasan_report+0x26/0x30
[<ffffffff812d9fc1>] __asan_load1+0x3d/0x50
[<ffffffff815f1ee2>] crc32_le+0x1ce/0x260
[<ffffffff814764ae>] ? jffs2_alloc_full_dirent+0x2a/0x40
[<ffffffff81485cec>] jffs2_scan_eraseblock+0x1d0c/0x3b64
[<ffffffff81488813>] ? jffs2_scan_medium+0xccf/0xfe0
[<ffffffff81483fe0>] ? jffs2_scan_make_ino_cache+0x14c/0x14c
[<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50
[<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50
[<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70
[<ffffffff812d5d90>] ? kmem_cache_alloc_trace+0x10c/0x2cc
[<ffffffff818169fb>] ? mtd_point+0xf7/0x130
[<ffffffff81487dc9>] jffs2_scan_medium+0x285/0xfe0
[<ffffffff81487b44>] ? jffs2_scan_eraseblock+0x3b64/0x3b64
[<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50
[<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50
[<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70
[<ffffffff812d57df>] ? __kmalloc+0x12b/0x300
[<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70
[<ffffffff814a2753>] ? jffs2_sum_init+0x9f/0x240
[<ffffffff8148b2ff>] jffs2_do_mount_fs+0x5fb/0x1bbc
[<ffffffff8148ad04>] ? jffs2_del_noinode_dirent+0x640/0x640
[<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70
[<ffffffff81127c5b>] ? __init_rwsem+0x97/0xac
[<ffffffff81492349>] jffs2_do_fill_super+0x245/0x6f0
[<ffffffff81493c5b>] jffs2_fill_super+0x287/0x2e0
[<ffffffff814939d4>] ? jffs2_parse_options+0x594/0x594
[<ffffffff81819bea>] mount_mtd_aux.isra.0+0x9a/0x144
[<ffffffff81819eb6>] mount_mtd+0x222/0x2f0
[<ffffffff814939d4>] ? jffs2_parse_options+0x594/0x594
[<ffffffff81819c94>] ? mount_mtd_aux.isra.0+0x144/0x144
[<ffffffff81258757>] ? free_pages+0x13/0x1c
[<ffffffff814fa0ac>] ? selinux_sb_copy_data+0x278/0x2e0
[<ffffffff81492b35>] jffs2_mount+0x41/0x60
[<ffffffff81302fb7>] mount_fs+0x63/0x230
[<ffffffff8133755f>] ? alloc_vfsmnt+0x32f/0x3b0
[<ffffffff81337f2c>] vfs_kern_mount.part.6+0x6c/0x1f4
[<ffffffff8133ceec>] do_mount+0xae8/0x1940
[<ffffffff811b94e0>] ? audit_filter_rules.constprop.6+0x1d10/0x1d10
[<ffffffff8133c404>] ? copy_mount_string+0x40/0x40
[<ffffffff812cbf78>] ? alloc_pages_current+0xa4/0x1bc
[<ffffffff81253a89>] ? __get_free_pages+0x25/0x50
[<ffffffff81338993>] ? copy_mount_options.part.17+0x183/0x264
[<ffffffff8133e3a9>] SyS_mount+0x105/0x1d0
[<ffffffff8133e2a4>] ? copy_mnt_ns+0x560/0x560
[<ffffffff810e8391>] ? msa_space_switch_handler+0x13d/0x190
[<ffffffff81be184a>] entry_SYSCALL_64_fastpath+0x1e/0x97
[<ffffffff810e9274>] ? msa_space_switch+0xb0/0xe0
Memory state around the buggy address:
ffff8800842cf180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff8800842cf200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff8800842cf280: fc fc fc fc fc fc 00 00 00 00 01 fc fc fc fc fc
^
ffff8800842cf300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff8800842cf380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================--- fs/jffs2/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jffs2/scan.c +1 -1
@@ -1079,7 +1079,7 @@ static int jffs2_scan_dirent_node(structmemcpy (&fd->name, rd->name, checkedlen); fd->name[checkedlen] =0 ; - crc =crc32 (0 , fd->name, rd->nsize); + crc =crc32 (0 , fd->name, checkedlen);if (crc !=je32_to_cpu (rd->name_crc)) {pr_notice ("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n" , __func__, ofs,je32_to_cpu (rd->name_crc), crc);
Greg Kroah-Hartman
maintainerPATCH 238/299 jffs2: Hook up splice_write callback
In reply to Greg Kroah-HartmanFrom: Joel Stanley <[email protected]>
commit 42984af09afc414d540fcc8247f42894b0378a91 upstream.
overlayfs using jffs2 as the upper filesystem would fail in some cases since moving to v5.10. The test case used was to run 'touch' on a file that exists in the lower fs, causing the modification time to be updated. It returns EINVAL when the bug is triggered.
A bisection showed this was introduced in v5.9-rc1, with commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops"). Reverting that commit restores the expected behaviour.
Some digging showed that this was due to jffs2 lacking an implementation of splice_write. (For unknown reasons the warn_unsupported that should trigger was not displaying any output).
Adding this patch resolved the issue and the test now passes.
--- fs/jffs2/file.c | 1 + 1 file changed, 1 insertion(+)
fs/jffs2/file.c +1 -0
@@ -57,6 +57,7 @@ const struct file_operations jffs2_file_ .mmap = generic_file_readonly_mmap, .fsync = jffs2_fsync, .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, };/* jffs2_file_inode_operations */
Greg Kroah-Hartman
maintainerPATCH 239/299 powerpc/powernv: Enable HAIL (HV AIL) for ISA v3.1 processors
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
commit 49c1d07fd04f54eb588c4a1dfcedc8d22c5ffd50 upstream.
Starting with ISA v3.1, LPCR[AIL] no longer controls the interrupt mode for HV=1 interrupts. Instead, a new LPCR[HAIL] bit is defined which behaves like AIL=3 for HV interrupts when set.
Set HAIL on bare metal to give us mmu-on interrupts and improve performance.
This also fixes an scv bug: we don't implement scv real mode (AIL=0) vectors because they are at an inconvenient location, so we just disable scv support when AIL can not be set. However powernv assumes that LPCR[AIL] will enable AIL mode so it enables scv support despite HV interrupts being AIL=0, which causes scv interrupts to go off into the weeds.
--- arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/kernel/setup_64.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-)
arch/powerpc/include/asm/reg.h +1 -0
@@ -444,6 +444,7 @@#define LPCR_VRMA_LP1 ASM_CONST(0x0000800000000000)#define LPCR_RMLS 0x1C000000/* Implementation dependent RMO limit sel */ #define LPCR_RMLS_SH 26 +#define LPCR_HAIL ASM_CONST(0x0000000004000000)/* HV AIL (ISAv3.1) */ #define LPCR_ILE ASM_CONST(0x0000000002000000)/* !HV irqs set MSR:LE */ #define LPCR_AIL ASM_CONST(0x0000000001800000)/* Alternate interrupt location */ #define LPCR_AIL_0 ASM_CONST(0x0000000000000000)/* MMU off exception offset 0x0 */
arch/powerpc/kernel/setup_64.c +16 -3
@@ -231,10 +231,23 @@ static void cpu_ready_for_interrupts(voi* If we are not in hypervisor mode the job is done once for * the whole partition in configure_exceptions(). */ -if (cpu_has_feature (CPU_FTR_HVMODE ) && -cpu_has_feature (CPU_FTR_ARCH_207S )) { +if (cpu_has_feature (CPU_FTR_HVMODE )) {unsigned long lpcr =mfspr (SPRN_LPCR ); -mtspr (SPRN_LPCR , lpcr |LPCR_AIL_3 ); +unsigned long new_lpcr = lpcr; + +if (cpu_has_feature (CPU_FTR_ARCH_31 )) { +/* P10 DD1 does not have HAIL */ +if (pvr_version_is (PVR_POWER10 ) && + (mfspr (SPRN_PVR ) &0xf00 ) ==0x100 ) + new_lpcr |=LPCR_AIL_3 ; +else + new_lpcr |=LPCR_HAIL ; + }else if (cpu_has_feature (CPU_FTR_ARCH_207S )) { + new_lpcr |=LPCR_AIL_3 ; + } + +if (new_lpcr != lpcr) +mtspr (SPRN_LPCR , new_lpcr); }/*
Greg Kroah-Hartman
maintainerPATCH 240/299 powerpc/eeh: Fix EEH handling for hugepages in ioremap space.
In reply to Greg Kroah-HartmanFrom: Mahesh Salgaonkar <[email protected]>
commit 5ae5bc12d0728db60a0aa9b62160ffc038875f1a upstream.
During the EEH MMIO error checking, the current implementation fails to map the (virtual) MMIO address back to the pci device on radix with hugepage mappings for I/O. This results into failure to dispatch EEH event with no recovery even when EEH capability has been enabled on the device.
eeh_check_failure(token) # token = virtual MMIO address
addr = eeh_token_to_phys(token);
edev = eeh_addr_cache_get_dev(addr);
if (!edev)
return 0;
eeh_dev_check_failure(edev); <= Dispatch the EEH event
In case of hugepage mappings, eeh_token_to_phys() has a bug in virt -> phys translation that results in wrong physical address, which is then passed to eeh_addr_cache_get_dev() to match it against cached pci I/O address ranges to get to a PCI device. Hence, it fails to find a match and the EEH event never gets dispatched leaving the device in failed state.
The commit 33439620680be ("powerpc/eeh: Handle hugepages in ioremap space") introduced following logic to translate virt to phys for hugepage mappings:
eeh_token_to_phys():
+ pa = pte_pfn(*ptep);
+
+ /* On radix we can do hugepage mappings for io, so handle that */
+ if (hugepage_shift) {
+ pa <<= hugepage_shift; <= This is wrong
+ pa |= token & ((1ul << hugepage_shift) - 1);
+ }
This patch fixes the virt -> phys translation in eeh_token_to_phys() function.
$ cat /sys/kernel/debug/powerpc/eeh_address_cache mem addr range [0x0000040080000000-0x00000400807fffff]: 0030:01:00.1 mem addr range [0x0000040080800000-0x0000040080ffffff]: 0030:01:00.1 mem addr range [0x0000040081000000-0x00000400817fffff]: 0030:01:00.0 mem addr range [0x0000040081800000-0x0000040081ffffff]: 0030:01:00.0 mem addr range [0x0000040082000000-0x000004008207ffff]: 0030:01:00.1 mem addr range [0x0000040082080000-0x00000400820fffff]: 0030:01:00.0 mem addr range [0x0000040082100000-0x000004008210ffff]: 0030:01:00.1 mem addr range [0x0000040082110000-0x000004008211ffff]: 0030:01:00.0
Above is the list of cached io address ranges of pci 0030:01:00.<fn>.
Before this patch:
Tracing 'arg1' of function eeh_addr_cache_get_dev() during error injection clearly shows that 'addr=' contains wrong physical address:
kworker/u16:0-7 [001] .... 108.883775: eeh_addr_cache_get_dev:
(eeh_addr_cache_get_dev+0xc/0xf0) addr=0x80103000a510
dmesg shows no EEH recovery messages:
[ 108.563768] bnx2x: [bnx2x_timer:5801(eth2)]MFW seems hanged: drv_pulse (0x9ae) != mcp_pulse (0x7fff) [ 108.563788] bnx2x: [bnx2x_hw_stats_update:870(eth2)]NIG timer max (4294967295) [ 108.883788] bnx2x: [bnx2x_acquire_hw_lock:2013(eth1)]lock_status 0xffffffff resource_bit 0x1 [ 108.884407] bnx2x 0030:01:00.0 eth1: MDC/MDIO access timeout [ 108.884976] bnx2x 0030:01:00.0 eth1: MDC/MDIO access timeout <..>
After this patch:
eeh_addr_cache_get_dev() trace shows correct physical address:
<idle>-0 [001] ..s. 1043.123828: eeh_addr_cache_get_dev:
(eeh_addr_cache_get_dev+0xc/0xf0) addr=0x40080bc7cd8
dmesg logs shows EEH recovery getting triggerred:
[ 964.323980] bnx2x: [bnx2x_timer:5801(eth2)]MFW seems hanged: drv_pulse (0x746f) != mcp_pulse (0x7fff) [ 964.323991] EEH: Recovering PHB#30-PE#10000 [ 964.324002] EEH: PE location: N/A, PHB location: N/A [ 964.324006] EEH: Frozen PHB#30-PE#10000 detected <..>
--- arch/powerpc/kernel/eeh.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
arch/powerpc/kernel/eeh.c +4 -7
@@ -362,14 +362,11 @@ static inline unsigned long eeh_token_to pa =pte_pfn (*ptep);/* On radix we can do hugepage mappings for io, so handle that */ -if (hugepage_shift) { - pa <<= hugepage_shift; - pa |= token & ((1ul << hugepage_shift) -1 ); - }else { - pa <<=PAGE_SHIFT ; - pa |= token & (PAGE_SIZE -1 ); - } +if (!hugepage_shift) + hugepage_shift =PAGE_SHIFT ; + pa <<=PAGE_SHIFT ; + pa |= token & ((1ul << hugepage_shift) -1 );return pa; }
Greg Kroah-Hartman
maintainerPATCH 241/299 powerpc/kexec_file: Use current CPU info while setting up FDT
In reply to Greg Kroah-HartmanFrom: Sourabh Jain <[email protected]>
commit 40c753993e3aad51a12c21233486e2037417a4d6 upstream.
kexec_file_load() uses initial_boot_params in setting up the device tree for the kernel to be loaded. Though initial_boot_params holds info about CPUs at the time of boot, it doesn't account for hot added CPUs.
So, kexec'ing with kexec_file_load() syscall leaves the kexec'ed kernel with inaccurate CPU info.
If kdump kernel is loaded with kexec_file_load() syscall and the system crashes on a hot added CPU, the capture kernel hangs failing to identify the boot CPU, with no output.
To avoid this from happening, extract current CPU info from of_root device node and use it for setting up the fdt in kexec_file_load case.
--- arch/powerpc/kexec/file_load_64.c | 92 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+)
arch/powerpc/kexec/file_load_64.c +92 -0
@@ -961,6 +961,93 @@ unsigned int kexec_fdt_totalsize_ppc64(s }/** +* add_node_props - Reads node properties from device node structure and add +* them to fdt. +* @fdt: Flattened device tree of the kernel +* @node_offset: offset of the node to add a property at +* @dn: device node pointer +* +* Returns 0 on success, negative errno on error. +*/ +static int add_node_props (void *fdt,int node_offset,const struct device_node *dn) +{ +int ret =0 ; +struct property *pp; + +if (!dn) +return -EINVAL ; + +for_each_property_of_node (dn, pp) { + ret =fdt_setprop (fdt, node_offset, pp->name, pp->value, pp->length); +if (ret <0 ) { +pr_err ("Unable to add %s property: %s\n" , pp->name,fdt_strerror (ret)); +return ret; + } + } +return ret; +} + +/** +* update_cpus_node - Update cpus node of flattened device tree using of_root +* device node. +* @fdt: Flattened device tree of the kernel. +* +* Returns 0 on success, negative errno on error. +*/ +static int update_cpus_node (void *fdt) +{ +struct device_node *cpus_node, *dn; +int cpus_offset, cpus_subnode_offset, ret =0 ; + + cpus_offset =fdt_path_offset (fdt,"/cpus" ); +if (cpus_offset <0 && cpus_offset != -FDT_ERR_NOTFOUND ) { +pr_err ("Malformed device tree: error reading /cpus node: %s\n" , +fdt_strerror (cpus_offset)); +return cpus_offset; + } + +if (cpus_offset >0 ) { + ret =fdt_del_node (fdt, cpus_offset); +if (ret <0 ) { +pr_err ("Error deleting /cpus node: %s\n" ,fdt_strerror (ret)); +return -EINVAL ; + } + } + +/* Add cpus node to fdt */ + cpus_offset =fdt_add_subnode (fdt,fdt_path_offset (fdt,"/" ),"cpus" ); +if (cpus_offset <0 ) { +pr_err ("Error creating /cpus node: %s\n" ,fdt_strerror (cpus_offset)); +return -EINVAL ; + } + +/* Add cpus node properties */ + cpus_node =of_find_node_by_path ("/cpus" ); + ret =add_node_props (fdt, cpus_offset, cpus_node); +of_node_put (cpus_node); +if (ret <0 ) +return ret; + +/* Loop through all subnodes of cpus and add them to fdt */ +for_each_node_by_type (dn,"cpu" ) { + cpus_subnode_offset =fdt_add_subnode (fdt, cpus_offset, dn->full_name); +if (cpus_subnode_offset <0 ) { +pr_err ("Unable to add %s subnode: %s\n" , dn->full_name, +fdt_strerror (cpus_subnode_offset)); + ret = cpus_subnode_offset; + goto out; + } + + ret =add_node_props (fdt, cpus_subnode_offset, dn); +if (ret <0 ) + goto out; + } +out: +of_node_put (dn); +return ret; +} + +/** * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel * being loaded. * @image: kexec image being loaded.
@@ -1020,6 +1107,11 @@ int setup_new_fdt_ppc64(const struct kim } } +/* Update cpus nodes information to account hotplug CPUs. */ + ret =update_cpus_node (fdt); +if (ret <0 ) + goto out; +/* Update memory reserve map */ ret =get_reserved_memory_ranges (&rmem);if (ret)
Greg Kroah-Hartman
maintainerPATCH 242/299 powerpc/32: Fix boot failure with CONFIG_STACKPROTECTOR
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit f5668260b872e89b8d3942a8b7d4278aa9c2c981 upstream.
Commit 7c95d8893fb5 ("powerpc: Change calling convention for create_branch() et. al.") complexified the frame of function do_feature_fixups(), leading to GCC setting up a stack guard when CONFIG_STACKPROTECTOR is selected.
The problem is that do_feature_fixups() is called very early while 'current' in r2 is not set up yet and the code is still not at the final address used at link time.
So, like other instrumentation, stack protection needs to be deactivated for feature-fixups.c and code-patching.c
--- arch/powerpc/lib/Makefile | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/lib/Makefile +3 -0
@@ -5,6 +5,9 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) +CFLAGS_code-patching.o += -fno-stack-protector +CFLAGS_feature-fixups.o += -fno-stack-protector + CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
Greg Kroah-Hartman
maintainerPATCH 243/299 powerpc: fix EDEADLOCK redefinition error in uapi/asm/errno.h
In reply to Greg Kroah-HartmanFrom: Tony Ambardar <[email protected]>
commit 7de21e679e6a789f3729e8402bc440b623a28eae upstream.
A few archs like powerpc have different errno.h values for macros EDEADLOCK and EDEADLK. In code including both libc and linux versions of errno.h, this can result in multiple definitions of EDEADLOCK in the include chain. Definitions to the same value (e.g. seen with mips) do not raise warnings, but on powerpc there are redefinitions changing the value, which raise warnings and errors (if using "-Werror").
Guard against these redefinitions to avoid build errors like the following, first seen cross-compiling libbpf v5.8.9 for powerpc using GCC 8.4.0 with musl 1.1.24:
In file included from ../../arch/powerpc/include/uapi/asm/errno.h:5,
from ../../include/linux/err.h:8,
from libbpf.c:29: ../../include/uapi/asm-generic/errno.h:40: error: "EDEADLOCK" redefined [-Werror]
#define EDEADLOCK EDEADLK
In file included from toolchain-powerpc_8540_gcc-8.4.0_musl/include/errno.h:10,
from libbpf.c:26:
toolchain-powerpc_8540_gcc-8.4.0_musl/include/bits/errno.h:58: note: this is the location of the previous definition
#define EDEADLOCK 58
cc1: all warnings being treated as errors
--- arch/powerpc/include/uapi/asm/errno.h | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/include/uapi/asm/errno.h +1 -0
@@ -2,6 +2,7 @@#ifndef _ASM_POWERPC_ERRNO_H#define _ASM_POWERPC_ERRNO_H +#undef EDEADLOCK#include <asm-generic/errno.h> #undef EDEADLOCK
Greg Kroah-Hartman
maintainerPATCH 244/299 intel_th: pci: Add Alder Lake-M support
In reply to Greg Kroah-HartmanFrom: Alexander Shishkin <[email protected]>
commit 48cb17531b15967d9d3f34c770a25cc6c4ca6ad1 upstream.
This adds support for the Trace Hub in Alder Lake-M PCH.
--- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/hwtracing/intel_th/pci.c +5 -0
@@ -274,6 +274,11 @@ static const struct pci_device_id intel_ .driver_data = (kernel_ulong_t)&intel_th_2x, }, { +/* Alder Lake-M */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + {/* Alder Lake CPU */ PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x466f ), .driver_data = (kernel_ulong_t)&intel_th_2x,
Greg Kroah-Hartman
maintainerPATCH 245/299 tpm: efi: Use local variable for calculating final log size
In reply to Greg Kroah-HartmanFrom: Stefan Berger <[email protected]>
commit 48cff270b037022e37835d93361646205ca25101 upstream.
When tpm_read_log_efi is called multiple times, which happens when one loads and unloads a TPM2 driver multiple times, then the global variable efi_tpm_final_log_size will at some point become a negative number due to the subtraction of final_events_preboot_size occurring each time. Use a local variable to avoid this integer underflow.
The following issue is now resolved:
Mar 8 15:35:12 hibinst kernel: Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 Mar 8 15:35:12 hibinst kernel: Workqueue: tpm-vtpm vtpm_proxy_work [tpm_vtpm_proxy] Mar 8 15:35:12 hibinst kernel: RIP: 0010:__memcpy+0x12/0x20 Mar 8 15:35:12 hibinst kernel: Code: 00 b8 01 00 00 00 85 d2 74 0a c7 05 44 7b ef 00 0f 00 00 00 c3 cc cc cc 66 66 90 66 90 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 <f3> 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 f3 a4 Mar 8 15:35:12 hibinst kernel: RSP: 0018:ffff9ac4c0fcfde0 EFLAGS: 00010206 Mar 8 15:35:12 hibinst kernel: RAX: ffff88f878cefed5 RBX: ffff88f878ce9000 RCX: 1ffffffffffffe0f Mar 8 15:35:12 hibinst kernel: RDX: 0000000000000003 RSI: ffff9ac4c003bff9 RDI: ffff88f878cf0e4d Mar 8 15:35:12 hibinst kernel: RBP: ffff9ac4c003b000 R08: 0000000000001000 R09: 000000007e9d6073 Mar 8 15:35:12 hibinst kernel: R10: ffff9ac4c003b000 R11: ffff88f879ad3500 R12: 0000000000000ed5 Mar 8 15:35:12 hibinst kernel: R13: ffff88f878ce9760 R14: 0000000000000002 R15: ffff88f77de7f018 Mar 8 15:35:12 hibinst kernel: FS: 0000000000000000(0000) GS:ffff88f87bd00000(0000) knlGS:0000000000000000 Mar 8 15:35:12 hibinst kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Mar 8 15:35:12 hibinst kernel: CR2: ffff9ac4c003c000 CR3: 00000001785a6004 CR4: 0000000000060ee0 Mar 8 15:35:12 hibinst kernel: Call Trace: Mar 8 15:35:12 hibinst kernel: tpm_read_log_efi+0x152/0x1a7 Mar 8 15:35:12 hibinst kernel: tpm_bios_log_setup+0xc8/0x1c0 Mar 8 15:35:12 hibinst kernel: tpm_chip_register+0x8f/0x260 Mar 8 15:35:12 hibinst kernel: vtpm_proxy_work+0x16/0x60 [tpm_vtpm_proxy] Mar 8 15:35:12 hibinst kernel: process_one_work+0x1b4/0x370 Mar 8 15:35:12 hibinst kernel: worker_thread+0x53/0x3e0 Mar 8 15:35:12 hibinst kernel: ? process_one_work+0x370/0x370
--- drivers/char/tpm/eventlog/efi.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/char/tpm/eventlog/efi.c +21 -8
@@ -17,6 +17,7 @@ int tpm_read_log_efi(struct tpm_chip *ch {struct efi_tcg2_final_events_table *final_tbl =NULL ; +int final_events_log_size = efi_tpm_final_log_size;struct linux_efi_tpm_eventlog *log_tbl;struct tpm_bios_log *log;u32 log_size;
@@ -66,12 +67,12 @@ int tpm_read_log_efi(struct tpm_chip *ch ret = tpm_log_version;if (efi.tpm_final_log ==EFI_INVALID_TABLE_ADDR || - efi_tpm_final_log_size ==0 || + final_events_log_size ==0 || tpm_log_version !=EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 ) goto out; final_tbl =memremap (efi.tpm_final_log, -sizeof (*final_tbl) + efi_tpm_final_log_size, +sizeof (*final_tbl) + final_events_log_size,MEMREMAP_WB );if (!final_tbl) {pr_err ("Could not map UEFI TPM final log\n" );
@@ -80,10 +81,18 @@ int tpm_read_log_efi(struct tpm_chip *ch goto out; } - efi_tpm_final_log_size -= log_tbl->final_events_preboot_size; +/* +* The 'final events log' size excludes the 'final events preboot log' +* at its beginning. +*/ + final_events_log_size -= log_tbl->final_events_preboot_size; +/* +* Allocate memory for the 'combined log' where we will append the +* 'final events log' to. +*/ tmp =krealloc (log->bios_event_log, - log_size + efi_tpm_final_log_size, + log_size + final_events_log_size,GFP_KERNEL );if (!tmp) {kfree (log->bios_event_log);
@@ -94,15 +103,19 @@ int tpm_read_log_efi(struct tpm_chip *ch log->bios_event_log = tmp;/* -* Copy any of the final events log that didn't also end up in the -* main log. Events can be logged in both if events are generated +* Append any of the 'final events log' that didn't also end up in the +* 'main log'. Events can be logged in both if events are generated * between GetEventLog() and ExitBootServices(). */ memcpy ((void *)log->bios_event_log + log_size, final_tbl->events + log_tbl->final_events_preboot_size, - efi_tpm_final_log_size); + final_events_log_size); +/* +* The size of the 'combined log' is the size of the 'main log' plus +* the size of the 'final events log'. +*/ log->bios_event_log_end = log->bios_event_log + - log_size + efi_tpm_final_log_size; + log_size + final_events_log_size; out:memunmap (final_tbl);
Greg Kroah-Hartman
maintainerPATCH 246/299 tpm: vtpm_proxy: Avoid reading host log when using a virtual device
In reply to Greg Kroah-HartmanFrom: Stefan Berger <[email protected]>
commit 9716ac65efc8f780549b03bddf41e60c445d4709 upstream.
Avoid allocating memory and reading the host log when a virtual device is used since this log is of no use to that driver. A virtual device can be identified through the flag TPM_CHIP_FLAG_VIRTUAL, which is only set for the tpm_vtpm_proxy driver.
--- drivers/char/tpm/eventlog/common.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/char/tpm/eventlog/common.c +3 -0
@@ -107,6 +107,9 @@ void tpm_bios_log_setup(struct tpm_chipint log_version;int rc =0 ; +if (chip->flags &TPM_CHIP_FLAG_VIRTUAL ) +return ; + rc =tpm_read_log (chip);if (rc <0 )return ;
Greg Kroah-Hartman
maintainerPATCH 247/299 crypto: arm/curve25519 - Move .fpu after .arch
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 44200f2d9b8b52389c70e6c7bbe51e0dc6eaf938 upstream.
Debian's clang carries a patch that makes the default FPU mode 'vfp3-d16' instead of 'neon' for 'armv7-a' to avoid generating NEON instructions on hardware that does not support them:
https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/raw/5a61ca6f21b4ad8c6ac4970e5ea5a7b5b4486d22/debian/patches/clang-arm-default-vfp3-on-armv7a.patch
https://bugs.debian.org/841474
https://bugs.debian.org/842142
https://bugs.debian.org/914268
This results in the following build error when clang's integrated assembler is used because the '.arch' directive overrides the '.fpu' directive:
arch/arm/crypto/curve25519-core.S:25:2: error: instruction requires: NEON
vmov.i32 q0, #1
^arch/arm/crypto/curve25519-core.S:26:2: error: instruction requires: NEON
vshr.u64 q1, q0, #7
^arch/arm/crypto/curve25519-core.S:27:2: error: instruction requires: NEON
vshr.u64 q0, q0, #8
^arch/arm/crypto/curve25519-core.S:28:2: error: instruction requires: NEON
vmov.i32 d4, #19
^
Shuffle the order of the '.arch' and '.fpu' directives so that the code builds regardless of the default FPU mode. This has been tested against both clang with and without Debian's patch and GCC.
--- arch/arm/crypto/curve25519-core.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/crypto/curve25519-core.S +1 -1
@@ -10,8 +10,8 @@ #include <linux/linkage.h> .text -.fpu neon .arch armv7-a +.fpu neon .align 4 ENTRY(curve25519_neon)
Greg Kroah-Hartman
maintainerPATCH 248/299 crypto: rng - fix crypto_rng_reset() refcounting when !CRYPTO_STATS
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 30d0f6a956fc74bb2e948398daf3278c6b08c7e9 upstream.
crypto_stats_get() is a no-op when the kernel is compiled without CONFIG_CRYPTO_STATS, so pairing it with crypto_alg_put() unconditionally (as crypto_rng_reset() does) is wrong.
Fix this by moving the call to crypto_stats_get() to just before the actual algorithm operation which might need it. This makes it always paired with crypto_stats_rng_seed().
--- crypto/rng.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
crypto/rng.c +3 -7
@@ -34,22 +34,18 @@ int crypto_rng_reset(struct crypto_rng *u8 *buf =NULL ;int err; -crypto_stats_get (alg);if (!seed && slen) { buf =kmalloc (slen,GFP_KERNEL ); -if (!buf) { -crypto_alg_put (alg); +if (!buf)return -ENOMEM ; - } err =get_random_bytes_wait (buf, slen); -if (err) { -crypto_alg_put (alg); +if (err) goto out; - } seed = buf; } +crypto_stats_get (alg); err =crypto_rng_alg (tfm)->seed (tfm, seed, slen);crypto_stats_rng_seed (alg, err); out:
Greg Kroah-Hartman
maintainerPATCH 249/299 md/raid1: properly indicate failure when ending a failed write request
In reply to Greg Kroah-HartmanFrom: Paul Clements <[email protected]>
commit 2417b9869b81882ab90fd5ed1081a1cb2d4db1dd upstream.
This patch addresses a data corruption bug in raid1 arrays using bitmaps. Without this fix, the bitmap bits for the failed I/O end up being cleared.
Since we are in the failure leg of raid1_end_write_request, the request either needs to be retried (R1BIO_WriteError) or failed (R1BIO_Degraded).
--- drivers/md/raid1.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/raid1.c +2 -0
@@ -478,6 +478,8 @@ static void raid1_end_write_request(struif (!test_bit (Faulty, &rdev->flags))set_bit (R1BIO_WriteError, &r1_bio->state);else { +/* Fail the request */ +set_bit (R1BIO_Degraded, &r1_bio->state);/* Finished with this branch */ r1_bio->bios[mirror] =NULL ; to_put = bio;
Greg Kroah-Hartman
maintainerPATCH 250/299 dm raid: fix inconclusive reshape layout on fast raid4/5/6 table reload sequences
In reply to Greg Kroah-HartmanFrom: Heinz Mauelshagen <[email protected]>
commit f99a8e4373eeacb279bc9696937a55adbff7a28a upstream.
If fast table reloads occur during an ongoing reshape of raid4/5/6 devices the target may race reading a superblock vs the the MD resync thread; causing an inconclusive reshape state to be read in its constructor.
lvm2 test lvconvert-raid-reshape-stripes-load-reload.sh can cause BUG_ON() to trigger in md_run(), e.g.:
"kernel BUG at drivers/md/raid5.c:7567!".
Scenario triggering the bug:
1. the MD sync thread calls end_reshape() from raid5_sync_request() when done reshaping. However end_reshape() _only_ updates the reshape position to MaxSector keeping the changed layout configuration though (i.e. any delta disks, chunk sector or RAID algorithm changes). That inconclusive configuration is stored in the superblock.
2. dm-raid constructs a mapping, loading named inconsistent superblock as of step 1 before step 3 is able to finish resetting the reshape state completely, and calls md_run() which leads to mentioned bug in raid5.c.
3. the MD RAID personality's finish_reshape() is called; which resets the reshape information on chunk sectors, delta disks, etc. This explains why the bug is rarely seen on multi-core machines, as MD's finish_reshape() superblock update races with the dm-raid constructor's superblock load in step 2.
Fix identifies inconclusive superblock content in the dm-raid constructor and resets it before calling md_run(), factoring out identifying checks into rs_is_layout_change() to share in existing rs_reshape_requested() and new rs_reset_inclonclusive_reshape(). Also enhance a comment and remove an empty line.
--- drivers/md/dm-raid.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-)
drivers/md/dm-raid.c +28 -6
@@ -1869,6 +1869,14 @@ static bool rs_takeover_requested(structreturn rs->md.new_level != rs->md.level; } +/* True if layout is set to reshape. */ +static bool rs_is_layout_change (struct raid_set *rs,bool use_mddev) +{ +return (use_mddev ? rs->md.delta_disks : rs->delta_disks) || + rs->md.new_layout != rs->md.layout || + rs->md.new_chunk_sectors != rs->md.chunk_sectors; +} +/* True if @rs is requested to reshape by ctr */ static bool rs_reshape_requested (struct raid_set *rs) {
@@ -1881,9 +1889,7 @@ static bool rs_reshape_requested(structif (rs_is_raid0 (rs))return false; - change = mddev->new_layout != mddev->layout || - mddev->new_chunk_sectors != mddev->chunk_sectors || - rs->delta_disks; + change =rs_is_layout_change (rs, false);/* Historical case to support raid1 reshape without delta disks */ if (rs_is_raid1 (rs)) {
@@ -2818,7 +2824,7 @@ static sector_t _get_reshape_sectors(str }/* -* +* Reshape: * - change raid layout * - change chunk size * - add disks
@@ -2928,6 +2934,20 @@ static int rs_setup_reshape(struct raid_ }/* +* If the md resync thread has updated superblock with max reshape position +* at the end of a reshape but not (yet) reset the layout configuration +* changes -> reset the latter. +*/ +static void rs_reset_inconclusive_reshape (struct raid_set *rs) +{ +if (!rs_is_reshaping (rs) &&rs_is_layout_change (rs, true)) { +rs_set_cur (rs); + rs->md.delta_disks =0 ; + rs->md.reshape_backwards =0 ; + } +} + +/* * Enable/disable discard support on RAID set depending on * RAID level and discard properties of underlying RAID members. */
@@ -3213,11 +3233,14 @@ size_check:if (r) goto bad; +/* Catch any inconclusive reshape superblock content. */ +rs_reset_inconclusive_reshape (rs); +/* Start raid set read-only and assumed clean to change in raid_resume() */ rs->md.ro =1 ; rs->md.in_sync =1 ; -/* Keep array frozen */ +/* Keep array frozen until resume. */ set_bit (MD_RECOVERY_FROZEN , &rs->md.recovery);/* Has to be held on running the array */
@@ -3231,7 +3254,6 @@ size_check: } r =md_start (&rs->md); -if (r) { ti->error ="Failed to start raid array" ;mddev_unlock (&rs->md);
Greg Kroah-Hartman
maintainerPATCH 251/299 fuse: fix write deadlock
In reply to Greg Kroah-HartmanFrom: Vivek Goyal <[email protected]>
commit 4f06dd92b5d0a6f8eec6a34b8d6ef3e1f4ac1e10 upstream.
There are two modes for write(2) and friends in fuse:
a) write through (update page cache, send sync WRITE request to userspace)
b) buffered write (update page cache, async writeout later)
The write through method kept all the page cache pages locked that were used for the request. Keeping more than one page locked is deadlock prone and Qian Cai demonstrated this with trinity fuzzing.
The reason for keeping the pages locked is that concurrent mapped reads shouldn't try to pull possibly stale data into the page cache.
For full page writes, the easy way to fix this is to make the cached page be the authoritative source by marking the page PG_uptodate immediately. After this the page can be safely unlocked, since mapped/cached reads will take the written data from the cache.
Concurrent mapped writes will now cause data in the original WRITE request to be updated; this however doesn't cause any data inconsistency and this scenario should be exceedingly rare anyway.
If the WRITE request returns with an error in the above case, currently the page is not marked uptodate; this means that a concurrent read will always read consistent data. After this patch the page is uptodate between writing to the cache and receiving the error: there's window where a cached read will read the wrong data. While theoretically this could be a regression, it is unlikely to be one in practice, since this is normal for buffered writes.
In case of a partial page write to an already uptodate page the locking is also unnecessary, with the above caveats.
Partial write of a not uptodate page still needs to be handled. One way would be to read the complete page before doing the write. This is not possible, since it might break filesystems that don't expect any READ requests when the file was opened O_WRONLY.
The other solution is to serialize the synchronous write with reads from the partial pages. The easiest way to do this is to keep the partial pages locked. The problem is that a write() may involve two such pages (one head and one tail). This patch fixes it by only locking the partial tail page. If there's a partial head page as well, then split that off as a separate WRITE request.
--- fs/fuse/file.c | 41 +++++++++++++++++++++++++++++------------ fs/fuse/fuse_i.h | 1 + 2 files changed, 30 insertions(+), 12 deletions(-)
fs/fuse/file.c +29 -12
@@ -1093,6 +1093,7 @@ static ssize_t fuse_send_write_pages(strstruct fuse_file *ff = file->private_data;struct fuse_mount *fm = ff->fm;unsigned int offset, i; +bool short_write;int err;for (i =0 ; i < ap->num_pages; i++)
@@ -1105,32 +1106,38 @@ static ssize_t fuse_send_write_pages(strif (!err && ia->write.out.size > count) err = -EIO ; + short_write = ia->write.out.size < count; offset = ap->descs[0 ].offset; count = ia->write.out.size;for (i =0 ; i < ap->num_pages; i++) {struct page *page = ap->pages[i]; -if (!err && !offset && count >=PAGE_SIZE ) -SetPageUptodate (page); - -if (count >PAGE_SIZE - offset) - count -=PAGE_SIZE - offset; -else - count =0 ; - offset =0 ; - -unlock_page (page); +if (err) { +ClearPageUptodate (page); + }else { +if (count >=PAGE_SIZE - offset) + count -=PAGE_SIZE - offset; +else { +if (short_write) +ClearPageUptodate (page); + count =0 ; + } + offset =0 ; + } +if (ia->write.page_locked && (i == ap->num_pages -1 )) +unlock_page (page);put_page (page); }return err; } -static ssize_t fuse_fill_write_pages (struct fuse_args_pages *ap, +static ssize_t fuse_fill_write_pages (struct fuse_io_args *ia,struct address_space *mapping,struct iov_iter *ii,loff_t pos,unsigned int max_pages) { +struct fuse_args_pages *ap = &ia->ap;struct fuse_conn *fc =get_fuse_conn (mapping->host);unsigned offset = pos & (PAGE_SIZE -1 );size_t count =0 ;
@@ -1183,6 +1190,16 @@ static ssize_t fuse_fill_write_pages(strif (offset ==PAGE_SIZE ) offset =0 ; +/* If we copied full page, mark it uptodate */ +if (tmp ==PAGE_SIZE ) +SetPageUptodate (page); + +if (PageUptodate (page)) { +unlock_page (page); + }else { + ia->write.page_locked = true; +break ; + }if (!fc->big_writes)break ; } while (iov_iter_count(ii) && count < fc->max_write &&
@@ -1226,7 +1243,7 @@ static ssize_t fuse_perform_write(structbreak ; } - count =fuse_fill_write_pages (ap, mapping, ii, pos, nr_pages); + count =fuse_fill_write_pages (&ia, mapping, ii, pos, nr_pages);if (count <=0 ) { err = count; }else {
fs/fuse/fuse_i.h +1 -0
@@ -911,6 +911,7 @@ struct fuse_io_args {struct {struct fuse_write_in in;struct fuse_write_out out; +bool page_locked; } write; };struct fuse_args_pages ap;
Greg Kroah-Hartman
maintainerPATCH 252/299 exfat: fix erroneous discard when clear cluster bit
In reply to Greg Kroah-HartmanFrom: Hyeongseok Kim <[email protected]>
commit 77edfc6e51055b61cae2f54c8e6c3bb7c762e4fe upstream.
If mounted with discard option, exFAT issues discard command when clear cluster bit to remove file. But the input parameter of cluster-to-sector calculation is abnormally added by reserved cluster size which is 2, leading to discard unrelated sectors included in target+2 cluster. With fixing this, remove the wrong comments in set/clear/find bitmap functions.
--- fs/exfat/balloc.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
fs/exfat/balloc.c +1 -10
@@ -141,10 +141,6 @@ void exfat_free_bitmap(struct exfat_sb_ikfree (sbi->vol_amap); } -/* -* If the value of "clu" is 0, it means cluster 2 which is the first cluster of -* the cluster heap. -*/ int exfat_set_bitmap (struct inode *inode,unsigned int clu) {int i, b;
@@ -162,10 +158,6 @@ int exfat_set_bitmap(struct inode *inodereturn 0 ; } -/* -* If the value of "clu" is 0, it means cluster 2 which is the first cluster of -* the cluster heap. -*/ void exfat_clear_bitmap (struct inode *inode,unsigned int clu) {int i, b;
@@ -186,8 +178,7 @@ void exfat_clear_bitmap(struct inode *inint ret_discard; ret_discard =sb_issue_discard (sb, -exfat_cluster_to_sector (sbi, clu + -EXFAT_RESERVED_CLUSTERS ), +exfat_cluster_to_sector (sbi, clu), (1 << sbi->sect_per_clus_bits),GFP_NOFS ,0 );if (ret_discard == -EOPNOTSUPP ) {
Greg Kroah-Hartman
maintainerPATCH 253/299 sfc: farch: fix TX queue lookup in TX flush done handling
In reply to Greg Kroah-HartmanFrom: Edward Cree <[email protected]>
commit 5b1faa92289b53cad654123ed2bc8e10f6ddd4ac upstream.
We're starting from a TXQ instance number ('qid'), not a TXQ type, so
efx_get_tx_queue() is inappropriate (and could return NULL, leading to panics).
--- drivers/net/ethernet/sfc/farch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/sfc/farch.c +4 -4
@@ -1081,16 +1081,16 @@ static void efx_farch_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) { struct efx_tx_queue *tx_queue; +struct efx_channel *channel;int qid; qid =EFX_QWORD_FIELD (*event,FSF_AZ_DRIVER_EV_SUBDATA );if (qid <EFX_MAX_TXQ_PER_CHANNEL * (efx->n_tx_channels + efx->n_extra_tx_channels)) { - tx_queue =efx_get_tx_queue (efx, qid /EFX_MAX_TXQ_PER_CHANNEL , - qid %EFX_MAX_TXQ_PER_CHANNEL ); -if (atomic_cmpxchg (&tx_queue->flush_outstanding,1 ,0 )) { + channel =efx_get_tx_channel (efx, qid /EFX_MAX_TXQ_PER_CHANNEL ); + tx_queue = channel->tx_queue + (qid %EFX_MAX_TXQ_PER_CHANNEL ); +if (atomic_cmpxchg (&tx_queue->flush_outstanding,1 ,0 ))efx_farch_magic_event (tx_queue->channel,EFX_CHANNEL_MAGIC_TX_DRAIN (tx_queue)); - } } }
Greg Kroah-Hartman
maintainerPATCH 254/299 sfc: farch: fix TX queue lookup in TX event handling
In reply to Greg Kroah-HartmanFrom: Edward Cree <[email protected]>
commit 83b09a1807415608b387c7bc748d329fefc5617e upstream.
We're starting from a TXQ label, not a TXQ type, so
efx_channel_get_tx_queue() is inappropriate (and could return NULL, leading to panics).
--- drivers/net/ethernet/sfc/farch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/sfc/farch.c +4 -4
@@ -835,14 +835,14 @@ efx_farch_handle_tx_event(struct efx_cha/* Transmit completion */ tx_ev_desc_ptr =EFX_QWORD_FIELD (*event,FSF_AZ_TX_EV_DESC_PTR ); tx_ev_q_label =EFX_QWORD_FIELD (*event,FSF_AZ_TX_EV_Q_LABEL ); - tx_queue =efx_channel_get_tx_queue ( - channel, tx_ev_q_label %EFX_MAX_TXQ_PER_CHANNEL ); + tx_queue = channel->tx_queue + + (tx_ev_q_label %EFX_MAX_TXQ_PER_CHANNEL );efx_xmit_done (tx_queue, tx_ev_desc_ptr); }else if (EFX_QWORD_FIELD (*event,FSF_AZ_TX_EV_WQ_FF_FULL )) {/* Rewrite the FIFO write pointer */ tx_ev_q_label =EFX_QWORD_FIELD (*event,FSF_AZ_TX_EV_Q_LABEL ); - tx_queue =efx_channel_get_tx_queue ( - channel, tx_ev_q_label %EFX_MAX_TXQ_PER_CHANNEL ); + tx_queue = channel->tx_queue + + (tx_ev_q_label %EFX_MAX_TXQ_PER_CHANNEL );netif_tx_lock (efx->net_dev);efx_farch_notify_tx_desc (tx_queue);
Greg Kroah-Hartman
maintainerPATCH 255/299 security: commoncap: fix -Wstringop-overread warning
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit 82e5d8cc768b0c7b03c551a9ab1f8f3f68d5f83f upstream.
gcc-11 introdces a harmless warning for cap_inode_getsecurity:
security/commoncap.c: In function ‘cap_inode_getsecurity’:security/commoncap.c:440:33: error: ‘memcpy’ reading 16 bytes from a region of size 0 [-Werror=stringop-overread]
440 | memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~The problem here is that tmpbuf is initialized to NULL, so gcc assumes it is not accessible unless it gets set by vfs_getxattr_alloc(). This is a legitimate warning as far as I can tell, but the code is correct since it correctly handles the error when that function fails.
Add a separate NULL check to tell gcc about it as well.
--- security/commoncap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/commoncap.c +1 -1
@@ -391,7 +391,7 @@ int cap_inode_getsecurity(struct inode * &tmpbuf, size, GFP_NOFS);dput (dentry); -if (ret <0 ) +if (ret <0 || !tmpbuf)return ret; fs_ns = inode->i_sb->s_user_ns;
Greg Kroah-Hartman
maintainerPATCH 256/299 Fix misc new gcc warnings
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit e7c6e405e171fb33990a12ecfd14e6500d9e5cf2 upstream.
It seems like Fedora 34 ends up enabling a few new gcc warnings, notably "-Wstringop-overread" and "-Warray-parameter".
Both of them cause what seem to be valid warnings in the kernel, where we have array size mismatches in function arguments (that are no longer just silently converted to a pointer to element, but actually checked).
This fixes most of the trivial ones, by making the function declaration match the function definition, and in the case of intel_pm.c, removing the over-specified array size from the argument declaration.
At least one 'stringop-overread' warning remains in the i915 driver, but that one doesn't have the same obvious trivial fix, and may or may not actually be indicative of a bug.
[ It was a mistake to upgrade one of my machines to Fedora 34 while
being busy with the merge window, but if this is the extent of the
compiler upgrade problems, things are better than usual - Linus ]
--- drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/media/usb/dvb-usb/dvb-usb.h | 2 +- include/scsi/libfcoe.h | 2 +- net/bluetooth/ecdh_helper.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/intel_pm.c +1 -1
@@ -2992,7 +2992,7 @@ int ilk_wm_max_level(const struct drm_i9static void intel_print_wm_latency (struct drm_i915_private *dev_priv,const char *name, -const u16 wm[8 ]) +const u16 wm[]) {int level, max_level =ilk_wm_max_level (dev_priv);
drivers/media/usb/dvb-usb/dvb-usb.h +1 -1
@@ -487,7 +487,7 @@ extern int __must_check dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);/* commonly used remote control parsing */ -extern int dvb_usb_nec_rc_key_to_event (struct dvb_usb_device *,u8 [],u32 *,int *); +extern int dvb_usb_nec_rc_key_to_event (struct dvb_usb_device *,u8 [5 ],u32 *,int *);/* commonly used firmware download types and function */ struct hexline {
include/scsi/libfcoe.h +1 -1
@@ -249,7 +249,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctl struct fc_frame *);/* libfcoe funcs */ -u64 fcoe_wwn_from_mac (unsigned char mac[],unsigned int ,unsigned int ); +u64 fcoe_wwn_from_mac (unsigned char mac[MAX_ADDR_LEN ],unsigned int ,unsigned int );int fcoe_libfc_config (struct fc_lport *,struct fcoe_ctlr *,const struct libfc_function_template *,int init_fcp);u32 fcoe_fc_crc (struct fc_frame *fp);
net/bluetooth/ecdh_helper.h +1 -1
@@ -25,6 +25,6 @@int compute_ecdh_secret (struct crypto_kpp *tfm,const u8 pair_public_key[64 ],u8 secret[32 ]); -int set_ecdh_privkey (struct crypto_kpp *tfm,const u8 *private_key); +int set_ecdh_privkey (struct crypto_kpp *tfm,const u8 private_key[32 ]);int generate_ecdh_public_key (struct crypto_kpp *tfm,u8 public_key[64 ]);int generate_ecdh_keys (struct crypto_kpp *tfm,u8 public_key[64 ]);
Greg Kroah-Hartman
maintainerPATCH 257/299 jffs2: check the validity of dstlen in jffs2_zlib_compress()
In reply to Greg Kroah-HartmanFrom: Yang Yang <[email protected]>
commit 90ada91f4610c5ef11bc52576516d96c496fc3f1 upstream.
KASAN reports a BUG when download file in jffs2 filesystem.It is because when dstlen == 1, cpage_out will write array out of bounds. Actually, data will not be compressed in jffs2_zlib_compress() if data's length less than 4.
[ 393.799778] BUG: KASAN: slab-out-of-bounds in jffs2_rtime_compress+0x214/0x2f0 at addr ffff800062e3b281 [ 393.809166] Write of size 1 by task tftp/2918 [ 393.813526] CPU: 3 PID: 2918 Comm: tftp Tainted: G B 4.9.115-rt93-EMBSYS-CGEL-6.1.R6-dirty #1 [ 393.823173] Hardware name: LS1043A RDB Board (DT) [ 393.827870] Call trace: [ 393.830322] [<ffff20000808c700>] dump_backtrace+0x0/0x2f0 [ 393.835721] [<ffff20000808ca04>] show_stack+0x14/0x20 [ 393.840774] [<ffff2000086ef700>] dump_stack+0x90/0xb0 [ 393.845829] [<ffff20000827b19c>] kasan_object_err+0x24/0x80 [ 393.851402] [<ffff20000827b404>] kasan_report_error+0x1b4/0x4d8 [ 393.857323] [<ffff20000827bae8>] kasan_report+0x38/0x40 [ 393.862548] [<ffff200008279d44>] __asan_store1+0x4c/0x58 [ 393.867859] [<ffff2000084ce2ec>] jffs2_rtime_compress+0x214/0x2f0 [ 393.873955] [<ffff2000084bb3b0>] jffs2_selected_compress+0x178/0x2a0 [ 393.880308] [<ffff2000084bb530>] jffs2_compress+0x58/0x478 [ 393.885796] [<ffff2000084c5b34>] jffs2_write_inode_range+0x13c/0x450 [ 393.892150] [<ffff2000084be0b8>] jffs2_write_end+0x2a8/0x4a0 [ 393.897811] [<ffff2000081f3008>] generic_perform_write+0x1c0/0x280 [ 393.903990] [<ffff2000081f5074>] __generic_file_write_iter+0x1c4/0x228 [ 393.910517] [<ffff2000081f5210>] generic_file_write_iter+0x138/0x288 [ 393.916870] [<ffff20000829ec1c>] __vfs_write+0x1b4/0x238 [ 393.922181] [<ffff20000829ff00>] vfs_write+0xd0/0x238 [ 393.927232] [<ffff2000082a1ba8>] SyS_write+0xa0/0x110 [ 393.932283] [<ffff20000808429c>] __sys_trace_return+0x0/0x4 [ 393.937851] Object at ffff800062e3b280, in cache kmalloc-64 size: 64 [ 393.944197] Allocated: [ 393.946552] PID = 2918 [ 393.948913] save_stack_trace_tsk+0x0/0x220 [ 393.953096] save_stack_trace+0x18/0x20 [ 393.956932] kasan_kmalloc+0xd8/0x188 [ 393.960594] __kmalloc+0x144/0x238 [ 393.963994] jffs2_selected_compress+0x48/0x2a0 [ 393.968524] jffs2_compress+0x58/0x478 [ 393.972273] jffs2_write_inode_range+0x13c/0x450 [ 393.976889] jffs2_write_end+0x2a8/0x4a0 [ 393.980810] generic_perform_write+0x1c0/0x280 [ 393.985251] __generic_file_write_iter+0x1c4/0x228 [ 393.990040] generic_file_write_iter+0x138/0x288 [ 393.994655] __vfs_write+0x1b4/0x238 [ 393.998228] vfs_write+0xd0/0x238 [ 394.001543] SyS_write+0xa0/0x110 [ 394.004856] __sys_trace_return+0x0/0x4 [ 394.008684] Freed: [ 394.010691] PID = 2918 [ 394.013051] save_stack_trace_tsk+0x0/0x220 [ 394.017233] save_stack_trace+0x18/0x20 [ 394.021069] kasan_slab_free+0x88/0x188 [ 394.024902] kfree+0x6c/0x1d8 [ 394.027868] jffs2_sum_write_sumnode+0x2c4/0x880 [ 394.032486] jffs2_do_reserve_space+0x198/0x598 [ 394.037016] jffs2_reserve_space+0x3f8/0x4d8 [ 394.041286] jffs2_write_inode_range+0xf0/0x450 [ 394.045816] jffs2_write_end+0x2a8/0x4a0 [ 394.049737] generic_perform_write+0x1c0/0x280 [ 394.054179] __generic_file_write_iter+0x1c4/0x228 [ 394.058968] generic_file_write_iter+0x138/0x288 [ 394.063583] __vfs_write+0x1b4/0x238 [ 394.067157] vfs_write+0xd0/0x238 [ 394.070470] SyS_write+0xa0/0x110 [ 394.073783] __sys_trace_return+0x0/0x4 [ 394.077612] Memory state around the buggy address: [ 394.082404] ffff800062e3b180: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc [ 394.089623] ffff800062e3b200: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc [ 394.096842] >ffff800062e3b280: 01 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 394.104056] ^ [ 394.107283] ffff800062e3b300: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 394.114502] ffff800062e3b380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 394.121718] ==================================================================
--- fs/jffs2/compr_rtime.c | 3 +++ 1 file changed, 3 insertions(+)
fs/jffs2/compr_rtime.c +3 -0
@@ -37,6 +37,9 @@ static int jffs2_rtime_compress(unsignedint outpos =0 ;int pos=0 ; +if (*dstlen <=3 ) +return -1 ; +memset (positions,0 ,sizeof (positions));while (pos < (*sourcelen) && outpos <= (*dstlen)-2 ) {
Greg Kroah-Hartman
maintainerPATCH 258/299 smb3: when mounting with multichannel include it in requested capabilities
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit 679971e7213174efb56abc8fab1299d0a88db0e8 upstream.
In the SMB3/SMB3.1.1 negotiate protocol request, we are supposed to advertise CAP_MULTICHANNEL capability when establishing multiple channels has been requested by the user doing the mount. See MS-SMB2 sections 2.2.3 and 3.2.5.2
Without setting it there is some risk that multichannel could fail if the server interpreted the field strictly.
--- fs/cifs/smb2pdu.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/cifs/smb2pdu.c +5 -0
@@ -840,6 +840,8 @@ SMB2_negotiate(const unsigned int xid, s req->SecurityMode =0 ; req->Capabilities =cpu_to_le32 (server->vals->req_capabilities); +if (ses->chan_max >1 ) + req->Capabilities |=cpu_to_le32 (SMB2_GLOBAL_CAP_MULTI_CHANNEL );/* ClientGUID must be zero for SMB2.02 dialect */ if (server->vals->protocol_id ==SMB20_PROT_ID )
@@ -1025,6 +1027,9 @@ int smb3_validate_negotiate(const unsign pneg_inbuf->Capabilities =cpu_to_le32 (server->vals->req_capabilities); +if (tcon->ses->chan_max >1 ) + pneg_inbuf->Capabilities |=cpu_to_le32 (SMB2_GLOBAL_CAP_MULTI_CHANNEL ); +memcpy (pneg_inbuf->Guid, server->client_guid,SMB2_CLIENT_GUID_SIZE );
Greg Kroah-Hartman
maintainerPATCH 259/299 smb3: do not attempt multichannel to server which does not support it
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit 9c2dc11df50d1c8537075ff6b98472198e24438e upstream.
We were ignoring CAP_MULTI_CHANNEL in the server response - if the server doesn't support multichannel we should not be attempting it.
See MS-SMB2 section 3.2.5.2
--- fs/cifs/sess.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/cifs/sess.c +6 -0
@@ -92,6 +92,12 @@ int cifs_try_adding_channels(struct cifsreturn 0 ; } +if (!(ses->server->capabilities &SMB2_GLOBAL_CAP_MULTI_CHANNEL )) { +cifs_dbg (VFS ,"server %s does not support multichannel\n" , ses->server->hostname); + ses->chan_max =1 ; +return 0 ; + } +/* * Make a copy of the iface list at the time and use that * instead so as to not hold the iface spinlock for opening
Greg Kroah-Hartman
maintainerPATCH 260/299 Revert 337f13046ff0 ("futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op")
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit 4fbf5d6837bf81fd7a27d771358f4ee6c4f243f8 upstream.
The FUTEX_WAIT operand has historically a relative timeout which means that the clock id is irrelevant as relative timeouts on CLOCK_REALTIME are not subject to wall clock changes and therefore are mapped by the kernel to CLOCK_MONOTONIC for simplicity.
If a caller would set FUTEX_CLOCK_REALTIME for FUTEX_WAIT the timeout is still treated relative vs. CLOCK_MONOTONIC and then the wait arms that timeout based on CLOCK_REALTIME which is broken and obviously has never been used or even tested.
Reject any attempt to use FUTEX_CLOCK_REALTIME with FUTEX_WAIT again.
The desired functionality can be achieved with FUTEX_WAIT_BITSET and a FUTEX_BITSET_MATCH_ANY argument.
--- kernel/futex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/futex.c +1 -2
@@ -3714,8 +3714,7 @@ long do_futex(u32 __user *uaddr, int op,if (op &FUTEX_CLOCK_REALTIME ) { flags |=FLAGS_CLOCKRT ; -if (cmd !=FUTEX_WAIT && cmd !=FUTEX_WAIT_BITSET && \ - cmd !=FUTEX_WAIT_REQUEUE_PI ) +if (cmd !=FUTEX_WAIT_BITSET && cmd !=FUTEX_WAIT_REQUEUE_PI )return -ENOSYS ; }
Greg Kroah-Hartman
maintainerPATCH 261/299 futex: Do not apply time namespace adjustment on FUTEX_LOCK_PI
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit cdf78db4070967869e4d027c11f4dd825d8f815a upstream.
FUTEX_LOCK_PI does not require to have the FUTEX_CLOCK_REALTIME bit set because it has been using CLOCK_REALTIME based absolute timeouts forever. Due to that, the time namespace adjustment which is applied when FUTEX_CLOCK_REALTIME is not set, will wrongly take place for FUTEX_LOCK_PI and wreckage the timeout.
Exclude it from that procedure.
--- kernel/futex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/futex.c +2 -2
@@ -3784,7 +3784,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uad t =timespec64_to_ktime (ts);if (cmd ==FUTEX_WAIT ) t =ktime_add_safe (ktime_get (), t); -else if (!(op &FUTEX_CLOCK_REALTIME )) +else if (cmd !=FUTEX_LOCK_PI && !(op &FUTEX_CLOCK_REALTIME )) t =timens_ktime_to_host (CLOCK_MONOTONIC , t); tp = &t; }
@@ -3978,7 +3978,7 @@ SYSCALL_DEFINE6(futex_time32, u32 __user t =timespec64_to_ktime (ts);if (cmd ==FUTEX_WAIT ) t =ktime_add_safe (ktime_get (), t); -else if (!(op &FUTEX_CLOCK_REALTIME )) +else if (cmd !=FUTEX_LOCK_PI && !(op &FUTEX_CLOCK_REALTIME )) t =timens_ktime_to_host (CLOCK_MONOTONIC , t); tp = &t; }
Greg Kroah-Hartman
maintainerPATCH 262/299 x86/cpu: Initialize MSR_TSC_AUX if RDTSCP *or* RDPID is supported
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit b6b4fbd90b155a0025223df2c137af8a701d53b3 upstream.
Initialize MSR_TSC_AUX with CPU node information if RDTSCP or RDPID is supported. This fixes a bug where vdso_read_cpunode() will read garbage via RDPID if RDPID is supported but RDTSCP is not. While no known CPU supports RDPID but not RDTSCP, both Intel's SDM and AMD's APM allow for RDPID to exist without RDTSCP, e.g. it's technically a legal CPU model for a virtual machine.
Note, technically MSR_TSC_AUX could be initialized if and only if RDPID is supported since RDTSCP is currently not used to retrieve the CPU node. But, the cost of the superfluous WRMSR is negigible, whereas leaving MSR_TSC_AUX uninitialized is just asking for future breakage if someone decides to utilize RDTSCP.
--- arch/x86/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/common.c +1 -1
@@ -1847,7 +1847,7 @@ static inline void setup_getcpu(int cpu)unsigned long cpudata =vdso_encode_cpunode (cpu,early_cpu_to_node (cpu));struct desc_struct d = { }; -if (boot_cpu_has (X86_FEATURE_RDTSCP )) +if (boot_cpu_has (X86_FEATURE_RDTSCP ) ||boot_cpu_has (X86_FEATURE_RDPID ))write_rdtscp_aux (cpudata);/* Store CPU and node number in limit. */
Greg Kroah-Hartman
maintainerPATCH 263/299 kbuild: update config_data.gz only when the content of .config is changed
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
commit 46b41d5dd8019b264717978c39c43313a524d033 upstream.
If the timestamp of the .config file is updated, config_data.gz is regenerated, then vmlinux is re-linked. This occurs even if the content of the .config has not changed at all.
This issue was mitigated by commit 67424f61f813 ("kconfig: do not write .config if the content is the same"); Kconfig does not update the .config when it ends up with the identical configuration.
The issue is remaining when the .config is created by *_defconfig with some config fragment(s) applied on top.
This is typical for powerpc and mips, where several *_defconfig targets are constructed by using merge_config.sh.
One workaround is to have the copy of the .config. The filechk rule updates the copy, kernel/config_data, by checking the content instead of the timestamp.
With this commit, the second run with the same configuration avoids the needless rebuilds.
$ make ARCH=mips defconfig all
[ snip ]
$ make ARCH=mips defconfig all
*** Default configuration is based on target '32r2el_defconfig'
Using ./arch/mips/configs/generic_defconfig as base
Merging arch/mips/configs/generic/32r2.config
Merging arch/mips/configs/generic/el.config
Merging ./arch/mips/configs/generic/board-boston.config
Merging ./arch/mips/configs/generic/board-ni169445.config
Merging ./arch/mips/configs/generic/board-ocelot.config
Merging ./arch/mips/configs/generic/board-ranchu.config
Merging ./arch/mips/configs/generic/board-sead-3.config
Merging ./arch/mips/configs/generic/board-xilfpga.config
#
# configuration written to .config
#
SYNC include/config/auto.conf
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
CHK include/generated/compile.h
CHK include/generated/autoksyms.h--- kernel/.gitignore | 1 + kernel/Makefile | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
kernel/.gitignore +1 -0
@@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +/config_data kheaders.md5 timeconst.h hz.bc
kernel/Makefile +7 -2
@@ -134,10 +134,15 @@ obj-$(CONFIG_SCF_TORTURE_TEST) += scftor $(obj)/configs.o: $(obj)/config_data.gz -targets += config_data.gz -$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE +targets += config_data config_data.gz +$(obj)/config_data.gz: $(obj)/config_data FORCE $(call if_changed,gzip) +filechk_cat = cat $< + +$(obj)/config_data: $(KCONFIG_CONFIG) FORCE + $(call filechk,cat) + $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz
Greg Kroah-Hartman
maintainerPATCH 264/299 ext4: annotate data race in start_this_handle()
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 3b1833e92baba135923af4a07e73fe6e54be5a2f upstream.
Access to journal->j_running_transaction is not protected by appropriate lock and thus is racy. We are well aware of that and the code handles the race properly. Just add a comment and data_race() annotation.
--- fs/jbd2/transaction.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/jbd2/transaction.c +6 -1
@@ -349,7 +349,12 @@ static int start_this_handle(journal_t * } alloc_transaction: -if (!journal->j_running_transaction) { +/* +* This check is racy but it is just an optimization of allocating new +* transaction early if there are high chances we'll need it. If we +* guess wrong, we'll retry or free unused transaction. +*/ +if (!data_race (journal->j_running_transaction)) {/* * If __GFP_FS is not present, then we may be being called from * inside the fs writeback layer, so we MUST NOT fail.
Greg Kroah-Hartman
maintainerPATCH 265/299 ext4: annotate data race in jbd2_journal_dirty_metadata()
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 83fe6b18b8d04c6c849379005e1679bac9752466 upstream.
Assertion checks in jbd2_journal_dirty_metadata() are known to be racy but we don't want to be grabbing locks just for them. We thus recheck them under b_state_lock only if it looks like they would fail. Annotate the checks with data_race().
--- fs/jbd2/transaction.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/jbd2/transaction.c +4 -4
@@ -1479,8 +1479,8 @@ int jbd2_journal_dirty_metadata(handle_t* crucial to catch bugs so let's do a reliable check until the * lockless handling is fully proven. */ -if (jh->b_transaction != transaction && - jh->b_next_transaction != transaction) { +if (data_race (jh->b_transaction != transaction && + jh->b_next_transaction != transaction)) {spin_lock (&jh->b_state_lock);J_ASSERT_JH (jh, jh->b_transaction == transaction || jh->b_next_transaction == transaction);
@@ -1488,8 +1488,8 @@ int jbd2_journal_dirty_metadata(handle_t }if (jh->b_modified ==1 ) {/* If it's in our transaction it must be in BJ_Metadata list. */ -if (jh->b_transaction == transaction && - jh->b_jlist != BJ_Metadata) { +if (data_race (jh->b_transaction == transaction && + jh->b_jlist != BJ_Metadata)) {spin_lock (&jh->b_state_lock);if (jh->b_transaction == transaction && jh->b_jlist != BJ_Metadata)
Greg Kroah-Hartman
maintainerPATCH 266/299 ext4: fix check to prevent false positive report of incorrect used inodes
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
commit a149d2a5cabbf6507a7832a1c4fd2593c55fd450 upstream.
Commit <50122847007> ("ext4: fix check to prevent initializing reserved inodes") check the block group zero and prevent initializing reserved inodes. But in some special cases, the reserved inode may not all belong to the group zero, it may exist into the second group if we format filesystem below.
mkfs.ext4 -b 4096 -g 8192 -N 1024 -I 4096 /dev/sda
So, it will end up triggering a false positive report of a corrupted file system. This patch fix it by avoid check reserved inodes if no free inode blocks will be zeroed.
--- fs/ext4/ialloc.c | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-)
fs/ext4/ialloc.c +32 -16
@@ -1512,6 +1512,7 @@ int ext4_init_inode_table(struct super_bhandle_t *handle;ext4_fsblk_t blk;int num, ret =0 , used_blks =0 ; +unsigned long used_inos =0 ;/* This should not happen, but just to be sure check this */ if (sb_rdonly (sb)) {
@@ -1542,22 +1543,37 @@ int ext4_init_inode_table(struct super_b* used inodes so we need to skip blocks with used inodes in * inode table. */ -if (!(gdp->bg_flags &cpu_to_le16 (EXT4_BG_INODE_UNINIT ))) - used_blks =DIV_ROUND_UP ((EXT4_INODES_PER_GROUP (sb) - -ext4_itable_unused_count (sb, gdp)), - sbi->s_inodes_per_block); - -if ((used_blks <0 ) || (used_blks > sbi->s_itb_per_group) || - ((group ==0 ) && ((EXT4_INODES_PER_GROUP (sb) - -ext4_itable_unused_count (sb, gdp)) < -EXT4_FIRST_INO (sb)))) { -ext4_error (sb,"Something is wrong with group %u: " -"used itable blocks: %d; " -"itable unused count: %u" , - group, used_blks, -ext4_itable_unused_count (sb, gdp)); - ret =1 ; - goto err_out; +if (!(gdp->bg_flags &cpu_to_le16 (EXT4_BG_INODE_UNINIT ))) { + used_inos =EXT4_INODES_PER_GROUP (sb) - +ext4_itable_unused_count (sb, gdp); + used_blks =DIV_ROUND_UP (used_inos, sbi->s_inodes_per_block); + +/* Bogus inode unused count? */ +if (used_blks <0 || used_blks > sbi->s_itb_per_group) { +ext4_error (sb,"Something is wrong with group %u: " +"used itable blocks: %d; " +"itable unused count: %u" , + group, used_blks, +ext4_itable_unused_count (sb, gdp)); + ret =1 ; + goto err_out; + } + + used_inos += group *EXT4_INODES_PER_GROUP (sb); +/* +* Are there some uninitialized inodes in the inode table +* before the first normal inode? +*/ +if ((used_blks != sbi->s_itb_per_group) && + (used_inos <EXT4_FIRST_INO (sb))) { +ext4_error (sb,"Something is wrong with group %u: " +"itable unused count: %u; " +"itables initialized count: %ld" , + group,ext4_itable_unused_count (sb, gdp), + used_inos); + ret =1 ; + goto err_out; + } } blk =ext4_inode_table (sb, gdp) + used_blks;
Greg Kroah-Hartman
maintainerPATCH 267/299 ext4: do not set SB_ACTIVE in ext4_orphan_cleanup()
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
commit 72ffb49a7b623c92a37657eda7cc46a06d3e8398 upstream.
When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due to some error happens behind ext4_orphan_cleanup(), it will end up triggering a after free issue of super_block. The problem is that ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is enabled, after we cleanup the truncated inodes, the last iput() will put them into the lru list, and these inodes' pages may probably dirty and will be write back by the writeback thread, so it could be raced by freeing super_block in the error path of mount_bdev().
After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it was used to ensure updating the quota file properly, but evict inode and trash data immediately in the last iput does not affect the quotafile, so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by just remove the SB_ACTIVE setting.
[1] https://lore.kernel.org/linux-ext4/[email protected]/T/#m04990cfbc4f44592421736b504afcc346b2a7c00
--- fs/ext4/super.c | 3 --- 1 file changed, 3 deletions(-)
fs/ext4/super.c +0 -3
@@ -3039,9 +3039,6 @@ static void ext4_orphan_cleanup(struct s sb->s_flags &= ~SB_RDONLY ; }#ifdef CONFIG_QUOTA -/* Needed for iput() to work correctly and not trash data */ - sb->s_flags |=SB_ACTIVE ; -/* * Turn on quotas which were not enabled for read-only mounts if * filesystem has quota feature, so that they are updated correctly.
Greg Kroah-Hartman
maintainerPATCH 268/299 ext4: fix error code in ext4_commit_super
In reply to Greg Kroah-HartmanFrom: Fengnan Chang <[email protected]>
commit f88f1466e2a2e5ca17dfada436d3efa1b03a3972 upstream.
We should set the error code when ext4_commit_super check argument failed. Found in code review.
--- fs/ext4/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/super.c +4 -2
@@ -5489,8 +5489,10 @@ static int ext4_commit_super(struct supestruct buffer_head *sbh =EXT4_SB (sb)->s_sbh;int error =0 ; -if (!sbh ||block_device_ejected (sb)) -return error; +if (!sbh) +return -EINVAL ; +if (block_device_ejected (sb)) +return -ENODEV ;/* * If the file system is mounted read-only, don't update the
Greg Kroah-Hartman
maintainerPATCH 269/299 ext4: fix ext4_error_err save negative errno into superblock
In reply to Greg Kroah-HartmanFrom: Ye Bin <[email protected]>
commit 6810fad956df9e5467e8e8a5ac66fda0836c71fa upstream.
Fix As write_mmp_block() so that it returns -EIO instead of 1, so that the correct error gets saved into the superblock.
--- fs/ext4/mmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/mmp.c +1 -1
@@ -56,7 +56,7 @@ static int write_mmp_block(struct super_wait_on_buffer (bh);sb_end_write (sb);if (unlikely (!buffer_uptodate (bh))) -return 1 ; +return -EIO ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 270/299 ext4: fix error return code in ext4_fc_perform_commit()
In reply to Greg Kroah-HartmanFrom: Xu Yihang <[email protected]>
commit e1262cd2e68a0870fb9fc95eb202d22e8f0074b7 upstream.
In case of if not ext4_fc_add_tlv branch, an error return code is missing.
--- fs/ext4/fast_commit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/ext4/fast_commit.c +3 -1
@@ -1032,8 +1032,10 @@ static int ext4_fc_perform_commit(journa head.fc_tid =cpu_to_le32 ( sbi->s_journal->j_running_transaction->t_tid);if (!ext4_fc_add_tlv (sb,EXT4_FC_TAG_HEAD ,sizeof (head), - (u8 *)&head, &crc)) + (u8 *)&head, &crc)) { + ret = -ENOSPC ; goto out; + } }spin_lock (&sbi->s_fc_lock);
Greg Kroah-Hartman
maintainerPATCH 271/299 ext4: allow the dax flag to be set and cleared on inline directories
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 4811d9929cdae4238baf5b2522247bd2f9fa7b50 upstream.
This is needed to allow generic/607 to pass for file systems with the inline data_feature enabled, and it allows the use of file systems where the directories use inline_data, while the files are accessed via DAX.
--- fs/ext4/ialloc.c | 3 ++- fs/ext4/ioctl.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
fs/ext4/ialloc.c +2 -1
@@ -1291,7 +1291,8 @@ got: ei->i_extra_isize = sbi->s_want_extra_isize; ei->i_inline_off =0 ; -if (ext4_has_feature_inline_data (sb)) +if (ext4_has_feature_inline_data (sb) && + (!(ei->i_flags &EXT4_DAX_FL ) ||S_ISDIR (mode)))ext4_set_inode_state (inode,EXT4_STATE_MAY_INLINE_DATA ); ret = inode; err =dquot_alloc_inode (inode);
fs/ext4/ioctl.c +6 -0
@@ -312,6 +312,12 @@ static void ext4_dax_dontcache(struct in static bool dax_compatible(struct inode *inode, unsigned int oldflags, unsigned int flags) { + /* Allow the DAX flag to be changed on inline directories */ + if (S_ISDIR(inode->i_mode)) { + flags &= ~EXT4_INLINE_DATA_FL; + oldflags &= ~EXT4_INLINE_DATA_FL; + } + if (flags & EXT4_DAX_FL) { if ((oldflags & EXT4_DAX_MUT_EXCL) || ext4_test_inode_state(inode,
Greg Kroah-Hartman
maintainerPATCH 272/299 ext4: Fix occasional generic/418 failure
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 5899593f51e63dde2f07c67358bd65a641585abb upstream.
Eric has noticed that after pagecache read rework, generic/418 is occasionally failing for ext4 when blocksize < pagesize. In fact, the pagecache rework just made hard to hit race in ext4 more likely. The problem is that since ext4 conversion of direct IO writes to iomap framework (commit 378f32bab371), we update inode size after direct IO write only after invalidating page cache. Thus if buffered read sneaks at unfortunate moment like:
CPU1 - write at offset 1k CPU2 - read from offset 0
iomap_dio_rw(..., IOMAP_DIO_FORCE_WAIT);
ext4_readpage();ext4_handle_inode_extension()
the read will zero out tail of the page as it still sees smaller inode size and thus page cache becomes inconsistent with on-disk contents with all the consequences.
Fix the problem by moving inode size update into end_io handler which gets called before the page cache is invalidated.
--- fs/ext4/file.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
fs/ext4/file.c +21 -4
@@ -372,15 +372,32 @@ truncate:static int ext4_dio_write_end_io (struct kiocb *iocb,ssize_t size,int error,unsigned int flags) { -loff_t offset = iocb->ki_pos; +loff_t pos = iocb->ki_pos;struct inode *inode =file_inode (iocb->ki_filp);if (error)return error; -if (size && flags &IOMAP_DIO_UNWRITTEN ) -return ext4_convert_unwritten_extents (NULL , inode, - offset, size); +if (size && flags &IOMAP_DIO_UNWRITTEN ) { + error =ext4_convert_unwritten_extents (NULL , inode, pos, size); +if (error <0 ) +return error; + } +/* +* If we are extending the file, we have to update i_size here before +* page cache gets invalidated in iomap_dio_rw(). Otherwise racing +* buffered reads could zero out too much from page cache pages. Update +* of on-disk size will happen later in ext4_dio_write_iter() where +* we have enough information to also perform orphan list handling etc. +* Note that we perform all extending writes synchronously under +* i_rwsem held exclusively so i_size update is safe here in that case. +* If the write was not extending, we cannot see pos > i_size here +* because operations reducing i_size like truncate wait for all +* outstanding DIO before updating i_size. +*/ + pos += size; +if (pos >i_size_read (inode)) +i_size_write (inode, pos);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 273/299 media: dvbdev: Fix memory leak in dvb_media_device_free()
In reply to Greg Kroah-HartmanFrom: Peilin Ye <[email protected]>
commit bf9a40ae8d722f281a2721779595d6df1c33a0bf upstream.
dvb_media_device_free() is leaking memory. Free dvbdev->adapter->conn before setting it to NULL, as documented in include/media/media-device.h:
"The media_entity instance itself must be freed explicitly by the driver if required."
--- drivers/media/dvb-core/dvbdev.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/dvb-core/dvbdev.c +1 -0
@@ -241,6 +241,7 @@ static void dvb_media_device_free(structif (dvbdev->adapter->conn) {media_device_unregister_entity (dvbdev->adapter->conn); +kfree (dvbdev->adapter->conn); dvbdev->adapter->conn =NULL ;kfree (dvbdev->adapter->conn_pads); dvbdev->adapter->conn_pads =NULL ;
Greg Kroah-Hartman
maintainerPATCH 274/299 media: dvb-usb: Fix use-after-free access
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit c49206786ee252f28b7d4d155d1fff96f145a05d upstream.
dvb_usb_device_init() copies the properties to the own data, so that the callers can release the original properties later (as done in the commit 299c7007e936 ("media: dw2102: Fix memleak on sequence of probes")). However, it also stores dev->desc pointer that is a reference to the original properties data. Since dev->desc is referred later, it may result in use-after-free, in the worst case, leading to a kernel Oops as reported.
This patch addresses the problem by allocating and copying the properties at first, then get the desc from the copied properties.
--- drivers/media/usb/dvb-usb/dvb-usb-init.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
drivers/media/usb/dvb-usb/dvb-usb-init.c +13 -10
@@ -267,27 +267,30 @@ int dvb_usb_device_init(struct usb_interif (du !=NULL ) *du =NULL ; -if ((desc =dvb_usb_find_device (udev, props, &cold)) ==NULL ) { + d =kzalloc (sizeof (*d),GFP_KERNEL ); +if (!d) { +err ("no memory for 'struct dvb_usb_device'" ); +return -ENOMEM ; + } + +memcpy (&d->props, props,sizeof (struct dvb_usb_device_properties )); + + desc =dvb_usb_find_device (udev, &d->props, &cold); +if (!desc) {deb_err ("something went very wrong, device was not found in current device list - let's see what comes next.\n" ); -return -ENODEV ; + ret = -ENODEV ; + goto error; }if (cold) {info ("found a '%s' in cold state, will try to load a firmware" , desc->name); ret =dvb_usb_download_firmware (udev, props);if (!props->no_reconnect || ret !=0 ) -return ret; + goto error; }info ("found a '%s' in warm state." , desc->name); - d =kzalloc (sizeof (struct dvb_usb_device ),GFP_KERNEL ); -if (d ==NULL ) { -err ("no memory for 'struct dvb_usb_device'" ); -return -ENOMEM ; - } - d->udev = udev; -memcpy (&d->props, props,sizeof (struct dvb_usb_device_properties )); d->desc = desc; d->owner = owner;
Greg Kroah-Hartman
maintainerPATCH 275/299 media: dvb-usb: Fix memory leak at error in dvb_usb_device_init()
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 13a79f14ab285120bc4977e00a7c731e8143f548 upstream.
dvb_usb_device_init() allocates a dvb_usb_device object, but it doesn't release the object by itself even at errors. The object is released in the callee side (dvb_usb_init()) in some error cases via dvb_usb_exit() call, but it also missed the object free in other error paths. And, the caller (it's only dvb_usb_device_init()) doesn't seem caring the resource management as well, hence those memories are leaked.
This patch assures releasing the memory at the error path in dvb_usb_device_init(). Now dvb_usb_init() frees the resources it allocated but leaves the passed dvb_usb_device object intact. In turn, the dvb_usb_device object is released in dvb_usb_device_init() instead.
We could use dvb_usb_exit() function for releasing everything in the callee (as it was used for some error cases in the original code), but releasing the passed object in the callee is non-intuitive and error-prone. So I took this approach (which is more standard in Linus kernel code) although it ended with a bit more open codes.
Along with the change, the patch makes sure that USB intfdata is reset and don't return the bogus pointer to the caller of dvb_usb_device_init() at the error path, too.
--- drivers/media/usb/dvb-usb/dvb-usb-init.c | 47 ++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 16 deletions(-)
drivers/media/usb/dvb-usb/dvb-usb-init.c +31 -16
@@ -170,22 +170,20 @@ static int dvb_usb_init(struct dvb_usb_dif (d->props.priv_init !=NULL ) { ret = d->props.priv_init (d); -if (ret !=0 ) { -kfree (d->priv); - d->priv =NULL ; -return ret; - } +if (ret !=0 ) + goto err_priv_init; } }/* check the capabilities and set appropriate variables */ dvb_usb_device_power_ctrl (d,1 ); -if ((ret =dvb_usb_i2c_init (d)) || - (ret =dvb_usb_adapter_init (d, adapter_nums))) { -dvb_usb_exit (d); -return ret; - } + ret =dvb_usb_i2c_init (d); +if (ret) + goto err_i2c_init; + ret =dvb_usb_adapter_init (d, adapter_nums); +if (ret) + goto err_adapter_init;if ((ret =dvb_usb_remote_init (d)))err ("could not initialize remote control." );
@@ -193,6 +191,17 @@ static int dvb_usb_init(struct dvb_usb_ddvb_usb_device_power_ctrl (d,0 );return 0 ; + +err_adapter_init: +dvb_usb_adapter_exit (d); +err_i2c_init: +dvb_usb_i2c_exit (d); +if (d->priv && d->props.priv_destroy) + d->props.priv_destroy (d); +err_priv_init: +kfree (d->priv); + d->priv =NULL ; +return ret; }/* determine the name and the state of the just found USB device */
@@ -296,15 +305,21 @@ int dvb_usb_device_init(struct usb_interusb_set_intfdata (intf, d); -if (du !=NULL ) + ret =dvb_usb_init (d, adapter_nums); +if (ret) { +info ("%s error while loading driver (%d)" , desc->name, ret); + goto error; + } + +if (du) *du = d; - ret =dvb_usb_init (d, adapter_nums); +info ("%s successfully initialized and connected." , desc->name); +return 0 ; -if (ret ==0 ) -info ("%s successfully initialized and connected." , desc->name); -else -info ("%s error while loading driver (%d)" , desc->name, ret); + error: +usb_set_intfdata (intf,NULL ); +kfree (d);return ret; }EXPORT_SYMBOL (dvb_usb_device_init);
Greg Kroah-Hartman
maintainerPATCH 276/299 media: staging/intel-ipu3: Fix memory leak in imu_fmt
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit 3630901933afba1d16c462b04d569b7576339223 upstream.
We are losing the reference to an allocated memory if try. Change the order of the check to avoid that.
--- drivers/staging/media/ipu3/ipu3-v4l2.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/staging/media/ipu3/ipu3-v4l2.c +7 -4
@@ -693,6 +693,13 @@ static int imgu_fmt(struct imgu_device *if (inode ==IMGU_NODE_STAT_3A || inode ==IMGU_NODE_PARAMS )continue ; +/* CSS expects some format on OUT queue */ +if (i !=IPU3_CSS_QUEUE_OUT && + !imgu_pipe->nodes[inode].enabled) { + fmts[i] =NULL ; +continue ; + } +if (try) { fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, sizeof(struct v4l2_pix_format_mplane),
@@ -705,10 +712,6 @@ static int imgu_fmt(struct imgu_device * fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; } -/* CSS expects some format on OUT queue */ -if (i !=IPU3_CSS_QUEUE_OUT && - !imgu_pipe->nodes[inode].enabled) - fmts[i] =NULL ; }if (!try) {
Greg Kroah-Hartman
maintainerPATCH 277/299 media: staging/intel-ipu3: Fix set_fmt error handling
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit ad91849996f9dd79741a961fd03585a683b08356 upstream.
If there in an error during a set_fmt, do not overwrite the previous sizes with the invalid config.
Without this patch, v4l2-compliance ends up allocating 4GiB of RAM and causing the following OOPs
[ 38.662975] ipu3-imgu 0000:00:05.0: swiotlb buffer is full (sz: 4096 bytes) [ 38.662980] DMA: Out of SW-IOMMU space for 4096 bytes at device 0000:00:05.0 [ 38.663010] general protection fault: 0000 [#1] PREEMPT SMP
--- drivers/staging/media/ipu3/ipu3-v4l2.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/staging/media/ipu3/ipu3-v4l2.c +5 -0
@@ -669,6 +669,7 @@ static int imgu_fmt(struct imgu_device *struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe];struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; +struct v4l2_pix_format_mplane fmt_backup;dev_dbg (dev,"set fmt node [%u][%u](try = %u)" , pipe, node, try);
@@ -737,6 +738,7 @@ static int imgu_fmt(struct imgu_device * ret = -EINVAL ; goto out; } + fmt_backup = *fmts[css_q]; *fmts[css_q] = f->fmt.pix_mp;if (try)
@@ -744,6 +746,9 @@ static int imgu_fmt(struct imgu_device *else ret =imgu_css_fmt_set (&imgu->css, fmts, rects, pipe); +if (try || ret <0 ) + *fmts[css_q] = fmt_backup; +/* ret is the binary number in the firmware blob */ if (ret <0 ) goto out;
Greg Kroah-Hartman
maintainerPATCH 278/299 media: staging/intel-ipu3: Fix race condition during set_fmt
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit dccfe2548746ca9cca3a20401ece4cf255d1f171 upstream.
Do not modify imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, until the format has been correctly validated.
Otherwise, even if we use a backup variable, there is a period of time where imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp might have an invalid value that can be used by other functions.
--- drivers/staging/media/ipu3/ipu3-v4l2.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-)
drivers/staging/media/ipu3/ipu3-v4l2.c +14 -16
@@ -669,7 +669,6 @@ static int imgu_fmt(struct imgu_device *struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe];struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; -struct v4l2_pix_format_mplane fmt_backup;dev_dbg (dev,"set fmt node [%u][%u](try = %u)" , pipe, node, try);
@@ -687,6 +686,7 @@ static int imgu_fmt(struct imgu_device *dev_dbg (dev,"IPU3 pipe %u pipe_id = %u" , pipe, css_pipe->pipe_id); + css_q =imgu_node_to_queue (node);for (i =0 ; i <IPU3_CSS_QUEUES ; i++) {unsigned int inode =imgu_map_node (imgu, i);
@@ -701,6 +701,11 @@ static int imgu_fmt(struct imgu_device *continue ; } +if (i == css_q) { + fmts[i] = &f->fmt.pix_mp; +continue ; + } +if (try) { fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, sizeof(struct v4l2_pix_format_mplane),
@@ -729,39 +734,32 @@ static int imgu_fmt(struct imgu_device * rects[IPU3_CSS_RECT_GDC ]->height = pad_fmt.height; } -/* -* imgu doesn't set the node to the value given by user -* before we return success from this function, so set it here. -*/ - css_q =imgu_node_to_queue (node);if (!fmts[css_q]) { ret = -EINVAL ; goto out; } - fmt_backup = *fmts[css_q]; - *fmts[css_q] = f->fmt.pix_mp;if (try) ret =imgu_css_fmt_try (&imgu->css, fmts, rects, pipe);else ret =imgu_css_fmt_set (&imgu->css, fmts, rects, pipe); -if (try || ret <0 ) - *fmts[css_q] = fmt_backup; -/* ret is the binary number in the firmware blob */ if (ret <0 ) goto out; -if (try) - f->fmt.pix_mp = *fmts[css_q]; -else - f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; +/* +* imgu doesn't set the node to the value given by user +* before we return success from this function, so set it here. +*/ +if (!try) + imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp = f->fmt.pix_mp; out:if (try) {for (i =0 ; i <IPU3_CSS_QUEUES ; i++) -kfree (fmts[i]); +if (i != css_q) +kfree (fmts[i]); }return ret;
Greg Kroah-Hartman
maintainerPATCH 279/299 media: v4l2-ctrls: fix reference to freed memory
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
commit ac34b79da14d67a9b494f6125186becbd067e225 upstream.
When controls are used together with the Request API, then for each request a v4l2_ctrl_handler struct is allocated. This contains the controls that can be set in a request. If a control is *not* set in the request, then the value used in the most recent previous request must be used, or the current value if it is not found in any outstanding requests.
The framework tried to find such a previous request and it would set the 'req' pointer in struct v4l2_ctrl_ref to the v4l2_ctrl_ref of the control in such a previous request. So far, so good. However, when that previous request was applied to the hardware, returned to userspace, and then userspace would re-init or free that request, any 'ref' pointer in still-queued requests would suddenly point to freed memory.
This was not noticed before since the drivers that use this expected that each request would always have the controls set, so there was never any need to find a control in older requests. This requirement was relaxed, and now this bug surfaced.
It was also made worse by changeset2fae4d6aabc8 ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req") which increased the chance of this happening.
The use of the 'req' pointer in v4l2_ctrl_ref was very fragile, so drop this entirely. Instead add a valid_p_req bool to indicate that p_req contains a valid value for this control. And if it is false, then just use the current value of the control.
Note that VIDIOC_G_EXT_CTRLS will always return -EACCES when attempting to get a control from a request until the request is completed. And in that case, all controls in the request will have the control value set (i.e. valid_p_req is true). This means that the whole 'find the most recent previous request containing a control' idea is pointless, and the code can be simplified considerably.
The v4l2_g_ext_ctrls_common() function was refactored a bit to make it more understandable. It also avoids updating volatile controls in a completed request since that was already done when the request was completed.
--- drivers/media/v4l2-core/v4l2-ctrls.c | 137 ++++++++++++++++------------------- include/media/v4l2-ctrls.h | 12 +-- 2 files changed, 70 insertions(+), 79 deletions(-)
drivers/media/v4l2-core/v4l2-ctrls.c +63 -74
@@ -2201,7 +2201,16 @@ static void new_to_req(struct v4l2_ctrl_if (!ref)return ;ptr_to_ptr (ref->ctrl, ref->ctrl->p_new, ref->p_req); - ref->req = ref; + ref->valid_p_req = true; +} + +/* Copy the current value to the request value */ +static void cur_to_req (struct v4l2_ctrl_ref *ref) +{ +if (!ref) +return ; +ptr_to_ptr (ref->ctrl, ref->ctrl->p_cur, ref->p_req); + ref->valid_p_req = true; }/* Copy the request value to the new value */
@@ -2209,8 +2218,8 @@ static void req_to_new(struct v4l2_ctrl_ {if (!ref)return ; -if (ref->req) -ptr_to_ptr (ref->ctrl, ref->req->p_req, ref->ctrl->p_new); +if (ref->valid_p_req) +ptr_to_ptr (ref->ctrl, ref->p_req, ref->ctrl->p_new);else ptr_to_ptr (ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); }
@@ -3380,39 +3389,8 @@ static void v4l2_ctrl_request_queue(strustruct v4l2_ctrl_handler *hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);struct v4l2_ctrl_handler *main_hdl = obj->priv; -struct v4l2_ctrl_handler *prev_hdl =NULL ; -struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev =NULL ;mutex_lock (main_hdl->lock); -if (list_empty (&main_hdl->requests_queued)) - goto queue; - - prev_hdl =list_last_entry (&main_hdl->requests_queued, - struct v4l2_ctrl_handler, requests_queued); -/* -* Note: prev_hdl and hdl must contain the same list of control -* references, so if any differences are detected then that is a -* driver bug and the WARN_ON is triggered. -*/ -mutex_lock (prev_hdl->lock); - ref_ctrl_prev =list_first_entry (&prev_hdl->ctrl_refs, - struct v4l2_ctrl_ref, node); -list_for_each_entry (ref_ctrl, &hdl->ctrl_refs, node) { -if (ref_ctrl->req) -continue ; -while (ref_ctrl_prev->ctrl->id < ref_ctrl->ctrl->id) { -/* Should never happen, but just in case... */ -if (list_is_last (&ref_ctrl_prev->node, - &prev_hdl->ctrl_refs)) -break ; - ref_ctrl_prev =list_next_entry (ref_ctrl_prev, node); - } -if (WARN_ON (ref_ctrl_prev->ctrl->id != ref_ctrl->ctrl->id)) -break ; - ref_ctrl->req = ref_ctrl_prev->req; - } -mutex_unlock (prev_hdl->lock); -queue:list_add_tail (&hdl->requests_queued, &main_hdl->requests_queued); hdl->request_is_queued = true;mutex_unlock (main_hdl->lock);
@@ -3469,7 +3447,7 @@ v4l2_ctrl_request_hdl_ctrl_find(struct v {struct v4l2_ctrl_ref *ref =find_ref_lock (hdl, id); -return (ref && ref->req == ref) ? ref->ctrl :NULL ; +return (ref && ref->valid_p_req) ? ref->ctrl :NULL ; }EXPORT_SYMBOL_GPL (v4l2_ctrl_request_hdl_ctrl_find);
@@ -3655,7 +3633,13 @@ static int class_check(struct v4l2_ctrl_return find_ref_lock (hdl, which |1 ) ?0 : -EINVAL ; } -/* Get extended controls. Allocates the helpers array if needed. */ +/* +* Get extended controls. Allocates the helpers array if needed. +* +* Note that v4l2_g_ext_ctrls_common() with 'which' set to +* V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was +* completed, and in that case valid_p_req is true for all controls. +*/ static int v4l2_g_ext_ctrls_common (struct v4l2_ctrl_handler *hdl,struct v4l2_ext_controls *cs,struct video_device *vdev)
@@ -3664,9 +3648,10 @@ static int v4l2_g_ext_ctrls_common(strucstruct v4l2_ctrl_helper *helpers = helper;int ret;int i, j; -bool def_value; +bool is_default, is_request; - def_value = (cs->which ==V4L2_CTRL_WHICH_DEF_VAL ); + is_default = (cs->which ==V4L2_CTRL_WHICH_DEF_VAL ); + is_request = (cs->which ==V4L2_CTRL_WHICH_REQUEST_VAL ); cs->error_idx = cs->count; cs->which =V4L2_CTRL_ID2WHICH (cs->which);
@@ -3692,11 +3677,9 @@ static int v4l2_g_ext_ctrls_common(struc ret = -EACCES ;for (i =0 ; !ret && i < cs->count; i++) { -int (*ctrl_to_user)(struct v4l2_ext_control *c, -struct v4l2_ctrl *ctrl);struct v4l2_ctrl *master; - - ctrl_to_user = def_value ? def_to_user : cur_to_user; +bool is_volatile = false; +u32 idx = i;if (helpers[i].mref ==NULL )continue ;
@@ -3706,31 +3689,48 @@ static int v4l2_g_ext_ctrls_common(strucv4l2_ctrl_lock (master); -/* g_volatile_ctrl will update the new control values */ -if (!def_value && +/* +* g_volatile_ctrl will update the new control values. +* This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and +* V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests +* it is v4l2_ctrl_request_complete() that copies the +* volatile controls at the time of request completion +* to the request, so you don't want to do that again. +*/ +if (!is_default && !is_request && ((master->flags &V4L2_CTRL_FLAG_VOLATILE ) || (master->has_volatiles && !is_cur_manual (master)))) {for (j =0 ; j < master->ncontrols; j++)cur_to_new (master->cluster[j]); ret =call_op (master, g_volatile_ctrl); - ctrl_to_user = new_to_user; + is_volatile = true; } -/* If OK, then copy the current (for non-volatile controls) -or the new (for volatile controls) control values to the -caller */ -if (!ret) { -u32 idx = i; -do { -if (helpers[idx].ref->req) - ret =req_to_user (cs->controls + idx, - helpers[idx].ref->req); -else - ret =ctrl_to_user (cs->controls + idx, - helpers[idx].ref->ctrl); - idx = helpers[idx].next; - }while (!ret && idx); +if (ret) { +v4l2_ctrl_unlock (master); +break ; } + +/* +* Copy the default value (if is_default is true), the +* request value (if is_request is true and p_req is valid), +* the new volatile value (if is_volatile is true) or the +* current value. +*/ +do { +struct v4l2_ctrl_ref *ref = helpers[idx].ref; + +if (is_default) + ret =def_to_user (cs->controls + idx, ref->ctrl); +else if (is_request && ref->valid_p_req) + ret =req_to_user (cs->controls + idx, ref); +else if (is_volatile) + ret =new_to_user (cs->controls + idx, ref->ctrl); +else + ret =cur_to_user (cs->controls + idx, ref->ctrl); + idx = helpers[idx].next; + }while (!ret && idx); +v4l2_ctrl_unlock (master); }
@@ -4368,8 +4368,6 @@ void v4l2_ctrl_request_complete(struct munsigned int i;if (ctrl->flags &V4L2_CTRL_FLAG_VOLATILE ) { - ref->req = ref; -v4l2_ctrl_lock (master);/* g_volatile_ctrl will update the current control values */ for (i =0 ; i < master->ncontrols; i++)
@@ -4379,21 +4377,12 @@ void v4l2_ctrl_request_complete(struct mv4l2_ctrl_unlock (master);continue ; } -if (ref->req == ref) +if (ref->valid_p_req)continue ; +/* Copy the current control value into the request */ v4l2_ctrl_lock (ctrl); -if (ref->req) { -ptr_to_ptr (ctrl, ref->req->p_req, ref->p_req); - }else { -ptr_to_ptr (ctrl, ctrl->p_cur, ref->p_req); -/* -* Set ref->req to ensure that when userspace wants to -* obtain the controls of this request it will take -* this value and not the current value of the control. -*/ - ref->req = ref; - } +cur_to_req (ref);v4l2_ctrl_unlock (ctrl); }
@@ -4458,7 +4447,7 @@ int v4l2_ctrl_request_setup(struct mediastruct v4l2_ctrl_ref *r =find_ref (hdl, master->cluster[i]->id); -if (r->req && r == r->req) { +if (r->valid_p_req) { have_new_data = true;break ; }
include/media/v4l2-ctrls.h +7 -5
@@ -303,12 +303,14 @@ struct v4l2_ctrl {* the control has been applied. This prevents applying controls * from a cluster with multiple controls twice (when the first * control of a cluster is applied, they all are). -* @req: If set, this refers to another request that sets this control. +* @valid_p_req: If set, then p_req contains the control value for the request. * @p_req: If the control handler containing this control reference * is bound to a media request, then this points to the -* value of the control that should be applied when the request +* value of the control that must be applied when the request * is executed, or to the value of the control at the time -* that the request was completed. +* that the request was completed. If @valid_p_req is false, +* then this control was never set for this request and the +* control will not be updated when this request is applied. * * Each control handler has a list of these refs. The list_head is used to * keep a sorted-by-control-ID list of all controls, while the next pointer
@@ -321,7 +323,7 @@ struct v4l2_ctrl_ref {struct v4l2_ctrl_helper *helper;bool from_other_dev;bool req_done; -struct v4l2_ctrl_ref *req; +bool valid_p_req;union v4l2_ctrl_ptr p_req; };
@@ -348,7 +350,7 @@ struct v4l2_ctrl_ref {* @error: The error code of the first failed control addition. * @request_is_queued: True if the request was queued. * @requests: List to keep track of open control handler request objects. -* For the parent control handler (@req_obj.req == NULL) this +* For the parent control handler (@req_obj.ops == NULL) this * is the list header. When the parent control handler is * removed, it has to unbind and put all these requests since * they refer to the parent.
Greg Kroah-Hartman
maintainerPATCH 280/299 media: venus: hfi_parser: Dont initialize parser on v1
In reply to Greg Kroah-HartmanFrom: Stanimir Varbanov <[email protected]>
commit 834124c596e2dddbbdba06620835710ccca32fd0 upstream.
The Venus v1 behaves differently comparing with the other Venus version in respect to capability parsing and when they are send to the driver. So we don't need to initialize hfi parser for multiple invocations like what we do for > v1 Venus versions.
--- drivers/media/platform/qcom/venus/hfi_parser.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/media/platform/qcom/venus/hfi_parser.c +4 -2
@@ -239,8 +239,10 @@ u32 hfi_parser(struct venus_core *core,parser_init (inst, &codecs, &domain); - core->codecs_count =0 ; -memset (core->caps,0 ,sizeof (core->caps)); +if (core->res->hfi_version >HFI_VERSION_1XX ) { + core->codecs_count =0 ; +memset (core->caps,0 ,sizeof (core->caps)); + }while (words_count) { data = word +1 ;
Greg Kroah-Hartman
maintainerPATCH 281/299 usb: gadget: dummy_hcd: fix gpf in gadget_setup
In reply to Greg Kroah-HartmanFrom: Anirudh Rayabharam <[email protected]>
commit 4a5d797a9f9c4f18585544237216d7812686a71f upstream.
Fix a general protection fault reported by syzbot due to a race between gadget_setup() and gadget_unbind() in raw_gadget.
The gadget core is supposed to guarantee that there won't be any more callbacks to the gadget driver once the driver's unbind routine is called. That guarantee is enforced in usb_gadget_remove_driver as follows:
usb_gadget_disconnect(udc->gadget);
if (udc->gadget->irq)
synchronize_irq(udc->gadget->irq);
udc->driver->unbind(udc->gadget);
usb_gadget_udc_stop(udc);usb_gadget_disconnect turns off the pullup resistor, telling the host that the gadget is no longer connected and preventing the transmission of any more USB packets. Any packets that have already been received are sure to processed by the UDC driver's interrupt handler by the time synchronize_irq returns.
But this doesn't work with dummy_hcd, because dummy_hcd doesn't use interrupts; it uses a timer instead. It does have code to emulate the effect of synchronize_irq, but that code doesn't get invoked at the right time -- it currently runs in usb_gadget_udc_stop, after the unbind callback instead of before. Indeed, there's no way for usb_gadget_remove_driver to invoke this code before the unbind callback.
To fix this, move the synchronize_irq() emulation code to dummy_pullup so that it runs before unbind. Also, add a comment explaining why it is necessary to have it there.
--- drivers/usb/gadget/udc/dummy_hcd.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
drivers/usb/gadget/udc/dummy_hcd.c +15 -8
@@ -901,6 +901,21 @@ static int dummy_pullup(struct usb_gadgespin_lock_irqsave (&dum->lock, flags); dum->pullup = (value !=0 );set_link_state (dum_hcd); +if (value ==0 ) { +/* +* Emulate synchronize_irq(): wait for callbacks to finish. +* This seems to be the best place to emulate the call to +* synchronize_irq() that's in usb_gadget_remove_driver(). +* Doing it in dummy_udc_stop() would be too late since it +* is called after the unbind callback and unbind shouldn't +* be invoked until all the other callbacks are finished. +*/ +while (dum->callback_usage >0 ) { +spin_unlock_irqrestore (&dum->lock, flags); +usleep_range (1000 ,2000 ); +spin_lock_irqsave (&dum->lock, flags); + } + }spin_unlock_irqrestore (&dum->lock, flags);usb_hcd_poll_rh_status (dummy_hcd_to_hcd (dum_hcd));
@@ -1002,14 +1017,6 @@ static int dummy_udc_stop(struct usb_gadspin_lock_irq (&dum->lock); dum->ints_enabled =0 ;stop_activity (dum); - -/* emulate synchronize_irq(): wait for callbacks to finish */ -while (dum->callback_usage >0 ) { -spin_unlock_irq (&dum->lock); -usleep_range (1000 ,2000 ); -spin_lock_irq (&dum->lock); - } - dum->driver =NULL ;spin_unlock_irq (&dum->lock);
Greg Kroah-Hartman
maintainerPATCH 282/299 usb: gadget: Fix double free of device descriptor pointers
In reply to Greg Kroah-HartmanFrom: Hemant Kumar <[email protected]>
commit 43c4cab006f55b6ca549dd1214e22f5965a8675f upstream.
Upon driver unbind usb_free_all_descriptors() function frees all speed descriptor pointers without setting them to NULL. In case gadget speed changes (i.e from super speed plus to super speed) after driver unbind only upto super speed descriptor pointers get populated. Super speed plus desc still holds the stale (already freed) pointer. Fix this issue by setting all descriptor pointers to NULL after freeing them in usb_free_all_descriptors().
--- drivers/usb/gadget/config.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/gadget/config.c +4 -0
@@ -194,9 +194,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptorsvoid usb_free_all_descriptors (struct usb_function *f) {usb_free_descriptors (f->fs_descriptors); + f->fs_descriptors =NULL ;usb_free_descriptors (f->hs_descriptors); + f->hs_descriptors =NULL ;usb_free_descriptors (f->ss_descriptors); + f->ss_descriptors =NULL ;usb_free_descriptors (f->ssp_descriptors); + f->ssp_descriptors =NULL ; }EXPORT_SYMBOL_GPL (usb_free_all_descriptors);
Greg Kroah-Hartman
maintainerPATCH 283/299 usb: gadget/function/f_fs string table fix for multiple languages
In reply to Greg Kroah-HartmanFrom: Dean Anderson <[email protected]>
commit 55b74ce7d2ce0b0058f3e08cab185a0afacfe39e upstream.
Fixes bug with the handling of more than one language in the string table in f_fs.c.str_count was not reset for subsequent language codes. str_count-- "rolls under" and processes u32 max strings on the processing of the second language entry.
The existing bug can be reproduced by adding a second language table to the structure "strings" in tools/usb/ffs-test.c.
--- drivers/usb/gadget/function/f_fs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/gadget/function/f_fs.c +2 -1
@@ -2639,6 +2639,7 @@ static int __ffs_data_got_strings(struct do { /* lang_count > 0 so we can use do-while */ unsigned needed = needed_count; + u32 str_per_lang = str_count; if (unlikely(len < 3)) goto error_free;
@@ -2674,7 +2675,7 @@ static int __ffs_data_got_strings(struct data += length +1 ; len -= length +1 ; - }while (--str_count); + }while (--str_per_lang); s->id =0 ;/* terminator */ s->s =NULL ;
Greg Kroah-Hartman
maintainerPATCH 284/299 usb: dwc3: gadget: Remove FS bInterval_m1 limitation
In reply to Greg Kroah-HartmanFrom: Thinh Nguyen <[email protected]>
commit 3232a3ce55edfc0d7f8904543b4088a5339c2b2b upstream.
The programming guide incorrectly stated that the DCFG.bInterval_m1 must be set to 0 when operating in fullspeed. There's no such limitation for all IPs. See DWC_usb3x programming guide section 3.2.2.1.
--- drivers/usb/dwc3/gadget.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/dwc3/gadget.c +6 -4
@@ -608,12 +608,14 @@ static int dwc3_gadget_set_ep_config(stru8 bInterval_m1;/* -* Valid range for DEPCFG.bInterval_m1 is from 0 to 13, and it -* must be set to 0 when the controller operates in full-speed. +* Valid range for DEPCFG.bInterval_m1 is from 0 to 13. +* +* NOTE: The programming guide incorrectly stated bInterval_m1 +* must be set to 0 when operating in fullspeed. Internally the +* controller does not have this limitation. See DWC_usb3x +* programming guide section 3.2.2.1. */ bInterval_m1 =min_t (u8, desc->bInterval -1 ,13 ); -if (dwc->gadget->speed ==USB_SPEED_FULL ) - bInterval_m1 =0 ;if (usb_endpoint_type (desc) ==USB_ENDPOINT_XFER_INT && dwc->gadget->speed ==USB_SPEED_FULL )
Greg Kroah-Hartman
maintainerPATCH 285/299 usb: dwc3: gadget: Fix START_TRANSFER link state check
In reply to Greg Kroah-HartmanFrom: Thinh Nguyen <[email protected]>
commit c560e76319a94a3b9285bc426c609903408e4826 upstream.
The START_TRANSFER command needs to be executed while in ON/U0 link state (with an exception during register initialization). Don't use dwc->link_state to check this since the driver only tracks the link state when the link state change interrupt is enabled. Check the link state from DSTS register instead.
Note that often the host already brings the device out of low power before it sends/requests the next transfer. So, the user won't see any issue when the device starts transfer then. This issue is more noticeable in cases when the device delays starting transfer, which can happen during delayed control status after the host put the device in low power.
--- drivers/usb/dwc3/gadget.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/usb/dwc3/gadget.c +7 -6
@@ -308,13 +308,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ }if (DWC3_DEPCMD_CMD (cmd) ==DWC3_DEPCMD_STARTTRANSFER ) { -int needs_wakeup; +int link_state; - needs_wakeup = (dwc->link_state ==DWC3_LINK_STATE_U1 || - dwc->link_state ==DWC3_LINK_STATE_U2 || - dwc->link_state ==DWC3_LINK_STATE_U3 ); - -if (unlikely (needs_wakeup)) { + link_state =dwc3_gadget_get_link_state (dwc); +if (link_state ==DWC3_LINK_STATE_U1 || + link_state ==DWC3_LINK_STATE_U2 || + link_state ==DWC3_LINK_STATE_U3 ) { ret =__dwc3_gadget_wakeup (dwc);dev_WARN_ONCE (dwc->dev, ret,"wakeup failed --> %d\n" , ret);
@@ -1975,6 +1974,8 @@ static int __dwc3_gadget_wakeup(struct dcase DWC3_LINK_STATE_RESET :case DWC3_LINK_STATE_RX_DET :/* in HS, means Early Suspend */ case DWC3_LINK_STATE_U3 :/* in HS, means SUSPEND */ +case DWC3_LINK_STATE_U2 :/* in HS, means Sleep (L1) */ +case DWC3_LINK_STATE_U1 :case DWC3_LINK_STATE_RESUME :break ;default :
Greg Kroah-Hartman
maintainerPATCH 286/299 usb: dwc3: core: Do core softreset when switch mode
In reply to Greg Kroah-HartmanFrom: Yu Chen <[email protected]>
commit f88359e1588b85cf0e8209ab7d6620085f3441d9 upstream.
From: John Stultz <[email protected]>
According to the programming guide, to switch mode for DRD controller, the driver needs to do the following.
To switch from device to host:
1. Reset controller with GCTL.CoreSoftReset
2. Set GCTL.PrtCapDir(host mode)
3. Reset the host with USBCMD.HCRESET
4. Then follow up with the initializing host registers sequence
To switch from host to device:
1. Reset controller with GCTL.CoreSoftReset
2. Set GCTL.PrtCapDir(device mode)
3. Reset the device with DCTL.CSftRst
4. Then follow up with the initializing registers sequence
Currently we're missing step 1) to do GCTL.CoreSoftReset and step 3) of switching from host to device. John Stult reported a lockup issue seen with HiKey960 platform without these steps[1]. Similar issue is observed with Ferry's testing platform[2].
So, apply the required steps along with some fixes to Yu Chen's and John Stultz's version. The main fixes to their versions are the missing wait for clocks synchronization before clearing GCTL.CoreSoftReset and only apply DCTL.CSftRst when switching from host to device.
[1] https://lore.kernel.org/linux-usb/[email protected]/
[2] https://lore.kernel.org/linux-usb/[email protected]/
--- drivers/usb/dwc3/core.c | 27 +++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 5 +++++ 2 files changed, 32 insertions(+)
drivers/usb/dwc3/core.c +27 -0
@@ -114,6 +114,8 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u dwc->current_dr_role = mode; } +static int dwc3_core_soft_reset (struct dwc3 *dwc); +static void __dwc3_set_mode (struct work_struct *work) {struct dwc3 *dwc =work_to_dwc (work);
@@ -121,6 +123,8 @@ static void __dwc3_set_mode(struct work_int ret;u32 reg; +mutex_lock (&dwc->mutex); +pm_runtime_get_sync (dwc->dev);if (dwc->current_dr_role ==DWC3_GCTL_PRTCAP_OTG )
@@ -154,6 +158,25 @@ static void __dwc3_set_mode(struct work_break ; } +/* For DRD host or device mode only */ +if (dwc->desired_dr_role !=DWC3_GCTL_PRTCAP_OTG ) { + reg =dwc3_readl (dwc->regs,DWC3_GCTL ); + reg |=DWC3_GCTL_CORESOFTRESET ; +dwc3_writel (dwc->regs,DWC3_GCTL , reg); + +/* +* Wait for internal clocks to synchronized. DWC_usb31 and +* DWC_usb32 may need at least 50ms (less for DWC_usb3). To +* keep it consistent across different IPs, let's wait up to +* 100ms before clearing GCTL.CORESOFTRESET. +*/ +msleep (100 ); + + reg =dwc3_readl (dwc->regs,DWC3_GCTL ); + reg &= ~DWC3_GCTL_CORESOFTRESET ; +dwc3_writel (dwc->regs,DWC3_GCTL , reg); + } +spin_lock_irqsave (&dwc->lock, flags);dwc3_set_prtcap (dwc, dwc->desired_dr_role);
@@ -178,6 +201,8 @@ static void __dwc3_set_mode(struct work_ }break ;case DWC3_GCTL_PRTCAP_DEVICE : +dwc3_core_soft_reset (dwc); +dwc3_event_buffers_setup (dwc);if (dwc->usb2_phy)
@@ -200,6 +225,7 @@ static void __dwc3_set_mode(struct work_ out:pm_runtime_mark_last_busy (dwc->dev);pm_runtime_put_autosuspend (dwc->dev); +mutex_unlock (&dwc->mutex); }void dwc3_set_mode (struct dwc3 *dwc,u32 mode)
@@ -1529,6 +1555,7 @@ static int dwc3_probe(struct platform_dedwc3_cache_hwparams (dwc);spin_lock_init (&dwc->lock); +mutex_init (&dwc->mutex);pm_runtime_set_active (dev);pm_runtime_use_autosuspend (dev);
drivers/usb/dwc3/core.h +5 -0
@@ -13,6 +13,7 @@#include <linux/device.h> #include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/ioport.h> #include <linux/list.h> #include <linux/bitops.h>
@@ -942,6 +943,7 @@ struct dwc3_scratchpad_array {* @scratch_addr: dma address of scratchbuf * @ep0_in_setup: one control transfer is completed and enter setup phase * @lock: for synchronizing +* @mutex: for mode switching * @dev: pointer to our struct device * @sysdev: pointer to the DMA-capable device * @xhci: pointer to our xHCI child
@@ -1078,6 +1080,9 @@ struct dwc3 {/* device lock */ spinlock_t lock; +/* mode switching lock */ +struct mutex mutex; +struct device *dev;struct device *sysdev;
Greg Kroah-Hartman
maintainerPATCH 287/299 usb: dwc2: Fix session request interrupt handler
In reply to Greg Kroah-HartmanFrom: Artur Petrosyan <[email protected]>
commit 42b32b164acecd850edef010915a02418345a033 upstream.
According to programming guide in host mode, port
power must be turned on in session request
interrupt handlers.
--- drivers/usb/dwc2/core_intr.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/usb/dwc2/core_intr.c +8 -0
@@ -307,6 +307,7 @@ static void dwc2_handle_conn_id_status_cstatic void dwc2_handle_session_req_intr (struct dwc2_hsotg *hsotg) {int ret; +u32 hprt0;/* Clear interrupt */ dwc2_writel (hsotg,GINTSTS_SESSREQINT ,GINTSTS );
@@ -327,6 +328,13 @@ static void dwc2_handle_session_req_intr* established */ dwc2_hsotg_disconnect (hsotg); + }else { +/* Turn on the port power bit. */ + hprt0 =dwc2_read_hprt0 (hsotg); + hprt0 |=HPRT0_PWR ; +dwc2_writel (hsotg, hprt0,HPRT0 ); +/* Connect hcd after port power is set. */ +dwc2_hcd_connect (hsotg); } }
Greg Kroah-Hartman
maintainerPATCH 288/299 tty: fix memory leak in vc_deallocate
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
commit 211b4d42b70f1c1660feaa968dac0efc2a96ac4d upstream.
syzbot reported memory leak in tty/vt.
The problem was in VT_DISALLOCATE ioctl cmd. After allocating unimap with PIO_UNIMAP it wasn't freed via VT_DISALLOCATE, but vc_cons[currcons].d was zeroed.
--- drivers/tty/vt/vt.c | 1 + 1 file changed, 1 insertion(+)
drivers/tty/vt/vt.c +1 -0
@@ -1382,6 +1382,7 @@ struct vc_data *vc_deallocate(unsigned iatomic_notifier_call_chain (&vt_notifier_list,VT_DEALLOCATE , ¶m);vcs_remove_sysfs (currcons);visual_deinit (vc); +con_free_unimap (vc);put_pid (vc->vt_pid);vc_uniscr_set (vc,NULL );kfree (vc->vc_screenbuf);
Greg Kroah-Hartman
maintainerPATCH 289/299 rsi: Use resume_noirq for SDIO
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
commit c434e5e48dc4e626364491455f97e2db0aa137b1 upstream.
The rsi_resume() does access the bus to enable interrupts on the RSI SDIO WiFi card, however when calling sdio_claim_host() in the resume path, it is possible the bus is already claimed and sdio_claim_host() spins indefinitelly. Enable the SDIO card interrupts in resume_noirq instead to prevent anything else from claiming the SDIO bus first.
--- drivers/net/wireless/rsi/rsi_91x_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/rsi/rsi_91x_sdio.c +1 -1
@@ -1513,7 +1513,7 @@ static int rsi_restore(struct device *de }static const struct dev_pm_ops rsi_pm_ops = { .suspend = rsi_suspend, - .resume = rsi_resume, + .resume_noirq = rsi_resume, .freeze = rsi_freeze, .thaw = rsi_thaw, .restore = rsi_restore,
Greg Kroah-Hartman
maintainerPATCH 290/299 tools/power turbostat: Fix offset overflow issue in index converting
In reply to Greg Kroah-HartmanFrom: Calvin Walton <[email protected]>
commit 13a779de4175df602366d129e41782ad7168cef0 upstream.
The idx_to_offset() function returns type int (32-bit signed), but MSR_PKG_ENERGY_STAT is u32 and would be interpreted as a negative number. The end result is that it hits the if (offset < 0) check in update_msr_sum() which prevents the timer callback from updating the stat in the background when long durations are used. The similar issue exists in offset_to_idx() and update_msr_sum(). Fix this issue by converting the 'int' to 'off_t' accordingly.
--- tools/power/x86/turbostat/turbostat.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
tools/power/x86/turbostat/turbostat.c +6 -5
@@ -291,9 +291,9 @@ struct msr_sum_array {/* The percpu MSR sum array.*/ struct msr_sum_array *per_cpu_msr_sum; -int idx_to_offset (int idx) +off_t idx_to_offset (int idx) { -int offset; +off_t offset;switch (idx) {case IDX_PKG_ENERGY :
@@ -323,7 +323,7 @@ int idx_to_offset(int idx)return offset; } -int offset_to_idx (int offset) +int offset_to_idx (off_t offset) {int idx;
@@ -3249,7 +3249,7 @@ static int update_msr_sum(struct thread_for (i =IDX_PKG_ENERGY ; i <IDX_COUNT ; i++) {unsigned long long msr_cur, msr_last; -int offset; +off_t offset;if (!idx_valid (i))continue ;
@@ -3258,7 +3258,8 @@ static int update_msr_sum(struct thread_continue ; ret =get_msr (cpu, offset, &msr_cur);if (ret) { -fprintf (outf,"Can not update msr(0x%x)\n" , offset); +fprintf (outf,"Can not update msr(0x%llx)\n" , + (unsigned long long )offset);continue ; }
Greg Kroah-Hartman
maintainerPATCH 291/299 tracing: Map all PIDs to command lines
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit 785e3c0a3a870e72dc530856136ab4c8dd207128 upstream.
The default max PID is set by PID_MAX_DEFAULT, and the tracing infrastructure uses this number to map PIDs to the comm names of the tasks, such output of the trace can show names from the recorded PIDs in the ring buffer. This mapping is also exported to user space via the "saved_cmdlines" file in the tracefs directory.
But currently the mapping expects the PIDs to be less than PID_MAX_DEFAULT, which is the default maximum and not the real maximum. Recently, systemd will increases the maximum value of a PID on the system, and when tasks are traced that have a PID higher than PID_MAX_DEFAULT, its comm is not recorded. This leads to the entire trace to have "<...>" as the comm name, which is pretty useless.
Instead, keep the array mapping the size of PID_MAX_DEFAULT, but instead of just mapping the index to the comm, map a mask of the PID (PID_MAX_DEFAULT - 1) to the comm, and find the full PID from the map_cmdline_to_pid array (that already exists).
This bug goes back to the beginning of ftrace, but hasn't been an issue until user space started increasing the maximum value of PIDs.
--- kernel/trace/trace.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-)
kernel/trace/trace.c +15 -26
@@ -2387,14 +2387,13 @@ static void tracing_stop_tr(struct tracestatic int trace_save_cmdline (struct task_struct *tsk) { -unsigned pid, idx; +unsigned tpid, idx;/* treat recording of idle task as a success */ if (!tsk->pid)return 1 ; -if (unlikely (tsk->pid >PID_MAX_DEFAULT )) -return 0 ; + tpid = tsk->pid & (PID_MAX_DEFAULT -1 );/* * It's not the end of the world if we don't get
@@ -2405,26 +2404,15 @@ static int trace_save_cmdline(struct tasif (!arch_spin_trylock (&trace_cmdline_lock))return 0 ; - idx = savedcmd->map_pid_to_cmdline[tsk->pid]; + idx = savedcmd->map_pid_to_cmdline[tpid];if (idx ==NO_CMDLINE_MAP ) { idx = (savedcmd->cmdline_idx +1 ) % savedcmd->cmdline_num; -/* -* Check whether the cmdline buffer at idx has a pid -* mapped. We are going to overwrite that entry so we -* need to clear the map_pid_to_cmdline. Otherwise we -* would read the new comm for the old pid. -*/ - pid = savedcmd->map_cmdline_to_pid[idx]; -if (pid !=NO_CMDLINE_MAP ) - savedcmd->map_pid_to_cmdline[pid] =NO_CMDLINE_MAP ; - - savedcmd->map_cmdline_to_pid[idx] = tsk->pid; - savedcmd->map_pid_to_cmdline[tsk->pid] = idx; - + savedcmd->map_pid_to_cmdline[tpid] = idx; savedcmd->cmdline_idx = idx; } + savedcmd->map_cmdline_to_pid[idx] = tsk->pid;set_cmdline (idx, tsk->comm);arch_spin_unlock (&trace_cmdline_lock);
@@ -2435,6 +2423,7 @@ static int trace_save_cmdline(struct tasstatic void __trace_find_cmdline (int pid,char comm[]) {unsigned map; +int tpid;if (!pid) {strcpy (comm,"<idle>" );
@@ -2446,16 +2435,16 @@ static void __trace_find_cmdline(int pidreturn ; } -if (pid >PID_MAX_DEFAULT ) { -strcpy (comm,"<...>" ); -return ; + tpid = pid & (PID_MAX_DEFAULT -1 ); + map = savedcmd->map_pid_to_cmdline[tpid]; +if (map !=NO_CMDLINE_MAP ) { + tpid = savedcmd->map_cmdline_to_pid[map]; +if (tpid == pid) { +strlcpy (comm,get_saved_cmdlines (map),TASK_COMM_LEN ); +return ; + } } - - map = savedcmd->map_pid_to_cmdline[pid]; -if (map !=NO_CMDLINE_MAP ) -strlcpy (comm,get_saved_cmdlines (map),TASK_COMM_LEN ); -else -strcpy (comm,"<...>" ); +strcpy (comm,"<...>" ); }void trace_find_cmdline (int pid,char comm[])
Greg Kroah-Hartman
maintainerPATCH 292/299 tracing: Restructure trace_clock_global() to never block
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit aafe104aa9096827a429bc1358f8260ee565b7cc upstream.
It was reported that a fix to the ring buffer recursion detection would cause a hung machine when performing suspend / resume testing. The following backtrace was extracted from debugging that case:
Call Trace: trace_clock_global+0x91/0xa0 __rb_reserve_next+0x237/0x460 ring_buffer_lock_reserve+0x12a/0x3f0 trace_buffer_lock_reserve+0x10/0x50 __trace_graph_return+0x1f/0x80 trace_graph_return+0xb7/0xf0 ? trace_clock_global+0x91/0xa0 ftrace_return_to_handler+0x8b/0xf0 ? pv_hash+0xa0/0xa0 return_to_handler+0x15/0x30 ? ftrace_graph_caller+0xa0/0xa0 ? trace_clock_global+0x91/0xa0 ? __rb_reserve_next+0x237/0x460 ? ring_buffer_lock_reserve+0x12a/0x3f0 ? trace_event_buffer_lock_reserve+0x3c/0x120 ? trace_event_buffer_reserve+0x6b/0xc0 ? trace_event_raw_event_device_pm_callback_start+0x125/0x2d0 ? dpm_run_callback+0x3b/0xc0 ? pm_ops_is_empty+0x50/0x50 ? platform_get_irq_byname_optional+0x90/0x90 ? trace_device_pm_callback_start+0x82/0xd0 ? dpm_run_callback+0x49/0xc0
With the following RIP:
RIP: 0010:native_queued_spin_lock_slowpath+0x69/0x200
Since the fix to the recursion detection would allow a single recursion to happen while tracing, this lead to the trace_clock_global() taking a spin lock and then trying to take it again:
ring_buffer_lock_reserve() {
trace_clock_global() {
arch_spin_lock() {
queued_spin_lock_slowpath() {
/* lock taken */
(something else gets traced by function graph tracer)
ring_buffer_lock_reserve() {
trace_clock_global() {
arch_spin_lock() {
queued_spin_lock_slowpath() {
/* DEAD LOCK! */Tracing should *never* block, as it can lead to strange lockups like the above.
Restructure the trace_clock_global() code to instead of simply taking a lock to update the recorded "prev_time" simply use it, as two events happening on two different CPUs that calls this at the same time, really doesn't matter which one goes first. Use a trylock to grab the lock for updating the prev_time, and if it fails, simply try again the next time. If it failed to be taken, that means something else is already updating it.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212761
--- kernel/trace/trace_clock.c | 48 ++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-)
kernel/trace/trace_clock.c +32 -16
@@ -95,33 +95,49 @@ u64 notrace trace_clock_global(void) {unsigned long flags;int this_cpu; -u64 now; +u64 now, prev_time;raw_local_irq_save (flags); this_cpu =raw_smp_processor_id (); - now =sched_clock_cpu (this_cpu); +/* -* If in an NMI context then dont risk lockups and return the -* cpu_clock() time: +* The global clock "guarantees" that the events are ordered +* between CPUs. But if two events on two different CPUS call +* trace_clock_global at roughly the same time, it really does +* not matter which one gets the earlier time. Just make sure +* that the same CPU will always show a monotonic clock. +* +* Use a read memory barrier to get the latest written +* time that was recorded. */ -if (unlikely (in_nmi ())) - goto out; +smp_rmb (); + prev_time =READ_ONCE (trace_clock_struct.prev_time); + now =sched_clock_cpu (this_cpu); -arch_spin_lock (&trace_clock_struct.lock); +/* Make sure that now is always greater than prev_time */ +if ((s64)(now - prev_time) <0 ) + now = prev_time +1 ;/* -* TODO: if this happens often then maybe we should reset -* my_scd->clock to prev_time+1, to make sure -* we start ticking with the local clock from now on? +* If in an NMI context then dont risk lockups and simply return +* the current time. */ -if ((s64)(now - trace_clock_struct.prev_time) <0 ) - now = trace_clock_struct.prev_time +1 ; - - trace_clock_struct.prev_time = now; - -arch_spin_unlock (&trace_clock_struct.lock); +if (unlikely (in_nmi ())) + goto out; +/* Tracing can cause strange recursion, always use a try lock */ +if (arch_spin_trylock (&trace_clock_struct.lock)) { +/* Reread prev_time in case it was already updated */ + prev_time =READ_ONCE (trace_clock_struct.prev_time); +if ((s64)(now - prev_time) <0 ) + now = prev_time +1 ; + + trace_clock_struct.prev_time = now; + +/* The unlock acts as the wmb for the above rmb */ +arch_spin_unlock (&trace_clock_struct.lock); + } out:raw_local_irq_restore (flags);
Greg Kroah-Hartman
maintainerPATCH 293/299 dm persistent data: packed struct should have an aligned() attribute too
In reply to Greg Kroah-HartmanFrom: Joe Thornber <[email protected]>
commit a88b2358f1da2c9f9fcc432f2e0a79617fea397c upstream.
Otherwise most non-x86 architectures (e.g. riscv, arm) will resort to byte-by-byte access.
--- drivers/md/persistent-data/dm-btree-internal.h | 4 ++-- drivers/md/persistent-data/dm-space-map-common.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/md/persistent-data/dm-btree-internal.h +2 -2
@@ -34,12 +34,12 @@ struct node_header {__le32 max_entries;__le32 value_size;__le32 padding; -} __packed; +} __attribute__((packed, aligned(8)));struct btree_node {struct node_header header;__le64 keys[]; -} __packed; +} __attribute__((packed,aligned (8 )));/*
drivers/md/persistent-data/dm-space-map-common.h +4 -4
@@ -33,7 +33,7 @@ struct disk_index_entry {__le64 blocknr;__le32 nr_free;__le32 none_free_before; -} __packed; +} __attribute__ ((packed, aligned(8)));#define MAX_METADATA_BITMAPS 255
@@ -43,7 +43,7 @@ struct disk_metadata_index {__le64 blocknr;struct disk_index_entry index[MAX_METADATA_BITMAPS ]; -} __packed; +} __attribute__ ((packed, aligned(8)));struct ll_disk ;
@@ -86,7 +86,7 @@ struct disk_sm_root {__le64 nr_allocated;__le64 bitmap_root;__le64 ref_count_root; -} __packed; +} __attribute__ ((packed, aligned(8)));#define ENTRIES_PER_BYTE 4
@@ -94,7 +94,7 @@ struct disk_bitmap_header {__le32 csum;__le32 not_used;__le64 blocknr; -} __packed; +} __attribute__ ((packed, aligned(8)));enum allocation_event {SM_NONE ,
Greg Kroah-Hartman
maintainerPATCH 294/299 dm space map common: fix division bug in sm_ll_find_free_block()
In reply to Greg Kroah-HartmanFrom: Joe Thornber <[email protected]>
commit 5208692e80a1f3c8ce2063a22b675dd5589d1d80 upstream.
This division bug meant the search for free metadata space could skip the final allocation bitmap's worth of entries. Fix affects DM thinp, cache and era targets.
--- drivers/md/persistent-data/dm-space-map-common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/persistent-data/dm-space-map-common.c +2 -0
@@ -339,6 +339,8 @@ int sm_ll_find_free_block(struct ll_disk*/ begin =do_div (index_begin, ll->entries_per_block); end =do_div (end, ll->entries_per_block); +if (end ==0 ) + end = ll->entries_per_block;for (i = index_begin; i < index_end; i++, begin =0 ) {struct dm_block *blk;
Greg Kroah-Hartman
maintainerPATCH 295/299 dm integrity: fix missing goto in bitmap_flush_interval error handling
In reply to Greg Kroah-HartmanFrom: Tian Tao <[email protected]>
commit 17e9e134a8efabbbf689a0904eee92bb5a868172 upstream.
--- drivers/md/dm-integrity.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-integrity.c +1 -0
@@ -3929,6 +3929,7 @@ static int dm_integrity_ctr(struct dm_taif (val >= (uint64_t )UINT_MAX *1000 /HZ ) { r = -EINVAL ; ti->error ="Invalid bitmap_flush_interval argument" ; + goto bad; } ic->bitmap_flush_interval =msecs_to_jiffies (val); }else if (!strncmp (opt_string,"internal_hash:" ,strlen ("internal_hash:" ))) {
Greg Kroah-Hartman
maintainerPATCH 296/299 dm rq: fix double free of blk_mq_tag_set in dev remove after table load fails
In reply to Greg Kroah-HartmanFrom: Benjamin Block <[email protected]>
commit 8e947c8f4a5620df77e43c9c75310dc510250166 upstream.
When loading a device-mapper table for a request-based mapped device, and the allocation/initialization of the blk_mq_tag_set for the device fails, a following device remove will cause a double free.
E.g. (dmesg):
device-mapper: core: Cannot initialize queue for request-based dm-mq mapped device
device-mapper: ioctl: unable to set up device queue for new table.
Unable to handle kernel pointer dereference in virtual kernel address space
Failing address: 0305e098835de000 TEID: 0305e098835de803
Fault in home space mode while using kernel ASCE.
AS:000000025efe0007 R3:0000000000000024
Oops: 0038 ilc:3 [#1] SMP
Modules linked in: ... lots of modules ...
Supported: Yes, External
CPU: 0 PID: 7348 Comm: multipathd Kdump: loaded Tainted: G W X 5.3.18-53-default #1 SLE15-SP3
Hardware name: IBM 8561 T01 7I2 (LPAR)
Krnl PSW : 0704e00180000000 000000025e368eca (kfree+0x42/0x330)
R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3
Krnl GPRS: 000000000000004a 000000025efe5230 c1773200d779968d 0000000000000000
000000025e520270 000000025e8d1b40 0000000000000003 00000007aae10000
000000025e5202a2 0000000000000001 c1773200d779968d 0305e098835de640
00000007a8170000 000003ff80138650 000000025e5202a2 000003e00396faa8
Krnl Code: 000000025e368eb8: c4180041e100 lgrl %r1,25eba50b8
000000025e368ebe: ecba06b93a55 risbg %r11,%r10,6,185,58
#000000025e368ec4: e3b010000008 ag %r11,0(%r1)
>000000025e368eca: e310b0080004 lg %r1,8(%r11)
000000025e368ed0: a7110001 tmll %r1,1
000000025e368ed4: a7740129 brc 7,25e369126
000000025e368ed8: e320b0080004 lg %r2,8(%r11)
000000025e368ede: b904001b lgr %r1,%r11
Call Trace:
[<000000025e368eca>] kfree+0x42/0x330
[<000000025e5202a2>] blk_mq_free_tag_set+0x72/0xb8
[<000003ff801316a8>] dm_mq_cleanup_mapped_device+0x38/0x50 [dm_mod]
[<000003ff80120082>] free_dev+0x52/0xd0 [dm_mod]
[<000003ff801233f0>] __dm_destroy+0x150/0x1d0 [dm_mod]
[<000003ff8012bb9a>] dev_remove+0x162/0x1c0 [dm_mod]
[<000003ff8012a988>] ctl_ioctl+0x198/0x478 [dm_mod]
[<000003ff8012ac8a>] dm_ctl_ioctl+0x22/0x38 [dm_mod]
[<000000025e3b11ee>] ksys_ioctl+0xbe/0xe0
[<000000025e3b127a>] __s390x_sys_ioctl+0x2a/0x40
[<000000025e8c15ac>] system_call+0xd8/0x2c8
Last Breaking-Event-Address:
[<000000025e52029c>] blk_mq_free_tag_set+0x6c/0xb8
Kernel panic - not syncing: Fatal exception: panic_on_oopsWhen allocation/initialization of the blk_mq_tag_set fails in dm_mq_init_request_queue(), it is uninitialized/freed, but the pointer is not reset to NULL; so when dev_remove() later gets into dm_mq_cleanup_mapped_device() it sees the pointer and tries to uninitialize and free it again.
Fix this by setting the pointer to NULL in dm_mq_init_request_queue() error-handling. Also set it to NULL in dm_mq_cleanup_mapped_device().
--- drivers/md/dm-rq.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/dm-rq.c +2 -0
@@ -569,6 +569,7 @@ out_tag_set:blk_mq_free_tag_set (md->tag_set); out_kfree_tag_set:kfree (md->tag_set); + md->tag_set =NULL ;return err; }
@@ -578,6 +579,7 @@ void dm_mq_cleanup_mapped_device(structif (md->tag_set) {blk_mq_free_tag_set (md->tag_set);kfree (md->tag_set); + md->tag_set =NULL ; } }
Greg Kroah-Hartman
maintainerPATCH 297/299 lib/vsprintf.c: remove leftover f and F cases from bstr_printf()
In reply to Greg Kroah-HartmanFrom: Rasmus Villemoes <[email protected]>
commit 84696cfaf4d90945eb2a8302edc6cf627db56b84 upstream.
Commit 9af7706492f9 ("lib/vsprintf: Remove support for %pF and %pf in favour of %pS and %ps") removed support for %pF and %pf, and correctly removed the handling of those cases in vbin_printf(). However, the corresponding cases in bstr_printf() were left behind.
In the same series, %pf was re-purposed for dealing with fwnodes (3bd32d6a2ee6, "lib/vsprintf: Add %pfw conversion specifier for printing fwnode names").
So should anyone use %pf with the binary printf routines, vbin_printf() would (correctly, as it involves dereferencing the pointer) do the string formatting to the u32 array, but bstr_printf() would not copy the string from the u32 array, but instead interpret the first sizeof(void*) bytes of the formatted string as a pointer - which generally won't end well (also, all subsequent get_args would be out of sync).
--- lib/vsprintf.c | 2 -- 1 file changed, 2 deletions(-)
lib/vsprintf.c +0 -2
@@ -3102,8 +3102,6 @@ int bstr_printf(char *buf, size_t size,switch (*fmt) {case 'S' :case 's' : -case 'F' : -case 'f' :case 'x' :case 'K' :case 'e' :
Greg Kroah-Hartman
maintainerPATCH 298/299 thermal/drivers/cpufreq_cooling: Fix slab OOB issue
In reply to Greg Kroah-HartmanFrom: brian-sy yang <[email protected]>
commit 34ab17cc6c2c1ac93d7e5d53bb972df9a968f085 upstream.
Slab OOB issue is scanned by KASAN in cpu_power_to_freq(). If power is limited below the power of OPP0 in EM table, it will cause slab out-of-bound issue with negative array index.
Return the lowest frequency if limited power cannot found a suitable OPP in EM table to fix this issue.
Backtrace: [<ffffffd02d2a37f0>] die+0x104/0x5ac [<ffffffd02d2a5630>] bug_handler+0x64/0xd0 [<ffffffd02d288ce4>] brk_handler+0x160/0x258 [<ffffffd02d281e5c>] do_debug_exception+0x248/0x3f0 [<ffffffd02d284488>] el1_dbg+0x14/0xbc [<ffffffd02d75d1d4>] __kasan_report+0x1dc/0x1e0 [<ffffffd02d75c2e0>] kasan_report+0x10/0x20 [<ffffffd02d75def8>] __asan_report_load8_noabort+0x18/0x28 [<ffffffd02e6fce5c>] cpufreq_power2state+0x180/0x43c [<ffffffd02e6ead80>] power_actor_set_power+0x114/0x1d4 [<ffffffd02e6fac24>] allocate_power+0xaec/0xde0 [<ffffffd02e6f9f80>] power_allocator_throttle+0x3ec/0x5a4 [<ffffffd02e6ea888>] handle_thermal_trip+0x160/0x294 [<ffffffd02e6edd08>] thermal_zone_device_check+0xe4/0x154 [<ffffffd02d351cb4>] process_one_work+0x5e4/0xe28 [<ffffffd02d352f44>] worker_thread+0xa4c/0xfac [<ffffffd02d360124>] kthread+0x33c/0x358 [<ffffffd02d289940>] ret_from_fork+0xc/0x18
--- drivers/thermal/cpufreq_cooling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/cpufreq_cooling.c +1 -1
@@ -123,7 +123,7 @@ static u32 cpu_power_to_freq(struct cpuf {int i; -for (i = cpufreq_cdev->max_level; i >=0 ; i--) { +for (i = cpufreq_cdev->max_level; i >0 ; i--) {if (power >= cpufreq_cdev->em->table[i].power)break ; }
Greg Kroah-Hartman
maintainerPATCH 299/299 thermal/core/fair share: Lock the thermal zone while looping over instances
In reply to Greg Kroah-HartmanFrom: Lukasz Luba <[email protected]>
commit fef05776eb02238dcad8d5514e666a42572c3f32 upstream.
The tz->lock must be hold during the looping over the instances in that thermal zone. This lock was missing in the governor code since the beginning, so it's hard to point into a particular commit.
--- drivers/thermal/gov_fair_share.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/thermal/gov_fair_share.c +4 -0
@@ -82,6 +82,8 @@ static int fair_share_throttle(struct thint total_instance =0 ;int cur_trip_level =get_trip_level (tz); +mutex_lock (&tz->lock); +list_for_each_entry (instance, &tz->thermal_instances, tz_node) {if (instance->trip != trip)continue ;
@@ -110,6 +112,8 @@ static int fair_share_throttle(struct thmutex_unlock (&instance->cdev->lock);thermal_cdev_update (cdev); } + +mutex_unlock (&tz->lock);return 0 ; }
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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.
CIP testing did not find any kernel problems here: (Siemens board is unavailable):
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.10.y
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.10:
12 builds: 12 pass, 0 fail
28 boots: 28 pass, 0 fail
70 tests: 70 pass, 0 failLinux version: 5.10.36-rc1-g4edc8f7e8676
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 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB, using 32-bit and 64-bit ARM kernels:
Signature · 1 line
Florian
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
5.10.36-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +0000. Anything received after that time might be too late.
Build results:
total: 156 pass: 156 fail: 0 Qemu test results: total: 455 pass: 455 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.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 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.
Boot tested in qemu for the 32 bit ARM aspeed_g5 and aspeed_g4 defconfigs.
Cheers,
Joel
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 5.10.36-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git branch: linux-5.10.y
* git commit: 4edc8f7e8676bbfdec9d67dc6b90ec72fd3bacaa
* git describe: v5.10.35-300-g4edc8f7e8676
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.10.y/build/v5.10.35-300-g4edc8f7e8676
## No regressions (compared to v5.10.35-221-gbb0eba64e018)
## No fixes (compared to v5.10.35-221-gbb0eba64e018)
## Test result summary
total: 78630, pass: 64381, fail: 2948, skip: 11032, xfail: 269,
## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 193 total, 193 passed, 0 failed
* arm64: 27 total, 27 passed, 0 failed
* dragonboard-410c: 1 total, 1 passed, 0 failed
* hi6220-hikey: 1 total, 1 passed, 0 failed
* i386: 26 total, 26 passed, 0 failed
* juno-r2: 1 total, 1 passed, 0 failed
* mips: 45 total, 45 passed, 0 failed
* parisc: 9 total, 9 passed, 0 failed
* powerpc: 27 total, 27 passed, 0 failed
* riscv: 21 total, 21 passed, 0 failed
* s390: 18 total, 18 passed, 0 failed
* sh: 18 total, 18 passed, 0 failed
* sparc: 9 total, 9 passed, 0 failed
* x15: 1 total, 1 passed, 0 failed
* x86: 1 total, 1 passed, 0 failed
* x86_64: 27 total, 27 passed, 0 failed
## Test suites summary
* fwts
* install-android-platform-tools-r2600
* kselftest-
* kselftest-android
* kselftest-bpf
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-firmware
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-lkdtm
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-vsyscall-mode-native-
* kselftest-vsyscall-mode-none-
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* packetdrill
* perf
* rcutorture
* ssuite
* v4l2-compliance
--
Linaro LKFT
https://lkft.linaro.org