6.1.149-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 298/482 wifi: ath11k: fix dest ring-buffer corruption when ring is full
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit aa6956150f820e6a6deba44be325ddfcb5b10f88 upstream.
Add the missing memory barriers to make sure that destination ring descriptors are read before updating the tail pointer (and passing ownership to the device) to avoid memory corruption on weakly ordered architectures like aarch64 when the ring is full.
Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41
--- drivers/net/wireless/ath/ath11k/hal.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath11k/hal.c +9 -2
@@ -827,7 +827,6 @@ void ath11k_hal_srng_access_end(struct a {lockdep_assert_held (&srng->lock); -/* TODO: See if we need a write memory barrier here */ if (srng->flags &HAL_SRNG_FLAGS_LMAC_RING ) {/* For LMAC rings, ring pointer updates are done through FW and * hence written to a shared memory location that is read by FW
@@ -842,7 +841,11 @@ void ath11k_hal_srng_access_end(struct aWRITE_ONCE (*srng->u.src_ring.hp_addr, srng->u.src_ring.hp); }else { srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; - *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; +/* Make sure descriptor is read before updating the +* tail pointer. +*/ +dma_mb (); +WRITE_ONCE (*srng->u.dst_ring.tp_addr, srng->u.dst_ring.tp); } }else {if (srng->ring_dir ==HAL_SRNG_DIR_SRC ) {
@@ -858,6 +861,10 @@ void ath11k_hal_srng_access_end(struct a srng->u.src_ring.hp); }else { srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; +/* Make sure descriptor is read before updating the +* tail pointer. +*/ +mb (); ath11k_hif_write32(ab, (unsigned long)srng->u.dst_ring.tp_addr - (unsigned long)ab->mem,
Greg Kroah-Hartman
maintainerPATCH 299/482 pwm: imx-tpm: Reset counter if CMOD is 0
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurentiu Mihalcea <[email protected]>
commit 65c6f742ab14ab1a2679fba72b82dcc0289d96f1 upstream.
As per the i.MX93 TRM, section 67.3.2.1 "MOD register update", the value of the TPM counter does NOT get updated when writing MOD.MOD unless SC.CMOD != 0. Therefore, with the current code, assuming the following sequence:
1) pwm_disable()
2) pwm_apply_might_sleep() /* period is changed here */
3) pwm_enable()
and assuming only one channel is active, if CNT.COUNT is higher than the MOD.MOD value written during the pwm_apply_might_sleep() call then, when re-enabling the PWM during pwm_enable(), the counter will end up resetting after UINT32_MAX - CNT.COUNT + MOD.MOD cycles instead of MOD.MOD cycles as normally expected.
Fix this problem by forcing a reset of the TPM counter before MOD.MOD is written.
--- drivers/pwm/pwm-imx-tpm.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/pwm/pwm-imx-tpm.c +9 -0
@@ -205,6 +205,15 @@ static int pwm_imx_tpm_apply_hw(struct pwritel (val, tpm->base +PWM_IMX_TPM_SC );/* +* if the counter is disabled (CMOD == 0), programming the new +* period length (MOD) will not reset the counter (CNT). If +* CNT.COUNT happens to be bigger than the new MOD value then +* the counter will end up being reset way too late. Therefore, +* manually reset it to 0. +*/ +if (!cmod) +writel (0x0 , tpm->base +PWM_IMX_TPM_CNT ); +/* * set period count: * if the PWM is disabled (CMOD[1:0] = 2b00), then MOD register * is updated when MOD register is written.
Greg Kroah-Hartman
maintainerPATCH 300/482 pwm: mediatek: Handle hardware enable and clock enable separately
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit 704d918341c378c5f9505dfdf32d315e256d3846 upstream.
Stop handling the clocks in pwm_mediatek_enable() and pwm_mediatek_disable(). This is a preparing change for the next commit that requires that clocks and the enable bit are handled separately.
Also move these two functions a bit further up in the source file to make them usable in pwm_mediatek_config(), which is needed in the next commit, too.
--- drivers/pwm/pwm-mediatek.c | 60 +++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 32 deletions(-)
drivers/pwm/pwm-mediatek.c +28 -32
@@ -114,6 +114,26 @@ static inline void pwm_mediatek_writel(swritel (value, chip->regs + pwm_mediatek_reg_offset[num] + offset); } +static void pwm_mediatek_enable (struct pwm_chip *chip,struct pwm_device *pwm) +{ +struct pwm_mediatek_chip *pc =to_pwm_mediatek_chip (chip); +u32 value; + + value =readl (pc->regs); + value |=BIT (pwm->hwpwm); +writel (value, pc->regs); +} + +static void pwm_mediatek_disable (struct pwm_chip *chip,struct pwm_device *pwm) +{ +struct pwm_mediatek_chip *pc =to_pwm_mediatek_chip (chip); +u32 value; + + value =readl (pc->regs); + value &= ~BIT (pwm->hwpwm); +writel (value, pc->regs); +} +static int pwm_mediatek_config (struct pwm_chip *chip,struct pwm_device *pwm,int duty_ns,int period_ns) {
@@ -176,35 +196,6 @@ out:return ret; } -static int pwm_mediatek_enable (struct pwm_chip *chip,struct pwm_device *pwm) -{ -struct pwm_mediatek_chip *pc =to_pwm_mediatek_chip (chip); -u32 value; -int ret; - - ret =pwm_mediatek_clk_enable (chip, pwm); -if (ret <0 ) -return ret; - - value =readl (pc->regs); - value |=BIT (pwm->hwpwm); -writel (value, pc->regs); - -return 0 ; -} - -static void pwm_mediatek_disable (struct pwm_chip *chip,struct pwm_device *pwm) -{ -struct pwm_mediatek_chip *pc =to_pwm_mediatek_chip (chip); -u32 value; - - value =readl (pc->regs); - value &= ~BIT (pwm->hwpwm); -writel (value, pc->regs); - -pwm_mediatek_clk_disable (chip, pwm); -} -static int pwm_mediatek_apply (struct pwm_chip *chip,struct pwm_device *pwm,const struct pwm_state *state) {
@@ -214,8 +205,10 @@ static int pwm_mediatek_apply(struct pwmreturn -EINVAL ;if (!state->enabled) { -if (pwm->state.enabled) +if (pwm->state.enabled) {pwm_mediatek_disable (chip, pwm); +pwm_mediatek_clk_disable (chip, pwm); + }return 0 ; }
@@ -224,8 +217,11 @@ static int pwm_mediatek_apply(struct pwmif (err)return err; -if (!pwm->state.enabled) - err =pwm_mediatek_enable (chip, pwm); +if (!pwm->state.enabled) { + err =pwm_mediatek_clk_enable (chip, pwm); +if (!err) +pwm_mediatek_enable (chip, pwm); + }return err; }
Greg Kroah-Hartman
maintainerPATCH 301/482 pwm: mediatek: Fix duty and period setting
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit f21d136caf8171f94159d975ea4620c164431bd9 upstream.
The period generated by the hardware is
(PWMDWIDTH + 1) << CLKDIV) / freq
according to my tests with a signal analyser and also the documentation.
The current algorithm doesn't consider the + 1 part and so configures slightly too high periods. The same issue exists for the duty cycle setting. So subtract 1 from both the register values for period and duty cycle. If period is 0, bail out, if duty_cycle is 0, just disable the PWM which results in a constant low output.
--- drivers/pwm/pwm-mediatek.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
drivers/pwm/pwm-mediatek.c +14 -7
@@ -163,7 +163,10 @@ static int pwm_mediatek_config(struct pwdo_div (resolution, clk_rate); cnt_period =DIV_ROUND_CLOSEST_ULL ((u64 )period_ns *1000 , resolution); -while (cnt_period >8191 ) { +if (!cnt_period) +return -EINVAL ; + +while (cnt_period >8192 ) { resolution *=2 ; clkdiv++; cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000,
@@ -186,9 +189,16 @@ static int pwm_mediatek_config(struct pw } cnt_duty =DIV_ROUND_CLOSEST_ULL ((u64 )duty_ns *1000 , resolution); +pwm_mediatek_writel (pc, pwm->hwpwm,PWMCON ,BIT (15 ) | clkdiv); -pwm_mediatek_writel (pc, pwm->hwpwm, reg_width, cnt_period); -pwm_mediatek_writel (pc, pwm->hwpwm, reg_thres, cnt_duty); +pwm_mediatek_writel (pc, pwm->hwpwm, reg_width, cnt_period -1 ); + +if (cnt_duty) { +pwm_mediatek_writel (pc, pwm->hwpwm, reg_thres, cnt_duty -1 ); +pwm_mediatek_enable (chip, pwm); + }else { +pwm_mediatek_disable (chip, pwm); + } out:pwm_mediatek_clk_disable (chip, pwm);
@@ -217,11 +227,8 @@ static int pwm_mediatek_apply(struct pwmif (err)return err; -if (!pwm->state.enabled) { +if (!pwm->state.enabled) err =pwm_mediatek_clk_enable (chip, pwm); -if (!err) -pwm_mediatek_enable (chip, pwm); - }return err; }
Greg Kroah-Hartman
maintainerPATCH 302/482 hwmon: (gsc-hwmon) fix fan pwm setpoint show functions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Harvey <[email protected]>
commit 9c62e2282900332c8b711d9f9e37af369a8ef71b upstream.
The Linux hwmon sysfs API values for pwmX_auto_pointY_pwm represent an integer value between 0 (0%) to 255 (100%) and the pwmX_auto_pointY_temp represent millidegrees Celcius.
Commit a6d80df47ee2 ("hwmon: (gsc-hwmon) fix fan pwm temperature scaling") properly addressed the incorrect scaling in the pwm_auto_point_temp_store implementation but erroneously scaled the pwm_auto_point_pwm_show (pwm value) instead of the pwm_auto_point_temp_show (temp value) resulting in:
# cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_pwm 25500 # cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_temp 4500
Fix the scaling of these attributes:
# cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_pwm 255 # cat /sys/class/hwmon/hwmon0/pwm1_auto_point6_temp 45000
--- drivers/hwmon/gsc-hwmon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/gsc-hwmon.c +2 -2
@@ -65,7 +65,7 @@ static ssize_t pwm_auto_point_temp_show(return ret; ret = regs[0 ] | regs[1 ] <<8 ; -return sprintf (buf,"%d\n" , ret *10 ); +return sprintf (buf,"%d\n" , ret *100 ); } static ssize_t pwm_auto_point_temp_store(struct device *dev,
@@ -100,7 +100,7 @@ static ssize_t pwm_auto_point_pwm_show(s {struct sensor_device_attribute *attr =to_sensor_dev_attr (devattr); -return sprintf (buf,"%d\n" ,255 * (50 + (attr->index *10 ))); +return sprintf (buf,"%d\n" ,255 * (50 + (attr->index *10 )) /100 ); } static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
Greg Kroah-Hartman
maintainerPATCH 303/482 mtd: spi-nor: Fix spi_nor_try_unlock_all()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Walle <[email protected]>
commit 2e3a7476ec3989e77270b9481e76e137824b17c0 upstream.
Commit ff67592cbdfc ("mtd: spi-nor: Introduce spi_nor_set_mtd_info()") moved all initialization of the mtd fields at the end of spi_nor_scan(). Normally, the mtd info is only needed for the mtd ops on the device, with one exception: spi_nor_try_unlock_all(), which will also make use of the mtd->size parameter. With that commit, the size will always be zero because it is not initialized. Fix that by not using the size of the mtd_info struct, but use the size from struct spi_nor_flash_parameter.
--- drivers/mtd/spi-nor/swp.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/mtd/spi-nor/swp.c +8 -11
@@ -50,7 +50,6 @@ static u64 spi_nor_get_min_prot_length_sstatic void spi_nor_get_locked_range_sr (struct spi_nor *nor,u8 sr,loff_t *ofs,uint64_t *len) { -struct mtd_info *mtd = &nor->mtd;u64 min_prot_len;u8 mask =spi_nor_get_sr_bp_mask (nor);u8 tb_mask =spi_nor_get_sr_tb_mask (nor);
@@ -71,13 +70,13 @@ static void spi_nor_get_locked_range_sr( min_prot_len =spi_nor_get_min_prot_length_sr (nor); *len = min_prot_len << (bp -1 ); -if (*len > mtd->size) - *len = mtd->size; +if (*len > nor->params->size) + *len = nor->params->size;if (nor->flags &SNOR_F_HAS_SR_TB && sr & tb_mask) *ofs =0 ;else - *ofs = mtd->size - *len; + *ofs = nor->params->size - *len; }/*
@@ -153,7 +152,6 @@ static bool spi_nor_is_unlocked_sr(struc*/ static int spi_nor_sr_lock (struct spi_nor *nor,loff_t ofs,uint64_t len) { -struct mtd_info *mtd = &nor->mtd;u64 min_prot_len;int ret, status_old, status_new;u8 mask =spi_nor_get_sr_bp_mask (nor);
@@ -178,7 +176,7 @@ static int spi_nor_sr_lock(struct spi_no can_be_bottom = false;/* If anything above us is unlocked, we can't use 'top' protection */ -if (!spi_nor_is_locked_sr (nor, ofs + len, mtd->size - (ofs + len), +if (!spi_nor_is_locked_sr (nor, ofs + len, nor->params->size - (ofs + len), status_old)) can_be_top = false;
@@ -190,11 +188,11 @@ static int spi_nor_sr_lock(struct spi_no/* lock_len: length of region that should end up locked */ if (use_top) - lock_len = mtd->size - ofs; + lock_len = nor->params->size - ofs;else lock_len = ofs + len; -if (lock_len == mtd->size) { +if (lock_len == nor->params->size) { val = mask; }else { min_prot_len =spi_nor_get_min_prot_length_sr (nor);
@@ -238,7 +236,6 @@ static int spi_nor_sr_lock(struct spi_no*/ static int spi_nor_sr_unlock (struct spi_nor *nor,loff_t ofs,uint64_t len) { -struct mtd_info *mtd = &nor->mtd;u64 min_prot_len;int ret, status_old, status_new;u8 mask =spi_nor_get_sr_bp_mask (nor);
@@ -263,7 +260,7 @@ static int spi_nor_sr_unlock(struct spi_ can_be_top = false;/* If anything above us is locked, we can't use 'bottom' protection */ -if (!spi_nor_is_unlocked_sr (nor, ofs + len, mtd->size - (ofs + len), +if (!spi_nor_is_unlocked_sr (nor, ofs + len, nor->params->size - (ofs + len), status_old)) can_be_bottom = false;
@@ -275,7 +272,7 @@ static int spi_nor_sr_unlock(struct spi_/* lock_len: length of region that should remain locked */ if (use_top) - lock_len = mtd->size - (ofs + len); + lock_len = nor->params->size - (ofs + len);else lock_len = ofs;
Greg Kroah-Hartman
maintainerPATCH 304/482 mtd: spinand: propagate spinand_wait() errors from spinand_write_page()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
commit 091d9e35b85b0f8f7e1c73535299f91364a5c73a upstream.
Since commit 3d1f08b032dc ("mtd: spinand: Use the external ECC engine logic") the spinand_write_page() function ignores the errors returned by spinand_wait(). Change the code to propagate those up to the stack as it was done before the offending change.
--- drivers/mtd/nand/spi/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/nand/spi/core.c +4 -1
@@ -624,7 +624,10 @@ static int spinand_write_page(struct spiSPINAND_WRITE_INITIAL_DELAY_US ,SPINAND_WRITE_POLL_DELAY_US , &status); -if (!ret && (status &STATUS_PROG_FAILED )) +if (ret) +return ret; + +if (status &STATUS_PROG_FAILED )return -EIO ;return nand_ecc_finish_io_req (nand, (struct nand_page_io_req *)req);
Greg Kroah-Hartman
maintainerPATCH 305/482 mtd: rawnand: fsmc: Add missing check after DMA map
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
commit 6c4dab38431fee3d39a841d66ba6f2890b31b005 upstream.
The DMA map functions can fail and should be tested for errors.
Rule: add
--- drivers/mtd/nand/raw/fsmc_nand.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mtd/nand/raw/fsmc_nand.c +2 -0
@@ -503,6 +503,8 @@ static int dma_xfer(struct fsmc_nand_dat dma_dev = chan->device; dma_addr =dma_map_single (dma_dev->dev, buffer, len, direction); +if (dma_mapping_error (dma_dev->dev, dma_addr)) +return -EINVAL ;if (direction ==DMA_TO_DEVICE ) { dma_src = dma_addr;
Greg Kroah-Hartman
maintainerPATCH 306/482 mtd: rawnand: renesas: Add missing check after DMA map
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
commit 79e441ee47949376e3bc20f085cf017b70523d0f upstream.
The DMA map functions can fail and should be tested for errors.
--- drivers/mtd/nand/raw/renesas-nand-controller.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/mtd/nand/raw/renesas-nand-controller.c +6 -0
@@ -426,6 +426,9 @@ static int rnandc_read_page_hw_ecc(struc/* Configure DMA */ dma_addr =dma_map_single (rnandc->dev, rnandc->buf, mtd->writesize,DMA_FROM_DEVICE ); +if (dma_mapping_error (rnandc->dev, dma_addr)) +return -ENOMEM ; +writel (dma_addr, rnandc->regs +DMA_ADDR_LOW_REG );writel (mtd->writesize, rnandc->regs +DMA_CNT_REG );writel (DMA_TLVL_MAX , rnandc->regs +DMA_TLVL_REG );
@@ -606,6 +609,9 @@ static int rnandc_write_page_hw_ecc(stru/* Configure DMA */ dma_addr =dma_map_single (rnandc->dev, (void *)rnandc->buf, mtd->writesize,DMA_TO_DEVICE ); +if (dma_mapping_error (rnandc->dev, dma_addr)) +return -ENOMEM ; +writel (dma_addr, rnandc->regs +DMA_ADDR_LOW_REG );writel (mtd->writesize, rnandc->regs +DMA_CNT_REG );writel (DMA_TLVL_MAX , rnandc->regs +DMA_TLVL_REG );
Greg Kroah-Hartman
maintainerPATCH 307/482 PCI: endpoint: Fix configfs group list head handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit d79123d79a8154b4318529b7b2ff7e15806f480b upstream.
Doing a list_del() on the epf_group field of struct pci_epf_driver in pci_epf_remove_cfs() is not correct as this field is a list head, not a list entry. This list_del() call triggers a KASAN warning when an endpoint function driver which has a configfs attribute group is torn down:
==================================================================
BUG: KASAN: slab-use-after-free in pci_epf_remove_cfs+0x17c/0x198 Write of size 8 at addr ffff00010f4a0d80 by task rmmod/319 CPU: 3 UID: 0 PID: 319 Comm: rmmod Not tainted 6.16.0-rc2 #1 NONE Hardware name: Radxa ROCK 5B (DT) Call trace: show_stack+0x2c/0x84 (C) dump_stack_lvl+0x70/0x98 print_report+0x17c/0x538 kasan_report+0xb8/0x190 __asan_report_store8_noabort+0x20/0x2c pci_epf_remove_cfs+0x17c/0x198 pci_epf_unregister_driver+0x18/0x30 nvmet_pci_epf_cleanup_module+0x24/0x30 [nvmet_pci_epf] __arm64_sys_delete_module+0x264/0x424 invoke_syscall+0x70/0x260 el0_svc_common.constprop.0+0xac/0x230 do_el0_svc+0x40/0x58 el0_svc+0x48/0xdc el0t_64_sync_handler+0x10c/0x138 el0t_64_sync+0x198/0x19c
...
Remove this incorrect list_del() call from pci_epf_remove_cfs().
--- drivers/pci/endpoint/pci-epf-core.c | 1 - 1 file changed, 1 deletion(-)
drivers/pci/endpoint/pci-epf-core.c +0 -1
@@ -343,7 +343,6 @@ static void pci_epf_remove_cfs(struct pcmutex_lock (&pci_epf_mutex);list_for_each_entry_safe (group, tmp, &driver->epf_group, group_entry)pci_ep_cfs_remove_epf_group (group); -list_del (&driver->epf_group);mutex_unlock (&pci_epf_mutex); }
Greg Kroah-Hartman
maintainerPATCH 308/482 PCI: endpoint: Fix configfs group removal on driver teardown
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 910bdb8197f9322790c738bb32feaa11dba26909 upstream.
An endpoint driver configfs attributes group is added to the epf_group list of struct pci_epf_driver by pci_epf_add_cfs() but an added group is not removed from this list when the attribute group is unregistered with pci_ep_cfs_remove_epf_group().
Add the missing list_del() call in pci_ep_cfs_remove_epf_group() to correctly remove the attribute group from the driver list.
With this change, once the loop over all attribute groups in pci_epf_remove_cfs() completes, the driver epf_group list should be empty. Add a WARN_ON() to make sure of that.
--- drivers/pci/endpoint/pci-ep-cfs.c | 1 + drivers/pci/endpoint/pci-epf-core.c | 1 + 2 files changed, 2 insertions(+)
drivers/pci/endpoint/pci-ep-cfs.c +1 -0
@@ -646,6 +646,7 @@ void pci_ep_cfs_remove_epf_group(structif (IS_ERR_OR_NULL (group))return ; +list_del (&group->group_entry);configfs_unregister_default_group (group); }EXPORT_SYMBOL (pci_ep_cfs_remove_epf_group);
drivers/pci/endpoint/pci-epf-core.c +1 -0
@@ -343,6 +343,7 @@ static void pci_epf_remove_cfs(struct pcmutex_lock (&pci_epf_mutex);list_for_each_entry_safe (group, tmp, &driver->epf_group, group_entry)pci_ep_cfs_remove_epf_group (group); +WARN_ON (!list_empty (&driver->epf_group));mutex_unlock (&pci_epf_mutex); }
Greg Kroah-Hartman
maintainerPATCH 309/482 vsock/virtio: Validate length in packet header before skb_put()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 0dab92484474587b82e8e0455839eaf5ac7bf894 upstream.
When receiving a vsock packet in the guest, only the virtqueue buffer size is validated prior to virtio_vsock_skb_rx_put(). Unfortunately, virtio_vsock_skb_rx_put() uses the length from the packet header as the length argument to skb_put(), potentially resulting in SKB overflow if the host has gone wonky.
Validate the length as advertised by the packet header before calling virtio_vsock_skb_rx_put().
Message-Id: <[email protected]>
--- net/vmw_vsock/virtio_transport.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
net/vmw_vsock/virtio_transport.c +10 -2
@@ -494,8 +494,9 @@ static void virtio_transport_rx_work(str do { virtqueue_disable_cb(vq); for (;;) { + unsigned int len, payload_len; + struct virtio_vsock_hdr *hdr; struct sk_buff *skb; - unsigned int len; if (!virtio_transport_more_replies(vsock)) { /* Stop rx until the device processes already
@@ -512,11 +513,18 @@ static void virtio_transport_rx_work(str vsock->rx_buf_nr--;/* Drop short/long packets */ -if (unlikely (len <sizeof (struct virtio_vsock_hdr ) || +if (unlikely (len <sizeof (*hdr) || len >virtio_vsock_skb_len (skb))) {kfree_skb (skb);continue ; } + + hdr =virtio_vsock_hdr (skb); + payload_len =le32_to_cpu (hdr->len); +if (unlikely (payload_len > len -sizeof (*hdr))) { +kfree_skb (skb); +continue ; + }virtio_vsock_skb_rx_put (skb);virtio_transport_deliver_tap_pkt (skb);
Greg Kroah-Hartman
maintainerPATCH 310/482 vhost/vsock: Avoid allocating arbitrarily-sized SKBs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 10a886aaed293c4db3417951f396827216299e3d upstream.
vhost_vsock_alloc_skb() returns NULL for packets advertising a length larger than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE in the packet header. However, this is only checked once the SKB has been allocated and, if the length in the packet header is zero, the SKB may not be freed immediately.
Hoist the size check before the SKB allocation so that an iovec larger than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + the header size is rejected outright. The subsequent check on the length field in the header can then simply check that the allocated SKB is indeed large enough to hold the packet.
Message-Id: <[email protected]>
--- drivers/vhost/vsock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/vhost/vsock.c +4 -2
@@ -340,6 +340,9 @@ vhost_vsock_alloc_skb(struct vhost_virtq len =iov_length (vq->iov, out); +if (len >VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +VIRTIO_VSOCK_SKB_HEADROOM ) +return NULL ; +/* len contains both payload and hdr */ skb =virtio_vsock_alloc_skb (len,GFP_KERNEL );if (!skb)
@@ -363,8 +366,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqreturn skb;/* The pkt is too big or the length in the header is invalid */ -if (payload_len >VIRTIO_VSOCK_MAX_PKT_BUF_SIZE || - payload_len +sizeof (*hdr) > len) { +if (payload_len +sizeof (*hdr) > len) {kfree_skb (skb);return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 311/482 jbd2: prevent softlockup in jbd2_log_do_checkpoint()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 9d98cf4632258720f18265a058e62fde120c0151 upstream.
Both jbd2_log_do_checkpoint() and jbd2_journal_shrink_checkpoint_list() periodically release j_list_lock after processing a batch of buffers to avoid long hold times on the j_list_lock. However, since both functions contend for j_list_lock, the combined time spent waiting and processing can be significant.
jbd2_journal_shrink_checkpoint_list() explicitly calls cond_resched() when need_resched() is true to avoid softlockups during prolonged operations. But jbd2_log_do_checkpoint() only exits its loop when need_resched() is true, relying on potentially sleeping functions like __flush_batch() or wait_on_buffer() to trigger rescheduling. If those functions do not sleep, the kernel may hit a softlockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 156s! [kworker/u129:2:373] CPU: 3 PID: 373 Comm: kworker/u129:2 Kdump: loaded Not tainted 6.6.0+ #10 Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.27 06/13/2017 Workqueue: writeback wb_workfn (flush-7:2) pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : native_queued_spin_lock_slowpath+0x358/0x418 lr : jbd2_log_do_checkpoint+0x31c/0x438 [jbd2] Call trace: native_queued_spin_lock_slowpath+0x358/0x418 jbd2_log_do_checkpoint+0x31c/0x438 [jbd2] __jbd2_log_wait_for_space+0xfc/0x2f8 [jbd2] add_transaction_credits+0x3bc/0x418 [jbd2] start_this_handle+0xf8/0x560 [jbd2] jbd2__journal_start+0x118/0x228 [jbd2] __ext4_journal_start_sb+0x110/0x188 [ext4] ext4_do_writepages+0x3dc/0x740 [ext4] ext4_writepages+0xa4/0x190 [ext4] do_writepages+0x94/0x228 __writeback_single_inode+0x48/0x318 writeback_sb_inodes+0x204/0x590 __writeback_inodes_wb+0x54/0xf8 wb_writeback+0x2cc/0x3d8 wb_do_writeback+0x2e0/0x2f8 wb_workfn+0x80/0x2a8 process_one_work+0x178/0x3e8 worker_thread+0x234/0x3b8 kthread+0xf0/0x108 ret_from_fork+0x10/0x20
So explicitly call cond_resched() in jbd2_log_do_checkpoint() to avoid softlockup.
--- fs/jbd2/checkpoint.c | 1 + 1 file changed, 1 insertion(+)
fs/jbd2/checkpoint.c +1 -0
@@ -297,6 +297,7 @@ restart: retry:if (batch_count)__flush_batch (journal, &batch_count); +cond_resched ();spin_lock (&journal->j_list_lock); goto restart; }
Greg Kroah-Hartman
maintainerPATCH 312/482 soc/tegra: pmc: Ensure power-domains are in a known state
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Hunter <[email protected]>
commit b6bcbce3359619d05bf387d4f5cc3af63668dbaa upstream.
After commit 13a4b7fb6260 ("pmdomain: core: Leave powered-on genpds on until late_initcall_sync") was applied, the Tegra210 Jetson TX1 board failed to boot. Looking into this issue, before this commit was applied, if any of the Tegra power-domains were in 'on' state when the kernel booted, they were being turned off by the genpd core before any driver had chance to request them. This was purely by luck and a consequence of the power-domains being turned off earlier during boot. After this commit was applied, any power-domains in the 'on' state are kept on for longer during boot and therefore, may never transitioned to the off state before they are requested/used. The hang on the Tegra210 Jetson TX1 is caused because devices in some power-domains are accessed without the power-domain being turned off and on, indicating that the power-domain is not in a completely on state.
Quoted 1 line
From reviewing the Tegra PMC driver code, if a power-domain is in the
'on' state there is no guarantee that all the necessary clocks associated with the power-domain are on and even if they are they would not have been requested via the clock framework and so could be turned off later. Some power-domains also have a 'clamping' register that needs to be configured as well. In short, if a power-domain is already 'on' it is difficult to know if it has been configured correctly. Given that the power-domains happened to be switched off during boot previously, to ensure that they are in a good known state on boot, fix this by switching off any power-domains that are on initially when registering the power-domains with the genpd framework.
Note that commit 05cfb988a4d0 ("soc/tegra: pmc: Initialise resets associated with a power partition") updated the tegra_powergate_of_get_resets() function to pass the 'off' to ensure that the resets for the power-domain are in the correct state on boot. However, now that we may power off a domain on boot, if it is on, it is better to move this logic into the tegra_powergate_add() function so that there is a single place where we are handling the initial state of the power-domain.
--- drivers/soc/tegra/pmc.c | 51 +++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 22 deletions(-)
drivers/soc/tegra/pmc.c +29 -22
@@ -1224,7 +1224,7 @@ err: }static int tegra_powergate_of_get_resets (struct tegra_powergate *pg, -struct device_node *np,bool off) +struct device_node *np) {struct device *dev = pg->pmc->dev;int err;
@@ -1239,22 +1239,6 @@ static int tegra_powergate_of_get_resets err =reset_control_acquire (pg->reset);if (err <0 ) {pr_err ("failed to acquire resets: %d\n" , err); - goto out; - } - -if (off) { - err =reset_control_assert (pg->reset); - }else { - err =reset_control_deassert (pg->reset); -if (err <0 ) - goto out; - -reset_control_release (pg->reset); - } - -out: -if (err) { -reset_control_release (pg->reset);reset_control_put (pg->reset); }
@@ -1299,20 +1283,43 @@ static int tegra_powergate_add(struct te goto set_available; } - err =tegra_powergate_of_get_resets (pg, np, off); + err =tegra_powergate_of_get_resets (pg, np);if (err <0 ) {dev_err (dev,"failed to get resets for %pOFn: %d\n" , np, err); goto remove_clks; } -if (!IS_ENABLED (CONFIG_PM_GENERIC_DOMAINS )) { -if (off) -WARN_ON (tegra_powergate_power_up (pg, true)); +/* +* If the power-domain is off, then ensure the resets are asserted. +* If the power-domain is on, then power down to ensure that when is +* it turned on the power-domain, clocks and resets are all in the +* expected state. +*/ +if (off) { + err =reset_control_assert (pg->reset); +if (err) { +pr_err ("failed to assert resets: %d\n" , err); + goto remove_resets; + } + }else { + err =tegra_powergate_power_down (pg); +if (err) { +dev_err (dev,"failed to turn off PM domain %s: %d\n" , + pg->genpd.name, err); + goto remove_resets; + } + } +/* +* If PM_GENERIC_DOMAINS is not enabled, power-on +* the domain and skip the genpd registration. +*/ +if (!IS_ENABLED (CONFIG_PM_GENERIC_DOMAINS )) { +WARN_ON (tegra_powergate_power_up (pg, true)); goto remove_resets; } - err =pm_genpd_init (&pg->genpd,NULL , off); + err =pm_genpd_init (&pg->genpd,NULL , true);if (err <0 ) {dev_err (dev,"failed to initialise PM domain %pOFn: %d\n" , np, err);
Greg Kroah-Hartman
maintainerPATCH 313/482 parisc: Check region is readable by user in raw_copy_from_user()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John David Anglin <[email protected]>
commit 91428ca9320edbab1211851d82429d33b9cd73ef upstream.
Because of the way the _PAGE_READ is handled in the parisc PTE, an access interruption is not generated when the kernel reads from a region where the _PAGE_READ is zero. The current code was written assuming read access faults would also occur in the kernel.
This change adds user access checks to raw_copy_from_user(). The prober_user() define checks whether user code has read access to a virtual address. Note that page faults are not handled in the exception support for the probe instruction. For this reason, we precede the probe by a ldb access check.
--- arch/parisc/include/asm/special_insns.h | 28 ++++++++++++++++++++++++++++ arch/parisc/lib/memcpy.c | 19 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-)
arch/parisc/include/asm/special_insns.h +28 -0
@@ -32,6 +32,34 @@ pa; \ }) +/** +* prober_user() - Probe user read access +* @sr: Space regster. +* @va: Virtual address. +* +* Return: Non-zero if address is accessible. +* +* Due to the way _PAGE_READ is handled in TLB entries, we need +* a special check to determine whether a user address is accessible. +* The ldb instruction does the initial access check. If it is +* successful, the probe instruction checks user access rights. +*/ +#define prober_user (sr, va) ({ \ + unsigned long read_allowed; \ + __asm__ __volatile__( \ + "copy %%r0,%0\n" \ + "8:\tldb 0(%%sr%1,%2),%%r0\n" \ + "\tproberi (%%sr%1,%2),%3,%0\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ + "or %%r0,%%r0,%%r0") \ + : "=&r" (read_allowed) \ + : "i" (sr), "r" (va), "i" (PRIV_USER) \ + : "memory" \ + ); \ + read_allowed; \ +}) +#define CR_EIEM 15/* External Interrupt Enable Mask */ #define CR_CR16 16/* CR16 Interval Timer */ #define CR_EIRR 23/* External Interrupt Request Register */
arch/parisc/lib/memcpy.c +18 -1
@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/compiler.h> #include <linux/uaccess.h> +#include <linux/mm.h> #define get_user_space () mfsp(SR_USER)#define get_kernel_space () SR_KERNEL
@@ -32,9 +33,25 @@ EXPORT_SYMBOL(raw_copy_to_user);unsigned long raw_copy_from_user (void *dst,const void __user *src,unsigned long len) { +unsigned long start = (unsigned long ) src; +unsigned long end = start + len; +unsigned long newlen = len; +mtsp (get_user_space (),SR_TEMP1 );mtsp (get_kernel_space (),SR_TEMP2 ); -return pa_memcpy (dst, (void __force *)src, len); + +/* Check region is user accessible */ +if (start) +while (start < end) { +if (!prober_user (SR_TEMP1 , start)) { + newlen = (start - (unsigned long ) src); +break ; + } + start +=PAGE_SIZE ; +/* align to page boundry which may have different permission */ + start =PAGE_ALIGN_DOWN (start); + } +return len - newlen +pa_memcpy (dst, (void __force *)src, newlen); }EXPORT_SYMBOL (raw_copy_from_user);
Greg Kroah-Hartman
maintainerPATCH 314/482 parisc: Makefile: explain that 64BIT requires both 32-bit and 64-bit compilers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
commit 305ab0a748c52eeaeb01d8cff6408842d19e5cb5 upstream.
For building a 64-bit kernel, both 32-bit and 64-bit VDSO binaries are built, so both 32-bit and 64-bit compilers (and tools) should be in the PATH environment variable.
--- arch/parisc/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/parisc/Makefile +3 -1
@@ -39,7 +39,9 @@ endif export LD_BFD -# Set default 32 bits cross compilers for vdso +# Set default 32 bits cross compilers for vdso. +# This means that for 64BIT, both the 64-bit tools and the 32-bit tools +# need to be in the path. CC_ARCHES_32 = hppa hppa2.0 hppa1.1 CC_SUFFIXES = linux linux-gnu unknown-linux-gnu suse-linux CROSS32_COMPILE := $(call cc-cross-prefix, \
Greg Kroah-Hartman
maintainerPATCH 315/482 parisc: Revise __get_user() to probe user read access
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John David Anglin <[email protected]>
commit 89f686a0fb6e473a876a9a60a13aec67a62b9a7e upstream.
Because of the way read access support is implemented, read access interruptions are only triggered at privilege levels 2 and 3. The kernel executes at privilege level 0, so __get_user() never triggers a read access interruption (code 26). Thus, it is currently possible for user code to access a read protected address via a system call.
Fix this by probing read access rights at privilege level 3 (PRIV_USER) and setting __gu_err to -EFAULT (-14) if access isn't allowed.
Note the cmpiclr instruction does a 32-bit compare because COND macro doesn't work inside asm.
--- arch/parisc/include/asm/uaccess.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
arch/parisc/include/asm/uaccess.h +18 -3
@@ -42,9 +42,24 @@ __gu_err; \ }) -#define __get_user (val, ptr) \ -({ \ - __get_user_internal(SR_USER, val, ptr); \ +#define __probe_user_internal (sr, error, ptr) \ +({ \ + __asm__("\tproberi (%%sr%1,%2),%3,%0\n" \ + "\tcmpiclr,= 1,%0,%0\n" \ + "\tldi %4,%0\n" \ + : "=r"(error) \ + : "i"(sr), "r"(ptr), "i"(PRIV_USER), \ + "i"(-EFAULT)); \ +}) + +#define __get_user (val, ptr) \ +({ \ + register long __gu_err; \ + \ + __gu_err = __get_user_internal(SR_USER, val, ptr); \ + if (likely(!__gu_err)) \ + __probe_user_internal(SR_USER, __gu_err, ptr); \ + __gu_err; \ })#define __get_user_asm (sr, val, ldx, ptr) \
Greg Kroah-Hartman
maintainerPATCH 316/482 parisc: Revise gateway LWS calls to probe user read access
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John David Anglin <[email protected]>
commit f6334f4ae9a4e962ba74b026e1d965dfdf8cbef8 upstream.
We use load and stbys,e instructions to trigger memory reference interruptions without writing to memory. Because of the way read access support is implemented, read access interruptions are only triggered at privilege levels 2 and 3. The kernel and gateway page execute at privilege level 0, so this code never triggers a read access interruption. Thus, it is currently possible for user code to execute a LWS compare and swap operation at an address that is read protected at privilege level 3 (PRIV_USER).
Fix this by probing read access rights at privilege level 3 and branching to lws_fault if access isn't allowed.
--- arch/parisc/kernel/syscall.S | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
arch/parisc/kernel/syscall.S +21 -9
@@ -600,6 +600,9 @@ lws_compare_and_swap32: lws_compare_and_swap: /* Trigger memory reference interruptions without writing to memory */ 1: ldw 0(%r26), %r28 + proberi (%r26), PRIV_USER, %r28 + comb,=,n %r28, %r0, lws_fault /* backwards, likely not taken */ + nop 2: stbys,e %r0, 0(%r26) /* Calculate 8-bit hash index from virtual address */
@@ -753,6 +756,9 @@ cas2_lock_start: copy %r26, %r28 depi_safe 0, 31, 2, %r28 10: ldw 0(%r28), %r1 + proberi (%r28), PRIV_USER, %r1 + comb,=,n %r1, %r0, lws_fault /* backwards, likely not taken */ + nop 11: stbys,e %r0, 0(%r28) /* Calculate 8-bit hash index from virtual address */
@@ -936,41 +942,47 @@ atomic_xchg_begin: /* 8-bit exchange */ 1: ldb 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop copy %r23, %r20 depi_safe 0, 31, 2, %r20 b atomic_xchg_start 2: stbys,e %r0, 0(%r20) - nop - nop - nop /* 16-bit exchange */ 3: ldh 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop copy %r23, %r20 depi_safe 0, 31, 2, %r20 b atomic_xchg_start 4: stbys,e %r0, 0(%r20) - nop - nop - nop /* 32-bit exchange */ 5: ldw 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop b atomic_xchg_start 6: stbys,e %r0, 0(%r23) nop nop - nop - nop - nop /* 64-bit exchange */ #ifdef CONFIG_64BIT 7: ldd 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop 8: stdby,e %r0, 0(%r23) #else 7: ldw 0(%r24), %r20 8: ldw 4(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop copy %r23, %r20 depi_safe 0, 31, 2, %r20 9: stbys,e %r0, 0(%r20)
Greg Kroah-Hartman
maintainerPATCH 317/482 parisc: Try to fixup kernel exception in bad_area_nosemaphore path of do_page_fault()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John David Anglin <[email protected]>
commit f92a5e36b0c45cd12ac0d1bc44680c0dfae34543 upstream.
--- arch/parisc/mm/fault.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/parisc/mm/fault.c +4 -0
@@ -358,6 +358,10 @@ bad_area:mmap_read_unlock (mm); bad_area_nosemaphore: +if (!user_mode (regs) &&fixup_exception (regs)) { +return ; + } +if (user_mode (regs)) {int signo, si_code;
Greg Kroah-Hartman
maintainerPATCH 318/482 parisc: Update comments in make_insert_tlb
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: John David Anglin <[email protected]>
commit cb22f247f371bd206a88cf0e0c05d80b8b62fb26 upstream.
The following testcase exposed a problem with our read access checks in get_user() and raw_copy_from_user():
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
unsigned long page_size = sysconf(_SC_PAGESIZE); char *p = malloc(3 * page_size);
char *p_aligned;
/* initialize memory region. If not initialized, write syscall below will correctly return EFAULT. */ if (1)
memset(p, 'X', 3 * page_size);
p_aligned = (char *) ((((uintptr_t) p) + (2*page_size - 1)) & ~(page_size - 1)); /* Drop PROT_READ protection. Kernel and userspace should fault when accessing that memory region */ mprotect(p_aligned, page_size, PROT_NONE);
/* the following write() should return EFAULT, since PROT_READ was dropped by previous mprotect() */ int ret = write(2, p_aligned, 1);
if (!ret || errno != EFAULT)
printf("\n FAILURE: write() did not returned expected EFAULT value\n"); return 0;
}
Because of the way _PAGE_READ is handled, kernel code never generates a read access fault when it access a page as the kernel privilege level is always less than PL1 in the PTE.
This patch reworks the comments in the make_insert_tlb macro to try to make this clearer.
--- arch/parisc/kernel/entry.S | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
arch/parisc/kernel/entry.S +12 -5
@@ -486,6 +486,12 @@ * this happens is quite subtle, read below */ .macro make_insert_tlb spc,pte,prot,tmp space_to_prot \spc \prot /* create prot id from space */ + +#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT + /* need to drop DMB bit, as it's used as SPECIAL flag */ + depi 0,_PAGE_SPECIAL_BIT,1,\pte +#endif + /* The following is the real subtlety. This is depositing * T <-> _PAGE_REFTRAP * D <-> _PAGE_DIRTY
@@ -498,17 +504,18 @@ * Finally, _PAGE_READ goes in the top bit of PL1 (so we * trigger an access rights trap in user space if the user * tries to read an unreadable page */ -#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT - /* need to drop DMB bit, as it's used as SPECIAL flag */ - depi 0,_PAGE_SPECIAL_BIT,1,\pte -#endif depd \pte,8,7,\prot /* PAGE_USER indicates the page can be read with user privileges, * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1 - * contains _PAGE_READ) */ + * contains _PAGE_READ). While the kernel can't directly write + * user pages which have _PAGE_WRITE zero, it can read pages + * which have _PAGE_READ zero (PL <= PL1). Thus, the kernel + * exception fault handler doesn't trigger when reading pages + * that aren't user read accessible */ extrd,u,*= \pte,_PAGE_USER_BIT+32,1,%r0 depdi 7,11,3,\prot + /* If we're a gateway page, drop PL2 back to zero for promotion * to kernel privilege (so we can execute the page as kernel). * Any privilege promotion page always denys read and write */
Greg Kroah-Hartman
maintainerPATCH 319/482 media: gspca: Add bounds checking to firmware parser
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit aef89c0b2417da79cb2062a95476288f9f203ab0 upstream.
This sd_init() function reads the firmware. The firmware data holds a series of records and the function reads each record and sends the data to the device. The request_ihex_firmware() function
calls ihex_validate_fw() which ensures that the total length of all the records won't read out of bounds of the fw->data[].
However, a potential issue is if there is a single very large record (larger than PAGE_SIZE) and that would result in memory corruption. Generally we trust the firmware, but it's always better to double check.
--- drivers/media/usb/gspca/vicam.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/media/usb/gspca/vicam.c +8 -2
@@ -227,6 +227,7 @@ static int sd_init(struct gspca_dev *gspconst struct ihex_binrec *rec;const struct firmware *fw;u8 *firmware_buf; +int len; ret =request_ihex_firmware (&fw,VICAM_FIRMWARE , &gspca_dev->dev->dev);
@@ -241,9 +242,14 @@ static int sd_init(struct gspca_dev *gsp goto exit; }for (rec = (void *)fw->data; rec; rec =ihex_next_binrec (rec)) { -memcpy (firmware_buf, rec->data,be16_to_cpu (rec->len)); + len =be16_to_cpu (rec->len); +if (len >PAGE_SIZE ) { + ret = -EINVAL ; +break ; + } +memcpy (firmware_buf, rec->data, len); ret =vicam_control_msg (gspca_dev,0xff ,0 ,0 , firmware_buf, -be16_to_cpu (rec->len)); + len);if (ret <0 )break ; }
Greg Kroah-Hartman
maintainerPATCH 320/482 media: hi556: correct the test pattern configuration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bingbu Cao <[email protected]>
commit 020f602b068c9ce18d5056d02c8302199377d98d upstream.
Hynix hi556 support 8 test pattern modes:
hi556_test_pattern_menu[] = {
{
"Disabled",
"Solid Colour",
"100% Colour Bars",
"Fade To Grey Colour Bars",
"PN9",
"Gradient Horizontal",
"Gradient Vertical",
"Check Board",
"Slant Pattern",
}The test pattern is set by a 8-bit register according to the specification.
+--------+-------------------------------+ | BIT[0] | Solid color | +--------+-------------------------------+ | BIT[1] | Color bar | +--------+-------------------------------+ | BIT[2] | Fade to grey color bar | +--------+-------------------------------+ | BIT[3] | PN9 | +--------+-------------------------------+ | BIT[4] | Gradient horizontal | +--------+-------------------------------+ | BIT[5] | Gradient vertical | +--------+-------------------------------+ | BIT[6] | Check board | +--------+-------------------------------+ | BIT[7] | Slant pattern | +--------+-------------------------------+
Based on function above, current test pattern programming is wrong. This patch fixes it by 'BIT(pattern - 1)'. If pattern is 0, driver will disable the test pattern generation and set the pattern to 0.
--- drivers/media/i2c/hi556.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
drivers/media/i2c/hi556.c +15 -13
@@ -605,21 +605,23 @@ static int hi556_test_pattern(struct hi5int ret;u32 val; -if (pattern) { - ret =hi556_read_reg (hi556,HI556_REG_ISP , -HI556_REG_VALUE_08BIT , &val); -if (ret) -return ret; - - ret =hi556_write_reg (hi556,HI556_REG_ISP , -HI556_REG_VALUE_08BIT , - val |HI556_REG_ISP_TPG_EN ); -if (ret) -return ret; - } + ret =hi556_read_reg (hi556,HI556_REG_ISP , +HI556_REG_VALUE_08BIT , &val); +if (ret) +return ret; + + val = pattern ? (val |HI556_REG_ISP_TPG_EN ) : + (val & ~HI556_REG_ISP_TPG_EN ); + + ret =hi556_write_reg (hi556,HI556_REG_ISP , +HI556_REG_VALUE_08BIT , val); +if (ret) +return ret; + + val = pattern ?BIT (pattern -1 ) :0 ;return hi556_write_reg (hi556,HI556_REG_TEST_PATTERN , -HI556_REG_VALUE_08BIT , pattern); +HI556_REG_VALUE_08BIT , val); }static int hi556_set_ctrl (struct v4l2_ctrl *ctrl)
Greg Kroah-Hartman
maintainerPATCH 321/482 media: imx: fix a potential memory leak in imx_media_csc_scaler_device_init()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit fc5f8aec77704373ee804b5dba0e0e5029c0f180 upstream.
Add video_device_release() in label 'err_m2m' to release the memory allocated by video_device_alloc() and prevent potential memory leaks. Remove the reduntant code in label 'err_m2m'.
--- drivers/staging/media/imx/imx-media-csc-scaler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/imx/imx-media-csc-scaler.c +1 -1
@@ -914,7 +914,7 @@ imx_media_csc_scaler_device_init(structreturn &priv->vdev; err_m2m: -video_set_drvdata (vfd,NULL ); +video_device_release (vfd); err_vfd:kfree (priv);return ERR_PTR (ret);
Greg Kroah-Hartman
maintainerPATCH 322/482 media: vivid: fix wrong pixel_array control size
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit 3e43442d4994c9e1e202c98129a87e330f7faaed upstream.
The pixel_array control size was calculated incorrectly:
the dimensions were swapped (dims[0] should be the height), and the values should be the width or height divided by PIXEL_ARRAY_DIV and rounded up. So don't use roundup, but use DIV_ROUND_UP instead.
This bug is harmless in the sense that nothing will break, except that it consumes way too much memory for this control.
--- drivers/media/test-drivers/vivid/vivid-ctrls.c | 3 ++- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/media/test-drivers/vivid/vivid-ctrls.c +2 -1
@@ -238,7 +238,8 @@ static const struct v4l2_ctrl_config viv .min = 0x00, .max = 0xff, .step = 1, - .dims = { 640 / PIXEL_ARRAY_DIV, 360 / PIXEL_ARRAY_DIV }, + .dims = { DIV_ROUND_UP(360, PIXEL_ARRAY_DIV), + DIV_ROUND_UP(640, PIXEL_ARRAY_DIV) }, }; static const char * const vivid_ctrl_menu_strings[] = {
drivers/media/test-drivers/vivid/vivid-vid-cap.c +2 -2
@@ -475,8 +475,8 @@ void vivid_update_format_cap(struct viviif (keep_controls)return ; - dims[0 ] =roundup (dev->src_rect.width,PIXEL_ARRAY_DIV ); - dims[1 ] =roundup (dev->src_rect.height,PIXEL_ARRAY_DIV ); + dims[0 ] =DIV_ROUND_UP (dev->src_rect.height,PIXEL_ARRAY_DIV ); + dims[1 ] =DIV_ROUND_UP (dev->src_rect.width,PIXEL_ARRAY_DIV );v4l2_ctrl_modify_dimensions (dev->pixel_array, dims); }
Greg Kroah-Hartman
maintainerPATCH 323/482 media: v4l2-ctrls: Dont reset handlers error in v4l2_ctrl_handler_free()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
commit 5a0400aca5fa7c6b8ba456c311a460e733571c88 upstream.
It's a common pattern in drivers to free the control handler's resources and then return the handler's error code on drivers' error handling paths. Alas, the v4l2_ctrl_handler_free() function also zeroes the error field, effectively indicating successful return to the caller.
There's no apparent need to touch the error field while releasing the control handler's resources and cleaning up stale pointers. Not touching the handler's error field is a more certain way to address this problem than changing all the users, in which case the pattern would be likely to re-emerge in new drivers.
Do just that, don't touch the control handler's error field in v4l2_ctrl_handler_free().
--- drivers/media/v4l2-core/v4l2-ctrls-core.c | 1 - 1 file changed, 1 deletion(-)
drivers/media/v4l2-core/v4l2-ctrls-core.c +0 -1
@@ -1327,7 +1327,6 @@ void v4l2_ctrl_handler_free(struct v4l2_kvfree (hdl->buckets); hdl->buckets =NULL ; hdl->cached =NULL ; - hdl->error =0 ;mutex_unlock (hdl->lock);mutex_destroy (&hdl->_lock); }
Greg Kroah-Hartman
maintainerPATCH 324/482 media: usbtv: Lock resolution while streaming
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ludwig Disterhof <[email protected]>
commit 7e40e0bb778907b2441bff68d73c3eb6b6cd319f upstream.
When an program is streaming (ffplay) and another program (qv4l2) changes the TV standard from NTSC to PAL, the kernel crashes due to trying to copy to unmapped memory.
Changing from NTSC to PAL increases the resolution in the usbtv struct, but the video plane buffer isn't adjusted, so it overflows.
--- drivers/media/usb/usbtv/usbtv-video.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/media/usb/usbtv/usbtv-video.c +4 -0
@@ -73,6 +73,10 @@ static int usbtv_configure_for_norm(stru }if (params) { +if (vb2_is_busy (&usbtv->vb2q) && + (usbtv->width != params->cap_width || + usbtv->height != params->cap_height)) +return -EBUSY ; usbtv->width = params->cap_width; usbtv->height = params->cap_height; usbtv->n_chunks = usbtv->width * usbtv->height
Greg Kroah-Hartman
maintainerPATCH 325/482 media: rainshadow-cec: fix TOCTOU race condition in rain_interrupt()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
commit 7af160aea26c7dc9e6734d19306128cce156ec40 upstream.
In the interrupt handler rain_interrupt(), the buffer full check on rain->buf_len is performed before acquiring rain->buf_lock. This creates a Time-of-Check to Time-of-Use (TOCTOU) race condition, as rain->buf_len is concurrently accessed and modified in the work handler rain_irq_work_handler() under the same lock.
Multiple interrupt invocations can race, with each reading buf_len before it becomes full and then proceeding. This can lead to both interrupts attempting to write to the buffer, incrementing buf_len beyond its capacity (DATA_SIZE) and causing a buffer overflow.
Fix this bug by moving the spin_lock() to before the buffer full check. This ensures that the check and the subsequent buffer modification are performed atomically, preventing the race condition. An corresponding spin_unlock() is added to the overflow path to correctly release the lock.
This possible bug was found by an experimental static analysis tool developed by our team.
--- drivers/media/cec/usb/rainshadow/rainshadow-cec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/cec/usb/rainshadow/rainshadow-cec.c +2 -1
@@ -171,11 +171,12 @@ static irqreturn_t rain_interrupt(struct {struct rain *rain =serio_get_drvdata (serio); +spin_lock (&rain->buf_lock);if (rain->buf_len ==DATA_SIZE ) { +spin_unlock (&rain->buf_lock);dev_warn_once (rain->dev,"buffer overflow\n" );return IRQ_HANDLED ; } -spin_lock (&rain->buf_lock); rain->buf_len++; rain->buf[rain->buf_wr_idx] = data; rain->buf_wr_idx = (rain->buf_wr_idx +1 ) &0xff ;
Greg Kroah-Hartman
maintainerPATCH 326/482 media: ov2659: Fix memory leaks in ov2659_probe()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Shurong <[email protected]>
commit 76142b137b968d47b35cdd8d1dc924677d319c8b upstream.
ov2659_probe() doesn't properly free control handler resources in failure paths, causing memory leaks. Add v4l2_ctrl_handler_free() to prevent these memory leaks and reorder the ctrl_handler assignment for better code flow.
--- drivers/media/i2c/ov2659.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/i2c/ov2659.c +2 -1
@@ -1479,14 +1479,15 @@ static int ov2659_probe(struct i2c_clienV4L2_CID_TEST_PATTERN ,ARRAY_SIZE (ov2659_test_pattern_menu) -1 , 0, 0, ov2659_test_pattern_menu); - ov2659->sd.ctrl_handler = &ov2659->ctrls;if (ov2659->ctrls.error) {dev_err (&client->dev,"%s: control initialization error %d\n" , __func__, ov2659->ctrls.error); +v4l2_ctrl_handler_free (&ov2659->ctrls);return ov2659->ctrls.error; } + ov2659->sd.ctrl_handler = &ov2659->ctrls; sd = &ov2659->sd; client->flags |=I2C_CLIENT_SCCB ;#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
Greg Kroah-Hartman
maintainerPATCH 327/482 media: qcom: camss: cleanup media device allocated resource on error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Zapolskiy <[email protected]>
commit 69080ec3d0daba8a894025476c98ab16b5a505a4 upstream.
A call to media_device_init() requires media_device_cleanup() counterpart to complete cleanup and release any allocated resources.
This has been done in the driver .remove() right from the beginning, but error paths on .probe() shall also be fixed.
--- drivers/media/platform/qcom/camss/camss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/platform/qcom/camss/camss.c +3 -1
@@ -1658,7 +1658,7 @@ static int camss_probe(struct platform_d ret =v4l2_device_register (camss->dev, &camss->v4l2_dev);if (ret <0 ) {dev_err (dev,"Failed to register V4L2 device: %d\n" , ret); - goto err_genpd_cleanup; + goto err_media_device_cleanup; }v4l2_async_nf_init (&camss->notifier);
@@ -1710,6 +1710,8 @@ err_v4l2_device_unregister:v4l2_device_unregister (&camss->v4l2_dev);v4l2_async_nf_cleanup (&camss->notifier);pm_runtime_disable (dev); +err_media_device_cleanup: +media_device_cleanup (&camss->media_dev); err_genpd_cleanup:camss_genpd_cleanup (camss);
Greg Kroah-Hartman
maintainerPATCH 328/482 media: venus: Add a check for packet size after reading from shared memory
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vedang Nagar <[email protected]>
commit 49befc830daa743e051a65468c05c2ff9e8580e6 upstream.
Add a check to ensure that the packet size does not exceed the number of available words after reading the packet header from shared memory. This ensures that the size provided by the firmware is safe to process and prevent potential out-of-bounds memory access.
--- drivers/media/platform/qcom/venus/hfi_venus.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/media/platform/qcom/venus/hfi_venus.c +4 -0
@@ -239,6 +239,7 @@ static int venus_write_queue(struct venustatic int venus_read_queue (struct venus_hfi_device *hdev,struct iface_queue *queue,void *pkt,u32 *tx_req) { +struct hfi_pkt_hdr *pkt_hdr =NULL ;struct hfi_queue_header *qhdr;u32 dwords, new_rd_idx;u32 rd_idx, wr_idx, type, qsize;
@@ -304,6 +305,9 @@ static int venus_read_queue(struct venusmemcpy (pkt, rd_ptr, len);memcpy (pkt + len, queue->qmem.kva, new_rd_idx <<2 ); } + pkt_hdr = (struct hfi_pkt_hdr *)(pkt); +if ((pkt_hdr->size >>2 ) != dwords) +return -EINVAL ; }else {/* bad packet received, dropping */ new_rd_idx = qhdr->write_idx;
Greg Kroah-Hartman
maintainerPATCH 329/482 media: venus: hfi: explicitly release IRQ during teardown
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorge Ramirez-Ortiz <[email protected]>
commit 640803003cd903cea73dc6a86bf6963e238e2b3f upstream.
Ensure the IRQ is disabled - and all pending handlers completed - before dismantling the interrupt routing and clearing related pointers.
This prevents any possibility of the interrupt triggering after the handler context has been invalidated.
--- drivers/media/platform/qcom/venus/hfi_venus.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/qcom/venus/hfi_venus.c +1 -0
@@ -1711,6 +1711,7 @@ void venus_hfi_destroy(struct venus_corevenus_interface_queues_release (hdev);mutex_destroy (&hdev->lock);kfree (hdev); +disable_irq (core->irq); core->ops =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 330/482 media: venus: protect against spurious interrupts during probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorge Ramirez-Ortiz <[email protected]>
commit 3200144a2fa4209dc084a19941b9b203b43580f0 upstream.
Make sure the interrupt handler is initialized before the interrupt is registered.
If the IRQ is registered before hfi_create(), it's possible that an interrupt fires before the handler setup is complete, leading to a NULL dereference.
This error condition has been observed during system boot on Rb3Gen2.
--- drivers/media/platform/qcom/venus/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/media/platform/qcom/venus/core.c +4 -4
@@ -333,13 +333,13 @@ static int venus_probe(struct platform_dINIT_DELAYED_WORK (&core->work, venus_sys_error_handler);init_waitqueue_head (&core->sys_err_done); - ret =devm_request_threaded_irq (dev, core->irq, hfi_isr, venus_isr_thread, -IRQF_TRIGGER_HIGH |IRQF_ONESHOT , -"venus" , core); + ret =hfi_create (core, &venus_core_ops);if (ret) goto err_core_put; - ret =hfi_create (core, &venus_core_ops); + ret =devm_request_threaded_irq (dev, core->irq, hfi_isr, venus_isr_thread, +IRQF_TRIGGER_HIGH |IRQF_ONESHOT , +"venus" , core);if (ret) goto err_core_put;
Greg Kroah-Hartman
maintainerPATCH 331/482 media: venus: vdec: Clamp param smaller than 1fps and bigger than 240.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit 377dc500d253f0b26732b2cb062e89668aef890a upstream.
The driver uses "whole" fps in all its calculations (e.g. in load_per_instance()). Those calculation expect an fps bigger than 1, and not big enough to overflow.
Clamp the value if the user provides a param that will result in an invalid fps.
--- drivers/media/platform/qcom/venus/core.h | 2 ++ drivers/media/platform/qcom/venus/vdec.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/media/platform/qcom/venus/core.h +2 -0
@@ -28,6 +28,8 @@#define VIDC_PMDOMAINS_NUM_MAX 3#define VIDC_RESETS_NUM_MAX 2 +#define VENUS_MAX_FPS 240 +extern int venus_fw_debug;struct freq_tbl {
drivers/media/platform/qcom/venus/vdec.c +2 -3
@@ -458,11 +458,10 @@ static int vdec_s_parm(struct file *file us_per_frame = timeperframe->numerator * (u64 )USEC_PER_SEC ;do_div (us_per_frame, timeperframe->denominator); -if (!us_per_frame) -return -EINVAL ; - + us_per_frame =clamp (us_per_frame,1 ,USEC_PER_SEC ); fps = (u64 )USEC_PER_SEC ;do_div (fps, us_per_frame); + fps =min (VENUS_MAX_FPS , fps); inst->fps = fps; inst->timeperframe = *timeperframe;
Greg Kroah-Hartman
maintainerPATCH 332/482 media: venus: venc: Clamp param smaller than 1fps and bigger than 240
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit 417c01b92ec278a1118a05c6ad8a796eaa0c9c52 upstream.
The driver uses "whole" fps in all its calculations (e.g. in load_per_instance()). Those calculation expect an fps bigger than 1, and not big enough to overflow.
Clamp the param if the user provides a value that will result in an invalid fps.
--- drivers/media/platform/qcom/venus/venc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/media/platform/qcom/venus/venc.c +2 -3
@@ -406,11 +406,10 @@ static int venc_s_parm(struct file *file us_per_frame = timeperframe->numerator * (u64 )USEC_PER_SEC ;do_div (us_per_frame, timeperframe->denominator); -if (!us_per_frame) -return -EINVAL ; - + us_per_frame =clamp (us_per_frame,1 ,USEC_PER_SEC ); fps = (u64 )USEC_PER_SEC ;do_div (fps, us_per_frame); + fps =min (VENUS_MAX_FPS , fps); inst->timeperframe = *timeperframe; inst->fps = fps;
Greg Kroah-Hartman
maintainerPATCH 333/482 drm/amd: Restore cached power limit during resume
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit ed4efe426a49729952b3dc05d20e33b94409bdd1 upstream.
The power limit will be cached in smu->current_power_limit but if the ASIC goes into S3 this value won't be restored.
Restore the value during SMU resume.
--- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +6 -0
@@ -1738,6 +1738,12 @@ static int smu_resume(void *handle) adev->pm.dpm_enabled = true; +if (smu->current_power_limit) { + ret =smu_set_power_limit (smu, smu->current_power_limit); +if (ret && ret != -EOPNOTSUPP ) +return ret; + } +dev_info (adev->dev,"SMU is resumed successfully!\n" );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 334/482 drm/amdgpu: Avoid extra evict-restore process.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gang Ba <[email protected]>
commit 1f02f2044bda1db1fd995bc35961ab075fa7b5a2 upstream.
If vm belongs to another process, this is fclose after fork,
wait may enable signaling KFD eviction fence and cause parent process queue evicted.
[677852.634569] amdkfd_fence_enable_signaling+0x56/0x70 [amdgpu] [677852.634814] __dma_fence_enable_signaling+0x3e/0xe0 [677852.634820] dma_fence_wait_timeout+0x3a/0x140 [677852.634825] amddma_resv_wait_timeout+0x7f/0xf0 [amdkcl] [677852.634831] amdgpu_vm_wait_idle+0x2d/0x60 [amdgpu] [677852.635026] amdgpu_flush+0x34/0x50 [amdgpu] [677852.635208] filp_flush+0x38/0x90 [677852.635213] filp_close+0x14/0x30 [677852.635216] do_close_on_exec+0xdd/0x130 [677852.635221] begin_new_exec+0x1da/0x490 [677852.635225] load_elf_binary+0x307/0xea0 [677852.635231] ? srso_alias_return_thunk+0x5/0xfbef5 [677852.635235] ? ima_bprm_check+0xa2/0xd0 [677852.635240] search_binary_handler+0xda/0x260 [677852.635245] exec_binprm+0x58/0x1a0 [677852.635249] bprm_execve.part.0+0x16f/0x210 [677852.635254] bprm_execve+0x45/0x80 [677852.635257] do_execveat_common.isra.0+0x190/0x200
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +2 -4
@@ -2024,13 +2024,11 @@ void amdgpu_vm_adjust_size(struct amdgpu*/ long amdgpu_vm_wait_idle (struct amdgpu_vm *vm,long timeout) { - timeout =dma_resv_wait_timeout (vm->root.bo->tbo.base.resv, -DMA_RESV_USAGE_BOOKKEEP , - true, timeout); + timeout =drm_sched_entity_flush (&vm->immediate, timeout);if (timeout <=0 )return timeout; -return dma_fence_wait_timeout (vm->last_unlocked, true, timeout); +return drm_sched_entity_flush (&vm->delayed, timeout); }/**
Greg Kroah-Hartman
maintainerPATCH 335/482 drm/amdgpu: update mmhub 3.0.1 client id mappings
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 0bae62cc989fa99ac9cb564eb573aad916d1eb61 upstream.
Update the client id mapping so the correct clients get printed when there is a mmhub page fault.
--- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c | 57 ++++++++++++++++-------------- 1 file changed, 32 insertions(+), 25 deletions(-)
drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c +32 -25
@@ -36,40 +36,47 @@static const char *mmhub_client_ids_v3_0_1[][2 ] = { [0 ][0 ] ="VMC" , + [1 ][0 ] ="ISPXT" , + [2 ][0 ] ="ISPIXT" , [4 ][0 ] ="DCEDMC" , [5 ][0 ] ="DCEVGA" , [6 ][0 ] ="MP0" , [7 ][0 ] ="MP1" , - [8 ][0 ] ="MPIO" , - [16 ][0 ] ="HDP" , - [17 ][0 ] ="LSDMA" , - [18 ][0 ] ="JPEG" , - [19 ][0 ] ="VCNU0" , - [21 ][0 ] ="VSCH" , - [22 ][0 ] ="VCNU1" , - [23 ][0 ] ="VCN1" , - [32 +20 ][0 ] ="VCN0" , - [2 ][1 ] ="DBGUNBIO" , + [8 ][0 ] ="MPM" , + [12 ][0 ] ="ISPTNR" , + [14 ][0 ] ="ISPCRD0" , + [15 ][0 ] ="ISPCRD1" , + [16 ][0 ] ="ISPCRD2" , + [22 ][0 ] ="HDP" , + [23 ][0 ] ="LSDMA" , + [24 ][0 ] ="JPEG" , + [27 ][0 ] ="VSCH" , + [28 ][0 ] ="VCNU" , + [29 ][0 ] ="VCN" , + [1 ][1 ] ="ISPXT" , + [2 ][1 ] ="ISPIXT" , [3 ][1 ] ="DCEDWB" , [4 ][1 ] ="DCEDMC" , [5 ][1 ] ="DCEVGA" , [6 ][1 ] ="MP0" , [7 ][1 ] ="MP1" , - [8 ][1 ] ="MPIO" , - [10 ][1 ] ="DBGU0" , - [11 ][1 ] ="DBGU1" , - [12 ][1 ] ="DBGU2" , - [13 ][1 ] ="DBGU3" , - [14 ][1 ] ="XDP" , - [15 ][1 ] ="OSSSYS" , - [16 ][1 ] ="HDP" , - [17 ][1 ] ="LSDMA" , - [18 ][1 ] ="JPEG" , - [19 ][1 ] ="VCNU0" , - [20 ][1 ] ="VCN0" , - [21 ][1 ] ="VSCH" , - [22 ][1 ] ="VCNU1" , - [23 ][1 ] ="VCN1" , + [8 ][1 ] ="MPM" , + [10 ][1 ] ="ISPMWR0" , + [11 ][1 ] ="ISPMWR1" , + [12 ][1 ] ="ISPTNR" , + [13 ][1 ] ="ISPSWR" , + [14 ][1 ] ="ISPCWR0" , + [15 ][1 ] ="ISPCWR1" , + [16 ][1 ] ="ISPCWR2" , + [17 ][1 ] ="ISPCWR3" , + [18 ][1 ] ="XDP" , + [21 ][1 ] ="OSSSYS" , + [22 ][1 ] ="HDP" , + [23 ][1 ] ="LSDMA" , + [24 ][1 ] ="JPEG" , + [27 ][1 ] ="VSCH" , + [28 ][1 ] ="VCNU" , + [29 ][1 ] ="VCN" , }; static uint32_t mmhub_v3_0_1_get_invalidate_req(unsigned int vmid,
Greg Kroah-Hartman
maintainerPATCH 336/482 drm/amdkfd: Destroy KFD debugfs after destroy KFD wq
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amber Lin <[email protected]>
commit 2e58401a24e7b2d4ec619104e1a76590c1284a4c upstream.
Since KFD proc content was moved to kernel debugfs, we can't destroy KFD debugfs before kfd_process_destroy_wq. Move kfd_process_destroy_wq prior to kfd_debugfs_fini to fix a kernel NULL pointer problem. It happens when /sys/kernel/debug/kfd was already destroyed in kfd_debugfs_fini but kfd_process_destroy_wq calls kfd_debugfs_remove_process. This line
debugfs_remove_recursive(entry->proc_dentry);
tries to remove /sys/kernel/debug/kfd/proc/<pid> while /sys/kernel/debug/kfd is already gone. It hangs the kernel by kernel NULL pointer.
--- drivers/gpu/drm/amd/amdkfd/kfd_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/kfd_module.c +1 -1
@@ -78,8 +78,8 @@ err_ioctl:static void kfd_exit (void ) {kfd_cleanup_processes (); -kfd_debugfs_fini ();kfd_process_destroy_wq (); +kfd_debugfs_fini ();kfd_procfs_shutdown ();kfd_topology_shutdown ();kfd_chardev_exit ();
Greg Kroah-Hartman
maintainerPATCH 337/482 drm/amd/display: Dont overwrite dce60_clk_mgr
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 4db9cd554883e051df1840d4d58d636043101034 upstream.
dc_clk_mgr_create accidentally overwrites the dce60_clk_mgr with the dce_clk_mgr, causing incorrect behaviour on DCE6. Fix it by removing the extra dce_clk_mgr_construct.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 1 - 1 file changed, 1 deletion(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +0 -1
@@ -158,7 +158,6 @@ struct clk_mgr *dc_clk_mgr_create(struct return NULL; }dce60_clk_mgr_construct (ctx, clk_mgr); -dce_clk_mgr_construct (ctx, clk_mgr);return &clk_mgr->base; }#endif
Greg Kroah-Hartman
maintainerPATCH 338/482 net, hsr: reject HSR frame if skb cant hold tag
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Acs <[email protected]>
commit 7af76e9d18a9fd6f8611b3313c86c190f9b6a5a7 upstream.
Receiving HSR frame with insufficient space to hold HSR tag in the skb can result in a crash (kernel BUG):
[ 45.390915] skbuff: skb_under_panic: text:ffffffff86f32cac len:26 put:14 head:ffff888042418000 data:ffff888042417ff4 tail:0xe end:0x180 dev:bridge_slave_1 [ 45.392559] ------------[ cut here ]------------ [ 45.392912] kernel BUG at net/core/skbuff.c:211! [ 45.393276] Oops: invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN NOPTI [ 45.393809] CPU: 1 UID: 0 PID: 2496 Comm: reproducer Not tainted 6.15.0 #12 PREEMPT(undef) [ 45.394433] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 [ 45.395273] RIP: 0010:skb_panic+0x15b/0x1d0
<snip registers, remove unreliable trace>
[ 45.402911] Call Trace: [ 45.403105] <IRQ> [ 45.404470] skb_push+0xcd/0xf0 [ 45.404726] br_dev_queue_push_xmit+0x7c/0x6c0 [ 45.406513] br_forward_finish+0x128/0x260 [ 45.408483] __br_forward+0x42d/0x590 [ 45.409464] maybe_deliver+0x2eb/0x420 [ 45.409763] br_flood+0x174/0x4a0 [ 45.410030] br_handle_frame_finish+0xc7c/0x1bc0 [ 45.411618] br_handle_frame+0xac3/0x1230 [ 45.413674] __netif_receive_skb_core.constprop.0+0x808/0x3df0 [ 45.422966] __netif_receive_skb_one_core+0xb4/0x1f0 [ 45.424478] __netif_receive_skb+0x22/0x170 [ 45.424806] process_backlog+0x242/0x6d0 [ 45.425116] __napi_poll+0xbb/0x630 [ 45.425394] net_rx_action+0x4d1/0xcc0 [ 45.427613] handle_softirqs+0x1a4/0x580 [ 45.427926] do_softirq+0x74/0x90 [ 45.428196] </IRQ>
This issue was found by syzkaller.
The panic happens in br_dev_queue_push_xmit() once it receives a corrupted skb with ETH header already pushed in linear data. When it attempts the skb_push() call, there's not enough headroom and skb_push() panics.
The corrupted skb is put on the queue by HSR layer, which makes a sequence of unintended transformations when it receives a specific corrupted HSR frame (with incomplete TAG).
Fix it by dropping and consuming frames that are not long enough to contain both ethernet and hsr headers.
Alternative fix would be to check for enough headroom before skb_push() in br_dev_queue_push_xmit().
In the reproducer, this is injected via AF_PACKET, but I don't easily see why it couldn't be sent over the wire from adjacent network.
Further Details:
In the reproducer, the following network interface chain is set up:
┌────────────────┐ ┌────────────────┐
│ veth0_to_hsr ├───┤ hsr_slave0 ┼───┐
└────────────────┘ └────────────────┘ │
│ ┌──────┐
├─┤ hsr0 ├───┐
│ └──────┘ │
┌────────────────┐ ┌────────────────┐ │ │┌────────┐
│ veth1_to_hsr ┼───┤ hsr_slave1 ├───┘ └┤ │
└────────────────┘ └────────────────┘ ┌┼ bridge │
││ │
│└────────┘
│
┌───────┐ │
│ ... ├──────┘
└───────┘To trigger the events leading up to crash, reproducer sends a corrupted HSR frame with incomplete TAG, via AF_PACKET socket on 'veth0_to_hsr'.
The first HSR-layer function to process this frame is hsr_handle_frame(). It and then checks if the
protocol is ETH_P_PRP or ETH_P_HSR. If it is, it calls skb_set_network_header(skb, ETH_HLEN + HSR_HLEN), without checking that the skb is long enough. For the crashing frame it is not, and hence the skb->network_header and skb->mac_len fields are set incorrectly, pointing after the end of the linear buffer.
I will call this a BUG#1 and it is what is addressed by this patch. In the crashing scenario before the fix, the skb continues to go down the hsr path as follows.
hsr_handle_frame() then calls this sequencehsr_forward_skb()
fill_frame_info()
hsr->proto_ops->fill_frame_info()
hsr_fill_frame_info()hsr_fill_frame_info() contains a check that intends to check whether the skb actually contains the HSR header. But the check relies on the skb->mac_len field which was erroneously setup due to BUG#1, so the check passes and the execution continues back in the hsr_forward_skb():
hsr_forward_skb()
hsr_forward_do()
hsr->proto_ops->get_untagged_frame()
hsr_get_untagged_frame()
create_stripped_skb_hsr()In create_stripped_skb_hsr(), a copy of the skb is created and is further corrupted by operation that attempts to strip the HSR tag in a call to __pskb_copy().
The skb enters create_stripped_skb_hsr() with ethernet header pushed in linear buffer. The skb_pull(skb_in, HSR_HLEN) thus pulls 6 bytes of ethernet header into the headroom, creating skb_in with a headroom of size 8. The subsequent __pskb_copy() then creates an skb with headroom of just 2 and skb->len of just 12, this is how it looks after the copy:
gdb) p skb->len
$10 = 12
(gdb) p skb->data
$11 = (unsigned char *) 0xffff888041e45382 "\252\252\252\252\252!\210\373", (gdb) p skb->head
$12 = (unsigned char *) 0xffff888041e45380 ""
It seems create_stripped_skb_hsr() assumes that ETH header is pulled in the headroom when it's entered, because it just pulls HSR header on top. But that is not the case in our code-path and we end up with the corrupted skb instead. I will call this BUG#2
*I got confused here because it seems that under no conditions can create_stripped_skb_hsr() work well, the assumption it makes is not true during the processing of hsr frames - since the skb_push() in hsr_handle_frame to skb_pull in hsr_deliver_master(). I wonder whether I missed something here.*
Next, the execution arrives in hsr_deliver_master(). It calls skb_pull(ETH_HLEN), which just returns NULL - the SKB does not have enough space for the pull (as it only has 12 bytes in total at this point).
*The skb_pull() here further suggests that ethernet header is meant to be pushed through the whole hsr processing and create_stripped_skb_hsr() should pull it before doing the HSR header pull.*
hsr_deliver_master() then puts the corrupted skb on the queue, it is then picked up from there by bridge frame handling layer and finally lands in br_dev_queue_push_xmit where it panics.
--- net/hsr/hsr_slave.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/hsr/hsr_slave.c +7 -1
@@ -62,8 +62,14 @@ static rx_handler_result_t hsr_handle_frskb_push (skb,ETH_HLEN );skb_reset_mac_header (skb);if ((!hsr->prot_version && protocol ==htons (ETH_P_PRP )) || - protocol ==htons (ETH_P_HSR )) + protocol ==htons (ETH_P_HSR )) { +if (!pskb_may_pull (skb,ETH_HLEN +HSR_HLEN )) { +kfree_skb (skb); + goto finish_consume; + } +skb_set_network_header (skb,ETH_HLEN +HSR_HLEN ); + }skb_reset_mac_len (skb);hsr_forward_skb (skb, port);
Greg Kroah-Hartman
maintainerPATCH 339/482 ipv6: sr: Fix MAC comparison to be constant-time
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit a458b2902115b26a25d67393b12ddd57d1216aaa upstream.
To prevent timing attacks, MACs need to be compared in constant time. Use the appropriate helper function for this.
--- net/ipv6/seg6_hmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/seg6_hmac.c +2 -1
@@ -35,6 +35,7 @@#include <net/xfrm.h> #include <crypto/hash.h> +#include <crypto/algapi.h> #include <net/seg6.h> #include <net/genetlink.h> #include <net/seg6_hmac.h>
@@ -269,7 +270,7 @@ bool seg6_hmac_validate_skb(struct sk_buif (seg6_hmac_compute (hinfo, srh, &ipv6_hdr (skb)->saddr, hmac_output))return false; -if (memcmp (hmac_output, tlv->hmac,SEG6_HMAC_FIELD_LEN ) !=0 ) +if (crypto_memneq (hmac_output, tlv->hmac,SEG6_HMAC_FIELD_LEN ))return false;return true;
Greg Kroah-Hartman
maintainerPATCH 340/482 ACPI: pfr_update: Fix the driver update version check
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yu <[email protected]>
commit 8151320c747efb22d30b035af989fed0d502176e upstream.
The security-version-number check should be used rather than the runtime version check for driver updates.
Otherwise, the firmware update would fail when the update binary had a lower runtime version number than the current one.
--- drivers/acpi/pfr_update.c | 2 +- include/uapi/linux/pfrut.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/acpi/pfr_update.c +1 -1
@@ -310,7 +310,7 @@ static bool applicable_image(const voidif (type ==PFRU_CODE_INJECT_TYPE )return payload_hdr->rt_ver >= cap->code_rt_version; -return payload_hdr->rt_ver >= cap->drv_rt_version; +return payload_hdr->svn_ver >= cap->drv_svn; } static void print_update_debug_info(struct pfru_updated_result *result,
include/uapi/linux/pfrut.h +1 -0
@@ -89,6 +89,7 @@ struct pfru_payload_hdr {__u32 hw_ver;__u32 rt_ver;__u8 platform_id[16 ]; +__u32 svn_ver; };enum pfru_dsm_status {
Greg Kroah-Hartman
maintainerPATCH 341/482 mptcp: drop skb if MPTCP skb extension allocation fails
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Paasch <[email protected]>
commit ccab044697980c6c01ab51f43f48f13b8a3e5c33 upstream.
When skb_ext_add(skb, SKB_EXT_MPTCP) fails in mptcp_incoming_options(), we used to return true, letting the segment proceed through the TCP receive path without a DSS mapping. Such segments can leave inconsistent mapping state and trigger a mid-stream fallback to TCP, which in testing collapsed (by artificially forcing failures in skb_ext_add) throughput to zero.
Return false instead so the TCP input path drops the skb (see tcp_data_queue() and step-7 processing). This is the safer choice under memory pressure: it preserves MPTCP correctness and provides backpressure to the sender.
Control packets remain unaffected: ACK updates and DATA_FIN handling happen before attempting the extension allocation, and tcp_reset() continues to ignore the return value.
With this change, MPTCP continues to work at high throughput if we artificially inject failures into skb_ext_add.
--- net/mptcp/options.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/mptcp/options.c +4 -2
@@ -1100,7 +1100,9 @@ static bool add_addr_hmac_valid(struct mreturn hmac == mp_opt->ahmac; } -/* Return false if a subflow has been reset, else return true */ +/* Return false in case of error (or subflow has been reset), +* else return true. +*/ bool mptcp_incoming_options (struct sock *sk,struct sk_buff *skb) {struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (sk);
@@ -1198,7 +1200,7 @@ bool mptcp_incoming_options(struct sock mpext =skb_ext_add (skb,SKB_EXT_MPTCP );if (!mpext) -return true; +return false;memset (mpext,0 ,sizeof (*mpext));
Greg Kroah-Hartman
maintainerPATCH 342/482 mptcp: pm: kernel: flush: do not reset ADD_ADDR limit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 68fc0f4b0d25692940cdc85c68e366cae63e1757 upstream.
A flush of the MPTCP endpoints should not affect the MPTCP limits. In other words, 'ip mptcp endpoint flush' should not change 'ip mptcp limits'.
But it was the case: the MPTCP_PM_ATTR_RCV_ADD_ADDRS (add_addr_accepted) limit was reset by accident. Removing the reset of this counter during a flush fixes this issue.
--- net/mptcp/pm_netlink.c | 1 - 1 file changed, 1 deletion(-)
net/mptcp/pm_netlink.c +0 -1
@@ -1778,7 +1778,6 @@ static void __flush_addrs(struct list_hestatic void __reset_counters (struct pm_nl_pernet *pernet) {WRITE_ONCE (pernet->add_addr_signal_max,0 ); -WRITE_ONCE (pernet->add_addr_accept_max,0 );WRITE_ONCE (pernet->local_addr_max,0 ); pernet->addrs =0 ; }
Greg Kroah-Hartman
maintainerPATCH 343/482 f2fs: fix to do sanity check on ino and xnid
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 061cf3a84bde038708eb0f1d065b31b7c2456533 ]
syzbot reported a f2fs bug as below:
INFO: task syz-executor140:5308 blocked for more than 143 seconds.
Not tainted 6.14.0-rc7-syzkaller-00069-g81e4f8d68c66 #0
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:syz-executor140 state:D stack:24016 pid:5308 tgid:5308 ppid:5306 task_flags:0x400140 flags:0x00000006
Call Trace:
<TASK>
context_switch kernel/sched/core.c:5378 [inline]
__schedule+0x190e/0x4c90 kernel/sched/core.c:6765
__schedule_loop kernel/sched/core.c:6842 [inline]
schedule+0x14b/0x320 kernel/sched/core.c:6857
io_schedule+0x8d/0x110 kernel/sched/core.c:7690
folio_wait_bit_common+0x839/0xee0 mm/filemap.c:1317
__folio_lock mm/filemap.c:1664 [inline]
folio_lock include/linux/pagemap.h:1163 [inline]
__filemap_get_folio+0x147/0xb40 mm/filemap.c:1917
pagecache_get_page+0x2c/0x130 mm/folio-compat.c:87
find_get_page_flags include/linux/pagemap.h:842 [inline]
f2fs_grab_cache_page+0x2b/0x320 fs/f2fs/f2fs.h:2776
__get_node_page+0x131/0x11b0 fs/f2fs/node.c:1463
read_xattr_block+0xfb/0x190 fs/f2fs/xattr.c:306
lookup_all_xattrs fs/f2fs/xattr.c:355 [inline]
f2fs_getxattr+0x676/0xf70 fs/f2fs/xattr.c:533
__f2fs_get_acl+0x52/0x870 fs/f2fs/acl.c:179
f2fs_acl_create fs/f2fs/acl.c:375 [inline]
f2fs_init_acl+0xd7/0x9b0 fs/f2fs/acl.c:418
f2fs_init_inode_metadata+0xa0f/0x1050 fs/f2fs/dir.c:539
f2fs_add_inline_entry+0x448/0x860 fs/f2fs/inline.c:666
f2fs_add_dentry+0xba/0x1e0 fs/f2fs/dir.c:765
f2fs_do_add_link+0x28c/0x3a0 fs/f2fs/dir.c:808
f2fs_add_link fs/f2fs/f2fs.h:3616 [inline]
f2fs_mknod+0x2e8/0x5b0 fs/f2fs/namei.c:766
vfs_mknod+0x36d/0x3b0 fs/namei.c:4191
unix_bind_bsd net/unix/af_unix.c:1286 [inline]
unix_bind+0x563/0xe30 net/unix/af_unix.c:1379
__sys_bind_socket net/socket.c:1817 [inline]
__sys_bind+0x1e4/0x290 net/socket.c:1848
__do_sys_bind net/socket.c:1853 [inline]
__se_sys_bind net/socket.c:1851 [inline]
__x64_sys_bind+0x7a/0x90 net/socket.c:1851
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7fLet's dump and check metadata of corrupted inode, it shows its xattr_nid is the same to its i_ino.
dump.f2fs -i 3 chaseyu.img.rawi_xattr_nid [0x 3 : 3]
So that, during mknod in the corrupted directory, it tries to get and lock inode page twice, result in deadlock.
- f2fs_mknod
- f2fs_add_inline_entry
- f2fs_get_inode_page --- lock dir's inode page
- f2fs_init_acl
- f2fs_acl_create(dir,..)
- __f2fs_get_acl
- f2fs_getxattr
- lookup_all_xattrs
- __get_node_page --- try to lock dir's inode page
In order to fix this, let's add sanity check on ino and xnid.
--- fs/f2fs/inode.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/f2fs/inode.c +7 -0
@@ -210,6 +210,13 @@ static bool sanity_check_inode(struct inreturn false; } +if (ino_of_node (node_page) == fi->i_xattr_nid) { +set_sbi_flag (sbi,SBI_NEED_FSCK ); +f2fs_warn (sbi,"%s: corrupted inode i_ino=%lx, xnid=%x, run fsck to fix." , + __func__, inode->i_ino, fi->i_xattr_nid); +return false; + } +if (f2fs_sb_has_flexible_inline_xattr (sbi) && !f2fs_has_extra_attr (inode)) {set_sbi_flag (sbi,SBI_NEED_FSCK );
Greg Kroah-Hartman
maintainerPATCH 344/482 iio: hid-sensor-prox: Restore lost scale assignments
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Lixu <[email protected]>
[ Upstream commit 83ded7cfaccccd2f4041769c313b58b4c9e265ad ]
The variables scale_pre_decml, scale_post_decml, and scale_precision were assigned in commit d68c592e02f6 ("iio: hid-sensor-prox: Fix scale not correct issue"), but due to a merge conflict in
commit 9c15db92a8e5 ("Merge tag 'iio-for-5.13a' of
https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next"), these assignments were lost.
Add back lost assignments and replace st->prox_attr with st->prox_attr[0] because commit 596ef5cf654b ("iio: hid-sensor-prox: Add support for more channels") changed prox_attr to an array.
--- drivers/iio/light/hid-sensor-prox.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/iio/light/hid-sensor-prox.c +5 -0
@@ -222,6 +222,11 @@ static int prox_parse_report(struct platdev_dbg (&pdev->dev,"prox %x:%x\n" , st->prox_attr.index, st->prox_attr.report_id); + st->scale_precision =hid_sensor_format_scale (hsdev->usage, + &st->prox_attr, + &st->scale_pre_decml, + &st->scale_post_decml); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 345/482 iio: hid-sensor-prox: Fix incorrect OFFSET calculation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Lixu <[email protected]>
[ Upstream commit 79dabbd505210e41c88060806c92c052496dd61c ]
The OFFSET calculation in the prox_read_raw() was incorrectly using the unit exponent, which is intended for SCALE calculations.
Remove the incorrect OFFSET calculation and set it to a fixed value of 0.
--- drivers/iio/light/hid-sensor-prox.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/light/hid-sensor-prox.c +1 -2
@@ -103,8 +103,7 @@ static int prox_read_raw(struct iio_dev ret_type = prox_state->scale_precision;break ;case IIO_CHAN_INFO_OFFSET : - *val =hid_sensor_convert_exponent ( - prox_state->prox_attr.unit_expo); + *val =0 ; ret_type =IIO_VAL_INT ;break ;case IIO_CHAN_INFO_SAMP_FREQ :
Greg Kroah-Hartman
maintainerPATCH 346/482 perf/x86/intel: Fix crash in icl_update_topdown_event()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
[ Upstream commit b0823d5fbacb1c551d793cbfe7af24e0d1fa45ed ]
The perf_fuzzer found a hard-lockup crash on a RaptorLake machine:
Oops: general protection fault, maybe for address 0xffff89aeceab400: 0000
CPU: 23 UID: 0 PID: 0 Comm: swapper/23
Tainted: [W]=WARN
Hardware name: Dell Inc. Precision 9660/0VJ762
RIP: 0010:native_read_pmc+0x7/0x40
Code: cc e8 8d a9 01 00 48 89 03 5b cd cc cc cc cc 0f 1f ...
RSP: 000:fffb03100273de8 EFLAGS: 00010046
....
Call Trace:
<TASK>
icl_update_topdown_event+0x165/0x190
? ktime_get+0x38/0xd0
intel_pmu_read_event+0xf9/0x210
__perf_event_read+0xf9/0x210CPUs 16-23 are E-core CPUs that don't support the perf metrics feature. The icl_update_topdown_event() should not be invoked on these CPUs.
It's a regression of commit:
f9bdf1f95339 ("perf/x86/intel: Avoid disable PMU if !cpuc->enabled in sample read")
The bug introduced by that commit is that the is_topdown_event() function is mistakenly used to replace the is_topdown_count() call to check if the topdown functions for the perf metrics feature should be invoked.
Fix it.
--- arch/x86/events/intel/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/core.c +1 -1
@@ -2703,7 +2703,7 @@ static void intel_pmu_read_event(structif (pmu_enabled)intel_pmu_disable_all (); -if (is_topdown_event (event)) +if (is_topdown_count (event))static_call (intel_pmu_update_topdown_event)(event);else intel_pmu_drain_pebs_buffer ();
Greg Kroah-Hartman
maintainerPATCH 347/482 x86/mce/amd: Add default names for MCA banks and blocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
[ Upstream commit d66e1e90b16055d2f0ee76e5384e3f119c3c2773 ]
Ensure that sysfs init doesn't fail for new/unrecognized bank types or if a bank has additional blocks available.
Most MCA banks have a single thresholding block, so the block takes the same name as the bank.
Unified Memory Controllers (UMCs) are a special case where there are two blocks and each has a unique name.
However, the microarchitecture allows for five blocks. Any new MCA bank types with more than one block will be missing names for the extra blocks. The MCE sysfs will fail to initialize in this case.
--- arch/x86/kernel/cpu/mce/amd.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +10 -3
@@ -1052,13 +1052,20 @@ static const char *get_name(unsigned int } bank_type =smca_get_bank_type (cpu, bank); -if (bank_type >=N_SMCA_BANK_TYPES ) -return NULL ;if (b && bank_type ==SMCA_UMC ) {if (b->block <ARRAY_SIZE (smca_umc_block_names))return smca_umc_block_names[b->block]; -return NULL ; + } + +if (b && b->block) { +snprintf (buf_mcatype,MAX_MCATYPE_NAME_LEN ,"th_block_%u" , b->block); +return buf_mcatype; + } + +if (bank_type >=N_SMCA_BANK_TYPES ) { +snprintf (buf_mcatype,MAX_MCATYPE_NAME_LEN ,"th_bank_%u" , bank); +return buf_mcatype; }if (per_cpu (smca_bank_counts, cpu)[bank_type] ==1 )
Greg Kroah-Hartman
maintainerPATCH 348/482 net: add netdev_lockdep_set_classes() to virtual drivers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
commit 0bef512012b1cd8820f0c9ec80e5f8ceb43fdd59 upstream.
Based on a syzbot report, it appears many virtual drivers do not yet use netdev_lockdep_set_classes(), triggerring lockdep false positives.
WARNING: possible recursive locking detected
6.8.0-rc4-next-20240212-syzkaller #0 Not tainted
syz-executor.0/19016 is trying to acquire lock:
ffff8880162cb298 (_xmit_ETHER#2){+.-.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline] ffff8880162cb298 (_xmit_ETHER#2){+.-.}-{2:2}, at: __netif_tx_lock include/linux/netdevice.h:4452 [inline] ffff8880162cb298 (_xmit_ETHER#2){+.-.}-{2:2}, at: sch_direct_xmit+0x1c4/0x5f0 net/sched/sch_generic.c:340
but task is already holding lock:
ffff8880223db4d8 (_xmit_ETHER#2){+.-.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline] ffff8880223db4d8 (_xmit_ETHER#2){+.-.}-{2:2}, at: __netif_tx_lock include/linux/netdevice.h:4452 [inline] ffff8880223db4d8 (_xmit_ETHER#2){+.-.}-{2:2}, at: sch_direct_xmit+0x1c4/0x5f0 net/sched/sch_generic.c:340
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
lock(_xmit_ETHER#2);
lock(_xmit_ETHER#2);
*** DEADLOCK ***
May be due to missing lock nesting notation
9 locks held by syz-executor.0/19016:
#0: ffffffff8f385208 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock net/core/rtnetlink.c:79 [inline]
#0: ffffffff8f385208 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x82c/0x1040 net/core/rtnetlink.c:6603
#1: ffffc90000a08c00 ((&in_dev->mr_ifc_timer)){+.-.}-{0:0}, at: call_timer_fn+0xc0/0x600 kernel/time/timer.c:1697 #2: ffffffff8e131520 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire include/linux/rcupdate.h:298 [inline]
#2: ffffffff8e131520 (rcu_read_lock){....}-{1:2}, at: rcu_read_lock include/linux/rcupdate.h:750 [inline]
#2: ffffffff8e131520 (rcu_read_lock){....}-{1:2}, at: ip_finish_output2+0x45f/0x1360 net/ipv4/ip_output.c:228
#3: ffffffff8e131580 (rcu_read_lock_bh){....}-{1:2}, at: local_bh_disable include/linux/bottom_half.h:20 [inline] #3: ffffffff8e131580 (rcu_read_lock_bh){....}-{1:2}, at: rcu_read_lock_bh include/linux/rcupdate.h:802 [inline]
#3: ffffffff8e131580 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x2c4/0x3b10 net/core/dev.c:4284
#4: ffff8880416e3258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: spin_trylock include/linux/spinlock.h:361 [inline] #4: ffff8880416e3258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: qdisc_run_begin include/net/sch_generic.h:195 [inline] #4: ffff8880416e3258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_xmit_skb net/core/dev.c:3771 [inline] #4: ffff8880416e3258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x1262/0x3b10 net/core/dev.c:4325 #5: ffff8880223db4d8 (_xmit_ETHER#2){+.-.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline]
#5: ffff8880223db4d8 (_xmit_ETHER#2){+.-.}-{2:2}, at: __netif_tx_lock include/linux/netdevice.h:4452 [inline]
#5: ffff8880223db4d8 (_xmit_ETHER#2){+.-.}-{2:2}, at: sch_direct_xmit+0x1c4/0x5f0 net/sched/sch_generic.c:340
#6: ffffffff8e131520 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire include/linux/rcupdate.h:298 [inline]
#6: ffffffff8e131520 (rcu_read_lock){....}-{1:2}, at: rcu_read_lock include/linux/rcupdate.h:750 [inline]
#6: ffffffff8e131520 (rcu_read_lock){....}-{1:2}, at: ip_finish_output2+0x45f/0x1360 net/ipv4/ip_output.c:228
#7: ffffffff8e131580 (rcu_read_lock_bh){....}-{1:2}, at: local_bh_disable include/linux/bottom_half.h:20 [inline] #7: ffffffff8e131580 (rcu_read_lock_bh){....}-{1:2}, at: rcu_read_lock_bh include/linux/rcupdate.h:802 [inline]
#7: ffffffff8e131580 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x2c4/0x3b10 net/core/dev.c:4284
#8: ffff888014d9d258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: spin_trylock include/linux/spinlock.h:361 [inline] #8: ffff888014d9d258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: qdisc_run_begin include/net/sch_generic.h:195 [inline] #8: ffff888014d9d258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_xmit_skb net/core/dev.c:3771 [inline] #8: ffff888014d9d258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x1262/0x3b10 net/core/dev.c:4325
stack backtrace: CPU: 1 PID: 19016 Comm: syz-executor.0 Not tainted 6.8.0-rc4-next-20240212-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024 Call Trace: <IRQ> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114 check_deadlock kernel/locking/lockdep.c:3062 [inline] validate_chain+0x15c1/0x58e0 kernel/locking/lockdep.c:3856 __lock_acquire+0x1346/0x1fd0 kernel/locking/lockdep.c:5137 lock_acquire+0x1e4/0x530 kernel/locking/lockdep.c:5754 __raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline] _raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:154 spin_lock include/linux/spinlock.h:351 [inline] __netif_tx_lock include/linux/netdevice.h:4452 [inline] sch_direct_xmit+0x1c4/0x5f0 net/sched/sch_generic.c:340 __dev_xmit_skb net/core/dev.c:3784 [inline] __dev_queue_xmit+0x1912/0x3b10 net/core/dev.c:4325 neigh_output include/net/neighbour.h:542 [inline] ip_finish_output2+0xe66/0x1360 net/ipv4/ip_output.c:235 iptunnel_xmit+0x540/0x9b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x20ee/0x2960 net/ipv4/ip_tunnel.c:831 erspan_xmit+0x9de/0x1460 net/ipv4/ip_gre.c:720 __netdev_start_xmit include/linux/netdevice.h:4989 [inline] netdev_start_xmit include/linux/netdevice.h:5003 [inline] xmit_one net/core/dev.c:3555 [inline] dev_hard_start_xmit+0x242/0x770 net/core/dev.c:3571 sch_direct_xmit+0x2b6/0x5f0 net/sched/sch_generic.c:342 __dev_xmit_skb net/core/dev.c:3784 [inline] __dev_queue_xmit+0x1912/0x3b10 net/core/dev.c:4325 neigh_output include/net/neighbour.h:542 [inline] ip_finish_output2+0xe66/0x1360 net/ipv4/ip_output.c:235 igmpv3_send_cr net/ipv4/igmp.c:723 [inline] igmp_ifc_timer_expire+0xb71/0xd90 net/ipv4/igmp.c:813 call_timer_fn+0x17e/0x600 kernel/time/timer.c:1700 expire_timers kernel/time/timer.c:1751 [inline] __run_timers+0x621/0x830 kernel/time/timer.c:2038 run_timer_softirq+0x67/0xf0 kernel/time/timer.c:2051 __do_softirq+0x2bc/0x943 kernel/softirq.c:554 invoke_softirq kernel/softirq.c:428 [inline] __irq_exit_rcu+0xf2/0x1c0 kernel/softirq.c:633 irq_exit_rcu+0x9/0x30 kernel/softirq.c:645 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1076 [inline] sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1076 </IRQ> <TASK> asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702 RIP: 0010:resched_offsets_ok kernel/sched/core.c:10127 [inline] RIP: 0010:__might_resched+0x16f/0x780 kernel/sched/core.c:10142 Code: 00 4c 89 e8 48 c1 e8 03 48 ba 00 00 00 00 00 fc ff df 48 89 44 24 38 0f b6 04 10 84 c0 0f 85 87 04 00 00 41 8b 45 00 c1 e0 08 <01> d8 44 39 e0 0f 85 d6 00 00 00 44 89 64 24 1c 48 8d bc 24 a0 00 RSP: 0018:ffffc9000ee069e0 EFLAGS: 00000246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff8880296a9e00 RDX: dffffc0000000000 RSI: ffff8880296a9e00 RDI: ffffffff8bfe8fa0 RBP: ffffc9000ee06b00 R08: ffffffff82326877 R09: 1ffff11002b5ad1b R10: dffffc0000000000 R11: ffffed1002b5ad1c R12: 0000000000000000 R13: ffff8880296aa23c R14: 000000000000062a R15: 1ffff92001dc0d44 down_write+0x19/0x50 kernel/locking/rwsem.c:1578 kernfs_activate fs/kernfs/dir.c:1403 [inline] kernfs_add_one+0x4af/0x8b0 fs/kernfs/dir.c:819 __kernfs_create_file+0x22e/0x2e0 fs/kernfs/file.c:1056 sysfs_add_file_mode_ns+0x24a/0x310 fs/sysfs/file.c:307 create_files fs/sysfs/group.c:64 [inline] internal_create_group+0x4f4/0xf20 fs/sysfs/group.c:152 internal_create_groups fs/sysfs/group.c:192 [inline] sysfs_create_groups+0x56/0x120 fs/sysfs/group.c:218 create_dir lib/kobject.c:78 [inline] kobject_add_internal+0x472/0x8d0 lib/kobject.c:240 kobject_add_varg lib/kobject.c:374 [inline] kobject_init_and_add+0x124/0x190 lib/kobject.c:457 netdev_queue_add_kobject net/core/net-sysfs.c:1706 [inline] netdev_queue_update_kobjects+0x1f3/0x480 net/core/net-sysfs.c:1758 register_queue_kobjects net/core/net-sysfs.c:1819 [inline] netdev_register_kobject+0x265/0x310 net/core/net-sysfs.c:2059 register_netdevice+0x1191/0x19c0 net/core/dev.c:10298 bond_newlink+0x3b/0x90 drivers/net/bonding/bond_netlink.c:576 rtnl_newlink_create net/core/rtnetlink.c:3506 [inline] __rtnl_newlink net/core/rtnetlink.c:3726 [inline] rtnl_newlink+0x158f/0x20a0 net/core/rtnetlink.c:3739 rtnetlink_rcv_msg+0x885/0x1040 net/core/rtnetlink.c:6606 netlink_rcv_skb+0x1e3/0x430 net/netlink/af_netlink.c:2543 netlink_unicast_kernel net/netlink/af_netlink.c:1341 [inline] netlink_unicast+0x7ea/0x980 net/netlink/af_netlink.c:1367 netlink_sendmsg+0xa3c/0xd70 net/netlink/af_netlink.c:1908 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg+0x221/0x270 net/socket.c:745 __sys_sendto+0x3a4/0x4f0 net/socket.c:2191 __do_sys_sendto net/socket.c:2203 [inline] __se_sys_sendto net/socket.c:2199 [inline] __x64_sys_sendto+0xde/0x100 net/socket.c:2199 do_syscall_64+0xfb/0x240 entry_SYSCALL_64_after_hwframe+0x6d/0x75 RIP: 0033:0x7fc3fa87fa9c
--- drivers/net/dummy.c | 1 + drivers/net/geneve.c | 1 + drivers/net/loopback.c | 1 + drivers/net/veth.c | 1 + drivers/net/vxlan/vxlan_core.c | 1 + net/ipv4/ip_tunnel.c | 1 + net/ipv6/ip6_gre.c | 2 ++ net/ipv6/ip6_tunnel.c | 1 + net/ipv6/ip6_vti.c | 1 + net/ipv6/sit.c | 1 + 10 files changed, 11 insertions(+)
drivers/net/dummy.c +1 -0
@@ -71,6 +71,7 @@ static int dummy_dev_init(struct net_devif (!dev->lstats)return -ENOMEM ; +netdev_lockdep_set_classes (dev);return 0 ; }
drivers/net/geneve.c +1 -0
@@ -349,6 +349,7 @@ static int geneve_init(struct net_devicegro_cells_destroy (&geneve->gro_cells);return err; } +netdev_lockdep_set_classes (dev);return 0 ; }
drivers/net/loopback.c +1 -0
@@ -144,6 +144,7 @@ static int loopback_dev_init(struct net_ dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);if (!dev->lstats)return -ENOMEM ; +netdev_lockdep_set_classes (dev);return 0 ; }
drivers/net/veth.c +1 -0
@@ -1373,6 +1373,7 @@ static void veth_free_queues(struct net_static int veth_dev_init (struct net_device *dev) { +netdev_lockdep_set_classes (dev);return veth_alloc_queues (dev); }
drivers/net/vxlan/vxlan_core.c +1 -0
@@ -2998,6 +2998,7 @@ static int vxlan_init(struct net_deviceif (err) goto err_free_percpu; +netdev_lockdep_set_classes (dev);return 0 ; err_free_percpu:
net/ipv4/ip_tunnel.c +1 -0
@@ -1298,6 +1298,7 @@ int ip_tunnel_init(struct net_device *deif (tunnel->collect_md)netif_keep_dst (dev); +netdev_lockdep_set_classes (dev);return 0 ; }EXPORT_SYMBOL_GPL (ip_tunnel_init);
net/ipv6/ip6_gre.c +2 -0
@@ -1537,6 +1537,7 @@ static int ip6gre_tunnel_init_common(strip6gre_tnl_init_features (dev);netdev_hold (dev, &tunnel->dev_tracker,GFP_KERNEL ); +netdev_lockdep_set_classes (dev);return 0 ; cleanup_dst_cache_init:
@@ -1929,6 +1930,7 @@ static int ip6erspan_tap_init(struct netip6erspan_tnl_link_config (tunnel,1 );netdev_hold (dev, &tunnel->dev_tracker,GFP_KERNEL ); +netdev_lockdep_set_classes (dev);return 0 ; cleanup_dst_cache_init:
net/ipv6/ip6_tunnel.c +1 -0
@@ -1902,6 +1902,7 @@ ip6_tnl_dev_init_gen(struct net_device * dev->max_mtu =IP6_MAX_MTU - dev->hard_header_len - t_hlen;netdev_hold (dev, &t->dev_tracker,GFP_KERNEL ); +netdev_lockdep_set_classes (dev);return 0 ; destroy_dst:
net/ipv6/ip6_vti.c +1 -0
@@ -937,6 +937,7 @@ static inline int vti6_dev_init_gen(struif (!dev->tstats)return -ENOMEM ;netdev_hold (dev, &t->dev_tracker,GFP_KERNEL ); +netdev_lockdep_set_classes (dev);return 0 ; }
net/ipv6/sit.c +1 -0
@@ -1460,6 +1460,7 @@ static int ipip6_tunnel_init(struct net_return err; }netdev_hold (dev, &tunnel->dev_tracker,GFP_KERNEL ); +netdev_lockdep_set_classes (dev);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 349/482 btrfs: fix qgroup reservation leak on failure to allocate ordered extent
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 1f2889f5594a2bc4c6a52634c4a51b93e785def5 ]
If we fail to allocate an ordered extent for a COW write we end up leaking a qgroup data reservation since we called btrfs_qgroup_release_data() but we didn't call btrfs_qgroup_free_refroot() (which would happen when running the respective data delayed ref created by ordered extent completion or when finishing the ordered extent in case an error happened).
So make sure we call btrfs_qgroup_free_refroot() if we fail to allocate an ordered extent for a COW write.
--- fs/btrfs/ordered-data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/btrfs/ordered-data.c +9 -3
@@ -173,9 +173,10 @@ int btrfs_add_ordered_extent(struct btrfstruct btrfs_ordered_extent *entry;int ret;u64 qgroup_rsv =0 ; +const bool is_nocow = (flags & + ((1U <<BTRFS_ORDERED_NOCOW ) | (1U <<BTRFS_ORDERED_PREALLOC ))); -if (flags & - ((1 <<BTRFS_ORDERED_NOCOW ) | (1 <<BTRFS_ORDERED_PREALLOC ))) { +if (is_nocow) {/* For nocow write, we can release the qgroup rsv right now */ ret =btrfs_qgroup_free_data (inode,NULL , file_offset, num_bytes, &qgroup_rsv);if (ret <0 )
@@ -191,8 +192,13 @@ int btrfs_add_ordered_extent(struct btrfreturn ret; } entry =kmem_cache_zalloc (btrfs_ordered_extent_cache,GFP_NOFS ); -if (!entry) +if (!entry) { +if (!is_nocow) +btrfs_qgroup_free_refroot (inode->root->fs_info, +btrfs_root_id (inode->root), + qgroup_rsv,BTRFS_QGROUP_RSV_DATA );return -ENOMEM ; + } entry->file_offset = file_offset; entry->num_bytes = num_bytes;
Greg Kroah-Hartman
maintainerPATCH 350/482 ARM: 9448/1: Use an absolute path to unified.h in KBUILD_AFLAGS
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
[ Upstream commit 87c4e1459e80bf65066f864c762ef4dc932fad4b ]
After commit d5c8d6e0fa61 ("kbuild: Update assembler calls to use proper flags and language target"), which updated as-instr to use the 'assembler-with-cpp' language option, the Kbuild version of as-instr always fails internally for arch/arm with
<command-line>: fatal error: asm/unified.h: No such file or directory compilation terminated.
because '-include' flags are now taken into account by the compiler driver and as-instr does not have '$(LINUXINCLUDE)', so unified.h is not found.
This went unnoticed at the time of the Kbuild change because the last use of as-instr in Kbuild that arch/arm could reach was removed in 5.7 by commit 541ad0150ca4 ("arm: Remove 32bit KVM host support") but a stable backport of the Kbuild change to before that point exposed this potential issue if one were to be reintroduced.
Follow the general pattern of '-include' paths throughout the tree and make unified.h absolute using '$(srctree)' to ensure KBUILD_AFLAGS can be used independently.
--- arch/arm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/Makefile +1 -1
@@ -133,7 +133,7 @@ endif # Need -Uarm for gcc < 3.x KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm -KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float +KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include $(srctree)/arch/arm/include/asm/unified.h -msoft-float CHECKFLAGS += -D__arm__
Greg Kroah-Hartman
maintainerPATCH 351/482 arm64/entry: Mask DAIF in cpu_switch_to(), call_on_irq_stack()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ada Couprie Diaz <[email protected]>
[ Upstream commit d42e6c20de6192f8e4ab4cf10be8c694ef27e8cb ]
cpu_switch_to() and call_on_irq_stack() manipulate SP to change to different stacks along with the Shadow Call Stack if it is enabled. Those two stack changes cannot be done atomically and both functions can be interrupted by SErrors or Debug Exceptions which, though unlikely, is very much broken : if interrupted, we can end up with mismatched stacks and Shadow Call Stack leading to clobbered stacks.
In cpu_switch_to(), it can happen when SP_EL0 points to the new task, but x18 stills points to the old task's SCS. When the interrupt handler tries to save the task's SCS pointer, it will save the old task SCS pointer (x18) into the new task struct (pointed to by SP_EL0), clobbering it.
In call_on_irq_stack(), it can happen when switching from the task stack to the IRQ stack and when switching back. In both cases, we can be interrupted when the SCS pointer points to the IRQ SCS, but SP points to the task stack. The nested interrupt handler pushes its return addresses on the IRQ SCS. It then detects that SP points to the task stack, calls call_on_irq_stack() and clobbers the task SCS pointer with the IRQ SCS pointer, which it will also use !
This leads to tasks returning to addresses on the wrong SCS, or even on the IRQ SCS, triggering kernel panics via CONFIG_VMAP_STACK or FPAC if enabled.
This is possible on a default config, but unlikely.
However, when enabling CONFIG_ARM64_PSEUDO_NMI, DAIF is unmasked and instead the GIC is responsible for filtering what interrupts the CPU should receive based on priority.
Given the goal of emulating NMIs, pseudo-NMIs can be received by the CPU even in cpu_switch_to() and call_on_irq_stack(), possibly *very* frequently depending on the system configuration and workload, leading to unpredictable kernel panics.
Completely mask DAIF in cpu_switch_to() and restore it when returning. Do the same in call_on_irq_stack(), but restore and mask around the branch.
Mask DAIF even if CONFIG_SHADOW_CALL_STACK is not enabled for consistency of behaviour between all configurations.
Introduce and use an assembly macro for saving and masking DAIF, as the existing one saves but only masks IF.
--- arch/arm64/kernel/entry.S | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm64/kernel/entry.S +6 -0
@@ -827,6 +827,7 @@ SYM_CODE_END(__bp_harden_el1_vectors) * */ SYM_FUNC_START(cpu_switch_to) + save_and_disable_daif x11 mov x10, #THREAD_CPU_CONTEXT add x8, x0, x10 mov x9, sp
@@ -850,6 +851,7 @@ SYM_FUNC_START(cpu_switch_to) ptrauth_keys_install_kernel x1, x8, x9, x10 scs_save x0 scs_load_current + restore_irq x11 ret SYM_FUNC_END(cpu_switch_to) NOKPROBE(cpu_switch_to)
@@ -876,6 +878,7 @@ NOKPROBE(ret_from_fork) * Calls func(regs) using this CPU's irq stack and shadow irq stack. */ SYM_FUNC_START(call_on_irq_stack) + save_and_disable_daif x9 #ifdef CONFIG_SHADOW_CALL_STACK get_current_task x16 scs_save x16
@@ -890,8 +893,10 @@ SYM_FUNC_START(call_on_irq_stack) /* Move to the new stack and call the function there */ add sp, x16, #IRQ_STACK_SIZE + restore_irq x9 blr x1 + save_and_disable_daif x9 /* * Restore the SP from the FP, and restore the FP and LR from the frame * record.
@@ -899,6 +904,7 @@ SYM_FUNC_START(call_on_irq_stack) mov sp, x29 ldp x29, x30, [sp], #16 scs_load_current + restore_irq x9 ret SYM_FUNC_END(call_on_irq_stack) NOKPROBE(call_on_irq_stack)
Greg Kroah-Hartman
maintainerPATCH 352/482 drm/sched: Remove optimization that causes hang when killing dependent jobs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Lin.Cao" <[email protected]>
[ Upstream commit 15f77764e90a713ee3916ca424757688e4f565b9 ]
When application A submits jobs and application B submits a job with a dependency on A's fence, the normal flow wakes up the scheduler after processing each job. However, the optimization in drm_sched_entity_add_dependency_cb() uses a callback that only clears dependencies without waking up the scheduler.
When application A is killed before its jobs can run, the callback gets triggered but only clears the dependency without waking up the scheduler, causing the scheduler to enter sleep state and application B to hang.
Remove the optimization by deleting drm_sched_entity_clear_dep() and its usage, ensuring the scheduler is always woken up when dependencies are cleared.
--- drivers/gpu/drm/scheduler/sched_entity.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-)
drivers/gpu/drm/scheduler/sched_entity.c +2 -19
@@ -327,17 +327,6 @@ void drm_sched_entity_destroy(struct drm }EXPORT_SYMBOL (drm_sched_entity_destroy); -/* drm_sched_entity_clear_dep - callback to clear the entities dependency */ -static void drm_sched_entity_clear_dep (struct dma_fence *f, -struct dma_fence_cb *cb) -{ -struct drm_sched_entity *entity = - container_of(cb, struct drm_sched_entity, cb); - - entity->dependency =NULL ; -dma_fence_put (f); -} -/* * drm_sched_entity_clear_dep - callback to clear the entities dependency and * wake up scheduler
@@ -348,7 +337,8 @@ static void drm_sched_entity_wakeup(strustruct drm_sched_entity *entity = container_of(cb, struct drm_sched_entity, cb); -drm_sched_entity_clear_dep (f, cb); + entity->dependency =NULL ; +dma_fence_put (f);drm_sched_wakeup (entity->rq->sched); }
@@ -401,13 +391,6 @@ static bool drm_sched_entity_add_depende fence =dma_fence_get (&s_fence->scheduled);dma_fence_put (entity->dependency); entity->dependency = fence; -if (!dma_fence_add_callback (fence, &entity->cb, - drm_sched_entity_clear_dep)) -return true; - -/* Ignore it when it is already scheduled */ -dma_fence_put (fence); -return false; } if (!dma_fence_add_callback(entity->dependency, &entity->cb,
Greg Kroah-Hartman
maintainerPATCH 353/482 net: enetc: fix device and OF node leak at probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 70458f8a6b44daf3ad39f0d9b6d1097c8a7780ed ]
Make sure to drop the references to the IERB OF node and platform device taken by of_parse_phandle() and of_find_device_by_node() during probe.
--- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/net/ethernet/freescale/enetc/enetc_pf.c +12 -2
@@ -1207,6 +1207,7 @@ static int enetc_pf_register_with_ierb(sstruct device_node *node = pdev->dev.of_node;struct platform_device *ierb_pdev;struct device_node *ierb_node; +int ret;/* Don't register with the IERB if the PF itself is disabled */ if (!node || !of_device_is_available (node))
@@ -1214,16 +1215,25 @@ static int enetc_pf_register_with_ierb(s ierb_node =of_find_compatible_node (NULL ,NULL ,"fsl,ls1028a-enetc-ierb" ); -if (!ierb_node || !of_device_is_available (ierb_node)) +if (!ierb_node)return -ENODEV ; +if (!of_device_is_available (ierb_node)) { +of_node_put (ierb_node); +return -ENODEV ; + } + ierb_pdev =of_find_device_by_node (ierb_node);of_node_put (ierb_node);if (!ierb_pdev)return -EPROBE_DEFER ; -return enetc_ierb_register_pf (ierb_pdev, pdev); + ret =enetc_ierb_register_pf (ierb_pdev, pdev); + +put_device (&ierb_pdev->dev); + +return ret; } static int enetc_pf_probe(struct pci_dev *pdev,
Greg Kroah-Hartman
maintainerPATCH 354/482 fscrypt: Dont use problematic non-inline crypto engines
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
[ Upstream commit b41c1d8d07906786c60893980d52688f31d114a6 ]
Make fscrypt no longer use Crypto API drivers for non-inline crypto engines, even when the Crypto API prioritizes them over CPU-based code (which unfortunately it often does). These drivers tend to be really problematic, especially for fscrypt's workload. This commit has no effect on inline crypto engines, which are different and do work well.
Specifically, exclude drivers that have CRYPTO_ALG_KERN_DRIVER_ONLY or CRYPTO_ALG_ALLOCATES_MEMORY set. (Later, CRYPTO_ALG_ASYNC should be excluded too. That's omitted for now to keep this commit backportable, since until recently some CPU-based code had CRYPTO_ALG_ASYNC set.)
There are two major issues with these drivers: bugs and performance.
First, these drivers tend to be buggy. They're fundamentally much more error-prone and harder to test than the CPU-based code. They often don't get tested before kernel releases, and even if they do, the crypto self-tests don't properly test these drivers. Released drivers have en/decrypted or hashed data incorrectly. These bugs cause issues for fscrypt users who often didn't even want to use these drivers, e.g.:
- https://github.com/google/fscryptctl/issues/32
- https://github.com/google/fscryptctl/issues/9
- https://lore.kernel.org/r/PH0PR02MB731916ECDB6C613665863B6CFFAA2@PH0PR02MB7319.namprd02.prod.outlook.com
These drivers have also similarly caused issues for dm-crypt users, including data corruption and deadlocks. Since Linux v5.10, dm-crypt has disabled most of them by excluding CRYPTO_ALG_ALLOCATES_MEMORY.
Second, these drivers tend to be *much* slower than the CPU-based code. This may seem counterintuitive, but benchmarks clearly show it. There's a *lot* of overhead associated with going to a hardware driver, off the CPU, and back again. To prove this, I gathered as many systems with this type of crypto engine as I could, and I measured synchronous encryption of 4096-byte messages (which matches fscrypt's workload):
Intel Emerald Rapids server:
AES-256-XTS:
xts-aes-vaes-avx512 16171 MB/s [CPU-based, Vector AES]
qat_aes_xts 289 MB/s [Offload, Intel QuickAssist]
Qualcomm SM8650 HDK:
AES-256-XTS:
xts-aes-ce 4301 MB/s [CPU-based, ARMv8 Crypto Extensions]
xts-aes-qce 73 MB/s [Offload, Qualcomm Crypto Engine]
i.MX 8M Nano LPDDR4 EVK:
AES-256-XTS:
xts-aes-ce 647 MB/s [CPU-based, ARMv8 Crypto Extensions]
xts(ecb-aes-caam) 20 MB/s [Offload, CAAM]
AES-128-CBC-ESSIV:
essiv(cbc-aes-caam,sha256-lib) 23 MB/s [Offload, CAAM]
STM32MP157F-DK2:
AES-256-XTS:
xts-aes-neonbs 13.2 MB/s [CPU-based, ARM NEON]
xts(stm32-ecb-aes) 3.1 MB/s [Offload, STM32 crypto engine]
AES-128-CBC-ESSIV:
essiv(cbc-aes-neonbs,sha256-lib)
14.7 MB/s [CPU-based, ARM NEON]
essiv(stm32-cbc-aes,sha256-lib)
3.2 MB/s [Offload, STM32 crypto engine] Adiantum:
adiantum(xchacha12-arm,aes-arm,nhpoly1305-neon)
52.8 MB/s [CPU-based, ARM scalar + NEON]
So, there was no case in which the crypto engine was even *close* to being faster. On the first three, which have AES instructions in the CPU, the CPU was 30 to 55 times faster (!). Even on STM32MP157F-DK2 which has a Cortex-A7 CPU that doesn't have AES instructions, AES was over 4 times faster on the CPU. And Adiantum encryption, which is what actually should be used on CPUs like that, was over 17 times faster.
Other justifications that have been given for these non-inline crypto engines (almost always coming from the hardware vendors, not actual users) don't seem very plausible either:
- The crypto engine throughput could be improved by processing multiple requests concurrently. Currently irrelevant to fscrypt, since it doesn't do that. This would also be complex, and unhelpful in many cases. 2 of the 4 engines I tested even had only one queue.
- Some of the engines, e.g. STM32, support hardware keys. Also currently irrelevant to fscrypt, since it doesn't support these. Interestingly, the STM32 driver itself doesn't support this either.
- Free up CPU for other tasks and/or reduce energy usage. Not very plausible considering the "short" message length, driver overhead, and scheduling overhead. There's just very little time for the CPU to do something else like run another task or enter low-power state, before the message finishes and it's time to process the next one.
- Some of these engines resist power analysis and electromagnetic attacks, while the CPU-based crypto generally does not. In theory, this sounds great. In practice, if this benefit requires the use of an off-CPU offload that massively regresses performance and has a low-quality, buggy driver, the price for this hardening (which is not relevant to most fscrypt users, and tends to be incomplete) is just too high. Inline crypto engines are much more promising here, as are on-CPU solutions like RISC-V High Assurance Cryptography.
--- fs/crypto/fscrypt_private.h | 17 +++++++++++++++++ fs/crypto/hkdf.c | 2 +- fs/crypto/keysetup.c | 3 ++- fs/crypto/keysetup_v1.c | 3 ++- 4 files changed, 22 insertions(+), 3 deletions(-)
fs/crypto/fscrypt_private.h +17 -0
@@ -27,6 +27,23 @@*/ #define FSCRYPT_MIN_KEY_SIZE 16 +/* +* This mask is passed as the third argument to the crypto_alloc_*() functions +* to prevent fscrypt from using the Crypto API drivers for non-inline crypto +* engines. Those drivers have been problematic for fscrypt. fscrypt users +* have reported hangs and even incorrect en/decryption with these drivers. +* Since going to the driver, off CPU, and back again is really slow, such +* drivers can be over 50 times slower than the CPU-based code for fscrypt's +* workload. Even on platforms that lack AES instructions on the CPU, using the +* offloads has been shown to be slower, even staying with AES. (Of course, +* Adiantum is faster still, and is the recommended option on such platforms...) +* +* Note that fscrypt also supports inline crypto engines. Those don't use the +* Crypto API and work much better than the old-style (non-inline) engines. +*/ +#define FSCRYPT_CRYPTOAPI_MASK \ + (CRYPTO_ALG_ALLOCATES_MEMORY | CRYPTO_ALG_KERN_DRIVER_ONLY) +#define FSCRYPT_CONTEXT_V1 1#define FSCRYPT_CONTEXT_V2 2
fs/crypto/hkdf.c +1 -1
@@ -72,7 +72,7 @@ int fscrypt_init_hkdf(struct fscrypt_hkdu8 prk[HKDF_HASHLEN ];int err; - hmac_tfm =crypto_alloc_shash (HKDF_HMAC_ALG ,0 ,0 ); + hmac_tfm =crypto_alloc_shash (HKDF_HMAC_ALG ,0 ,FSCRYPT_CRYPTOAPI_MASK );if (IS_ERR (hmac_tfm)) {fscrypt_err (NULL ,"Error allocating " HKDF_HMAC_ALG ": %ld" ,PTR_ERR (hmac_tfm));
fs/crypto/keysetup.c +2 -1
@@ -88,7 +88,8 @@ fscrypt_allocate_skcipher(struct fscryptstruct crypto_skcipher *tfm;int err; - tfm =crypto_alloc_skcipher (mode->cipher_str,0 ,0 ); + tfm =crypto_alloc_skcipher (mode->cipher_str,0 , +FSCRYPT_CRYPTOAPI_MASK );if (IS_ERR (tfm)) {if (PTR_ERR (tfm) == -ENOENT ) { fscrypt_warn(inode,
fs/crypto/keysetup_v1.c +2 -1
@@ -52,7 +52,8 @@ static int derive_key_aes(const u8 *maststruct skcipher_request *req =NULL ;DECLARE_CRYPTO_WAIT (wait);struct scatterlist src_sg, dst_sg; -struct crypto_skcipher *tfm =crypto_alloc_skcipher ("ecb(aes)" ,0 ,0 ); +struct crypto_skcipher *tfm = +crypto_alloc_skcipher ("ecb(aes)" ,0 ,FSCRYPT_CRYPTOAPI_MASK );if (IS_ERR (tfm)) { res =PTR_ERR (tfm);
Greg Kroah-Hartman
maintainerPATCH 355/482 block: reject invalid operation in submit_bio_noacct
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 1c042f8d4bc342b7985b1de3d76836f1a1083b65 ]
submit_bio_noacct allows completely invalid operations, or operations that are not supported in the bio path. Extent the existing switch statement to rejcect all invalid types.
Move the code point for REQ_OP_ZONE_APPEND so that it's not right in the middle of the zone management operations and the switch statement can follow the numerical order of the operations.
Stable-dep-of: 3f66ccbaaef3 ("block: Make REQ_OP_ZONE_FINISH a write operation")
--- block/blk-core.c | 26 +++++++++++++++++++++----- include/linux/blk_types.h | 8 ++++---- 2 files changed, 25 insertions(+), 9 deletions(-)
block/blk-core.c +21 -5
@@ -755,6 +755,15 @@ void submit_bio_noacct(struct bio *bio)bio_clear_polled (bio);switch (bio_op (bio)) { +case REQ_OP_READ : +case REQ_OP_WRITE : +break ; +case REQ_OP_FLUSH : +/* +* REQ_OP_FLUSH can't be submitted through bios, it is only +* synthetized in struct request by the flush state machine. +*/ + goto not_supported;case REQ_OP_DISCARD :if (!bdev_max_discard_sectors (bdev)) goto not_supported;
@@ -768,6 +777,10 @@ void submit_bio_noacct(struct bio *bio)if (status !=BLK_STS_OK ) goto end_io;break ; +case REQ_OP_WRITE_ZEROES : +if (!q->limits.max_write_zeroes_sectors) + goto not_supported; +break ;case REQ_OP_ZONE_RESET :case REQ_OP_ZONE_OPEN :case REQ_OP_ZONE_CLOSE :
@@ -779,12 +792,15 @@ void submit_bio_noacct(struct bio *bio)if (!bdev_is_zoned (bio->bi_bdev) || !blk_queue_zone_resetall (q)) goto not_supported;break ; -case REQ_OP_WRITE_ZEROES : -if (!q->limits.max_write_zeroes_sectors) - goto not_supported; -break ; +case REQ_OP_DRV_IN : +case REQ_OP_DRV_OUT : +/* +* Driver private operations are only used with passthrough +* requests. +*/ + fallthrough;default : -break ; + goto not_supported; }if (blk_throtl_bio (bio))
include/linux/blk_types.h +4 -4
@@ -366,6 +366,8 @@ enum req_op {REQ_OP_DISCARD = (__force blk_opf_t )3 ,/* securely erase sectors */ REQ_OP_SECURE_ERASE = (__force blk_opf_t )5 , +/* write data at the current zone write pointer */ +REQ_OP_ZONE_APPEND = (__force blk_opf_t )7 ,/* write the zero filled sector many times */ REQ_OP_WRITE_ZEROES = (__force blk_opf_t)9,/* Open a zone */
@@ -374,12 +376,10 @@ enum req_op {REQ_OP_ZONE_CLOSE = (__force blk_opf_t )11 ,/* Transition a zone to full */ REQ_OP_ZONE_FINISH = (__force blk_opf_t )12 , -/* write data at the current zone write pointer */ -REQ_OP_ZONE_APPEND = (__force blk_opf_t )13 ,/* reset a zone write pointer */ -REQ_OP_ZONE_RESET = (__force blk_opf_t )15 , +REQ_OP_ZONE_RESET = (__force blk_opf_t )13 ,/* reset all the zone present on the device */ -REQ_OP_ZONE_RESET_ALL = (__force blk_opf_t )17 , +REQ_OP_ZONE_RESET_ALL = (__force blk_opf_t )15 ,/* Driver private requests */ REQ_OP_DRV_IN = (__force blk_opf_t)34,
Greg Kroah-Hartman
maintainerPATCH 356/482 block: Make REQ_OP_ZONE_FINISH a write operation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 3f66ccbaaef3a0c5bd844eab04e3207b4061c546 ]
REQ_OP_ZONE_FINISH is defined as "12", which makes op_is_write(REQ_OP_ZONE_FINISH) return false, despite the fact that a zone finish operation is an operation that modifies a zone (transition it to full) and so should be considered as a write operation (albeit one that does not transfer any data to the device).
Fix this by redefining REQ_OP_ZONE_FINISH to be an odd number (13), and redefine REQ_OP_ZONE_RESET and REQ_OP_ZONE_RESET_ALL using sequential odd numbers from that new value.
--- include/linux/blk_types.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/linux/blk_types.h +3 -3
@@ -375,11 +375,11 @@ enum req_op {/* Close a zone */ REQ_OP_ZONE_CLOSE = (__force blk_opf_t )11 ,/* Transition a zone to full */ -REQ_OP_ZONE_FINISH = (__force blk_opf_t )12 , +REQ_OP_ZONE_FINISH = (__force blk_opf_t )13 ,/* reset a zone write pointer */ -REQ_OP_ZONE_RESET = (__force blk_opf_t )13 , +REQ_OP_ZONE_RESET = (__force blk_opf_t )15 ,/* reset all the zone present on the device */ -REQ_OP_ZONE_RESET_ALL = (__force blk_opf_t )15 , +REQ_OP_ZONE_RESET_ALL = (__force blk_opf_t )17 ,/* Driver private requests */ REQ_OP_DRV_IN = (__force blk_opf_t)34,
Greg Kroah-Hartman
maintainerPATCH 357/482 PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
[ Upstream commit 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a ]
pci_bridge_d3_possible() is called from both pcie_portdrv_probe() and pcie_portdrv_remove() to determine whether runtime power management shall be enabled (on probe) or disabled (on remove) on a PCIe port.
The underlying assumption is that pci_bridge_d3_possible() always returns the same value, else a runtime PM reference imbalance would occur. That assumption is not given if the PCIe port is inaccessible on remove due to
hot-unplug: pci_bridge_d3_possible() calls pciehp_is_native(), which accesses Config Space to determine whether the port is Hot-Plug Capable. An inaccessible port returns "all ones", which is converted to "all zeroes" by pcie_capability_read_dword(). Hence the port no longer seems Hot-Plug Capable on remove even though it was on probe.
The resulting runtime PM ref imbalance causes warning messages such as:
pcieport 0000:02:04.0: Runtime PM usage count underflow!
Avoid the Config Space access (and thus the runtime PM ref imbalance) by caching the Hot-Plug Capable bit in struct pci_dev.
The struct already contains an "is_hotplug_bridge" flag, which however is not only set on Hot-Plug Capable PCIe ports, but also Conventional PCI Hot-Plug bridges and ACPI slots. The flag identifies bridges which are allocated additional MMIO and bus number resources to allow for hierarchy expansion.
The kernel is somewhat sloppily using "is_hotplug_bridge" in a number of places to identify Hot-Plug Capable PCIe ports, even though the flag encompasses other devices. Subsequent commits replace these occurrences with the new flag to clearly delineate Hot-Plug Capable PCIe ports from other kinds of hotplug bridges.
Document the existing "is_hotplug_bridge" and the new "is_pciehp" flag and document the (non-obvious) requirement that pci_bridge_d3_possible() always returns the same value across the entire lifetime of a bridge, including its hot-removal.
--- drivers/pci/pci-acpi.c | 4 +--- drivers/pci/pci.c | 8 ++++++-- drivers/pci/probe.c | 2 +- include/linux/pci.h | 10 +++++++++- 4 files changed, 17 insertions(+), 7 deletions(-)
drivers/pci/pci-acpi.c +1 -3
@@ -793,13 +793,11 @@ int pci_acpi_program_hp_params(struct pcbool pciehp_is_native (struct pci_dev *bridge) {const struct pci_host_bridge *host; -u32 slot_cap;if (!IS_ENABLED (CONFIG_HOTPLUG_PCI_PCIE ))return false; -pcie_capability_read_dword (bridge,PCI_EXP_SLTCAP , &slot_cap); -if (!(slot_cap &PCI_EXP_SLTCAP_HPC )) +if (!bridge->is_pciehp)return false;if (pcie_ports_native)
drivers/pci/pci.c +6 -2
@@ -3019,8 +3019,12 @@ static const struct dmi_system_id bridge* pci_bridge_d3_possible - Is it possible to put the bridge into D3 * @bridge: Bridge to check * -* This function checks if it is possible to move the bridge to D3. -* Currently we only allow D3 for recent enough PCIe ports and Thunderbolt. +* Currently we only allow D3 for some PCIe ports and for Thunderbolt. +* +* Return: Whether it is possible to move the bridge to D3. +* +* The return value is guaranteed to be constant across the entire lifetime +* of the bridge, including its hot-removal. */ bool pci_bridge_d3_possible (struct pci_dev *bridge) {
drivers/pci/probe.c +1 -1
@@ -1592,7 +1592,7 @@ void set_pcie_hotplug_bridge(struct pci_pcie_capability_read_dword (pdev,PCI_EXP_SLTCAP , ®32);if (reg32 &PCI_EXP_SLTCAP_HPC ) - pdev->is_hotplug_bridge =1 ; + pdev->is_hotplug_bridge = pdev->is_pciehp =1 ; }static void set_pcie_thunderbolt (struct pci_dev *dev)
include/linux/pci.h +9 -1
@@ -317,7 +317,14 @@ struct pci_sriov;struct pci_p2pdma ;struct rcec_ea ; -/* The pci_dev structure describes PCI devices */ +/* struct pci_dev - describes a PCI device +* +* @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable, +* Conventional PCI Hot-Plug, ACPI slot). +* Such bridges are allocated additional MMIO and bus +* number resources to allow for hierarchy expansion. +* @is_pciehp: PCIe Hot-Plug Capable bridge. +*/ struct pci_dev {struct list_head bus_list;/* Node in per-bus list */ struct pci_bus *bus;/* Bus this device is on */
@@ -438,6 +445,7 @@ struct pci_dev { unsigned int is_physfn:1; unsigned int is_virtfn:1; unsigned int is_hotplug_bridge:1; + unsigned int is_pciehp:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ unsigned int is_thunderbolt:1; /* Thunderbolt controller *//*
Greg Kroah-Hartman
maintainerPATCH 358/482 cifs: reset iface weights when we cannot find a candidate
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
[ Upstream commit 9d5eff7821f6d70f7d1b4d8a60680fba4de868a7 ]
We now do a weighted selection of server interfaces when allocating new channels. The weights are decided based on the speed advertised. The fulfilled weight for an interface is a counter that is used to track the interface selection. It should be reset back to zero once all interfaces fulfilling their weight.
In cifs_chan_update_iface, this reset logic was missing. As a result when the server interface list changes, the client may not be able to find a new candidate for other channels after all interfaces have been fulfilled.
--- fs/smb/client/sess.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/smb/client/sess.c +9 -0
@@ -292,6 +292,7 @@ cifs_chan_update_iface(struct cifs_ses *struct cifs_server_iface *last_iface =NULL ;struct sockaddr_storage ss;int rc =0 ; +int retry =0 ;spin_lock (&ses->chan_lock); chan_index =cifs_ses_get_chan_index (ses, server);
@@ -320,6 +321,7 @@ cifs_chan_update_iface(struct cifs_ses *return 0 ; } +try_again: last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface, iface_head); iface_min_speed = last_iface->speed;
@@ -358,6 +360,13 @@ cifs_chan_update_iface(struct cifs_ses *if (list_entry_is_head (iface, &ses->iface_list, iface_head)) { rc =1 ; +list_for_each_entry (iface, &ses->iface_list, iface_head) + iface->weight_fulfilled =0 ; + +/* see if it can be satisfied in second attempt */ +if (!retry++) + goto try_again; + iface =NULL ;cifs_dbg (FYI ,"unable to find a suitable iface\n" ); }
Greg Kroah-Hartman
maintainerPATCH 359/482 usb: typec: fusb302: cache PD RX state
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Reichel <[email protected]>
[ Upstream commit 1e61f6ab08786d66a11cfc51e13d6f08a6b06c56 ]
This patch fixes a race condition communication error, which ends up in PD hard resets when losing the race. Some systems, like the Radxa ROCK 5B are powered through USB-C without any backup power source and use a FUSB302 chip to do the PD negotiation. This means it is quite important to avoid hard resets, since that effectively kills the system's power-supply.
I've found the following race condition while debugging unplanned power loss during booting the board every now and then:
1. lots of TCPM/FUSB302/PD initialization stuff
2. TCPM ends up in SNK_WAIT_CAPABILITIES (tcpm_set_pd_rx is enabled here)
3. the remote PD source does not send anything, so TCPM does a SOFT RESET
4. TCPM ends up in SNK_WAIT_CAPABILITIES for the second time (tcpm_set_pd_rx is enabled again, even though it is still on)
At this point I've seen broken CRC good messages being send by the FUSB302 with a logic analyzer sniffing the CC lines. Also it looks like messages are being lost and things generally going haywire with one of the two sides doing a hard reset once a broken CRC good message was send to the bus.
I think the system is running into a race condition, that the FIFOs are being cleared and/or the automatic good CRC message generation flag is being updated while a message is already arriving.
Let's avoid this by caching the PD RX enabled state, as we have already processed anything in the FIFOs and are in a good state. As a side effect that this also optimizes I2C bus usage :)
As far as I can tell the problem theoretically also exists when TCPM enters SNK_WAIT_CAPABILITIES the first time, but I believe this is less critical for the following reason:
On devices like the ROCK 5B, which are powered through a TCPM backed USB-C port, the bootloader must have done some prior PD communication (initial communication must happen within 5 seconds after plugging the USB-C plug). This means the first time the kernel TCPM state machine reaches SNK_WAIT_CAPABILITIES, the remote side is not sending messages actively. On other devices a hard reset simply adds some extra delay and things should be good afterwards.
--- drivers/usb/typec/tcpm/fusb302.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/usb/typec/tcpm/fusb302.c +8 -0
@@ -103,6 +103,7 @@ struct fusb302_chip {bool vconn_on;bool vbus_on;bool charge_on; +bool pd_rx_on;bool vbus_present;enum typec_cc_polarity cc_polarity;enum typec_cc_status cc1;
@@ -841,6 +842,11 @@ static int tcpm_set_pd_rx(struct tcpc_deint ret =0 ;mutex_lock (&chip->lock); +if (chip->pd_rx_on == on) { +fusb302_log (chip,"pd is already %s" ,str_on_off (on)); + goto done; + } + ret =fusb302_pd_rx_flush (chip);if (ret <0 ) {fusb302_log (chip,"cannot flush pd rx buffer, ret=%d" , ret);
@@ -863,6 +869,8 @@ static int tcpm_set_pd_rx(struct tcpc_de on ? "on" : "off", ret); goto done; } + + chip->pd_rx_on = on;fusb302_log (chip,"pd := %s" , on ?"on" :"off" ); done:mutex_unlock (&chip->lock);
Greg Kroah-Hartman
maintainerPATCH 360/482 btrfs: qgroup: fix race between quota disable and quota rescan ioctl
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit e1249667750399a48cafcf5945761d39fa584edf ]
There's a race between a task disabling quotas and another running the rescan ioctl that can result in a use-after-free of qgroup records from the fs_info->qgroup_tree rbtree.
This happens as follows:
1) Task A enters btrfs_ioctl_quota_rescan() -> btrfs_qgroup_rescan();
2) Task B enters btrfs_quota_disable() and calls btrfs_qgroup_wait_for_completion(), which does nothing because at that point fs_info->qgroup_rescan_running is false (it wasn't set yet by task A);
3) Task B calls btrfs_free_qgroup_config() which starts freeing qgroups from fs_info->qgroup_tree without taking the lock fs_info->qgroup_lock;
4) Task A enters qgroup_rescan_zero_tracking() which starts iterating the fs_info->qgroup_tree tree while holding fs_info->qgroup_lock, but task B is freeing qgroup records from that tree without holding the lock, resulting in a use-after-free.
Fix this by taking fs_info->qgroup_lock at btrfs_free_qgroup_config(). Also at btrfs_qgroup_rescan() don't start the rescan worker if quotas were already disabled.
--- fs/btrfs/qgroup.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-)
fs/btrfs/qgroup.c +24 -7
@@ -573,22 +573,30 @@ bool btrfs_check_quota_leak(struct btrfs/* * This is called from close_ctree() or open_ctree() or btrfs_quota_disable(), -* first two are in single-threaded paths.And for the third one, we have set -* quota_root to be null with qgroup_lock held before, so it is safe to clean -* up the in-memory structures without qgroup_lock held. +* first two are in single-threaded paths. */ void btrfs_free_qgroup_config (struct btrfs_fs_info *fs_info) {struct rb_node *n;struct btrfs_qgroup *qgroup; +/* +* btrfs_quota_disable() can be called concurrently with +* btrfs_qgroup_rescan() -> qgroup_rescan_zero_tracking(), so take the +* lock. +*/ +spin_lock (&fs_info->qgroup_lock);while ((n =rb_first (&fs_info->qgroup_tree))) { qgroup = rb_entry(n, struct btrfs_qgroup, node);rb_erase (n, &fs_info->qgroup_tree);__del_qgroup_rb (fs_info, qgroup); +spin_unlock (&fs_info->qgroup_lock);btrfs_sysfs_del_one_qgroup (fs_info, qgroup);kfree (qgroup); +spin_lock (&fs_info->qgroup_lock); } +spin_unlock (&fs_info->qgroup_lock); +/* * We call btrfs_free_qgroup_config() when unmounting * filesystem and disabling quota, so we set qgroup_ulist
@@ -3597,12 +3605,21 @@ btrfs_qgroup_rescan(struct btrfs_fs_infoqgroup_rescan_zero_tracking (fs_info);mutex_lock (&fs_info->qgroup_rescan_lock); - fs_info->qgroup_rescan_running = true; -btrfs_queue_work (fs_info->qgroup_rescan_workers, - &fs_info->qgroup_rescan_work); +/* +* The rescan worker is only for full accounting qgroups, check if it's +* enabled as it is pointless to queue it otherwise. A concurrent quota +* disable may also have just cleared BTRFS_FS_QUOTA_ENABLED. +*/ +if (test_bit (BTRFS_FS_QUOTA_ENABLED , &fs_info->flags)) { + fs_info->qgroup_rescan_running = true; +btrfs_queue_work (fs_info->qgroup_rescan_workers, + &fs_info->qgroup_rescan_work); + }else { + ret = -ENOTCONN ; + }mutex_unlock (&fs_info->qgroup_rescan_lock); -return 0 ; +return ret; } int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info,
Greg Kroah-Hartman
maintainerPATCH 361/482 btrfs: abort transaction on unexpected eb generation at btrfs_copy_root()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 33e8f24b52d2796b8cfb28c19a1a7dd6476323a8 ]
If we find an unexpected generation for the extent buffer we are cloning at btrfs_copy_root(), we just WARN_ON() and don't error out and abort the transaction, meaning we allow to persist metadata with an unexpected generation. Instead of warning only, abort the transaction and return -EUCLEAN.
--- fs/btrfs/ctree.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/btrfs/ctree.c +8 -1
@@ -237,7 +237,14 @@ int btrfs_copy_root(struct btrfs_trans_hwrite_extent_buffer_fsid (cow, fs_info->fs_devices->metadata_uuid); -WARN_ON (btrfs_header_generation (buf) > trans->transid); +if (unlikely (btrfs_header_generation (buf) > trans->transid)) { +btrfs_tree_unlock (cow); +free_extent_buffer (cow); + ret = -EUCLEAN ; +btrfs_abort_transaction (trans, ret); +return ret; + } +if (new_root_objectid ==BTRFS_TREE_RELOC_OBJECTID ) ret =btrfs_inc_ref (trans, root, cow,1 );else
Greg Kroah-Hartman
maintainerPATCH 362/482 xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit d2845519b0723c5d5a0266cbf410495f9b8fd65c ]
Fix up xfs_inumbers to now pass in the XFS_IBULK* flags into the flags argument to xfs_inobt_walk, which expects the XFS_IWALK* flags.
Currently passing the wrong flags works for non-debug builds because the only XFS_IWALK* flag has the same encoding as the corresponding XFS_IBULK* flag, but in debug builds it can trigger an assert that no incorrect flag is passed. Instead just extra the relevant flag.
--- fs/xfs/xfs_itable.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/xfs/xfs_itable.c +5 -1
@@ -422,11 +422,15 @@ xfs_inumbers( .breq = breq, };struct xfs_trans *tp; +unsigned int iwalk_flags =0 ;int error =0 ;if (xfs_bulkstat_already_done (breq->mp, breq->startino))return 0 ; +if (breq->flags &XFS_IBULK_SAME_AG ) + iwalk_flags |=XFS_IWALK_SAME_AG ; +/* * Grab an empty transaction so that we can use its recursive buffer * locking abilities to detect cycles in the inobt without deadlocking.
@@ -435,7 +439,7 @@ xfs_inumbers(if (error) goto out; - error =xfs_inobt_walk (breq->mp, tp, breq->startino, breq->flags, + error =xfs_inobt_walk (breq->mp, tp, breq->startino, iwalk_flags, xfs_inumbers_walk, breq->icount, &ic);xfs_trans_cancel (tp); out:
Greg Kroah-Hartman
maintainerPATCH 363/482 btrfs: send: use fallocate for hole punching with send stream v2
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 005b0a0c24e1628313e951516b675109a92cacfe ]
Currently holes are sent as writes full of zeroes, which results in unnecessarily using disk space at the receiving end and increasing the stream size.
In some cases we avoid sending writes of zeroes, like during a full send operation where we just skip writes for holes.
But for some cases we fill previous holes with writes of zeroes too, like in this scenario:
1) We have a file with a hole in the range [2M, 3M), we snapshot the subvolume and do a full send. The range [2M, 3M) stays as a hole at the receiver since we skip sending write commands full of zeroes;
2) We punch a hole for the range [3M, 4M) in our file, so that now it has a 2M hole in the range [2M, 4M), and snapshot the subvolume. Now if we do an incremental send, we will send write commands full of zeroes for the range [2M, 4M), removing the hole for [2M, 3M) at the receiver.
We could improve cases such as this last one by doing additional comparisons of file extent items (or their absence) between the parent and send snapshots, but that's a lot of code to add plus additional CPU and IO costs.
Since the send stream v2 already has a fallocate command and btrfs-progs implements a callback to execute fallocate since the send stream v2 support was added to it, update the kernel to use fallocate for punching holes for V2+ streams.
Test coverage is provided by btrfs/284 which is a version of btrfs/007 that exercises send stream v2 instead of v1, using fsstress with random operations and fssum to verify file contents.
--- fs/btrfs/send.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
fs/btrfs/send.c +39 -0
@@ -4,6 +4,7 @@*/ #include <linux/bsearch.h> +#include <linux/falloc.h> #include <linux/fs.h> #include <linux/file.h> #include <linux/sort.h>
@@ -5231,6 +5232,36 @@ out:return ret; } +static int send_fallocate (struct send_ctx *sctx,u32 mode,u64 offset,u64 len) +{ +struct fs_path *p; +int ret; + + p =fs_path_alloc (); +if (!p) +return -ENOMEM ; + + ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); +if (ret <0 ) + goto out; + + ret =begin_cmd (sctx,BTRFS_SEND_C_FALLOCATE ); +if (ret <0 ) + goto out; + +TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p); +TLV_PUT_U32 (sctx,BTRFS_SEND_A_FALLOCATE_MODE , mode); +TLV_PUT_U64 (sctx,BTRFS_SEND_A_FILE_OFFSET , offset); +TLV_PUT_U64 (sctx,BTRFS_SEND_A_SIZE , len); + + ret =send_cmd (sctx); + +tlv_put_failure: +out: +fs_path_free (p); +return ret; +} +static int send_hole (struct send_ctx *sctx,u64 end) {struct fs_path *p =NULL ;
@@ -5239,6 +5270,14 @@ static int send_hole(struct send_ctx *scint ret =0 ;/* +* Starting with send stream v2 we have fallocate and can use it to +* punch holes instead of sending writes full of zeroes. +*/ +if (proto_cmd_ok (sctx,BTRFS_SEND_C_FALLOCATE )) +return send_fallocate (sctx,FALLOC_FL_PUNCH_HOLE |FALLOC_FL_KEEP_SIZE , + offset, end - offset); + +/* * A hole that starts at EOF or beyond it. Since we do not yet support * fallocate (for extent preallocation and hole punching), sending a * write of zeroes starting at EOF or beyond would later require issuing
Greg Kroah-Hartman
maintainerPATCH 364/482 net_sched: sch_ets: implement lockless ets_dump()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit c5f1dde7f731e7bf2e7c169ca42cb4989fc2f8b9 ]
Instead of relying on RTNL, ets_dump() can use READ_ONCE() annotations, paired with WRITE_ONCE() ones in ets_change().
Stable-dep-of: 87c6efc5ce9c ("net/sched: ets: use old 'nbands' while purging unused classes")
--- net/sched/sch_ets.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
net/sched/sch_ets.c +14 -11
@@ -651,7 +651,7 @@ static int ets_qdisc_change(struct Qdiscsch_tree_lock (sch); - q->nbands = nbands; +WRITE_ONCE (q->nbands, nbands);for (i = nstrict; i < q->nstrict; i++) {if (q->classes[i].qdisc->q.qlen) {list_add_tail (&q->classes[i].alist, &q->active);
@@ -663,11 +663,11 @@ static int ets_qdisc_change(struct Qdisclist_del_init (&q->classes[i].alist);qdisc_purge_queue (q->classes[i].qdisc); } - q->nstrict = nstrict; +WRITE_ONCE (q->nstrict, nstrict);memcpy (q->prio2band, priomap,sizeof (priomap));for (i =0 ; i < q->nbands; i++) - q->classes[i].quantum = quanta[i]; +WRITE_ONCE (q->classes[i].quantum, quanta[i]);for (i = oldbands; i < q->nbands; i++) { q->classes[i].qdisc = queues[i];
@@ -681,7 +681,7 @@ static int ets_qdisc_change(struct Qdiscfor (i = q->nbands; i < oldbands; i++) {qdisc_put (q->classes[i].qdisc); q->classes[i].qdisc =NULL ; - q->classes[i].quantum =0 ; +WRITE_ONCE (q->classes[i].quantum,0 ); q->classes[i].deficit =0 ;gnet_stats_basic_sync_init (&q->classes[i].bstats);memset (&q->classes[i].qstats,0 ,sizeof (q->classes[i].qstats));
@@ -738,6 +738,7 @@ static int ets_qdisc_dump(struct Qdisc *struct ets_sched *q =qdisc_priv (sch);struct nlattr *opts;struct nlattr *nest; +u8 nbands, nstrict;int band;int prio;int err;
@@ -750,21 +751,22 @@ static int ets_qdisc_dump(struct Qdisc *if (!opts) goto nla_err; -if (nla_put_u8 (skb,TCA_ETS_NBANDS , q->nbands)) + nbands =READ_ONCE (q->nbands); +if (nla_put_u8 (skb,TCA_ETS_NBANDS , nbands)) goto nla_err; -if (q->nstrict && -nla_put_u8 (skb,TCA_ETS_NSTRICT , q->nstrict)) + nstrict =READ_ONCE (q->nstrict); +if (nstrict &&nla_put_u8 (skb,TCA_ETS_NSTRICT , nstrict)) goto nla_err; -if (q->nbands > q->nstrict) { +if (nbands > nstrict) { nest =nla_nest_start (skb,TCA_ETS_QUANTA );if (!nest) goto nla_err; -for (band = q->nstrict; band < q->nbands; band++) { +for (band = nstrict; band < nbands; band++) {if (nla_put_u32 (skb,TCA_ETS_QUANTA_BAND , - q->classes[band].quantum)) +READ_ONCE (q->classes[band].quantum))) goto nla_err; }
@@ -776,7 +778,8 @@ static int ets_qdisc_dump(struct Qdisc * goto nla_err;for (prio =0 ; prio <=TC_PRIO_MAX ; prio++) { -if (nla_put_u8 (skb,TCA_ETS_PRIOMAP_BAND , q->prio2band[prio])) +if (nla_put_u8 (skb,TCA_ETS_PRIOMAP_BAND , +READ_ONCE (q->prio2band[prio]))) goto nla_err; }
Greg Kroah-Hartman
maintainerPATCH 365/482 net/sched: ets: use old nbands while purging unused classes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davide Caratti <[email protected]>
[ Upstream commit 87c6efc5ce9c126ae4a781bc04504b83780e3650 ]
Shuang reported sch_ets test-case [1] crashing in ets_class_qlen_notify() after recent changes from Lion [2]. The problem is: in ets_qdisc_change() we purge unused DWRR queues; the value of 'q->nbands' is the new one, and the cleanup should be done with the old one. The problem is here since my first attempts to fix ets_qdisc_change(), but it surfaced again after the recent qdisc len accounting fixes. Fix it purging idle DWRR queues before assigning a new value of 'q->nbands', so that all purge operations find a consistent configuration:
- old 'q->nbands' because it's needed by ets_class_find()
- old 'q->nstrict' because it's needed by ets_class_is_strict()
BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 62 UID: 0 PID: 39457 Comm: tc Kdump: loaded Not tainted 6.12.0-116.el10.x86_64 #1 PREEMPT(voluntary) Hardware name: Dell Inc. PowerEdge R640/06DKY5, BIOS 2.12.2 07/09/2021 RIP: 0010:__list_del_entry_valid_or_report+0x4/0x80 Code: ff 4c 39 c7 0f 84 39 19 8e ff b8 01 00 00 00 c3 cc cc cc cc 66 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa <48> 8b 17 48 8b 4f 08 48 85 d2 0f 84 56 19 8e ff 48 85 c9 0f 84 ab RSP: 0018:ffffba186009f400 EFLAGS: 00010202 RAX: 00000000000000d6 RBX: 0000000000000000 RCX: 0000000000000004 RDX: ffff9f0fa29b69c0 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffffffc12c2400 R08: 0000000000000008 R09: 0000000000000004 R10: ffffffffffffffff R11: 0000000000000004 R12: 0000000000000000 R13: ffff9f0f8cfe0000 R14: 0000000000100005 R15: 0000000000000000 FS: 00007f2154f37480(0000) GS:ffff9f269c1c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001530be001 CR4: 00000000007726f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> ets_class_qlen_notify+0x65/0x90 [sch_ets] qdisc_tree_reduce_backlog+0x74/0x110 ets_qdisc_change+0x630/0xa40 [sch_ets] __tc_modify_qdisc.constprop.0+0x216/0x7f0 tc_modify_qdisc+0x7c/0x120 rtnetlink_rcv_msg+0x145/0x3f0 netlink_rcv_skb+0x53/0x100 netlink_unicast+0x245/0x390 netlink_sendmsg+0x21b/0x470 ____sys_sendmsg+0x39d/0x3d0 ___sys_sendmsg+0x9a/0xe0 __sys_sendmsg+0x7a/0xd0 do_syscall_64+0x7d/0x160 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f2155114084 Code: 89 02 b8 ff ff ff ff eb bb 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 80 3d 25 f0 0c 00 00 74 13 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 89 54 24 1c 48 89 RSP: 002b:00007fff1fd7a988 EFLAGS: 00000202 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000560ec063e5e0 RCX: 00007f2155114084 RDX: 0000000000000000 RSI: 00007fff1fd7a9f0 RDI: 0000000000000003 RBP: 00007fff1fd7aa60 R08: 0000000000000010 R09: 000000000000003f R10: 0000560ee9b3a010 R11: 0000000000000202 R12: 00007fff1fd7aae0 R13: 000000006891ccde R14: 0000560ec063e5e0 R15: 00007fff1fd7aad0 </TASK>
[1] https://lore.kernel.org/netdev/e08c7f4a6882f260011909a868311c6e9b54f3e4.1639153474.git.dcaratti@redhat.com/
[2] https://lore.kernel.org/netdev/[email protected]/
--- net/sched/sch_ets.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/sched/sch_ets.c +6 -5
@@ -651,6 +651,12 @@ static int ets_qdisc_change(struct Qdiscsch_tree_lock (sch); +for (i = nbands; i < oldbands; i++) { +if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) +list_del_init (&q->classes[i].alist); +qdisc_purge_queue (q->classes[i].qdisc); + } +WRITE_ONCE (q->nbands, nbands);for (i = nstrict; i < q->nstrict; i++) {if (q->classes[i].qdisc->q.qlen) {
@@ -658,11 +664,6 @@ static int ets_qdisc_change(struct Qdisc q->classes[i].deficit = quanta[i]; } } -for (i = q->nbands; i < oldbands; i++) { -if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) -list_del_init (&q->classes[i].alist); -qdisc_purge_queue (q->classes[i].qdisc); - }WRITE_ONCE (q->nstrict, nstrict);memcpy (q->prio2band, priomap,sizeof (priomap));
Greg Kroah-Hartman
maintainerPATCH 366/482 mm/ptdump: take the memory hotplug lock inside ptdump_walk_pgd()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anshuman Khandual <[email protected]>
[ Upstream commit 59305202c67fea50378dcad0cc199dbc13a0e99a ]
Memory hot remove unmaps and tears down various kernel page table regions as required. The ptdump code can race with concurrent modifications of the kernel page tables. When leaf entries are modified concurrently, the dump code may log stale or inconsistent information for a VA range, but this is otherwise not harmful.
But when intermediate levels of kernel page table are freed, the dump code will continue to use memory that has been freed and potentially reallocated for another purpose. In such cases, the ptdump code may dereference bogus addresses, leading to a number of potential problems.
To avoid the above mentioned race condition, platforms such as arm64, riscv and s390 take memory hotplug lock, while dumping kernel page table via the sysfs interface /sys/kernel/debug/kernel_page_tables.
Similar race condition exists while checking for pages that might have been marked W+X via /sys/kernel/debug/kernel_page_tables/check_wx_pages which in turn calls ptdump_check_wx(). Instead of solving this race condition again, let's just move the memory hotplug lock inside generic ptdump_check_wx() which will benefit both the scenarios.
Drop get_online_mems() and put_online_mems() combination from all existing platform ptdump code paths.
--- arch/arm64/mm/ptdump_debugfs.c | 3 --- arch/s390/mm/dump_pagetables.c | 2 -- mm/ptdump.c | 2 ++ 3 files changed, 2 insertions(+), 5 deletions(-)
arch/arm64/mm/ptdump_debugfs.c +0 -3
@@ -1,6 +1,5 @@// SPDX-License-Identifier: GPL-2.0 #include <linux/debugfs.h> -#include <linux/memory_hotplug.h> #include <linux/seq_file.h> #include <asm/ptdump.h>
@@ -9,9 +8,7 @@ static int ptdump_show(struct seq_file * {struct ptdump_info *info = m->private; -get_online_mems ();ptdump_walk (m, info); -put_online_mems ();return 0 ; }DEFINE_SHOW_ATTRIBUTE (ptdump);
arch/s390/mm/dump_pagetables.c +0 -2
@@ -249,11 +249,9 @@ static int ptdump_show(struct seq_file * .marker = address_markers, }; -get_online_mems ();mutex_lock (&cpa_mutex);ptdump_walk_pgd (&st.ptdump, &init_mm,NULL );mutex_unlock (&cpa_mutex); -put_online_mems ();return 0 ; }DEFINE_SHOW_ATTRIBUTE (ptdump);
mm/ptdump.c +2 -0
@@ -152,6 +152,7 @@ void ptdump_walk_pgd(struct ptdump_state {const struct ptdump_range *range = st->range; +get_online_mems ();mmap_write_lock (mm);while (range->start != range->end) { walk_page_range_novma(mm, range->start, range->end,
@@ -159,6 +160,7 @@ void ptdump_walk_pgd(struct ptdump_state range++; }mmap_write_unlock (mm); +put_online_mems ();/* Flush out the last page */ st->note_page (st,0 ,-1 ,0 );
Greg Kroah-Hartman
maintainerPATCH 367/482 media: venus: Introduce accessors for remapped hfi_buffer_reqs members
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit bbfc89e6f67ccb1ddefc3e8a284248bcfea58544 ]
Currently we have macros to access these, but they don't provide a way to override the remapped fields. Replace the macros with actual get/set pairs to fix that.
Stable-dep-of: 06d6770ff0d8 ("media: venus: Fix OOB read due to missing payload bound check")
--- drivers/media/platform/qcom/venus/helpers.c | 2 drivers/media/platform/qcom/venus/hfi_helper.h | 61 +++++++++++++++++++++---- drivers/media/platform/qcom/venus/hfi_msgs.c | 2 drivers/media/platform/qcom/venus/vdec.c | 8 +-- drivers/media/platform/qcom/venus/vdec_ctrls.c | 2 drivers/media/platform/qcom/venus/venc.c | 4 - drivers/media/platform/qcom/venus/venc_ctrls.c | 2 7 files changed, 63 insertions(+), 18 deletions(-)
drivers/media/platform/qcom/venus/helpers.c +1 -1
@@ -189,7 +189,7 @@ int venus_helper_alloc_dpb_bufs(struct vif (ret)return ret; - count =HFI_BUFREQ_COUNT_MIN (&bufreq, ver); + count =hfi_bufreq_get_count_min (&bufreq, ver);for (i =0 ; i < count; i++) { buf =kzalloc (sizeof (*buf),GFP_KERNEL );
drivers/media/platform/qcom/venus/hfi_helper.h +53 -8
73 lines not on this page · raw message
drivers/media/platform/qcom/venus/hfi_msgs.c +1 -1
@@ -99,7 +99,7 @@ static void event_seq_changed(struct vencase HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS : data_ptr +=sizeof (u32); bufreq = (struct hfi_buffer_requirements *)data_ptr; - event.buf_count =HFI_BUFREQ_COUNT_MIN (bufreq, ver); + event.buf_count =hfi_bufreq_get_count_min (bufreq, ver); data_ptr +=sizeof (*bufreq);break ;case HFI_INDEX_EXTRADATA_INPUT_CROP :
drivers/media/platform/qcom/venus/vdec.c +4 -4
@@ -864,13 +864,13 @@ static int vdec_num_buffers(struct venusif (ret)return ret; - *in_num =HFI_BUFREQ_COUNT_MIN (&bufreq, ver); + *in_num =hfi_bufreq_get_count_min (&bufreq, ver); ret =venus_helper_get_bufreq (inst,HFI_BUFFER_OUTPUT , &bufreq);if (ret)return ret; - *out_num =HFI_BUFREQ_COUNT_MIN (&bufreq, ver); + *out_num =hfi_bufreq_get_count_min (&bufreq, ver);return 0 ; }
@@ -984,14 +984,14 @@ static int vdec_verify_conf(struct venusreturn ret;if (inst->num_output_bufs < bufreq.count_actual || - inst->num_output_bufs <HFI_BUFREQ_COUNT_MIN (&bufreq, ver)) + inst->num_output_bufs <hfi_bufreq_get_count_min (&bufreq, ver))return -EINVAL ; ret =venus_helper_get_bufreq (inst,HFI_BUFFER_INPUT , &bufreq);if (ret)return ret; -if (inst->num_input_bufs <HFI_BUFREQ_COUNT_MIN (&bufreq, ver)) +if (inst->num_input_bufs <hfi_bufreq_get_count_min (&bufreq, ver))return -EINVAL ;return 0 ;
drivers/media/platform/qcom/venus/vdec_ctrls.c +1 -1
@@ -79,7 +79,7 @@ static int vdec_op_g_volatile_ctrl(struccase V4L2_CID_MIN_BUFFERS_FOR_CAPTURE : ret =venus_helper_get_bufreq (inst,HFI_BUFFER_OUTPUT , &bufreq);if (!ret) - ctrl->val =HFI_BUFREQ_COUNT_MIN (&bufreq, ver); + ctrl->val =hfi_bufreq_get_count_min (&bufreq, ver);break ;default :return -EINVAL ;
drivers/media/platform/qcom/venus/venc.c +2 -2
@@ -1176,7 +1176,7 @@ static int venc_verify_conf(struct venusreturn ret;if (inst->num_output_bufs < bufreq.count_actual || - inst->num_output_bufs <HFI_BUFREQ_COUNT_MIN (&bufreq, ver)) + inst->num_output_bufs <hfi_bufreq_get_count_min (&bufreq, ver))return -EINVAL ; ret =venus_helper_get_bufreq (inst,HFI_BUFFER_INPUT , &bufreq);
@@ -1184,7 +1184,7 @@ static int venc_verify_conf(struct venusreturn ret;if (inst->num_input_bufs < bufreq.count_actual || - inst->num_input_bufs <HFI_BUFREQ_COUNT_MIN (&bufreq, ver)) + inst->num_input_bufs <hfi_bufreq_get_count_min (&bufreq, ver))return -EINVAL ;return 0 ;
drivers/media/platform/qcom/venus/venc_ctrls.c +1 -1
@@ -358,7 +358,7 @@ static int venc_op_g_volatile_ctrl(struccase V4L2_CID_MIN_BUFFERS_FOR_OUTPUT : ret =venus_helper_get_bufreq (inst,HFI_BUFFER_INPUT , &bufreq);if (!ret) - ctrl->val =HFI_BUFREQ_COUNT_MIN (&bufreq, ver); + ctrl->val =hfi_bufreq_get_count_min (&bufreq, ver);break ;default :return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 368/482 media: venus: Fix OOB read due to missing payload bound check
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vedang Nagar <[email protected]>
[ Upstream commit 06d6770ff0d8cc8dfd392329a8cc03e2a83e7289 ]
Currently, The event_seq_changed() handler processes a variable number of properties sent by the firmware. The number of properties is indicated by the firmware and used to iterate over the payload. However, the payload size is not being validated against the actual message length.
This can lead to out-of-bounds memory access if the firmware provides a property count that exceeds the data available in the payload. Such a condition can result in kernel crashes or potential information leaks if memory beyond the buffer is accessed.
Fix this by properly validating the remaining size of the payload before each property access and updating bounds accordingly as properties are parsed.
This ensures that property parsing is safely bounded within the received message buffer and protects against malformed or malicious firmware behavior.
--- drivers/media/platform/qcom/venus/hfi_msgs.c | 83 ++++++++++++++++++--------- 1 file changed, 58 insertions(+), 25 deletions(-)
drivers/media/platform/qcom/venus/hfi_msgs.c +58 -25
@@ -33,8 +33,9 @@ static void event_seq_changed(struct venstruct hfi_buffer_requirements *bufreq;struct hfi_extradata_input_crop *crop;struct hfi_dpb_counts *dpb_count; +u32 ptype, rem_bytes; +u32 size_read =0 ;u8 *data_ptr; -u32 ptype; inst->error =HFI_ERR_NONE ;
@@ -44,86 +45,118 @@ static void event_seq_changed(struct venbreak ;default : inst->error =HFI_ERR_SESSION_INVALID_PARAMETER ; - goto done; + inst->ops->event_notify (inst,EVT_SYS_EVENT_CHANGE , &event); +return ; } event.event_type = pkt->event_data1; num_properties_changed = pkt->event_data2; -if (!num_properties_changed) { - inst->error =HFI_ERR_SESSION_INSUFFICIENT_RESOURCES ; - goto done; - } +if (!num_properties_changed) + goto error; data_ptr = (u8 *)&pkt->ext_event_data[0 ]; + rem_bytes = pkt->shdr.hdr.size -sizeof (*pkt); +do { +if (rem_bytes <sizeof (u32)) + goto error; ptype = *((u32 *)data_ptr); + + data_ptr +=sizeof (u32); + rem_bytes -=sizeof (u32); +switch (ptype) {case HFI_PROPERTY_PARAM_FRAME_SIZE : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_framesize )) + goto error; + frame_sz = (struct hfi_framesize *)data_ptr; event.width = frame_sz->width; event.height = frame_sz->height; - data_ptr +=sizeof (*frame_sz); + size_read =sizeof (struct hfi_framesize );break ;case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_profile_level )) + goto error; + profile_level = (struct hfi_profile_level *)data_ptr; event.profile = profile_level->profile; event.level = profile_level->level; - data_ptr +=sizeof (*profile_level); + size_read =sizeof (struct hfi_profile_level );break ;case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_bit_depth )) + goto error; + pixel_depth = (struct hfi_bit_depth *)data_ptr; event.bit_depth = pixel_depth->bit_depth; - data_ptr +=sizeof (*pixel_depth); + size_read =sizeof (struct hfi_bit_depth );break ;case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_pic_struct )) + goto error; + pic_struct = (struct hfi_pic_struct *)data_ptr; event.pic_struct = pic_struct->progressive_only; - data_ptr +=sizeof (*pic_struct); + size_read =sizeof (struct hfi_pic_struct );break ;case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_colour_space )) + goto error; + colour_info = (struct hfi_colour_space *)data_ptr; event.colour_space = colour_info->colour_space; - data_ptr +=sizeof (*colour_info); + size_read =sizeof (struct hfi_colour_space );break ;case HFI_PROPERTY_CONFIG_VDEC_ENTROPY : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (u32)) + goto error; + event.entropy_mode = *(u32 *)data_ptr; - data_ptr +=sizeof (u32); + size_read =sizeof (u32);break ;case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_buffer_requirements )) + goto error; + bufreq = (struct hfi_buffer_requirements *)data_ptr; event.buf_count =hfi_bufreq_get_count_min (bufreq, ver); - data_ptr +=sizeof (*bufreq); + size_read =sizeof (struct hfi_buffer_requirements );break ;case HFI_INDEX_EXTRADATA_INPUT_CROP : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_extradata_input_crop )) + goto error; + crop = (struct hfi_extradata_input_crop *)data_ptr; event.input_crop.left = crop->left; event.input_crop.top = crop->top; event.input_crop.width = crop->width; event.input_crop.height = crop->height; - data_ptr +=sizeof (*crop); + size_read =sizeof (struct hfi_extradata_input_crop );break ;case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS : - data_ptr +=sizeof (u32); +if (rem_bytes <sizeof (struct hfi_dpb_counts )) + goto error; + dpb_count = (struct hfi_dpb_counts *)data_ptr; event.buf_count = dpb_count->fw_min_cnt; - data_ptr +=sizeof (*dpb_count); + size_read =sizeof (struct hfi_dpb_counts );break ;default : + size_read =0 ;break ; } + data_ptr += size_read; + rem_bytes -= size_read; num_properties_changed--; }while (num_properties_changed >0 ); -done: + inst->ops->event_notify (inst,EVT_SYS_EVENT_CHANGE , &event); +return ; + +error: + inst->error =HFI_ERR_SESSION_INSUFFICIENT_RESOURCES ; inst->ops->event_notify (inst,EVT_SYS_EVENT_CHANGE , &event); }
Greg Kroah-Hartman
maintainerPATCH 369/482 usb: musb: omap2430: Convert to platform remove callback returning void
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit cb020bf52253327fe382e10bcae02a4f1da33c04 ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is (mostly) ignored and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void.
Trivially convert this driver from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: 1473e9e7679b ("usb: musb: omap2430: fix device leak at unbind")
--- drivers/usb/musb/omap2430.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/usb/musb/omap2430.c +2 -4
@@ -471,14 +471,12 @@ err0:return ret; } -static int omap2430_remove (struct platform_device *pdev) +static void omap2430_remove (struct platform_device *pdev) {struct omap2430_glue *glue =platform_get_drvdata (pdev);platform_device_unregister (glue->musb);pm_runtime_disable (glue->dev); - -return 0 ; }#ifdef CONFIG_PM
@@ -610,7 +608,7 @@ MODULE_DEVICE_TABLE(of, omap2430_id_tablstatic struct platform_driver omap2430_driver = { .probe = omap2430_probe, - .remove = omap2430_remove, + .remove_new = omap2430_remove, .driver = { .name ="musb-omap2430" , .pm =DEV_PM_OPS ,
Greg Kroah-Hartman
maintainerPATCH 370/482 usb: musb: omap2430: fix device leak at unbind
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 1473e9e7679bd4f5a62d1abccae894fb86de280f ]
Make sure to drop the reference to the control device taken by of_find_device_by_node() during probe when the driver is unbound.
--- drivers/usb/musb/omap2430.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/usb/musb/omap2430.c +9 -5
@@ -400,7 +400,7 @@ static int omap2430_probe(struct platfor ret =platform_device_add_resources (musb, pdev->resource, pdev->num_resources);if (ret) {dev_err (&pdev->dev,"failed to add resources\n" ); - goto err2; + goto err_put_control_otghs; }if (populate_irqs) {
@@ -413,7 +413,7 @@ static int omap2430_probe(struct platfor res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!res) { ret = -EINVAL ; - goto err2; + goto err_put_control_otghs; } musb_res[i].start = res->start;
@@ -441,14 +441,14 @@ static int omap2430_probe(struct platfor ret =platform_device_add_resources (musb, musb_res, i);if (ret) {dev_err (&pdev->dev,"failed to add IRQ resources\n" ); - goto err2; + goto err_put_control_otghs; } } ret =platform_device_add_data (musb, pdata,sizeof (*pdata));if (ret) {dev_err (&pdev->dev,"failed to add platform_data\n" ); - goto err2; + goto err_put_control_otghs; }pm_runtime_enable (glue->dev);
@@ -463,7 +463,9 @@ static int omap2430_probe(struct platfor err3:pm_runtime_disable (glue->dev); - +err_put_control_otghs: +if (!IS_ERR (glue->control_otghs)) +put_device (glue->control_otghs); err2:platform_device_put (musb);
@@ -477,6 +479,8 @@ static void omap2430_remove(struct platfplatform_device_unregister (glue->musb);pm_runtime_disable (glue->dev); +if (!IS_ERR (glue->control_otghs)) +put_device (glue->control_otghs); }#ifdef CONFIG_PM
Greg Kroah-Hartman
maintainerPATCH 371/482 platform/chrome: cros_ec: Use per-device lockdep key
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit 961a325becd9a142ae5c8b258e5c2f221f8bfac8 ]
Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to the following lock sequences:
1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock)
2. lock(&ec_dev->lock); lock(prepare_lock);
The actual dependency chains are much longer. The shortened version looks somewhat like:
1. cros-ec-rpmsg on mtk-scp
ec_dev->lock -> prepare_lock
2. In rt5682_i2c_probe() on native I2C bus:
prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock
3. In rt5682_i2c_probe() on native I2C bus:
regmap->lock -> i2c_adapter->bus_lock
4. In sbs_probe() on i2c-cros-ec-tunnel I2C bus attached on cros-ec:
i2c_adapter->bus_lock -> ec_dev->lock
While lockdep is correct that the shared lockdep classes have a circular dependency, it is bogus because
a) 2+3 happen on a native I2C bus
b) 4 happens on the actual EC on ChromeOS devices
c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just happens to expose a cros-ec interface, but does not have an i2c-cros-ec-tunnel I2C bus
In short, the "dependencies" are actually on different devices.
Setup a per-device lockdep key for cros_ec devices so lockdep can tell the two instances apart. This helps with getting rid of the bogus lockdep warning. For ChromeOS devices that only have one cros-ec instance this doesn't change anything.
Also add a missing mutex_destroy, just to make the teardown complete.
[1] This is likely the per I2C bus lock with shared lockdep class
Stable-dep-of: e23749534619 ("platform/chrome: cros_ec: Unregister notifier in cros_ec_unregister()")
--- drivers/platform/chrome/cros_ec.c | 14 +++++++++++--- include/linux/platform_data/cros_ec_proto.h | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/platform/chrome/cros_ec.c +11 -3
@@ -198,12 +198,14 @@ int cros_ec_register(struct cros_ec_deviif (!ec_dev->dout)return -ENOMEM ; +lockdep_register_key (&ec_dev->lockdep_key);mutex_init (&ec_dev->lock); +lockdep_set_class (&ec_dev->lock, &ec_dev->lockdep_key); err =cros_ec_query_all (ec_dev);if (err) {dev_err (dev,"Cannot identify the EC: error %d\n" , err); -return err; + goto destroy_mutex; }if (ec_dev->irq >0 ) {
@@ -215,7 +217,7 @@ int cros_ec_register(struct cros_ec_deviif (err) {dev_err (dev,"Failed to request IRQ %d: %d\n" , ec_dev->irq, err); -return err; + goto destroy_mutex; } }
@@ -226,7 +228,8 @@ int cros_ec_register(struct cros_ec_deviif (IS_ERR (ec_dev->ec)) {dev_err (ec_dev->dev,"Failed to create CrOS EC platform device\n" ); -return PTR_ERR (ec_dev->ec); + err =PTR_ERR (ec_dev->ec); + goto destroy_mutex; }if (ec_dev->max_passthru) {
@@ -292,6 +295,9 @@ int cros_ec_register(struct cros_ec_devi exit:platform_device_unregister (ec_dev->ec);platform_device_unregister (ec_dev->pd); +destroy_mutex: +mutex_destroy (&ec_dev->lock); +lockdep_unregister_key (&ec_dev->lockdep_key);return err; }EXPORT_SYMBOL (cros_ec_register);
@@ -309,6 +315,8 @@ void cros_ec_unregister(struct cros_ec_dif (ec_dev->pd)platform_device_unregister (ec_dev->pd);platform_device_unregister (ec_dev->ec); +mutex_destroy (&ec_dev->lock); +lockdep_unregister_key (&ec_dev->lockdep_key); }EXPORT_SYMBOL (cros_ec_unregister);
include/linux/platform_data/cros_ec_proto.h +4 -0
@@ -9,6 +9,7 @@#define __LINUX_CROS_EC_PROTO_H#include <linux/device.h> +#include <linux/lockdep_types.h> #include <linux/mutex.h> #include <linux/notifier.h>
@@ -116,6 +117,8 @@ struct cros_ec_command {* command. The caller should check msg.result for the EC's result * code. * @pkt_xfer: Send packet to EC and get response. +* @lockdep_key: Lockdep class for each instance. Unused if CONFIG_LOCKDEP is +* not enabled. * @lock: One transaction at a time. * @mkbp_event_supported: 0 if MKBP not supported. Otherwise its value is * the maximum supported version of the MKBP host event
@@ -160,6 +163,7 @@ struct cros_ec_device { struct cros_ec_command *msg);int (*pkt_xfer)(struct cros_ec_device *ec,struct cros_ec_command *msg); +struct lock_class_key lockdep_key;struct mutex lock;u8 mkbp_event_supported;bool host_sleep_v1;
Greg Kroah-Hartman
maintainerPATCH 372/482 platform/chrome: cros_ec: remove unneeded label and if-condition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <[email protected]>
[ Upstream commit 554ec02c97254962bbb0a8776c3160d294fc7e51 ]
Both ec_dev->ec and ec_dev->pd are initialized to NULL at the beginning of cros_ec_register(). Also, platform_device_unregister() takes care if the given platform_device is NULL.
Remove the unneeded goto-label and if-condition.
Stable-dep-of: e23749534619 ("platform/chrome: cros_ec: Unregister notifier in cros_ec_unregister()")
--- drivers/platform/chrome/cros_ec.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/platform/chrome/cros_ec.c +4 -6
@@ -205,7 +205,7 @@ int cros_ec_register(struct cros_ec_devi err =cros_ec_query_all (ec_dev);if (err) {dev_err (dev,"Cannot identify the EC: error %d\n" , err); - goto destroy_mutex; + goto exit; }if (ec_dev->irq >0 ) {
@@ -217,7 +217,7 @@ int cros_ec_register(struct cros_ec_deviif (err) {dev_err (dev,"Failed to request IRQ %d: %d\n" , ec_dev->irq, err); - goto destroy_mutex; + goto exit; } }
@@ -229,7 +229,7 @@ int cros_ec_register(struct cros_ec_devidev_err (ec_dev->dev,"Failed to create CrOS EC platform device\n" ); err =PTR_ERR (ec_dev->ec); - goto destroy_mutex; + goto exit; }if (ec_dev->max_passthru) {
@@ -295,7 +295,6 @@ int cros_ec_register(struct cros_ec_devi exit:platform_device_unregister (ec_dev->ec);platform_device_unregister (ec_dev->pd); -destroy_mutex:mutex_destroy (&ec_dev->lock);lockdep_unregister_key (&ec_dev->lockdep_key);return err;
@@ -312,8 +311,7 @@ EXPORT_SYMBOL(cros_ec_register);*/ void cros_ec_unregister (struct cros_ec_device *ec_dev) { -if (ec_dev->pd) -platform_device_unregister (ec_dev->pd); +platform_device_unregister (ec_dev->pd);platform_device_unregister (ec_dev->ec);mutex_destroy (&ec_dev->lock);lockdep_unregister_key (&ec_dev->lockdep_key);
Greg Kroah-Hartman
maintainerPATCH 373/482 platform/chrome: cros_ec: Unregister notifier in cros_ec_unregister()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <[email protected]>
[ Upstream commit e2374953461947eee49f69b3e3204ff080ef31b1 ]
The blocking notifier is registered in cros_ec_register(); however, it isn't unregistered in cros_ec_unregister().
Fix it.
--- drivers/platform/chrome/cros_ec.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/chrome/cros_ec.c +3 -0
@@ -311,6 +311,9 @@ EXPORT_SYMBOL(cros_ec_register);*/ void cros_ec_unregister (struct cros_ec_device *ec_dev) { +if (ec_dev->mkbp_event_supported) +blocking_notifier_chain_unregister (&ec_dev->event_notifier, + &ec_dev->notifier_ready);platform_device_unregister (ec_dev->pd);platform_device_unregister (ec_dev->ec);mutex_destroy (&ec_dev->lock);
Greg Kroah-Hartman
maintainerPATCH 374/482 usb: dwc3: imx8mp: fix device leak at unbind
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 086a0e516f7b3844e6328a5c69e2708b66b0ce18 ]
Make sure to drop the reference to the dwc3 device taken by of_find_device_by_node() on probe errors and on driver unbind.
--- drivers/usb/dwc3/dwc3-imx8mp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/dwc3/dwc3-imx8mp.c +5 -1
@@ -243,7 +243,7 @@ static int dwc3_imx8mp_probe(struct plat IRQF_ONESHOT, dev_name(dev), dwc3_imx);if (err) {dev_err (dev,"failed to request IRQ #%d --> %d\n" , irq, err); - goto depopulate; + goto put_dwc3; }device_set_wakeup_capable (dev, true);
@@ -251,6 +251,8 @@ static int dwc3_imx8mp_probe(struct platreturn 0 ; +put_dwc3: +put_device (&dwc3_imx->dwc3->dev); depopulate:of_platform_depopulate (dev); err_node_put:
@@ -271,6 +273,8 @@ static int dwc3_imx8mp_remove(struct plastruct dwc3_imx8mp *dwc3_imx =platform_get_drvdata (pdev);struct device *dev = &pdev->dev; +put_device (&dwc3_imx->dwc3->dev); +pm_runtime_get_sync (dev);of_platform_depopulate (dev);
Greg Kroah-Hartman
maintainerPATCH 375/482 ata: Fix SATA_MOBILE_LPM_POLICY description in Kconfig
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit ed62a62a18bc144f73eadf866ae46842e8f6606e ]
Improve the description of the possible default SATA link power management policies and add the missing description for policy 5. No functional changes.
--- drivers/ata/Kconfig | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-)
drivers/ata/Kconfig +25 -8
@@ -117,7 +117,7 @@ config SATA_AHCI config SATA_MOBILE_LPM_POLICY int "Default SATA Link Power Management policy for low power chipsets" - range 0 4 + range 0 5 default 0 depends on SATA_AHCI help
@@ -126,15 +126,32 @@ config SATA_MOBILE_LPM_POLICY chipsets are typically found on most laptops but desktops and servers now also widely use chipsets supporting low power modes. - The value set has the following meanings: + Each policy combines power saving states and features: + - Partial: The Phy logic is powered but is in a reduced power + state. The exit latency from this state is no longer than + 10us). + - Slumber: The Phy logic is powered but is in an even lower power + state. The exit latency from this state is potentially + longer, but no longer than 10ms. + - DevSleep: The Phy logic may be powered down. The exit latency from + this state is no longer than 20 ms, unless otherwise + specified by DETO in the device Identify Device Data log. + - HIPM: Host Initiated Power Management (host automatically + transitions to partial and slumber). + - DIPM: Device Initiated Power Management (device automatically + transitions to partial and slumber). + + The possible values for the default SATA link power management + policies are: 0 => Keep firmware settings - 1 => Maximum performance - 2 => Medium power - 3 => Medium power with Device Initiated PM enabled - 4 => Minimum power + 1 => No power savings (maximum performance) + 2 => HIPM (Partial) + 3 => HIPM (Partial) and DIPM (Partial and Slumber) + 4 => HIPM (Partial and DevSleep) and DIPM (Partial and Slumber) + 5 => HIPM (Slumber and DevSleep) and DIPM (Partial and Slumber) - Note "Minimum power" is known to cause issues, including disk - corruption, with some disks and should not be used. + Excluding the value 0, higher values represent policies with higher + power savings. config SATA_AHCI_PLATFORM tristate "Platform AHCI SATA support"
Greg Kroah-Hartman
maintainerPATCH 376/482 btrfs: populate otime when logging an inode item
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 1ef94169db0958d6de39f9ea6e063ce887342e2d ]
[TEST FAILURE WITH EXPERIMENTAL FEATURES]
When running test case generic/508, the test case will fail with the new btrfs shutdown support:
generic/508 - output mismatch (see /home/adam/xfstests/results//generic/508.out.bad)
# --- tests/generic/508.out 2022-05-11 11:25:30.806666664 +0930 # +++ /home/adam/xfstests/results//generic/508.out.bad 2025-07-02 14:53:22.401824212 +0930 # @@ -1,2 +1,6 @@ # QA output created by 508 # Silence is golden # +Before: # +After : stat.btime = Thu Jan 1 09:30:00 1970 # +Before: # +After : stat.btime = Wed Jul 2 14:53:22 2025 # ... # (Run 'diff -u /home/adam/xfstests/tests/generic/508.out /home/adam/xfstests/results//generic/508.out.bad' to see the entire diff)
Ran: generic/508
Failures: generic/508
Failed 1 of 1 tests
Please note that the test case requires shutdown support, thus the test case will be skipped using the current upstream kernel, as it doesn't have shutdown ioctl support.
[CAUSE]
The direct cause the 0 time stamp in the log tree:
leaf 30507008 items 2 free space 16057 generation 9 owner TREE_LOG leaf 30507008 flags 0x1(WRITTEN) backref revision 1 checksum stored e522548d
checksum calced e522548d
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (257 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 9 transid 9 size 0 nbytes 0 block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0 sequence 1 flags 0x0(none) atime 1751432947.492000000 (2025-07-02 14:39:07) ctime 1751432947.492000000 (2025-07-02 14:39:07) mtime 1751432947.492000000 (2025-07-02 14:39:07) otime 0.0 (1970-01-01 09:30:00) <<<
But the old fs tree has all the correct time stamp:
btrfs-progs v6.12
fs tree key (FS_TREE ROOT_ITEM 0)
leaf 30425088 items 2 free space 16061 generation 5 owner FS_TREE leaf 30425088 flags 0x1(WRITTEN) backref revision 1 checksum stored 48f6c57e
checksum calced 48f6c57e
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 3 transid 0 size 0 nbytes 16384 block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0 sequence 0 flags 0x0(none) atime 1751432947.0 (2025-07-02 14:39:07) ctime 1751432947.0 (2025-07-02 14:39:07) mtime 1751432947.0 (2025-07-02 14:39:07) otime 1751432947.0 (2025-07-02 14:39:07) <<<
The root cause is that fill_inode_item() in tree-log.c is only populating a/c/m time, not the otime (or btime in statx output).
Part of the reason is that, the vfs inode only has a/c/m time, no native btime support yet.
[FIX]
Thankfully btrfs has its otime stored in btrfs_inode::i_otime_sec and btrfs_inode::i_otime_nsec.
So what we really need is just fill the otime time stamp in fill_inode_item() of tree-log.c
There is another fill_inode_item() in inode.c, which is doing the proper otime population.
--- fs/btrfs/tree-log.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/btrfs/tree-log.c +5 -0
@@ -4210,6 +4210,11 @@ static void fill_inode_item(struct btrfsbtrfs_set_token_timespec_nsec (&token, &item->ctime, inode->i_ctime.tv_nsec); +btrfs_set_token_timespec_sec (&token, &item->otime, +BTRFS_I (inode)->i_otime.tv_sec); +btrfs_set_token_timespec_nsec (&token, &item->otime, +BTRFS_I (inode)->i_otime.tv_nsec); +/* * We do not need to set the nbytes field, in fact during a fast fsync * its value may not even be correct, since a fast fsync does not wait
Greg Kroah-Hartman
maintainerPATCH 377/482 tls: separate no-async decryption request handling from async
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <[email protected]>
commit 41532b785e9d79636b3815a64ddf6a096647d011 upstream.
If we're not doing async, the handling is much simpler. There's no reference counting, we just need to wait for the completion to wake us up and return its result.
We should preferably also use a separate crypto_wait. I'm not seeing a UAF as I did in the past, I think aec7961916f3 ("tls: fix race between async notify and socket close") took care of it.
This will make the next fix easier.
[ William: The original patch did not apply cleanly due to deletions of
non-existent lines in 6.1.y. The UAF the author stopped seeing can still be reproduced on systems without AVX in conjunction with cryptd. Also removed an extraneous statement after a return statement that is adjacent to diff. ]
--- net/tls/tls_sw.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/tls/tls_sw.c +7 -2
@@ -274,9 +274,15 @@ static int tls_do_decryption(struct sockDEBUG_NET_WARN_ON_ONCE (atomic_read (&ctx->decrypt_pending) <1 );atomic_inc (&ctx->decrypt_pending); }else { +DECLARE_CRYPTO_WAIT (wait); +aead_request_set_callback (aead_req,CRYPTO_TFM_REQ_MAY_BACKLOG , - crypto_req_done, &ctx->async_wait); + crypto_req_done, &wait); + ret =crypto_aead_decrypt (aead_req); +if (ret == -EINPROGRESS || ret == -EBUSY ) + ret =crypto_wait_req (ret, &wait); +return ret; } ret =crypto_aead_decrypt (aead_req);
@@ -289,7 +295,6 @@ static int tls_do_decryption(struct sock/* all completions have run, we're not doing async anymore */ darg->async = false;return ret; - ret = ret ?: -EINPROGRESS ; }atomic_dec (&ctx->decrypt_pending);
Greg Kroah-Hartman
maintainerPATCH 378/482 crypto: qat - fix ring to service map for QAT GEN4
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giovanni Cabiddu <[email protected]>
commit a238487f7965d102794ed9f8aff0b667cd2ae886 upstream.
The 4xxx drivers hardcode the ring to service mapping. However, when additional configurations where added to the driver, the mappings were not updated. This implies that an incorrect mapping might be reported through pfvf for certain configurations.
Add an algorithm that computes the correct ring to service mapping based on the firmware loaded on the device.
[Giovanni: backport to 6.1.y, conflict resolved simplifying the logic in the function get_ring_to_svc_map() as the QAT driver in v6.1 supports only limited configurations (crypto only and compression). Differs from upstream as the ring to service mapping is hardcoded rather than being dynamically computed.]
--- drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 13 +++++++++++++ drivers/crypto/qat/qat_common/adf_accel_devices.h | 1 + drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 6 ++++++ drivers/crypto/qat/qat_common/adf_init.c | 3 +++ 4 files changed, 23 insertions(+)
drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c +13 -0
@@ -297,6 +297,18 @@ static char *uof_get_name(struct adf_accreturn NULL ; } +static u16 get_ring_to_svc_map (struct adf_accel_dev *accel_dev) +{ +switch (get_service_enabled (accel_dev)) { +case SVC_CY : +return ADF_GEN4_DEFAULT_RING_TO_SRV_MAP ; +case SVC_DC : +return ADF_GEN4_DEFAULT_RING_TO_SRV_MAP_DC ; + } + +return 0 ; +} +static u32 uof_get_ae_mask (struct adf_accel_dev *accel_dev,u32 obj_num) {switch (get_service_enabled (accel_dev)) {
@@ -353,6 +365,7 @@ void adf_init_hw_data_4xxx(struct adf_hw hw_data->uof_get_ae_mask = uof_get_ae_mask; hw_data->set_msix_rttable = set_msix_default_rttable; hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer; + hw_data->get_ring_to_svc_map = get_ring_to_svc_map; hw_data->disable_iov = adf_disable_sriov; hw_data->ring_pair_reset = adf_gen4_ring_pair_reset; hw_data->enable_pm = adf_gen4_enable_pm;
drivers/crypto/qat/qat_common/adf_accel_devices.h +1 -0
@@ -176,6 +176,7 @@ struct adf_hw_device_data {void (*get_arb_info)(struct arb_info *arb_csrs_info);void (*get_admin_info)(struct admin_info *admin_csrs_info);enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self); +u16 (*get_ring_to_svc_map)(struct adf_accel_dev *accel_dev);int (*alloc_irq)(struct adf_accel_dev *accel_dev);void (*free_irq)(struct adf_accel_dev *accel_dev);void (*enable_error_correction)(struct adf_accel_dev *accel_dev);
drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +6 -0
@@ -95,6 +95,12 @@ do { \ ADF_RING_BUNDLE_SIZE * (bank) + \ ADF_RING_CSR_RING_SRV_ARB_EN, (value)) +#define ADF_GEN4_DEFAULT_RING_TO_SRV_MAP_DC \ + (COMP << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) +/* Default ring mapping */ #define ADF_GEN4_DEFAULT_RING_TO_SRV_MAP \ (ASYM << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \
drivers/crypto/qat/qat_common/adf_init.c +3 -0
@@ -95,6 +95,9 @@ int adf_dev_init(struct adf_accel_dev *areturn -EFAULT ; } +if (hw_data->get_ring_to_svc_map) + hw_data->ring_to_svc_map = hw_data->get_ring_to_svc_map (accel_dev); +if (adf_ae_init (accel_dev)) {dev_err (&GET_DEV (accel_dev),"Failed to initialise Acceleration Engine\n" );
Greg Kroah-Hartman
maintainerPATCH 379/482 arm64/cpufeatures/kvm: Add ARMv8.9 FEAT_ECBHB bits in ID_AA64MMFR1 register
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nianyao Tang <[email protected]>
commit e8cde32f111f7f5681a7bad3ec747e9e697569a9 upstream.
Enable ECBHB bits in ID_AA64MMFR1 register as per ARM DDI 0487K.a specification.
When guest OS read ID_AA64MMFR1_EL1, kvm emulate this reg using ftr_id_aa64mmfr1 and always return ID_AA64MMFR1_EL1.ECBHB=0 to guest. It results in guest syscall jump to tramp ventry, which is not needed in implementation with ID_AA64MMFR1_EL1.ECBHB=1.
Let's make the guest syscall process the same as the host.
--- arch/arm64/kernel/cpufeature.c | 1 + 1 file changed, 1 insertion(+)
arch/arm64/kernel/cpufeature.c +1 -0
@@ -343,6 +343,7 @@ static const struct arm64_ftr_bits ftr_i };static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { +ARM64_FTR_BITS (FTR_HIDDEN ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64MMFR1_EL1_ECBHB_SHIFT ,4 ,0 ),ARM64_FTR_BITS (FTR_HIDDEN ,FTR_NONSTRICT ,FTR_LOWER_SAFE ,ID_AA64MMFR1_EL1_TIDCP1_SHIFT ,4 ,0 ),ARM64_FTR_BITS (FTR_VISIBLE ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64MMFR1_EL1_AFP_SHIFT ,4 ,0 ),ARM64_FTR_BITS (FTR_HIDDEN ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64MMFR1_EL1_ETS_SHIFT ,4 ,0 ),
Greg Kroah-Hartman
maintainerPATCH 380/482 KVM: x86: Take irqfds.lock when adding/deleting IRQ bypass producer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit f1fb088d9cecde5c3066d8ff8846789667519b7d upstream.
Take irqfds.lock when adding/deleting an IRQ bypass producer to ensure irqfd->producer isn't modified while kvm_irq_routing_update() is running. The only lock held when a producer is added/removed is irqbypass's mutex.
Message-ID: <[email protected]>
--- arch/x86/kvm/x86.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
arch/x86/kvm/x86.c +16 -3
@@ -13387,16 +13387,22 @@ int kvm_arch_irq_bypass_add_producer(str {struct kvm_kernel_irqfd *irqfd = container_of(cons, struct kvm_kernel_irqfd, consumer); +struct kvm *kvm = irqfd->kvm;int ret; - irqfd->producer = prod;kvm_arch_start_assignment (irqfd->kvm); + +spin_lock_irq (&kvm->irqfds.lock); + irqfd->producer = prod; + ret =static_call (kvm_x86_pi_update_irte)(irqfd->kvm, prod->irq, irqfd->gsi,1 ); -if (ret)kvm_arch_end_assignment (irqfd->kvm); +spin_unlock_irq (&kvm->irqfds.lock); + +return ret; }
@@ -13406,9 +13412,9 @@ void kvm_arch_irq_bypass_del_producer(stint ret;struct kvm_kernel_irqfd *irqfd = container_of(cons, struct kvm_kernel_irqfd, consumer); +struct kvm *kvm = irqfd->kvm;WARN_ON (irqfd->producer != prod); - irqfd->producer =NULL ;/* * When producer of consumer is unregistered, we change back to
@@ -13416,11 +13422,18 @@ void kvm_arch_irq_bypass_del_producer(st* when the irq is masked/disabled or the consumer side (KVM * int this case doesn't want to receive the interrupts. */ +spin_lock_irq (&kvm->irqfds.lock); + irqfd->producer =NULL ; + + ret =static_call (kvm_x86_pi_update_irte)(irqfd->kvm, prod->irq, irqfd->gsi,0 );if (ret)printk (KERN_INFO "irq bypass consumer (token %p) unregistration" " fails: %d\n" , irqfd->consumer.token, ret); +spin_unlock_irq (&kvm->irqfds.lock); + +kvm_arch_end_assignment (irqfd->kvm); }
Greg Kroah-Hartman
maintainerPATCH 381/482 mptcp: make fallback action and fallback decision atomic
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit f8a1d9b18c5efc76784f5a326e905f641f839894 upstream.
Syzkaller reported the following splat:
WARNING: CPU: 1 PID: 7704 at net/mptcp/protocol.h:1223 __mptcp_do_fallback net/mptcp/protocol.h:1223 [inline] WARNING: CPU: 1 PID: 7704 at net/mptcp/protocol.h:1223 mptcp_do_fallback net/mptcp/protocol.h:1244 [inline] WARNING: CPU: 1 PID: 7704 at net/mptcp/protocol.h:1223 check_fully_established net/mptcp/options.c:982 [inline] WARNING: CPU: 1 PID: 7704 at net/mptcp/protocol.h:1223 mptcp_incoming_options+0x21a8/0x2510 net/mptcp/options.c:1153 Modules linked in: CPU: 1 UID: 0 PID: 7704 Comm: syz.3.1419 Not tainted 6.16.0-rc3-gbd5ce2324dba #20 PREEMPT(voluntary) Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:__mptcp_do_fallback net/mptcp/protocol.h:1223 [inline] RIP: 0010:mptcp_do_fallback net/mptcp/protocol.h:1244 [inline] RIP: 0010:check_fully_established net/mptcp/options.c:982 [inline] RIP: 0010:mptcp_incoming_options+0x21a8/0x2510 net/mptcp/options.c:1153 Code: 24 18 e8 bb 2a 00 fd e9 1b df ff ff e8 b1 21 0f 00 e8 ec 5f c4 fc 44 0f b7 ac 24 b0 00 00 00 e9 54 f1 ff ff e8 d9 5f c4 fc 90 <0f> 0b 90 e9 b8 f4 ff ff e8 8b 2a 00 fd e9 8d e6 ff ff e8 81 2a 00 RSP: 0018:ffff8880a3f08448 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff8880180a8000 RCX: ffffffff84afcf45 RDX: ffff888090223700 RSI: ffffffff84afdaa7 RDI: 0000000000000001 RBP: ffff888017955780 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff8880180a8910 R14: ffff8880a3e9d058 R15: 0000000000000000 FS: 00005555791b8500(0000) GS:ffff88811c495000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000110c2800b7 CR3: 0000000058e44000 CR4: 0000000000350ef0 Call Trace: <IRQ> tcp_reset+0x26f/0x2b0 net/ipv4/tcp_input.c:4432 tcp_validate_incoming+0x1057/0x1b60 net/ipv4/tcp_input.c:5975 tcp_rcv_established+0x5b5/0x21f0 net/ipv4/tcp_input.c:6166 tcp_v4_do_rcv+0x5dc/0xa70 net/ipv4/tcp_ipv4.c:1925 tcp_v4_rcv+0x3473/0x44a0 net/ipv4/tcp_ipv4.c:2363 ip_protocol_deliver_rcu+0xba/0x480 net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x2f1/0x500 net/ipv4/ip_input.c:233 NF_HOOK include/linux/netfilter.h:317 [inline] NF_HOOK include/linux/netfilter.h:311 [inline] ip_local_deliver+0x1be/0x560 net/ipv4/ip_input.c:254 dst_input include/net/dst.h:469 [inline] ip_rcv_finish net/ipv4/ip_input.c:447 [inline] NF_HOOK include/linux/netfilter.h:317 [inline] NF_HOOK include/linux/netfilter.h:311 [inline] ip_rcv+0x514/0x810 net/ipv4/ip_input.c:567 __netif_receive_skb_one_core+0x197/0x1e0 net/core/dev.c:5975 __netif_receive_skb+0x1f/0x120 net/core/dev.c:6088 process_backlog+0x301/0x1360 net/core/dev.c:6440 __napi_poll.constprop.0+0xba/0x550 net/core/dev.c:7453 napi_poll net/core/dev.c:7517 [inline] net_rx_action+0xb44/0x1010 net/core/dev.c:7644 handle_softirqs+0x1d0/0x770 kernel/softirq.c:579 do_softirq+0x3f/0x90 kernel/softirq.c:480 </IRQ> <TASK> __local_bh_enable_ip+0xed/0x110 kernel/softirq.c:407 local_bh_enable include/linux/bottom_half.h:33 [inline] inet_csk_listen_stop+0x2c5/0x1070 net/ipv4/inet_connection_sock.c:1524 mptcp_check_listen_stop.part.0+0x1cc/0x220 net/mptcp/protocol.c:2985 mptcp_check_listen_stop net/mptcp/mib.h:118 [inline] __mptcp_close+0x9b9/0xbd0 net/mptcp/protocol.c:3000 mptcp_close+0x2f/0x140 net/mptcp/protocol.c:3066 inet_release+0xed/0x200 net/ipv4/af_inet.c:435 inet6_release+0x4f/0x70 net/ipv6/af_inet6.c:487 __sock_release+0xb3/0x270 net/socket.c:649 sock_close+0x1c/0x30 net/socket.c:1439 __fput+0x402/0xb70 fs/file_table.c:465 task_work_run+0x150/0x240 kernel/task_work.c:227 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] exit_to_user_mode_loop+0xd4/0xe0 kernel/entry/common.c:114 exit_to_user_mode_prepare include/linux/entry-common.h:330 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:414 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:449 [inline] do_syscall_64+0x245/0x360 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fc92f8a36ad Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffcf52802d8 EFLAGS: 00000246 ORIG_RAX: 00000000000001b4 RAX: 0000000000000000 RBX: 00007ffcf52803a8 RCX: 00007fc92f8a36ad RDX: 0000000000000000 RSI: 000000000000001e RDI: 0000000000000003 RBP: 00007fc92fae7ba0 R08: 0000000000000001 R09: 0000002800000000 R10: 00007fc92f700000 R11: 0000000000000246 R12: 00007fc92fae5fac R13: 00007fc92fae5fa0 R14: 0000000000026d00 R15: 0000000000026c51 </TASK> irq event stamp: 4068 hardirqs last enabled at (4076): [<ffffffff81544816>] __up_console_sem+0x76/0x80 kernel/printk/printk.c:344 hardirqs last disabled at (4085): [<ffffffff815447fb>] __up_console_sem+0x5b/0x80 kernel/printk/printk.c:342 softirqs last enabled at (3096): [<ffffffff840e1be0>] local_bh_enable include/linux/bottom_half.h:33 [inline] softirqs last enabled at (3096): [<ffffffff840e1be0>] inet_csk_listen_stop+0x2c0/0x1070 net/ipv4/inet_connection_sock.c:1524 softirqs last disabled at (3097): [<ffffffff813b6b9f>] do_softirq+0x3f/0x90 kernel/softirq.c:480
Since we need to track the 'fallback is possible' condition and the fallback status separately, there are a few possible races open between the check and the actual fallback action.
Add a spinlock to protect the fallback related information and use it close all the possible related races. While at it also remove the too-early clearing of allow_infinite_fallback in __mptcp_subflow_connect():
the field will be correctly cleared by subflow_finish_connect() if/when the connection will complete successfully.
If fallback is not possible, as per RFC, reset the current subflow.
Since the fallback operation can now fail and return value should be checked, rename the helper accordingly.
[ Conflicts in protocol.h, because commit 6ebf6f90ab4a ("mptcp: add
mptcpi_subflows_total counter") is not in this version, and this causes conflicts in the context. Commit 65b02260a0e0 ("mptcp: export mptcp_subflow_early_fallback()") is also not in this version, and moves code from protocol.c to protocol.h, but the modification can still apply there. Conflicts in protocol.c because commit ee2708aedad0 ("mptcp: use get_retrans wrapper") is not in this version and refactor the code in __mptcp_retrans(), but the modification can still be applied, just not at the same indentation level. There were other conflicts in the context due to commit 8005184fd1ca ("mptcp: refactor sndbuf auto-tuning"), commit b3ea6b272d79 ("mptcp: consolidate initial ack seq generation"), and commit 013e3179dbd2 ("mptcp: fix rcv space initialization") that are not in this version. ]
--- net/mptcp/options.c | 3 ++- net/mptcp/protocol.c | 39 +++++++++++++++++++++++++++++++++------ net/mptcp/protocol.h | 24 ++++++++++++++++++------ net/mptcp/subflow.c | 11 +++++------ 4 files changed, 58 insertions(+), 19 deletions(-)
net/mptcp/options.c +2 -1
@@ -973,8 +973,9 @@ static bool check_fully_established(struif (subflow->mp_join) goto reset; subflow->mp_capable =0 ; +if (!mptcp_try_fallback (ssk)) + goto reset;pr_fallback (msk); -mptcp_do_fallback (ssk);return false; }
net/mptcp/protocol.c +33 -6
@@ -633,10 +633,9 @@ static bool mptcp_check_data_fin(structstatic void mptcp_dss_corruption (struct mptcp_sock *msk,struct sock *ssk) { -if (READ_ONCE (msk->allow_infinite_fallback)) { +if (mptcp_try_fallback (ssk)) {MPTCP_INC_STATS (sock_net (ssk),MPTCP_MIB_DSSCORRUPTIONFALLBACK ); -mptcp_do_fallback (ssk); }else {MPTCP_INC_STATS (sock_net (ssk),MPTCP_MIB_DSSCORRUPTIONRESET );mptcp_subflow_reset (ssk);
@@ -897,6 +896,14 @@ static bool __mptcp_finish_join(struct mif (sk->sk_state !=TCP_ESTABLISHED )return false; +spin_lock_bh (&msk->fallback_lock); +if (__mptcp_check_fallback (msk)) { +spin_unlock_bh (&msk->fallback_lock); +return false; + } +mptcp_subflow_joined (msk, ssk); +spin_unlock_bh (&msk->fallback_lock); +/* attach to msk socket only after we are sure we will deal with it * at close time */
@@ -904,7 +911,6 @@ static bool __mptcp_finish_join(struct mmptcp_sock_graft (ssk, sk->sk_socket);mptcp_sockopt_sync_locked (msk, ssk); -mptcp_subflow_joined (msk, ssk);mptcp_stop_tout_timer (sk);return true; }
@@ -1288,10 +1294,14 @@ static void mptcp_update_infinite_map(st mpext->infinite_map =1 ; mpext->data_len =0 ; +if (!mptcp_try_fallback (ssk)) { +mptcp_subflow_reset (ssk); +return ; + } +MPTCP_INC_STATS (sock_net (ssk),MPTCP_MIB_INFINITEMAPTX );mptcp_subflow_ctx (ssk)->send_infinite_map =0 ;pr_fallback (msk); -mptcp_do_fallback (ssk); }#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1))
@@ -2638,8 +2648,8 @@ static void mptcp_check_fastclose(structstatic void __mptcp_retrans (struct sock *sk) { +struct mptcp_sendmsg_info info = { .data_lock_held = true, };struct mptcp_sock *msk =mptcp_sk (sk); -struct mptcp_sendmsg_info info = {};struct mptcp_data_frag *dfrag;size_t copied =0 ;struct sock *ssk;
@@ -2675,6 +2685,15 @@ static void __mptcp_retrans(struct sock/* limit retransmission to the bytes already sent on some subflows */ info.sent =0 ; info.limit =READ_ONCE (msk->csum_enabled) ? dfrag->data_len : dfrag->already_sent; + +/* make the whole retrans decision, xmit, disallow fallback atomic */ +spin_lock_bh (&msk->fallback_lock); +if (__mptcp_check_fallback (msk)) { +spin_unlock_bh (&msk->fallback_lock); +release_sock (ssk); +return ; + } +while (info.sent < info.limit) { ret =mptcp_sendmsg_frag (sk, ssk, dfrag, &info);if (ret <=0 )
@@ -2690,6 +2709,7 @@ static void __mptcp_retrans(struct sock info.size_goal);WRITE_ONCE (msk->allow_infinite_fallback, false); } +spin_unlock_bh (&msk->fallback_lock);release_sock (ssk);
@@ -2819,6 +2839,7 @@ static int __mptcp_init_sock(struct sock msk->recovery = false;mptcp_pm_data_init (msk); +spin_lock_init (&msk->fallback_lock);/* re-use the csk retrans timer for MPTCP-level retrans */ timer_setup (&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer,0 );
@@ -3651,7 +3672,13 @@ bool mptcp_finish_join(struct sock *ssk)/* active subflow, already present inside the conn_list */ if (!list_empty (&subflow->node)) { +spin_lock_bh (&msk->fallback_lock); +if (__mptcp_check_fallback (msk)) { +spin_unlock_bh (&msk->fallback_lock); +return false; + }mptcp_subflow_joined (msk, ssk); +spin_unlock_bh (&msk->fallback_lock);return true; }
@@ -3764,7 +3791,7 @@ static void mptcp_subflow_early_fallback struct mptcp_subflow_context *subflow) { subflow->request_mptcp =0 ; -__mptcp_do_fallback (msk); +WARN_ON_ONCE (!__mptcp_try_fallback (msk)); }static int mptcp_connect (struct sock *sk,struct sockaddr *uaddr,int addr_len)
net/mptcp/protocol.h +18 -6
@@ -317,6 +317,10 @@ struct mptcp_sock {u32 setsockopt_seq;char ca_name[TCP_CA_NAME_MAX ]; + +spinlock_t fallback_lock;/* protects fallback and +* allow_infinite_fallback +*/ };#define mptcp_data_lock (sk) spin_lock_bh(&(sk)->sk_lock.slock)
@@ -975,25 +979,32 @@ static inline bool mptcp_check_fallback(return __mptcp_check_fallback (msk); } -static inline void __mptcp_do_fallback (struct mptcp_sock *msk) +static inline bool __mptcp_try_fallback (struct mptcp_sock *msk) {if (test_bit (MPTCP_FALLBACK_DONE , &msk->flags)) {pr_debug ("TCP fallback already done (msk=%p)\n" , msk); -return ; +return true; } -if (WARN_ON_ONCE (!READ_ONCE (msk->allow_infinite_fallback))) -return ; +spin_lock_bh (&msk->fallback_lock); +if (!msk->allow_infinite_fallback) { +spin_unlock_bh (&msk->fallback_lock); +return false; + } +set_bit (MPTCP_FALLBACK_DONE , &msk->flags); +spin_unlock_bh (&msk->fallback_lock); +return true; } -static inline void mptcp_do_fallback (struct sock *ssk) +static inline bool mptcp_try_fallback (struct sock *ssk) {struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (ssk);struct sock *sk = subflow->conn;struct mptcp_sock *msk; msk =mptcp_sk (sk); -__mptcp_do_fallback (msk); +if (!__mptcp_try_fallback (msk)) +return false;if (READ_ONCE (msk->snd_data_fin_enable) && !(ssk->sk_shutdown &SEND_SHUTDOWN )) {gfp_t saved_allocation = ssk->sk_allocation;
@@ -1005,6 +1016,7 @@ static inline void mptcp_do_fallback(strtcp_shutdown (ssk,SEND_SHUTDOWN ); ssk->sk_allocation = saved_allocation; } +return true; }#define pr_fallback (a) pr_debug("%s:fallback to TCP (msk=%p)\n", __func__, a)
net/mptcp/subflow.c +5 -6
@@ -431,9 +431,11 @@ static void subflow_finish_connect(strucmptcp_get_options (skb, &mp_opt);if (subflow->request_mptcp) {if (!(mp_opt.suboptions &OPTION_MPTCP_MPC_SYNACK )) { +if (!mptcp_try_fallback (sk)) + goto do_reset; +MPTCP_INC_STATS (sock_net (sk),MPTCP_MIB_MPCAPABLEACTIVEFALLBACK ); -mptcp_do_fallback (sk);pr_fallback (mptcp_sk (subflow->conn)); goto fallback; }
@@ -1269,7 +1271,7 @@ fallback:return true; } -if (!READ_ONCE (msk->allow_infinite_fallback)) { +if (!mptcp_try_fallback (ssk)) {/* fatal protocol error, close the socket. * subflow_error_report() will introduce the appropriate barriers */
@@ -1285,8 +1287,6 @@ reset:WRITE_ONCE (subflow->data_avail,MPTCP_SUBFLOW_NODATA );return false; } - -mptcp_do_fallback (ssk); } skb =skb_peek (&ssk->sk_receive_queue);
@@ -1519,7 +1519,6 @@ int __mptcp_subflow_connect(struct sock/* discard the subflow socket */ mptcp_sock_graft (ssk, sk->sk_socket);iput (SOCK_INODE (sf)); -WRITE_ONCE (msk->allow_infinite_fallback, false);mptcp_stop_tout_timer (sk);return 0 ;
@@ -1690,7 +1689,7 @@ static void subflow_state_change(struct msk =mptcp_sk (parent);if (subflow_simultaneous_connect (sk)) {mptcp_propagate_sndbuf (parent, sk); -mptcp_do_fallback (sk); +WARN_ON_ONCE (!mptcp_try_fallback (sk));mptcp_rcv_space_init (msk, sk);pr_fallback (msk); subflow->conn_finished =1 ;
Greg Kroah-Hartman
maintainerPATCH 382/482 mptcp: plug races between subflow fail and subflow creation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit def5b7b2643ebba696fc60ddf675dca13f073486 upstream.
We have races similar to the one addressed by the previous patch between subflow failing and additional subflow creation. They are just harder to trigger.
The solution is similar. Use a separate flag to track the condition 'socket state prevent any additional subflow creation' protected by the fallback lock.
The socket fallback makes such flag true, and also receiving or sending an MP_FAIL option.
The field 'allow_infinite_fallback' is now always touched under the relevant lock, we can drop the ONCE annotation on write.
[ Conflicts in subflow.c, because commit f1f26512a9bf ("mptcp: use plain
bool instead of custom binary enum") and commit 46a5d3abedbe ("mptcp: fix typos in comments") are not in this version. Both are causing conflicts in the context, and the same modifications can still be applied. Same in protocol.h with commit b8dc6d6ce931 ("mptcp: fix rcv buffer auto-tuning"). Conflicts in protocol.c because commit ee2708aedad0 ("mptcp: use get_retrans wrapper") is not in this version and refactor the code in __mptcp_retrans(), but the modification can still be applied, just not at the same indentation level. ]
--- net/mptcp/pm.c | 8 +++++++- net/mptcp/protocol.c | 11 ++++++----- net/mptcp/protocol.h | 7 +++++-- net/mptcp/subflow.c | 19 ++++++++++++++----- 4 files changed, 32 insertions(+), 13 deletions(-)
net/mptcp/pm.c +7 -1
@@ -309,8 +309,14 @@ void mptcp_pm_mp_fail_received(struct sopr_debug ("fail_seq=%llu\n" , fail_seq); -if (!READ_ONCE (msk->allow_infinite_fallback)) +/* After accepting the fail, we can't create any other subflows */ +spin_lock_bh (&msk->fallback_lock); +if (!msk->allow_infinite_fallback) { +spin_unlock_bh (&msk->fallback_lock);return ; + } + msk->allow_subflows = false; +spin_unlock_bh (&msk->fallback_lock);if (!subflow->fail_tout) {pr_debug ("send MP_FAIL response and infinite map\n" );
net/mptcp/protocol.c +6 -5
@@ -885,7 +885,7 @@ void mptcp_data_ready(struct sock *sk, sstatic void mptcp_subflow_joined (struct mptcp_sock *msk,struct sock *ssk) {mptcp_subflow_ctx (ssk)->map_seq =READ_ONCE (msk->ack_seq); -WRITE_ONCE (msk->allow_infinite_fallback, false); + msk->allow_infinite_fallback = false;mptcp_event (MPTCP_EVENT_SUB_ESTABLISHED , msk, ssk,GFP_ATOMIC ); }
@@ -897,7 +897,7 @@ static bool __mptcp_finish_join(struct mreturn false;spin_lock_bh (&msk->fallback_lock); -if (__mptcp_check_fallback (msk)) { +if (!msk->allow_subflows) {spin_unlock_bh (&msk->fallback_lock);return false; }
@@ -2707,7 +2707,7 @@ static void __mptcp_retrans(struct sock dfrag->already_sent =max (dfrag->already_sent, info.sent);tcp_push (ssk,0 , info.mss_now,tcp_sk (ssk)->nonagle, info.size_goal); -WRITE_ONCE (msk->allow_infinite_fallback, false); + msk->allow_infinite_fallback = false; }spin_unlock_bh (&msk->fallback_lock);
@@ -2835,7 +2835,8 @@ static int __mptcp_init_sock(struct sockWRITE_ONCE (msk->first,NULL );inet_csk (sk)->icsk_sync_mss = mptcp_sync_mss;WRITE_ONCE (msk->csum_enabled,mptcp_is_checksum_enabled (sock_net (sk))); -WRITE_ONCE (msk->allow_infinite_fallback, true); + msk->allow_infinite_fallback = true; + msk->allow_subflows = true; msk->recovery = false;mptcp_pm_data_init (msk);
@@ -3673,7 +3674,7 @@ bool mptcp_finish_join(struct sock *ssk)/* active subflow, already present inside the conn_list */ if (!list_empty (&subflow->node)) {spin_lock_bh (&msk->fallback_lock); -if (__mptcp_check_fallback (msk)) { +if (!msk->allow_subflows) {spin_unlock_bh (&msk->fallback_lock);return false; }
net/mptcp/protocol.h +5 -2
@@ -314,12 +314,14 @@ struct mptcp_sock {u64 time;/* start time of measurement window */ u64 rtt_us;/* last maximum rtt of subflows */ } rcvq_space; +bool allow_subflows;u32 setsockopt_seq;char ca_name[TCP_CA_NAME_MAX ]; -spinlock_t fallback_lock;/* protects fallback and -* allow_infinite_fallback +spinlock_t fallback_lock;/* protects fallback, +* allow_infinite_fallback and +* allow_join */ };
@@ -991,6 +993,7 @@ static inline bool __mptcp_try_fallback(return false; } + msk->allow_subflows = false;set_bit (MPTCP_FALLBACK_DONE , &msk->flags);spin_unlock_bh (&msk->fallback_lock);return true;
net/mptcp/subflow.c +14 -5
@@ -1168,20 +1168,29 @@ static void subflow_sched_work_if_closedmptcp_schedule_work (sk); } -static void mptcp_subflow_fail (struct mptcp_sock *msk,struct sock *ssk) +static bool mptcp_subflow_fail (struct mptcp_sock *msk,struct sock *ssk) {struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (ssk);unsigned long fail_tout; +/* we are really failing, prevent any later subflow join */ +spin_lock_bh (&msk->fallback_lock); +if (!msk->allow_infinite_fallback) { +spin_unlock_bh (&msk->fallback_lock); +return false; + } + msk->allow_subflows = false; +spin_unlock_bh (&msk->fallback_lock); +/* greceful failure can happen only on the MPC subflow */ if (WARN_ON_ONCE (ssk !=READ_ONCE (msk->first))) -return ; +return false;/* since the close timeout take precedence on the fail one, * no need to start the latter when the first is already set */ if (sock_flag ((struct sock *)msk,SOCK_DEAD )) -return ; +return true;/* we don't need extreme accuracy here, use a zero fail_tout as special * value meaning no fail timeout at all;
@@ -1193,6 +1202,7 @@ static void mptcp_subflow_fail(struct mptcp_send_ack (ssk);mptcp_reset_tout_timer (msk, subflow->fail_tout); +return true; }static bool subflow_check_data_avail (struct sock *ssk)
@@ -1261,12 +1271,11 @@ fallback: (subflow->mp_join || subflow->valid_csum_seen)) { subflow->send_mp_fail =1 ; -if (!READ_ONCE (msk->allow_infinite_fallback)) { +if (!mptcp_subflow_fail (msk, ssk)) { subflow->reset_transient =0 ; subflow->reset_reason =MPTCP_RST_EMIDDLEBOX ; goto reset; } -mptcp_subflow_fail (msk, ssk);WRITE_ONCE (subflow->data_avail,MPTCP_SUBFLOW_DATA_AVAIL );return true; }
Greg Kroah-Hartman
maintainerPATCH 383/482 mptcp: reset fallback status gracefully at disconnect() time
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit da9b2fc7b73d147d88abe1922de5ab72d72d7756 upstream.
mptcp_disconnect() clears the fallback bit unconditionally, without touching the associated flags.
The bit clear is safe, as no fallback operation can race with that -- all subflow are already in TCP_CLOSE status thanks to the previous FASTCLOSE -- but we need to consistently reset all the fallback related status.
Also acquire the relevant lock, to avoid fouling static analyzers.
[ Conflicts in protocol.c, because commit ebc1e08f01eb ("mptcp: drop
last_snd and MPTCP_RESET_SCHEDULER") is not in this version and changed the context. The same modification can still be applied at the same place. ]
--- net/mptcp/protocol.c | 9 +++++++++ 1 file changed, 9 insertions(+)
net/mptcp/protocol.c +9 -0
@@ -3204,7 +3204,16 @@ static int mptcp_disconnect(struct sock*/ mptcp_destroy_common (msk,MPTCP_CF_FASTCLOSE ); msk->last_snd =NULL ; + +/* The first subflow is already in TCP_CLOSE status, the following +* can't overlap with a fallback anymore +*/ +spin_lock_bh (&msk->fallback_lock); + msk->allow_subflows = true; + msk->allow_infinite_fallback = true;WRITE_ONCE (msk->flags,0 ); +spin_unlock_bh (&msk->fallback_lock); + msk->cb_flags =0 ; msk->recovery = false; msk->can_ack = false;
Greg Kroah-Hartman
maintainerPATCH 384/482 mm: drop the assumption that VM_SHARED always implies writable
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes <[email protected]>
[ Upstream commit e8e17ee90eaf650c855adb0a3e5e965fd6692ff1 ]
Patch series "permit write-sealed memfd read-only shared mappings", v4.
The man page for fcntl() describing memfd file seals states the following about F_SEAL_WRITE:-
Furthermore, trying to create new shared, writable memory-mappings via mmap(2) will also fail with EPERM.
With emphasis on 'writable'. In turns out in fact that currently the kernel simply disallows all new shared memory mappings for a memfd with F_SEAL_WRITE applied, rendering this documentation inaccurate.
This matters because users are therefore unable to obtain a shared mapping to a memfd after write sealing altogether, which limits their usefulness. This was reported in the discussion thread [1] originating from a bug report [2].
This is a product of both using the struct address_space->i_mmap_writable atomic counter to determine whether writing may be permitted, and the kernel adjusting this counter when any VM_SHARED mapping is performed and more generally implicitly assuming VM_SHARED implies writable.
It seems sensible that we should only update this mapping if VM_MAYWRITE is specified, i.e. whether it is possible that this mapping could at any point be written to.
If we do so then all we need to do to permit write seals to function as documented is to clear VM_MAYWRITE when mapping read-only. It turns out this functionality already exists for F_SEAL_FUTURE_WRITE - we can therefore simply adapt this logic to do the same for F_SEAL_WRITE.
We then hit a chicken and egg situation in mmap_region() where the check for VM_MAYWRITE occurs before we are able to clear this flag. To work around this, perform this check after we invoke call_mmap(), with careful consideration of error paths.
Thanks to Andy Lutomirski for the suggestion!
[1]:https://lore.kernel.org/all/[email protected]/ [2]:https://bugzilla.kernel.org/show_bug.cgi?id=217238
This patch (of 3):
There is a general assumption that VMAs with the VM_SHARED flag set are writable. If the VM_MAYWRITE flag is not set, then this is simply not the case.
Update those checks which affect the struct address_space->i_mmap_writable field to explicitly test for this by introducing [vma_]is_shared_maywrite() helper functions.
This remains entirely conservative, as the lack of VM_MAYWRITE guarantees that the VMA cannot be written to.
[isaacmanjarres: resolved merge conflicts due to
due to refactoring that happened in upstream commit 5de195060b2e ("mm: resolve faulty mmap_region() error path behaviour")]
--- include/linux/fs.h | 4 ++-- include/linux/mm.h | 11 +++++++++++ kernel/fork.c | 2 +- mm/filemap.c | 2 +- mm/madvise.c | 2 +- mm/mmap.c | 8 ++++---- 6 files changed, 20 insertions(+), 9 deletions(-)
include/linux/fs.h +2 -2
@@ -410,7 +410,7 @@ extern const struct address_space_operat* It is also used to block modification of page cache contents through * memory mappings. * @gfp_mask: Memory allocation flags to use for allocating pages. -* @i_mmap_writable: Number of VM_SHARED mappings. +* @i_mmap_writable: Number of VM_SHARED, VM_MAYWRITE mappings. * @nr_thps: Number of THPs in the pagecache (non-shmem only). * @i_mmap: Tree of private and shared mappings. * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable.
@@ -513,7 +513,7 @@ static inline int mapping_mapped(struct/* * Might pages of this file have been modified in userspace? -* Note that i_mmap_writable counts all VM_SHARED vmas: do_mmap +* Note that i_mmap_writable counts all VM_SHARED, VM_MAYWRITE vmas: do_mmap * marks vma as VM_SHARED if it is shared, and the file was opened for * writing i.e. vma may be mprotected writable even if now readonly. *
include/linux/mm.h +11 -0
@@ -673,6 +673,17 @@ static inline bool vma_is_accessible(strreturn vma->vm_flags &VM_ACCESS_FLAGS ; } +static inline bool is_shared_maywrite (vm_flags_t vm_flags) +{ +return (vm_flags & (VM_SHARED |VM_MAYWRITE )) == + (VM_SHARED |VM_MAYWRITE ); +} + +static inline bool vma_is_shared_maywrite (struct vm_area_struct *vma) +{ +return is_shared_maywrite (vma->vm_flags); +} +static inline struct vm_area_struct *vma_find (struct vma_iterator *vmi,unsigned long max) {
kernel/fork.c +1 -1
@@ -669,7 +669,7 @@ static __latent_entropy int dup_mmap(strget_file (file);i_mmap_lock_write (mapping); -if (tmp->vm_flags &VM_SHARED ) +if (vma_is_shared_maywrite (tmp))mapping_allow_writable (mapping);flush_dcache_mmap_lock (mapping);/* insert tmp into the share list, just after mpnt */
mm/filemap.c +1 -1
@@ -3554,7 +3554,7 @@ int generic_file_mmap(struct file *file,*/ int generic_file_readonly_mmap (struct file *file,struct vm_area_struct *vma) { -if ((vma->vm_flags &VM_SHARED ) && (vma->vm_flags &VM_MAYWRITE )) +if (vma_is_shared_maywrite (vma))return -EINVAL ;return generic_file_mmap (file, vma); }
mm/madvise.c +1 -1
@@ -980,7 +980,7 @@ static long madvise_remove(struct vm_arereturn -EINVAL ; } -if ((vma->vm_flags & (VM_SHARED |VM_WRITE )) != (VM_SHARED |VM_WRITE )) +if (!vma_is_shared_maywrite (vma))return -EACCES ; offset = (loff_t)(start - vma->vm_start)
mm/mmap.c +4 -4
@@ -106,7 +106,7 @@ void vma_set_page_prot(struct vm_area_ststatic void __remove_shared_vm_struct (struct vm_area_struct *vma,struct file *file,struct address_space *mapping) { -if (vma->vm_flags &VM_SHARED ) +if (vma_is_shared_maywrite (vma))mapping_unmap_writable (mapping);flush_dcache_mmap_lock (mapping);
@@ -408,7 +408,7 @@ static unsigned long count_vma_pages_ranstatic void __vma_link_file (struct vm_area_struct *vma,struct address_space *mapping) { -if (vma->vm_flags &VM_SHARED ) +if (vma_is_shared_maywrite (vma))mapping_allow_writable (mapping);flush_dcache_mmap_lock (mapping);
@@ -2827,7 +2827,7 @@ cannot_expand:vma_mas_store (vma, &mas); mm->map_count++;if (vma->vm_file) { -if (vma->vm_flags &VM_SHARED ) +if (vma_is_shared_maywrite (vma))mapping_allow_writable (vma->vm_file->f_mapping);flush_dcache_mmap_lock (vma->vm_file->f_mapping);
@@ -2901,7 +2901,7 @@ unsigned long mmap_region(struct file *freturn -EINVAL ;/* Map writable and ensure this isn't a sealed memfd. */ -if (file && (vm_flags &VM_SHARED )) { +if (file &&is_shared_maywrite (vm_flags)) {int error =mapping_map_writable (file->f_mapping);if (error)
Greg Kroah-Hartman
maintainerPATCH 385/482 mm: update memfd seal write check to include F_SEAL_WRITE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes <[email protected]>
[ Upstream commit 28464bbb2ddc199433383994bcb9600c8034afa1 ]
The seal_check_future_write() function is called by shmem_mmap() or hugetlbfs_file_mmap() to disallow any future writable mappings of an memfd sealed this way.
The F_SEAL_WRITE flag is not checked here, as that is handled via the mapping->i_mmap_writable mechanism and so any attempt at a mapping would fail before this could be run.
However we intend to change this, meaning this check can be performed for F_SEAL_WRITE mappings also.
The logic here is equally applicable to both flags, so update this function to accommodate both and rename it accordingly.
--- fs/hugetlbfs/inode.c | 2 +- include/linux/mm.h | 15 ++++++++------- mm/shmem.c | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-)
fs/hugetlbfs/inode.c +1 -1
@@ -136,7 +136,7 @@ static int hugetlbfs_file_mmap(struct fi vma->vm_flags |=VM_HUGETLB |VM_DONTEXPAND ; vma->vm_ops = &hugetlb_vm_ops; - ret =seal_check_future_write (info->seals, vma); + ret =seal_check_write (info->seals, vma);if (ret)return ret;
include/linux/mm.h +8 -7
@@ -3526,25 +3526,26 @@ static inline void mem_dump_obj(void *ob#endif /** -* seal_check_future_write - Check for F_SEAL_FUTURE_WRITE flag and handle it +* seal_check_write - Check for F_SEAL_WRITE or F_SEAL_FUTURE_WRITE flags and +* handle them. * @seals: the seals to check * @vma: the vma to operate on * -* Check whether F_SEAL_FUTURE_WRITE is set; if so, do proper check/handling on -* the vma flags. Return 0 if check pass, or <0 for errors. +* Check whether F_SEAL_WRITE or F_SEAL_FUTURE_WRITE are set; if so, do proper +* check/handling on the vma flags. Return 0 if check pass, or <0 for errors. */ -static inline int seal_check_future_write (int seals,struct vm_area_struct *vma) +static inline int seal_check_write (int seals,struct vm_area_struct *vma) { -if (seals &F_SEAL_FUTURE_WRITE ) { +if (seals & (F_SEAL_WRITE |F_SEAL_FUTURE_WRITE )) {/* * New PROT_WRITE and MAP_SHARED mmaps are not allowed when -* "future write" seal active. +* write seals are active. */ if ((vma->vm_flags &VM_SHARED ) && (vma->vm_flags &VM_WRITE ))return -EPERM ;/* -* Since an F_SEAL_FUTURE_WRITE sealed memfd can be mapped as +* Since an F_SEAL_[FUTURE_]WRITE sealed memfd can be mapped as * MAP_SHARED and read-only, take care to not allow mprotect to * revert protections on such mappings. Do this only for shared * mappings. For private mappings, don't need to mask
mm/shmem.c +1 -1
@@ -2302,7 +2302,7 @@ static int shmem_mmap(struct file *file,struct shmem_inode_info *info =SHMEM_I (file_inode (file));int ret; - ret =seal_check_future_write (info->seals, vma); + ret =seal_check_write (info->seals, vma);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 386/482 mm: reinstate ability to map write-sealed memfd mappings read-only
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes <[email protected]>
[ Upstream commit 8ec396d05d1b737c87311fb7311f753b02c2a6b1 ]
Patch series "mm: reinstate ability to map write-sealed memfd mappings read-only".
In commit 158978945f31 ("mm: perform the mapping_map_writable() check after call_mmap()") (and preceding changes in the same series) it became possible to mmap() F_SEAL_WRITE sealed memfd mappings read-only.
Commit 5de195060b2e ("mm: resolve faulty mmap_region() error path behaviour") unintentionally undid this logic by moving the mapping_map_writable() check before the shmem_mmap() hook is invoked, thereby regressing this change.
This series reworks how we both permit write-sealed mappings being mapped read-only and disallow mprotect() from undoing the write-seal, fixing this regression.
We also add a regression test to ensure that we do not accidentally regress this in future.
Thanks to Julian Orth for reporting this regression.
This patch (of 2):
In commit 158978945f31 ("mm: perform the mapping_map_writable() check after call_mmap()") (and preceding changes in the same series) it became possible to mmap() F_SEAL_WRITE sealed memfd mappings read-only.
This was previously unnecessarily disallowed, despite the man page documentation indicating that it would be, thereby limiting the usefulness of F_SEAL_WRITE logic.
We fixed this by adapting logic that existed for the F_SEAL_FUTURE_WRITE seal (one which disallows future writes to the memfd) to also be used for F_SEAL_WRITE.
For background - the F_SEAL_FUTURE_WRITE seal clears VM_MAYWRITE for a read-only mapping to disallow mprotect() from overriding the seal - an operation performed by seal_check_write(), invoked from shmem_mmap(), the f_op->mmap() hook used by shmem mappings.
By extending this to F_SEAL_WRITE and critically - checking mapping_map_writable() to determine if we may map the memfd AFTER we invoke shmem_mmap() - the desired logic becomes possible. This is because mapping_map_writable() explicitly checks for VM_MAYWRITE, which we will have cleared.
Commit 5de195060b2e ("mm: resolve faulty mmap_region() error path behaviour") unintentionally undid this logic by moving the mapping_map_writable() check before the shmem_mmap() hook is invoked, thereby regressing this change.
We reinstate this functionality by moving the check out of shmem_mmap() and instead performing it in do_mmap() at the point at which VMA flags are being determined, which seems in any case to be a more appropriate place in which to make this determination.
In order to achieve this we rework memfd seal logic to allow us access to this information using existing logic and eliminate the clearing of VM_MAYWRITE from seal_check_write() which we are performing in do_mmap() instead.
--- include/linux/memfd.h | 14 ++++++++++++ include/linux/mm.h | 58 ++++++++++++++++++++++++++++++++++---------------- mm/memfd.c | 2 - mm/mmap.c | 4 +++ 4 files changed, 59 insertions(+), 19 deletions(-)
include/linux/memfd.h +14 -0
@@ -6,11 +6,25 @@#ifdef CONFIG_MEMFD_CREATE extern long memfd_fcntl (struct file *file,unsigned int cmd,unsigned long arg); +unsigned int *memfd_file_seals_ptr (struct file *file);#else static inline long memfd_fcntl (struct file *f,unsigned int c,unsigned long a) {return -EINVAL ; } + +static inline unsigned int *memfd_file_seals_ptr (struct file *file) +{ +return NULL ; +}#endif +/* Retrieve memfd seals associated with the file, if any. */ +static inline unsigned int memfd_file_seals (struct file *file) +{ +unsigned int *sealsp =memfd_file_seals_ptr (file); + +return sealsp ? *sealsp :0 ; +} +#endif /* __LINUX_MEMFD_H */
include/linux/mm.h +40 -18
70 lines not on this page · raw message
mm/memfd.c +1 -1
@@ -133,7 +133,7 @@ static int memfd_wait_for_pins(struct adreturn error; } -static unsigned int *memfd_file_seals_ptr (struct file *file) +unsigned int *memfd_file_seals_ptr (struct file *file) {if (shmem_file (file))return &SHMEM_I (file_inode (file))->seals;
mm/mmap.c +4 -0
@@ -46,6 +46,7 @@#include <linux/pkeys.h> #include <linux/oom.h> #include <linux/sched/mm.h> +#include <linux/memfd.h> #include <linux/uaccess.h> #include <asm/cacheflush.h>
@@ -1336,6 +1337,7 @@ unsigned long do_mmap(struct file *file,if (file) {struct inode *inode =file_inode (file); +unsigned int seals =memfd_file_seals (file);unsigned long flags_mask;if (!file_mmap_ok (file, inode, pgoff, len))
@@ -1374,6 +1376,8 @@ unsigned long do_mmap(struct file *file, vm_flags |=VM_SHARED |VM_MAYSHARE ;if (!(file->f_mode &FMODE_WRITE )) vm_flags &= ~(VM_MAYWRITE |VM_SHARED ); +else if (is_readonly_sealed (seals, vm_flags)) + vm_flags &= ~VM_MAYWRITE ; fallthrough;case MAP_PRIVATE :if (!(file->f_mode &FMODE_READ ))
Greg Kroah-Hartman
maintainerPATCH 387/482 selftests/memfd: add test for mapping write-sealed memfd read-only
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes <[email protected]>
[ Upstream commit ea0916e01d0b0f2cce1369ac1494239a79827270 ]
Now we have reinstated the ability to map F_SEAL_WRITE mappings read-only, assert that we are able to do this in a test to ensure that we do not regress this again.
--- tools/testing/selftests/memfd/memfd_test.c | 43 +++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
tools/testing/selftests/memfd/memfd_test.c +43 -0
@@ -186,6 +186,24 @@ static void *mfd_assert_mmap_shared(intreturn p; } +static void *mfd_assert_mmap_read_shared (int fd) +{ +void *p; + + p =mmap (NULL , + mfd_def_size, +PROT_READ , +MAP_SHARED , + fd, +0 ); +if (p ==MAP_FAILED ) { +printf ("mmap() failed: %m\n" ); +abort (); + } + +return p; +} +static void *mfd_assert_mmap_private (int fd) {void *p;
@@ -802,6 +820,30 @@ static void test_seal_future_write(void)close (fd); } +static void test_seal_write_map_read_shared (void ) +{ +int fd; +void *p; + +printf ("%s SEAL-WRITE-MAP-READ\n" , memfd_str); + + fd =mfd_assert_new ("kern_memfd_seal_write_map_read" , + mfd_def_size, +MFD_CLOEXEC |MFD_ALLOW_SEALING ); + +mfd_assert_add_seals (fd,F_SEAL_WRITE ); +mfd_assert_has_seals (fd,F_SEAL_WRITE ); + + p =mfd_assert_mmap_read_shared (fd); + +mfd_assert_read (fd); +mfd_assert_read_shared (fd); +mfd_fail_write (fd); + +munmap (p, mfd_def_size); +close (fd); +} +/* * Test SEAL_SHRINK * Test whether SEAL_SHRINK actually prevents shrinking
@@ -1056,6 +1098,7 @@ int main(int argc, char **argv)test_seal_write ();test_seal_future_write (); +test_seal_write_map_read_shared ();test_seal_shrink ();test_seal_grow ();test_seal_resize ();
Greg Kroah-Hartman
maintainerPATCH 388/482 Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumanth Gavini <[email protected]>
commit 5af1f84ed13a416297ab9ced7537f4d5ae7f329a upstream.
Connections may be cleanup while waiting for the commands to complete so this attempts to check if the connection handle remains valid in case of errors that would lead to call hci_conn_failed:
BUG: KASAN: slab-use-after-free in hci_conn_failed+0x1f/0x160 Read of size 8 at addr ffff888001376958 by task kworker/u3:0/52 CPU: 0 PID: 52 Comm: kworker/u3:0 Not tainted 6.5.0-rc1-00527-g2dfe76d58d3a #5615 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014 Workqueue: hci0 hci_cmd_sync_work Call Trace: <TASK> dump_stack_lvl+0x1d/0x70 print_report+0xce/0x620 ? __virt_addr_valid+0xd4/0x150 ? hci_conn_failed+0x1f/0x160 kasan_report+0xd1/0x100 ? hci_conn_failed+0x1f/0x160 hci_conn_failed+0x1f/0x160 hci_abort_conn_sync+0x237/0x360
--- net/bluetooth/hci_sync.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-)
net/bluetooth/hci_sync.c +29 -14
@@ -5525,31 +5525,46 @@ static int hci_reject_conn_sync(struct hint hci_abort_conn_sync (struct hci_dev *hdev,struct hci_conn *conn,u8 reason) { -int err; +int err =0 ; +u16 handle = conn->handle;switch (conn->state) {case BT_CONNECTED :case BT_CONFIG : -return hci_disconnect_sync (hdev, conn, reason); + err =hci_disconnect_sync (hdev, conn, reason); +break ;case BT_CONNECT : err =hci_connect_cancel_sync (hdev, conn); -/* Cleanup hci_conn object if it cannot be cancelled as it -* likelly means the controller and host stack are out of sync. -*/ -if (err) { -hci_dev_lock (hdev); -hci_conn_failed (conn, err); -hci_dev_unlock (hdev); - } -return err; +break ;case BT_CONNECT2 : -return hci_reject_conn_sync (hdev, conn, reason); + err =hci_reject_conn_sync (hdev, conn, reason); +break ;default : conn->state =BT_CLOSED ; -break ; +return 0 ; + } + +/* Cleanup hci_conn object if it cannot be cancelled as it +* likelly means the controller and host stack are out of sync +* or in case of LE it was still scanning so it can be cleanup +* safely. +*/ +if (err) { +struct hci_conn *c; + +/* Check if the connection hasn't been cleanup while waiting +* commands to complete. +*/ + c =hci_conn_hash_lookup_handle (hdev, handle); +if (!c || c != conn) +return 0 ; + +hci_dev_lock (hdev); +hci_conn_failed (conn, err); +hci_dev_unlock (hdev); } -return 0 ; +return err; }static int hci_disconnect_all_sync (struct hci_dev *hdev,u8 reason)
Greg Kroah-Hartman
maintainerPATCH 389/482 kbuild: userprogs: use correct linker when mixing clang and GNU ld
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 936599ca514973d44a766b7376c6bbdc96b6a8cc upstream.
The userprogs infrastructure does not expect clang being used with GNU ld and in that case uses /usr/bin/ld for linking, not the configured $(LD). This fallback is problematic as it will break when cross-compiling. Mixing clang and GNU ld is used for example when building for SPARC64, as ld.lld is not sufficient; see Documentation/kbuild/llvm.rst.
Relax the check around --ld-path so it gets used for all linkers.
[nathan: Work around wrapping '--ld-path' in cc-option in older stable
branches due to older minimum LLVM version]
--- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Makefile +1 -1
@@ -1143,7 +1143,7 @@ KBUILD_USERCFLAGS += $(filter -m32 -m64 KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) # userspace programs are linked via the compiler, use the correct linker -ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) +ifdef CONFIG_CC_IS_CLANG KBUILD_USERLDFLAGS += $(call cc-option, --ld-path=$(LD)) endif
Greg Kroah-Hartman
maintainerPATCH 390/482 x86/reboot: Harden virtualization hooks for emergency reboot
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit 5e408396c60cd0f0b53a43713016b6d6af8d69e0 ]
Provide dedicated helpers to (un)register virt hooks used during an emergency crash/reboot, and WARN if there is an attempt to overwrite the registered callback, or an attempt to do an unpaired unregister.
Opportunsitically use rcu_assign_pointer() instead of RCU_INIT_POINTER(), mainly so that the set/unset paths are more symmetrical, but also because any performance gains from using RCU_INIT_POINTER() are meaningless for this code.
Stable-dep-of: a0ee1d5faff1 ("KVM: VMX: Flush shadow VMCS on emergency reboot")
--- arch/x86/include/asm/reboot.h | 5 +++-- arch/x86/kernel/reboot.c | 30 ++++++++++++++++++++++++------ arch/x86/kvm/vmx/vmx.c | 6 ++---- 3 files changed, 29 insertions(+), 12 deletions(-)
arch/x86/include/asm/reboot.h +3 -2
@@ -25,8 +25,9 @@ void __noreturn machine_real_restart(uns#define MRR_BIOS 0#define MRR_APM 1 -typedef void crash_vmclear_fn (void ); -extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; +typedef void (cpu_emergency_virt_cb )(void ); +void cpu_emergency_register_virt_callback (cpu_emergency_virt_cb *callback); +void cpu_emergency_unregister_virt_callback (cpu_emergency_virt_cb *callback);void cpu_emergency_disable_virtualization (void );typedef void (*nmi_shootdown_cb )(int ,struct pt_regs *);
arch/x86/kernel/reboot.c +24 -6
@@ -794,17 +794,35 @@ void machine_crash_shutdown(struct pt_re* * protected by rcu. */ -crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; -EXPORT_SYMBOL_GPL (crash_vmclear_loaded_vmcss); +static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; + +void cpu_emergency_register_virt_callback (cpu_emergency_virt_cb *callback) +{ +if (WARN_ON_ONCE (rcu_access_pointer (cpu_emergency_virt_callback))) +return ; + +rcu_assign_pointer (cpu_emergency_virt_callback, callback); +} +EXPORT_SYMBOL_GPL (cpu_emergency_register_virt_callback); + +void cpu_emergency_unregister_virt_callback (cpu_emergency_virt_cb *callback) +{ +if (WARN_ON_ONCE (rcu_access_pointer (cpu_emergency_virt_callback) != callback)) +return ; + +rcu_assign_pointer (cpu_emergency_virt_callback,NULL ); +synchronize_rcu (); +} +EXPORT_SYMBOL_GPL (cpu_emergency_unregister_virt_callback);static inline void cpu_crash_vmclear_loaded_vmcss (void ) { -crash_vmclear_fn *do_vmclear_operation =NULL ; +cpu_emergency_virt_cb *callback;rcu_read_lock (); - do_vmclear_operation =rcu_dereference (crash_vmclear_loaded_vmcss); -if (do_vmclear_operation) -do_vmclear_operation (); + callback =rcu_dereference (cpu_emergency_virt_callback); +if (callback) +callback ();rcu_read_unlock (); }
arch/x86/kvm/vmx/vmx.c +2 -4
@@ -8602,8 +8602,7 @@ static void __vmx_exit(void) { allow_smaller_maxphyaddr = false; -RCU_INIT_POINTER (crash_vmclear_loaded_vmcss,NULL ); -synchronize_rcu (); +cpu_emergency_unregister_virt_callback (crash_vmclear_local_loaded_vmcss);vmx_cleanup_l1d_flush (); }
@@ -8677,8 +8676,7 @@ static int __init vmx_init(void)pi_init_cpu (cpu); } -rcu_assign_pointer (crash_vmclear_loaded_vmcss, - crash_vmclear_local_loaded_vmcss); +cpu_emergency_register_virt_callback (crash_vmclear_local_loaded_vmcss);vmx_check_vmcs12_offsets ();
Greg Kroah-Hartman
maintainerPATCH 391/482 x86/reboot: KVM: Handle VMXOFF in KVMs reboot callback
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit 119b5cb4ffd0166f3e98e9ee042f5046f7744f28 ]
Use KVM VMX's reboot/crash callback to do VMXOFF in an emergency instead of manually and blindly doing VMXOFF. There's no need to attempt VMXOFF if a hypervisor, i.e. KVM, isn't loaded/active, i.e. if the CPU can't possibly be post-VMXON.
Stable-dep-of: a0ee1d5faff1 ("KVM: VMX: Flush shadow VMCS on emergency reboot")
--- arch/x86/include/asm/virtext.h | 10 ---------- arch/x86/kernel/reboot.c | 29 +++++++++-------------------- arch/x86/kvm/vmx/vmx.c | 8 +++++--- 3 files changed, 14 insertions(+), 33 deletions(-)
arch/x86/include/asm/virtext.h +0 -10
@@ -70,16 +70,6 @@ static inline void __cpu_emergency_vmxofcpu_vmxoff (); } -/** Disable VMX if it is supported and enabled on the current CPU -*/ -static inline void cpu_emergency_vmxoff (void ) -{ -if (cpu_has_vmx ()) -__cpu_emergency_vmxoff (); -} - - -/* * SVM functions:
arch/x86/kernel/reboot.c +9 -20
@@ -787,13 +787,7 @@ void machine_crash_shutdown(struct pt_re }#endif -/* -* This is used to VMCLEAR all VMCSs loaded on the -* processor. And when loading kvm_intel module, the -* callback function pointer will be assigned. -* -* protected by rcu. -*/ +/* RCU-protected callback to disable virtualization prior to reboot. */ static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback;void cpu_emergency_register_virt_callback (cpu_emergency_virt_cb *callback)
@@ -815,17 +809,6 @@ void cpu_emergency_unregister_virt_callb }EXPORT_SYMBOL_GPL (cpu_emergency_unregister_virt_callback); -static inline void cpu_crash_vmclear_loaded_vmcss (void ) -{ -cpu_emergency_virt_cb *callback; - -rcu_read_lock (); - callback =rcu_dereference (cpu_emergency_virt_callback); -if (callback) -callback (); -rcu_read_unlock (); -} -/* This is the CPU performing the emergency shutdown work. */ int crashing_cpu =-1 ;
@@ -836,9 +819,15 @@ int crashing_cpu = -1;*/ void cpu_emergency_disable_virtualization (void ) { -cpu_crash_vmclear_loaded_vmcss (); +cpu_emergency_virt_cb *callback; + +rcu_read_lock (); + callback =rcu_dereference (cpu_emergency_virt_callback); +if (callback) +callback (); +rcu_read_unlock (); -cpu_emergency_vmxoff (); +/* KVM_AMD doesn't yet utilize the common callback. */ cpu_emergency_svm_disable (); }
arch/x86/kvm/vmx/vmx.c +5 -3
@@ -707,7 +707,7 @@ static int vmx_set_guest_uret_msr(structreturn ret; } -static void crash_vmclear_local_loaded_vmcss (void ) +static void vmx_emergency_disable (void ) {int cpu =raw_smp_processor_id ();struct loaded_vmcs *v;
@@ -715,6 +715,8 @@ static void crash_vmclear_local_loaded_vlist_for_each_entry (v, &per_cpu (loaded_vmcss_on_cpu, cpu), loaded_vmcss_on_cpu_link)vmcs_clear (v->vmcs); + +__cpu_emergency_vmxoff (); }static void __loaded_vmcs_clear (void *arg)
@@ -8602,7 +8604,7 @@ static void __vmx_exit(void) { allow_smaller_maxphyaddr = false; -cpu_emergency_unregister_virt_callback (crash_vmclear_local_loaded_vmcss); +cpu_emergency_unregister_virt_callback (vmx_emergency_disable);vmx_cleanup_l1d_flush (); }
@@ -8676,7 +8678,7 @@ static int __init vmx_init(void)pi_init_cpu (cpu); } -cpu_emergency_register_virt_callback (crash_vmclear_local_loaded_vmcss); +cpu_emergency_register_virt_callback (vmx_emergency_disable);vmx_check_vmcs12_offsets ();
Greg Kroah-Hartman
maintainerPATCH 392/482 KVM: VMX: Flush shadow VMCS on emergency reboot
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Gao <[email protected]>
[ Upstream commit a0ee1d5faff135e28810f29e0f06328c66f89852 ]
Ensure the shadow VMCS cache is evicted during an emergency reboot to prevent potential memory corruption if the cache is evicted after reboot.
This issue was identified through code inspection, as __loaded_vmcs_clear() flushes both the normal VMCS and the shadow VMCS.
Avoid checking the "launched" state during an emergency reboot, unlike the behavior in __loaded_vmcs_clear(). This is important because reboot NMIs can interfere with operations like copy_shadow_to_vmcs12(), where shadow VMCSes are loaded directly using VMPTRLD. In such cases, if NMIs occur right after the VMCS load, the shadow VMCSes will be active but the "launched" state may not be set.
--- arch/x86/kvm/vmx/vmx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/vmx.c +4 -1
@@ -713,8 +713,11 @@ static void vmx_emergency_disable(void)struct loaded_vmcs *v;list_for_each_entry (v, &per_cpu (loaded_vmcss_on_cpu, cpu), - loaded_vmcss_on_cpu_link) + loaded_vmcss_on_cpu_link) {vmcs_clear (v->vmcs); +if (v->shadow_vmcs) +vmcs_clear (v->shadow_vmcs); + }__cpu_emergency_vmxoff (); }
Greg Kroah-Hartman
maintainerPATCH 393/482 KVM: arm64: Fix kernel BUG() due to bad backport of FPSIMD/SVE/SME fix
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
Upstream commit fbc7e61195e2 ("KVM: arm64: Unconditionally save+flush host FPSIMD/SVE/SME state") relies on interrupts being disabled during fpsimd_save_and_flush_cpu_state() so that a softirq cannot be taken while the host floating point context is being saved and potentially try to use kernel-mode NEON.
Unfortunately, stable kernels without 9b19700e623f ("arm64: fpsimd: Drop unneeded 'busy' flag") leave interrupts enabled in fpsimd_save_and_flush_cpu_state() and so the BUG_ON(!may_use_simd()) in kernel_neon_begin() has been observed to trigger in real-world usage:
| kernel BUG at arch/arm64/kernel/fpsimd.c:1904! | Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP | | Call trace: | kernel_neon_begin+0xdc/0x12c | ... | crypto_aead_decrypt+0x5c/0x6c | seqiv_aead_decrypt+0x88/0x9c | crypto_aead_decrypt+0x5c/0x6c | esp_input+0x280/0x364 | xfrm_input+0x6ac/0x16f8 | ... | net_rx_action+0x13c/0x31c | handle_softirqs+0x124/0x3d0 | __do_softirq+0x14/0x20 | ____do_softirq+0x10/0x20 | call_on_irq_stack+0x3c/0x74 | do_softirq_own_stack+0x1c/0x2c | __irq_exit_rcu+0x54/0xb4 | irq_exit_rcu+0x10/0x1c | el1_interrupt+0x38/0x58 | el1h_64_irq_handler+0x18/0x24 | el1h_64_irq+0x68/0x6c | fpsimd_save+0xe4/0x130 | kvm_arch_vcpu_load_fp+0x2c/0x58 | kvm_arch_vcpu_load+0x88/0x26c | kvm_sched_in+0x2c/0x3c
Given that 9b19700e623f ("arm64: fpsimd: Drop unneeded 'busy' flag") is not a fix in its own right, has non-trivial dependencies and is a reasonably invasive change to the in-kernel use of fpsimd, opt instead for a simple fix to use the softirq-safe {get,put}_cpu_fpsimd_context() helpers in fpsimd_save_and_flush_cpu_state().
--- arch/arm64/kernel/fpsimd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/fpsimd.c +2 -2
@@ -1851,10 +1851,10 @@ void fpsimd_save_and_flush_cpu_state(voiif (!system_supports_fpsimd ())return ;WARN_ON (preemptible ()); -__get_cpu_fpsimd_context (); +get_cpu_fpsimd_context ();fpsimd_save ();fpsimd_flush_cpu_state (); -__put_cpu_fpsimd_context (); +put_cpu_fpsimd_context (); }#ifdef CONFIG_KERNEL_MODE_NEON
Greg Kroah-Hartman
maintainerPATCH 394/482 memstick: Fix deadlock by moving removing flag earlier
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayi Li <[email protected]>
commit 99d7ab8db9d8230b243f5ed20ba0229e54cc0dfa upstream.
The existing memstick core patch: commit 62c59a8786e6 ("memstick: Skip allocating card when removing host") sets host->removing in memstick_remove_host(),but still exists a critical time window where memstick_check can run after host->eject is set but before removing is set.
In the rtsx_usb_ms driver, the problematic sequence is:
rtsx_usb_ms_drv_remove: memstick_check:
host->eject = true
cancel_work_sync(handle_req) if(!host->removing)
... memstick_alloc_card()
memstick_set_rw_addr()
memstick_new_req()
rtsx_usb_ms_request()
if(!host->eject)
skip schedule_work
wait_for_completion()
memstick_remove_host: [blocks indefinitely]
host->removing = true
flush_workqueue()
[block]1. rtsx_usb_ms_drv_remove sets host->eject = true
2. cancel_work_sync(&host->handle_req) runs
3. memstick_check work may be executed here <-- danger window
4. memstick_remove_host sets removing = 1
During this window (step 3), memstick_check calls memstick_alloc_card, which may indefinitely waiting for mrq_complete completion that will never occur because rtsx_usb_ms_request sees eject=true and skips scheduling work, memstick_set_rw_addr waits forever for completion.
This causes a deadlock when memstick_remove_host tries to flush_workqueue, waiting for memstick_check to complete, while memstick_check is blocked waiting for mrq_complete completion.
Fix this by setting removing=true at the start of rtsx_usb_ms_drv_remove, before any work cancellation. This ensures memstick_check will see the removing flag immediately and exit early, avoiding the deadlock.
--- drivers/memstick/core/memstick.c | 1 - drivers/memstick/host/rtsx_usb_ms.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
drivers/memstick/core/memstick.c +0 -1
@@ -548,7 +548,6 @@ EXPORT_SYMBOL(memstick_add_host);*/ void memstick_remove_host (struct memstick_host *host) { - host->removing =1 ;flush_workqueue (workqueue);mutex_lock (&host->lock);if (host->card)
drivers/memstick/host/rtsx_usb_ms.c +1 -0
@@ -812,6 +812,7 @@ static int rtsx_usb_ms_drv_remove(structint err; host->eject = true; + msh->removing = true;cancel_work_sync (&host->handle_req);cancel_delayed_work_sync (&host->poll_card);
Greg Kroah-Hartman
maintainerPATCH 395/482 mmc: sdhci-pci-gli: GL9763e: Rename the gli_set_gl9763e() for consistency
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit 293ed0f5f34e1e9df888456af4b0a021f57b5f54 upstream.
In preparation to fix replay timer timeout, rename the gli_set_gl9763e() to gl9763e_hw_setting() for consistency.
--- drivers/mmc/host/sdhci-pci-gli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/sdhci-pci-gli.c +2 -2
@@ -953,7 +953,7 @@ static void sdhci_gl9763e_reset(struct ssdhci_reset (host, mask); } -static void gli_set_gl9763e (struct sdhci_pci_slot *slot) +static void gl9763e_hw_setting (struct sdhci_pci_slot *slot) {struct pci_dev *pdev = slot->chip->pdev;u32 value;
@@ -1125,7 +1125,7 @@ static int gli_probe_slot_gl9763e(structgli_pcie_enable_msi (slot); host->mmc_host_ops.hs400_enhanced_strobe = gl9763e_hs400_enhanced_strobe; -gli_set_gl9763e (slot); +gl9763e_hw_setting (slot);sdhci_enable_v4_mode (host);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 396/482 squashfs: fix memory leak in squashfs_fill_super
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phillip Lougher <[email protected]>
commit b64700d41bdc4e9f82f1346c15a3678ebb91a89c upstream.
If sb_min_blocksize returns 0, squashfs_fill_super exits without freeing allocated memory (sb->s_fs_info).
Fix this by moving the call to sb_min_blocksize to before memory is allocated.
--- fs/squashfs/super.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/squashfs/super.c +7 -7
@@ -123,10 +123,15 @@ static int squashfs_fill_super(struct suunsigned short flags;unsigned int fragments;u64 lookup_table_start, xattr_id_table_start, next_table; -int err; +int err, devblksize =sb_min_blocksize (sb,SQUASHFS_DEVBLK_SIZE );TRACE ("Entered squashfs_fill_superblock\n" ); +if (!devblksize) { +errorf (fc,"squashfs: unable to set blocksize\n" ); +return -EINVAL ; + } + sb->s_fs_info =kzalloc (sizeof (*msblk),GFP_KERNEL );if (sb->s_fs_info ==NULL ) {ERROR ("Failed to allocate squashfs_sb_info\n" );
@@ -136,12 +141,7 @@ static int squashfs_fill_super(struct su msblk->panic_on_errors = (opts->errors == Opt_errors_panic); - msblk->devblksize =sb_min_blocksize (sb,SQUASHFS_DEVBLK_SIZE ); -if (!msblk->devblksize) { -errorf (fc,"squashfs: unable to set blocksize\n" ); -return -EINVAL ; - } - + msblk->devblksize = devblksize; msblk->devblksize_log2 =ffz (~msblk->devblksize);mutex_init (&msblk->meta_index_mutex);
Greg Kroah-Hartman
maintainerPATCH 397/482 mm/debug_vm_pgtable: clear page table entries at destroy_args()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herton R. Krzesinski <[email protected]>
commit dde30854bddfb5d69f30022b53c5955a41088b33 upstream.
The mm/debug_vm_pagetable test allocates manually page table entries for the tests it runs, using also its manually allocated mm_struct. That in itself is ok, but when it exits, at destroy_args() it fails to clear those entries with the *_clear functions.
The problem is that leaves stale entries. If another process allocates an mm_struct with a pgd at the same address, it may end up running into the stale entry. This is happening in practice on a debug kernel with CONFIG_DEBUG_VM_PGTABLE=y, for example this is the output with some extra debugging I added (it prints a warning trace if pgtables_bytes goes negative, in addition to the warning at check_mm() function):
[ 2.539353] debug_vm_pgtable: [get_random_vaddr ]: random_vaddr is 0x7ea247140000 [ 2.539366] kmem_cache info [ 2.539374] kmem_cachep 0x000000002ce82385 - freelist 0x0000000000000000 - offset 0x508 [ 2.539447] debug_vm_pgtable: [init_args ]: args->mm is 0x000000002267cc9e (...) [ 2.552800] WARNING: CPU: 5 PID: 116 at include/linux/mm.h:2841 free_pud_range+0x8bc/0x8d0 [ 2.552816] Modules linked in: [ 2.552843] CPU: 5 UID: 0 PID: 116 Comm: modprobe Not tainted 6.12.0-105.debug_vm2.el10.ppc64le+debug #1 VOLUNTARY [ 2.552859] Hardware name: IBM,9009-41A POWER9 (architected) 0x4e0202 0xf000005 of:IBM,FW910.00 (VL910_062) hv:phyp pSeries [ 2.552872] NIP: c0000000007eef3c LR: c0000000007eef30 CTR: c0000000003d8c90 [ 2.552885] REGS: c0000000622e73b0 TRAP: 0700 Not tainted (6.12.0-105.debug_vm2.el10.ppc64le+debug) [ 2.552899] MSR: 800000000282b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24002822 XER: 0000000a [ 2.552954] CFAR: c0000000008f03f0 IRQMASK: 0 [ 2.552954] GPR00: c0000000007eef30 c0000000622e7650 c000000002b1ac00 0000000000000001 [ 2.552954] GPR04: 0000000000000008 0000000000000000 c0000000007eef30 ffffffffffffffff [ 2.552954] GPR08: 00000000ffff00f5 0000000000000001 0000000000000048 0000000000004000 [ 2.552954] GPR12: 00000003fa440000 c000000017ffa300 c0000000051d9f80 ffffffffffffffdb [ 2.552954] GPR16: 0000000000000000 0000000000000008 000000000000000a 60000000000000e0 [ 2.552954] GPR20: 4080000000000000 c0000000113af038 00007fffcf130000 0000700000000000 [ 2.552954] GPR24: c000000062a6a000 0000000000000001 8000000062a68000 0000000000000001 [ 2.552954] GPR28: 000000000000000a c000000062ebc600 0000000000002000 c000000062ebc760 [ 2.553170] NIP [c0000000007eef3c] free_pud_range+0x8bc/0x8d0 [ 2.553185] LR [c0000000007eef30] free_pud_range+0x8b0/0x8d0 [ 2.553199] Call Trace: [ 2.553207] [c0000000622e7650] [c0000000007eef30] free_pud_range+0x8b0/0x8d0 (unreliable) [ 2.553229] [c0000000622e7750] [c0000000007f40b4] free_pgd_range+0x284/0x3b0 [ 2.553248] [c0000000622e7800] [c0000000007f4630] free_pgtables+0x450/0x570 [ 2.553274] [c0000000622e78e0] [c0000000008161c0] exit_mmap+0x250/0x650 [ 2.553292] [c0000000622e7a30] [c0000000001b95b8] __mmput+0x98/0x290 [ 2.558344] [c0000000622e7a80] [c0000000001d1018] exit_mm+0x118/0x1b0 [ 2.558361] [c0000000622e7ac0] [c0000000001d141c] do_exit+0x2ec/0x870 [ 2.558376] [c0000000622e7b60] [c0000000001d1ca8] do_group_exit+0x88/0x150 [ 2.558391] [c0000000622e7bb0] [c0000000001d1db8] sys_exit_group+0x48/0x50 [ 2.558407] [c0000000622e7be0] [c00000000003d810] system_call_exception+0x1e0/0x4c0 [ 2.558423] [c0000000622e7e50] [c00000000000d05c] system_call_vectored_common+0x15c/0x2ec (...) [ 2.558892] ---[ end trace 0000000000000000 ]--- [ 2.559022] BUG: Bad rss-counter state mm:000000002267cc9e type:MM_ANONPAGES val:1 [ 2.559037] BUG: non-zero pgtables_bytes on freeing mm: -6144
Here the modprobe process ended up with an allocated mm_struct from the mm_struct slab that was used before by the debug_vm_pgtable test. That is not a problem, since the mm_struct is initialized again etc., however, if it ends up using the same pgd table, it bumps into the old stale entry when clearing/freeing the page table entries, so it tries to free an entry already gone (that one which was allocated by the debug_vm_pgtable test), which also explains the negative pgtables_bytes since it's accounting for not allocated entries in the current process.
As far as I looked pgd_{alloc,free} etc. does not clear entries, and clearing of the entries is explicitly done in the free_pgtables-> free_pgd_range->free_p4d_range->free_pud_range->free_pmd_range-> free_pte_range path. However, the debug_vm_pgtable test does not call free_pgtables, since it allocates mm_struct and entries manually for its test and eg. not goes through page faults. So it also should clear manually the entries before exit at destroy_args().
This problem was noticed on a reboot X number of times test being done on a powerpc host, with a debug kernel with CONFIG_DEBUG_VM_PGTABLE enabled. Depends on the system, but on a 100 times reboot loop the problem could manifest once or twice, if a process ends up getting the right mm->pgd entry with the stale entries used by mm/debug_vm_pagetable. After using this patch, I couldn't reproduce/experience the problems anymore. I was able to reproduce the problem as well on latest upstream kernel (6.16).
I also modified destroy_args() to use mmput() instead of mmdrop(), there is no reason to hold mm_users reference and not release the mm_struct entirely, and in the output above with my debugging prints I already had patched it to use mmput, it did not fix the problem, but helped in the debugging as well.
--- mm/debug_vm_pgtable.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
mm/debug_vm_pgtable.c +7 -2
@@ -1063,29 +1063,34 @@ static void __init destroy_args(struct p/* Free page table entries */ if (args->start_ptep) { +pmd_clear (args->pmdp);pte_free (args->mm, args->start_ptep);mm_dec_nr_ptes (args->mm); }if (args->start_pmdp) { +pud_clear (args->pudp);pmd_free (args->mm, args->start_pmdp);mm_dec_nr_pmds (args->mm); }if (args->start_pudp) { +p4d_clear (args->p4dp);pud_free (args->mm, args->start_pudp);mm_dec_nr_puds (args->mm); } -if (args->start_p4dp) +if (args->start_p4dp) { +pgd_clear (args->pgdp);p4d_free (args->mm, args->start_p4dp); + }/* Free vma and mm struct */ if (args->vma)vm_area_free (args->vma);if (args->mm) -mmdrop (args->mm); +mmput (args->mm); } static struct page * __init
Greg Kroah-Hartman
maintainerPATCH 398/482 ALSA: hda/realtek: Add support for HP EliteBook x360 830 G6 and EliteBook 830 G6
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evgeniy Harchenko <[email protected]>
commit eafae0fdd115a71b3a200ef1a31f86da04bac77f upstream.
The HP EliteBook x360 830 G6 and HP EliteBook 830 G6 have Realtek HDA codec ALC215. It needs the ALC285_FIXUP_HP_GPIO_LED quirk to enable the mute LED.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -9915,6 +9915,8 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x84e7 ,"HP Pavilion 15" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ),SND_PCI_QUIRK (0x103c ,0x8519 ,"HP Spectre x360 15-df0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360 ),SND_PCI_QUIRK (0x103c ,0x8537 ,"HP ProBook 440 G6" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ), +SND_PCI_QUIRK (0x103c ,0x8548 ,"HP EliteBook x360 830 G6" ,ALC285_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x854a ,"HP EliteBook 830 G6" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x85c6 ,"HP Pavilion x360 Convertible 14-dy1xxx" ,ALC295_FIXUP_HP_MUTE_LED_COEFBIT11 ),SND_PCI_QUIRK (0x103c ,0x85de ,"HP Envy x360 13-ar0xxx" ,ALC285_FIXUP_HP_ENVY_X360 ), SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
Greg Kroah-Hartman
maintainerPATCH 399/482 s390/sclp: Fix SCCB present check
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
commit 430fa71027b6ac9bb0ce5532b8d0676777d4219a upstream.
Tracing code called by the SCLP interrupt handler contains early exits if the SCCB address associated with an interrupt is NULL. This check is performed after physical to virtual address translation.
If the kernel identity mapping does not start at address zero, the resulting virtual address is never zero, so that the NULL checks won't work. Subsequently this may result in incorrect accesses to the first page of the identity mapping.
Fix this by introducing a function that handles the NULL case before address translation.
--- drivers/s390/char/sclp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/s390/char/sclp.c +9 -2
@@ -76,6 +76,13 @@ unsigned long sclp_console_full;/* The currently active SCLP command word. */ static sclp_cmdw_t active_cmd; +static inline struct sccb_header *sclpint_to_sccb (u32 sccb_int) +{ +if (sccb_int) +return __va (sccb_int); +return NULL ; +} +static inline void sclp_trace (int prio,char *id,u32 a,u64 b,bool err) {struct sclp_trace_entry e;
@@ -625,7 +632,7 @@ __sclp_find_req(u32 sccb)static bool ok_response (u32 sccb_int,sclp_cmdw_t cmd) { -struct sccb_header *sccb = (struct sccb_header *)__va (sccb_int); +struct sccb_header *sccb =sclpint_to_sccb (sccb_int);struct evbuf_header *evbuf;u16 response;
@@ -664,7 +671,7 @@ static void sclp_interrupt_handler(struc/* INT: Interrupt received (a=intparm, b=cmd) */ sclp_trace_sccb (0 ,"INT" , param32, active_cmd, active_cmd, - (struct sccb_header *)__va (finished_sccb), +sclpint_to_sccb (finished_sccb), !ok_response (finished_sccb, active_cmd));if (finished_sccb) {
Greg Kroah-Hartman
maintainerPATCH 400/482 drm/amd/display: Avoid a NULL pointer dereference
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 07b93a5704b0b72002f0c4bd1076214af67dc661 upstream.
[WHY]
Although unlikely drm_atomic_get_new_connector_state() or drm_atomic_get_old_connector_state() can return NULL.
[HOW]
Check returns before dereference.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -0
@@ -6620,6 +6620,9 @@ amdgpu_dm_connector_atomic_check(structstruct amdgpu_dm_connector *aconn =to_amdgpu_dm_connector (conn);int ret; +if (WARN_ON (unlikely (!old_con_state || !new_con_state))) +return -EINVAL ; +trace_amdgpu_dm_connector_atomic_check (new_con_state);if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
Greg Kroah-Hartman
maintainerPATCH 401/482 drm/amd/display: Fix fractional fb divider in set_pixel_clock_v3
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 10507478468f165ea681605d133991ed05cdff62 upstream.
For later VBIOS versions, the fractional feedback divider is calculated as the remainder of dividing the feedback divider by a factor, which is set to 1000000. For reference, see:
- calculate_fb_and_fractional_fb_divider
- calc_pll_max_vco_construct
However, in case of old VBIOS versions that have set_pixel_clock_v3, they only have 1 byte available for the fractional feedback divider, and it's expected to be set to the remainder from dividing the feedback divider by 10. For reference see the legacy display code:
- amdgpu_pll_compute
- amdgpu_atombios_crtc_program_pll
This commit fixes set_pixel_clock_v3 by dividing the fractional feedback divider passed to the function by 100000.
--- drivers/gpu/drm/amd/display/dc/bios/command_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/bios/command_table.c +1 -1
@@ -993,7 +993,7 @@ static enum bp_result set_pixel_clock_v3 allocation.sPCLKInput.usFbDiv =cpu_to_le16 ((uint16_t )bp_params->feedback_divider); allocation.sPCLKInput.ucFracFbDiv = - (uint8_t )bp_params->fractional_feedback_divider; + (uint8_t )(bp_params->fractional_feedback_divider /100000 ); allocation.sPCLKInput.ucPostDiv = (uint8_t )bp_params->pixel_clock_post_divider;
Greg Kroah-Hartman
maintainerPATCH 402/482 drm/amd/display: Fix DP audio DTO1 clock source on DCE 6.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 297a4833a68aac3316eb808b4123eb016ef242d7 upstream.
On DCE 6, DP audio was not working. However, it worked when an HDMI monitor was also plugged in.
Looking at dce_aud_wall_dto_setup it seems that the main difference is that we use DTO1 when only DP is plugged in.
When programming DTO1, it uses audio_dto_source_clock_in_khz which is set from get_dp_ref_freq_khz
The dce60_get_dp_ref_freq_khz implementation looks incorrect, because DENTIST_DISPCLK_CNTL seems to be always zero on DCE 6, so it isn't usable.
I compared dce60_get_dp_ref_freq_khz to the legacy display code, specifically dce_v6_0_audio_set_dto, and it turns out that in case of DCE 6, it needs to use the display clock. With that, DP audio started working on Pitcairn, Oland and Cape Verde.
However, it still didn't work on Tahiti. Despite having the same DCE version, Tahiti seems to have a different audio device. After some trial and error I realized that it works with the default display clock as reported by the VBIOS, not the current display clock.
The patch was tested on all four SI GPUs:
* Pitcairn (DCE 6.0)
* Oland (DCE 6.4)
* Cape Verde (DCE 6.0)
* Tahiti (DCE 6.0 but different)
The testing was done on Samsung Odyssey G7 LS28BG700EPXEN on each of the above GPUs, at the following settings:
* 4K 60 Hz
* 1080p 60 Hz
* 1080p 144 Hz
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 21 +++-------- 1 file changed, 6 insertions(+), 15 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +6 -15
@@ -83,22 +83,13 @@ static const struct state_dependent_clocstatic int dce60_get_dp_ref_freq_khz (struct clk_mgr *clk_mgr_base) {struct clk_mgr_internal *clk_mgr =TO_CLK_MGR_INTERNAL (clk_mgr_base); -int dprefclk_wdivider; -int dp_ref_clk_khz; -int target_div; +struct dc_context *ctx = clk_mgr_base->ctx; +int dp_ref_clk_khz =0 ; -/* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */ - -/* Read the mmDENTIST_DISPCLK_CNTL to get the currently -* programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -REG_GET (DENTIST_DISPCLK_CNTL ,DENTIST_DPREFCLK_WDIVIDER , &dprefclk_wdivider); - -/* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ - target_div =dentist_get_divider_from_did (dprefclk_wdivider); - -/* Calculate the current DFS clock, in kHz.*/ - dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR - * clk_mgr->base.dentist_vco_freq_khz) / target_div; +if (ASIC_REV_IS_TAHITI_P (ctx->asic_id.hw_internal_rev)) + dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency; +else + dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz;return dce_adjust_dp_ref_freq_for_ss (clk_mgr, dp_ref_clk_khz); }
Greg Kroah-Hartman
maintainerPATCH 403/482 drm/amd/display: Find first CRTC and its line time in dce110_fill_display_configs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 669f73a26f6112eedbadac53a2f2707ac6d0b9c8 upstream.
dce110_fill_display_configs is shared between DCE 6-11, and finding the first CRTC and its line time is relevant to DCE 6 too. Move the code to find it from DCE 11 specific code.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 30 ++++++---- 1 file changed, 20 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +20 -10
@@ -120,9 +120,12 @@ void dce110_fill_display_configs(const struct dc_state *context, struct dm_pp_display_configuration *pp_display_cfg) { + struct dc *dc = context->clk_mgr->ctx->dc;int j;int num_cfgs =0 ; + pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator; +for (j =0 ; j < context->stream_count; j++) {int k;
@@ -164,6 +167,23 @@ void dce110_fill_display_configs( cfg->v_refresh /= stream->timing.h_total; cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total /2 ) / stream->timing.v_total; + +/* Find first CRTC index and calculate its line time. +* This is necessary for DPM on SI GPUs. +*/ +if (cfg->pipe_idx < pp_display_cfg->crtc_index) { +const struct dc_crtc_timing *timing = + &context->streams[0 ]->timing; + + pp_display_cfg->crtc_index = cfg->pipe_idx; + pp_display_cfg->line_time_in_us = + timing->h_total *10000 / timing->pix_clk_100hz; + } + } + +if (!num_cfgs) { + pp_display_cfg->crtc_index =0 ; + pp_display_cfg->line_time_in_us =0 ; } pp_display_cfg->display_count = num_cfgs;
@@ -232,16 +252,6 @@ void dce11_pplib_apply_display_requiremedce110_fill_display_configs (context, pp_display_cfg); -/* TODO: is this still applicable?*/ -if (pp_display_cfg->display_count ==1 ) { -const struct dc_crtc_timing *timing = - &context->streams[0 ]->timing; - - pp_display_cfg->crtc_index = - pp_display_cfg->disp_configs[0 ].pipe_idx; - pp_display_cfg->line_time_in_us = timing->h_total *10000 / timing->pix_clk_100hz; - } -if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )dm_pp_apply_display_requirements (dc->ctx, pp_display_cfg); }
Greg Kroah-Hartman
maintainerPATCH 404/482 drm/amd/display: Fill display clock and vblank time in dce110_fill_display_configs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 7d07140d37f792f01cfdb8ca9a6a792ab1d29126 upstream.
Also needed by DCE 6.
This way the code that gathers this info can be shared between different DCE versions and doesn't have to be repeated.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c | 2 -- drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 10 +++------- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 2 -- 3 files changed, 3 insertions(+), 11 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +0 -2
@@ -386,8 +386,6 @@ static void dce_pplib_apply_display_requ {struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +3 -7
@@ -124,6 +124,9 @@ void dce110_fill_display_configs(int j;int num_cfgs =0 ; + pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); + pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =0 ; pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator;for (j =0 ; j < context->stream_count; j++) {
@@ -243,13 +246,6 @@ void dce11_pplib_apply_display_requireme pp_display_cfg->min_engine_clock_deep_sleep_khz = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; - pp_display_cfg->avail_mclk_switch_time_us = -dce110_get_min_vblank_time_us (context); -/* TODO: dce11.2*/ - pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =0 ; - - pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +0 -2
@@ -100,8 +100,6 @@ static void dce60_pplib_apply_display_re {struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
Greg Kroah-Hartman
maintainerPATCH 405/482 smb: server: split ksmbd_rdma_stop_listening() out of ksmbd_rdma_destroy()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <[email protected]>
[ Upstream commit bac7b996d42e458a94578f4227795a0d4deef6fa ]
We can't call destroy_workqueue(smb_direct_wq); before stop_sessions()!
Otherwise already existing connections try to use smb_direct_wq as a NULL pointer.
--- fs/smb/server/connection.c | 3 ++- fs/smb/server/transport_rdma.c | 5 ++++- fs/smb/server/transport_rdma.h | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-)
fs/smb/server/connection.c +2 -1
@@ -436,7 +436,8 @@ void ksmbd_conn_transport_destroy(void) {mutex_lock (&init_lock);ksmbd_tcp_destroy (); -ksmbd_rdma_destroy (); +ksmbd_rdma_stop_listening ();stop_sessions (); +ksmbd_rdma_destroy ();mutex_unlock (&init_lock); }
fs/smb/server/transport_rdma.c +4 -1
@@ -2188,7 +2188,7 @@ int ksmbd_rdma_init(void)return 0 ; } -void ksmbd_rdma_destroy (void ) +void ksmbd_rdma_stop_listening (void ) {if (!smb_direct_listener.cm_id)return ;
@@ -2197,7 +2197,10 @@ void ksmbd_rdma_destroy(void)rdma_destroy_id (smb_direct_listener.cm_id); smb_direct_listener.cm_id =NULL ; +} +void ksmbd_rdma_destroy (void ) +{if (smb_direct_wq) {destroy_workqueue (smb_direct_wq); smb_direct_wq =NULL ;
fs/smb/server/transport_rdma.h +3 -1
@@ -54,13 +54,15 @@ struct smb_direct_data_transfer {#ifdef CONFIG_SMB_SERVER_SMBDIRECT int ksmbd_rdma_init (void ); +void ksmbd_rdma_stop_listening (void );void ksmbd_rdma_destroy (void );bool ksmbd_rdma_capable_netdev (struct net_device *netdev);void init_smbd_max_io_size (unsigned int sz);unsigned int get_smbd_max_read_write_size (void );#else static inline int ksmbd_rdma_init (void ) {return 0 ; } -static inline int ksmbd_rdma_destroy (void ) {return 0 ; } +static inline void ksmbd_rdma_stop_listening (void ) { } +static inline void ksmbd_rdma_destroy (void ) { }static inline bool ksmbd_rdma_capable_netdev (struct net_device *netdev) {return false; }static inline void init_smbd_max_io_size (unsigned int sz) { }static inline unsigned int get_smbd_max_read_write_size (void ) {return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 406/482 fs/buffer: fix use-after-free when call bh_read() helper
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 7375f22495e7cd1c5b3b5af9dcc4f6dffe34ce49 ]
There's issue as follows:
BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110 Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0 CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Call Trace: <IRQ> dump_stack_lvl+0x55/0x70 print_address_description.constprop.0+0x2c/0x390 print_report+0xb4/0x270 kasan_report+0xb8/0xf0 end_buffer_read_sync+0xe3/0x110 end_bio_bh_io_sync+0x56/0x80 blk_update_request+0x30a/0x720 scsi_end_request+0x51/0x2b0 scsi_io_completion+0xe3/0x480 ? scsi_device_unbusy+0x11e/0x160 blk_complete_reqs+0x7b/0x90 handle_softirqs+0xef/0x370 irq_exit_rcu+0xa5/0xd0 sysvec_apic_timer_interrupt+0x6e/0x90 </IRQ>
Above issue happens when do ntfs3 filesystem mount, issue may happens as follows:
mount IRQntfs_fill_super
read_cache_page
do_read_cache_folio
filemap_read_folio
mpage_read_folio
do_mpage_readpage
ntfs_get_block_vbo
bh_read
submit_bh
wait_on_buffer(bh);
blk_complete_reqs
scsi_io_completion
scsi_end_request
blk_update_request
end_bio_bh_io_sync
end_buffer_read_sync
__end_buffer_read_notouch
unlock_buffer
wait_on_buffer(bh);--> return will return to caller
put_bh
--> trigger stack-out-of-boundsIn the mpage_read_folio() function, the stack variable 'map_bh' is passed to ntfs_get_block_vbo(). Once unlock_buffer() unlocks and wait_on_buffer() returns to continue processing, the stack variable is likely to be reclaimed. Consequently, during the end_buffer_read_sync() process, calling put_bh() may result in stack overrun.
If the bh is not allocated on the stack, it belongs to a folio. Freeing a buffer head which belongs to a folio is done by drop_buffers() which will fail to free buffers which are still locked. So it is safe to call put_bh() before __end_buffer_read_notouch().
--- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/buffer.c +1 -1
@@ -156,8 +156,8 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)*/ void end_buffer_read_sync (struct buffer_head *bh,int uptodate) { -__end_buffer_read_notouch (bh, uptodate);put_bh (bh); +__end_buffer_read_notouch (bh, uptodate); }EXPORT_SYMBOL (end_buffer_read_sync);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 407/482 use uniform permission checks for all mount propagation changes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit cffd0441872e7f6b1fce5e78fb1c99187a291330 ]
do_change_type() and do_set_group() are operating on different aspects of the same thing - propagation graph. The latter asks for mounts involved to be mounted in namespace(s) the caller has CAP_SYS_ADMIN for. The former is a mess - originally it didn't even check that mount *is* mounted. That got fixed, but the resulting check turns out to be too strict for userland - in effect, we check that mount is in our namespace, having already checked that we have CAP_SYS_ADMIN there.
What we really need (in both cases) is
* only touch mounts that are mounted. That's a must-have
constraint - data corruption happens if it get violated.
* don't allow to mess with a namespace unless you already
have enough permissions to do so (i.e. CAP_SYS_ADMIN in its userns).
That's an equivalent of what do_set_group() does; let's extract that into a helper (may_change_propagation()) and use it in both do_set_group() and do_change_type().
--- fs/namespace.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
fs/namespace.c +20 -14
@@ -2340,6 +2340,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)return attach_recursive_mnt (mnt, p, mp, false); } +static int may_change_propagation (const struct mount *m) +{ +struct mnt_namespace *ns = m->mnt_ns; + +// it must be mounted in some namespace +if (IS_ERR_OR_NULL (ns))// is_mounted() +return -EINVAL ; +// and the caller must be admin in userns of that namespace +if (!ns_capable (ns->user_ns,CAP_SYS_ADMIN )) +return -EPERM ; +return 0 ; +} +/* * Sanity check the flags to change_mnt_propagation. */
@@ -2376,10 +2389,10 @@ static int do_change_type(struct path *path, int ms_flags)return -EINVAL ;namespace_lock (); -if (!check_mnt (mnt)) { - err = -EINVAL ; + err =may_change_propagation (mnt); +if (err) goto out_unlock; - } +if (type ==MS_SHARED ) { err =invent_group_ids (mnt, recurse);if (err)
@@ -2774,18 +2787,11 @@ static int do_set_group(struct path *from_path, struct path *to_path)namespace_lock (); - err = -EINVAL ; -/* To and From must be mounted */ -if (!is_mounted (&from->mnt)) - goto out; -if (!is_mounted (&to->mnt)) - goto out; - - err = -EPERM ; -/* We should be allowed to modify mount namespaces of both mounts */ -if (!ns_capable (from->mnt_ns->user_ns,CAP_SYS_ADMIN )) + err =may_change_propagation (from); +if (err) goto out; -if (!ns_capable (to->mnt_ns->user_ns,CAP_SYS_ADMIN )) + err =may_change_propagation (to); +if (err) goto out; err = -EINVAL ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 408/482 fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yilun <[email protected]>
commit 1ca61060de92a4320d73adfe5dc8d335653907ac upstream.
dma_map_sgtable() returns only 0 or the error code. Read sgt->nents to get the number of mapped segments.
--- drivers/fpga/zynq-fpga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/fpga/zynq-fpga.c +4 -4
@@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fp } } - priv->dma_nelms = -dma_map_sgtable (mgr->dev.parent, sgt,DMA_TO_DEVICE ,0 ); -if (priv->dma_nelms ==0 ) { + err =dma_map_sgtable (mgr->dev.parent, sgt,DMA_TO_DEVICE ,0 ); +if (err) {dev_err (&mgr->dev,"Unable to DMA map (TO_DEVICE)\n" ); -return -ENOMEM ; +return err; } + priv->dma_nelms = sgt->nents;/* enable clock */ err =clk_enable (priv->clk);
Greg Kroah-Hartman
maintainerPATCH 409/482 ftrace: Also allocate and copy hash for reading of filter files
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit bfb336cf97df7b37b2b2edec0f69773e06d11955 upstream.
Currently the reader of set_ftrace_filter and set_ftrace_notrace just adds the pointer to the global tracer hash to its iterator. Unlike the writer that allocates a copy of the hash, the reader keeps the pointer to the filter hashes. This is problematic because this pointer is static across function calls that release the locks that can update the global tracer hashes. This can cause UAF and similar bugs.
Allocate and copy the hash for reading the filter files like it is done for the writers. This not only fixes UAF bugs, but also makes the code a bit simpler as it doesn't have to differentiate when to free the iterator's hash between writers and readers.
--- kernel/trace/ftrace.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
kernel/trace/ftrace.c +10 -9
@@ -3934,13 +3934,17 @@ ftrace_regex_open(struct ftrace_ops *ops }else { iter->hash =alloc_and_copy_ftrace_hash (size_bits, hash); } + }else { +if (hash) + iter->hash =alloc_and_copy_ftrace_hash (hash->size_bits, hash); +else + iter->hash =EMPTY_HASH ; + } -if (!iter->hash) { -trace_parser_put (&iter->parser); - goto out_unlock; - } - }else - iter->hash = hash; +if (!iter->hash) { +trace_parser_put (&iter->parser); + goto out_unlock; + } ret =0 ;
@@ -6132,9 +6136,6 @@ int ftrace_regex_release(struct inode *iftrace_hash_move_and_update_ops (iter->ops, orig_hash, iter->hash, filter_hash);mutex_unlock (&ftrace_lock); - }else { -/* For read only, the hash is the ops hash */ - iter->hash =NULL ; }mutex_unlock (&iter->ops->func_hash->regex_lock);
Greg Kroah-Hartman
maintainerPATCH 410/482 iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <[email protected]>
commit 43c0f6456f801181a80b73d95def0e0fd134e1cc upstream.
devm_gpiod_get_optional() may return non-NULL error pointer on failure. Check its return value using IS_ERR() and propagate the error if necessary.
--- drivers/iio/pressure/bmp280-core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/iio/pressure/bmp280-core.c +5 -4
@@ -1740,11 +1740,12 @@ int bmp280_common_probe(struct device *d/* Bring chip out of reset if there is an assigned GPIO line */ gpiod =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); +if (IS_ERR (gpiod)) +return dev_err_probe (dev,PTR_ERR (gpiod),"failed to get reset GPIO\n" ); +/* Deassert the signal */ -if (gpiod) { -dev_info (dev,"release reset\n" ); -gpiod_set_value (gpiod,0 ); - } +dev_info (dev,"release reset\n" ); +gpiod_set_value (gpiod,0 ); data->regmap = regmap;
Greg Kroah-Hartman
maintainerPATCH 411/482 iio: proximity: isl29501: fix buffered read on big-endian systems
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit de18e978d0cda23e4c102e18092b63a5b0b3a800 upstream.
Fix passing a u32 value as a u16 buffer scan item. This works on little- endian systems, but not on big-endian systems.
A new local variable is introduced for getting the register value and the array is changed to a struct to make the data layout more explicit rather than just changing the type and having to recalculate the proper length needed for the timestamp.
--- drivers/iio/proximity/isl29501.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/iio/proximity/isl29501.c +10 -4
@@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handstruct iio_dev *indio_dev = pf->indio_dev;struct isl29501_private *isl29501 =iio_priv (indio_dev);const unsigned long *active_mask = indio_dev->active_scan_mask; -u32 buffer[4 ]__aligned(8) = {};/* 1x16-bit + naturally aligned ts */ +u32 value; +struct { +u16 data; +aligned_s64 ts; + } scan = { }; -if (test_bit (ISL29501_DISTANCE_SCAN_INDEX , active_mask)) -isl29501_register_read (isl29501,REG_DISTANCE , buffer); +if (test_bit (ISL29501_DISTANCE_SCAN_INDEX , active_mask)) { +isl29501_register_read (isl29501,REG_DISTANCE , &value); + scan.data = value; + } -iio_push_to_buffers_with_timestamp (indio_dev, buffer, pf->timestamp); +iio_push_to_buffers_with_timestamp (indio_dev, &scan, pf->timestamp);iio_trigger_notify_done (indio_dev->trig);return IRQ_HANDLED ;
Greg Kroah-Hartman
maintainerPATCH 412/482 most: core: Drop device reference after usage in get_channel()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit b47b493d6387ae437098112936f32be27f73516c upstream.
In get_channel(), the reference obtained by bus_find_device_by_name() was dropped via put_device() before accessing the device's driver data Move put_device() after usage to avoid potential issues.
--- drivers/most/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/most/core.c +1 -1
@@ -538,8 +538,8 @@ static struct most_channel *get_channel( dev =bus_find_device_by_name (&mostbus,NULL , mdev);if (!dev)return NULL ; -put_device (dev); iface =dev_get_drvdata (dev); +put_device (dev);list_for_each_entry_safe (c, tmp, &iface->p->channel_list, list) {if (!strcmp (dev_name (&c->dev), mdev_ch))return c;
Greg Kroah-Hartman
maintainerPATCH 413/482 usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miao Li <[email protected]>
commit e664036cf36480414936cd91f4cfa2179a3d8367 upstream.
Another SanDisk 3.2Gen1 Flash Drive also need DELAY_INIT quick, or it will randomly work incorrectly on Huawei hisi platforms when doing reboot test.
--- drivers/usb/core/quirks.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/core/quirks.c +1 -0
@@ -371,6 +371,7 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, /* SanDisk Corp. SanDisk 3.2Gen1 */ + { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },/* SanDisk Extreme 55AE */
Greg Kroah-Hartman
maintainerPATCH 414/482 comedi: Make insn_rw_emulate_bits() do insn->n samples
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 7afba9221f70d4cbce0f417c558879cba0eb5e66 upstream.
The insn_rw_emulate_bits() function is used as a default handler for INSN_READ instructions for subdevices that have a handler for INSN_BITS but not for INSN_READ. Similarly, it is used as a default handler for INSN_WRITE instructions for subdevices that have a handler for INSN_BITS but not for INSN_WRITE. It works by emulating the INSN_READ or INSN_WRITE instruction handling with a constructed INSN_BITS instruction. However, INSN_READ and INSN_WRITE instructions are supposed to be able read or write multiple samples, indicated by the insn->n value, but insn_rw_emulate_bits() currently only handles a single sample. For INSN_READ, the comedi core will copy insn->n samples back to user-space. (That triggered KASAN kernel-infoleak errors when insn->n was greater than 1, but that is being fixed more generally elsewhere in the comedi core.)
Make insn_rw_emulate_bits() either handle insn->n samples, or return an error, to conform to the general expectation for INSN_READ and INSN_WRITE handlers.
--- drivers/comedi/drivers.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/comedi/drivers.c +13 -12
@@ -619,11 +619,9 @@ static int insn_rw_emulate_bits(struct cunsigned int chan =CR_CHAN (insn->chanspec);unsigned int base_chan = (chan <32 ) ?0 : chan;unsigned int _data[2 ]; +unsigned int i;int ret; -if (insn->n ==0 ) -return 0 ; -memset (_data,0 ,sizeof (_data));memset (&_insn,0 ,sizeof (_insn)); _insn.insn =INSN_BITS ;
@@ -634,18 +632,21 @@ static int insn_rw_emulate_bits(struct cif (insn->insn ==INSN_WRITE ) {if (!(s->subdev_flags &SDF_WRITABLE ))return -EINVAL ; - _data[0 ] =1U << (chan - base_chan);/* mask */ - _data[1 ] = data[0 ] ? (1U << (chan - base_chan)) :0 ;/* bits */ + _data[0 ] =1U << (chan - base_chan);/* mask */ } +for (i =0 ; i < insn->n; i++) { +if (insn->insn ==INSN_WRITE ) + _data[1 ] = data[i] ? _data[0 ] :0 ;/* bits */ + + ret = s->insn_bits (dev, s, &_insn, _data); +if (ret <0 ) +return ret; - ret = s->insn_bits (dev, s, &_insn, _data); -if (ret <0 ) -return ret; - -if (insn->insn ==INSN_READ ) - data[0 ] = (_data[1 ] >> (chan - base_chan)) &1 ; +if (insn->insn ==INSN_READ ) + data[i] = (_data[1 ] >> (chan - base_chan)) &1 ; + } -return 1 ; +return insn->n; } static int __comedi_device_postconfig_async(struct comedi_device *dev,
Greg Kroah-Hartman
maintainerPATCH 415/482 comedi: pcl726: Prevent invalid irq number
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
commit 96cb948408b3adb69df7e451ba7da9d21f814d00 upstream.
The reproducer passed in an irq number(0x80008000) that was too large, which triggered the oob.
Added an interrupt number check to prevent users from passing in an irq number that was too large.
If it->options[1] is 31, then 1 << it->options[1] is still invalid because it shifts a 1-bit into the sign bit (which is UB in C). Possible solutions include reducing the upper bound on the it->options[1] value to 30 or lower, or using 1U << it->options[1].
The old code would just not attempt to request the IRQ if the options[1] value were invalid. And it would still configure the device without interrupts even if the call to request_irq returned an error. So it would be better to combine this test with the test below.
--- drivers/comedi/drivers/pcl726.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/comedi/drivers/pcl726.c +2 -1
@@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_d* Hook up the external trigger source interrupt only if the * user config option is valid and the board supports interrupts. */ -if (it->options[1 ] && (board->irq_mask & (1 << it->options[1 ]))) { +if (it->options[1 ] >0 && it->options[1 ] <16 && + (board->irq_mask & (1U << it->options[1 ]))) { ret =request_irq (it->options[1 ], pcl726_interrupt,0 , dev->board_name, dev);if (ret ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 416/482 comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 3cd212e895ca2d58963fdc6422502b10dd3966bb upstream.
syzbot reports a KMSAN kernel-infoleak in do_insn_ioctl(). A kernel buffer is allocated to hold insn->n samples (each of which is an unsigned int). For some instruction types, insn->n samples are copied back to user-space, unless an error code is being returned. The problem is that not all the instruction handlers that need to return data to userspace fill in the whole insn->n samples, so that there is an information leak. There is a similar syzbot report for do_insnlist_ioctl(), although it does not have a reproducer for it at the time of writing.
One culprit is insn_rw_emulate_bits() which is used as the handler for INSN_READ or INSN_WRITE instructions for subdevices that do not have a specific handler for that instruction, but do have an INSN_BITS handler. For INSN_READ it only fills in at most 1 sample, so if insn->n is greater than 1, the remaining insn->n - 1 samples copied to userspace will be uninitialized kernel data.
Another culprit is vm80xx_ai_insn_read() in the "vm80xx" driver. It never returns an error, even if it fails to fill the buffer.
Fix it in do_insn_ioctl() and do_insnlist_ioctl() by making sure that uninitialized parts of the allocated buffer are zeroed before handling each instruction.
Thanks to Arnaud Lecomte for their fix to do_insn_ioctl(). That fix replaced the call to kmalloc_array() with kcalloc(), but it is not always necessary to clear the whole buffer.
--- drivers/comedi/comedi_fops.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/comedi/comedi_fops.c +5 -0
@@ -1582,6 +1582,9 @@ static int do_insnlist_ioctl(struct comememset (&data[n],0 , (MIN_SAMPLES - n) *sizeof (unsigned int )); } + }else { + memset(data, 0, max_t(unsigned int, n, MIN_SAMPLES) * +sizeof (unsigned int )); } ret =parse_insn (dev, insns + i, data, file);if (ret <0 )
@@ -1665,6 +1668,8 @@ static int do_insn_ioctl(struct comedi_dmemset (&data[insn->n],0 , (MIN_SAMPLES - insn->n) *sizeof (unsigned int )); } + }else { +memset (data,0 , n_data *sizeof (unsigned int )); } ret =parse_insn (dev, insn, data, file);if (ret <0 )
Greg Kroah-Hartman
maintainerPATCH 417/482 usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
commit 8fe06185e11ae753414aa6117f0e798aa77567ff upstream.
The USB core will unmap urb->transfer_dma after SETUP stage completes. Then the USB controller will access unmapped memory when it received device descriptor. If iommu is equipped, the entire test can't be completed due to the memory accessing is blocked.
Fix it by calling map_urb_for_dma() again for IN stage. To reduce redundant map for urb->transfer_buffer, this will also set URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP flag before second map_urb_for_dma().
--- drivers/usb/core/hcd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/usb/core/hcd.c +7 -1
@@ -2177,7 +2177,7 @@ static struct urb *request_single_step_s urb->complete = usb_ehset_completion; urb->status = -EINPROGRESS ; urb->actual_length =0 ; - urb->transfer_flags =URB_DIR_IN ; + urb->transfer_flags =URB_DIR_IN |URB_NO_TRANSFER_DMA_MAP ;usb_get_urb (urb);atomic_inc (&urb->use_count);atomic_inc (&urb->dev->urbnum);
@@ -2241,9 +2241,15 @@ int ehset_single_step_set_feature(struct/* Complete remaining DATA and STATUS stages using the same URB */ urb->status = -EINPROGRESS ; + urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP ;usb_get_urb (urb);atomic_inc (&urb->use_count);atomic_inc (&urb->dev->urbnum); +if (map_urb_for_dma (hcd, urb,GFP_KERNEL )) { +usb_put_urb (urb); + goto out1; + } + retval = hcd->driver->submit_single_step_set_feature (hcd, urb,0 );if (!retval && !wait_for_completion_timeout (&done,msecs_to_jiffies (2000 ))) {
Greg Kroah-Hartman
maintainerPATCH 418/482 usb: renesas-xhci: Fix External ROM access timeouts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit f9420f4757752f056144896024d5ea89e5a611f1 upstream.
Increase the External ROM access timeouts to prevent failures during programming of External SPI EEPROM chips. The current timeouts are too short for some SPI EEPROMs used with uPD720201 controllers.
The current timeout for Chip Erase in renesas_rom_erase() is 100 ms , the current timeout for Sector Erase issued by the controller before Page Program in renesas_fw_download_image() is also 100 ms. Neither timeout is sufficient for e.g. the Macronix MX25L5121E or MX25V5126F.
MX25L5121E reference manual [1] page 35 section "ERASE AND PROGRAMMING PERFORMANCE" and page 23 section "Table 8. AC CHARACTERISTICS (Temperature = 0°C to 70°C for Commercial grade, VCC = 2.7V ~ 3.6V)" row "tCE" indicate that the maximum time required for Chip Erase opcode to complete is 2 s, and for Sector Erase it is 300 ms .
MX25V5126F reference manual [2] page 47 section "13. ERASE AND PROGRAMMING PERFORMANCE (2.3V - 3.6V)" and page 42 section "Table 8. AC CHARACTERISTICS (Temperature = -40°C to 85°C for Industrial grade, VCC = 2.3V - 3.6V)" row "tCE" indicate that the maximum time required for Chip Erase opcode to complete is 3.2 s, and for Sector Erase it is 400 ms .
Update the timeouts such, that Chip Erase timeout is set to 5 seconds, and Sector Erase timeout is set to 500 ms. Such lengthy timeouts ought to be sufficient for majority of SPI EEPROM chips.
[1] https://www.macronix.com/Lists/Datasheet/Attachments/8634/MX25L5121E,%203V,%20512Kb,%20v1.3.pdf
[2] https://www.macronix.com/Lists/Datasheet/Attachments/8750/MX25V5126F,%202.5V,%20512Kb,%20v1.1.pdf
--- drivers/usb/host/xhci-pci-renesas.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci-renesas.c +4 -3
@@ -47,8 +47,9 @@#define RENESAS_ROM_ERASE_MAGIC 0x5A65726F#define RENESAS_ROM_WRITE_MAGIC 0x53524F4D -#define RENESAS_RETRY 10000 -#define RENESAS_DELAY 10 +#define RENESAS_RETRY 50000/* 50000 * RENESAS_DELAY ~= 500ms */ +#define RENESAS_CHIP_ERASE_RETRY 500000/* 500000 * RENESAS_DELAY ~= 5s */ +#define RENESAS_DELAY 10static int renesas_fw_download_image (struct pci_dev *dev,const u32 *fw,size_t step,bool rom)
@@ -405,7 +406,7 @@ static void renesas_rom_erase(struct pci/* sleep a bit while ROM is erased */ msleep (20 ); -for (i =0 ; i <RENESAS_RETRY ; i++) { +for (i =0 ; i <RENESAS_CHIP_ERASE_RETRY ; i++) { retval =pci_read_config_byte (pdev,RENESAS_ROM_STATUS , &status); status &=RENESAS_ROM_STATUS_ERASE ;
Greg Kroah-Hartman
maintainerPATCH 419/482 USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mael GUERIN <[email protected]>
commit 6ca8af3c8fb584f3424a827f554ff74f898c27cd upstream.
Add the US_FL_BULK_IGNORE_TAG quirk for Novatek NTK96550-based camera to fix USB resets after sending SCSI vendor commands due to CBW and CSW tags difference, leading to undesired slowness while communicating with the device.
Please find below the copy of /sys/kernel/debug/usb/devices with my device plugged in (listed as TechSys USB mass storage here, the underlying chipset being the Novatek NTK96550-based camera):
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0603 ProdID=8611 Rev= 0.01 S: Manufacturer=TechSys S: Product=USB Mass Storage S: SerialNumber=966110000000100 C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/storage/unusual_devs.h +7 -0
@@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Added by Maël GUERIN <[email protected]> */ +UNUSUAL_DEV (0x0603 ,0x8611 ,0x0000 ,0xffff , +"Novatek" , +"NTK96550-based camera" , +USB_SC_SCSI ,USB_PR_BULK ,NULL , + US_FL_BULK_IGNORE_TAG ), +/* * Reported by Hanno Boeck <[email protected]> * Taken from the Lycoris Kernel
Greg Kroah-Hartman
maintainerPATCH 420/482 usb: storage: realtek_cr: Use correct byte order for bcs->Residue
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 98da66a70ad2396e5a508c4245367797ebc052ce upstream.
Since 'bcs->Residue' has the data type '__le32', convert it to the correct byte order of the CPU using this driver when assigning it to the local variable 'residue'.
--- drivers/usb/storage/realtek_cr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/realtek_cr.c +1 -1
@@ -252,7 +252,7 @@ static int rts51x_bulk_transport(structreturn USB_STOR_TRANSPORT_ERROR ; } - residue = bcs->Residue; + residue =le32_to_cpu (bcs->Residue);if (bcs->Tag != us->tag)return USB_STOR_TRANSPORT_ERROR ;
Greg Kroah-Hartman
maintainerPATCH 421/482 USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zenm Chen <[email protected]>
commit a3dc32c635bae0ae569f489e00de0e8f015bfc25 upstream.
Many Realtek USB Wi-Fi dongles released in recent years have two modes:
one is driver CD mode which has Windows driver onboard, another one is Wi-Fi mode. Add the US_FL_IGNORE_DEVICE quirk for these multi-mode devices. Otherwise, usb_modeswitch may fail to switch them to Wi-Fi mode.
Currently there are only two USB IDs known to be used by these multi-mode Wi-Fi dongles: 0bda:1a2b and 0bda:a192.
Information about Mercury MW310UH in /sys/kernel/debug/usb/devices.
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=a192 Rev= 2.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Information about D-Link AX9U rev. A1 in /sys/kernel/debug/usb/devices.
T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 55 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=1a2b Rev= 0.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/usb/storage/unusual_devs.h +22 -0
@@ -1501,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9 USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_WP_DETECT ), +/* +* Reported by Zenm Chen <[email protected]> +* Ignore driver CD mode, otherwise usb_modeswitch may fail to switch +* the device into Wi-Fi mode. +*/ +UNUSUAL_DEV (0x0bda ,0x1a2b ,0x0000 ,0xffff , +"Realtek" , +"DISK" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_IGNORE_DEVICE ), + +/* +* Reported by Zenm Chen <[email protected]> +* Ignore driver CD mode, otherwise usb_modeswitch may fail to switch +* the device into Wi-Fi mode. +*/ +UNUSUAL_DEV (0x0bda ,0xa192 ,0x0000 ,0xffff , +"Realtek" , +"DISK" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_IGNORE_DEVICE ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA",
Greg Kroah-Hartman
maintainerPATCH 422/482 usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <[email protected]>
commit 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 upstream.
During a device-initiated disconnect, the End Transfer command resets the event filter, allowing a new xferNotReady event to be generated before the controller is fully halted. Processing this late event incorrectly triggers a Start Transfer, which prevents the controller from halting and results in a DSTS.DEVCTLHLT bit polling timeout.
Ignore the late xferNotReady event if the controller is already in a disconnected state.
--- drivers/usb/dwc3/gadget.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/dwc3/gadget.c +9 -0
@@ -3590,6 +3590,15 @@ static void dwc3_gadget_endpoint_transfestatic void dwc3_gadget_endpoint_transfer_not_ready (struct dwc3_ep *dep,const struct dwc3_event_depevt *event) { +/* +* During a device-initiated disconnect, a late xferNotReady event can +* be generated after the End Transfer command resets the event filter, +* but before the controller is halted. Ignore it to prevent a new +* transfer from starting. +*/ +if (!dep->dwc->connected) +return ; +dwc3_gadget_endpoint_frame_from_event (dep, event);/*
Greg Kroah-Hartman
maintainerPATCH 423/482 usb: dwc3: Remove WARN_ON for device endpoint command timeouts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvarasu Ganesan <[email protected]>
commit 45eae113dccaf8e502090ecf5b3d9e9b805add6f upstream.
This commit addresses a rarely observed endpoint command timeout which causes kernel panic due to warn when 'panic_on_warn' is enabled and unnecessary call trace prints when 'panic_on_warn' is disabled. It is seen during fast software-controlled connect/disconnect testcases. The following is one such endpoint command timeout that we observed:
1. Connect
=======
->dwc3_thread_interrupt
->dwc3_ep0_interrupt
->configfs_composite_setup
->composite_setup
->usb_ep_queue
->dwc3_gadget_ep0_queue
->__dwc3_gadget_ep0_queue
->__dwc3_ep0_do_control_data
->dwc3_send_gadget_ep_cmd2. Disconnect
==========
->dwc3_thread_interrupt
->dwc3_gadget_disconnect_interrupt
->dwc3_ep0_reset_state
->dwc3_ep0_end_control_data
->dwc3_send_gadget_ep_cmd
In the issue scenario, in Exynos platforms, we observed that control transfers for the previous connect have not yet been completed and end transfer command sent as a part of the disconnect sequence and processing of USB_ENDPOINT_HALT feature request from the host timeout. This maybe an expected scenario since the controller is processing EP commands sent as a part of the previous connect. It maybe better to remove WARN_ON in all places where device endpoint commands are sent to avoid unnecessary kernel panic due to warn.
--- drivers/usb/dwc3/ep0.c | 20 ++++++++++++++++---- drivers/usb/dwc3/gadget.c | 10 ++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/usb/dwc3/ep0.c +16 -4
@@ -286,7 +286,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwcdwc3_ep0_prepare_one_trb (dep, dwc->ep0_trb_addr,8 ,DWC3_TRBCTL_CONTROL_SETUP , false); ret =dwc3_ep0_start_trans (dep); -WARN_ON (ret <0 ); +if (ret <0 ) +dev_err (dwc->dev,"ep0 out start transfer failed: %d\n" , ret); +for (i =2 ; i <DWC3_ENDPOINTS_NUM ; i++) {struct dwc3_ep *dwc3_ep;
@@ -1058,7 +1060,9 @@ static void __dwc3_ep0_do_control_data(s ret =dwc3_ep0_start_trans (dep); } -WARN_ON (ret <0 ); +if (ret <0 ) +dev_err (dwc->dev, +"ep0 data phase start transfer failed: %d\n" , ret); }static int dwc3_ep0_start_control_status (struct dwc3_ep *dep)
@@ -1075,7 +1079,12 @@ static int dwc3_ep0_start_control_statusstatic void __dwc3_ep0_do_control_status (struct dwc3 *dwc,struct dwc3_ep *dep) { -WARN_ON (dwc3_ep0_start_control_status (dep)); +int ret; + + ret =dwc3_ep0_start_control_status (dep); +if (ret) +dev_err (dwc->dev, +"ep0 status phase start transfer failed: %d\n" , ret); } static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
@@ -1118,7 +1127,10 @@ void dwc3_ep0_end_control_data(struct dw cmd |=DWC3_DEPCMD_PARAM (dep->resource_index);memset (¶ms,0 ,sizeof (params)); ret =dwc3_send_gadget_ep_cmd (dep, cmd, ¶ms); -WARN_ON_ONCE (ret); +if (ret) +dev_err_ratelimited (dwc->dev, +"ep0 data phase end transfer failed: %d\n" , ret); + dep->resource_index =0 ; }
drivers/usb/dwc3/gadget.c +8 -2
@@ -1724,7 +1724,11 @@ static int __dwc3_stop_active_transfer(s dep->flags |=DWC3_EP_DELAY_STOP ;return 0 ; } -WARN_ON_ONCE (ret); + +if (ret) +dev_err_ratelimited (dep->dwc->dev, +"end transfer failed: %d\n" , ret); + dep->resource_index =0 ;if (!interrupt)
@@ -3897,7 +3901,9 @@ static void dwc3_clear_stall_all_ep(stru dep->flags &= ~DWC3_EP_STALL ; ret =dwc3_send_clear_stall_ep_cmd (dep); -WARN_ON_ONCE (ret); +if (ret) +dev_err_ratelimited (dwc->dev, +"failed to clear STALL on %s\n" , dep->name); } }
Greg Kroah-Hartman
maintainerPATCH 424/482 arm64: dts: ti: k3-am62-main: Remove eMMC High Speed DDR support
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
[ Upstream commit 265f70af805f33a0dfc90f50cc0f116f702c3811 ]
For eMMC, High Speed DDR mode is not supported [0], so remove mmc-ddr-1_8v flag which adds the capability.
[0] https://www.ti.com/lit/gpn/am625
--- arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/ti/k3-am62-main.dtsi +0 -1
@@ -386,7 +386,6 @@ clock-names = "clk_ahb", "clk_xin"; assigned-clocks = <&k3_clks 57 6>; assigned-clock-parents = <&k3_clks 57 8>; - mmc-ddr-1_8v; mmc-hs200-1_8v; ti,trm-icp = <0x2>; bus-width = <8>;
Greg Kroah-Hartman
maintainerPATCH 425/482 scsi: ufs: exynos: Fix programming of HCI_UTRL_NEXUS_TYPE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <[email protected]>
[ Upstream commit 01aad16c2257ab8ff33b152b972c9f2e1af47912 ]
On Google gs101, the number of UTP transfer request slots (nutrs) is 32, and in this case the driver ends up programming the UTRL_NEXUS_TYPE incorrectly as 0.
This is because the left hand side of the shift is 1, which is of type int, i.e. 31 bits wide. Shifting by more than that width results in undefined behaviour.
Fix this by switching to the BIT() macro, which applies correct type casting as required. This ensures the correct value is written to UTRL_NEXUS_TYPE (0xffffffff on gs101), and it also fixes a UBSAN shift warning:
UBSAN: shift-out-of-bounds in drivers/ufs/host/ufs-exynos.c:1113:21
shift exponent 32 is too large for 32-bit type 'int'For consistency, apply the same change to the nutmrs / UTMRL_NEXUS_TYPE write.
--- drivers/ufs/host/ufs-exynos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/ufs/host/ufs-exynos.c +2 -2
@@ -1028,8 +1028,8 @@ static int exynos_ufs_post_link(struct uhci_writel (ufs,0xa ,HCI_DATA_REORDER );hci_writel (ufs,PRDT_SET_SIZE (12 ),HCI_TXPRDT_ENTRY_SIZE );hci_writel (ufs,PRDT_SET_SIZE (12 ),HCI_RXPRDT_ENTRY_SIZE ); -hci_writel (ufs, (1 << hba->nutrs) -1 ,HCI_UTRL_NEXUS_TYPE ); -hci_writel (ufs, (1 << hba->nutmrs) -1 ,HCI_UTMRL_NEXUS_TYPE ); +hci_writel (ufs,BIT (hba->nutrs) -1 ,HCI_UTRL_NEXUS_TYPE ); +hci_writel (ufs,BIT (hba->nutmrs) -1 ,HCI_UTMRL_NEXUS_TYPE );hci_writel (ufs,0xf ,HCI_AXIDMA_RWDATA_BURST_LEN );if (ufs->opts &EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB )
Greg Kroah-Hartman
maintainerPATCH 426/482 ext4: preserve SB_I_VERSION on remount
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
[ Upstream commit f2326fd14a224e4cccbab89e14c52279ff79b7ec ]
IMA testing revealed that after an ext4 remount, file accesses triggered full measurements even without modifications, instead of skipping as expected when i_version is unchanged.
Debugging showed SB_I_VERSION was cleared in reconfigure_super() during remount due to commit 1ff20307393e ("ext4: unconditionally enable the i_version counter") removing the fix from commit 960e0ab63b2e ("ext4: fix i_version handling on remount").
To rectify this, SB_I_VERSION is always set for fc->sb_flags in ext4_init_fs_context(), instead of sb->s_flags in __ext4_fill_super(), ensuring it persists across all mounts.
--- fs/ext4/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/super.c +3 -3
@@ -1937,6 +1937,9 @@ int ext4_init_fs_context(struct fs_conte fc->fs_private = ctx; fc->ops = &ext4_context_ops; +/* i_version is always enabled now */ + fc->sb_flags |=SB_I_VERSION ; +return 0 ; }
@@ -5113,9 +5116,6 @@ static int __ext4_fill_super(struct fs_c sb->s_flags = (sb->s_flags & ~SB_POSIXACL ) | (test_opt (sb,POSIX_ACL ) ?SB_POSIXACL :0 ); -/* i_version is always enabled now */ - sb->s_flags |=SB_I_VERSION ; -if (ext4_check_feature_compatibility (sb, es, silent)) goto failed_mount;
Greg Kroah-Hartman
maintainerPATCH 427/482 scsi: mpi3mr: Drop unnecessary volatile from __iomem pointers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit 6853885b21cb1d7157cc14c9d30cc17141565bae ]
The volatile qualifier is redundant for __iomem pointers.
Cleaned up usage in mpi3mr_writeq() and sysif_regs pointer as per Upstream compliance.
Stable-dep-of: c91e140c82eb ("scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems")
--- drivers/scsi/mpi3mr/mpi3mr.h | 2 +- drivers/scsi/mpi3mr/mpi3mr_fw.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/mpi3mr/mpi3mr.h +1 -1
@@ -1035,7 +1035,7 @@ struct mpi3mr_ioc {char name[MPI3MR_NAME_LENGTH ];char driver_name[MPI3MR_NAME_LENGTH ]; -volatile struct mpi3_sysif_registers __iomem *sysif_regs; +struct mpi3_sysif_registers __iomem *sysif_regs;resource_size_t sysif_regs_phys;int bars;u64 dma_mask;
drivers/scsi/mpi3mr/mpi3mr_fw.c +2 -2
@@ -23,12 +23,12 @@ module_param(poll_queues, int, 0444);MODULE_PARM_DESC (poll_queues,"Number of queues for io_uring poll mode. (Range 1 - 126)" );#if defined(writeq) && defined(CONFIG_64BIT ) -static inline void mpi3mr_writeq (__u64 b,volatile void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) {writeq (b, addr); }#else -static inline void mpi3mr_writeq (__u64 b,volatile void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) {__u64 data_out = b;
Greg Kroah-Hartman
maintainerPATCH 428/482 scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit c91e140c82eb58724c435f623702e51cc7896646 ]
On 32-bit systems, 64-bit BAR writes to admin queue registers are performed as two 32-bit writes. Without locking, this can cause partial writes when accessed concurrently.
Updated per-queue spinlocks is used to serialize these writes and prevent race conditions.
--- drivers/scsi/mpi3mr/mpi3mr.h | 4 ++++ drivers/scsi/mpi3mr/mpi3mr_fw.c | 15 +++++++++++---- drivers/scsi/mpi3mr/mpi3mr_os.c | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-)
drivers/scsi/mpi3mr/mpi3mr.h +4 -0
@@ -1005,6 +1005,8 @@ struct scmd_priv {* @logdata_buf: Circular buffer to store log data entries * @logdata_buf_idx: Index of entry in buffer to store * @logdata_entry_sz: log data entry size +* @adm_req_q_bar_writeq_lock: Admin request queue lock +* @adm_reply_q_bar_writeq_lock: Admin reply queue lock * @pend_large_data_sz: Counter to track pending large data * @io_throttle_data_length: I/O size to track in 512b blocks * @io_throttle_high: I/O size to start throttle in 512b blocks
@@ -1186,6 +1188,8 @@ struct mpi3mr_ioc {u8 *logdata_buf;u16 logdata_buf_idx;u16 logdata_entry_sz; +spinlock_t adm_req_q_bar_writeq_lock; +spinlock_t adm_reply_q_bar_writeq_lock;atomic_t pend_large_data_sz;u32 io_throttle_data_length;
drivers/scsi/mpi3mr/mpi3mr_fw.c +11 -4
@@ -23,17 +23,22 @@ module_param(poll_queues, int, 0444);MODULE_PARM_DESC (poll_queues,"Number of queues for io_uring poll mode. (Range 1 - 126)" );#if defined(writeq) && defined(CONFIG_64BIT ) -static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr, +spinlock_t *write_queue_lock) {writeq (b, addr); }#else -static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr, +spinlock_t *write_queue_lock) {__u64 data_out = b; +unsigned long flags; +spin_lock_irqsave (write_queue_lock, flags);writel ((u32)(data_out), addr);writel ((u32)(data_out >>32 ), (addr +4 )); +spin_unlock_irqrestore (write_queue_lock, flags); }#endif
@@ -2662,9 +2667,11 @@ static int mpi3mr_setup_admin_qpair(stru (mrioc->num_admin_req);writel (num_admin_entries, &mrioc->sysif_regs->admin_queue_num_entries);mpi3mr_writeq (mrioc->admin_req_dma, - &mrioc->sysif_regs->admin_request_queue_address); + &mrioc->sysif_regs->admin_request_queue_address, + &mrioc->adm_req_q_bar_writeq_lock);mpi3mr_writeq (mrioc->admin_reply_dma, - &mrioc->sysif_regs->admin_reply_queue_address); + &mrioc->sysif_regs->admin_reply_queue_address, + &mrioc->adm_reply_q_bar_writeq_lock);writel (mrioc->admin_req_pi, &mrioc->sysif_regs->admin_request_queue_pi);writel (mrioc->admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci);return retval;
drivers/scsi/mpi3mr/mpi3mr_os.c +2 -0
@@ -4966,6 +4966,8 @@ mpi3mr_probe(struct pci_dev *pdev, constspin_lock_init (&mrioc->tgtdev_lock);spin_lock_init (&mrioc->watchdog_lock);spin_lock_init (&mrioc->chain_buf_lock); +spin_lock_init (&mrioc->adm_req_q_bar_writeq_lock); +spin_lock_init (&mrioc->adm_reply_q_bar_writeq_lock);spin_lock_init (&mrioc->sas_node_lock);INIT_LIST_HEAD (&mrioc->fwevt_list);
Greg Kroah-Hartman
maintainerPATCH 429/482 PCI: rockchip: Use standard PCIe definitions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit cbbfe9f683f0f9b6a1da2eaa53b995a4b5961086 ]
Current code uses custom-defined register offsets and bitfields for the standard PCIe registers. This creates duplication as the PCI header already defines them. So, switch to using the standard PCIe definitions and drop the custom ones.
--- drivers/pci/controller/pcie-rockchip-host.c | 45 ++++++++++++++-------------- drivers/pci/controller/pcie-rockchip.h | 11 ------ 2 files changed, 24 insertions(+), 32 deletions(-)
drivers/pci/controller/pcie-rockchip-host.c +23 -22
@@ -11,6 +11,7 @@* ARM PCI Host generic driver. */ +#include <linux/bitfield.h> #include <linux/bitrev.h> #include <linux/clk.h> #include <linux/delay.h>
@@ -43,18 +44,18 @@ static void rockchip_pcie_enable_bw_int( {u32 status; - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |= (PCI_EXP_LNKCTL_LBMIE |PCI_EXP_LNKCTL_LABIE ); -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); }static void rockchip_pcie_clr_bw_int (struct rockchip_pcie *rockchip) {u32 status; - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |= (PCI_EXP_LNKSTA_LBMS |PCI_EXP_LNKSTA_LABS ) <<16 ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); }static void rockchip_pcie_update_txcredit_mui (struct rockchip_pcie *rockchip)
@@ -272,7 +273,7 @@ static void rockchip_pcie_set_power_limi scale =3 ;/* 0.001x */ curr = curr /1000 ;/* convert to mA */ power = (curr *3300 ) /1000 ;/* milliwatt */ -while (power >PCIE_RC_CONFIG_DCR_CSPL_LIMIT ) { +while (power >FIELD_MAX (PCI_EXP_DEVCAP_PWR_VAL )) {if (!scale) {dev_warn (rockchip->dev,"invalid power supply\n" );return ;
@@ -281,10 +282,10 @@ static void rockchip_pcie_set_power_limi power = power /10 ; } - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_DCR ); - status |= (power <<PCIE_RC_CONFIG_DCR_CSPL_SHIFT ) | - (scale <<PCIE_RC_CONFIG_DCR_CPLS_SHIFT ); -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_DCR ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCAP ); + status |=FIELD_PREP (PCI_EXP_DEVCAP_PWR_VAL , power); + status |=FIELD_PREP (PCI_EXP_DEVCAP_PWR_SCL , scale); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCAP ); }/**
@@ -312,14 +313,14 @@ static int rockchip_pcie_host_init_port(rockchip_pcie_set_power_limit (rockchip);/* Set RC's clock architecture as common clock */ - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKSTA_SLC <<16 ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );/* Set RC's RCB to 128 */ - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RCB ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );/* Enable Gen1 training */ rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
@@ -341,9 +342,9 @@ static int rockchip_pcie_host_init_port(* Enable retrain for gen2. This should be configured only after * gen1 finished. */ - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RL ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); err = readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL, status, PCIE_LINK_IS_GEN2(status), 20,
@@ -380,15 +381,15 @@ static int rockchip_pcie_host_init_port(/* Clear L0s from RC's link cap */ if (of_property_read_bool (dev->of_node,"aspm-no-l0s" )) { - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LINK_CAP ); - status &= ~PCIE_RC_CONFIG_LINK_CAP_L0S ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LINK_CAP ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCAP ); + status &= ~PCI_EXP_LNKCAP_ASPM_L0S ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCAP ); } - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_DCSR ); - status &= ~PCIE_RC_CONFIG_DCSR_MPS_MASK ; - status |=PCIE_RC_CONFIG_DCSR_MPS_256 ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_DCSR ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCTL ); + status &= ~PCI_EXP_DEVCTL_PAYLOAD ; + status |=PCI_EXP_DEVCTL_PAYLOAD_256B ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCTL );return 0 ; err_power_off_phy:
drivers/pci/controller/pcie-rockchip.h +1 -10
@@ -144,16 +144,7 @@#define PCIE_EP_CONFIG_BASE 0xa00000#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00)#define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) -#define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) -#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 -#define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff -#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 -#define PCIE_RC_CONFIG_DCSR (PCIE_RC_CONFIG_BASE + 0xc8) -#define PCIE_RC_CONFIG_DCSR_MPS_MASK GENMASK(7, 5) -#define PCIE_RC_CONFIG_DCSR_MPS_256 (0x1 << 5) -#define PCIE_RC_CONFIG_LINK_CAP (PCIE_RC_CONFIG_BASE + 0xcc) -#define PCIE_RC_CONFIG_LINK_CAP_L0S BIT(10) -#define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) +#define PCIE_RC_CONFIG_CR (PCIE_RC_CONFIG_BASE + 0xc0)#define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20)
Greg Kroah-Hartman
maintainerPATCH 430/482 PCI: rockchip: Set Target Link Speed to 5.0 GT/s before retraining
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit 114b06ee108cabc82b995fbac6672230a9776936 ]
Rockchip controllers can support up to 5.0 GT/s link speed. But the driver doesn't set the Target Link Speed currently. This may cause failure in retraining the link to 5.0 GT/s if supported by the endpoint. So set the Target Link Speed to 5.0 GT/s in the Link Control and Status Register 2.
--- drivers/pci/controller/pcie-rockchip-host.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/pci/controller/pcie-rockchip-host.c +4 -0
@@ -342,6 +342,10 @@ static int rockchip_pcie_host_init_port(* Enable retrain for gen2. This should be configured only after * gen1 finished. */ + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL2 ); + status &= ~PCI_EXP_LNKCTL2_TLS ; + status |=PCI_EXP_LNKCTL2_TLS_5_0GT ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL2 ); status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RL ;rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );
Greg Kroah-Hartman
maintainerPATCH 431/482 soc: qcom: mdt_loader: Enhance split binary detection
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gokul krishna Krishnakumar <[email protected]>
[ Upstream commit 210d12c8197a551caa2979be421aa42381156aec ]
It may be that the offset of the first program header lies inside the mdt's filesize, in this case the loader would incorrectly assume that the bins were not split and in this scenario the firmware authentication fails. This change updates the logic used by the mdt loader to understand whether the firmware images are split or not. It figures this out by checking if each programs header's segment lies within the file or not.
Stable-dep-of: 9f9967fed9d0 ("soc: qcom: mdt_loader: Ensure we don't read past the ELF header")
--- drivers/soc/qcom/mdt_loader.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
drivers/soc/qcom/mdt_loader.c +23 -2
@@ -264,6 +264,26 @@ out: }EXPORT_SYMBOL_GPL (qcom_mdt_pas_init); +static bool qcom_mdt_bins_are_split (const struct firmware *fw,const char *fw_name) +{ +const struct elf32_phdr *phdrs; +const struct elf32_hdr *ehdr; +uint64_t seg_start, seg_end; +int i; + + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(ehdr +1 ); + +for (i =0 ; i < ehdr->e_phnum; i++) { + seg_start = phdrs[i].p_offset; + seg_end = phdrs[i].p_offset + phdrs[i].p_filesz; +if (seg_start > fw->size || seg_end > fw->size) +return true; + } + +return false; +} + static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size,
@@ -276,6 +296,7 @@ static int __qcom_mdt_load(struct devicephys_addr_t min_addr =PHYS_ADDR_MAX ;ssize_t offset;bool relocate = false; +bool is_split;void *ptr;int ret =0 ;int i;
@@ -283,6 +304,7 @@ static int __qcom_mdt_load(struct deviceif (!fw || !mem_region || !mem_phys || !mem_size)return -EINVAL ; + is_split =qcom_mdt_bins_are_split (fw, fw_name); ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -336,8 +358,7 @@ static int __qcom_mdt_load(struct device ptr = mem_region + offset; -if (phdr->p_filesz && phdr->p_offset < fw->size && - phdr->p_offset + phdr->p_filesz <= fw->size) { +if (phdr->p_filesz && !is_split) {/* Firmware is large enough to be non-split */ if (phdr->p_offset + phdr->p_filesz > fw->size) { dev_err(dev, "file %s segment %d would be truncated\n",
Greg Kroah-Hartman
maintainerPATCH 432/482 soc: qcom: mdt_loader: Ensure we dont read past the ELF header
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Andersson <[email protected]>
[ Upstream commit 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef ]
When the MDT loader is used in remoteproc, the ELF header is sanitized beforehand, but that's not necessary the case for other clients.
Validate the size of the firmware buffer to ensure that we don't read past the end as we iterate over the header. e_phentsize and e_shentsize are validated as well, to ensure that the assumptions about step size in the traversal are valid.
--- drivers/soc/qcom/mdt_loader.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
drivers/soc/qcom/mdt_loader.c +43 -0
@@ -17,6 +17,37 @@#include <linux/slab.h> #include <linux/soc/qcom/mdt_loader.h> +static bool mdt_header_valid (const struct firmware *fw) +{ +const struct elf32_hdr *ehdr; +size_t phend; +size_t shend; + +if (fw->size <sizeof (*ehdr)) +return false; + + ehdr = (struct elf32_hdr *)fw->data; + +if (memcmp (ehdr->e_ident,ELFMAG ,SELFMAG )) +return false; + +if (ehdr->e_phentsize !=sizeof (struct elf32_phdr )) +return -EINVAL ; + + phend =size_add (size_mul (sizeof (struct elf32_phdr ), ehdr->e_phnum), ehdr->e_phoff); +if (phend > fw->size) +return false; + +if (ehdr->e_shentsize !=sizeof (struct elf32_shdr )) +return -EINVAL ; + + shend =size_add (size_mul (sizeof (struct elf32_shdr ), ehdr->e_shnum), ehdr->e_shoff); +if (shend > fw->size) +return false; + +return true; +} +static bool mdt_phdr_valid (const struct elf32_phdr *phdr) {if (phdr->p_type !=PT_LOAD )
@@ -84,6 +115,9 @@ ssize_t qcom_mdt_get_size(const struct fphys_addr_t max_addr =0 ;int i; +if (!mdt_header_valid (fw)) +return -EINVAL ; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -136,6 +170,9 @@ void *qcom_mdt_read_metadata(const strucssize_t ret;void *data; +if (!mdt_header_valid (fw)) +return ERR_PTR (-EINVAL ); + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -216,6 +253,9 @@ int qcom_mdt_pas_init(struct device *devint ret;int i; +if (!mdt_header_valid (fw)) +return -EINVAL ; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -304,6 +344,9 @@ static int __qcom_mdt_load(struct deviceif (!fw || !mem_region || !mem_phys || !mem_size)return -EINVAL ; +if (!mdt_header_valid (fw)) +return -EINVAL ; + is_split =qcom_mdt_bins_are_split (fw, fw_name); ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
Greg Kroah-Hartman
maintainerPATCH 433/482 f2fs: fix to call clear_page_private_reference in .{release,invalid}_folio
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 6779b5db90c5b925293f7ccc5ed5336c5b24ed50 ]
b763f3bedc2d ("f2fs: restructure f2fs page.private layout") missed to call clear_page_private_reference() in .{release,invalid}_folio, fix it, though it's not a big deal since folio_detach_private() was called to clear all privae info and reference count in the page.
BTW, remove page_private_reference() definition as it never be used.
Stable-dep-of: 77de19b6867f ("f2fs: fix to avoid out-of-boundary access in dnode page")
--- fs/f2fs/data.c | 2 ++ fs/f2fs/f2fs.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/data.c +2 -0
@@ -3729,6 +3729,7 @@ void f2fs_invalidate_folio(struct folio } } +clear_page_private_reference (&folio->page);clear_page_private_gcing (&folio->page); if (test_opt(sbi, COMPRESS_CACHE) &&
@@ -3754,6 +3755,7 @@ bool f2fs_release_folio(struct folio *foclear_page_private_data (&folio->page); } +clear_page_private_reference (&folio->page);clear_page_private_gcing (&folio->page);folio_detach_private (folio);
fs/f2fs/f2fs.h +0 -1
@@ -1428,7 +1428,6 @@ static inline void clear_page_private_## }PAGE_PRIVATE_GET_FUNC (nonpointer,NOT_POINTER ); -PAGE_PRIVATE_GET_FUNC (reference,REF_RESOURCE );PAGE_PRIVATE_GET_FUNC (inline,INLINE_INODE );PAGE_PRIVATE_GET_FUNC (gcing,ONGOING_MIGRATION );PAGE_PRIVATE_GET_FUNC (atomic,ATOMIC_WRITE );
Greg Kroah-Hartman
maintainerPATCH 434/482 f2fs: fix to avoid out-of-boundary access in dnode page
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 77de19b6867f2740cdcb6c9c7e50d522b47847a4 ]
As Jiaming Zhang reported:
<TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x1c1/0x2a0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x17e/0x800 mm/kasan/report.c:480 kasan_report+0x147/0x180 mm/kasan/report.c:593 data_blkaddr fs/f2fs/f2fs.h:3053 [inline] f2fs_data_blkaddr fs/f2fs/f2fs.h:3058 [inline] f2fs_get_dnode_of_data+0x1a09/0x1c40 fs/f2fs/node.c:855 f2fs_reserve_block+0x53/0x310 fs/f2fs/data.c:1195 prepare_write_begin fs/f2fs/data.c:3395 [inline] f2fs_write_begin+0xf39/0x2190 fs/f2fs/data.c:3594 generic_perform_write+0x2c7/0x910 mm/filemap.c:4112 f2fs_buffered_write_iter fs/f2fs/file.c:4988 [inline] f2fs_file_write_iter+0x1ec8/0x2410 fs/f2fs/file.c:5216 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x546/0xa90 fs/read_write.c:686 ksys_write+0x149/0x250 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf3/0x3d0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
The root cause is in the corrupted image, there is a dnode has the same node id w/ its inode, so during f2fs_get_dnode_of_data(), it tries to access block address in dnode at offset 934, however it parses the dnode as inode node, so that get_dnode_addr() returns 360, then it tries to access page address from 360 + 934 * 4 = 4096 w/ 4 bytes.
To fix this issue, let's add sanity check for node id of all direct nodes during f2fs_get_dnode_of_data().
--- fs/f2fs/node.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/f2fs/node.c +10 -0
@@ -797,6 +797,16 @@ int f2fs_get_dnode_of_data(struct dnode_for (i =1 ; i <= level; i++) {bool done = false; +if (nids[i] && nids[i] == dn->inode->i_ino) { + err = -EFSCORRUPTED ; +f2fs_err (sbi, +"inode mapping table is corrupted, run fsck to fix it, " +"ino:%lu, nid:%u, level:%d, offset:%d" , + dn->inode->i_ino, nids[i], level, offset[level]); +set_sbi_flag (sbi,SBI_NEED_FSCK ); + goto release_pages; + } +if (!nids[i] && mode ==ALLOC_NODE ) {/* alloc new node */ if (!f2fs_alloc_nid (sbi, &(nids[i]))) {