5.11.21-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 288/601 security: keys: trusted: fix TPM2 authorizations
In reply to Greg Kroah-HartmanFrom: James Bottomley <[email protected]>
[ Upstream commit de66514d934d70ce73c302ce0644b54970fc7196 ]
In TPM 1.2 an authorization was a 20 byte number. The spec actually recommended you to hash variable length passwords and use the sha1 hash as the authorization. Because the spec doesn't require this hashing, the current authorization for trusted keys is a 40 digit hex number. For TPM 2.0 the spec allows the passing in of variable length passwords and passphrases directly, so we should allow that in trusted keys for ease of use. Update the 'blobauth' parameter to take this into account, so we can now use plain text passwords for the keys.
so before
keyctl add trusted kmk "new 32 blobauth=f572d396fae9206628714fb2ce00f72e94f2258fkeyhandle=81000001" @u
after we will accept both the old hex sha1 form as well as a new directly supplied password:
keyctl add trusted kmk "new 32 blobauth=hello keyhandle=81000001" @u
Since a sha1 hex code must be exactly 40 bytes long and a direct password must be 20 or less, we use the length as the discriminator for which form is input.
Note this is both and enhancement and a potential bug fix. The TPM 2.0 spec requires us to strip leading zeros, meaning empyty authorization is a zero length HMAC whereas we're currently passing in 20 bytes of zeros. A lot of TPMs simply accept this as OK, but the Microsoft TPM emulator rejects it with TPM_RC_BAD_AUTH, so this patch makes the Microsoft TPM emulator work with trusted keys.
--- include/keys/trusted-type.h | 1 + security/keys/trusted-keys/trusted_tpm1.c | 32 ++++++++++++++++++----- security/keys/trusted-keys/trusted_tpm2.c | 10 ++++--- 3 files changed, 33 insertions(+), 10 deletions(-)
include/keys/trusted-type.h +1 -0
@@ -30,6 +30,7 @@ struct trusted_key_options {uint16_t keytype;uint32_t keyhandle;unsigned char keyauth[TPM_DIGEST_SIZE ]; +uint32_t blobauth_len;unsigned char blobauth[TPM_DIGEST_SIZE ];uint32_t pcrinfo_len;unsigned char pcrinfo[MAX_PCRINFO_SIZE ];
security/keys/trusted-keys/trusted_tpm1.c +26 -6
@@ -791,13 +791,33 @@ static int getoptions(char *c, struct trusted_key_payload *pay,return -EINVAL ;break ;case Opt_blobauth: -if (strlen (args[0 ].from) !=2 *SHA1_DIGEST_SIZE ) -return -EINVAL ; - res =hex2bin (opt->blobauth, args[0 ].from, -SHA1_DIGEST_SIZE ); -if (res <0 ) -return -EINVAL ; +/* +* TPM 1.2 authorizations are sha1 hashes passed in as +* hex strings. TPM 2.0 authorizations are simple +* passwords (although it can take a hash as well) +*/ + opt->blobauth_len =strlen (args[0 ].from); + +if (opt->blobauth_len ==2 *TPM_DIGEST_SIZE ) { + res =hex2bin (opt->blobauth, args[0 ].from, +TPM_DIGEST_SIZE ); +if (res <0 ) +return -EINVAL ; + + opt->blobauth_len =TPM_DIGEST_SIZE ; +break ; + } + +if (tpm2 && opt->blobauth_len <=sizeof (opt->blobauth)) { +memcpy (opt->blobauth, args[0 ].from, + opt->blobauth_len); +break ; + } + +return -EINVAL ; +break ; +case Opt_migratable:if (*args[0 ].from =='0' ) pay->migratable =0 ;
security/keys/trusted-keys/trusted_tpm2.c +6 -4
@@ -97,10 +97,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip, TPM_DIGEST_SIZE);/* sensitive */ -tpm_buf_append_u16 (&buf,4 +TPM_DIGEST_SIZE + payload->key_len +1 ); +tpm_buf_append_u16 (&buf,4 + options->blobauth_len + payload->key_len +1 ); + +tpm_buf_append_u16 (&buf, options->blobauth_len); +if (options->blobauth_len) +tpm_buf_append (&buf, options->blobauth, options->blobauth_len); -tpm_buf_append_u16 (&buf,TPM_DIGEST_SIZE ); -tpm_buf_append (&buf, options->blobauth,TPM_DIGEST_SIZE );tpm_buf_append_u16 (&buf, payload->key_len +1 );tpm_buf_append (&buf, payload->key, payload->key_len);tpm_buf_append_u8 (&buf, payload->migratable);
@@ -265,7 +267,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,NULL /* nonce */ ,0 ,TPM2_SA_CONTINUE_SESSION , options->blobauth/* hmac */ , - TPM_DIGEST_SIZE); + options->blobauth_len); rc =tpm_transmit_cmd (chip, &buf,6 ,"unsealing" );if (rc >0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 289/601 platform/x86: pmc_atom: Match all Beckhoff Automation baytrail boards with critclk_systems DMI table
In reply to Greg Kroah-HartmanFrom: Steffen Dirkwinkel <[email protected]>
[ Upstream commit d21e5abd3a005253eb033090aab2e43bce090d89 ]
pmc_plt_clk* clocks are used for ethernet controllers, so need to stay turned on. This adds the affected board family to critclk_systems DMI table, so the clocks are marked as CLK_CRITICAL and not turned off.
This replaces the previously listed boards with a match for the whole device family CBxx63. CBxx63 matches only baytrail devices. There are new affected boards that would otherwise need to be listed. There are unaffected boards in the family, but having the clocks turned on is not an issue.
--- drivers/platform/x86/pmc_atom.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-)
drivers/platform/x86/pmc_atom.c +2 -26
@@ -393,34 +393,10 @@ static const struct dmi_system_id critclk_systems[] = { }, {/* pmc_plt_clk* - are used for ethernet controllers */ - .ident = "Beckhoff CB3163", + .ident = "Beckhoff Baytrail", .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"Beckhoff Automation" ), - DMI_MATCH(DMI_BOARD_NAME, "CB3163"), - }, - }, - { -/* pmc_plt_clk* - are used for ethernet controllers */ - .ident ="Beckhoff CB4063" , - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"Beckhoff Automation" ), - DMI_MATCH(DMI_BOARD_NAME, "CB4063"), - }, - }, - { -/* pmc_plt_clk* - are used for ethernet controllers */ - .ident ="Beckhoff CB6263" , - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"Beckhoff Automation" ), - DMI_MATCH(DMI_BOARD_NAME, "CB6263"), - }, - }, - { -/* pmc_plt_clk* - are used for ethernet controllers */ - .ident ="Beckhoff CB6363" , - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"Beckhoff Automation" ), - DMI_MATCH(DMI_BOARD_NAME, "CB6363"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "CBxx63"), }, }, {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 290/601 ARM: dts: aspeed: Rainier: Fix humidity sensor bus address
In reply to Greg Kroah-HartmanFrom: Eddie James <[email protected]>
[ Upstream commit 1d5d46a1adafafce2b0c9105eab563709c84e3db ]
The si7021 was incorrectly placed at 0x20 on i2c bus 7. It is at 0x40.
--- arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +2 -2
@@ -712,9 +712,9 @@ multi-master; status = "okay"; - si7021-a20@20 { + si7021-a20@40 { compatible = "silabs,si7020"; - reg = <0x20>; + reg = <0x40>; }; tmp275@48 {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 291/601 Drivers: hv: vmbus: Use after free in __vmbus_open()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 3e9bf43f7f7a46f21ec071cb47be92d0874c48da ]
The "open_info" variable is added to the &vmbus_connection.chn_msg_list, but the error handling frees "open_info" without removing it from the list. This will result in a use after free. First remove it from the list, and then free it.
--- drivers/hv/channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hv/channel.c +1 -1
@@ -653,7 +653,7 @@ static int __vmbus_open(struct vmbus_channel *newchannel,if (newchannel->rescind) { err = -ENODEV ; - goto error_free_info; + goto error_clean_msglist; } err = vmbus_post_msg(open_msg,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 292/601 spi: spi-zynqmp-gqspi: fix clk_enable/disable imbalance issue
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit c6bdae08012b2ca3e94f3a41ef4ca8cfe7c9ab6f ]
The clks "pclk" and "ref_clk" are enabled twice during the probe. The first time is in the function zynqmp_qspi_probe and the second time is in zynqmp_qspi_setup_op which is called by devm_spi_register_controller. Then calling zynqmp_qspi_remove (rmmod this module) to disable these clks will trigger a warning as below:
[ 309.124604] Unpreparing enabled qspi_ref [ 309.128641] WARNING: CPU: 1 PID: 537 at drivers/clk/clk.c:824 clk_core_unprepare+0x108/0x110
Since pm_runtime works now, clks can be enabled/disabled by calling zynqmp_runtime_suspend/resume. So we don't need to enable these clks explicitly in zynqmp_qspi_setup_op. Remove them to fix this issue.
And remove clk enabling/disabling in zynqmp_qspi_resume because there is no spi transfer operation so enabling ref_clk is redundant meanwhile pclk is not disabled for it is shared with other peripherals.
Furthermore replace clk_enable/disable with clk_prepare_enable and clk_disable_unprepare in runtime_suspend/resume functions.
--- drivers/spi/spi-zynqmp-gqspi.c | 47 ++++++---------------------------- 1 file changed, 8 insertions(+), 39 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +8 -39
@@ -487,24 +487,10 @@ static int zynqmp_qspi_setup_op(struct spi_device *qspi) {struct spi_controller *ctlr = qspi->master;struct zynqmp_qspi *xqspi =spi_controller_get_devdata (ctlr); -struct device *dev = &ctlr->dev; -int ret;if (ctlr->busy)return -EBUSY ; - ret =clk_enable (xqspi->refclk); -if (ret) { -dev_err (dev,"Cannot enable device clock.\n" ); -return ret; - } - - ret =clk_enable (xqspi->pclk); -if (ret) { -dev_err (dev,"Cannot enable APB clock.\n" ); -clk_disable (xqspi->refclk); -return ret; - }zynqmp_gqspi_write (xqspi,GQSPI_EN_OFST ,GQSPI_EN_MASK );return 0 ;
@@ -863,26 +849,9 @@ static int __maybe_unused zynqmp_qspi_suspend(struct device *dev)static int __maybe_unused zynqmp_qspi_resume (struct device *dev) {struct spi_controller *ctlr =dev_get_drvdata (dev); -struct zynqmp_qspi *xqspi =spi_controller_get_devdata (ctlr); -int ret =0 ; - - ret =clk_enable (xqspi->pclk); -if (ret) { -dev_err (dev,"Cannot enable APB clock.\n" ); -return ret; - } - - ret =clk_enable (xqspi->refclk); -if (ret) { -dev_err (dev,"Cannot enable device clock.\n" ); -clk_disable (xqspi->pclk); -return ret; - }spi_controller_resume (ctlr); -clk_disable (xqspi->refclk); -clk_disable (xqspi->pclk);return 0 ; }
@@ -898,8 +867,8 @@ static int __maybe_unused zynqmp_runtime_suspend(struct device *dev) {struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_get_drvdata (dev); -clk_disable (xqspi->refclk); -clk_disable (xqspi->pclk); +clk_disable_unprepare (xqspi->refclk); +clk_disable_unprepare (xqspi->pclk);return 0 ; }
@@ -917,16 +886,16 @@ static int __maybe_unused zynqmp_runtime_resume(struct device *dev)struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_get_drvdata (dev);int ret; - ret =clk_enable (xqspi->pclk); + ret =clk_prepare_enable (xqspi->pclk);if (ret) {dev_err (dev,"Cannot enable APB clock.\n" );return ret; } - ret =clk_enable (xqspi->refclk); + ret =clk_prepare_enable (xqspi->refclk);if (ret) {dev_err (dev,"Cannot enable device clock.\n" ); -clk_disable (xqspi->pclk); +clk_disable_unprepare (xqspi->pclk);return ret; }
@@ -1136,13 +1105,11 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) goto remove_master; } -init_completion (&xqspi->data_completion); - xqspi->refclk =devm_clk_get (&pdev->dev,"ref_clk" );if (IS_ERR (xqspi->refclk)) {dev_err (dev,"ref_clk clock not found.\n" ); ret =PTR_ERR (xqspi->refclk); - goto clk_dis_pclk; + goto remove_master; } ret =clk_prepare_enable (xqspi->pclk);
@@ -1157,6 +1124,8 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) goto clk_dis_pclk; } +init_completion (&xqspi->data_completion); +mutex_init (&xqspi->op_lock);pm_runtime_use_autosuspend (&pdev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 293/601 spi: spi-zynqmp-gqspi: fix hang issue when suspend/resume
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 799f923f0a66a9c99f0a3eaa078b306db7a8b33a ]
After calling platform_set_drvdata(pdev, xqspi) in probe, the return value of dev_get_drvdata(dev) is a pointer to struct zynqmp_qspi but not struct spi_controller. A wrong structure type passing to the functions spi_controller_suspend/resume will hang the system.
And we should check the return value of spi_controller_suspend, if an error is returned, return it to PM subsystem to stop suspend.
Also, GQSPI_EN_MASK should be written to GQSPI_EN_OFST to enable the spi controller in zynqmp_qspi_resume since it was disabled in zynqmp_qspi_suspend before.
--- drivers/spi/spi-zynqmp-gqspi.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +14 -6
@@ -157,6 +157,7 @@ enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA};* @data_completion: completion structure */ struct zynqmp_qspi { +struct spi_controller *ctlr;void __iomem *regs;struct clk *refclk;struct clk *pclk;
@@ -827,10 +828,13 @@ static void zynqmp_qspi_read_op(struct zynqmp_qspi *xqspi, u8 rx_nbits,*/ static int __maybe_unused zynqmp_qspi_suspend (struct device *dev) { -struct spi_controller *ctlr =dev_get_drvdata (dev); -struct zynqmp_qspi *xqspi =spi_controller_get_devdata (ctlr); +struct zynqmp_qspi *xqspi =dev_get_drvdata (dev); +struct spi_controller *ctlr = xqspi->ctlr; +int ret; -spi_controller_suspend (ctlr); + ret =spi_controller_suspend (ctlr); +if (ret) +return ret;zynqmp_gqspi_write (xqspi,GQSPI_EN_OFST ,0x0 );
@@ -848,7 +852,10 @@ static int __maybe_unused zynqmp_qspi_suspend(struct device *dev)*/ static int __maybe_unused zynqmp_qspi_resume (struct device *dev) { -struct spi_controller *ctlr =dev_get_drvdata (dev); +struct zynqmp_qspi *xqspi =dev_get_drvdata (dev); +struct spi_controller *ctlr = xqspi->ctlr; + +zynqmp_gqspi_write (xqspi,GQSPI_EN_OFST ,GQSPI_EN_MASK );spi_controller_resume (ctlr);
@@ -865,7 +872,7 @@ static int __maybe_unused zynqmp_qspi_resume(struct device *dev)*/ static int __maybe_unused zynqmp_runtime_suspend (struct device *dev) { -struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_get_drvdata (dev); +struct zynqmp_qspi *xqspi =dev_get_drvdata (dev);clk_disable_unprepare (xqspi->refclk);clk_disable_unprepare (xqspi->pclk);
@@ -883,7 +890,7 @@ static int __maybe_unused zynqmp_runtime_suspend(struct device *dev)*/ static int __maybe_unused zynqmp_runtime_resume (struct device *dev) { -struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_get_drvdata (dev); +struct zynqmp_qspi *xqspi =dev_get_drvdata (dev);int ret; ret =clk_prepare_enable (xqspi->pclk);
@@ -1090,6 +1097,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) xqspi =spi_controller_get_devdata (ctlr); xqspi->dev = dev; + xqspi->ctlr = ctlr;platform_set_drvdata (pdev, xqspi); xqspi->regs =devm_platform_ioremap_resource (pdev,0 );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 294/601 spi: spi-zynqmp-gqspi: fix use-after-free in zynqmp_qspi_exec_op
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit a2c5bedb2d55dd27c642c7b9fb6886d7ad7bdb58 ]
When handling op->addr, it is using the buffer "tmpbuf" which has been freed. This will trigger a use-after-free KASAN warning. Let's use temporary variables to store op->addr.val and op->cmd.opcode to fix this issue.
--- drivers/spi/spi-zynqmp-gqspi.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +4 -10
@@ -926,8 +926,9 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,struct zynqmp_qspi *xqspi =spi_controller_get_devdata (mem->spi->master);int err =0 , i; -u8 *tmpbuf;u32 genfifoentry =0 ; +u16 opcode = op->cmd.opcode; +u64 opaddr; dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n", op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
@@ -940,14 +941,8 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem, genfifoentry |= xqspi->genfifobus;if (op->cmd.opcode) { - tmpbuf =kzalloc (op->cmd.nbytes,GFP_KERNEL |GFP_DMA ); -if (!tmpbuf) { -mutex_unlock (&xqspi->op_lock); -return -ENOMEM ; - } - tmpbuf[0 ] = op->cmd.opcode;reinit_completion (&xqspi->data_completion); - xqspi->txbuf = tmpbuf; + xqspi->txbuf = &opcode; xqspi->rxbuf =NULL ; xqspi->bytes_to_transfer = op->cmd.nbytes; xqspi->bytes_to_receive =0 ;
@@ -961,13 +956,12 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,if (!wait_for_completion_timeout (&xqspi->data_completion,msecs_to_jiffies (1000 ))) { err = -ETIMEDOUT ; -kfree (tmpbuf); goto return_err; } -kfree (tmpbuf); }if (op->addr.nbytes) { + xqspi->txbuf = &opaddr;for (i =0 ; i < op->addr.nbytes; i++) { *(((u8 *)xqspi->txbuf) + i) = op->addr.val >> (8 * (op->addr.nbytes - i -1 ));
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 295/601 spi: spi-zynqmp-gqspi: return -ENOMEM if dma_map_single fails
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 126bdb606fd2802454e6048caef1be3e25dd121e ]
The spi controller supports 44-bit address space on AXI in DMA mode, so set dma_addr_t width to 44-bit to avoid using a swiotlb mapping. In addition, if dma_map_single fails, it should return immediately instead of continuing doing the DMA operation which bases on invalid address.
This fixes the following crash which occurs in reading a big block from flash:
[ 123.633577] zynqmp-qspi ff0f0000.spi: swiotlb buffer is full (sz: 4194304 bytes), total 32768 (slots), used 0 (slots) [ 123.644230] zynqmp-qspi ff0f0000.spi: ERR:rxdma:memory not mapped [ 123.784625] Unable to handle kernel paging request at virtual address 00000000003fffc0 [ 123.792536] Mem abort info: [ 123.795313] ESR = 0x96000145 [ 123.798351] EC = 0x25: DABT (current EL), IL = 32 bits [ 123.803655] SET = 0, FnV = 0 [ 123.806693] EA = 0, S1PTW = 0 [ 123.809818] Data abort info: [ 123.812683] ISV = 0, ISS = 0x00000145 [ 123.816503] CM = 1, WnR = 1 [ 123.819455] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000805047000 [ 123.825887] [00000000003fffc0] pgd=0000000803b45003, p4d=0000000803b45003, pud=0000000000000000 [ 123.834586] Internal error: Oops: 96000145 [#1] PREEMPT SMP
--- drivers/spi/spi-zynqmp-gqspi.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +20 -6
@@ -731,7 +731,7 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id)* zynqmp_qspi_setuprxdma - This function sets up the RX DMA operation * @xqspi: xqspi is a pointer to the GQSPI instance. */ -static void zynqmp_qspi_setuprxdma (struct zynqmp_qspi *xqspi) +static int zynqmp_qspi_setuprxdma (struct zynqmp_qspi *xqspi) {u32 rx_bytes, rx_rem, config_reg;dma_addr_t addr;
@@ -745,7 +745,7 @@ static void zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi)zynqmp_gqspi_write (xqspi,GQSPI_CONFIG_OFST , config_reg); xqspi->mode =GQSPI_MODE_IO ; xqspi->dma_rx_bytes =0 ; -return ; +return 0 ; } rx_rem = xqspi->bytes_to_receive %4 ;
@@ -753,8 +753,10 @@ static void zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi) addr =dma_map_single (xqspi->dev, (void *)xqspi->rxbuf, rx_bytes,DMA_FROM_DEVICE ); -if (dma_mapping_error (xqspi->dev, addr)) +if (dma_mapping_error (xqspi->dev, addr)) {dev_err (xqspi->dev,"ERR:rxdma:memory not mapped\n" ); +return -ENOMEM ; + } xqspi->dma_rx_bytes = rx_bytes; xqspi->dma_addr = addr;
@@ -775,6 +777,8 @@ static void zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi)/* Write the number of bytes to transfer */ zynqmp_gqspi_write (xqspi,GQSPI_QSPIDMA_DST_SIZE_OFST , rx_bytes); + +return 0 ; }/**
@@ -811,11 +815,17 @@ static void zynqmp_qspi_write_op(struct zynqmp_qspi *xqspi, u8 tx_nbits,* @genfifoentry: genfifoentry is pointer to the variable in which * GENFIFO mask is returned to calling function */ -static void zynqmp_qspi_read_op (struct zynqmp_qspi *xqspi,u8 rx_nbits, +static int zynqmp_qspi_read_op (struct zynqmp_qspi *xqspi,u8 rx_nbits,u32 genfifoentry) { -zynqmp_qspi_setuprxdma (xqspi); +int ret; + + ret =zynqmp_qspi_setuprxdma (xqspi); +if (ret) +return ret;zynqmp_qspi_fillgenfifo (xqspi, rx_nbits, genfifoentry); + +return 0 ; }/**
@@ -1029,8 +1039,11 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem, xqspi->rxbuf = (u8 *)op->data.buf.in; xqspi->bytes_to_receive = op->data.nbytes; xqspi->bytes_to_transfer =0 ; -zynqmp_qspi_read_op (xqspi, op->data.buswidth, + err =zynqmp_qspi_read_op (xqspi, op->data.buswidth, genfifoentry); +if (err) + goto return_err; + zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, zynqmp_gqspi_read (xqspi, GQSPI_CONFIG_OFST) |
@@ -1152,6 +1165,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) goto clk_dis_all; } +dma_set_mask (&pdev->dev,DMA_BIT_MASK (44 )); ctlr->bits_per_word_mask =SPI_BPW_MASK (8 ); ctlr->num_chipselect =GQSPI_DEFAULT_NUM_CS ; ctlr->mem_ops = &zynqmp_qspi_mem_ops;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 296/601 x86/platform/uv: Fix !KEXEC build failure
In reply to Greg Kroah-HartmanFrom: Ingo Molnar <[email protected]>
[ Upstream commit c2209ea55612efac75de0a58ef5f7394fae7fa0f ]
When KEXEC is disabled, the UV build fails:
arch/x86/platform/uv/uv_nmi.c:875:14: error: ‘uv_nmi_kexec_failed’ undeclared (first use in this function)
Since uv_nmi_kexec_failed is only defined in the KEXEC_CORE #ifdef branch, this code cannot ever have been build tested:
if (main)
pr_err("UV: NMI kdump: KEXEC not supported in this kernel\n");
atomic_set(&uv_nmi_kexec_failed, 1);Nor is this use possible in uv_handle_nmi():
atomic_set(&uv_nmi_kexec_failed, 0);
These bugs were introduced in this commit:
d0a9964e9873: ("x86/platform/uv: Implement simple dump failover if kdump fails")
Which added the uv_nmi_kexec_failed assignments to !KEXEC code, while making the definition KEXEC-only - apparently without testing the !KEXEC case.
Instead of complicating the #ifdef maze, simplify the code by requiring X86_UV to depend on KEXEC_CORE. This pattern is present in other architectures as well.
( We'll remove the untested, 7 years old !KEXEC complications from the file in a
separate commit. )
--- arch/x86/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/x86/Kconfig +1 -0
@@ -564,6 +564,7 @@ config X86_UV depends on X86_EXTENDED_PLATFORM depends on NUMA depends on EFI + depends on KEXEC_CORE depends on X86_X2APIC depends on PCI help
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 297/601 hwmon: (pmbus/pxe1610) dont bail out when not all pages are active
In reply to Greg Kroah-HartmanFrom: Paul Fertser <[email protected]>
[ Upstream commit f025314306ae17a3fdaf2874d7e878ce19cea363 ]
Certain VRs might be configured to use only the first output channel and so the mode for the second will be 0. Handle this gracefully.
--- drivers/hwmon/pmbus/pxe1610.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/hwmon/pmbus/pxe1610.c +9 -0
@@ -41,6 +41,15 @@ static int pxe1610_identify(struct i2c_client *client, info->vrm_version[i] = vr13;break ;default : +/* +* If prior pages are available limit operation +* to them +*/ +if (i !=0 ) { + info->pages = i; +return 0 ; + } +return -ENODEV ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 298/601 Drivers: hv: vmbus: Increase wait time for VMbus unload
In reply to Greg Kroah-HartmanFrom: Michael Kelley <[email protected]>
[ Upstream commit 77db0ec8b7764cb9b09b78066ebfd47b2c0c1909 ]
When running in Azure, disks may be connected to a Linux VM with read/write caching enabled. If a VM panics and issues a VMbus UNLOAD request to Hyper-V, the response is delayed until all dirty data in the disk cache is flushed. In extreme cases, this flushing can take 10's of seconds, depending on the disk speed and the amount of dirty data. If kdump is configured for the VM, the current 10 second timeout in vmbus_wait_for_unload() may be exceeded, and the UNLOAD complete message may arrive well after the kdump kernel is already running, causing problems. Note that no problem occurs if kdump is not enabled because Hyper-V waits for the cache flush before doing a reboot through the BIOS/UEFI code.
Fix this problem by increasing the timeout in vmbus_wait_for_unload() to 100 seconds. Also output periodic messages so that if anyone is watching the serial console, they won't think the VM is completely hung.
--- drivers/hv/channel_mgmt.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-)
drivers/hv/channel_mgmt.c +25 -5
@@ -725,6 +725,12 @@ static void init_vp_index(struct vmbus_channel *channel)free_cpumask_var (available_mask); } +#define UNLOAD_DELAY_UNIT_MS 10/* 10 milliseconds */ +#define UNLOAD_WAIT_MS (100*1000)/* 100 seconds */ +#define UNLOAD_WAIT_LOOPS (UNLOAD_WAIT_MS/UNLOAD_DELAY_UNIT_MS) +#define UNLOAD_MSG_MS (5*1000)/* Every 5 seconds */ +#define UNLOAD_MSG_LOOPS (UNLOAD_MSG_MS/UNLOAD_DELAY_UNIT_MS) +static void vmbus_wait_for_unload (void ) {int cpu;
@@ -742,12 +748,17 @@ static void vmbus_wait_for_unload(void)* vmbus_connection.unload_event. If not, the last thing we can do is * read message pages for all CPUs directly. * -* Wait no more than 10 seconds so that the panic path can't get -* hung forever in case the response message isn't seen. +* Wait up to 100 seconds since an Azure host must writeback any dirty +* data in its disk cache before the VMbus UNLOAD request will +* complete. This flushing has been empirically observed to take up +* to 50 seconds in cases with a lot of dirty data, so allow additional +* leeway and for inaccuracies in mdelay(). But eventually time out so +* that the panic path can't get hung forever in case the response +* message isn't seen. */ -for (i =0 ; i <1000 ; i++) { +for (i =1 ; i <=UNLOAD_WAIT_LOOPS ; i++) {if (completion_done (&vmbus_connection.unload_event)) -break ; + goto completed;for_each_online_cpu (cpu) {struct hv_per_cpu_context *hv_cpu
@@ -770,9 +781,18 @@ static void vmbus_wait_for_unload(void)vmbus_signal_eom (msg, message_type); } -mdelay (10 ); +/* +* Give a notice periodically so someone watching the +* serial output won't think it is completely hung. +*/ +if (!(i %UNLOAD_MSG_LOOPS )) +pr_notice ("Waiting for VMBus UNLOAD to complete\n" ); + +mdelay (UNLOAD_DELAY_UNIT_MS ); } +pr_err ("Continuing even though VMBus UNLOAD did not complete\n" ); +completed:/* * We're crashing and already got the UNLOAD_RESPONSE, cleanup all * maybe-pending messages on all CPUs to be able to receive new
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 299/601 PM: hibernate: x86: Use crc32 instead of md5 for hibernation e820 integrity check
In reply to Greg Kroah-HartmanFrom: Chris von Recklinghausen <[email protected]>
[ Upstream commit f5d1499ae2096d7ea301023c4cc54e427300eb0a ]
Hibernation fails on a system in fips mode because md5 is used for the e820 integrity check and is not available. Use crc32 instead.
The check is intended to detect whether the E820 memory map provided by the firmware after cold boot unexpectedly differs from the one that was in use when the hibernation image was created. In this case, the hibernation image cannot be restored, as it may cover memory regions that are no longer available to the OS.
A non-cryptographic checksum such as CRC-32 is sufficient to detect such inadvertent deviations.
--- arch/x86/kernel/e820.c | 4 +- arch/x86/power/hibernate.c | 89 ++++++-------------------------------- 2 files changed, 16 insertions(+), 77 deletions(-)
arch/x86/kernel/e820.c +2 -2
@@ -31,8 +31,8 @@* - inform the user about the firmware's notion of memory layout * via /sys/firmware/memmap * -* - the hibernation code uses it to generate a kernel-independent MD5 -* fingerprint of the physical memory layout of a system. +* - the hibernation code uses it to generate a kernel-independent CRC32 +* checksum of the physical memory layout of a system. * * - 'e820_table_kexec': a slightly modified (by the kernel) firmware version * passed to us by the bootloader - the major difference between
arch/x86/power/hibernate.c +14 -75
131 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 300/601 usb: dwc2: Fix host mode hibernation exit with remote wakeup flow.
In reply to Greg Kroah-HartmanFrom: Artur Petrosyan <[email protected]>
[ Upstream commit c2db8d7b9568b10e014af83b3c15e39929e3579e ]
Added setting "port_connect_status_change" flag to "1" in order to re-enumerate, because after exit from hibernation port connection status is not detected.
--- drivers/usb/dwc2/hcd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/usb/dwc2/hcd.c +9 -1
@@ -5580,7 +5580,15 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,return ret; } -dwc2_hcd_rem_wakeup (hsotg); +if (rem_wakeup) { +dwc2_hcd_rem_wakeup (hsotg); +/* +* Change "port_connect_status_change" flag to re-enumerate, +* because after exit from hibernation port connection status +* is not detected. +*/ + hsotg->flags.b.port_connect_status_change =1 ; + } hsotg->hibernated =0 ; hsotg->bus_suspended =0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 301/601 usb: dwc2: Fix hibernation between host and device modes.
In reply to Greg Kroah-HartmanFrom: Artur Petrosyan <[email protected]>
[ Upstream commit 24d209dba5a3959b2ebde7cf3ad40c8015e814cf ]
When core is in hibernation in host mode and a device cable was connected then driver exited from device hibernation. However, registers saved for host mode and when exited from device hibernation register restore would be done for device register which was wrong because there was no device registers stored to restore.
- Added dwc_handle_gpwrdn_disc_det() function which handles gpwrdn disconnect detect flow and exits hibernation without restoring the registers.
- Updated exiting from hibernation in GPWRDN_STS_CHGINT with calling dwc_handle_gpwrdn_disc_det() function. Here no register is restored which is the solution described above.
--- drivers/usb/dwc2/core_intr.c | 154 +++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 71 deletions(-)
drivers/usb/dwc2/core_intr.c +83 -71
@@ -660,6 +660,71 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)return 0 ; } +/** +* dwc_handle_gpwrdn_disc_det() - Handles the gpwrdn disconnect detect. +* Exits hibernation without restoring registers. +* +* @hsotg: Programming view of DWC_otg controller +* @gpwrdn: GPWRDN register +*/ +static inline void dwc_handle_gpwrdn_disc_det (struct dwc2_hsotg *hsotg, +u32 gpwrdn) +{ +u32 gpwrdn_tmp; + +/* Switch-on voltage to the core */ + gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); + gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH ; +dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); +udelay (5 ); + +/* Reset core */ + gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); + gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN ; +dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); +udelay (5 ); + +/* Disable Power Down Clamp */ + gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); + gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP ; +dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); +udelay (5 ); + +/* Deassert reset core */ + gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); + gpwrdn_tmp |=GPWRDN_PWRDNRSTN ; +dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); +udelay (5 ); + +/* Disable PMU interrupt */ + gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); + gpwrdn_tmp &= ~GPWRDN_PMUINTSEL ; +dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); + +/* De-assert Wakeup Logic */ + gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); + gpwrdn_tmp &= ~GPWRDN_PMUACTV ; +dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); + + hsotg->hibernated =0 ; + hsotg->bus_suspended =0 ; + +if (gpwrdn &GPWRDN_IDSTS ) { + hsotg->op_state =OTG_STATE_B_PERIPHERAL ; +dwc2_core_init (hsotg, false); +dwc2_enable_global_interrupts (hsotg); +dwc2_hsotg_core_init_disconnected (hsotg, false); +dwc2_hsotg_core_connect (hsotg); + }else { + hsotg->op_state =OTG_STATE_A_HOST ; + +/* Initialize the Core for Host mode */ +dwc2_core_init (hsotg, false); +dwc2_enable_global_interrupts (hsotg); +dwc2_hcd_start (hsotg); + } +} +/* * GPWRDN interrupt handler. *
@@ -681,64 +746,14 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)if ((gpwrdn &GPWRDN_DISCONN_DET ) && (gpwrdn &GPWRDN_DISCONN_DET_MSK ) && !linestate) { -u32 gpwrdn_tmp; -dev_dbg (hsotg->dev,"%s: GPWRDN_DISCONN_DET\n" , __func__); - -/* Switch-on voltage to the core */ - gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); - gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH ; -dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); -udelay (10 ); - -/* Reset core */ - gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); - gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN ; -dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); -udelay (10 ); - -/* Disable Power Down Clamp */ - gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); - gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP ; -dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); -udelay (10 ); - -/* Deassert reset core */ - gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); - gpwrdn_tmp |=GPWRDN_PWRDNRSTN ; -dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); -udelay (10 ); - -/* Disable PMU interrupt */ - gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); - gpwrdn_tmp &= ~GPWRDN_PMUINTSEL ; -dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); - -/* De-assert Wakeup Logic */ - gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); - gpwrdn_tmp &= ~GPWRDN_PMUACTV ; -dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); - - hsotg->hibernated =0 ; - -if (gpwrdn &GPWRDN_IDSTS ) { - hsotg->op_state =OTG_STATE_B_PERIPHERAL ; -dwc2_core_init (hsotg, false); -dwc2_enable_global_interrupts (hsotg); -dwc2_hsotg_core_init_disconnected (hsotg, false); -dwc2_hsotg_core_connect (hsotg); - }else { - hsotg->op_state =OTG_STATE_A_HOST ; - -/* Initialize the Core for Host mode */ -dwc2_core_init (hsotg, false); -dwc2_enable_global_interrupts (hsotg); -dwc2_hcd_start (hsotg); - } - } - -if ((gpwrdn &GPWRDN_LNSTSCHG ) && - (gpwrdn &GPWRDN_LNSTSCHG_MSK ) && linestate) { +/* +* Call disconnect detect function to exit from +* hibernation +*/ +dwc_handle_gpwrdn_disc_det (hsotg, gpwrdn); + }else if ((gpwrdn &GPWRDN_LNSTSCHG ) && + (gpwrdn &GPWRDN_LNSTSCHG_MSK ) && linestate) {dev_dbg (hsotg->dev,"%s: GPWRDN_LNSTSCHG\n" , __func__);if (hsotg->hw_params.hibernation && hsotg->hibernated) {
@@ -749,24 +764,21 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)dwc2_exit_hibernation (hsotg,1 ,0 ,1 ); } } - } -if ((gpwrdn &GPWRDN_RST_DET ) && (gpwrdn &GPWRDN_RST_DET_MSK )) { + }else if ((gpwrdn &GPWRDN_RST_DET ) && + (gpwrdn &GPWRDN_RST_DET_MSK )) {dev_dbg (hsotg->dev,"%s: GPWRDN_RST_DET\n" , __func__);if (!linestate && (gpwrdn &GPWRDN_BSESSVLD ))dwc2_exit_hibernation (hsotg,0 ,1 ,0 ); - } -if ((gpwrdn &GPWRDN_STS_CHGINT ) && - (gpwrdn &GPWRDN_STS_CHGINT_MSK ) && linestate) { + }else if ((gpwrdn &GPWRDN_STS_CHGINT ) && + (gpwrdn &GPWRDN_STS_CHGINT_MSK )) {dev_dbg (hsotg->dev,"%s: GPWRDN_STS_CHGINT\n" , __func__); -if (hsotg->hw_params.hibernation && - hsotg->hibernated) { -if (gpwrdn &GPWRDN_IDSTS ) { -dwc2_exit_hibernation (hsotg,0 ,0 ,0 ); -call_gadget (hsotg, resume); - }else { -dwc2_exit_hibernation (hsotg,1 ,0 ,1 ); - } - } +/* +* As GPWRDN_STS_CHGINT exit from hibernation flow is +* the same as in GPWRDN_DISCONN_DET flow. Call +* disconnect detect helper function to exit from +* hibernation. +*/ +dwc_handle_gpwrdn_disc_det (hsotg, gpwrdn); } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 302/601 ttyprintk: Add TTY hangup callback.
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit c0070e1e60270f6a1e09442a9ab2335f3eaeaad2 ]
syzbot is reporting hung task due to flood of
tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__,
port->count);
message [1], for ioctl(TIOCVHANGUP) prevents tty_port_close() from decrementing port->count due to tty_hung_up_p() == true.
----------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i;
int fd[10];
for (i = 0; i < 10; i++)
fd[i] = open("/dev/ttyprintk", O_WRONLY);
ioctl(fd[0], TIOCVHANGUP);
for (i = 0; i < 10; i++)
close(fd[i]);
close(open("/dev/ttyprintk", O_WRONLY));
return 0;
}----------
When TTY hangup happens, port->count needs to be reset via "struct tty_operations"->hangup callback.
[1] https://syzkaller.appspot.com/bug?id=39ea6caa479af471183997376dc7e90bc7d64a6a
--- drivers/char/ttyprintk.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/char/ttyprintk.c +11 -0
@@ -158,12 +158,23 @@ static int tpk_ioctl(struct tty_struct *tty,return 0 ; } +/* +* TTY operations hangup function. +*/ +static void tpk_hangup (struct tty_struct *tty) +{ +struct ttyprintk_port *tpkp = tty->driver_data; + +tty_port_hangup (&tpkp->port); +} +static const struct tty_operations ttyprintk_ops = { .open = tpk_open, .close = tpk_close, .write = tpk_write, .write_room = tpk_write_room, .ioctl = tpk_ioctl, + .hangup = tpk_hangup, };static const struct tty_port_operations null_ops = { };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 303/601 serial: omap: dont disable rs485 if rts gpio is missing
In reply to Greg Kroah-HartmanFrom: Dario Binacchi <[email protected]>
[ Upstream commit 45f6b6db53c80787b79044629b062dfcf2da71ec ]
There are rs485 transceivers (e.g. MAX13487E/MAX13488E) which automatically disable or enable the driver and receiver to keep the bus in the correct state.
In these cases we don't need a GPIO for flow control.
--- drivers/tty/serial/omap-serial.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/tty/serial/omap-serial.c +4 -8
@@ -302,7 +302,8 @@ static void serial_omap_stop_tx(struct uart_port *port)serial_out (up,UART_OMAP_SCR , up->scr); res = (port->rs485.flags &SER_RS485_RTS_AFTER_SEND ) ?1 :0 ; -if (gpiod_get_value (up->rts_gpiod) != res) { +if (up->rts_gpiod && +gpiod_get_value (up->rts_gpiod) != res) {if (port->rs485.delay_rts_after_send >0 )mdelay ( port->rs485.delay_rts_after_send);
@@ -411,7 +412,7 @@ static void serial_omap_start_tx(struct uart_port *port)/* if rts not already enabled */ res = (port->rs485.flags &SER_RS485_RTS_ON_SEND ) ?1 :0 ; -if (gpiod_get_value (up->rts_gpiod) != res) { +if (up->rts_gpiod &&gpiod_get_value (up->rts_gpiod) != res) {gpiod_set_value (up->rts_gpiod, res);if (port->rs485.delay_rts_before_send >0 )mdelay (port->rs485.delay_rts_before_send);
@@ -1407,18 +1408,13 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)/* store new config */ port->rs485 = *rs485; -/* -* Just as a precaution, only allow rs485 -* to be enabled if the gpio pin is valid -*/ if (up->rts_gpiod) {/* enable / disable rts */ val = (port->rs485.flags &SER_RS485_ENABLED ) ?SER_RS485_RTS_AFTER_SEND :SER_RS485_RTS_ON_SEND ; val = (port->rs485.flags & val) ?1 :0 ;gpiod_set_value (up->rts_gpiod, val); - }else - port->rs485.flags &= ~SER_RS485_ENABLED ; + }/* Enable interrupts */ up->ier = mode;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 304/601 serial: omap: fix rs485 half-duplex filtering
In reply to Greg Kroah-HartmanFrom: Dario Binacchi <[email protected]>
[ Upstream commit e2a5e8448e7393e96ccde346c68764b40a52cc10 ]
Data received during half-duplex transmission must be filtered. If the target device responds quickly, emptying the FIFO at the end of the transmission can erase not only the echo characters but also part of the response message.
By keeping the receive interrupt enabled even during transmission, it allows you to filter each echo character and only in a number equal to those transmitted.
The issue was generated by a target device that started responding 240us later having received a request in communication at 115200bps. Sometimes, some messages received by the target were missing some of the first bytes.
--- drivers/tty/serial/omap-serial.c | 39 ++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-)
drivers/tty/serial/omap-serial.c +24 -15
@@ -159,6 +159,8 @@ struct uart_omap_port {u32 calc_latency;struct work_struct qos_work;bool is_suspending; + +unsigned int rs485_tx_filter_count; };#define to_uart_omap_port (p) ((container_of((p), struct uart_omap_port, port)))
@@ -329,19 +331,6 @@ static void serial_omap_stop_tx(struct uart_port *port)serial_out (up,UART_IER , up->ier); } -if ((port->rs485.flags &SER_RS485_ENABLED ) && - !(port->rs485.flags &SER_RS485_RX_DURING_TX )) { -/* -* Empty the RX FIFO, we are not interested in anything -* received during the half-duplex transmission. -*/ -serial_out (up,UART_FCR , up->fcr |UART_FCR_CLEAR_RCVR ); -/* Re-enable RX interrupts */ - up->ier |=UART_IER_RLSI |UART_IER_RDI ; - up->port.read_status_mask |=UART_LSR_DR ; -serial_out (up,UART_IER , up->ier); - } -pm_runtime_mark_last_busy (up->dev);pm_runtime_put_autosuspend (up->dev); }
@@ -367,6 +356,10 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr)serial_out (up,UART_TX , up->port.x_char); up->port.icount.tx++; up->port.x_char =0 ; +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX )) + up->rs485_tx_filter_count++; +return ; }if (uart_circ_empty (xmit) ||uart_tx_stopped (&up->port)) {
@@ -378,6 +371,10 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr)serial_out (up,UART_TX , xmit->buf[xmit->tail]); xmit->tail = (xmit->tail +1 ) & (UART_XMIT_SIZE -1 ); up->port.icount.tx++; +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX )) + up->rs485_tx_filter_count++; +if (uart_circ_empty (xmit))break ; }while (--count >0 );
@@ -421,7 +418,7 @@ static void serial_omap_start_tx(struct uart_port *port)if ((port->rs485.flags &SER_RS485_ENABLED ) && !(port->rs485.flags &SER_RS485_RX_DURING_TX )) -serial_omap_stop_rx (port); + up->rs485_tx_filter_count =0 ;serial_omap_enable_ier_thri (up);pm_runtime_mark_last_busy (up->dev);
@@ -492,8 +489,13 @@ static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr)* Read one data character out to avoid stalling the receiver according * to the table 23-246 of the omap4 TRM. */ -if (likely (lsr &UART_LSR_DR )) +if (likely (lsr &UART_LSR_DR )) {serial_in (up,UART_RX ); +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX ) && + up->rs485_tx_filter_count) + up->rs485_tx_filter_count--; + } up->port.icount.rx++; flag =TTY_NORMAL ;
@@ -544,6 +546,13 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr)return ; ch =serial_in (up,UART_RX ); +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX ) && + up->rs485_tx_filter_count) { + up->rs485_tx_filter_count--; +return ; + } + flag =TTY_NORMAL ; up->port.icount.rx++;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 305/601 xen-blkback: fix compatibility bug with single page rings
In reply to Greg Kroah-HartmanFrom: Paul Durrant <[email protected]>
[ Upstream commit d75e7f63b7c95c527cde42efb5d410d7f961498f ]
Prior to commit 4a8c31a1c6f5 ("xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront"), the behaviour of xen-blkback when connecting to a frontend was:
- read 'ring-page-order'
- if not present then expect a single page ring specified by 'ring-ref'
- else expect a ring specified by 'ring-refX' where X is between 0 and 1 << ring-page-order
This was correct behaviour, but was broken by the afforementioned commit to become:
- read 'ring-page-order'
- if not present then expect a single page ring (i.e. ring-page-order = 0)
- expect a ring specified by 'ring-refX' where X is between 0 and 1 << ring-page-order
- if that didn't work then see if there's a single page ring specified by 'ring-ref'
This incorrect behaviour works most of the time but fails when a frontend that sets 'ring-page-order' is unloaded and replaced by one that does not because, instead of reading 'ring-ref', xen-blkback will read the stale 'ring-ref0' left around by the previous frontend will try to map the wrong grant reference.
This patch restores the original behaviour.
--- drivers/block/xen-blkback/common.h | 1 + drivers/block/xen-blkback/xenbus.c | 38 +++++++++++++----------------- 2 files changed, 17 insertions(+), 22 deletions(-)
drivers/block/xen-blkback/common.h +1 -0
@@ -313,6 +313,7 @@ struct xen_blkif {struct work_struct free_work;unsigned int nr_ring_pages; +bool multi_ref;/* All rings for this device. */ struct xen_blkif_ring *rings;unsigned int nr_rings;
drivers/block/xen-blkback/xenbus.c +16 -22
@@ -998,14 +998,17 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir)for (i =0 ; i < nr_grefs; i++) {char ring_ref_name[RINGREF_NAME_LEN ]; -snprintf (ring_ref_name,RINGREF_NAME_LEN ,"ring-ref%u" , i); +if (blkif->multi_ref) +snprintf (ring_ref_name,RINGREF_NAME_LEN ,"ring-ref%u" , i); +else { +WARN_ON (i !=0 ); +snprintf (ring_ref_name,RINGREF_NAME_LEN ,"ring-ref" ); + } + err =xenbus_scanf (XBT_NIL , dir, ring_ref_name,"%u" , &ring_ref[i]);if (err !=1 ) { -if (nr_grefs ==1 ) -break ; - err = -EINVAL ;xenbus_dev_fatal (dev, err,"reading %s/%s" , dir, ring_ref_name);
@@ -1013,18 +1016,6 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) } } -if (err !=1 ) { -WARN_ON (nr_grefs !=1 ); - - err =xenbus_scanf (XBT_NIL , dir,"ring-ref" ,"%u" , - &ring_ref[0 ]); -if (err !=1 ) { - err = -EINVAL ; -xenbus_dev_fatal (dev, err,"reading %s/ring-ref" , dir); -return err; - } - } - err = -ENOMEM ;for (i =0 ; i < nr_grefs *XEN_BLKIF_REQS_PER_PAGE ; i++) { req =kzalloc (sizeof (*req),GFP_KERNEL );
@@ -1129,10 +1120,15 @@ static int connect_ring(struct backend_info *be) blkif->nr_rings, blkif->blk_protocol, protocol, blkif->vbd.feature_gnt_persistent ? "persistent grants" : ""); - ring_page_order =xenbus_read_unsigned (dev->otherend, -"ring-page-order" ,0 ); - -if (ring_page_order > xen_blkif_max_ring_order) { + err =xenbus_scanf (XBT_NIL , dev->otherend,"ring-page-order" ,"%u" , + &ring_page_order); +if (err !=1 ) { + blkif->nr_ring_pages =1 ; + blkif->multi_ref = false; + }else if (ring_page_order <= xen_blkif_max_ring_order) { + blkif->nr_ring_pages =1 << ring_page_order; + blkif->multi_ref = true; + }else { err = -EINVAL ; xenbus_dev_fatal(dev, err, "requested ring page order %d exceed max:%d",
@@ -1141,8 +1137,6 @@ static int connect_ring(struct backend_info *be)return err; } - blkif->nr_ring_pages =1 << ring_page_order; -if (blkif->nr_rings ==1 )return read_per_ring_refs (&blkif->rings[0 ], dev->otherend);else {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 306/601 soc: aspeed: fix a ternary sign expansion bug
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5ffa828534036348fa90fb3079ccc0972d202c4a ]
The intent here was to return negative error codes but it actually returns positive values. The problem is that type promotion with ternary operations is quite complicated.
"ret" is an int. "copied" is a u32. And the snoop_file_read() function returns long. What happens is that "ret" is cast to u32 and becomes positive then it's cast to long and it's still positive.
Fix this by removing the ternary so that "ret" is type promoted directly to long.
--- drivers/soc/aspeed/aspeed-lpc-snoop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/soc/aspeed/aspeed-lpc-snoop.c +3 -1
@@ -95,8 +95,10 @@ static ssize_t snoop_file_read(struct file *file, char __user *buffer,return -EINTR ; } ret =kfifo_to_user (&chan->fifo, buffer, count, &copied); +if (ret) +return ret; -return ret ? ret : copied; +return copied; } static __poll_t snoop_file_poll(struct file *file,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 307/601 drm/tilcdc: send vblank event when disabling crtc
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit f1a75f4dd8edf272b6b7cdccf6ba6254ec9d15fa ]
When run xrandr to change resolution on Beaglebone Black board, it will print the error information:
root@beaglebone:~# xrandr -display :0 --output HDMI-1 --mode 720x400 [drm:drm_crtc_commit_wait] *ERROR* flip_done timed out [drm:drm_atomic_helper_wait_for_dependencies] *ERROR* [CRTC:32:tilcdc crtc] commit wait timed out [drm:drm_crtc_commit_wait] *ERROR* flip_done timed out [drm:drm_atomic_helper_wait_for_dependencies] *ERROR* [CONNECTOR:34:HDMI-A-1] commit wait timed out [drm:drm_crtc_commit_wait] *ERROR* flip_done timed out [drm:drm_atomic_helper_wait_for_dependencies] *ERROR* [PLANE:31:plane-0] commit wait timed out tilcdc 4830e000.lcdc: already pending page flip!
This is because there is operation sequence as below:
drm_atomic_connector_commit_dpms(mode is DRM_MODE_DPMS_OFF):
...
drm_atomic_helper_setup_commit <- init_completion(commit_A->flip_done)
drm_atomic_helper_commit_tail
tilcdc_crtc_atomic_disable
tilcdc_plane_atomic_update <- drm_crtc_send_vblank_event in tilcdc_crtc_irq
is skipped since tilcdc_crtc->enabled is 0
tilcdc_crtc_atomic_flush <- drm_crtc_send_vblank_event is skipped since
crtc->state->event is set to be NULL in
tilcdc_plane_atomic_update
drm_mode_setcrtc:
...
drm_atomic_helper_setup_commit <- init_completion(commit_B->flip_done)
drm_atomic_helper_wait_for_dependencies
drm_crtc_commit_wait <- wait for commit_A->flip_done completingJust as shown above, the steps which could complete commit_A->flip_done are all skipped and commit_A->flip_done will never be completed. This will result a time-out ERROR when drm_crtc_commit_wait check the commit_A->flip_done. So add drm_crtc_send_vblank_event in tilcdc_crtc_atomic_disable to complete commit_A->flip_done.
--- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/tilcdc/tilcdc_crtc.c +9 -0
@@ -515,6 +515,15 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)drm_crtc_vblank_off (crtc); +spin_lock_irq (&crtc->dev->event_lock); + +if (crtc->state->event) { +drm_crtc_send_vblank_event (crtc, crtc->state->event); + crtc->state->event =NULL ; + } + +spin_unlock_irq (&crtc->dev->event_lock); +tilcdc_crtc_disable_irqs (dev);pm_runtime_put_sync (dev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 308/601 drm/stm: Fix bus_flags handling
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
[ Upstream commit 99e360442f223dd40fc23ae07c7a263836fd27e6 ]
The drm_display_mode_to_videomode() does not populate DISPLAY_FLAGS_DE_LOW or DISPLAY_FLAGS_PIXDATA_NEGEDGE flags in struct videomode. Therefore, no matter what polarity the next bridge or display might require, these flags are never set, and thus the LTDC GCR_DEPOL and GCR_PCPOL bits are never set and the LTDC behaves as if both DISPLAY_FLAGS_PIXDATA_POSEDGE and DISPLAY_FLAGS_DE_HIGH were always set.
The fix for this problem is taken almost verbatim from MXSFB driver. In case there is a bridge attached to the LTDC, the bridge might have extra polarity requirements, so extract bus_flags from the bridge and use them for LTDC configuration. Otherwise, extract bus_flags from the connector, which is the display.
--- drivers/gpu/drm/stm/ltdc.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
drivers/gpu/drm/stm/ltdc.c +31 -2
@@ -525,13 +525,42 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) {struct ltdc_device *ldev =crtc_to_ltdc (crtc);struct drm_device *ddev = crtc->dev; +struct drm_connector_list_iter iter; +struct drm_connector *connector =NULL ; +struct drm_encoder *encoder =NULL ; +struct drm_bridge *bridge =NULL ;struct drm_display_mode *mode = &crtc->state->adjusted_mode;struct videomode vm;u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;u32 total_width, total_height; +u32 bus_flags =0 ;u32 val;int ret; +/* get encoder from crtc */ +drm_for_each_encoder (encoder, ddev) +if (encoder->crtc == crtc) +break ; + +if (encoder) { +/* get bridge from encoder */ +list_for_each_entry (bridge, &encoder->bridge_chain, chain_node) +if (bridge->encoder == encoder) +break ; + +/* Get the connector from encoder */ +drm_connector_list_iter_begin (ddev, &iter); +drm_for_each_connector_iter (connector, &iter) +if (connector->encoder == encoder) +break ; +drm_connector_list_iter_end (&iter); + } + +if (bridge && bridge->timings) + bus_flags = bridge->timings->input_bus_flags; +else if (connector) + bus_flags = connector->display_info.bus_flags; +if (!pm_runtime_active (ddev->dev)) { ret =pm_runtime_get_sync (ddev->dev);if (ret) {
@@ -567,10 +596,10 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)if (vm.flags &DISPLAY_FLAGS_VSYNC_HIGH ) val |=GCR_VSPOL ; -if (vm.flags &DISPLAY_FLAGS_DE_LOW ) +if (bus_flags &DRM_BUS_FLAG_DE_LOW ) val |=GCR_DEPOL ; -if (vm.flags &DISPLAY_FLAGS_PIXDATA_NEGEDGE ) +if (bus_flags &DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE ) val |=GCR_PCPOL ; reg_update_bits(ldev->regs, LTDC_GCR,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 309/601 drm/amd/display: Fix off by one in hdmi_14_process_transaction()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 8e6fafd5a22e7a2eb216f5510db7aab54cc545c1 ]
The hdcp_i2c_offsets[] array did not have an entry for HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE so it led to an off by one read overflow. I added an entry and copied the 0x0 value for the offset from similar code in drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c.
I also declared several of these arrays as having HDCP_MESSAGE_ID_MAX entries. This doesn't change the code, but it's just a belt and suspenders approach to try future proof the code.
--- drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +5 -4
@@ -39,7 +39,7 @@#define HDCP14_KSV_SIZE 5#define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE -static const bool hdcp_cmd_is_read[] = { +static const bool hdcp_cmd_is_read[HDCP_MESSAGE_ID_MAX ] = { [HDCP_MESSAGE_ID_READ_BKSV ] = true, [HDCP_MESSAGE_ID_READ_RI_R0 ] = true, [HDCP_MESSAGE_ID_READ_PJ ] = true,
@@ -75,7 +75,7 @@ static const bool hdcp_cmd_is_read[] = { [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE ] = false }; -static const uint8_t hdcp_i2c_offsets[] = { +static const uint8_t hdcp_i2c_offsets[HDCP_MESSAGE_ID_MAX ] = { [HDCP_MESSAGE_ID_READ_BKSV ] =0x0 , [HDCP_MESSAGE_ID_READ_RI_R0 ] =0x8 , [HDCP_MESSAGE_ID_READ_PJ ] =0xA ,
@@ -106,7 +106,8 @@ static const uint8_t hdcp_i2c_offsets[] = { [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60, [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60, [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80, - [HDCP_MESSAGE_ID_READ_RXSTATUS ] =0x70 + [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70, + [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0, };struct protection_properties {
@@ -184,7 +185,7 @@ static const struct protection_properties hdmi_14_protection = { .process_transaction = hdmi_14_process_transaction }; -static const uint32_t hdcp_dpcd_addrs[] = { +static const uint32_t hdcp_dpcd_addrs[HDCP_MESSAGE_ID_MAX ] = { [HDCP_MESSAGE_ID_READ_BKSV ] =0x68000 , [HDCP_MESSAGE_ID_READ_RI_R0 ] =0x68005 , [HDCP_MESSAGE_ID_READ_PJ ] =0xFFFFFFFF ,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 310/601 drm/mcde/panel: Inverse misunderstood flag
In reply to Greg Kroah-HartmanFrom: Linus Walleij <[email protected]>
[ Upstream commit d0c5ac04e7feedbc069f26f4dcbf35b521ae7fc5 ]
A recent patch renaming MIPI_DSI_MODE_EOT_PACKET to MIPI_DSI_MODE_NO_EOT_PACKET brought to light the misunderstanding in the current MCDE driver and all its associated panel drivers that MIPI_DSI_MODE_EOT_PACKET would mean "use EOT packet" when in fact it means the reverse.
Fix it up by implementing the flag right in the MCDE DSI driver and remove the flag from panels that actually want the EOT packet.
--- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- drivers/gpu/drm/panel/panel-novatek-nt35510.c | 3 +-- drivers/gpu/drm/panel/panel-samsung-s6d16d0.c | 4 +--- drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c | 1 - drivers/gpu/drm/panel/panel-sony-acx424akp.c | 3 +-- 5 files changed, 4 insertions(+), 9 deletions(-)
drivers/gpu/drm/mcde/mcde_dsi.c +1 -1
@@ -760,7 +760,7 @@ static void mcde_dsi_start(struct mcde_dsi *d)DSI_MCTL_MAIN_DATA_CTL_BTA_EN |DSI_MCTL_MAIN_DATA_CTL_READ_EN |DSI_MCTL_MAIN_DATA_CTL_REG_TE_EN ; -if (d->mdsi->mode_flags &MIPI_DSI_MODE_EOT_PACKET ) +if (!(d->mdsi->mode_flags &MIPI_DSI_MODE_EOT_PACKET )) val |=DSI_MCTL_MAIN_DATA_CTL_HOST_EOT_GEN ;writel (val, d->regs +DSI_MCTL_MAIN_DATA_CTL );
drivers/gpu/drm/panel/panel-novatek-nt35510.c +1 -2
@@ -898,8 +898,7 @@ static int nt35510_probe(struct mipi_dsi_device *dsi)*/ dsi->hs_rate =349440000 ; dsi->lp_rate =9600000 ; - dsi->mode_flags =MIPI_DSI_CLOCK_NON_CONTINUOUS | -MIPI_DSI_MODE_EOT_PACKET ; + dsi->mode_flags =MIPI_DSI_CLOCK_NON_CONTINUOUS ;/* * Every new incarnation of this display must have a unique
drivers/gpu/drm/panel/panel-samsung-s6d16d0.c +1 -3
@@ -184,9 +184,7 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi)* As we only send commands we do not need to be continuously * clocked. */ - dsi->mode_flags = -MIPI_DSI_CLOCK_NON_CONTINUOUS | -MIPI_DSI_MODE_EOT_PACKET ; + dsi->mode_flags =MIPI_DSI_CLOCK_NON_CONTINUOUS ; s6->supply =devm_regulator_get (dev,"vdd1" );if (IS_ERR (s6->supply))
drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c +0 -1
@@ -97,7 +97,6 @@ static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi) dsi->hs_rate =349440000 ; dsi->lp_rate =9600000 ; dsi->mode_flags =MIPI_DSI_MODE_VIDEO | -MIPI_DSI_MODE_EOT_PACKET |MIPI_DSI_MODE_VIDEO_BURST ; ret = s6e63m0_probe(dev, s6e63m0_dsi_dcs_read, s6e63m0_dsi_dcs_write,
drivers/gpu/drm/panel/panel-sony-acx424akp.c +1 -2
@@ -449,8 +449,7 @@ static int acx424akp_probe(struct mipi_dsi_device *dsi)MIPI_DSI_MODE_VIDEO_BURST ; else dsi->mode_flags = -MIPI_DSI_CLOCK_NON_CONTINUOUS | -MIPI_DSI_MODE_EOT_PACKET ; +MIPI_DSI_CLOCK_NON_CONTINUOUS ; acx->supply =devm_regulator_get (dev,"vddi" );if (IS_ERR (acx->supply))
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 311/601 scsi: lpfc: Fix null pointer dereference in lpfc_prep_els_iocb()
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 8dd1c125f7f838abad009b64bff5f0a11afe3cb6 ]
It is possible to call lpfc_issue_els_plogi() passing a did for which no matching ndlp is found. A call is then made to lpfc_prep_els_iocb() with a null pointer to a lpfc_nodelist structure resulting in a null pointer dereference.
Fix by returning an error status if no valid ndlp is found. Fix up comments regarding ndlp reference counting.
--- drivers/scsi/lpfc/lpfc_els.c | 50 +++++++++++++++++------------------- 1 file changed, 24 insertions(+), 26 deletions(-)
drivers/scsi/lpfc/lpfc_els.c +24 -26
@@ -1,7 +1,7 @@/******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * -* Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * +* Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. *
@@ -2041,13 +2041,12 @@ out_freeiocb:* This routine issues a Port Login (PLOGI) command to a remote N_Port * (with the @did) for a @vport. Before issuing a PLOGI to a remote N_Port, * the ndlp with the remote N_Port DID must exist on the @vport's ndlp list. -* This routine constructs the proper feilds of the PLOGI IOCB and invokes +* This routine constructs the proper fields of the PLOGI IOCB and invokes * the lpfc_sli_issue_iocb() routine to send out PLOGI ELS command. * -* Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp -* will be incremented by 1 for holding the ndlp and the reference to ndlp -* will be stored into the context1 field of the IOCB for the completion -* callback function to the PLOGI ELS command. +* Note that the ndlp reference count will be incremented by 1 for holding +* the ndlp and the reference to ndlp will be stored into the context1 field +* of the IOCB for the completion callback function to the PLOGI ELS command. * * Return code * 0 - Successfully issued a plogi for @vport
@@ -2065,29 +2064,28 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)int ret; ndlp =lpfc_findnode_did (vport, did); +if (!ndlp) +return 1 ; -if (ndlp) { -/* Defer the processing of the issue PLOGI until after the -* outstanding UNREG_RPI mbox command completes, unless we -* are going offline. This logic does not apply for Fabric DIDs -*/ -if ((ndlp->nlp_flag &NLP_UNREG_INP ) && - ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && - !(vport->fc_flag &FC_OFFLINE_MODE )) { -lpfc_printf_vlog (vport,KERN_INFO ,LOG_DISCOVERY , -"4110 Issue PLOGI x%x deferred " -"on NPort x%x rpi x%x Data: x%px\n" , - ndlp->nlp_defer_did, ndlp->nlp_DID, - ndlp->nlp_rpi, ndlp); - -/* We can only defer 1st PLOGI */ -if (ndlp->nlp_defer_did ==NLP_EVT_NOTHING_PENDING ) - ndlp->nlp_defer_did = did; -return 0 ; - } +/* Defer the processing of the issue PLOGI until after the +* outstanding UNREG_RPI mbox command completes, unless we +* are going offline. This logic does not apply for Fabric DIDs +*/ +if ((ndlp->nlp_flag &NLP_UNREG_INP ) && + ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && + !(vport->fc_flag &FC_OFFLINE_MODE )) { +lpfc_printf_vlog (vport,KERN_INFO ,LOG_DISCOVERY , +"4110 Issue PLOGI x%x deferred " +"on NPort x%x rpi x%x Data: x%px\n" , + ndlp->nlp_defer_did, ndlp->nlp_DID, + ndlp->nlp_rpi, ndlp); + +/* We can only defer 1st PLOGI */ +if (ndlp->nlp_defer_did ==NLP_EVT_NOTHING_PENDING ) + ndlp->nlp_defer_did = did; +return 0 ; } -/* If ndlp is not NULL, we will bump the reference count on it */ cmdsize = (sizeof (uint32_t ) +sizeof (struct serv_parm )); elsiocb =lpfc_prep_els_iocb (vport,1 , cmdsize, retry, ndlp, did,ELS_CMD_PLOGI );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 312/601 sched/fair: Fix shift-out-of-bounds in load_balance()
In reply to Greg Kroah-HartmanFrom: Valentin Schneider <[email protected]>
[ Upstream commit 39a2a6eb5c9b66ea7c8055026303b3aa681b49a5 ]
Syzbot reported a handful of occurrences where an sd->nr_balance_failed can grow to much higher values than one would expect.
A successful load_balance() resets it to 0; a failed one increments it. Once it gets to sd->cache_nice_tries + 3, this *should* trigger an active balance, which will either set it to sd->cache_nice_tries+1 or reset it to 0. However, in case the to-be-active-balanced task is not allowed to run on env->dst_cpu, then the increment is done without any further modification.
This could then be repeated ad nauseam, and would explain the absurdly high values reported by syzbot (86, 149). VincentG noted there is value in letting sd->cache_nice_tries grow, so the shift itself should be fixed. That means preventing:
"""
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. """
Thus we need to cap the shift exponent to
BITS_PER_TYPE(typeof(lefthand)) - 1.
I had a look around for other similar cases via coccinelle:
@expr@
position pos;
expression E1;
expression E2;
@@
(
E1 >> E2@pos
|
E1 >> E2@pos
)
@cst depends on expr@
position pos;
expression expr.E1;
constant cst;
@@
(
E1 >> cst@pos
|
E1 << cst@pos
)
@script:python depends on !cst@
pos << expr.pos;
exp << expr.E2;
@@
# Dirty hack to ignore constexpr
if exp.upper() != exp:
coccilib.report.print_report(pos[0], "Possible UB shift here")
The only other match in kernel/sched is rq_clock_thermal() which employs sched_thermal_decay_shift, and that exponent is already capped to 10, so that one is fine.
--- kernel/sched/fair.c | 3 +-- kernel/sched/sched.h | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-)
kernel/sched/fair.c +1 -2
@@ -7760,8 +7760,7 @@ static int detach_tasks(struct lb_env *env)* scheduler fails to find a good waiting task to * migrate. */ - -if ((load >> env->sd->nr_balance_failed) > env->imbalance) +if (shr_bound (load, env->sd->nr_balance_failed) > env->imbalance) goto next; env->imbalance -= load;
kernel/sched/sched.h +7 -0
@@ -204,6 +204,13 @@ static inline void update_avg(u64 *avg, u64 sample) *avg += diff /8 ; } +/* +* Shifting a value by an exponent greater *or equal* to the size of said value +* is UB; cap at size-1. +*/ +#define shr_bound (val, shift) \ + (val >> min_t(typeof(shift), shift, BITS_PER_TYPE(typeof(val)) - 1)) +/* * !! For sched_setattr_nocheck() (kernel) only !! *
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 313/601 printk: limit second loop of syslog_print_all
In reply to Greg Kroah-HartmanFrom: John Ogness <[email protected]>
[ Upstream commit bb07b16c44b2c6ddbafa44bb06454719002e828e ]
The second loop of syslog_print_all() subtracts lengths that were added in the first loop. With commit b031a684bfd0 ("printk: remove logbuf_lock writer-protection of ringbuffer") it is possible that records are (over)written during syslog_print_all(). This allows the possibility of the second loop subtracting lengths that were never added in the first loop.
This situation can result in syslog_print_all() filling the buffer starting from a later record, even though there may have been room to fit the earlier record(s) as well.
--- kernel/printk/printk.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
kernel/printk/printk.c +8 -1
@@ -1494,6 +1494,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)struct printk_info info;unsigned int line_count;struct printk_record r; +u64 max_seq;char *text;int len =0 ;u64 seq;
@@ -1512,9 +1513,15 @@ static int syslog_print_all(char __user *buf, int size, bool clear)prb_for_each_info (clear_seq, prb, seq, &info, &line_count) len +=get_record_print_text_size (&info, line_count, true, time); +/* +* Set an upper bound for the next loop to avoid subtracting lengths +* that were never added. +*/ + max_seq = seq; +/* move first record forward until length fits into the buffer */ prb_for_each_info (clear_seq, prb, seq, &info, &line_count) { -if (len <= size) +if (len <= size || info.seq >= max_seq)break ; len -=get_record_print_text_size (&info, line_count, true, time); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 314/601 afs: Fix updating of i_mode due to 3rd party change
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 6e1eb04a87f954eb06a89ee6034c166351dfff6e ]
Fix afs_apply_status() to mask off the irrelevant bits from status->mode when OR'ing them into i_mode. This can happen when a 3rd party chmod occurs.
Also fix afs_inode_init_from_status() to mask off the mode bits when initialising i_mode.
--- fs/afs/inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/afs/inode.c +3 -3
@@ -102,13 +102,13 @@ static int afs_inode_init_from_status(struct afs_operation *op,switch (status->type) {case AFS_FTYPE_FILE : - inode->i_mode =S_IFREG | status->mode; + inode->i_mode =S_IFREG | (status->mode &S_IALLUGO ); inode->i_op = &afs_file_inode_operations; inode->i_fop = &afs_file_operations; inode->i_mapping->a_ops = &afs_fs_aops;break ;case AFS_FTYPE_DIR : - inode->i_mode =S_IFDIR | status->mode; + inode->i_mode =S_IFDIR | (status->mode &S_IALLUGO ); inode->i_op = &afs_dir_inode_operations; inode->i_fop = &afs_dir_file_operations; inode->i_mapping->a_ops = &afs_dir_aops;
@@ -198,7 +198,7 @@ static void afs_apply_status(struct afs_operation *op,if (status->mode != vnode->status.mode) { mode = inode->i_mode; mode &= ~S_IALLUGO ; - mode |= status->mode; + mode |= status->mode &S_IALLUGO ;WRITE_ONCE (inode->i_mode, mode); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 315/601 rcu: Remove spurious instrumentation_end() in rcu_nmi_enter()
In reply to Greg Kroah-HartmanFrom: Zhouyi Zhou <[email protected]>
[ Upstream commit 6494ccb93271bee596a12db32ff44867d5be2321 ]
In rcu_nmi_enter(), there is an erroneous instrumentation_end() in the second branch of the "if" statement. Oddly enough, "objtool check -f vmlinux.o" fails to complain because it is unable to correctly cover all cases. Instead, objtool visits the third branch first, which marks following trace_rcu_dyntick() as visited. This commit therefore removes the spurious instrumentation_end().
Reported-by Neeraj Upadhyay <[email protected]>
--- kernel/rcu/tree.c | 1 - 1 file changed, 1 deletion(-)
kernel/rcu/tree.c +0 -1
@@ -1072,7 +1072,6 @@ noinstr void rcu_nmi_enter(void) }else if (!in_nmi ()) {instrumentation_begin ();rcu_irq_enter_check_tick (); -instrumentation_end (); }else {instrumentation_begin (); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 316/601 media: vivid: fix assignment of dev->fbuf_out_flags
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 5cde22fcc7271812a7944c47b40100df15908358 ]
Currently the chroma_flags and alpha_flags are being zero'd with a bit-wise mask and the following statement should be bit-wise or'ing in the new flag bits but instead is making a direct assignment. Fix this by using the |= operator rather than an assignment.
Addresses-Coverity: ("Unused value")
--- drivers/media/test-drivers/vivid/vivid-vid-out.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/test-drivers/vivid/vivid-vid-out.c +1 -1
@@ -1021,7 +1021,7 @@ int vivid_vid_out_s_fbuf(struct file *file, void *fh,return -EINVAL ; } dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags); - dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags); + dev->fbuf_out_flags |= a->flags & (chroma_flags | alpha_flags);return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 317/601 media: saa7134: use sg_dma_len when building pgtable
In reply to Greg Kroah-HartmanFrom: Tasos Sahanidis <[email protected]>
[ Upstream commit 4e1cb753c04d74e06d7ca826ea0bcb02526af03e ]
The new AMD IOMMU DMA implementation concatenates sglist entries under certain conditions, and because saa7134 accessed the length member directly, it did not support this scenario.
This fixes IO_PAGE_FAULTs and choppy DMA audio by using the sg_dma_len macro.
--- drivers/media/pci/saa7134/saa7134-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/pci/saa7134/saa7134-core.c +1 -1
@@ -243,7 +243,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt, ptr = pt->cpu + startpage;for (i =0 ; i < length; i++, list =sg_next (list)) { -for (p =0 ; p *4096 < list->length; p++, ptr++) +for (p =0 ; p *4096 <sg_dma_len (list); p++, ptr++) *ptr =cpu_to_le32 (sg_dma_address (list) + list->offset + p *4096 ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 318/601 media: saa7146: use sg_dma_len when building pgtable
In reply to Greg Kroah-HartmanFrom: Tasos Sahanidis <[email protected]>
[ Upstream commit e56429b09d5e0802b86f84ec7c24025886c9f88b ]
The new AMD IOMMU DMA implementation concatenates sglist entries under certain conditions, and because saa7146 accessed the length member directly, it did not support this scenario.
This fixes IO_PAGE_FAULTs by using the sg_dma_len macro.
--- drivers/media/common/saa7146/saa7146_core.c | 2 +- drivers/media/common/saa7146/saa7146_video.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-)
drivers/media/common/saa7146/saa7146_core.c +1 -1
@@ -253,7 +253,7 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pti, sg_dma_address(list), sg_dma_len(list), list->offset); */ -for (p =0 ; p *4096 < list->length; p++, ptr++) { +for (p =0 ; p *4096 <sg_dma_len (list); p++, ptr++) { *ptr =cpu_to_le32 (sg_dma_address (list) + p *4096 ); nr_pages++; }
drivers/media/common/saa7146/saa7146_video.c +1 -2
@@ -247,9 +247,8 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu/* walk all pages, copy all page addresses to ptr1 */ for (i =0 ; i < length; i++, list++) { -for (p =0 ; p *4096 < list->length; p++, ptr1++) { +for (p =0 ; p *4096 <sg_dma_len (list); p++, ptr1++) *ptr1 =cpu_to_le32 (sg_dma_address (list) - list->offset); - } }/* ptr1 = pt1->cpu;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 319/601 media: omap4iss: return error code when omap4iss_get() failed
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 8938c48fa25b491842ece9eb38f0bea0fcbaca44 ]
If omap4iss_get() failed, it need return error code in iss_probe().
--- drivers/staging/media/omap4iss/iss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/staging/media/omap4iss/iss.c +3 -1
@@ -1236,8 +1236,10 @@ static int iss_probe(struct platform_device *pdev)if (ret <0 ) goto error; -if (!omap4iss_get (iss)) +if (!omap4iss_get (iss)) { + ret = -EINVAL ; goto error; + } ret =iss_reset (iss);if (ret <0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 320/601 media: rkisp1: rsz: crash fix when setting src format
In reply to Greg Kroah-HartmanFrom: Dafna Hirschfeld <[email protected]>
[ Upstream commit cbe8373ca7e7cbb4b263b6bf222ccc19f5e119d2 ]
When setting the source media bus code in the resizer, we first check that the current media bus code in the source is yuv encoded format. This is done by retrieving the data from the formats list of the isp entity. This cause a crash when the media bus code on the source is YUYV8_1_5X8 which is not supported by the isp entity. Instead we should test the sink format of the resizer which is guaranteed to be supported by the isp entity.
--- drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c +5 -4
@@ -520,14 +520,15 @@ static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz, struct v4l2_mbus_framefmt *format, unsigned int which) { -const struct rkisp1_isp_mbus_info *mbus_info; -struct v4l2_mbus_framefmt *src_fmt; +const struct rkisp1_isp_mbus_info *sink_mbus_info; +struct v4l2_mbus_framefmt *src_fmt, *sink_fmt; + sink_fmt =rkisp1_rsz_get_pad_fmt (rsz, cfg,RKISP1_RSZ_PAD_SINK , which); src_fmt =rkisp1_rsz_get_pad_fmt (rsz, cfg,RKISP1_RSZ_PAD_SRC , which); - mbus_info =rkisp1_isp_mbus_info_get (src_fmt->code); + sink_mbus_info =rkisp1_isp_mbus_info_get (sink_fmt->code);/* for YUV formats, userspace can change the mbus code on the src pad if it is supported */ -if (mbus_info->pixel_enc ==V4L2_PIXEL_ENC_YUV && +if (sink_mbus_info->pixel_enc ==V4L2_PIXEL_ENC_YUV &&rkisp1_rsz_get_yuv_mbus_info (format->code)) src_fmt->code = format->code;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 321/601 media: aspeed: fix clock handling logic
In reply to Greg Kroah-HartmanFrom: Jae Hyun Yoo <[email protected]>
[ Upstream commit 3536169f8531c2c5b153921dc7d1ac9fd570cda7 ]
Video engine uses eclk and vclk for its clock sources and its reset control is coupled with eclk so the current clock enabling sequence works like below.
Enable eclk
De-assert Video Engine reset
10ms delay
Enable vclk
It introduces improper reset on the Video Engine hardware and eventually the hardware generates unexpected DMA memory transfers that can corrupt memory region in random and sporadic patterns. This issue is observed very rarely on some specific AST2500 SoCs but it causes a critical kernel panic with making a various shape of signature so it's extremely hard to debug. Moreover, the issue is observed even when the video engine is not actively used because udevd turns on the video engine hardware for a short time to make a query in every boot.
To fix this issue, this commit changes the clock handling logic to make the reset de-assertion triggered after enabling both eclk and vclk. Also, it adds clk_unprepare call for a case when probe fails.
clk: ast2600: fix reset settings for eclk and vclk
Video engine reset setting should be coupled with eclk to match it with the setting for previous Aspeed SoCs which is defined in clk-aspeed.c since all Aspeed SoCs are sharing a single video engine driver. Also, reset bit 6 is defined as 'Video Engine' reset in datasheet so it should be de-asserted when eclk is enabled. This commit fixes the setting.
--- drivers/clk/clk-ast2600.c | 4 ++-- drivers/media/platform/aspeed-video.c | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-)
drivers/clk/clk-ast2600.c +2 -2
@@ -61,10 +61,10 @@ static void __iomem *scu_g6_base;static const struct aspeed_gate_data aspeed_g6_gates[] = {/* clk rst name parent flags */ [ASPEED_CLK_GATE_MCLK ] = {0 ,-1 ,"mclk-gate" ,"mpll" ,CLK_IS_CRITICAL },/* SDRAM */ - [ASPEED_CLK_GATE_ECLK ] = {1 ,-1 ,"eclk-gate" ,"eclk" ,0 },/* Video Engine */ + [ASPEED_CLK_GATE_ECLK ] = {1 ,6 ,"eclk-gate" ,"eclk" ,0 },/* Video Engine */ [ASPEED_CLK_GATE_GCLK ] = {2 ,7 ,"gclk-gate" ,NULL ,0 },/* 2D engine */ /* vclk parent - dclk/d1clk/hclk/mclk */ - [ASPEED_CLK_GATE_VCLK ] = {3 ,6 ,"vclk-gate" ,NULL ,0 },/* Video Capture */ + [ASPEED_CLK_GATE_VCLK ] = {3 ,-1 ,"vclk-gate" ,NULL ,0 },/* Video Capture */ [ASPEED_CLK_GATE_BCLK ] = {4 ,8 ,"bclk-gate" ,"bclk" ,0 },/* PCIe/PCI */ /* From dpll */ [ASPEED_CLK_GATE_DCLK ] = {5 ,-1 ,"dclk-gate" ,NULL ,CLK_IS_CRITICAL },/* DAC */
drivers/media/platform/aspeed-video.c +6 -3
@@ -514,8 +514,8 @@ static void aspeed_video_off(struct aspeed_video *video)aspeed_video_write (video,VE_INTERRUPT_STATUS ,0xffffffff );/* Turn off the relevant clocks */ -clk_disable (video->vclk);clk_disable (video->eclk); +clk_disable (video->vclk);clear_bit (VIDEO_CLOCKS_ON , &video->flags); }
@@ -526,8 +526,8 @@ static void aspeed_video_on(struct aspeed_video *video)return ;/* Turn on the relevant clocks */ -clk_enable (video->eclk);clk_enable (video->vclk); +clk_enable (video->eclk);set_bit (VIDEO_CLOCKS_ON , &video->flags); }
@@ -1719,8 +1719,11 @@ static int aspeed_video_probe(struct platform_device *pdev)return rc; rc =aspeed_video_setup_video (video); -if (rc) +if (rc) { +clk_unprepare (video->vclk); +clk_unprepare (video->eclk);return rc; + }return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 322/601 drm/probe-helper: Check epoch counter in output_poll_execute()
In reply to Greg Kroah-HartmanFrom: Noralf Trønnes <[email protected]>
[ Upstream commit dc659a4e852b591771fc2e5abb60f4455b0cf316 ]
drm_helper_hpd_irq_event() checks the epoch counter to determine connector status change. This was introduced in
commit 5186421cbfe2 ("drm: Introduce epoch counter to drm_connector"). Do the same for output_poll_execute() so it can detect other changes beside connection status value changes.
v2:
- Add Fixes tag (Daniel)
--- drivers/gpu/drm/drm_probe_helper.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_probe_helper.c +6 -1
@@ -623,6 +623,7 @@ static void output_poll_execute(struct work_struct *work)struct drm_connector_list_iter conn_iter;enum drm_connector_status old_status;bool repoll = false, changed; +u64 old_epoch_counter;if (!dev->mode_config.poll_enabled)return ;
@@ -659,8 +660,9 @@ static void output_poll_execute(struct work_struct *work) repoll = true; + old_epoch_counter = connector->epoch_counter; connector->status =drm_helper_probe_detect (connector,NULL , false); -if (old_status != connector->status) { +if (old_epoch_counter != connector->epoch_counter) {const char *old, *new;/*
@@ -689,6 +691,9 @@ static void output_poll_execute(struct work_struct *work) connector->base.id, connector->name, old, new); +DRM_DEBUG_KMS ("[CONNECTOR:%d:%s] epoch counter %llu -> %llu\n" , + connector->base.id, connector->name, + old_epoch_counter, connector->epoch_counter); changed = true; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 323/601 media: venus: core: Fix some resource leaks in the error path of venus_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 5a465c5391a856a0c1e9554964d660676c35d1b2 ]
If an error occurs after a successful 'of_icc_get()' call, it must be undone.
Use 'devm_of_icc_get()' instead of 'of_icc_get()' to avoid the leak. Update the remove function accordingly and axe the now unneeded 'icc_put()' calls.
--- drivers/media/platform/qcom/venus/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/media/platform/qcom/venus/core.c +2 -5
@@ -195,11 +195,11 @@ static int venus_probe(struct platform_device *pdev)if (IS_ERR (core->base))return PTR_ERR (core->base); - core->video_path =of_icc_get (dev,"video-mem" ); + core->video_path =devm_of_icc_get (dev,"video-mem" );if (IS_ERR (core->video_path))return PTR_ERR (core->video_path); - core->cpucfg_path =of_icc_get (dev,"cpu-cfg" ); + core->cpucfg_path =devm_of_icc_get (dev,"cpu-cfg" );if (IS_ERR (core->cpucfg_path))return PTR_ERR (core->cpucfg_path);
@@ -334,9 +334,6 @@ static int venus_remove(struct platform_device *pdev)hfi_destroy (core); -icc_put (core->video_path); -icc_put (core->cpucfg_path); -v4l2_device_unregister (&core->v4l2_dev);mutex_destroy (&core->pm_lock);mutex_destroy (&core->lock);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 324/601 media: platform: sunxi: sun6i-csi: fix error return code of sun6i_video_start_streaming()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit f3d384e36630e2a552d874e422835606d9cf230a ]
When sun6i_video_remote_subdev() returns NULL to subdev, no error return code of sun6i_video_start_streaming() is assigned.
To fix this bug, ret is assigned with -EINVAL in this case.
--- drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +3 -1
@@ -151,8 +151,10 @@ static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count) } subdev =sun6i_video_remote_subdev (video,NULL ); -if (!subdev) +if (!subdev) { + ret = -EINVAL ; goto stop_media_pipeline; + } config.pixelformat = video->fmt.fmt.pix.pixelformat; config.code = video->mbus_code;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 325/601 media: m88ds3103: fix return value check in m88ds3103_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit e61f9ea271933d987ab895c689fa37744f6fc27f ]
In case of error, the function i2c_new_dummy_device() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().
--- drivers/media/dvb-frontends/m88ds3103.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/m88ds3103.c +2 -2
@@ -1904,8 +1904,8 @@ static int m88ds3103_probe(struct i2c_client *client, dev->dt_client =i2c_new_dummy_device (client->adapter, dev->dt_addr); -if (!dev->dt_client) { - ret = -ENODEV ; +if (IS_ERR (dev->dt_client)) { + ret =PTR_ERR (dev->dt_client); goto err_kfree; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 326/601 media: docs: Fix data organization of MEDIA_BUS_FMT_RGB101010_1X30
In reply to Greg Kroah-HartmanFrom: Liu Ying <[email protected]>
[ Upstream commit c451ee146d449bbe39835fc3d9007b7f06332415 ]
The media bus bit width of MEDIA_BUS_FMT_RGB101010_1X30 is 30. So, 'Bit31' and 'Bit30' cells for the 'MEDIA_BUS_FMT_RGB101010_1X30' row should be spaces instead of '0's.
--- Documentation/userspace-api/media/v4l/subdev-formats.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Documentation/userspace-api/media/v4l/subdev-formats.rst +2 -2
@@ -1567,8 +1567,8 @@ The following tables list existing packed RGB formats. - MEDIA_BUS_FMT_RGB101010_1X30 - 0x1018 - - - 0 - - 0 + - + - - r\ :sub:`9` - r\ :sub:`8` - r\ :sub:`7`
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 327/601 media: [next] staging: media: atomisp: fix memory leak of object flash
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 6045b01dd0e3cd3759eafe7f290ed04c957500b1 ]
In the case where the call to lm3554_platform_data_func returns an error there is a memory leak on the error return path of object flash. Fix this by adding an error return path that will free flash and rename labels fail2 to fail3 and fail1 to fail2.
--- .../media/atomisp/i2c/atomisp-lm3554.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +11 -8
@@ -843,8 +843,10 @@ static int lm3554_probe(struct i2c_client *client)return -ENOMEM ; flash->pdata =lm3554_platform_data_func (client); -if (IS_ERR (flash->pdata)) -return PTR_ERR (flash->pdata); +if (IS_ERR (flash->pdata)) { + err =PTR_ERR (flash->pdata); + goto fail1; + }v4l2_i2c_subdev_init (&flash->sd, client, &lm3554_ops); flash->sd.internal_ops = &lm3554_internal_ops;
@@ -856,7 +858,7 @@ static int lm3554_probe(struct i2c_client *client) ARRAY_SIZE(lm3554_controls));if (ret) {dev_err (&client->dev,"error initialize a ctrl_handler.\n" ); - goto fail2; + goto fail3; }for (i =0 ; i <ARRAY_SIZE (lm3554_controls); i++)
@@ -865,14 +867,14 @@ static int lm3554_probe(struct i2c_client *client)if (flash->ctrl_handler.error) {dev_err (&client->dev,"ctrl_handler error.\n" ); - goto fail2; + goto fail3; } flash->sd.ctrl_handler = &flash->ctrl_handler; err =media_entity_pads_init (&flash->sd.entity,0 ,NULL );if (err) {dev_err (&client->dev,"error initialize a media entity.\n" ); - goto fail1; + goto fail2; } flash->sd.entity.function =MEDIA_ENT_F_FLASH ;
@@ -884,14 +886,15 @@ static int lm3554_probe(struct i2c_client *client) err =lm3554_gpio_init (client);if (err) {dev_err (&client->dev,"gpio request/direction_output fail" ); - goto fail2; + goto fail3; }return atomisp_register_i2c_module (&flash->sd,NULL ,LED_FLASH ); -fail2: +fail3:media_entity_cleanup (&flash->sd.entity);v4l2_ctrl_handler_free (&flash->ctrl_handler); -fail1: +fail2:v4l2_device_unregister_subdev (&flash->sd); +fail1:kfree (flash);return err;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 328/601 media: atomisp: Fixed error handling path
In reply to Greg Kroah-HartmanFrom: Souptick Joarder <[email protected]>
[ Upstream commit 16a5dcf7fbc2f5cd10c1e6264262bfa3832fb7d5 ]
Inside alloc_user_pages() based on flag value either pin_user_pages() or get_user_pages_fast() will be called. However, these API might fail.
But free_user_pages() called in error handling path doesn't bother about return value and will try to unpin bo->pgnr pages, which is incorrect.
Fix this by passing the page_nr to free_user_pages(). If page_nr > 0 pages will be unpinned based on bo->mem_type. This will also take care of non error handling path.
allocation")
--- drivers/staging/media/atomisp/pci/hmm/hmm_bo.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +8 -5
@@ -857,16 +857,17 @@ static void free_private_pages(struct hmm_buffer_object *bo,kfree (bo->page_obj); } -static void free_user_pages (struct hmm_buffer_object *bo) +static void free_user_pages (struct hmm_buffer_object *bo, +unsigned int page_nr) {int i; hmm_mem_stat.usr_size -= bo->pgnr;if (bo->mem_type ==HMM_BO_MEM_TYPE_PFN ) { -unpin_user_pages (bo->pages, bo->pgnr); +unpin_user_pages (bo->pages, page_nr); }else { -for (i =0 ; i < bo->pgnr; i++) +for (i =0 ; i < page_nr; i++)put_page (bo->pages[i]); }kfree (bo->pages);
@@ -942,6 +943,8 @@ static int alloc_user_pages(struct hmm_buffer_object *bo,dev_err (atomisp_dev,"get_user_pages err: bo->pgnr = %d, pgnr actually pinned = %d.\n" , bo->pgnr, page_nr); +if (page_nr <0 ) + page_nr =0 ; goto out_of_mem; }
@@ -954,7 +957,7 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, out_of_mem: -free_user_pages (bo); +free_user_pages (bo, page_nr);return -ENOMEM ; }
@@ -1037,7 +1040,7 @@ void hmm_bo_free_pages(struct hmm_buffer_object *bo)if (bo->type ==HMM_BO_PRIVATE )free_private_pages (bo, &dynamic_pool, &reserved_pool);else if (bo->type ==HMM_BO_USER ) -free_user_pages (bo); +free_user_pages (bo, bo->pgnr);else dev_err (atomisp_dev,"invalid buffer type.\n" );mutex_unlock (&bo->mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 329/601 media: m88rs6000t: avoid potential out-of-bounds reads on arrays
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 9baa3d64e8e2373ddd11c346439e5dfccb2cbb0d ]
There a 3 array for-loops that don't check the upper bounds of the index into arrays and this may lead to potential out-of-bounds reads. Fix this by adding array size upper bounds checks to be full safe.
Addresses-Coverity: ("Out-of-bounds read")
--- drivers/media/tuners/m88rs6000t.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/tuners/m88rs6000t.c +3 -3
@@ -525,7 +525,7 @@ static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength) PGA2_cri =PGA2_GC >>2 ; PGA2_crf =PGA2_GC &0x03 ; -for (i =0 ; i <=RF_GC ; i++) +for (i =0 ; i <=RF_GC && i <ARRAY_SIZE (RFGS ); i++)RFG +=RFGS [i];if (RF_GC ==0 )
@@ -537,12 +537,12 @@ static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength)if (RF_GC ==3 )RFG +=100 ; -for (i =0 ; i <=IF_GC ; i++) +for (i =0 ; i <=IF_GC && i <ARRAY_SIZE (IFGS ); i++)IFG +=IFGS [i];TIAG =TIA_GC *TIA_GS ; -for (i =0 ; i <=BB_GC ; i++) +for (i =0 ; i <=BB_GC && i <ARRAY_SIZE (BBGS ); i++)BBG +=BBGS [i];PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 330/601 media: atomisp: Fix use after free in atomisp_alloc_css_stat_bufs()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit ba11bbf303fafb33989e95473e409f6ab412b18d ]
The "s3a_buf" is freed along with all the other items on the "asd->s3a_stats" list. It leads to a double free and a use after free.
--- drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/staging/media/atomisp/pci/atomisp_ioctl.c +1 -3
@@ -948,10 +948,8 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,dev_dbg (isp->dev,"allocating %d dis buffers\n" , count);while (count--) { dis_buf =kzalloc (sizeof (struct atomisp_dis_buf ),GFP_KERNEL ); -if (!dis_buf) { -kfree (s3a_buf); +if (!dis_buf) goto error; - }if (atomisp_css_allocate_stat_buffers ( asd, stream_id,NULL , dis_buf,NULL )) {kfree (dis_buf);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 331/601 drm/amdkfd: fix build error with AMD_IOMMU_V2=m
In reply to Greg Kroah-HartmanFrom: Felix Kuehling <[email protected]>
[ Upstream commit 1e87068570a2cc4db5f95a881686add71729e769 ]
Using 'imply AMD_IOMMU_V2' does not guarantee that the driver can link against the exported functions. If the GPU driver is built-in but the IOMMU driver is a loadable module, the kfd_iommu.c file is indeed built but does not work:
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_bind_process_to_device':
kfd_iommu.c:(.text+0x516): undefined reference to `amd_iommu_bind_pasid'
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_unbind_process':
kfd_iommu.c:(.text+0x691): undefined reference to `amd_iommu_unbind_pasid'
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_suspend':
kfd_iommu.c:(.text+0x966): undefined reference to `amd_iommu_set_invalidate_ctx_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0x97f): undefined reference to `amd_iommu_set_invalid_ppr_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0x9a4): undefined reference to `amd_iommu_free_device'
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_resume':
kfd_iommu.c:(.text+0xa9a): undefined reference to `amd_iommu_init_device'
x86_64-linux-ld: kfd_iommu.c:(.text+0xadc): undefined reference to `amd_iommu_set_invalidate_ctx_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xaff): undefined reference to `amd_iommu_set_invalid_ppr_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xc72): undefined reference to `amd_iommu_bind_pasid'
x86_64-linux-ld: kfd_iommu.c:(.text+0xe08): undefined reference to `amd_iommu_set_invalidate_ctx_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xe26): undefined reference to `amd_iommu_set_invalid_ppr_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xe42): undefined reference to `amd_iommu_free_device'
Use IS_REACHABLE to only build IOMMU-V2 support if the amd_iommu symbols are reachable by the amdkfd driver. Output a warning if they are not, because that may not be what the user was expecting.
--- drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | 6 ++++++ drivers/gpu/drm/amd/amdkfd/kfd_iommu.h | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_iommu.c +6 -0
@@ -20,6 +20,10 @@* OTHER DEALINGS IN THE SOFTWARE. */ +#include <linux/kconfig.h> + +#if IS_REACHABLE (CONFIG_AMD_IOMMU_V2 ) +#include <linux/printk.h> #include <linux/device.h> #include <linux/slab.h>
@@ -355,3 +359,5 @@ int kfd_iommu_add_perf_counters(struct kfd_topology_device *kdev) return 0; } + +#endif
drivers/gpu/drm/amd/amdkfd/kfd_iommu.h +7 -2
@@ -23,7 +23,9 @@#ifndef __KFD_IOMMU_H__#define __KFD_IOMMU_H__ -#if defined(CONFIG_AMD_IOMMU_V2_MODULE ) || defined(CONFIG_AMD_IOMMU_V2 ) +#include <linux/kconfig.h> + +#if IS_REACHABLE (CONFIG_AMD_IOMMU_V2 )#define KFD_SUPPORT_IOMMU_V2
@@ -46,6 +48,9 @@ static inline int kfd_iommu_check_device(struct kfd_dev *kfd) }static inline int kfd_iommu_device_init (struct kfd_dev *kfd) { +#if IS_MODULE (CONFIG_AMD_IOMMU_V2 ) +WARN_ONCE (1 ,"iommu_v2 module is not usable by built-in KFD" ); +#endif return 0 ; }
@@ -73,6 +78,6 @@ static inline int kfd_iommu_add_perf_counters(struct kfd_topology_device *kdev)return 0 ; } -#endif /* defined(CONFIG_AMD_IOMMU_V2) */ +#endif /* IS_REACHABLE(CONFIG_AMD_IOMMU_V2) */ #endif /* __KFD_IOMMU_H__ */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 332/601 of: overlay: fix for_each_child.cocci warnings
In reply to Greg Kroah-HartmanFrom: kernel test robot <[email protected]>
[ Upstream commit c4d74f0f978ed5ceee62cd3f6708081042e582a1 ]
Function "for_each_child_of_node" should have of_node_put() before goto.
Generated by: scripts/coccinelle/iterators/for_each_child.cocci
--- drivers/of/overlay.c | 1 + 1 file changed, 1 insertion(+)
drivers/of/overlay.c +1 -0
@@ -796,6 +796,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,if (!fragment->target) {of_node_put (fragment->overlay); ret = -EINVAL ; +of_node_put (node); goto err_free_fragments; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 333/601 x86/kprobes: Fix to check non boostable prefixes correctly
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 6dd3b8c9f58816a1354be39559f630cd1bd12159 ]
There are 2 bugs in the can_boost() function because of using x86 insn decoder. Since the insn->opcode never has a prefix byte, it can not find CS override prefix in it. And the insn->attr is the attribute of the opcode, thus inat_is_address_size_prefix( insn->attr) always returns false.
Fix those by checking each prefix bytes with for_each_insn_prefix loop and getting the correct attribute for each prefix byte. Also, this removes unlikely, because this is a slow path.
--- arch/x86/kernel/kprobes/core.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
arch/x86/kernel/kprobes/core.c +12 -5
@@ -159,6 +159,8 @@ NOKPROBE_SYMBOL(skip_prefixes);int can_boost (struct insn *insn,void *addr) {kprobe_opcode_t opcode; +insn_byte_t prefix; +int i;if (search_exception_tables ((unsigned long )addr))return 0 ;/* Page fault may occur on this address. */
@@ -171,9 +173,14 @@ int can_boost(struct insn *insn, void *addr)if (insn->opcode.nbytes !=1 )return 0 ; -/* Can't boost Address-size override prefix */ -if (unlikely (inat_is_address_size_prefix (insn->attr))) -return 0 ; +for_each_insn_prefix (insn, i, prefix) { +insn_attr_t attr; + + attr =inat_get_opcode_attribute (prefix); +/* Can't boost Address-size override prefix and CS override prefix */ +if (prefix ==0x2e ||inat_is_address_size_prefix (attr)) +return 0 ; + } opcode = insn->opcode.bytes[0 ];
@@ -198,8 +205,8 @@ int can_boost(struct insn *insn, void *addr)/* clear and set flags are boostable */ return (opcode ==0xf5 || (0xf7 < opcode && opcode <0xfe ));default : -/* CS override prefix and call are not boostable */ -return (opcode !=0x2e && opcode !=0x9a ); +/* call is not boostable */ +return opcode !=0x9a ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 334/601 selftests: fix prepending $(OUTPUT) to $(TEST_PROGS)
In reply to Greg Kroah-HartmanFrom: Ilya Leoshkevich <[email protected]>
[ Upstream commit cb4969e6f9f5ee12521aec764fa3d4bbd91bc797 ]
Currently the following command produces an error message:
linux# make kselftest TARGETS=bpf O=/mnt/linux-build
# selftests: bpf: test_libbpf.sh
# ./test_libbpf.sh: line 23: ./test_libbpf_open: No such file or directory # test_libbpf: failed at file test_l4lb.o
# selftests: test_libbpf [FAILED]
The error message might not affect the return code of make, therefore one needs to grep make output in order to detect it.
This is not the only instance of the same underlying problem; any test with more than one element in $(TEST_PROGS) fails the same way. Another example:
linux# make O=/mnt/linux-build TARGETS=splice kselftest [...]
# ./short_splice_read.sh: 15: ./splice_read: not found # FAIL: /sys/module/test_module/sections/.init.text 2 not ok 2 selftests: splice: short_splice_read.sh # exit=1
The current logic prepends $(OUTPUT) only to the first member of $(TEST_PROGS). After that, run_one() does
cd dirname $TEST
For all tests except the first one, dirname $TEST is ., which means they cannot access the files generated in $(OUTPUT).
Fix by using $(addprefix) to prepend $(OUTPUT)/ to each member of $(TEST_PROGS).
--- tools/testing/selftests/lib.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/lib.mk +2 -1
@@ -74,7 +74,8 @@ ifdef building_out_of_srctree rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ fi @if [ "X$(TEST_PROGS)" != "X" ]; then \ - $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(OUTPUT)/$(TEST_PROGS)) ; \ + $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \ + $(addprefix $(OUTPUT)/,$(TEST_PROGS))) ; \ else \ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS)); \ fi
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 335/601 pata_arasan_cf: fix IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit c7e8f404d56b99c80990b19a402c3f640d74be05 ]
The driver's probe() method is written as if platform_get_irq() returns 0 on error, while actually it returns a negative error code (with all the other values considered valid IRQs). Rewrite the driver's IRQ checking code to pass the positive IRQ #s to ata_host_activate(), propagate upstream -EPROBE_DEFER, and set up the driver to polling mode on (negative) errors and IRQ0 (libata treats IRQ #0 as a polling mode anyway)...
--- drivers/ata/pata_arasan_cf.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/ata/pata_arasan_cf.c +11 -4
@@ -818,12 +818,19 @@ static int arasan_cf_probe(struct platform_device *pdev)else quirk =CF_BROKEN_UDMA ;/* as it is on spear1340 */ -/* if irq is 0, support only PIO */ - acdev->irq =platform_get_irq (pdev,0 ); -if (acdev->irq) +/* +* If there's an error getting IRQ (or we do get IRQ0), +* support only PIO +*/ + ret =platform_get_irq (pdev,0 ); +if (ret >0 ) { + acdev->irq = ret; irq_handler = arasan_cf_interrupt; -else + }else if (ret == -EPROBE_DEFER ) { +return ret; + }else { quirk |=CF_BROKEN_MWDMA |CF_BROKEN_UDMA ; + } acdev->pbase = res->start; acdev->vbase = devm_ioremap(&pdev->dev, res->start,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 336/601 pata_ipx4xx_cf: fix IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit e379b40cc0f179403ce0b82b7e539f635a568da5 ]
The driver's probe() method is written as if platform_get_irq() returns 0 on error, while actually it returns a negative error code (with all the other values considered valid IRQs). Rewrite the driver's IRQ checking code to pass the positive IRQ #s to ata_host_activate(), propagate errors upstream, and treat IRQ0 as error, returning -EINVAL, as the libata code treats 0 as an indication that polling should be used anyway...
--- drivers/ata/pata_ixp4xx_cf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/ata/pata_ixp4xx_cf.c +5 -1
@@ -165,8 +165,12 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)return -ENOMEM ; irq =platform_get_irq (pdev,0 ); -if (irq) +if (irq >0 )irq_set_irq_type (irq,IRQ_TYPE_EDGE_RISING ); +else if (irq <0 ) +return irq; +else +return -EINVAL ;/* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 337/601 sata_mv: add IRQ checks
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit e6471a65fdd5efbb8dd2732dd0f063f960685ceb ]
The function mv_platform_probe() neglects to check the results of the calls to platform_get_irq() and irq_of_parse_and_map() and blithely passes them to ata_host_activate() -- while the latter only checks for IRQ0 (treating it as a polling mode indicattion) and passes the negative values to devm_request_irq() causing it to fail as it takes unsigned values for the IRQ #...
Add to mv_platform_probe() the proper IRQ checks to pass the positive IRQ #s to ata_host_activate(), propagate upstream the negative error codes, and override the IRQ0 with -EINVAL (as we don't want the polling mode).
--- drivers/ata/sata_mv.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/ata/sata_mv.c +4 -0
@@ -4097,6 +4097,10 @@ static int mv_platform_probe(struct platform_device *pdev) n_ports = mv_platform_data->n_ports; irq =platform_get_irq (pdev,0 ); } +if (irq <0 ) +return irq; +if (!irq) +return -EINVAL ; host =ata_host_alloc_pinfo (&pdev->dev, ppi, n_ports); hpriv =devm_kzalloc (&pdev->dev,sizeof (*hpriv),GFP_KERNEL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 338/601 ata: libahci_platform: fix IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit b30d0040f06159de97ad9c0b1536f47250719d7d ]
Iff platform_get_irq() returns 0, ahci_platform_init_host() would return 0 early (as if the call was successful). Override IRQ0 with -EINVAL instead as the 'libata' regards 0 as "no IRQ" (thus polling) anyway...
--- drivers/ata/libahci_platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ata/libahci_platform.c +3 -1
@@ -582,11 +582,13 @@ int ahci_platform_init_host(struct platform_device *pdev,int i, irq, n_ports, rc; irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) { +if (irq <0 ) {if (irq != -EPROBE_DEFER )dev_err (dev,"no irq\n" );return irq; } +if (!irq) +return -EINVAL ; hpriv->irq = irq;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 339/601 seccomp: Fix CONFIG tests for Seccomp_filters
In reply to Greg Kroah-HartmanFrom: [email protected] <[email protected]>
[ Upstream commit 64bdc0244054f7d4bb621c8b4455e292f4e421bc ]
Strictly speaking, seccomp filters are only used when CONFIG_SECCOMP_FILTER.
This patch fixes the condition to enable "Seccomp_filters" in /proc/$pid/status.
--- fs/proc/array.c | 2 ++ init/init_task.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
fs/proc/array.c +2 -0
@@ -342,8 +342,10 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p)seq_put_decimal_ull (m,"NoNewPrivs:\t" ,task_no_new_privs (p));#ifdef CONFIG_SECCOMP seq_put_decimal_ull (m,"\nSeccomp:\t" , p->seccomp.mode); +#ifdef CONFIG_SECCOMP_FILTER seq_put_decimal_ull (m,"\nSeccomp_filters:\t" ,atomic_read (&p->seccomp.filter_count)); +#endif #endif seq_puts (m,"\nSpeculation_Store_Bypass:\t" );switch (arch_prctl_spec_ctrl_get (p,PR_SPEC_STORE_BYPASS )) {
init/init_task.c +1 -1
@@ -210,7 +210,7 @@ struct task_struct init_task#ifdef CONFIG_SECURITY .security = NULL,#endif -#ifdef CONFIG_SECCOMP +#ifdef CONFIG_SECCOMP_FILTER .seccomp = { .filter_count = ATOMIC_INIT(0) },#endif };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 340/601 nvme-tcp: block BH in sk state_change sk callback
In reply to Greg Kroah-HartmanFrom: Sagi Grimberg <[email protected]>
[ Upstream commit 8b73b45d54a14588f86792869bfb23098ea254cb ]
The TCP stack can run from process context for a long time so we should disable BH here.
--- drivers/nvme/host/tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/host/tcp.c +2 -2
@@ -874,7 +874,7 @@ static void nvme_tcp_state_change(struct sock *sk) {struct nvme_tcp_queue *queue; -read_lock (&sk->sk_callback_lock); +read_lock_bh (&sk->sk_callback_lock); queue = sk->sk_user_data;if (!queue) goto done;
@@ -895,7 +895,7 @@ static void nvme_tcp_state_change(struct sock *sk) queue->state_change (sk); done: -read_unlock (&sk->sk_callback_lock); +read_unlock_bh (&sk->sk_callback_lock); }static inline bool nvme_tcp_queue_more (struct nvme_tcp_queue *queue)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 341/601 nvmet-tcp: fix incorrect locking in state_change sk callback
In reply to Greg Kroah-HartmanFrom: Sagi Grimberg <[email protected]>
[ Upstream commit b5332a9f3f3d884a1b646ce155e664cc558c1722 ]
We are not changing anything in the TCP connection state so we should not take a write_lock but rather a read lock.
This caused a deadlock when running nvmet-tcp and nvme-tcp on the same system, where state_change callbacks on the host and on the controller side have causal relationship and made lockdep report on this with blktests:
================================
WARNING: inconsistent lock state
5.12.0-rc3 #1 Tainted: G I
--------------------------------
inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-R} usage.
nvme/1324 [HC0[0]:SC0[0]:HE1:SE1] takes:ffff888363151000 (clock-AF_INET){++-?}-{2:2}, at: nvme_tcp_state_change+0x21/0x150 [nvme_tcp] {IN-SOFTIRQ-W} state was registered at:
__lock_acquire+0x79b/0x18d0 lock_acquire+0x1ca/0x480 _raw_write_lock_bh+0x39/0x80 nvmet_tcp_state_change+0x21/0x170 [nvmet_tcp] tcp_fin+0x2a8/0x780 tcp_data_queue+0xf94/0x1f20 tcp_rcv_established+0x6ba/0x1f00 tcp_v4_do_rcv+0x502/0x760 tcp_v4_rcv+0x257e/0x3430 ip_protocol_deliver_rcu+0x69/0x6a0 ip_local_deliver_finish+0x1e2/0x2f0 ip_local_deliver+0x1a2/0x420 ip_rcv+0x4fb/0x6b0 __netif_receive_skb_one_core+0x162/0x1b0 process_backlog+0x1ff/0x770 __napi_poll.constprop.0+0xa9/0x5c0 net_rx_action+0x7b3/0xb30 __do_softirq+0x1f0/0x940 do_softirq+0xa1/0xd0 __local_bh_enable_ip+0xd8/0x100 ip_finish_output2+0x6b7/0x18a0 __ip_queue_xmit+0x706/0x1aa0 __tcp_transmit_skb+0x2068/0x2e20 tcp_write_xmit+0xc9e/0x2bb0 __tcp_push_pending_frames+0x92/0x310 inet_shutdown+0x158/0x300 __nvme_tcp_stop_queue+0x36/0x270 [nvme_tcp] nvme_tcp_stop_queue+0x87/0xb0 [nvme_tcp] nvme_tcp_teardown_admin_queue+0x69/0xe0 [nvme_tcp] nvme_do_delete_ctrl+0x100/0x10c [nvme_core] nvme_sysfs_delete.cold+0x8/0xd [nvme_core] kernfs_fop_write_iter+0x2c7/0x460 new_sync_write+0x36c/0x610 vfs_write+0x5c0/0x870 ksys_write+0xf9/0x1d0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae irq event stamp: 10687 hardirqs last enabled at (10687): [<ffffffff9ec376bd>] _raw_spin_unlock_irqrestore+0x2d/0x40 hardirqs last disabled at (10686): [<ffffffff9ec374d8>] _raw_spin_lock_irqsave+0x68/0x90 softirqs last enabled at (10684): [<ffffffff9f000608>] __do_softirq+0x608/0x940 softirqs last disabled at (10649): [<ffffffff9cdedd31>] do_softirq+0xa1/0xd0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(clock-AF_INET);
<Interrupt>
lock(clock-AF_INET);*** DEADLOCK ***
5 locks held by nvme/1324:
#0: ffff8884a01fe470 (sb_writers#4){.+.+}-{0:0}, at: ksys_write+0xf9/0x1d0
#1: ffff8886e435c090 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x216/0x460 #2: ffff888104d90c38 (kn->active#255){++++}-{0:0}, at: kernfs_remove_self+0x22d/0x330 #3: ffff8884634538d0 (&queue->queue_lock){+.+.}-{3:3}, at: nvme_tcp_stop_queue+0x52/0xb0 [nvme_tcp] #4: ffff888363150d30 (sk_lock-AF_INET){+.+.}-{0:0}, at: inet_shutdown+0x59/0x300
stack backtrace: CPU: 26 PID: 1324 Comm: nvme Tainted: G I 5.12.0-rc3 #1 Hardware name: Dell Inc. PowerEdge R640/06NR82, BIOS 2.10.0 11/12/2020 Call Trace: dump_stack+0x93/0xc2 mark_lock_irq.cold+0x2c/0xb3 ? verify_lock_unused+0x390/0x390 ? stack_trace_consume_entry+0x160/0x160 ? lock_downgrade+0x100/0x100 ? save_trace+0x88/0x5e0 ? _raw_spin_unlock_irqrestore+0x2d/0x40 mark_lock+0x530/0x1470 ? mark_lock_irq+0x1d10/0x1d10 ? enqueue_timer+0x660/0x660 mark_usage+0x215/0x2a0 __lock_acquire+0x79b/0x18d0 ? tcp_schedule_loss_probe.part.0+0x38c/0x520 lock_acquire+0x1ca/0x480 ? nvme_tcp_state_change+0x21/0x150 [nvme_tcp] ? rcu_read_unlock+0x40/0x40 ? tcp_mtu_probe+0x1ae0/0x1ae0 ? kmalloc_reserve+0xa0/0xa0 ? sysfs_file_ops+0x170/0x170 _raw_read_lock+0x3d/0xa0 ? nvme_tcp_state_change+0x21/0x150 [nvme_tcp] nvme_tcp_state_change+0x21/0x150 [nvme_tcp] ? sysfs_file_ops+0x170/0x170 inet_shutdown+0x189/0x300 __nvme_tcp_stop_queue+0x36/0x270 [nvme_tcp] nvme_tcp_stop_queue+0x87/0xb0 [nvme_tcp] nvme_tcp_teardown_admin_queue+0x69/0xe0 [nvme_tcp] nvme_do_delete_ctrl+0x100/0x10c [nvme_core] nvme_sysfs_delete.cold+0x8/0xd [nvme_core] kernfs_fop_write_iter+0x2c7/0x460 new_sync_write+0x36c/0x610 ? new_sync_read+0x600/0x600 ? lock_acquire+0x1ca/0x480 ? rcu_read_unlock+0x40/0x40 ? lock_is_held_type+0x9a/0x110 vfs_write+0x5c0/0x870 ksys_write+0xf9/0x1d0 ? __ia32_sys_read+0xa0/0xa0 ? lockdep_hardirqs_on_prepare.part.0+0x198/0x340 ? syscall_enter_from_user_mode+0x27/0x70 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae
--- drivers/nvme/target/tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/target/tcp.c +2 -2
@@ -1434,7 +1434,7 @@ static void nvmet_tcp_state_change(struct sock *sk) {struct nvmet_tcp_queue *queue; -write_lock_bh (&sk->sk_callback_lock); +read_lock_bh (&sk->sk_callback_lock); queue = sk->sk_user_data;if (!queue) goto done;
@@ -1452,7 +1452,7 @@ static void nvmet_tcp_state_change(struct sock *sk) queue->idx, sk->sk_state); } done: -write_unlock_bh (&sk->sk_callback_lock); +read_unlock_bh (&sk->sk_callback_lock); }static int nvmet_tcp_set_queue_sock (struct nvmet_tcp_queue *queue)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 342/601 clk: imx: Fix reparenting of UARTs not associated with stdout
In reply to Greg Kroah-HartmanFrom: Adam Ford <[email protected]>
[ Upstream commit 379c9a24cc239000b1dec53db02fe17a86947423 ]
Most if not all i.MX SoC's call a function which enables all UARTS. This is a problem for users who need to re-parent the clock source, because any attempt to change the parent results in an busy error due to the fact that the clocks have been enabled already.
clk: failed to reparent uart1 to sys_pll1_80m: -16
Instead of pre-initializing all UARTS, scan the device tree to see which UART clocks are associated to stdout, and only enable those UART clocks if it's needed early. This will move initialization of the remaining clocks until after the parenting of the clocks.
When the clocks are shutdown, this mechanism will also disable any clocks that were pre-initialized.
--- drivers/clk/imx/clk-imx25.c | 12 +--------- drivers/clk/imx/clk-imx27.c | 13 +---------- drivers/clk/imx/clk-imx35.c | 10 +-------- drivers/clk/imx/clk-imx5.c | 30 +++---------------------- drivers/clk/imx/clk-imx6q.c | 16 +------------- drivers/clk/imx/clk-imx6sl.c | 16 +------------- drivers/clk/imx/clk-imx6sll.c | 24 +------------------- drivers/clk/imx/clk-imx6sx.c | 16 +------------- drivers/clk/imx/clk-imx7d.c | 22 +------------------ drivers/clk/imx/clk-imx7ulp.c | 31 ++------------------------ drivers/clk/imx/clk-imx8mm.c | 18 ++------------- drivers/clk/imx/clk-imx8mn.c | 18 ++------------- drivers/clk/imx/clk-imx8mp.c | 17 +-------------- drivers/clk/imx/clk-imx8mq.c | 18 ++------------- drivers/clk/imx/clk.c | 41 +++++++++++++++++++++++++++-------- drivers/clk/imx/clk.h | 4 ++-- 16 files changed, 54 insertions(+), 252 deletions(-)
drivers/clk/imx/clk-imx25.c +1 -11
@@ -73,16 +73,6 @@ enum mx25_clks {static struct clk *clk[clk_max]; -static struct clk **const uart_clks[]__initconst = { - &clk[uart_ipg_per], - &clk[uart1_ipg], - &clk[uart2_ipg], - &clk[uart3_ipg], - &clk[uart4_ipg], - &clk[uart5_ipg], -NULL -}; -static int __init __mx25_clocks_init (void __iomem *ccm_base) {BUG_ON (!ccm_base);
@@ -228,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem *ccm_base)*/ clk_set_parent (clk[cko_sel], clk[ipg]); -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (6 );return 0 ; }
drivers/clk/imx/clk-imx27.c +1 -12
@@ -49,17 +49,6 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };static struct clk *clk[IMX27_CLK_MAX ];static struct clk_onecell_data clk_data; -static struct clk **const uart_clks[]__initconst = { - &clk[IMX27_CLK_PER1_GATE ], - &clk[IMX27_CLK_UART1_IPG_GATE ], - &clk[IMX27_CLK_UART2_IPG_GATE ], - &clk[IMX27_CLK_UART3_IPG_GATE ], - &clk[IMX27_CLK_UART4_IPG_GATE ], - &clk[IMX27_CLK_UART5_IPG_GATE ], - &clk[IMX27_CLK_UART6_IPG_GATE ], -NULL -}; -static void __init _mx27_clocks_init (unsigned long fref) {BUG_ON (!ccm);
@@ -176,7 +165,7 @@ static void __init _mx27_clocks_init(unsigned long fref)clk_prepare_enable (clk[IMX27_CLK_EMI_AHB_GATE ]); -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (7 );imx_print_silicon_rev ("i.MX27" ,mx27_revision ()); }
drivers/clk/imx/clk-imx35.c +1 -9
@@ -82,14 +82,6 @@ enum mx35_clks {static struct clk *clk[clk_max]; -static struct clk **const uart_clks[]__initconst = { - &clk[ipg], - &clk[uart1_gate], - &clk[uart2_gate], - &clk[uart3_gate], -NULL -}; -static void __init _mx35_clocks_init (void ) {void __iomem *base;
@@ -243,7 +235,7 @@ static void __init _mx35_clocks_init(void)*/ clk_prepare_enable (clk[scc_gate]); -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (4 );imx_print_silicon_rev ("i.MX35" ,mx35_revision ()); }
drivers/clk/imx/clk-imx5.c +3 -27
@@ -128,30 +128,6 @@ static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_static struct clk *clk[IMX5_CLK_END ];static struct clk_onecell_data clk_data; -static struct clk **const uart_clks_mx51[]__initconst = { - &clk[IMX5_CLK_UART1_IPG_GATE ], - &clk[IMX5_CLK_UART1_PER_GATE ], - &clk[IMX5_CLK_UART2_IPG_GATE ], - &clk[IMX5_CLK_UART2_PER_GATE ], - &clk[IMX5_CLK_UART3_IPG_GATE ], - &clk[IMX5_CLK_UART3_PER_GATE ], -NULL -}; - -static struct clk **const uart_clks_mx50_mx53[]__initconst = { - &clk[IMX5_CLK_UART1_IPG_GATE ], - &clk[IMX5_CLK_UART1_PER_GATE ], - &clk[IMX5_CLK_UART2_IPG_GATE ], - &clk[IMX5_CLK_UART2_PER_GATE ], - &clk[IMX5_CLK_UART3_IPG_GATE ], - &clk[IMX5_CLK_UART3_PER_GATE ], - &clk[IMX5_CLK_UART4_IPG_GATE ], - &clk[IMX5_CLK_UART4_PER_GATE ], - &clk[IMX5_CLK_UART5_IPG_GATE ], - &clk[IMX5_CLK_UART5_PER_GATE ], -NULL -}; -static void __init mx5_clocks_common_init (void __iomem *ccm_base) { clk[IMX5_CLK_DUMMY ] =imx_clk_fixed ("dummy" ,0 );
@@ -382,7 +358,7 @@ static void __init mx50_clocks_init(struct device_node *np) r =clk_round_rate (clk[IMX5_CLK_USBOH3_PER_GATE ],54000000 );clk_set_rate (clk[IMX5_CLK_USBOH3_PER_GATE ], r); -imx_register_uart_clocks (uart_clks_mx50_mx53); +imx_register_uart_clocks (5 ); }CLK_OF_DECLARE (imx50_ccm,"fsl,imx50-ccm" , mx50_clocks_init);
@@ -488,7 +464,7 @@ static void __init mx51_clocks_init(struct device_node *np) val |=1 <<23 ;writel (val,MXC_CCM_CLPCR ); -imx_register_uart_clocks (uart_clks_mx51); +imx_register_uart_clocks (3 ); }CLK_OF_DECLARE (imx51_ccm,"fsl,imx51-ccm" , mx51_clocks_init);
@@ -633,6 +609,6 @@ static void __init mx53_clocks_init(struct device_node *np) r =clk_round_rate (clk[IMX5_CLK_USBOH3_PER_GATE ],54000000 );clk_set_rate (clk[IMX5_CLK_USBOH3_PER_GATE ], r); -imx_register_uart_clocks (uart_clks_mx50_mx53); +imx_register_uart_clocks (5 ); }CLK_OF_DECLARE (imx53_ccm,"fsl,imx53-ccm" , mx53_clocks_init);
drivers/clk/imx/clk-imx6q.c +1 -15
@@ -140,13 +140,6 @@ static inline int clk_on_imx6dl(void)return of_machine_is_compatible ("fsl,imx6dl" ); } -static const int uart_clk_ids[]__initconst = { -IMX6QDL_CLK_UART_IPG , -IMX6QDL_CLK_UART_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static int ldb_di_sel_by_clock_id (int clock_id) {switch (clock_id) {
@@ -440,7 +433,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)struct device_node *np;void __iomem *anatop_base, *base;int ret; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6QDL_CLK_END ),GFP_KERNEL );
@@ -982,12 +974,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk); } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (1 ); }CLK_OF_DECLARE (imx6q,"fsl,imx6q-ccm" , imx6q_clocks_init);
drivers/clk/imx/clk-imx6sl.c +1 -15
@@ -178,19 +178,11 @@ void imx6sl_set_wait_clk(bool enter)imx6sl_enable_pll_arm (false); } -static const int uart_clk_ids[]__initconst = { -IMX6SL_CLK_UART , -IMX6SL_CLK_UART_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx6sl_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base;int ret; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6SL_CLK_END ),GFP_KERNEL );
@@ -447,12 +439,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6SL_CLK_LCDIF_AXI_SEL ]->clk, hws[IMX6SL_CLK_PLL2_PFD2 ]->clk); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (2 ); }CLK_OF_DECLARE (imx6sl,"fsl,imx6sl-ccm" , imx6sl_clocks_init);
drivers/clk/imx/clk-imx6sll.c +1 -23
@@ -76,26 +76,10 @@ static u32 share_count_ssi1;static u32 share_count_ssi2;static u32 share_count_ssi3; -static const int uart_clk_ids[]__initconst = { -IMX6SLL_CLK_UART1_IPG , -IMX6SLL_CLK_UART1_SERIAL , -IMX6SLL_CLK_UART2_IPG , -IMX6SLL_CLK_UART2_SERIAL , -IMX6SLL_CLK_UART3_IPG , -IMX6SLL_CLK_UART3_SERIAL , -IMX6SLL_CLK_UART4_IPG , -IMX6SLL_CLK_UART4_SERIAL , -IMX6SLL_CLK_UART5_IPG , -IMX6SLL_CLK_UART5_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx6sll_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6SLL_CLK_END ),GFP_KERNEL );
@@ -356,13 +340,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_hw_data); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (5 );/* Lower the AHB clock rate before changing the clock source. */ clk_set_rate (hws[IMX6SLL_CLK_AHB ]->clk,99000000 );
drivers/clk/imx/clk-imx6sx.c +1 -15
@@ -117,18 +117,10 @@ static u32 share_count_ssi3;static u32 share_count_sai1;static u32 share_count_sai2; -static const int uart_clk_ids[]__initconst = { -IMX6SX_CLK_UART_IPG , -IMX6SX_CLK_UART_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx6sx_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6SX_CLK_CLK_END ),GFP_KERNEL );
@@ -556,12 +548,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6SX_CLK_QSPI1_SEL ]->clk, hws[IMX6SX_CLK_PLL2_BUS ]->clk);clk_set_parent (hws[IMX6SX_CLK_QSPI2_SEL ]->clk, hws[IMX6SX_CLK_PLL2_BUS ]->clk); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (2 ); }CLK_OF_DECLARE (imx6sx,"fsl,imx6sx-ccm" , imx6sx_clocks_init);
drivers/clk/imx/clk-imx7d.c +1 -21
@@ -377,23 +377,10 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_static struct clk_hw **hws;static struct clk_hw_onecell_data *clk_hw_data; -static const int uart_clk_ids[]__initconst = { -IMX7D_UART1_ROOT_CLK , -IMX7D_UART2_ROOT_CLK , -IMX7D_UART3_ROOT_CLK , -IMX7D_UART4_ROOT_CLK , -IMX7D_UART5_ROOT_CLK , -IMX7D_UART6_ROOT_CLK , -IMX7D_UART7_ROOT_CLK , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx7d_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX7D_CLK_END ),GFP_KERNEL );
@@ -897,14 +884,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws[IMX7D_USB1_MAIN_480M_CLK ] =imx_clk_hw_fixed_factor ("pll_usb1_main_clk" ,"osc" ,20 ,1 ); hws[IMX7D_USB_MAIN_480M_CLK ] =imx_clk_hw_fixed_factor ("pll_usb_main_clk" ,"osc" ,20 ,1 ); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (7 ); }CLK_OF_DECLARE (imx7d,"fsl,imx7d-ccm" , imx7d_clocks_init);
drivers/clk/imx/clk-imx7ulp.c +2 -29
@@ -43,19 +43,6 @@ static const struct clk_div_table ulp_div_table[] = { { /* sentinel */ }, }; -static const int pcc2_uart_clk_ids[]__initconst = { -IMX7ULP_CLK_LPUART4 , -IMX7ULP_CLK_LPUART5 , -}; - -static const int pcc3_uart_clk_ids[]__initconst = { -IMX7ULP_CLK_LPUART6 , -IMX7ULP_CLK_LPUART7 , -}; - -static struct clk **pcc2_uart_clks[ARRAY_SIZE (pcc2_uart_clk_ids) +1 ]__initdata ; -static struct clk **pcc3_uart_clks[ARRAY_SIZE (pcc3_uart_clk_ids) +1 ]__initdata ; -static void __init imx7ulp_clk_scg1_init (struct device_node *np) {struct clk_hw_onecell_data *clk_data;
@@ -150,7 +137,6 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)struct clk_hw_onecell_data *clk_data;struct clk_hw **hws;void __iomem *base; -int i; clk_data =kzalloc (struct_size (clk_data, hws,IMX7ULP_CLK_PCC2_END ),GFP_KERNEL );
@@ -190,13 +176,7 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_data); -for (i =0 ; i <ARRAY_SIZE (pcc2_uart_clk_ids); i++) { -int index = pcc2_uart_clk_ids[i]; - - pcc2_uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (pcc2_uart_clks); +imx_register_uart_clocks (2 ); }CLK_OF_DECLARE (imx7ulp_clk_pcc2,"fsl,imx7ulp-pcc2" , imx7ulp_clk_pcc2_init);
@@ -205,7 +185,6 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)struct clk_hw_onecell_data *clk_data;struct clk_hw **hws;void __iomem *base; -int i; clk_data =kzalloc (struct_size (clk_data, hws,IMX7ULP_CLK_PCC3_END ),GFP_KERNEL );
@@ -244,13 +223,7 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_data); -for (i =0 ; i <ARRAY_SIZE (pcc3_uart_clk_ids); i++) { -int index = pcc3_uart_clk_ids[i]; - - pcc3_uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (pcc3_uart_clks); +imx_register_uart_clocks (7 ); }CLK_OF_DECLARE (imx7ulp_clk_pcc3,"fsl,imx7ulp-pcc3" , imx7ulp_clk_pcc3_init);
drivers/clk/imx/clk-imx8mm.c +2 -16
@@ -291,20 +291,12 @@ static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_static struct clk_hw_onecell_data *clk_hw_data;static struct clk_hw **hws; -static const int uart_clk_ids[] = { -IMX8MM_CLK_UART1_ROOT , -IMX8MM_CLK_UART2_ROOT , -IMX8MM_CLK_UART3_ROOT , -IMX8MM_CLK_UART4_ROOT , -}; -static struct clk **uart_hws[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mm_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *base; -int ret, i; +int ret; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX8MM_CLK_END ),GFP_KERNEL );
@@ -622,13 +614,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) goto unregister_hws; } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_hws[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_hws); +imx_register_uart_clocks (4 );return 0 ;
drivers/clk/imx/clk-imx8mn.c +2 -16
@@ -284,20 +284,12 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "systatic struct clk_hw_onecell_data *clk_hw_data;static struct clk_hw **hws; -static const int uart_clk_ids[] = { -IMX8MN_CLK_UART1_ROOT , -IMX8MN_CLK_UART2_ROOT , -IMX8MN_CLK_UART3_ROOT , -IMX8MN_CLK_UART4_ROOT , -}; -static struct clk **uart_hws[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mn_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *base; -int ret, i; +int ret; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX8MN_CLK_END ),GFP_KERNEL );
@@ -573,13 +565,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) goto unregister_hws; } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_hws[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_hws); +imx_register_uart_clocks (4 );return 0 ;
drivers/clk/imx/clk-imx8mp.c +1 -16
@@ -414,20 +414,11 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_rstatic struct clk_hw **hws;static struct clk_hw_onecell_data *clk_hw_data; -static const int uart_clk_ids[] = { -IMX8MP_CLK_UART1_ROOT , -IMX8MP_CLK_UART2_ROOT , -IMX8MP_CLK_UART3_ROOT , -IMX8MP_CLK_UART4_ROOT , -}; -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mp_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np;void __iomem *anatop_base, *ccm_base; -int i; np =of_find_compatible_node (NULL ,NULL ,"fsl,imx8mp-anatop" ); anatop_base =of_iomap (np,0 );
@@ -737,13 +728,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_hw_data); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (4 );return 0 ; }
drivers/clk/imx/clk-imx8mq.c +2 -16
@@ -273,20 +273,12 @@ static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "systatic struct clk_hw_onecell_data *clk_hw_data;static struct clk_hw **hws; -static const int uart_clk_ids[] = { -IMX8MQ_CLK_UART1_ROOT , -IMX8MQ_CLK_UART2_ROOT , -IMX8MQ_CLK_UART3_ROOT , -IMX8MQ_CLK_UART4_ROOT , -}; -static struct clk **uart_hws[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mq_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *base; -int err, i; +int err; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX8MQ_CLK_END ),GFP_KERNEL );
@@ -607,13 +599,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) goto unregister_hws; } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_hws[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_hws); +imx_register_uart_clocks (4 );return 0 ;
drivers/clk/imx/clk.c +32 -9
64 lines not on this page · raw message
drivers/clk/imx/clk.h +2 -2
@@ -11,9 +11,9 @@ extern spinlock_t imx_ccm_lock;void imx_check_clocks (struct clk *clks[],unsigned int count);void imx_check_clk_hws (struct clk_hw *clks[],unsigned int count);#ifndef MODULE -void imx_register_uart_clocks (struct clk **const clks[]); +void imx_register_uart_clocks (unsigned int clk_count);#else -static inline void imx_register_uart_clocks (struct clk **const clks[]) +static inline void imx_register_uart_clocks (unsigned int clk_count) { }#endif
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 343/601 power: supply: bq25980: Move props from battery node
In reply to Greg Kroah-HartmanFrom: Ricardo Rivera-Matos <[email protected]>
[ Upstream commit 04722cec1436c732d39153ce6ae2ebf71ac3ade7 ]
Currently POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT and POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE are exposed on the battery node and this is incorrect.
This patch exposes both of them on the charger node rather than the battery node.
--- drivers/power/supply/bq25980_charger.c | 40 ++++++++------------------ 1 file changed, 12 insertions(+), 28 deletions(-)
drivers/power/supply/bq25980_charger.c +12 -28
@@ -606,33 +606,6 @@ static int bq25980_get_state(struct bq25980_device *bq,return 0 ; } -static int bq25980_set_battery_property (struct power_supply *psy, -enum power_supply_property psp, -const union power_supply_propval *val) -{ -struct bq25980_device *bq =power_supply_get_drvdata (psy); -int ret =0 ; - -switch (psp) { -case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT : - ret =bq25980_set_const_charge_curr (bq, val->intval); -if (ret) -return ret; -break ; - -case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE : - ret =bq25980_set_const_charge_volt (bq, val->intval); -if (ret) -return ret; -break ; - -default : -return -EINVAL ; - } - -return ret; -} -static int bq25980_get_battery_property (struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val)
@@ -701,6 +674,18 @@ static int bq25980_set_charger_property(struct power_supply *psy,return ret;break ; +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT : + ret =bq25980_set_const_charge_curr (bq, val->intval); +if (ret) +return ret; +break ; + +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE : + ret =bq25980_set_const_charge_volt (bq, val->intval); +if (ret) +return ret; +break ; +default :return -EINVAL ; }
@@ -922,7 +907,6 @@ static struct power_supply_desc bq25980_battery_desc = { .name = "bq25980-battery", .type = POWER_SUPPLY_TYPE_BATTERY, .get_property = bq25980_get_battery_property, - .set_property = bq25980_set_battery_property, .properties = bq25980_battery_props, .num_properties = ARRAY_SIZE(bq25980_battery_props), .property_is_writeable = bq25980_property_is_writeable,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 344/601 nvme: retrigger ANA log update if group descriptor isnt found
In reply to Greg Kroah-HartmanFrom: Hannes Reinecke <[email protected]>
[ Upstream commit dd8f7fa908f66dd44abcd83cbb50410524b9f8ef ]
If ANA is enabled but no ANA group descriptor is found when creating a new namespace the ANA log is most likely out of date, so trigger a re-read. The namespace will be tagged with the NS_ANA_PENDING flag to exclude it from path selection until the ANA log has been re-read.
--- drivers/nvme/host/multipath.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/nvme/host/multipath.c +4 -0
@@ -668,6 +668,10 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)if (desc.state) {/* found the group desc: update */ nvme_update_ns_ana_state (&desc, ns); + }else { +/* group desc not found: trigger a re-read */ +set_bit (NVME_NS_ANA_PENDING , &ns->flags); +queue_work (nvme_wq, &ns->ctrl->ana_work); } }else { ns->ana_state =NVME_ANA_OPTIMIZED ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 345/601 media: ccs: Fix sub-device function
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
[ Upstream commit 8c43126e8c9f0990fa75fb5219c03b20d5ead7b7 ]
Fix sub-device function for the pixel array and the scaler.
It seems that the pixel array had gotten assigned as SCALER whereas the scaler had CAM_SENSOR function. Fix this by setting the pixel array function to CAM_SENSOR and that of scaler to SCALER.
--- drivers/media/i2c/ccs/ccs-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/i2c/ccs/ccs-core.c +2 -2
@@ -3290,11 +3290,11 @@ static int ccs_probe(struct i2c_client *client) sensor->pll.scale_n =CCS_LIM (sensor,SCALER_N_MIN );ccs_create_subdev (sensor, sensor->scaler," scaler" ,2 , -MEDIA_ENT_F_CAM_SENSOR ); +MEDIA_ENT_F_PROC_VIDEO_SCALER );ccs_create_subdev (sensor, sensor->binner," binner" ,2 ,MEDIA_ENT_F_PROC_VIDEO_SCALER );ccs_create_subdev (sensor, sensor->pixel_array," pixel_array" ,1 , -MEDIA_ENT_F_PROC_VIDEO_SCALER ); +MEDIA_ENT_F_CAM_SENSOR ); rval =ccs_init_controls (sensor);if (rval <0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 346/601 media: ipu3-cio2: Fix pixel-rate derived link frequency
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
[ Upstream commit a7de6eac6f6f73d48d97a6c93032107775f4593b ]
The driver uses v4l2_get_link_freq() helper to obtain the link frequency using the LINK_FREQ but also the PIXEL_RATE control. The divisor for the pixel rate derived link frequency was wrong, missing the bus uses double data rate. Fix this.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +1 -1
@@ -302,7 +302,7 @@ static int cio2_csi2_calc_timing(struct cio2_device *cio2, struct cio2_queue *q,if (!q->sensor)return -ENODEV ; - freq =v4l2_get_link_freq (q->sensor->ctrl_handler, bpp, lanes); + freq =v4l2_get_link_freq (q->sensor->ctrl_handler, bpp, lanes *2 );if (freq <0 ) {dev_err (dev,"error %lld, invalid link_freq\n" , freq);return freq;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 347/601 media: i2c: imx219: Move out locking/unlocking of vflip and hflip controls from imx219_set_stream
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit 745d4612d2c853c00abadbf69799c8aee7f99c39 ]
Move out locking/unlocking of vflip and hflip controls from imx219_set_stream() to the imx219_start_streaming()/ imx219_stop_streaming() respectively.
This fixes an issue in resume callback error path where streaming is stopped and the controls are left in locked state.
--- drivers/media/i2c/imx219.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/media/i2c/imx219.c +13 -6
@@ -1045,8 +1045,16 @@ static int imx219_start_streaming(struct imx219 *imx219)return ret;/* set stream on register */ -return imx219_write_reg (imx219,IMX219_REG_MODE_SELECT , -IMX219_REG_VALUE_08BIT ,IMX219_MODE_STREAMING ); + ret =imx219_write_reg (imx219,IMX219_REG_MODE_SELECT , +IMX219_REG_VALUE_08BIT ,IMX219_MODE_STREAMING ); +if (ret) +return ret; + +/* vflip and hflip cannot change during streaming */ +__v4l2_ctrl_grab (imx219->vflip, true); +__v4l2_ctrl_grab (imx219->hflip, true); + +return 0 ; }static void imx219_stop_streaming (struct imx219 *imx219)
@@ -1059,6 +1067,9 @@ static void imx219_stop_streaming(struct imx219 *imx219) IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);if (ret)dev_err (&client->dev,"%s failed to set stream\n" , __func__); + +__v4l2_ctrl_grab (imx219->vflip, false); +__v4l2_ctrl_grab (imx219->hflip, false); }static int imx219_set_stream (struct v4l2_subdev *sd,int enable)
@@ -1094,10 +1105,6 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) imx219->streaming = enable; -/* vflip and hflip cannot change during streaming */ -__v4l2_ctrl_grab (imx219->vflip, enable); -__v4l2_ctrl_grab (imx219->hflip, enable); -mutex_unlock (&imx219->mutex);return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 348/601 media: i2c: imx219: Balance runtime PM use-count
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit dd90caa0111e178b52b21e56364bc2244a3973b3 ]
Move incrementing/decrementing runtime PM count to imx219_start_streaming()/imx219_stop_streaming() functions respectively.
This fixes an issue of unbalanced runtime PM count in resume callback error path where streaming is stopped and runtime PM count is left unbalanced.
--- drivers/media/i2c/imx219.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
drivers/media/i2c/imx219.c +17 -15
@@ -1024,37 +1024,47 @@ static int imx219_start_streaming(struct imx219 *imx219)const struct imx219_reg_list *reg_list;int ret; + ret =pm_runtime_get_sync (&client->dev); +if (ret <0 ) { +pm_runtime_put_noidle (&client->dev); +return ret; + } +/* Apply default values of current mode */ reg_list = &imx219->mode->reg_list; ret =imx219_write_regs (imx219, reg_list->regs, reg_list->num_of_regs);if (ret) {dev_err (&client->dev,"%s failed to set mode\n" , __func__); -return ret; + goto err_rpm_put; } ret =imx219_set_framefmt (imx219);if (ret) {dev_err (&client->dev,"%s failed to set frame format: %d\n" , __func__, ret); -return ret; + goto err_rpm_put; }/* Apply customized values from user */ ret =__v4l2_ctrl_handler_setup (imx219->sd.ctrl_handler);if (ret) -return ret; + goto err_rpm_put;/* set stream on register */ ret =imx219_write_reg (imx219,IMX219_REG_MODE_SELECT ,IMX219_REG_VALUE_08BIT ,IMX219_MODE_STREAMING );if (ret) -return ret; + goto err_rpm_put;/* vflip and hflip cannot change during streaming */ __v4l2_ctrl_grab (imx219->vflip, true);__v4l2_ctrl_grab (imx219->hflip, true);return 0 ; + +err_rpm_put: +pm_runtime_put (&client->dev); +return ret; }static void imx219_stop_streaming (struct imx219 *imx219)
@@ -1070,12 +1080,13 @@ static void imx219_stop_streaming(struct imx219 *imx219)__v4l2_ctrl_grab (imx219->vflip, false);__v4l2_ctrl_grab (imx219->hflip, false); + +pm_runtime_put (&client->dev); }static int imx219_set_stream (struct v4l2_subdev *sd,int enable) {struct imx219 *imx219 =to_imx219 (sd); -struct i2c_client *client =v4l2_get_subdevdata (sd);int ret =0 ;mutex_lock (&imx219->mutex);
@@ -1085,22 +1096,15 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) }if (enable) { - ret =pm_runtime_get_sync (&client->dev); -if (ret <0 ) { -pm_runtime_put_noidle (&client->dev); - goto err_unlock; - } -/* * Apply default & customized values * and then start streaming. */ ret =imx219_start_streaming (imx219);if (ret) - goto err_rpm_put; + goto err_unlock; }else {imx219_stop_streaming (imx219); -pm_runtime_put (&client->dev); } imx219->streaming = enable;
@@ -1109,8 +1113,6 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable)return ret; -err_rpm_put: -pm_runtime_put (&client->dev); err_unlock:mutex_unlock (&imx219->mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 349/601 media: v4l2-ctrls.c: fix race condition in hdl->requests list
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
[ Upstream commit be7e8af98f3af729aa9f08b1053f9533a5cceb91 ]
When a request is re-inited it will release all control handler objects that are still in the request. It does that by unbinding and putting all those objects. When the object is unbound the obj->req pointer is set to NULL, and the object's unbind op is called. When the object it put the object's release op is called to free the memory.
For a request object that contains a control handler that means that v4l2_ctrl_handler_free() is called in the release op.
A control handler used in a request has a pointer to the main control handler that is created by the driver and contains the current state of all controls. If the device is unbound (due to rmmod or a forced unbind), then that main handler is freed, again by calling v4l2_ctrl_handler_free(), and any outstanding request objects that refer to that main handler have to be unbound and put as well.
It does that by this test:
if (!hdl->req_obj.req && !list_empty(&hdl->requests)) {I.e. the handler has no pointer to a request, so is the main handler, and one or more request objects refer to this main handler.
However, this test is wrong since hdl->req_obj.req is actually NULL when re-initing a request (the object unbind will set req to NULL), and the only reason this seemingly worked is that the requests list is typically empty since the request's unbind op will remove the handler from the requests list.
But if another thread is at the same time adding a new control to a request, then there is a race condition where one thread is removing a control handler object from the requests list and another thread is adding one. The result is that hdl->requests is no longer empty and the code thinks that a main handler is being freed instead of a control handler that is part of a request.
There are two bugs here: first the test for hdl->req_obj.req: this should be hdl->req_obj.ops since only the main control handler will have a NULL pointer there.
The second is that adding or deleting request objects from the requests list of the main handler isn't protected by taking the main handler's lock.
--- drivers/media/v4l2-core/v4l2-ctrls.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/media/v4l2-core/v4l2-ctrls.c +14 -3
@@ -2536,7 +2536,15 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)if (hdl ==NULL || hdl->buckets ==NULL )return ; -if (!hdl->req_obj.req && !list_empty (&hdl->requests)) { +/* +* If the main handler is freed and it is used by handler objects in +* outstanding requests, then unbind and put those objects before +* freeing the main handler. +* +* The main handler can be identified by having a NULL ops pointer in +* the request object. +*/ +if (!hdl->req_obj.ops && !list_empty (&hdl->requests)) {struct v4l2_ctrl_handler *req, *next_req;list_for_each_entry_safe (req, next_req, &hdl->requests, requests) {
@@ -3579,8 +3587,8 @@ static void v4l2_ctrl_request_unbind(struct media_request_object *obj) container_of(obj, struct v4l2_ctrl_handler, req_obj);struct v4l2_ctrl_handler *main_hdl = obj->priv; -list_del_init (&hdl->requests);mutex_lock (main_hdl->lock); +list_del_init (&hdl->requests);if (hdl->request_is_queued) {list_del_init (&hdl->requests_queued); hdl->request_is_queued = false;
@@ -3639,8 +3647,11 @@ static int v4l2_ctrl_request_bind(struct media_request *req,if (!ret) { ret =media_request_object_bind (req, &req_ops, from, false, &hdl->req_obj); -if (!ret) +if (!ret) { +mutex_lock (from->lock);list_add_tail (&hdl->requests, &from->requests); +mutex_unlock (from->lock); + } }return ret; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 350/601 media: rkvdec: Do not require all controls to be present in every request
In reply to Greg Kroah-HartmanFrom: Daniel Almeida <[email protected]>
[ Upstream commit 54676d5f5630b79f7b00c7c43882a58c1815aaf9 ]
According to the v4l2 api, it is allowed to skip
setting a control if its contents haven't changed for performance
reasons: userspace should only update the controls that changed from last frame rather then updating them all. Still some ancient code that checks for mandatory controls has been left in this driver.
Remove it.
--- drivers/staging/media/rkvdec/rkvdec.c | 48 +-------------------------- drivers/staging/media/rkvdec/rkvdec.h | 1 - 2 files changed, 1 insertion(+), 48 deletions(-)
drivers/staging/media/rkvdec/rkvdec.c +1 -47
@@ -55,16 +55,13 @@ static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = {static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { { - .mandatory = true, .cfg.id =V4L2_CID_STATELESS_H264_DECODE_PARAMS , }, { - .mandatory = true, .cfg.id =V4L2_CID_STATELESS_H264_SPS , .cfg.ops = &rkvdec_ctrl_ops, }, { - .mandatory = true, .cfg.id =V4L2_CID_STATELESS_H264_PPS , }, {
@@ -585,25 +582,7 @@ static const struct vb2_ops rkvdec_queue_ops = {static int rkvdec_request_validate (struct media_request *req) { -struct media_request_object *obj; -const struct rkvdec_ctrls *ctrls; -struct v4l2_ctrl_handler *hdl; -struct rkvdec_ctx *ctx =NULL ; -unsigned int count, i; -int ret; - -list_for_each_entry (obj, &req->objects, list) { -if (vb2_request_object_is_buffer (obj)) { -struct vb2_buffer *vb; - - vb = container_of(obj, struct vb2_buffer, req_obj); - ctx =vb2_get_drv_priv (vb->vb2_queue); -break ; - } - } - -if (!ctx) -return -EINVAL ; +unsigned int count; count =vb2_request_buffer_cnt (req);if (!count)
@@ -611,31 +590,6 @@ static int rkvdec_request_validate(struct media_request *req)else if (count >1 )return -EINVAL ; - hdl =v4l2_ctrl_request_hdl_find (req, &ctx->ctrl_hdl); -if (!hdl) -return -ENOENT ; - - ret =0 ; - ctrls = ctx->coded_fmt_desc->ctrls; -for (i =0 ; ctrls && i < ctrls->num_ctrls; i++) { -u32 id = ctrls->ctrls[i].cfg.id; -struct v4l2_ctrl *ctrl; - -if (!ctrls->ctrls[i].mandatory) -continue ; - - ctrl =v4l2_ctrl_request_hdl_ctrl_find (hdl, id); -if (!ctrl) { - ret = -ENOENT ; -break ; - } - } - -v4l2_ctrl_request_hdl_put (hdl); - -if (ret) -return ret; -return vb2_request_validate (req); }
drivers/staging/media/rkvdec/rkvdec.h +0 -1
@@ -25,7 +25,6 @@struct rkvdec_ctx ;struct rkvdec_ctrl_desc { -u32 mandatory :1 ;struct v4l2_ctrl_config cfg; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 351/601 vfio/fsl-mc: Re-order vfio_fsl_mc_probe()
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 2b1fe162e584a88ec7f12a651a2a50f94dd8cfac ]
vfio_add_group_dev() must be called only after all of the private data in vdev is fully setup and ready, otherwise there could be races with user space instantiating a device file descriptor and starting to call ops.
For instance vfio_fsl_mc_reflck_attach() sets vdev->reflck and vfio_fsl_mc_open(), called by fops open, unconditionally derefs it, which will crash if things get out of order.
This driver started life with the right sequence, but two commits added stuff after vfio_add_group_dev().
Message-Id: <[email protected]>
--- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 74 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 27 deletions(-)
drivers/vfio/fsl-mc/vfio_fsl_mc.c +47 -27
@@ -568,23 +568,39 @@ static int vfio_fsl_mc_init_device(struct vfio_fsl_mc_device *vdev)dev_err (&mc_dev->dev,"VFIO_FSL_MC: Failed to setup DPRC (%d)\n" , ret); goto out_nc_unreg; } +return 0 ; + +out_nc_unreg: +bus_unregister_notifier (&fsl_mc_bus_type, &vdev->nb); +return ret; +} +static int vfio_fsl_mc_scan_container (struct fsl_mc_device *mc_dev) +{ +int ret; + +/* non dprc devices do not scan for other devices */ +if (!is_fsl_mc_bus_dprc (mc_dev)) +return 0 ; ret =dprc_scan_container (mc_dev, false);if (ret) { -dev_err (&mc_dev->dev,"VFIO_FSL_MC: Container scanning failed (%d)\n" , ret); - goto out_dprc_cleanup; +dev_err (&mc_dev->dev, +"VFIO_FSL_MC: Container scanning failed (%d)\n" , ret); +dprc_remove_devices (mc_dev,NULL ,0 ); +return ret; } -return 0 ; +} + +static void vfio_fsl_uninit_device (struct vfio_fsl_mc_device *vdev) +{ +struct fsl_mc_device *mc_dev = vdev->mc_dev; + +if (!is_fsl_mc_bus_dprc (mc_dev)) +return ; -out_dprc_cleanup: -dprc_remove_devices (mc_dev,NULL ,0 );dprc_cleanup (mc_dev); -out_nc_unreg:bus_unregister_notifier (&fsl_mc_bus_type, &vdev->nb); - vdev->nb.notifier_call =NULL ; - -return ret; }static int vfio_fsl_mc_probe (struct fsl_mc_device *mc_dev)
@@ -607,29 +623,39 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) } vdev->mc_dev = mc_dev; - - ret =vfio_add_group_dev (dev, &vfio_fsl_mc_ops, vdev); -if (ret) { -dev_err (dev,"VFIO_FSL_MC: Failed to add to vfio group\n" ); - goto out_group_put; - } +mutex_init (&vdev->igate); ret =vfio_fsl_mc_reflck_attach (vdev);if (ret) - goto out_group_dev; + goto out_group_put; ret =vfio_fsl_mc_init_device (vdev);if (ret) goto out_reflck; -mutex_init (&vdev->igate); + ret =vfio_add_group_dev (dev, &vfio_fsl_mc_ops, vdev); +if (ret) { +dev_err (dev,"VFIO_FSL_MC: Failed to add to vfio group\n" ); + goto out_device; + } +/* +* This triggers recursion into vfio_fsl_mc_probe() on another device +* and the vfio_fsl_mc_reflck_attach() must succeed, which relies on the +* vfio_add_group_dev() above. It has no impact on this vdev, so it is +* safe to be after the vfio device is made live. +*/ + ret =vfio_fsl_mc_scan_container (mc_dev); +if (ret) + goto out_group_dev;return 0 ; -out_reflck: -vfio_fsl_mc_reflck_put (vdev->reflck); out_group_dev:vfio_del_group_dev (dev); +out_device: +vfio_fsl_uninit_device (vdev); +out_reflck: +vfio_fsl_mc_reflck_put (vdev->reflck); out_group_put:vfio_iommu_group_put (group, dev);return ret;
@@ -646,16 +672,10 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)mutex_destroy (&vdev->igate); +dprc_remove_devices (mc_dev,NULL ,0 ); +vfio_fsl_uninit_device (vdev);vfio_fsl_mc_reflck_put (vdev->reflck); -if (is_fsl_mc_bus_dprc (mc_dev)) { -dprc_remove_devices (mc_dev,NULL ,0 ); -dprc_cleanup (mc_dev); - } - -if (vdev->nb.notifier_call) -bus_unregister_notifier (&fsl_mc_bus_type, &vdev->nb); -vfio_iommu_group_put (mc_dev->dev.iommu_group, dev);return 0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 352/601 vfio/pci: Move VGA and VF initialization to functions
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 61e90817482871b614133c0f20feb1aba2faec86 ]
vfio_pci_probe() is quite complicated, with optional VF and VGA sub components. Move these into clear init/uninit functions and have a linear flow in probe/remove.
This fixes a few little buglets:
- vfio_pci_remove() is in the wrong order, vga_client_register() removes a notifier and is after kfree(vdev), but the notifier refers to vdev, so it can use after free in a race.
- vga_client_register() can fail but was ignored
Organize things so destruction order is the reverse of creation order.
Message-Id: <[email protected]>
--- drivers/vfio/pci/vfio_pci.c | 116 +++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 42 deletions(-)
drivers/vfio/pci/vfio_pci.c +74 -42
@@ -1926,6 +1926,68 @@ static int vfio_pci_bus_notifier(struct notifier_block *nb,return 0 ; } +static int vfio_pci_vf_init (struct vfio_pci_device *vdev) +{ +struct pci_dev *pdev = vdev->pdev; +int ret; + +if (!pdev->is_physfn) +return 0 ; + + vdev->vf_token =kzalloc (sizeof (*vdev->vf_token),GFP_KERNEL ); +if (!vdev->vf_token) +return -ENOMEM ; + +mutex_init (&vdev->vf_token->lock); +uuid_gen (&vdev->vf_token->uuid); + + vdev->nb.notifier_call = vfio_pci_bus_notifier; + ret =bus_register_notifier (&pci_bus_type, &vdev->nb); +if (ret) { +kfree (vdev->vf_token); +return ret; + } +return 0 ; +} + +static void vfio_pci_vf_uninit (struct vfio_pci_device *vdev) +{ +if (!vdev->vf_token) +return ; + +bus_unregister_notifier (&pci_bus_type, &vdev->nb); +WARN_ON (vdev->vf_token->users); +mutex_destroy (&vdev->vf_token->lock); +kfree (vdev->vf_token); +} + +static int vfio_pci_vga_init (struct vfio_pci_device *vdev) +{ +struct pci_dev *pdev = vdev->pdev; +int ret; + +if (!vfio_pci_is_vga (pdev)) +return 0 ; + + ret =vga_client_register (pdev, vdev,NULL , vfio_pci_set_vga_decode); +if (ret) +return ret; +vga_set_legacy_decoding (pdev,vfio_pci_set_vga_decode (vdev, false)); +return 0 ; +} + +static void vfio_pci_vga_uninit (struct vfio_pci_device *vdev) +{ +struct pci_dev *pdev = vdev->pdev; + +if (!vfio_pci_is_vga (pdev)) +return ; +vga_client_register (pdev,NULL ,NULL ,NULL ); +vga_set_legacy_decoding (pdev,VGA_RSRC_NORMAL_IO |VGA_RSRC_NORMAL_MEM | +VGA_RSRC_LEGACY_IO | +VGA_RSRC_LEGACY_MEM ); +} +static int vfio_pci_probe (struct pci_dev *pdev,const struct pci_device_id *id) {struct vfio_pci_device *vdev;
@@ -1979,28 +2041,12 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret =vfio_pci_reflck_attach (vdev);if (ret) goto out_del_group_dev; - -if (pdev->is_physfn) { - vdev->vf_token =kzalloc (sizeof (*vdev->vf_token),GFP_KERNEL ); -if (!vdev->vf_token) { - ret = -ENOMEM ; - goto out_reflck; - } - -mutex_init (&vdev->vf_token->lock); -uuid_gen (&vdev->vf_token->uuid); - - vdev->nb.notifier_call = vfio_pci_bus_notifier; - ret =bus_register_notifier (&pci_bus_type, &vdev->nb); -if (ret) - goto out_vf_token; - } - -if (vfio_pci_is_vga (pdev)) { -vga_client_register (pdev, vdev,NULL , vfio_pci_set_vga_decode); -vga_set_legacy_decoding (pdev, -vfio_pci_set_vga_decode (vdev, false)); - } + ret =vfio_pci_vf_init (vdev); +if (ret) + goto out_reflck; + ret =vfio_pci_vga_init (vdev); +if (ret) + goto out_vf;vfio_pci_probe_power_state (vdev);
@@ -2020,8 +2066,8 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)return ret; -out_vf_token: -kfree (vdev->vf_token); +out_vf: +vfio_pci_vf_uninit (vdev); out_reflck:vfio_pci_reflck_put (vdev->reflck); out_del_group_dev:
@@ -2043,33 +2089,19 @@ static void vfio_pci_remove(struct pci_dev *pdev)if (!vdev)return ; -if (vdev->vf_token) { -WARN_ON (vdev->vf_token->users); -mutex_destroy (&vdev->vf_token->lock); -kfree (vdev->vf_token); - } - -if (vdev->nb.notifier_call) -bus_unregister_notifier (&pci_bus_type, &vdev->nb); - +vfio_pci_vf_uninit (vdev);vfio_pci_reflck_put (vdev->reflck); +vfio_pci_vga_uninit (vdev);vfio_iommu_group_put (pdev->dev.iommu_group, &pdev->dev); -kfree (vdev->region); -mutex_destroy (&vdev->ioeventfds_lock);if (!disable_idle_d3)vfio_pci_set_power_state (vdev,PCI_D0 ); +mutex_destroy (&vdev->ioeventfds_lock); +kfree (vdev->region);kfree (vdev->pm_save);kfree (vdev); - -if (vfio_pci_is_vga (pdev)) { -vga_client_register (pdev,NULL ,NULL ,NULL ); -vga_set_legacy_decoding (pdev, -VGA_RSRC_NORMAL_IO |VGA_RSRC_NORMAL_MEM | -VGA_RSRC_LEGACY_IO |VGA_RSRC_LEGACY_MEM ); - } } static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 353/601 vfio/pci: Re-order vfio_pci_probe()
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 4aeec3984ddc853f7c65903bde472ffdef738bae ]
vfio_add_group_dev() must be called only after all of the private data in vdev is fully setup and ready, otherwise there could be races with user space instantiating a device file descriptor and starting to call ops.
For instance vfio_pci_reflck_attach() sets vdev->reflck and vfio_pci_open(), called by fops open, unconditionally derefs it, which will crash if things get out of order.
Message-Id: <[email protected]>
--- drivers/vfio/pci/vfio_pci.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/vfio/pci/vfio_pci.c +9 -8
@@ -2034,13 +2034,9 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)INIT_LIST_HEAD (&vdev->vma_list);init_rwsem (&vdev->memory_lock); - ret =vfio_add_group_dev (&pdev->dev, &vfio_pci_ops, vdev); -if (ret) - goto out_free; - ret =vfio_pci_reflck_attach (vdev);if (ret) - goto out_del_group_dev; + goto out_free; ret =vfio_pci_vf_init (vdev);if (ret) goto out_reflck;
@@ -2064,15 +2060,20 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)vfio_pci_set_power_state (vdev, PCI_D3hot); } -return ret; + ret =vfio_add_group_dev (&pdev->dev, &vfio_pci_ops, vdev); +if (ret) + goto out_power; +return 0 ; +out_power: +if (!disable_idle_d3) +vfio_pci_set_power_state (vdev,PCI_D0 ); out_vf:vfio_pci_vf_uninit (vdev); out_reflck:vfio_pci_reflck_put (vdev->reflck); -out_del_group_dev: -vfio_del_group_dev (&pdev->dev); out_free: +kfree (vdev->pm_save);kfree (vdev); out_group_put:vfio_iommu_group_put (group, &pdev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 354/601 drm/msm: Fix debugfs deadlock
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 6ed0897cd800c38b92a33d335d9086c7b092eb15 ]
In normal cases the gem obj lock is acquired first before mm_lock. The exception is iterating the various object lists. In the shrinker path, deadlock is avoided by using msm_gem_trylock() and skipping over objects that cannot be locked. But for debugfs the straightforward thing is to split things out into a separate list of all objects protected by it's own lock.
--- drivers/gpu/drm/msm/msm_debugfs.c | 14 +++----------- drivers/gpu/drm/msm/msm_drv.c | 3 +++ drivers/gpu/drm/msm/msm_drv.h | 9 ++++++++- drivers/gpu/drm/msm/msm_gem.c | 14 +++++++++++++- drivers/gpu/drm/msm/msm_gem.h | 12 ++++++++++-- 5 files changed, 37 insertions(+), 15 deletions(-)
drivers/gpu/drm/msm/msm_debugfs.c +3 -11
@@ -111,23 +111,15 @@ static const struct file_operations msm_gpu_fops = {static int msm_gem_show (struct drm_device *dev,struct seq_file *m) {struct msm_drm_private *priv = dev->dev_private; -struct msm_gpu *gpu = priv->gpu;int ret; - ret =mutex_lock_interruptible (&priv->mm_lock); + ret =mutex_lock_interruptible (&priv->obj_lock);if (ret)return ret; -if (gpu) { -seq_printf (m,"Active Objects (%s):\n" , gpu->name); -msm_gem_describe_objects (&gpu->active_list, m); - } - -seq_printf (m,"Inactive Objects:\n" ); -msm_gem_describe_objects (&priv->inactive_dontneed, m); -msm_gem_describe_objects (&priv->inactive_willneed, m); +msm_gem_describe_objects (&priv->objects, m); -mutex_unlock (&priv->mm_lock); +mutex_unlock (&priv->obj_lock);return 0 ; }
drivers/gpu/drm/msm/msm_drv.c +3 -0
@@ -446,6 +446,9 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) priv->wq =alloc_ordered_workqueue ("msm" ,0 ); +INIT_LIST_HEAD (&priv->objects); +mutex_init (&priv->obj_lock); +INIT_LIST_HEAD (&priv->inactive_willneed);INIT_LIST_HEAD (&priv->inactive_dontneed);mutex_init (&priv->mm_lock);
drivers/gpu/drm/msm/msm_drv.h +8 -1
@@ -174,7 +174,14 @@ struct msm_drm_private {struct msm_rd_state *hangrd;/* debugfs to dump hanging submits */ struct msm_perf_state *perf; -/* +/** +* List of all GEM objects (mainly for debugfs, protected by obj_lock +* (acquire before per GEM object lock) +*/ +struct list_head objects; +struct mutex obj_lock; + +/** * Lists of inactive GEM objects. Every bo is either in one of the * inactive lists (depending on whether or not it is shrinkable) or * gpu->active_list (for the gpu it is active on[1])
drivers/gpu/drm/msm/msm_gem.c +13 -1
@@ -951,7 +951,7 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m)size_t size =0 ;seq_puts (m," flags id ref offset kaddr size madv name\n" ); -list_for_each_entry (msm_obj, list, mm_list) { +list_for_each_entry (msm_obj, list, node) {struct drm_gem_object *obj = &msm_obj->base;seq_puts (m," " );msm_gem_describe (obj, m);
@@ -970,6 +970,10 @@ void msm_gem_free_object(struct drm_gem_object *obj)struct drm_device *dev = obj->dev;struct msm_drm_private *priv = dev->dev_private; +mutex_lock (&priv->obj_lock); +list_del (&msm_obj->node); +mutex_unlock (&priv->obj_lock); +mutex_lock (&priv->mm_lock);list_del (&msm_obj->mm_list);mutex_unlock (&priv->mm_lock);
@@ -1158,6 +1162,10 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev,list_add_tail (&msm_obj->mm_list, &priv->inactive_willneed);mutex_unlock (&priv->mm_lock); +mutex_lock (&priv->obj_lock); +list_add_tail (&msm_obj->node, &priv->objects); +mutex_unlock (&priv->obj_lock); +return obj; fail:
@@ -1228,6 +1236,10 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,list_add_tail (&msm_obj->mm_list, &priv->inactive_willneed);mutex_unlock (&priv->mm_lock); +mutex_lock (&priv->obj_lock); +list_add_tail (&msm_obj->node, &priv->objects); +mutex_unlock (&priv->obj_lock); +return obj; fail:
drivers/gpu/drm/msm/msm_gem.h +10 -2
@@ -55,8 +55,16 @@ struct msm_gem_object {*/ uint8_t vmap_count; -/* And object is either: -* inactive - on priv->inactive_list +/** +* Node in list of all objects (mainly for debugfs, protected by +* priv->obj_lock +*/ +struct list_head node; + +/** +* An object is either: +* inactive - on priv->inactive_dontneed or priv->inactive_willneed +* (depending on purgability status) * active - on one one of the gpu's active_list.. well, at * least for now we don't have (I don't think) hw sync between * 2d and 3d one devices which have both, meaning we need to
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 355/601 vfio/mdev: Do not allow a mdev_type to have a NULL parent pointer
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit b5a1f8921d5040bb788492bf33a66758021e4be5 ]
There is a small race where the parent is NULL even though the kobj has already been made visible in sysfs.
For instance the attribute_group is made visible in sysfs_create_files() and the mdev_type_attr_show() does:
ret = attr->show(kobj, type->parent->dev, buf);
Which will crash on NULL parent. Move the parent setup to before the type pointer leaves the stack frame.
Message-Id: <[email protected]>
--- drivers/vfio/mdev/mdev_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vfio/mdev/mdev_sysfs.c +1 -1
@@ -105,6 +105,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,return ERR_PTR (-ENOMEM ); type->kobj.kset = parent->mdev_types_kset; + type->parent = parent; ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL, "%s-%s", dev_driver_string(parent->dev),
@@ -132,7 +133,6 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent, } type->group = group; - type->parent = parent;return type; attrs_failed:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 356/601 clk: zynqmp: move zynqmp_pll_set_mode out of round_rate callback
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit d7fd3f9f53df8bb2212dff70f66f12cae0e1a653 ]
The round_rate callback should only perform rate calculation and not involve calling zynqmp_pll_set_mode to change the pll mode. So let's move zynqmp_pll_set_mode out of round_rate and to set_rate callback.
--- drivers/clk/zynqmp/pll.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/clk/zynqmp/pll.c +6 -6
@@ -100,9 +100,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,/* Enable the fractional mode if needed */ rate_div = (rate *FRAC_DIV ) / *prate; f = rate_div %FRAC_DIV ; -zynqmp_pll_set_mode (hw, !!f); - -if (zynqmp_pll_get_mode (hw) ==PLL_MODE_FRAC ) { +if (f) {if (rate >PS_PLL_VCO_MAX ) { fbdiv = rate /PS_PLL_VCO_MAX ; rate = rate / (fbdiv +1 );
@@ -173,10 +171,12 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,long rate_div, frac, m, f;int ret; -if (zynqmp_pll_get_mode (hw) ==PLL_MODE_FRAC ) { - rate_div = (rate *FRAC_DIV ) / parent_rate; + rate_div = (rate *FRAC_DIV ) / parent_rate; + f = rate_div %FRAC_DIV ; +zynqmp_pll_set_mode (hw, !!f); + +if (f) { m = rate_div /FRAC_DIV ; - f = rate_div %FRAC_DIV ; m =clamp_t (u32, m, (PLL_FBDIV_MIN ), (PLL_FBDIV_MAX )); rate = parent_rate * m; frac = (parent_rate * f) /FRAC_DIV ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 357/601 clk: zynqmp: pll: add set_pll_mode to check condition in zynqmp_pll_enable
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 394cdb69a3c30b33524cf1204afe5cceaba69cdc ]
If there is a IOCTL_SET_PLL_FRAC_MODE request sent to ATF ever, we shouldn't skip invoking PM_CLOCK_ENABLE fn even though this pll has been enabled. In ATF implementation, it will only assign the mode to the variable (struct pm_pll *)pll->mode when handling IOCTL_SET_PLL_FRAC_MODE call. Invoking PM_CLOCK_ENABLE can force ATF send request to PWU to set the pll mode to PLL's register.
There is a scenario that happens in enabling VPLL_INT(clk_id:96):
1) VPLL_INT has been enabled during booting.
2) A driver calls clk_set_rate and according to the rate, the VPLL_INT should be set to FRAC mode. Then zynqmp_pll_set_mode is called to pass IOCTL_SET_PLL_FRAC_MODE to ATF. Note that at this point ATF just stores the mode to a variable.
3) This driver calls clk_prepare_enable and zynqmp_pll_enable is called to try to enable VPLL_INT pll. Because of 1), the function zynqmp_pll_enable just returns without doing anything after checking that this pll has been enabled.
In the scenario above, the pll mode of VPLL_INT will never be set successfully. So adding set_pll_mode to check condition to fix it.
--- drivers/clk/zynqmp/pll.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/clk/zynqmp/pll.c +11 -1
@@ -14,10 +14,12 @@* struct zynqmp_pll - PLL clock * @hw: Handle between common and hardware-specific interfaces * @clk_id: PLL clock ID +* @set_pll_mode: Whether an IOCTL_SET_PLL_FRAC_MODE request be sent to ATF */ struct zynqmp_pll {struct clk_hw hw;u32 clk_id; +bool set_pll_mode; };#define to_zynqmp_pll (_hw) container_of(_hw, struct zynqmp_pll, hw)
@@ -81,6 +83,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)if (ret)pr_warn_once ("%s() PLL set frac mode failed for %s, ret = %d\n" , __func__, clk_name, ret); +else + clk->set_pll_mode = true; }/**
@@ -240,9 +244,15 @@ static int zynqmp_pll_enable(struct clk_hw *hw)u32 clk_id = clk->clk_id;int ret; -if (zynqmp_pll_is_enabled (hw)) +/* +* Don't skip enabling clock if there is an IOCTL_SET_PLL_FRAC_MODE request +* that has been sent to ATF. +*/ +if (zynqmp_pll_is_enabled (hw) && (!clk->set_pll_mode))return 0 ; + clk->set_pll_mode = false; + ret =zynqmp_pm_clock_enable (clk_id);if (ret) pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 358/601 drm: xlnx: zynqmp: fix a memset in zynqmp_dp_train()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5842ab76bbfadb37eaea91e53c1efe34ae504e4a ]
The dp->train_set[] for this driver is only two characters, not four so this memsets too much. Fortunately, this ends up corrupting a struct hole and not anything important.
--- drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/xlnx/zynqmp_dp.c +1 -1
@@ -866,7 +866,7 @@ static int zynqmp_dp_train(struct zynqmp_dp *dp)return ret;zynqmp_dp_write (dp,ZYNQMP_DP_SCRAMBLING_DISABLE ,1 ); -memset (dp->train_set,0 ,4 ); +memset (dp->train_set,0 ,sizeof (dp->train_set)); ret =zynqmp_dp_link_train_cr (dp);if (ret)return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 359/601 clk: qcom: a53-pll: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-HartmanFrom: Chen Hui <[email protected]>
[ Upstream commit 790b516ada10a4dcc0f0a56dc0ced475d86d5820 ]
CONFIG_QCOM_A53PLL is tristate option and therefore this driver can be compiled as a module. This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module.
--- drivers/clk/qcom/a53-pll.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/a53-pll.c +1 -0
@@ -93,6 +93,7 @@ static const struct of_device_id qcom_a53pll_match_table[] = { { .compatible = "qcom,msm8916-a53pll" }, { } }; +MODULE_DEVICE_TABLE (of, qcom_a53pll_match_table);static struct platform_driver qcom_a53pll_driver = { .probe = qcom_a53pll_probe,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 360/601 clk: qcom: apss-ipq-pll: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-HartmanFrom: Chen Hui <[email protected]>
[ Upstream commit d0a859edda46b45baeab9687d173102300d76e2b ]
CONFIG_IPQ_APSS_PLL is tristate option and therefore this driver can be compiled as a module. This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module.
--- drivers/clk/qcom/apss-ipq-pll.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/apss-ipq-pll.c +1 -0
@@ -81,6 +81,7 @@ static const struct of_device_id apss_ipq_pll_match_table[] = { { .compatible = "qcom,ipq6018-a53pll" }, { } }; +MODULE_DEVICE_TABLE (of, apss_ipq_pll_match_table);static struct platform_driver apss_ipq_pll_driver = { .probe = apss_ipq_pll_probe,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 361/601 drm/amd/display: use GFP_ATOMIC in dcn20_resource_construct
In reply to Greg Kroah-HartmanFrom: Nirmoy Das <[email protected]>
[ Upstream commit 3bb1105071fb974e3e3ca2f92ddfd69c81285ab6 ]
Replace GFP_KERNEL with GFP_ATOMIC as dcn20_resource_construct() can't sleep.
Partially fixes: https://bugzilla.kernel.org/show_bug.cgi?id=212311
as dcn20_resource_construct() also calls into SMU functions which does mutex_lock().
--- drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 6 ++--- .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c | 2 +- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 26 +++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-)
drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +1 -1
@@ -283,7 +283,7 @@ struct abm *dce_abm_create(const struct dce_abm_shift *abm_shift, const struct dce_abm_mask *abm_mask) { - struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); + struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_ATOMIC);if (abm_dce ==NULL ) {BREAK_TO_DEBUGGER ();
drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +3 -3
@@ -925,7 +925,7 @@ struct dmcu *dcn10_dmcu_create(const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);if (dmcu_dce ==NULL ) {BREAK_TO_DEBUGGER ();
@@ -946,7 +946,7 @@ struct dmcu *dcn20_dmcu_create(const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);if (dmcu_dce ==NULL ) {BREAK_TO_DEBUGGER ();
@@ -967,7 +967,7 @@ struct dmcu *dcn21_dmcu_create(const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);if (dmcu_dce ==NULL ) {BREAK_TO_DEBUGGER ();
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c +1 -1
@@ -112,7 +112,7 @@ struct dccg *dccg2_create(const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_ATOMIC);struct dccg *base;if (dccg_dcn ==NULL ) {
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +13 -13
@@ -1104,7 +1104,7 @@ struct dpp *dcn20_dpp_create( uint32_t inst) {struct dcn20_dpp *dpp = -kzalloc (sizeof (struct dcn20_dpp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_dpp ),GFP_ATOMIC );if (!dpp)return NULL ;
@@ -1122,7 +1122,7 @@ struct input_pixel_processor *dcn20_ipp_create( struct dc_context *ctx, uint32_t inst) {struct dcn10_ipp *ipp = -kzalloc (sizeof (struct dcn10_ipp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn10_ipp ),GFP_ATOMIC );if (!ipp) {BREAK_TO_DEBUGGER ();
@@ -1139,7 +1139,7 @@ struct output_pixel_processor *dcn20_opp_create( struct dc_context *ctx, uint32_t inst) {struct dcn20_opp *opp = -kzalloc (sizeof (struct dcn20_opp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_opp ),GFP_ATOMIC );if (!opp) {BREAK_TO_DEBUGGER ();
@@ -1156,7 +1156,7 @@ struct dce_aux *dcn20_aux_engine_create( uint32_t inst) {struct aux_engine_dce110 *aux_engine = -kzalloc (sizeof (struct aux_engine_dce110 ),GFP_KERNEL ); +kzalloc (sizeof (struct aux_engine_dce110 ),GFP_ATOMIC );if (!aux_engine)return NULL ;
@@ -1194,7 +1194,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create( uint32_t inst) {struct dce_i2c_hw *dce_i2c_hw = -kzalloc (sizeof (struct dce_i2c_hw ),GFP_KERNEL ); +kzalloc (sizeof (struct dce_i2c_hw ),GFP_ATOMIC );if (!dce_i2c_hw)return NULL ;
@@ -1207,7 +1207,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create(struct mpc *dcn20_mpc_create (struct dc_context *ctx) {struct dcn20_mpc *mpc20 =kzalloc (sizeof (struct dcn20_mpc ), -GFP_KERNEL ); +GFP_ATOMIC );if (!mpc20)return NULL ;
@@ -1225,7 +1225,7 @@ struct hubbub *dcn20_hubbub_create(struct dc_context *ctx) {int i;struct dcn20_hubbub *hubbub =kzalloc (sizeof (struct dcn20_hubbub ), -GFP_KERNEL ); +GFP_ATOMIC );if (!hubbub)return NULL ;
@@ -1253,7 +1253,7 @@ struct timing_generator *dcn20_timing_generator_create( uint32_t instance) {struct optc *tgn10 = -kzalloc (sizeof (struct optc ),GFP_KERNEL ); +kzalloc (sizeof (struct optc ),GFP_ATOMIC );if (!tgn10)return NULL ;
@@ -1332,7 +1332,7 @@ static struct clock_source *dcn20_clock_source_create( bool dp_clk_src) {struct dce110_clk_src *clk_src = -kzalloc (sizeof (struct dce110_clk_src ),GFP_KERNEL ); +kzalloc (sizeof (struct dce110_clk_src ),GFP_ATOMIC );if (!clk_src)return NULL ;
@@ -1438,7 +1438,7 @@ struct display_stream_compressor *dcn20_dsc_create( struct dc_context *ctx, uint32_t inst) {struct dcn20_dsc *dsc = -kzalloc (sizeof (struct dcn20_dsc ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_dsc ),GFP_ATOMIC );if (!dsc) {BREAK_TO_DEBUGGER ();
@@ -1572,7 +1572,7 @@ struct hubp *dcn20_hubp_create( uint32_t inst) {struct dcn20_hubp *hubp2 = -kzalloc (sizeof (struct dcn20_hubp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_hubp ),GFP_ATOMIC );if (!hubp2)return NULL ;
@@ -3388,7 +3388,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)static struct pp_smu_funcs *dcn20_pp_smu_create (struct dc_context *ctx) { -struct pp_smu_funcs *pp_smu =kzalloc (sizeof (*pp_smu),GFP_KERNEL ); +struct pp_smu_funcs *pp_smu =kzalloc (sizeof (*pp_smu),GFP_ATOMIC );if (!pp_smu)return pp_smu;
@@ -4142,7 +4142,7 @@ struct resource_pool *dcn20_create_resource_pool( struct dc *dc) {struct dcn20_resource_pool *pool = -kzalloc (sizeof (struct dcn20_resource_pool ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_resource_pool ),GFP_ATOMIC );if (!pool)return NULL ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 362/601 drm/amd/display: check fb of primary plane
In reply to Greg Kroah-HartmanFrom: Sefa Eyeoglu <[email protected]>
[ Upstream commit 7df4ceb60fa9a3c5160cfd5b696657291934a2c9 ]
Sometimes the primary plane might not be initialized (yet), which causes dm_check_crtc_cursor to divide by zero.
Apparently a weird state before a S3-suspend causes the aforementioned divide-by-zero error when resuming from S3. This was explained in bug 212293 on Bugzilla.
To avoid this divide-by-zero error we check if the primary plane's fb isn't NULL. If it's NULL the src_w and src_h attributes will be 0, which would cause a divide-by-zero.
This fixes Bugzilla report 212293
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -1
@@ -9119,7 +9119,8 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, new_cursor_state =drm_atomic_get_new_plane_state (state, crtc->cursor); new_primary_state =drm_atomic_get_new_plane_state (state, crtc->primary); -if (!new_cursor_state || !new_primary_state || !new_cursor_state->fb) { +if (!new_cursor_state || !new_primary_state || + !new_cursor_state->fb || !new_primary_state->fb) {return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 363/601 drm/radeon: Fix a missing check bug in radeon_dp_mst_detect()
In reply to Greg Kroah-HartmanFrom: Yingjie Wang <[email protected]>
[ Upstream commit 25315ebfaefcffd126a266116b37bb8a3d1c4620 ]
In radeon_dp_mst_detect(), We should check whether or not @connector has been unregistered from userspace. If the connector is unregistered, we should return disconnected status.
--- drivers/gpu/drm/radeon/radeon_dp_mst.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/radeon_dp_mst.c +3 -0
@@ -242,6 +242,9 @@ radeon_dp_mst_detect(struct drm_connector *connector,to_radeon_connector (connector);struct radeon_connector *master = radeon_connector->mst_port; +if (drm_connector_is_unregistered (connector)) +return connector_status_disconnected; +return drm_dp_mst_detect_port (connector, ctx, &master->mst_mgr, radeon_connector->port); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 364/601 clk: uniphier: Fix potential infinite loop
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit f6b1340dc751a6caa2a0567b667d0f4f4172cd58 ]
The for-loop iterates with a u8 loop counter i and compares this with the loop upper limit of num_parents that is an int type. There is a potential infinite loop if num_parents is larger than the u8 loop counter. Fix this by making the loop counter the same type as num_parents. Also make num_parents an unsigned int to match the return type of the call to clk_hw_get_num_parents.
Addresses-Coverity: ("Infinite loop")
--- drivers/clk/uniphier/clk-uniphier-mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/uniphier/clk-uniphier-mux.c +2 -2
@@ -31,10 +31,10 @@ static int uniphier_clk_mux_set_parent(struct clk_hw *hw, u8 index)static u8 uniphier_clk_mux_get_parent (struct clk_hw *hw) {struct uniphier_clk_mux *mux =to_uniphier_clk_mux (hw); -int num_parents =clk_hw_get_num_parents (hw); +unsigned int num_parents =clk_hw_get_num_parents (hw);int ret;unsigned int val; -u8 i; +unsigned int i; ret =regmap_read (mux->regmap, mux->reg, &val);if (ret)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 365/601 scsi: pm80xx: Increase timeout for pm80xx mpi_uninit_check()
In reply to Greg Kroah-HartmanFrom: Igor Pylypiv <[email protected]>
[ Upstream commit 3f744a14f331f56703a9d74e86520db045f11831 ]
The mpi_uninit_check() takes longer for inbound doorbell register to be cleared. Increase the timeout substantially so that the driver does not fail to load.
Previously, the inbound doorbell wait time was mistakenly increased in the mpi_init_check() instead of mpi_uninit_check(). It is okay to leave the mpi_init_check() wait time as-is as these are timeout values and if there is a failure, waiting longer is not an issue.
--- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/pm8001/pm80xx_hwi.c +2 -2
@@ -1489,9 +1489,9 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)/* wait until Inbound DoorBell Clear Register toggled */ if (IS_SPCV_12G (pm8001_ha->pdev)) { - max_wait_count =4 *1000 *1000 ;/* 4 sec */ + max_wait_count =30 *1000 *1000 ;/* 30 sec */ }else { - max_wait_count =2 *1000 *1000 ;/* 2 sec */ + max_wait_count =15 *1000 *1000 ;/* 15 sec */ } do { udelay(1);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 366/601 scsi: pm80xx: Fix potential infinite loop
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 40fa7394a1ad5706e795823276f2e394cca145d0 ]
The for-loop iterates with a u8 loop counter i and compares this with the loop upper limit of pm8001_ha->max_q_num which is a u32 type. There is a potential infinite loop if pm8001_ha->max_q_num is larger than the u8 loop counter. Fix this by making the loop counter the same type as pm8001_ha->max_q_num.
[mkp: this is purely theoretical, max_q_num is currently limited to 64]
Addresses-Coverity: ("Infinite loop")
--- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/pm8001/pm8001_hwi.c +1 -1
@@ -643,7 +643,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)*/ static int pm8001_chip_init (struct pm8001_hba_info *pm8001_ha) { -u8 i =0 ; +u32 i =0 ;u16 deviceid;pci_read_config_word (pm8001_ha->pdev,PCI_DEVICE_ID , &deviceid);/* 8081 controllers need BAR shift to access MPI space
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 367/601 scsi: ufs: ufshcd-pltfrm: Fix deferred probing
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 339c9b63cc7ce779ce45c675bf709cb58b807fc3 ]
The driver overrides the error codes returned by platform_get_irq() to -ENODEV, so if it returns -EPROBE_DEFER, the driver would fail the probe permanently instead of the deferred probing. Propagate the error code upstream as it should have been done from the start...
--- drivers/scsi/ufs/ufshcd-pltfrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/ufs/ufshcd-pltfrm.c +1 -1
@@ -377,7 +377,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, irq =platform_get_irq (pdev,0 );if (irq <0 ) { - err = -ENODEV ; + err = irq; goto out; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 368/601 scsi: hisi_sas: Fix IRQ checks
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 6c11dc060427e07ca144eacaccd696106b361b06 ]
Commit df2d8213d9e3 ("hisi_sas: use platform_get_irq()") failed to take into account that irq_of_parse_and_map() and platform_get_irq() have a different way of indicating an error: the former returns 0 and the latter returns a negative error code. Fix up the IRQ checks!
--- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +3 -3
@@ -1644,7 +1644,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = i *HISI_SAS_PHY_INT_NR ;for (j =0 ; j <HISI_SAS_PHY_INT_NR ; j++, idx++) { irq =platform_get_irq (pdev, idx); -if (!irq) { +if (irq <0 ) {dev_err (dev,"irq init: fail map phy interrupt %d\n" , idx);return -ENOENT ;
@@ -1663,7 +1663,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = hisi_hba->n_phy *HISI_SAS_PHY_INT_NR ;for (i =0 ; i < hisi_hba->queue_count; i++, idx++) { irq =platform_get_irq (pdev, idx); -if (!irq) { +if (irq <0 ) {dev_err (dev,"irq init: could not map cq interrupt %d\n" , idx);return -ENOENT ;
@@ -1681,7 +1681,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = (hisi_hba->n_phy *HISI_SAS_PHY_INT_NR ) + hisi_hba->queue_count;for (i =0 ; i <HISI_SAS_FATAL_INT_NR ; i++, idx++) { irq =platform_get_irq (pdev, idx); -if (!irq) { +if (irq <0 ) {dev_err (dev,"irq init: could not map fatal interrupt %d\n" , idx);return -ENOENT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 369/601 scsi: jazz_esp: Add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 38fca15c29db6ed06e894ac194502633e2a7d1fb ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding the real error code. Stop calling request_irq() with the invalid IRQ #s.
--- drivers/scsi/jazz_esp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/jazz_esp.c +3 -1
@@ -143,7 +143,9 @@ static int esp_jazz_probe(struct platform_device *dev)if (!esp->command_block) goto fail_unmap_regs; - host->irq =platform_get_irq (dev,0 ); + host->irq = err =platform_get_irq (dev,0 ); +if (err <0 ) + goto fail_unmap_command_block; err =request_irq (host->irq, scsi_esp_intr,IRQF_SHARED ,"ESP" , esp);if (err <0 ) goto fail_unmap_command_block;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 370/601 scsi: sun3x_esp: Add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 14b321380eb333c82853d7d612d0995f05f88fdc ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding the real error code. Stop calling request_irq() with the invalid IRQ #s.
--- drivers/scsi/sun3x_esp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/sun3x_esp.c +3 -1
@@ -206,7 +206,9 @@ static int esp_sun3x_probe(struct platform_device *dev)if (!esp->command_block) goto fail_unmap_regs_dma; - host->irq =platform_get_irq (dev,0 ); + host->irq = err =platform_get_irq (dev,0 ); +if (err <0 ) + goto fail_unmap_command_block; err =request_irq (host->irq, scsi_esp_intr,IRQF_SHARED ,"SUN3X ESP" , esp);if (err <0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 371/601 scsi: sni_53c710: Add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 1160d61bc51e87e509cfaf9da50a0060f67b6de4 ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #s), causing it to fail with -EINVAL (overridden by -ENODEV further below). Stop calling request_irq() with the invalid IRQ #s.
--- drivers/scsi/sni_53c710.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/scsi/sni_53c710.c +4 -1
@@ -58,6 +58,7 @@ static int snirm710_probe(struct platform_device *dev)struct NCR_700_Host_Parameters *hostdata;struct Scsi_Host *host;struct resource *res; +int rc; res =platform_get_resource (dev,IORESOURCE_MEM ,0 );if (!res)
@@ -83,7 +84,9 @@ static int snirm710_probe(struct platform_device *dev) goto out_kfree; host->this_id =7 ; host->base = base; - host->irq =platform_get_irq (dev,0 ); + host->irq = rc =platform_get_irq (dev,0 ); +if (rc <0 ) + goto out_put_host;if (request_irq (host->irq, NCR_700_intr,IRQF_SHARED ,"snirm710" , host)) {printk (KERN_ERR "snirm710: request_irq failed!\n" ); goto out_put_host;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 372/601 scsi: ibmvfc: Fix invalid state machine BUG_ON()
In reply to Greg Kroah-HartmanFrom: Brian King <[email protected]>
[ Upstream commit 15cfef8623a449d40d16541687afd58e78033be3 ]
This fixes an issue hitting the BUG_ON() in ibmvfc_do_work(). When going through a host action of IBMVFC_HOST_ACTION_RESET, we change the action to IBMVFC_HOST_ACTION_TGT_DEL, then drop the host lock, and reset the CRQ, which changes the host state to IBMVFC_NO_CRQ. If, prior to setting the host state to IBMVFC_NO_CRQ, ibmvfc_init_host() is called, it can then end up changing the host action to IBMVFC_HOST_ACTION_INIT. If we then change the host state to IBMVFC_NO_CRQ, we will then hit the BUG_ON().
Make a couple of changes to avoid this. Leave the host action to be IBMVFC_HOST_ACTION_RESET or IBMVFC_HOST_ACTION_REENABLE until after we drop the host lock and reset or reenable the CRQ. Also harden the host state machine to ensure we cannot leave the reset / reenable state until we've finished processing the reset or reenable.
--- drivers/scsi/ibmvscsi/ibmvfc.c | 57 ++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 19 deletions(-)
drivers/scsi/ibmvscsi/ibmvfc.c +38 -19
@@ -560,8 +560,17 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,if (vhost->action ==IBMVFC_HOST_ACTION_ALLOC_TGTS ) vhost->action = action;break ; +case IBMVFC_HOST_ACTION_REENABLE : +case IBMVFC_HOST_ACTION_RESET : + vhost->action = action; +break ;case IBMVFC_HOST_ACTION_INIT :case IBMVFC_HOST_ACTION_TGT_DEL : +case IBMVFC_HOST_ACTION_LOGO : +case IBMVFC_HOST_ACTION_QUERY_TGTS : +case IBMVFC_HOST_ACTION_TGT_DEL_FAILED : +case IBMVFC_HOST_ACTION_NONE : +default :switch (vhost->action) {case IBMVFC_HOST_ACTION_RESET :case IBMVFC_HOST_ACTION_REENABLE :
@@ -571,15 +580,6 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,break ; }break ; -case IBMVFC_HOST_ACTION_LOGO : -case IBMVFC_HOST_ACTION_QUERY_TGTS : -case IBMVFC_HOST_ACTION_TGT_DEL_FAILED : -case IBMVFC_HOST_ACTION_NONE : -case IBMVFC_HOST_ACTION_RESET : -case IBMVFC_HOST_ACTION_REENABLE : -default : - vhost->action = action; -break ; } }
@@ -4723,26 +4723,45 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)case IBMVFC_HOST_ACTION_INIT_WAIT :break ;case IBMVFC_HOST_ACTION_RESET : - vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ;spin_unlock_irqrestore (vhost->host->host_lock, flags); rc =ibmvfc_reset_crq (vhost); +spin_lock_irqsave (vhost->host->host_lock, flags); -if (rc ==H_CLOSED ) +if (!rc || rc ==H_CLOSED )vio_enable_interrupts (to_vio_dev (vhost->dev)); -if (rc || (rc =ibmvfc_send_crq_init (vhost)) || - (rc =vio_enable_interrupts (to_vio_dev (vhost->dev)))) { -ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); -dev_err (vhost->dev,"Error after reset (rc=%d)\n" , rc); +if (vhost->action ==IBMVFC_HOST_ACTION_RESET ) { +/* +* The only action we could have changed to would have +* been reenable, in which case, we skip the rest of +* this path and wait until we've done the re-enable +* before sending the crq init. +*/ + vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ; + +if (rc || (rc =ibmvfc_send_crq_init (vhost)) || + (rc =vio_enable_interrupts (to_vio_dev (vhost->dev)))) { +ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); +dev_err (vhost->dev,"Error after reset (rc=%d)\n" , rc); + } }break ;case IBMVFC_HOST_ACTION_REENABLE : - vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ;spin_unlock_irqrestore (vhost->host->host_lock, flags); rc =ibmvfc_reenable_crq_queue (vhost); +spin_lock_irqsave (vhost->host->host_lock, flags); -if (rc || (rc =ibmvfc_send_crq_init (vhost))) { -ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); -dev_err (vhost->dev,"Error after enable (rc=%d)\n" , rc); +if (vhost->action ==IBMVFC_HOST_ACTION_REENABLE ) { +/* +* The only action we could have changed to would have +* been reset, in which case, we skip the rest of this +* path and wait until we've done the reset before +* sending the crq init. +*/ + vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ; +if (rc || (rc =ibmvfc_send_crq_init (vhost))) { +ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); +dev_err (vhost->dev,"Error after enable (rc=%d)\n" , rc); + } }break ;case IBMVFC_HOST_ACTION_LOGO :
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 373/601 mailbox: sprd: Introduce refcnt when clients requests/free channels
In reply to Greg Kroah-HartmanFrom: Orson Zhai <[email protected]>
[ Upstream commit 9468ab84032f96496e998cfa173cd1d0ac316bcd ]
Unisoc mailbox has no way to be enabled/disabled for any single channel. They can only be set to startup or shutdown as a whole device at same time.
Add a variable to count references to avoid mailbox FIFO being reset unexpectedly when clients are requesting or freeing channels.
Also add a lock to dismiss possible conflicts from register r/w in different startup or shutdown threads. And fix the crash problem when early interrupts come from channel which has not been requested by client yet.
--- drivers/mailbox/sprd-mailbox.c | 43 +++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 14 deletions(-)
drivers/mailbox/sprd-mailbox.c +29 -14
@@ -60,6 +60,8 @@ struct sprd_mbox_priv {struct clk *clk;u32 outbox_fifo_depth; +struct mutex lock; +u32 refcnt;struct mbox_chan chan[SPRD_MBOX_CHAN_MAX ]; };
@@ -115,7 +117,11 @@ static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data) id =readl (priv->outbox_base +SPRD_MBOX_ID ); chan = &priv->chan[id]; -mbox_chan_received_data (chan, (void *)msg); +if (chan->cl) +mbox_chan_received_data (chan, (void *)msg); +else +dev_warn_ratelimited (priv->dev, +"message's been dropped at ch[%d]\n" , id);/* Trigger to update outbox FIFO pointer */ writel (0x1 , priv->outbox_base +SPRD_MBOX_TRIGGER );
@@ -215,18 +221,22 @@ static int sprd_mbox_startup(struct mbox_chan *chan)struct sprd_mbox_priv *priv =to_sprd_mbox_priv (chan->mbox);u32 val; -/* Select outbox FIFO mode and reset the outbox FIFO status */ -writel (0x0 , priv->outbox_base +SPRD_MBOX_FIFO_RST ); +mutex_lock (&priv->lock); +if (priv->refcnt++ ==0 ) { +/* Select outbox FIFO mode and reset the outbox FIFO status */ +writel (0x0 , priv->outbox_base +SPRD_MBOX_FIFO_RST ); -/* Enable inbox FIFO overflow and delivery interrupt */ - val =readl (priv->inbox_base +SPRD_MBOX_IRQ_MSK ); - val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ |SPRD_INBOX_FIFO_DELIVER_IRQ ); -writel (val, priv->inbox_base +SPRD_MBOX_IRQ_MSK ); +/* Enable inbox FIFO overflow and delivery interrupt */ + val =readl (priv->inbox_base +SPRD_MBOX_IRQ_MSK ); + val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ |SPRD_INBOX_FIFO_DELIVER_IRQ ); +writel (val, priv->inbox_base +SPRD_MBOX_IRQ_MSK ); -/* Enable outbox FIFO not empty interrupt */ - val =readl (priv->outbox_base +SPRD_MBOX_IRQ_MSK ); - val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ ; -writel (val, priv->outbox_base +SPRD_MBOX_IRQ_MSK ); +/* Enable outbox FIFO not empty interrupt */ + val =readl (priv->outbox_base +SPRD_MBOX_IRQ_MSK ); + val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ ; +writel (val, priv->outbox_base +SPRD_MBOX_IRQ_MSK ); + } +mutex_unlock (&priv->lock);return 0 ; }
@@ -235,9 +245,13 @@ static void sprd_mbox_shutdown(struct mbox_chan *chan) {struct sprd_mbox_priv *priv =to_sprd_mbox_priv (chan->mbox); -/* Disable inbox & outbox interrupt */ -writel (SPRD_INBOX_FIFO_IRQ_MASK , priv->inbox_base +SPRD_MBOX_IRQ_MSK ); -writel (SPRD_OUTBOX_FIFO_IRQ_MASK , priv->outbox_base +SPRD_MBOX_IRQ_MSK ); +mutex_lock (&priv->lock); +if (--priv->refcnt ==0 ) { +/* Disable inbox & outbox interrupt */ +writel (SPRD_INBOX_FIFO_IRQ_MASK , priv->inbox_base +SPRD_MBOX_IRQ_MSK ); +writel (SPRD_OUTBOX_FIFO_IRQ_MASK , priv->outbox_base +SPRD_MBOX_IRQ_MSK ); + } +mutex_unlock (&priv->lock); }static const struct mbox_chan_ops sprd_mbox_ops = {
@@ -266,6 +280,7 @@ static int sprd_mbox_probe(struct platform_device *pdev)return -ENOMEM ; priv->dev = dev; +mutex_init (&priv->lock);/* * The Spreadtrum mailbox uses an inbox to send messages to the target
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 374/601 mfd: stm32-timers: Avoid clearing auto reload register
In reply to Greg Kroah-HartmanFrom: Fabrice Gasnier <[email protected]>
[ Upstream commit 4917e498c6894ba077867aff78f82cffd5ffbb5c ]
The ARR register is cleared unconditionally upon probing, after the maximum value has been read. This initial condition is rather not intuitive, when considering the counter child driver. It rather expects the maximum value by default:
- The counter interface shows a zero value by default for 'ceiling' attribute.
- Enabling the counter without any prior configuration makes it doesn't count.
The reset value of ARR register is the maximum. So Choice here is to backup it, and restore it then, instead of clearing its value. It also fixes the initial condition seen by the counter driver.
--- drivers/mfd/stm32-timers.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mfd/stm32-timers.c +6 -1
@@ -158,13 +158,18 @@ static const struct regmap_config stm32_timers_regmap_cfg = {static void stm32_timers_get_arr_size (struct stm32_timers *ddata) { +u32 arr; + +/* Backup ARR to restore it after getting the maximum value */ +regmap_read (ddata->regmap,TIM_ARR , &arr); +/* * Only the available bits will be written so when readback * we get the maximum value of auto reload register */ regmap_write (ddata->regmap,TIM_ARR , ~0L );regmap_read (ddata->regmap,TIM_ARR , &ddata->max_arr); -regmap_write (ddata->regmap,TIM_ARR ,0x0 ); +regmap_write (ddata->regmap,TIM_ARR , arr); } static int stm32_timers_dma_probe(struct device *dev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 375/601 nvmet-tcp: fix a segmentation fault during io parsing error
In reply to Greg Kroah-HartmanFrom: Elad Grupi <[email protected]>
[ Upstream commit bdaf13279192c60b2b1fc99badef53b494fec055 ]
In case there is an io that contains inline data and it goes to parsing error flow, command response will free command and iov before clearing the data on the socket buffer.
This will delay the command response until receive flow is completed.
--- drivers/nvme/target/tcp.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-)
drivers/nvme/target/tcp.c +31 -8
@@ -525,11 +525,36 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req)struct nvmet_tcp_cmd *cmd = container_of(req, struct nvmet_tcp_cmd, req);struct nvmet_tcp_queue *queue = cmd->queue; +struct nvme_sgl_desc *sgl; +u32 len; + +if (unlikely (cmd == queue->cmd)) { + sgl = &cmd->req.cmd->common.dptr.sgl; + len =le32_to_cpu (sgl->length); + +/* +* Wait for inline data before processing the response. +* Avoid using helpers, this might happen before +* nvmet_req_init is completed. +*/ +if (queue->rcv_state ==NVMET_TCP_RECV_PDU && + len && len < cmd->req.port->inline_data_size && +nvme_is_write (cmd->req.cmd)) +return ; + }llist_add (&cmd->lentry, &queue->resp_list);queue_work_on (queue_cpu (queue), nvmet_tcp_wq, &cmd->queue->io_work); } +static void nvmet_tcp_execute_request (struct nvmet_tcp_cmd *cmd) +{ +if (unlikely (cmd->flags &NVMET_TCP_F_INIT_FAILED )) +nvmet_tcp_queue_response (&cmd->req); +else + cmd->req.execute (&cmd->req); +} +static int nvmet_try_send_data_pdu (struct nvmet_tcp_cmd *cmd) {u8 hdgst =nvmet_tcp_hdgst_len (cmd->queue);
@@ -961,7 +986,7 @@ static int nvmet_tcp_done_recv_pdu(struct nvmet_tcp_queue *queue) le32_to_cpu(req->cmd->common.dptr.sgl.length));nvmet_tcp_handle_req_failure (queue, queue->cmd, req); -return -EAGAIN ; +return 0 ; } ret =nvmet_tcp_map_data (queue->cmd);
@@ -1104,10 +1129,8 @@ static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue)return 0 ; } -if (!(cmd->flags &NVMET_TCP_F_INIT_FAILED ) && - cmd->rbytes_done == cmd->req.transfer_len) { - cmd->req.execute (&cmd->req); - } +if (cmd->rbytes_done == cmd->req.transfer_len) +nvmet_tcp_execute_request (cmd);nvmet_prepare_receive_pdu (queue);return 0 ;
@@ -1144,9 +1167,9 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue) goto out; } -if (!(cmd->flags &NVMET_TCP_F_INIT_FAILED ) && - cmd->rbytes_done == cmd->req.transfer_len) - cmd->req.execute (&cmd->req); +if (cmd->rbytes_done == cmd->req.transfer_len) +nvmet_tcp_execute_request (cmd); + ret =0 ; out:nvmet_prepare_receive_pdu (queue);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 376/601 nvme-pci: dont simple map sgl when sgls are disabled
In reply to Greg Kroah-HartmanFrom: Niklas Cassel <[email protected]>
[ Upstream commit e51183be1fa96dc6d3cd11b3c25a0f595807315e ]
According to the module parameter description for sgl_threshold, a value of 0 means that SGLs are disabled.
If SGLs are disabled, we should respect that, even for the case where the request is made up of a single physical segment.
--- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/pci.c +1 -1
@@ -852,7 +852,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,return nvme_setup_prp_simple (dev, req, &cmnd->rw, &bv); -if (iod->nvmeq->qid && +if (iod->nvmeq->qid && sgl_threshold && dev->ctrl.sgls & ((1 <<0 ) | (1 <<1 )))return nvme_setup_sgl_simple (dev, req, &cmnd->rw, &bv);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 377/601 media: meson-ge2d: fix rotation parameters
In reply to Greg Kroah-HartmanFrom: Neil Armstrong <[email protected]>
[ Upstream commit 87e780db2253a1759822c2c9ea207135fcc059de ]
With these settings, 90deg and 270deg rotation leads to inverted vertical, fix them to have correct rotation.
--- drivers/media/platform/meson/ge2d/ge2d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/platform/meson/ge2d/ge2d.c +2 -2
@@ -757,7 +757,7 @@ static int ge2d_s_ctrl(struct v4l2_ctrl *ctrl)if (ctrl->val ==90 ) { ctx->hflip =0 ; - ctx->vflip =0 ; + ctx->vflip =1 ; ctx->xy_swap =1 ; }else if (ctrl->val ==180 ) { ctx->hflip =1 ;
@@ -765,7 +765,7 @@ static int ge2d_s_ctrl(struct v4l2_ctrl *ctrl) ctx->xy_swap =0 ; }else if (ctrl->val ==270 ) { ctx->hflip =1 ; - ctx->vflip =1 ; + ctx->vflip =0 ; ctx->xy_swap =1 ; }else { ctx->hflip =0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 378/601 media: cedrus: Fix H265 status definitions
In reply to Greg Kroah-HartmanFrom: Jernej Skrabec <[email protected]>
[ Upstream commit 147d211cc9b4d753148d1640a1758b25edfbf437 ]
Some of the H265 status flags are wrong. Redefine them to corespond to Allwinner CedarC open source userspace library. Only one of these flags is actually used and new value also matches value used in libvdpau-sunxi library, which is proven to be working.
Note that wrong (old) value in right circumstances (in combination with another H265 decoding bug) causes driver lock up. With this fix decoding is still broken (green output) but at least driver doesn't lock up.
--- .../staging/media/sunxi/cedrus/cedrus_regs.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +9 -8
@@ -443,16 +443,17 @@#define VE_DEC_H265_STATUS_STCD_BUSY BIT(21)#define VE_DEC_H265_STATUS_WB_BUSY BIT(20)#define VE_DEC_H265_STATUS_BS_DMA_BUSY BIT(19) -#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(18) +#define VE_DEC_H265_STATUS_IT_BUSY BIT(18)#define VE_DEC_H265_STATUS_INTER_BUSY BIT(17)#define VE_DEC_H265_STATUS_MORE_DATA BIT(16) -#define VE_DEC_H265_STATUS_VLD_BUSY BIT(14) -#define VE_DEC_H265_STATUS_DEBLOCKING_BUSY BIT(13) -#define VE_DEC_H265_STATUS_DEBLOCKING_DRAM_BUSY BIT(12) -#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(11) -#define VE_DEC_H265_STATUS_SAO_BUSY BIT(10) -#define VE_DEC_H265_STATUS_MVP_BUSY BIT(9) -#define VE_DEC_H265_STATUS_SWDEC_BUSY BIT(8) +#define VE_DEC_H265_STATUS_DBLK_BUSY BIT(15) +#define VE_DEC_H265_STATUS_IREC_BUSY BIT(14) +#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(13) +#define VE_DEC_H265_STATUS_MCRI_BUSY BIT(12) +#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(11) +#define VE_DEC_H265_STATUS_MVP_BUSY BIT(10) +#define VE_DEC_H265_STATUS_IS_BUSY BIT(9) +#define VE_DEC_H265_STATUS_VLD_BUSY BIT(8)#define VE_DEC_H265_STATUS_OVER_TIME BIT(3)#define VE_DEC_H265_STATUS_VLD_DATA_REQ BIT(2)#define VE_DEC_H265_STATUS_ERROR BIT(1)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 379/601 HSI: core: fix resource leaks in hsi_add_client_from_dt()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5c08b0f75575648032f309a6f58294453423ed93 ]
If some of the allocations fail between the dev_set_name() and the device_register() then the name will not be freed. Fix this by moving dev_set_name() directly in front of the call to device_register().
--- drivers/hsi/hsi_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/hsi/hsi_core.c +1 -2
@@ -210,8 +210,6 @@ static void hsi_add_client_from_dt(struct hsi_port *port,if (err) goto err; -dev_set_name (&cl->device,"%s" , name); - err =hsi_of_property_parse_mode (client,"hsi-mode" , &mode);if (err) { err = hsi_of_property_parse_mode(client, "hsi-rx-mode",
@@ -293,6 +291,7 @@ static void hsi_add_client_from_dt(struct hsi_port *port, cl->device.release = hsi_client_release; cl->device.of_node = client; +dev_set_name (&cl->device,"%s" , name);if (device_register (&cl->device) <0 ) {pr_err ("hsi: failed to register client: %s\n" , name);put_device (&cl->device);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 380/601 x86/events/amd/iommu: Fix sysfs type mismatch
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit de5bc7b425d4c27ae5faa00ea7eb6b9780b9a355 ]
dev_attr_show() calls _iommu_event_show() via an indirect call but _iommu_event_show()'s type does not currently match the type of the show() member in 'struct device_attribute', resulting in a Control Flow Integrity violation.
$ cat /sys/devices/amd_iommu_1/events/mem_dte_hit csource=0x0a
$ dmesg | grep "CFI failure" [ 3526.735140] CFI failure (target: _iommu_event_show...):
Change _iommu_event_show() and 'struct amd_iommu_event_desc' to 'struct device_attribute' so that there is no more CFI violation.
--- arch/x86/events/amd/iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/events/amd/iommu.c +3 -3
@@ -81,12 +81,12 @@ static struct attribute_group amd_iommu_events_group = { };struct amd_iommu_event_desc { -struct kobj_attribute attr; +struct device_attribute attr;const char *event; }; -static ssize_t _iommu_event_show (struct kobject *kobj, -struct kobj_attribute *attr,char *buf) +static ssize_t _iommu_event_show (struct device *dev, +struct device_attribute *attr,char *buf) {struct amd_iommu_event_desc *event = container_of(attr, struct amd_iommu_event_desc, attr);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 381/601 perf/amd/uncore: Fix sysfs type mismatch
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 5deac80d4571dffb51f452f0027979d72259a1b9 ]
dev_attr_show() calls the __uncore_*_show() functions via an indirect call but their type does not currently match the type of the show() member in 'struct device_attribute', resulting in a Control Flow Integrity violation.
$ cat /sys/devices/amd_l3/format/umask config:8-15
$ dmesg | grep "CFI failure" [ 1258.174653] CFI failure (target: __uncore_umask_show...):
Update the type in the DEFINE_UNCORE_FORMAT_ATTR macro to match 'struct device_attribute' so that there is no more CFI violation.
--- arch/x86/events/amd/uncore.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/events/amd/uncore.c +3 -3
@@ -275,14 +275,14 @@ static struct attribute_group amd_uncore_attr_group = { };#define DEFINE_UNCORE_FORMAT_ATTR (_var, _name, _format) \ -static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, \ +static ssize_t __uncore_##_var##_show(struct device *dev, \ + struct device_attribute *attr, \ char *page) \ { \ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ return sprintf(page, _format "\n"); \ } \ -static struct kobj_attribute format_attr_##_var = \ +static struct device_attribute format_attr_##_var = \ __ATTR(_name, 0444, __uncore_##_var##_show, NULL)DEFINE_UNCORE_FORMAT_ATTR (event12, event,"config:0-7,32-35" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 382/601 io_uring: fix overflows checks in provide buffers
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit 38134ada0ceea3e848fe993263c0ff6207fd46e7 ]
Colin reported before possible overflow and sign extension problems in io_provide_buffers_prep(). As Linus pointed out previous attempt did nothing useful, see d81269fecb8ce ("io_uring: fix provide_buffers sign extension").
Do that with help of check_<op>_overflow helpers. And fix struct io_provide_buf::len type, as it doesn't make much sense to keep it signed.
--- fs/io_uring.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
fs/io_uring.c +8 -2
@@ -535,7 +535,7 @@ struct io_splice {struct io_provide_buf {struct file *file;__u64 addr; -__s32 len; +__u32 len;__u32 bgid;__u16 nbufs;__u16 bid;
@@ -4214,7 +4214,7 @@ static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock,static int io_provide_buffers_prep (struct io_kiocb *req,const struct io_uring_sqe *sqe) { -unsigned long size; +unsigned long size, tmp_check;struct io_provide_buf *p = &req->pbuf;u64 tmp;
@@ -4228,6 +4228,12 @@ static int io_provide_buffers_prep(struct io_kiocb *req, p->addr =READ_ONCE (sqe->addr); p->len =READ_ONCE (sqe->len); +if (check_mul_overflow ((unsigned long )p->len, (unsigned long )p->nbufs, + &size)) +return -EOVERFLOW ; +if (check_add_overflow ((unsigned long )p->addr, size, &tmp_check)) +return -EOVERFLOW ; + size = (unsigned long )p->len * p->nbufs;if (!access_ok (u64_to_user_ptr (p->addr), size))return -EFAULT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 383/601 block/rnbd-clt-sysfs: Remove copy buffer overlap in rnbd_clt_get_path_name
In reply to Greg Kroah-HartmanFrom: Dima Stepanov <[email protected]>
[ Upstream commit 3db7cf55d532a15ea26b4a14e8f8729ccd96fd22 ]
cppcheck report the following error:
rnbd/rnbd-clt-sysfs.c:522:36: error: The variable 'buf' is used both as a parameter and as destination in snprintf(). The origin and destination buffers overlap. Quote from glibc (C-library) documentation
(http://www.gnu.org/software/libc/manual/html_mono/libc.html#Formatted-Output-Functions):
"If copying takes place between objects that overlap as a result of a call to sprintf() or snprintf(), the results are undefined." [sprintfOverlappingData]
Fix it by initializing the buf variable in the first snprintf call.
--- drivers/block/rnbd/rnbd-clt-sysfs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/block/rnbd/rnbd-clt-sysfs.c +1 -5
@@ -483,11 +483,7 @@ static int rnbd_clt_get_path_name(struct rnbd_clt_dev *dev, char *buf,while ((s =strchr (pathname,'/' ))) s[0 ] ='!' ; - ret =snprintf (buf, len,"%s" , pathname); -if (ret >= len) -return -ENAMETOOLONG ; - - ret =snprintf (buf, len,"%s@%s" , buf, dev->sess->sessname); + ret =snprintf (buf, len,"%s@%s" , pathname, dev->sess->sessname);if (ret >= len)return -ENAMETOOLONG ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 384/601 sched/debug: Fix cgroup_path[] serialization
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit ad789f84c9a145f8a18744c0387cec22ec51651e ]
The handling of sysrq key can be activated by echoing the key to /proc/sysrq-trigger or via the magic key sequence typed into a terminal that is connected to the system in some way (serial, USB or other mean). In the former case, the handling is done in a user context. In the latter case, it is likely to be in an interrupt context.
Currently in print_cpu() of kernel/sched/debug.c, sched_debug_lock is taken with interrupt disabled for the whole duration of the calls to print_*_stats() and print_rq() which could last for the quite some time if the information dump happens on the serial console.
If the system has many cpus and the sched_debug_lock is somehow busy (e.g. parallel sysrq-t), the system may hit a hard lockup panic depending on the actually serial console implementation of the system.
The purpose of sched_debug_lock is to serialize the use of the global cgroup_path[] buffer in print_cpu(). The rests of the printk calls don't need serialization from sched_debug_lock.
Calling printk() with interrupt disabled can still be problematic if multiple instances are running. Allocating a stack buffer of PATH_MAX bytes is not feasible because of the limited size of the kernel stack.
The solution implemented in this patch is to allow only one caller at a time to use the full size group_path[], while other simultaneous callers will have to use shorter stack buffers with the possibility of path name truncation. A "..." suffix will be printed if truncation may have happened. The cgroup path name is provided for informational purpose only, so occasional path name truncation should not be a big problem.
--- kernel/sched/debug.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-)
kernel/sched/debug.c +29 -13
@@ -8,8 +8,6 @@*/ #include "sched.h" -static DEFINE_SPINLOCK (sched_debug_lock); -/* * This allows printing both to /proc/sched_debug and * to the console
@@ -470,16 +468,37 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group#endif #ifdef CONFIG_CGROUP_SCHED +static DEFINE_SPINLOCK (sched_debug_lock);static char group_path[PATH_MAX ]; -static char *task_group_path (struct task_group *tg) +static void task_group_path (struct task_group *tg,char *path,int plen) { -if (autogroup_path (tg, group_path,PATH_MAX )) -return group_path; +if (autogroup_path (tg, path, plen)) +return ; -cgroup_path (tg->css.cgroup, group_path,PATH_MAX ); +cgroup_path (tg->css.cgroup, path, plen); +} -return group_path; +/* +* Only 1 SEQ_printf_task_group_path() caller can use the full length +* group_path[] for cgroup path. Other simultaneous callers will have +* to use a shorter stack buffer. A "..." suffix is appended at the end +* of the stack buffer so that it will show up in case the output length +* matches the given buffer size to indicate possible path name truncation. +*/ +#define SEQ_printf_task_group_path(m, tg, fmt...) \ +{ \ + if (spin_trylock(&sched_debug_lock)) { \ + task_group_path(tg, group_path, sizeof(group_path)); \ + SEQ_printf(m, fmt, group_path); \ + spin_unlock(&sched_debug_lock); \ + } else { \ + char buf[128]; \ + char *bufend = buf + sizeof(buf) - 3; \ + task_group_path(tg, buf, bufend - buf); \ + strcpy(bufend - 1, "..."); \ + SEQ_printf(m, fmt, buf); \ + } \ }#endif
@@ -506,7 +525,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)SEQ_printf (m," %d %d" ,task_node (p),task_numa_group_id (p));#endif #ifdef CONFIG_CGROUP_SCHED -SEQ_printf (m," %s" ,task_group_path (task_group (p))); + SEQ_printf_task_group_path(m, task_group(p), " %s")#endif SEQ_printf (m,"\n" );
@@ -543,7 +562,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)#ifdef CONFIG_FAIR_GROUP_SCHED SEQ_printf (m,"\n" ); -SEQ_printf (m,"cfs_rq[%d]:%s\n" , cpu,task_group_path (cfs_rq->tg)); +SEQ_printf_task_group_path (m, cfs_rq->tg,"cfs_rq[%d]:%s\n" , cpu);#else SEQ_printf (m,"\n" );SEQ_printf (m,"cfs_rq[%d]:\n" , cpu);
@@ -614,7 +633,7 @@ void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq) {#ifdef CONFIG_RT_GROUP_SCHED SEQ_printf (m,"\n" ); -SEQ_printf (m,"rt_rq[%d]:%s\n" , cpu,task_group_path (rt_rq->tg)); +SEQ_printf_task_group_path (m, rt_rq->tg,"rt_rq[%d]:%s\n" , cpu);#else SEQ_printf (m,"\n" );SEQ_printf (m,"rt_rq[%d]:\n" , cpu);
@@ -666,7 +685,6 @@ void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq)static void print_cpu (struct seq_file *m,int cpu) {struct rq *rq =cpu_rq (cpu); -unsigned long flags;#ifdef CONFIG_X86 {
@@ -717,13 +735,11 @@ do { \ }#undef P -spin_lock_irqsave (&sched_debug_lock, flags);print_cfs_stats (m, cpu);print_rt_stats (m, cpu);print_dl_stats (m, cpu);print_rq (m, rq, cpu); -spin_unlock_irqrestore (&sched_debug_lock, flags);SEQ_printf (m,"\n" ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 385/601 kthread: Fix PF_KTHREAD vs to_kthread() race
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 3a7956e25e1d7b3c148569e78895e1f3178122a9 ]
The kthread_is_per_cpu() construct relies on only being called on PF_KTHREAD tasks (per the WARN in to_kthread). This gives rise to the following usage pattern:
if ((p->flags & PF_KTHREAD) && kthread_is_per_cpu(p))
However, as reported by syzcaller, this is broken. The scenario is:
CPU0 CPU1 (running p) (p->flags & PF_KTHREAD) // true begin_new_exec() me->flags &= ~(PF_KTHREAD|...); kthread_is_per_cpu(p) to_kthread(p) WARN(!(p->flags & PF_KTHREAD) <-- *SPLAT*
Introduce __to_kthread() that omits the WARN and is sure to check both values.
Use this to remove the problematic pattern for kthread_is_per_cpu() and fix a number of other kthread_*() functions that have similar issues but are currently not used in ways that would expose the problem.
Notably kthread_func() is only ever called on 'current', while kthread_probe_data() is only used for PF_WQ_WORKER, which implies the task is from kthread_create*().
--- kernel/kthread.c | 33 +++++++++++++++++++++++++++------ kernel/sched/core.c | 2 +- kernel/sched/fair.c | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-)
kernel/kthread.c +27 -6
@@ -84,6 +84,25 @@ static inline struct kthread *to_kthread(struct task_struct *k)return (__force void *)k->set_child_tid; } +/* +* Variant of to_kthread() that doesn't assume @p is a kthread. +* +* Per construction; when: +* +* (p->flags & PF_KTHREAD) && p->set_child_tid +* +* the task is both a kthread and struct kthread is persistent. However +* PF_KTHREAD on it's own is not, kernel_thread() can exec() (See umh.c and +* begin_new_exec()). +*/ +static inline struct kthread *__to_kthread (struct task_struct *p) +{ +void *kthread = (__force void *)p->set_child_tid; +if (kthread && !(p->flags &PF_KTHREAD )) + kthread =NULL ; +return kthread; +} +void free_kthread_struct (struct task_struct *k) {struct kthread *kthread;
@@ -168,8 +187,9 @@ EXPORT_SYMBOL_GPL(kthread_freezable_should_stop);*/ void *kthread_func (struct task_struct *task) { -if (task->flags &PF_KTHREAD ) -return to_kthread (task)->threadfn; +struct kthread *kthread =__to_kthread (task); +if (kthread) +return kthread->threadfn;return NULL ; }EXPORT_SYMBOL_GPL (kthread_func);
@@ -199,10 +219,11 @@ EXPORT_SYMBOL_GPL(kthread_data);*/ void *kthread_probe_data (struct task_struct *task) { -struct kthread *kthread =to_kthread (task); +struct kthread *kthread =__to_kthread (task);void *data =NULL ; -copy_from_kernel_nofault (&data, &kthread->data,sizeof (data)); +if (kthread) +copy_from_kernel_nofault (&data, &kthread->data,sizeof (data));return data; }
@@ -514,9 +535,9 @@ void kthread_set_per_cpu(struct task_struct *k, int cpu)set_bit (KTHREAD_IS_PER_CPU , &kthread->flags); } -bool kthread_is_per_cpu (struct task_struct *k) +bool kthread_is_per_cpu (struct task_struct *p) { -struct kthread *kthread =to_kthread (k); +struct kthread *kthread =__to_kthread (p);if (!kthread)return false;
kernel/sched/core.c +1 -1
@@ -7290,7 +7290,7 @@ static void balance_push(struct rq *rq)* histerical raisins. */ if (rq->idle == push_task || - ((push_task->flags &PF_KTHREAD ) &&kthread_is_per_cpu (push_task)) || +kthread_is_per_cpu (push_task) ||is_migration_disabled (push_task)) {/*
kernel/sched/fair.c +1 -1
@@ -7588,7 +7588,7 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)return 0 ;/* Disregard pcpu kthreads; they are where they need to be. */ -if ((p->flags &PF_KTHREAD ) &&kthread_is_per_cpu (p)) +if (kthread_is_per_cpu (p))return 0 ;if (!cpumask_test_cpu (env->dst_cpu, p->cpus_ptr)) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 386/601 ataflop: potential out of bounds in do_format()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 1ffec389a6431782a8a28805830b6fae9bf00af1 ]
The function uses "type" as an array index:
q = unit[drive].disk[type]->queue;
Unfortunately the bounds check on "type" isn't done until later in the function. Fix this by moving the bounds check to the start.
--- drivers/block/ataflop.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/block/ataflop.c +5 -6
@@ -729,8 +729,12 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)unsigned long flags;int ret; -if (type) +if (type) { type--; +if (type >=NUM_DISK_MINORS || + minor2disktype[type].drive_types > DriveType) +return -EINVAL ; + } q = unit[drive].disk[type]->queue;blk_mq_freeze_queue (q);
@@ -742,11 +746,6 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)local_irq_restore (flags);if (type) { -if (type >=NUM_DISK_MINORS || - minor2disktype[type].drive_types > DriveType) { - ret = -EINVAL ; - goto out; - } type = minor2disktype[type].index;UDT = &atari_disk_type[type]; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 387/601 ataflop: fix off by one in ataflop_probe()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit b777f4c47781df6b23e3f4df6fdb92d9aceac7bb ]
Smatch complains that the "type > NUM_DISK_MINORS" should be >= instead of >. We also need to subtract one from "type" at the start.
--- drivers/block/ataflop.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/block/ataflop.c +4 -1
@@ -2001,7 +2001,10 @@ static void ataflop_probe(dev_t dev)int drive =MINOR (dev) &3 ;int type =MINOR (dev) >>2 ; -if (drive >=FD_MAX_UNITS || type >NUM_DISK_MINORS ) +if (type) + type--; + +if (drive >=FD_MAX_UNITS || type >=NUM_DISK_MINORS )return ;mutex_lock (&ataflop_probe_lock);if (!unit[drive].disk[type]) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 388/601 drivers/block/null_blk/main: Fix a double free in null_init.
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit 72ce11ddfa4e9e1879103581a60b7e34547eaa0a ]
In null_init, null_add_dev(dev) is called.
In null_add_dev, it calls null_free_zoned_dev(dev) to free dev->zones via kvfree(dev->zones) in out_cleanup_zone branch and returns err. Then null_init accept the err code and then calls null_free_dev(dev).
But in null_free_dev(dev), dev->zones is freed again by null_free_zoned_dev().
My patch set dev->zones to NULL in null_free_zoned_dev() after kvfree(dev->zones) is called, to avoid the double free.
--- drivers/block/null_blk/zoned.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/null_blk/zoned.c +1 -0
@@ -180,6 +180,7 @@ int null_register_zoned_dev(struct nullb *nullb)void null_free_zoned_dev (struct nullb_device *dev) {kvfree (dev->zones); + dev->zones =NULL ; } int null_report_zones(struct gendisk *disk, sector_t sector,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 389/601 xsk: Respect devices headroom and tailroom on generic xmit path
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit 3914d88f7608e6c2e80e344474fa289370c32451 ]
xsk_generic_xmit() allocates a new skb and then queues it for xmitting. The size of new skb's headroom is desc->len, so it comes to the driver/device with no reserved headroom and/or tailroom. Lots of drivers need some headroom (and sometimes tailroom) to prepend (and/or append) some headers or data, e.g. CPU tags, device-specific headers/descriptors (LSO, TLS etc.), and if case of no available space skb_cow_head() will reallocate the skb. Reallocations are unwanted on fast-path, especially when it comes to XDP, so generic XSK xmit should reserve the spaces declared in dev->needed_headroom and dev->needed tailroom to avoid them.
Note on max(NET_SKB_PAD, L1_CACHE_ALIGN(dev->needed_headroom)):
Usually, output functions reserve LL_RESERVED_SPACE(dev), which consists of dev->hard_header_len + dev->needed_headroom, aligned by 16.
However, on XSK xmit hard header is already here in the chunk, so hard_header_len is not needed. But it'd still be better to align data up to cacheline, while reserving no less than driver requests for headroom. NET_SKB_PAD here is to double-insure there will be no reallocations even when the driver advertises no needed_headroom, but in fact need it (not so rare case).
--- net/xdp/xsk.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/xdp/xsk.c +7 -1
@@ -439,12 +439,16 @@ static int xsk_generic_xmit(struct sock *sk)struct sk_buff *skb;unsigned long flags;int err =0 ; +u32 hr, tr;mutex_lock (&xs->mutex);if (xs->queue_id >= xs->dev->real_num_tx_queues) goto out; + hr =max (NET_SKB_PAD ,L1_CACHE_ALIGN (xs->dev->needed_headroom)); + tr = xs->dev->needed_tailroom; +while (xskq_cons_peek_desc (xs->tx, &desc, xs->pool)) {char *buffer;u64 addr;
@@ -456,11 +460,13 @@ static int xsk_generic_xmit(struct sock *sk) } len = desc.len; - skb =sock_alloc_send_skb (sk, len,1 , &err); + skb =sock_alloc_send_skb (sk, hr + len + tr,1 , &err);if (unlikely (!skb)) goto out; +skb_reserve (skb, hr);skb_put (skb, len); + addr = desc.addr; buffer =xsk_buff_raw_get_data (xs->pool, addr); err =skb_store_bits (skb,0 , buffer, len);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 390/601 HID: plantronics: Workaround for double volume key presses
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit f567d6ef8606fb427636e824c867229ecb5aefab ]
Plantronics Blackwire 3220 Series (047f:c056) sends HID reports twice for each volume key press. This patch adds a quirk to hid-plantronics for this product ID, which will ignore the second volume key press if it happens within 5 ms from the last one that was handled.
The patch was tested on the mentioned model only, it shouldn't affect other models, however, this quirk might be needed for them too. Auto-repeat (when a key is held pressed) is not affected, because the rate is about 3 times per second, which is far less frequent than once in 5 ms.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-plantronics.c | 60 +++++++++++++++++++++++++++++++++-- include/linux/hid.h | 2 ++ 3 files changed, 61 insertions(+), 2 deletions(-)
drivers/hid/hid-ids.h +1 -0
@@ -941,6 +941,7 @@#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003#define USB_VENDOR_ID_PLANTRONICS 0x047f +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056#define USB_VENDOR_ID_PANASONIC 0x04da#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
drivers/hid/hid-plantronics.c +58 -2
113 lines not on this page · raw message
include/linux/hid.h +2 -0
@@ -262,6 +262,8 @@ struct hid_item {#define HID_CP_SELECTION 0x000c0080#define HID_CP_MEDIASELECTION 0x000c0087#define HID_CP_SELECTDISC 0x000c00ba +#define HID_CP_VOLUMEUP 0x000c00e9 +#define HID_CP_VOLUMEDOWN 0x000c00ea#define HID_CP_PLAYBACKSPEED 0x000c00f1#define HID_CP_PROXIMITY 0x000c0109#define HID_CP_SPEAKERSYSTEM 0x000c0160
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 391/601 perf symbols: Fix dso__fprintf_symbols_by_name() to return the number of printed chars
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 210e4c89ef61432040c6cd828fefa441f4887186 ]
The 'ret' variable was initialized to zero but then it was not updated from the fprintf() return, fix it.
--- tools/perf/util/symbol_fprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/symbol_fprintf.c +1 -1
@@ -68,7 +68,7 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,for (nd =rb_first_cached (&dso->symbol_names); nd; nd =rb_next (nd)) { pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); -fprintf (fp,"%s\n" , pos->sym.name); + ret +=fprintf (fp,"%s\n" , pos->sym.name); }return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 392/601 ASoC: Intel: boards: sof-wm8804: add check for PLL setting
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 1730ef62874dbdc53dc2abfa430f09f0b304bafc ]
Currently the return from snd_soc_dai_set_pll is not checking for failure, this is the only driver in the kernel that ignores this, so it probably should be added for sake of completeness. Fix this by adding an error return check.
Addresses-Coverity: ("Unchecked return value")
--- sound/soc/intel/boards/sof_wm8804.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
sound/soc/intel/boards/sof_wm8804.c +5 -1
@@ -124,7 +124,11 @@ static int sof_wm8804_hw_params(struct snd_pcm_substream *substream, }snd_soc_dai_set_clkdiv (codec_dai,WM8804_MCLK_DIV , mclk_div); -snd_soc_dai_set_pll (codec_dai,0 ,0 , sysclk, mclk_freq); + ret =snd_soc_dai_set_pll (codec_dai,0 ,0 , sysclk, mclk_freq); +if (ret <0 ) { +dev_err (rtd->card->dev,"Failed to set WM8804 PLL\n" ); +return ret; + } ret =snd_soc_dai_set_sysclk (codec_dai,WM8804_TX_CLKSRC_PLL , sysclk,SND_SOC_CLOCK_OUT );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 393/601 ASoC: Intel: Skylake: Compile when any configuration is selected
In reply to Greg Kroah-HartmanFrom: Cezary Rojewski <[email protected]>
[ Upstream commit 1b99d50b9709a2cddaba4a7faf1862b4f7bec865 ]
Skylake is dependent on SND_SOC_INTEL_SKYLAKE (aka "all SST platforms") whereas selecting specific configuration such as KBL-only will not cause driver code to compile. Switch to SND_SOC_INTEL_SKYLAKE_COMMON dependency so selecting any configuration causes the driver to be built.
--- sound/soc/intel/Makefile | 2 +- sound/soc/intel/skylake/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
sound/soc/intel/Makefile +1 -1
@@ -5,7 +5,7 @@ obj-$(CONFIG_SND_SOC) += common/ # Platform Support obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM) += atom/ obj-$(CONFIG_SND_SOC_INTEL_CATPT) += catpt/ -obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += skylake/ +obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON) += skylake/ obj-$(CONFIG_SND_SOC_INTEL_KEEMBAY) += keembay/ # Machine support
sound/soc/intel/skylake/Makefile +1 -1
@@ -7,7 +7,7 @@ ifdef CONFIG_DEBUG_FS snd-soc-skl-objs += skl-debug.o endif -obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o +obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON) += snd-soc-skl.o #Skylake Clock device support snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 394/601 RDMA/mlx5: Fix mlx5 rates to IB rates map
In reply to Greg Kroah-HartmanFrom: Mark Zhang <[email protected]>
[ Upstream commit 6fe6e568639859db960c8fcef19a2ece1c2d7eae ]
Correct the map between mlx5 rates and corresponding ib rates, as they don't always have a fixed offset between them.
--- drivers/infiniband/hw/mlx5/qp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/qp.c +14 -1
@@ -3054,6 +3054,19 @@ enum { MLX5_PATH_FLAG_COUNTER = 1 << 2, }; +static int mlx5_to_ib_rate_map (u8 rate) +{ +static const int rates[] = {IB_RATE_PORT_CURRENT ,IB_RATE_56_GBPS , +IB_RATE_25_GBPS ,IB_RATE_100_GBPS , +IB_RATE_200_GBPS ,IB_RATE_50_GBPS , +IB_RATE_400_GBPS }; + +if (rate <ARRAY_SIZE (rates)) +return rates[rate]; + +return rate -MLX5_STAT_RATE_OFFSET ; +} +static int ib_to_mlx5_rate_map (u8 rate) {switch (rate) {
@@ -4398,7 +4411,7 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev,rdma_ah_set_path_bits (ah_attr,MLX5_GET (ads, path, mlid)); static_rate =MLX5_GET (ads, path, stat_rate); -rdma_ah_set_static_rate (ah_attr, static_rate ? static_rate -5 :0 ); +rdma_ah_set_static_rate (ah_attr,mlx5_to_ib_rate_map (static_rate));if (MLX5_GET (ads, path, grh) || ah_attr->type ==RDMA_AH_ATTR_TYPE_ROCE ) { rdma_ah_set_grh(ah_attr, NULL, MLX5_GET(ads, path, flow_label),
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 395/601 wilc1000: write value to WILC_INTR2_ENABLE register
In reply to Greg Kroah-HartmanFrom: Marcus Folkesson <[email protected]>
[ Upstream commit e21b6e5a54628cd3935f200049d4430c25c54e03 ]
Write the value instead of reading it twice.
--- drivers/net/wireless/microchip/wilc1000/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/microchip/wilc1000/sdio.c +1 -1
@@ -947,7 +947,7 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)for (i =0 ; (i <3 ) && (nint >0 ); i++, nint--) reg |=BIT (i); - ret =wilc_sdio_read_reg (wilc,WILC_INTR2_ENABLE , ®); + ret =wilc_sdio_write_reg (wilc,WILC_INTR2_ENABLE , reg);if (ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 396/601 KVM: x86/mmu: Retry page faults that hit an invalid memslot
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit e0c378684b6545ad2d4403bb701d0ac4932b4e95 ]
Retry page faults (re-enter the guest) that hit an invalid memslot instead of treating the memslot as not existing, i.e. handling the page fault as an MMIO access. When deleting a memslot, SPTEs aren't zapped and the TLBs aren't flushed until after the memslot has been marked invalid.
Handling the invalid slot as MMIO means there's a small window where a page fault could replace a valid SPTE with an MMIO SPTE. The legacy MMU handles such a scenario cleanly, but the TDP MMU assumes such behavior is impossible (see the BUG() in __handle_changed_spte()). There's really no good reason why the legacy MMU should allow such a scenario, and closing this hole allows for additional cleanups.
Message-Id: <[email protected]>
--- arch/x86/kvm/mmu/mmu.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/x86/kvm/mmu/mmu.c +8 -0
@@ -3676,6 +3676,14 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,struct kvm_memory_slot *slot =kvm_vcpu_gfn_to_memslot (vcpu, gfn);bool async; +/* +* Retry the page fault if the gfn hit a memslot that is being deleted +* or moved. This ensures any existing SPTEs for the old memslot will +* be zapped before KVM inserts a new MMIO SPTE for the gfn. +*/ +if (slot && (slot->flags &KVM_MEMSLOT_INVALID )) +return true; +/* Don't expose private memslots to L2. */ if (is_guest_mode (vcpu) && !kvm_is_visible_memslot (slot)) { *pfn =KVM_PFN_NOSLOT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 397/601 Bluetooth: avoid deadlock between hci_dev->lock and socket lock
In reply to Greg Kroah-HartmanFrom: Jiri Kosina <[email protected]>
[ Upstream commit 17486960d79b900c45e0bb8fbcac0262848582ba ]
Commit eab2404ba798 ("Bluetooth: Add BT_PHY socket option") added a dependency between socket lock and hci_dev->lock that could lead to deadlock.
It turns out that hci_conn_get_phy() is not in any way relying on hdev being immutable during the runtime of this function, neither does it even look at any of the members of hdev, and as such there is no need to hold that lock.
This fixes the lockdep splat below:
======================================================
WARNING: possible circular locking dependency detected 5.12.0-rc1-00026-g73d464503354 #10 Not tainted
------------------------------------------------------
bluetoothd/1118 is trying to acquire lock:
ffff8f078383c078 (&hdev->lock){+.+.}-{3:3}, at: hci_conn_get_phy+0x1c/0x150 [bluetooth]
but task is already holding lock:
ffff8f07e831d920 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}-{0:0}, at: l2cap_sock_getsockopt+0x8b/0x610
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}-{0:0}:
lock_sock_nested+0x72/0xa0
l2cap_sock_ready_cb+0x18/0x70 [bluetooth]
l2cap_config_rsp+0x27a/0x520 [bluetooth]
l2cap_sig_channel+0x658/0x1330 [bluetooth]
l2cap_recv_frame+0x1ba/0x310 [bluetooth]
hci_rx_work+0x1cc/0x640 [bluetooth]
process_one_work+0x244/0x5f0
worker_thread+0x3c/0x380
kthread+0x13e/0x160
ret_from_fork+0x22/0x30-> #2 (&chan->lock#2/1){+.+.}-{3:3}:
__mutex_lock+0xa3/0xa10
l2cap_chan_connect+0x33a/0x940 [bluetooth]
l2cap_sock_connect+0x141/0x2a0 [bluetooth]
__sys_connect+0x9b/0xc0
__x64_sys_connect+0x16/0x20
do_syscall_64+0x33/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae-> #1 (&conn->chan_lock){+.+.}-{3:3}:
__mutex_lock+0xa3/0xa10
l2cap_chan_connect+0x322/0x940 [bluetooth]
l2cap_sock_connect+0x141/0x2a0 [bluetooth]
__sys_connect+0x9b/0xc0
__x64_sys_connect+0x16/0x20
do_syscall_64+0x33/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae-> #0 (&hdev->lock){+.+.}-{3:3}:
__lock_acquire+0x147a/0x1a50
lock_acquire+0x277/0x3d0
__mutex_lock+0xa3/0xa10
hci_conn_get_phy+0x1c/0x150 [bluetooth]
l2cap_sock_getsockopt+0x5a9/0x610 [bluetooth]
__sys_getsockopt+0xcc/0x200
__x64_sys_getsockopt+0x20/0x30
do_syscall_64+0x33/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xaeother info that might help us debug this:
Chain exists of: &hdev->lock --> &chan->lock#2/1 --> sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
lock(&chan->lock#2/1);
lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); lock(&hdev->lock);
*** DEADLOCK ***
1 lock held by bluetoothd/1118:
#0: ffff8f07e831d920 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}-{0:0}, at: l2cap_sock_getsockopt+0x8b/0x610 [bluetooth]
stack backtrace: CPU: 3 PID: 1118 Comm: bluetoothd Not tainted 5.12.0-rc1-00026-g73d464503354 #10 Hardware name: LENOVO 20K5S22R00/20K5S22R00, BIOS R0IET38W (1.16 ) 05/31/2017 Call Trace: dump_stack+0x7f/0xa1 check_noncircular+0x105/0x120 ? __lock_acquire+0x147a/0x1a50 __lock_acquire+0x147a/0x1a50 lock_acquire+0x277/0x3d0 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] ? __lock_acquire+0x2e1/0x1a50 ? lock_is_held_type+0xb4/0x120 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] __mutex_lock+0xa3/0xa10 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] ? lock_acquire+0x277/0x3d0 ? mark_held_locks+0x49/0x70 ? mark_held_locks+0x49/0x70 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] hci_conn_get_phy+0x1c/0x150 [bluetooth] l2cap_sock_getsockopt+0x5a9/0x610 [bluetooth] __sys_getsockopt+0xcc/0x200 __x64_sys_getsockopt+0x20/0x30 do_syscall_64+0x33/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7fb73df33eee Code: 48 8b 0d 85 0f 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 37 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 52 0f 0c 00 f7 d8 64 89 01 48 RSP: 002b:00007fffcfbbbf08 EFLAGS: 00000203 ORIG_RAX: 0000000000000037 RAX: ffffffffffffffda RBX: 0000000000000019 RCX: 00007fb73df33eee RDX: 000000000000000e RSI: 0000000000000112 RDI: 0000000000000018 RBP: 0000000000000000 R08: 00007fffcfbbbf44 R09: 0000000000000000 R10: 00007fffcfbbbf3c R11: 0000000000000203 R12: 0000000000000000 R13: 0000000000000018 R14: 0000000000000000 R15: 0000556fcefc70d0
--- net/bluetooth/hci_conn.c | 4 ---- 1 file changed, 4 deletions(-)
net/bluetooth/hci_conn.c +0 -4
@@ -1797,8 +1797,6 @@ u32 hci_conn_get_phy(struct hci_conn *conn) {u32 phys =0 ; -hci_dev_lock (conn->hdev); -/* BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 2, Part B page 471: * Table 6.2: Packets defined for synchronous, asynchronous, and * CSB logical transport types.
@@ -1895,7 +1893,5 @@ u32 hci_conn_get_phy(struct hci_conn *conn)break ; } -hci_dev_unlock (conn->hdev); -return phys; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 398/601 net: lapbether: Prevent racing when checking whether the netif is running
In reply to Greg Kroah-HartmanFrom: Xie He <[email protected]>
[ Upstream commit 5acd0cfbfbb5a688da1bfb1a2152b0c855115a35 ]
There are two "netif_running" checks in this driver. One is in "lapbeth_xmit" and the other is in "lapbeth_rcv". They serve to make sure that the LAPB APIs called in these functions are called before "lapb_unregister" is called by the "ndo_stop" function.
However, these "netif_running" checks are unreliable, because it's possible that immediately after "netif_running" returns true, "ndo_stop" is called (which causes "lapb_unregister" to be called).
This patch adds locking to make sure "lapbeth_xmit" and "lapbeth_rcv" can reliably check and ensure the netif is running while doing their work.
--- drivers/net/wan/lapbether.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-)
drivers/net/wan/lapbether.c +25 -7
@@ -51,6 +51,8 @@ struct lapbethdev {struct list_head node;struct net_device *ethdev;/* link to ethernet device */ struct net_device *axdev;/* lapbeth device (lapb#) */ +bool up; +spinlock_t up_lock;/* Protects "up" */ };static LIST_HEAD (lapbeth_devices);
@@ -101,8 +103,9 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packercu_read_lock (); lapbeth =lapbeth_get_x25_dev (dev);if (!lapbeth) - goto drop_unlock; -if (!netif_running (lapbeth->axdev)) + goto drop_unlock_rcu; +spin_lock_bh (&lapbeth->up_lock); +if (!lapbeth->up) goto drop_unlock; len = skb->data[0 ] + skb->data[1 ] *256 ;
@@ -117,11 +120,14 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe goto drop_unlock; } out: +spin_unlock_bh (&lapbeth->up_lock);rcu_read_unlock ();return 0 ; drop_unlock:kfree_skb (skb); goto out; +drop_unlock_rcu: +rcu_read_unlock (); drop:kfree_skb (skb);return 0 ;
@@ -151,13 +157,11 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)static netdev_tx_t lapbeth_xmit (struct sk_buff *skb,struct net_device *dev) { +struct lapbethdev *lapbeth =netdev_priv (dev);int err; -/* -* Just to be *really* sure not to send anything if the interface -* is down, the ethernet device may have gone. -*/ -if (!netif_running (dev)) +spin_lock_bh (&lapbeth->up_lock); +if (!lapbeth->up) goto drop;/* There should be a pseudo header of 1 byte added by upper layers.
@@ -194,6 +198,7 @@ static netdev_tx_t lapbeth_xmit(struct sk_buff *skb, goto drop; } out: +spin_unlock_bh (&lapbeth->up_lock);return NETDEV_TX_OK ; drop:kfree_skb (skb);
@@ -285,6 +290,7 @@ static const struct lapb_register_struct lapbeth_callbacks = {*/ static int lapbeth_open (struct net_device *dev) { +struct lapbethdev *lapbeth =netdev_priv (dev);int err;if ((err =lapb_register (dev, &lapbeth_callbacks)) !=LAPB_OK ) {
@@ -292,13 +298,22 @@ static int lapbeth_open(struct net_device *dev)return -ENODEV ; } +spin_lock_bh (&lapbeth->up_lock); + lapbeth->up = true; +spin_unlock_bh (&lapbeth->up_lock); +return 0 ; }static int lapbeth_close (struct net_device *dev) { +struct lapbethdev *lapbeth =netdev_priv (dev);int err; +spin_lock_bh (&lapbeth->up_lock); + lapbeth->up = false; +spin_unlock_bh (&lapbeth->up_lock); +if ((err =lapb_unregister (dev)) !=LAPB_OK )pr_err ("lapb_unregister error: %d\n" , err);
@@ -356,6 +371,9 @@ static int lapbeth_new_device(struct net_device *dev)dev_hold (dev); lapbeth->ethdev = dev; + lapbeth->up = false; +spin_lock_init (&lapbeth->up_lock); + rc = -EIO ;if (register_netdevice (ndev)) goto fail;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 399/601 libbpf: Add explicit padding to bpf_xdp_set_link_opts
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit dde7b3f5f2f458297aeccfd4783e53ab8ca046db ]
Adding such anonymous padding fixes the issue with uninitialized portions of bpf_xdp_set_link_opts when using LIBBPF_DECLARE_OPTS macro with inline field initialization:
DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = -1);
When such code is compiled in debug mode, compiler is generating code that leaves padding bytes uninitialized, which triggers error inside libbpf APIs that do strict zero initialization checks for OPTS structs.
Adding anonymous padding field fixes the issue.
--- tools/lib/bpf/libbpf.h | 1 + 1 file changed, 1 insertion(+)
tools/lib/bpf/libbpf.h +1 -0
@@ -507,6 +507,7 @@ struct xdp_link_info {struct bpf_xdp_set_link_opts {size_t sz;int old_fd; + size_t :0; };#define bpf_xdp_set_link_opts__last_field old_fd
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 400/601 bpftool: Fix maybe-uninitialized warnings
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 4bbb3583687051ef99966ddaeb1730441b777d40 ]
Somehow when bpftool is compiled in -Og mode, compiler produces new warnings about possibly uninitialized variables. Fix all the reported problems.
--- tools/bpf/bpftool/btf.c | 3 +++ tools/bpf/bpftool/main.c | 3 +-- tools/bpf/bpftool/map.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-)
tools/bpf/bpftool/btf.c +3 -0
@@ -538,6 +538,7 @@ static int do_dump(int argc, char **argv)NEXT_ARG ();if (argc <1 ) {p_err ("expecting value for 'format' option\n" ); + err = -EINVAL ; goto done; }if (strcmp (*argv,"c" ) ==0 ) {
@@ -547,11 +548,13 @@ static int do_dump(int argc, char **argv) }else {p_err ("unrecognized format specifier: '%s', possible values: raw, c" , *argv); + err = -EINVAL ; goto done; }NEXT_ARG (); }else {p_err ("unrecognized option: '%s'" , *argv); + err = -EINVAL ; goto done; } }
tools/bpf/bpftool/main.c +1 -2
@@ -276,7 +276,7 @@ static int do_batch(int argc, char **argv)int n_argc;FILE *fp;char *cp; -int err; +int err =0 ;int i;if (argc <2 ) {
@@ -370,7 +370,6 @@ static int do_batch(int argc, char **argv) }else {if (!json_output)printf ("processed %d commands\n" , lines); - err =0 ; } err_close:if (fp != stdin)
tools/bpf/bpftool/map.c +1 -1
@@ -100,7 +100,7 @@ static int do_dump_btf(const struct btf_dumper *d, void *value) {__u32 value_id; -int ret; +int ret =0 ;/* start of key-value pair */ jsonw_start_object (d->jw);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 401/601 iommu: Check dev->iommu in iommu_dev_xxx functions
In reply to Greg Kroah-HartmanFrom: Shameer Kolothum <[email protected]>
[ Upstream commit b9abb19fa5fd2d8a4be61c6cd4b2a48aa1a17f9c ]
The device iommu probe/attach might have failed leaving dev->iommu to NULL and device drivers may still invoke these functions resulting in a crash in iommu vendor driver code.
Hence make sure we check that.
--- drivers/iommu/iommu.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
drivers/iommu/iommu.c +15 -9
@@ -2889,10 +2889,12 @@ EXPORT_SYMBOL_GPL(iommu_dev_has_feature);int iommu_dev_enable_feature (struct device *dev,enum iommu_dev_features feat) { -const struct iommu_ops *ops = dev->bus->iommu_ops; +if (dev->iommu && dev->iommu->iommu_dev) { +const struct iommu_ops *ops = dev->iommu->iommu_dev->ops; -if (ops && ops->dev_enable_feat) -return ops->dev_enable_feat (dev, feat); +if (ops->dev_enable_feat) +return ops->dev_enable_feat (dev, feat); + }return -ENODEV ; }
@@ -2905,10 +2907,12 @@ EXPORT_SYMBOL_GPL(iommu_dev_enable_feature);*/ int iommu_dev_disable_feature (struct device *dev,enum iommu_dev_features feat) { -const struct iommu_ops *ops = dev->bus->iommu_ops; +if (dev->iommu && dev->iommu->iommu_dev) { +const struct iommu_ops *ops = dev->iommu->iommu_dev->ops; -if (ops && ops->dev_disable_feat) -return ops->dev_disable_feat (dev, feat); +if (ops->dev_disable_feat) +return ops->dev_disable_feat (dev, feat); + }return -EBUSY ; }
@@ -2916,10 +2920,12 @@ EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);bool iommu_dev_feature_enabled (struct device *dev,enum iommu_dev_features feat) { -const struct iommu_ops *ops = dev->bus->iommu_ops; +if (dev->iommu && dev->iommu->iommu_dev) { +const struct iommu_ops *ops = dev->iommu->iommu_dev->ops; -if (ops && ops->dev_feat_enabled) -return ops->dev_feat_enabled (dev, feat); +if (ops->dev_feat_enabled) +return ops->dev_feat_enabled (dev, feat); + }return false; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 402/601 dma-iommu: use static-key to minimize the impact in the fast-path
In reply to Greg Kroah-HartmanFrom: Lianbo Jiang <[email protected]>
[ Upstream commit a8e8af35c9f4f75f981a95488c7066d31bac4bef ]
Let's move out the is_kdump_kernel() check from iommu_dma_deferred_attach() to iommu_dma_init(), and use the static-key in the fast-path to minimize the impact in the normal case.
--- drivers/iommu/dma-iommu.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/iommu/dma-iommu.c +11 -6
@@ -51,6 +51,8 @@ struct iommu_dma_cookie {struct iommu_domain *fq_domain; }; +static DEFINE_STATIC_KEY_FALSE (iommu_deferred_attach_enabled); +void iommu_dma_free_cpu_cached_iovas (unsigned int cpu,struct iommu_domain *domain) {
@@ -389,9 +391,6 @@ static int iommu_dma_deferred_attach(struct device *dev, {const struct iommu_ops *ops = domain->ops; -if (!is_kdump_kernel ()) -return 0 ; -if (unlikely (ops->is_attach_deferred && ops->is_attach_deferred (domain, dev)))return iommu_attach_device (domain, dev);
@@ -536,7 +535,8 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,size_t iova_off =iova_offset (iovad, phys);dma_addr_t iova; -if (unlikely (iommu_dma_deferred_attach (dev, domain))) +if (static_branch_unlikely (&iommu_deferred_attach_enabled) && +iommu_dma_deferred_attach (dev, domain))return DMA_MAPPING_ERROR ; size =iova_align (iovad, size + iova_off);
@@ -694,7 +694,8 @@ static void *iommu_dma_alloc_remap(struct device *dev, size_t size, *dma_handle =DMA_MAPPING_ERROR ; -if (unlikely (iommu_dma_deferred_attach (dev, domain))) +if (static_branch_unlikely (&iommu_deferred_attach_enabled) && +iommu_dma_deferred_attach (dev, domain))return NULL ; min_size = alloc_sizes & -alloc_sizes;
@@ -977,7 +978,8 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,unsigned long mask =dma_get_seg_boundary (dev);int i; -if (unlikely (iommu_dma_deferred_attach (dev, domain))) +if (static_branch_unlikely (&iommu_deferred_attach_enabled) && +iommu_dma_deferred_attach (dev, domain))return 0 ;if (!(attrs &DMA_ATTR_SKIP_CPU_SYNC ))
@@ -1425,6 +1427,9 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc,static int iommu_dma_init (void ) { +if (is_kdump_kernel ()) +static_branch_enable (&iommu_deferred_attach_enabled); +return iova_cache_get (); }arch_initcall (iommu_dma_init);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 403/601 iommu/dma: Resurrect the "forcedac" option
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 3542dcb15cef66c0b9e6c3b33168eb657e0d9520 ]
In converting intel-iommu over to the common IOMMU DMA ops, it quietly lost the functionality of its "forcedac" option. Since this is a handy thing both for testing and for performance optimisation on certain platforms, reimplement it under the common IOMMU parameter namespace.
For the sake of fixing the inadvertent breakage of the Intel-specific parameter, remove the dmar_forcedac remnants and hook it up as an alias while documenting the transition to the new common parameter.
--- Documentation/admin-guide/kernel-parameters.txt | 15 ++++++++------- drivers/iommu/dma-iommu.c | 13 ++++++++++++- drivers/iommu/intel/iommu.c | 5 ++--- include/linux/dma-iommu.h | 2 ++ 4 files changed, 24 insertions(+), 11 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +8 -7
@@ -1854,13 +1854,6 @@ bypassed by not enabling DMAR with this option. In this case, gfx device will use physical address for DMA. - forcedac [X86-64] - With this option iommu will not optimize to look - for io virtual address below 32-bit forcing dual - address cycle on pci bus for cards supporting greater - than 32-bit addressing. The default is to look - for translation below 32-bit and if not available - then look in the higher range. strict [Default Off] With this option on every unmap_single operation will result in a hardware IOTLB flush operation as opposed
@@ -1949,6 +1942,14 @@ nobypass [PPC/POWERNV] Disable IOMMU bypass, using IOMMU for PCI devices. + iommu.forcedac= [ARM64, X86] Control IOVA allocation for PCI devices. + Format: { "0" | "1" } + 0 - Try to allocate a 32-bit DMA address first, before + falling back to the full range if needed. + 1 - Allocate directly from the full usable range, + forcing Dual Address Cycle for PCI cards supporting + greater than 32-bit addressing. + iommu.strict= [ARM64] Configure TLB invalidation behaviour Format: { "0" | "1" } 0 - Lazy mode.
drivers/iommu/dma-iommu.c +12 -1
@@ -52,6 +52,17 @@ struct iommu_dma_cookie { };static DEFINE_STATIC_KEY_FALSE (iommu_deferred_attach_enabled); +bool iommu_dma_forcedac__read_mostly ; + +static int __init iommu_dma_forcedac_setup (char *str) +{ +int ret =kstrtobool (str, &iommu_dma_forcedac); + +if (!ret && iommu_dma_forcedac) +pr_info ("Forcing DAC for PCI devices\n" ); +return ret; +} +early_param ("iommu.forcedac" , iommu_dma_forcedac_setup);void iommu_dma_free_cpu_cached_iovas (unsigned int cpu,struct iommu_domain *domain)
@@ -456,7 +467,7 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain, dma_limit =min (dma_limit, (u64 )domain->geometry.aperture_end);/* Try to get PCI devices a SAC address */ -if (dma_limit >DMA_BIT_MASK (32 ) &&dev_is_pci (dev)) +if (dma_limit >DMA_BIT_MASK (32 ) && !iommu_dma_forcedac &&dev_is_pci (dev)) iova =alloc_iova_fast (iovad, iova_len,DMA_BIT_MASK (32 ) >> shift, false);
drivers/iommu/intel/iommu.c +2 -3
@@ -350,7 +350,6 @@ int intel_iommu_enabled = 0;EXPORT_SYMBOL_GPL (intel_iommu_enabled);static int dmar_map_gfx =1 ; -static int dmar_forcedac;static int intel_iommu_strict;static int intel_iommu_superpage =1 ;static int iommu_identity_mapping;
@@ -441,8 +440,8 @@ static int __init intel_iommu_setup(char *str) dmar_map_gfx =0 ;pr_info ("Disable GFX device mapping\n" ); }else if (!strncmp (str,"forcedac" ,8 )) { -pr_info ("Forcing DAC for PCI devices\n" ); - dmar_forcedac =1 ; +pr_warn ("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n" ); + iommu_dma_forcedac = true; }else if (!strncmp (str,"strict" ,6 )) {pr_info ("Disable batched IOTLB flush\n" ); intel_iommu_strict =1 ;
include/linux/dma-iommu.h +2 -0
@@ -40,6 +40,8 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);void iommu_dma_free_cpu_cached_iovas (unsigned int cpu,struct iommu_domain *domain); +extern bool iommu_dma_forcedac; +#else /* CONFIG_IOMMU_DMA */ struct iommu_domain ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 404/601 iommu/vt-d: Reject unsupported page request modes
In reply to Greg Kroah-HartmanFrom: Jacob Pan <[email protected]>
[ Upstream commit 78a523fe73b81b4447beb2d6c78c9fafae24eebb ]
When supervisor/privilige mode SVM is used, we bind init_mm.pgd with a supervisor PASID. There should not be any page fault for init_mm. Execution request with DMA read is also not supported.
This patch checks PRQ descriptor for both unsupported configurations, reject them both with invalid responses.
--- drivers/iommu/intel/svm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/iommu/intel/svm.c +11 -1
@@ -959,7 +959,17 @@ static irqreturn_t prq_event_thread(int irq, void *d) ((unsigned long long *)req)[1]); goto no_pasid; } - +/* We shall not receive page request for supervisor SVM */ +if (req->pm_req && (req->rd_req | req->wr_req)) { +pr_err ("Unexpected page request in Privilege Mode" ); +/* No need to find the matching sdev as for bad_req */ + goto no_pasid; + } +/* DMA read with exec requeset is not supported. */ +if (req->exe_req && req->rd_req) { +pr_err ("Execution request not supported\n" ); + goto no_pasid; + }if (!svm || svm->pasid != req->pasid) {rcu_read_lock (); svm =ioasid_find (NULL , req->pasid,NULL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 405/601 selftests/bpf: Re-generate vmlinux.h and BPF skeletons if bpftool changed
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit cab62c37be057379a2a17b1b2eacd9dcba1e14dc ]
Trigger vmlinux.h and BPF skeletons re-generation if detected that bpftool was re-compiled. Otherwise full make clean is required to get updated skeletons, if bpftool is modified.
--- tools/testing/selftests/bpf/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/Makefile +3 -2
@@ -202,7 +202,7 @@ $(BUILD_DIR)/libbpf $(BUILD_DIR)/bpftool $(BUILD_DIR)/resolve_btfids $(INCLUDE_D $(call msg,MKDIR,,$@) $(Q)mkdir -p $@ -$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) | $(BPFTOOL) $(INCLUDE_DIR) +$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR) ifeq ($(VMLINUX_H),) $(call msg,GEN,,$@) $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
@@ -326,7 +326,8 @@ $(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.o: \ $(TRUNNER_BPF_SKELS): $(TRUNNER_OUTPUT)/%.skel.h: \ $(TRUNNER_OUTPUT)/%.o \ - | $(BPFTOOL) $(TRUNNER_OUTPUT) + $(BPFTOOL) \ + | $(TRUNNER_OUTPUT) $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) $(Q)$$(BPFTOOL) gen skeleton $$< > $$@ endif
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 406/601 libbpf: Add explicit padding to btf_dump_emit_type_decl_opts
In reply to Greg Kroah-HartmanFrom: KP Singh <[email protected]>
[ Upstream commit ea24b19562fe5f72c78319dbb347b701818956d9 ]
Similar to
https://lore.kernel.org/bpf/[email protected]/
When DECLARE_LIBBPF_OPTS is used with inline field initialization, e.g:
DECLARE_LIBBPF_OPTS(btf_dump_emit_type_decl_opts, opts,
.field_name = var_ident,
.indent_level = 2,
.strip_mods = strip_mods,
);
and compiled in debug mode, the compiler generates code which leaves the padding uninitialized and triggers errors within libbpf APIs which require strict zero initialization of OPTS structs.
Adding anonymous padding field fixes the issue.
--- tools/lib/bpf/btf.h | 1 + 1 file changed, 1 insertion(+)
tools/lib/bpf/btf.h +1 -0
@@ -173,6 +173,7 @@ struct btf_dump_emit_type_decl_opts {int indent_level;/* strip all the const/volatile/restrict mods */ bool strip_mods; + size_t :0; };#define btf_dump_emit_type_decl_opts__last_field strip_mods
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 407/601 powerpc/mm: Move the linear_mapping_mutex to the ifdef where it is used
In reply to Greg Kroah-HartmanFrom: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 9be77e11dade414d2fa63750aa5c754fac49d619 ]
The mutex linear_mapping_mutex is defined at the of the file while its only two user are within the CONFIG_MEMORY_HOTPLUG block.
A compile without CONFIG_MEMORY_HOTPLUG set fails on PREEMPT_RT because its mutex implementation is smart enough to realize that it is unused.
Move the definition of linear_mapping_mutex to ifdef block where it is used.
--- arch/powerpc/mm/mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/mem.c +1 -1
@@ -54,7 +54,6 @@#include <mm/mmu_decl.h> -static DEFINE_MUTEX (linear_mapping_mutex);unsigned long long memory_limit;bool init_mem_is_free;
@@ -72,6 +71,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,EXPORT_SYMBOL (phys_mem_access_prot);#ifdef CONFIG_MEMORY_HOTPLUG +static DEFINE_MUTEX (linear_mapping_mutex);#ifdef CONFIG_NUMA int memory_add_physaddr_to_nid (u64 start)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 408/601 powerpc/fadump: Mark fadump_calculate_reserve_size as __init
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit fbced1546eaaab57a32e56c974ea8acf10c6abd8 ]
If fadump_calculate_reserve_size() is not inlined, there is a modpost warning:
WARNING: modpost: vmlinux.o(.text+0x5196c): Section mismatch in reference from the function fadump_calculate_reserve_size() to the function .init.text:parse_crashkernel()
The function fadump_calculate_reserve_size() references the function __init parse_crashkernel().
This is often because fadump_calculate_reserve_size lacks a __init annotation or the annotation of parse_crashkernel is wrong.
fadump_calculate_reserve_size() calls parse_crashkernel(), which is marked as __init and fadump_calculate_reserve_size() is called from within fadump_reserve_mem(), which is also marked as __init.
Mark fadump_calculate_reserve_size() as __init to fix the section mismatch. Additionally, remove the inline keyword as it is not necessary to inline this function; the compiler is still free to do so if it feels it is worthwhile since commit 889b3c1245de ("compiler: remove CONFIG_OPTIMIZE_INLINING entirely").
--- arch/powerpc/kernel/fadump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/fadump.c +1 -1
@@ -292,7 +292,7 @@ static void fadump_show_config(void)* that is required for a kernel to boot successfully. * */ -static inline u64 fadump_calculate_reserve_size (void ) +static __init u64 fadump_calculate_reserve_size (void ) {u64 base, size, bootmem_min;int ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 409/601 powerpc/prom: Mark identical_pvr_fixup as __init
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 1ef1dd9c7ed27b080445e1576e8a05957e0e4dfc ]
If identical_pvr_fixup() is not inlined, there are two modpost warnings:
WARNING: modpost: vmlinux.o(.text+0x54e8): Section mismatch in reference from the function identical_pvr_fixup() to the function .init.text:of_get_flat_dt_prop()
The function identical_pvr_fixup() references
the function __init of_get_flat_dt_prop().
This is often because identical_pvr_fixup lacks a __init annotation or the annotation of of_get_flat_dt_prop is wrong.
WARNING: modpost: vmlinux.o(.text+0x551c): Section mismatch in reference from the function identical_pvr_fixup() to the function .init.text:identify_cpu()
The function identical_pvr_fixup() references
the function __init identify_cpu().
This is often because identical_pvr_fixup lacks a __init annotation or the annotation of identify_cpu is wrong.
identical_pvr_fixup() calls two functions marked as __init and is only called by a function marked as __init so it should be marked as __init as well. At the same time, remove the inline keywork as it is not necessary to inline this function. The compiler is still free to do so if it feels it is worthwhile since commit 889b3c1245de ("compiler:
remove CONFIG_OPTIMIZE_INLINING entirely").
--- arch/powerpc/kernel/prom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/prom.c +1 -1
@@ -267,7 +267,7 @@ static struct feature_property { };#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU ) -static inline void identical_pvr_fixup (unsigned long node) +static __init void identical_pvr_fixup (unsigned long node) {unsigned int pvr;const char *model =of_get_flat_dt_prop (node,"model" ,NULL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 410/601 MIPS: fix local_irq_{disable,enable} in asmmacro.h
In reply to Greg Kroah-HartmanFrom: Huang Pei <[email protected]>
[ Upstream commit 05c4e2721d7af0df7bc1378a23712a0fd16947b5 ]
commit ba9196d2e005 ("MIPS: Make DIEI support as a config option") use CPU_HAS_DIEI to indicate whether di/ei is implemented correctly, without this patch, "local_irq_disable" from entry.S in 3A1000 (with buggy di/ei) lose protection of commit e97c5b609880 ("MIPS:
Make irqflags.h functions preempt-safe for non-mipsr2 cpus")
--- arch/mips/include/asm/asmmacro.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/mips/include/asm/asmmacro.h +1 -2
@@ -44,8 +44,7 @@ .endm#endif -#if defined(CONFIG_CPU_MIPSR2 ) || defined(CONFIG_CPU_MIPSR5 ) || \ - defined(CONFIG_CPU_MIPSR6 ) +#ifdef CONFIG_CPU_HAS_DIEI .macro local_irq_enable reg=t0ei irq_enable_hazard
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 411/601 ima: Fix the error code for restoring the PCR value
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
[ Upstream commit 7990ccafaa37dc6d8bb095d4d7cd997e8903fd10 ]
In ima_restore_measurement_list(), hdr[HDR_PCR].data is pointing to a buffer of type u8, which contains the dumped 32-bit pcr value. Currently, only the least significant byte is used to restore the pcr value. We should convert hdr[HDR_PCR].data to a pointer of type u32 before fetching the value to restore the correct pcr value.
--- security/integrity/ima/ima_template.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
security/integrity/ima/ima_template.c +2 -2
@@ -494,8 +494,8 @@ int ima_restore_measurement_list(loff_t size, void *buf) } } - entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR ].data) : -le32_to_cpu (*(hdr[HDR_PCR ].data)); + entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR ].data) : +le32_to_cpu (*(u32 *)(hdr[HDR_PCR ].data)); ret =ima_restore_measurement_entry (entry);if (ret <0 )break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 412/601 inet: use bigger hash table for IP ID generation
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit aa6dd211e4b1dde9d5dc25d699d35f789ae7eeba ]
In commit 73f156a6e8c1 ("inetpeer: get rid of ip_id_count") I used a very small hash table that could be abused by patient attackers to reveal sensitive information.
Switch to a dynamic sizing, depending on RAM size.
Typical big hosts will now use 128x more storage (2 MB) to get a similar increase in security and reduction of hash collisions.
As a bonus, use of alloc_large_system_hash() spreads allocated memory among all NUMA nodes.
--- net/ipv4/route.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-)
net/ipv4/route.c +28 -14
@@ -66,6 +66,7 @@#include <linux/types.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/memblock.h> #include <linux/string.h> #include <linux/socket.h> #include <linux/sockios.h>
@@ -476,8 +477,10 @@ static void ipv4_confirm_neigh(const struct dst_entry *dst, const void *daddr)__ipv4_confirm_neigh (dev, *(__force u32 *)pkey); } -#define IP_IDENTS_SZ 2048u - +/* Hash tables of size 2048..262144 depending on RAM size. +* Each bucket uses 8 bytes. +*/ +static u32 ip_idents_mask__read_mostly ;static atomic_t *ip_idents__read_mostly ;static u32 *ip_tstamps__read_mostly ;
@@ -487,12 +490,16 @@ static u32 *ip_tstamps __read_mostly;*/ u32 ip_idents_reserve (u32 hash,int segs) { -u32 *p_tstamp = ip_tstamps + hash %IP_IDENTS_SZ ; -atomic_t *p_id = ip_idents + hash %IP_IDENTS_SZ ; -u32 old =READ_ONCE (*p_tstamp); -u32 now = (u32 )jiffies; +u32 bucket, old, now = (u32 )jiffies; +atomic_t *p_id; +u32 *p_tstamp;u32 delta =0 ; + bucket = hash & ip_idents_mask; + p_tstamp = ip_tstamps + bucket; + p_id = ip_idents + bucket; + old =READ_ONCE (*p_tstamp); +if (old != now &&cmpxchg (p_tstamp, old, now) == old) delta =prandom_u32_max (now - old);
@@ -3547,18 +3554,25 @@ struct ip_rt_acct __percpu *ip_rt_acct __read_mostly;int __init ip_rt_init (void ) { +void *idents_hash;int cpu; - ip_idents =kmalloc_array (IP_IDENTS_SZ ,sizeof (*ip_idents), -GFP_KERNEL ); -if (!ip_idents) -panic ("IP: failed to allocate ip_idents\n" ); +/* For modern hosts, this will use 2 MB of memory */ + idents_hash =alloc_large_system_hash ("IP idents" , +sizeof (*ip_idents) +sizeof (*ip_tstamps), +0 , +16 ,/* one bucket per 64 KB */ +HASH_ZERO , +NULL , + &ip_idents_mask, +2048 , +256 *1024 ); + + ip_idents = idents_hash; -prandom_bytes (ip_idents,IP_IDENTS_SZ *sizeof (*ip_idents)); +prandom_bytes (ip_idents, (ip_idents_mask +1 ) *sizeof (*ip_idents)); - ip_tstamps =kcalloc (IP_IDENTS_SZ ,sizeof (*ip_tstamps),GFP_KERNEL ); -if (!ip_tstamps) -panic ("IP: failed to allocate ip_tstamps\n" ); + ip_tstamps = idents_hash + (ip_idents_mask +1 ) *sizeof (*ip_idents);for_each_possible_cpu (cpu) {struct uncached_list *ul = &per_cpu (rt_uncached_list, cpu);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 413/601 pinctrl: pinctrl-single: remove unused parameter
In reply to Greg Kroah-HartmanFrom: Hanna Hawa <[email protected]>
[ Upstream commit 8fa2ea202b13b6da81e26c399ff1d87488398453 ]
Remove unused parameter 'pin_pos' from pcs_add_pin().
--- drivers/pinctrl/pinctrl-single.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/pinctrl/pinctrl-single.c +2 -6
@@ -656,10 +656,8 @@ static const struct pinconf_ops pcs_pinconf_ops = {* pcs_add_pin() - add a pin to the static per controller pin array * @pcs: pcs driver instance * @offset: register offset from base -* @pin_pos: unused */ -static int pcs_add_pin (struct pcs_device *pcs,unsigned offset, -unsigned pin_pos) +static int pcs_add_pin (struct pcs_device *pcs,unsigned int offset) {struct pcs_soc_data *pcs_soc = &pcs->socdata;struct pinctrl_pin_desc *pin;
@@ -729,16 +727,14 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)unsigned offset;int res;int byte_num; -int pin_pos =0 ;if (pcs->bits_per_mux) { byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; offset = (byte_num / mux_bytes) * mux_bytes; - pin_pos = i % num_pins_in_register; }else { offset = i * mux_bytes; } - res =pcs_add_pin (pcs, offset, pin_pos); + res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res);return res;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 414/601 pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero
In reply to Greg Kroah-HartmanFrom: Hanna Hawa <[email protected]>
[ Upstream commit bd85125ea88513f637a62a72e8949c579c5c0a87 ]
A System Error (SError, followed by kernel panic) was detected when trying to print the supported pins in a pinctrl device which supports multiple pins per register. This change fixes the pcs_pin_dbg_show() in pinctrl-single driver when bits_per_mux is not zero. In addition move offset calculation and pin offset in register to common function.
--- drivers/pinctrl/pinctrl-single.c | 55 ++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 20 deletions(-)
drivers/pinctrl/pinctrl-single.c +35 -20
@@ -270,20 +270,44 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)writel (val, reg); } +static unsigned int pcs_pin_reg_offset_get (struct pcs_device *pcs, +unsigned int pin) +{ +unsigned int mux_bytes = pcs->width /BITS_PER_BYTE ; + +if (pcs->bits_per_mux) { +unsigned int pin_offset_bytes; + + pin_offset_bytes = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; +return (pin_offset_bytes / mux_bytes) * mux_bytes; + } + +return pin * mux_bytes; +} + +static unsigned int pcs_pin_shift_reg_get (struct pcs_device *pcs, +unsigned int pin) +{ +return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin; +} +static void pcs_pin_dbg_show (struct pinctrl_dev *pctldev,struct seq_file *s,unsigned pin) {struct pcs_device *pcs; -unsigned val, mux_bytes; +unsigned int val;unsigned long offset;size_t pa; pcs =pinctrl_dev_get_drvdata (pctldev); - mux_bytes = pcs->width /BITS_PER_BYTE ; - offset = pin * mux_bytes; + offset =pcs_pin_reg_offset_get (pcs, pin); val = pcs->read (pcs->base + offset); + +if (pcs->bits_per_mux) + val &= pcs->fmask <<pcs_pin_shift_reg_get (pcs, pin); + pa = pcs->res->start + offset;seq_printf (s,"%zx %08x %s " , pa, val,DRIVER_NAME );
@@ -384,7 +408,6 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,struct pcs_device *pcs =pinctrl_dev_get_drvdata (pctldev);struct pcs_gpiofunc_range *frange =NULL ;struct list_head *pos, *tmp; -int mux_bytes =0 ;unsigned data;/* If function mask is null, return directly. */
@@ -392,29 +415,27 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,return -ENOTSUPP ;list_for_each_safe (pos, tmp, &pcs->gpiofuncs) { +u32 offset; + frange = list_entry(pos, struct pcs_gpiofunc_range, node);if (pin >= frange->offset + frange->npins || pin < frange->offset)continue ; - mux_bytes = pcs->width /BITS_PER_BYTE ; -if (pcs->bits_per_mux) { -int byte_num, offset, pin_shift; + offset =pcs_pin_reg_offset_get (pcs, pin); - byte_num = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - pin_shift = pin % (pcs->width / pcs->bits_per_pin) * - pcs->bits_per_pin; +if (pcs->bits_per_mux) { +int pin_shift =pcs_pin_shift_reg_get (pcs, pin); data = pcs->read (pcs->base + offset); data &= ~(pcs->fmask << pin_shift); data |= frange->gpiofunc << pin_shift; pcs->write (data, pcs->base + offset); }else { - data = pcs->read (pcs->base + pin * mux_bytes); + data = pcs->read (pcs->base + offset); data &= ~pcs->fmask; data |= frange->gpiofunc; - pcs->write (data, pcs->base + pin * mux_bytes); + pcs->write (data, pcs->base + offset); }break ; }
@@ -726,14 +747,8 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)for (i =0 ; i < pcs->desc.npins; i++) {unsigned offset;int res; -int byte_num; -if (pcs->bits_per_mux) { - byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - }else { - offset = i * mux_bytes; - } + offset =pcs_pin_reg_offset_get (pcs, i); res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 415/601 MIPS: loongson64: fix bug when PAGE_SIZE > 16KB
In reply to Greg Kroah-HartmanFrom: Huang Pei <[email protected]>
[ Upstream commit 509d36a941a3466b78d4377913623d210b162458 ]
When page size larger than 16KB, arguments "vaddr + size(16KB)" in "ioremap_page_range(vaddr, vaddr + size,...)" called by "add_legacy_isa_io" is not page-aligned.
As loongson64 needs at least page size 16KB to get rid of cache alias, and "vaddr" is 64KB-aligned, and 64KB is largest page size supported, rounding "size" up to PAGE_SIZE is enough for all page size supported.
--- arch/mips/loongson64/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/loongson64/init.c +1 -1
@@ -82,7 +82,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, resource_size_return -ENOMEM ; range->fwnode = fwnode; - range->size = size; + range->size = size =round_up (size,PAGE_SIZE ); range->hw_start = hw_start; range->flags =LOGIC_PIO_CPU_MMIO ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 416/601 ASoC: wm8960: Remove bitclk relax condition in wm8960_configure_sysclk
In reply to Greg Kroah-HartmanFrom: Shengjiu Wang <[email protected]>
[ Upstream commit 99067c07e8d877035f6249d194a317c78b7d052d ]
The call sequence in wm8960_configure_clocking is
ret = wm8960_configure_sysclk();
if (ret >= 0)
goto configure_clock;....
ret = wm8960_configure_pll();
configure_clock:
...
wm8960_configure_sysclk is called before wm8960_configure_pll, as there is bitclk relax on both functions, so wm8960_configure_sysclk always return success, then wm8960_configure_pll() never be called.
With this case:
aplay -Dhw:0,0 -d 5 -r 48000 -f S24_LE -c 2 audio48k24b2c.wav the required bitclk is 48000 * 24 * 2 = 2304000, bitclk got from wm8960_configure_sysclk is 3072000, but if go to wm8960_configure_pll. it can get correct bitclk 2304000.
So bitclk relax condition should be removed in wm8960_configure_sysclk, then wm8960_configure_pll can be called, and there is also bitclk relax function in wm8960_configure_pll.
--- sound/soc/codecs/wm8960.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
sound/soc/codecs/wm8960.c +1 -11
@@ -608,10 +608,6 @@ static const int bclk_divs[] = {* - lrclk = sysclk / dac_divs * - 10 * bclk = sysclk / bclk_divs * -* If we cannot find an exact match for (sysclk, lrclk, bclk) -* triplet, we relax the bclk such that bclk is chosen as the -* closest available frequency greater than expected bclk. -* * @wm8960: codec private data * @mclk: MCLK used to derive sysclk * @sysclk_idx: sysclk_divs index for found sysclk
@@ -629,7 +625,7 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk, {int sysclk, bclk, lrclk;int i, j, k; -int diff, closest = mclk; +int diff;/* marker for no match */ *bclk_idx =-1 ;
@@ -653,12 +649,6 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk, *bclk_idx = k;break ; } -if (diff >0 && closest > diff) { - *sysclk_idx = i; - *dac_idx = j; - *bclk_idx = k; - closest = diff; - } }if (k !=ARRAY_SIZE (bclk_divs))break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 417/601 iommu/arm-smmu-v3: add bit field SFM into GERROR_ERR_MASK
In reply to Greg Kroah-HartmanFrom: Zhen Lei <[email protected]>
[ Upstream commit 655c447c97d7fe462e6cd9e15809037be028bc70 ]
In arm_smmu_gerror_handler(), the value of the SMMU_GERROR register is filtered by GERROR_ERR_MASK. However, the GERROR_ERR_MASK does not contain the SFM bit. As a result, the subsequent error processing is not performed when only the SFM error occurs.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -1
@@ -115,7 +115,7 @@#define GERROR_PRIQ_ABT_ERR (1 << 3)#define GERROR_EVTQ_ABT_ERR (1 << 2)#define GERROR_CMDQ_ERR (1 << 0) -#define GERROR_ERR_MASK 0xfd +#define GERROR_ERR_MASK 0x1fd#define ARM_SMMU_GERRORN 0x64
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 418/601 RDMA/mlx5: Fix drop packet rule in egress table
In reply to Greg Kroah-HartmanFrom: Maor Gottlieb <[email protected]>
[ Upstream commit c73700806d4e430d182c2be069d230076818a99a ]
Initial drop action support missed that drop action can be added to egress flow tables as well. Add the missing support.
This requires making sure that dest_type isn't set to PORT which in turn exposes a possibility of passing dst while indicating number of dsts as zero. Explicitly check for number of dsts and pass the appropriate pointer.
--- drivers/infiniband/hw/mlx5/fs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/infiniband/hw/mlx5/fs.c +5 -4
@@ -1528,8 +1528,8 @@ static struct mlx5_ib_flow_handler *raw_fs_rule_add( dst_num++; } - handler =_create_raw_flow_rule (dev, ft_prio, dst, fs_matcher, - flow_context, flow_act, + handler =_create_raw_flow_rule (dev, ft_prio, dst_num ? dst :NULL , + fs_matcher, flow_context, flow_act, cmd_in, inlen, dst_num);if (IS_ERR (handler)) {
@@ -1885,8 +1885,9 @@ static int get_dests(struct uverbs_attr_bundle *attrs,else *dest_id = mqp->raw_packet_qp.rq.tirn; *dest_type =MLX5_FLOW_DESTINATION_TYPE_TIR ; - }else if (fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_EGRESS || - fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_RDMA_TX ) { + }else if ((fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_EGRESS || + fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_RDMA_TX ) && + !(*flags &MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP )) { *dest_type =MLX5_FLOW_DESTINATION_TYPE_PORT ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 419/601 IB/isert: Fix a use after free in isert_connect_request
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit adb76a520d068a54ee5ca82e756cf8e5a47363a4 ]
The device is got by isert_device_get() with refcount is 1, and is assigned to isert_conn by
isert_conn->device = device.
When isert_create_qp() failed, device will be freed with isert_device_put().
Later, the device is used in isert_free_login_buf(isert_conn) by the isert_conn->device->ib_device statement.
Free the device in the correct order.
--- drivers/infiniband/ulp/isert/ib_isert.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/infiniband/ulp/isert/ib_isert.c +8 -8
@@ -438,23 +438,23 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)isert_init_conn (isert_conn); isert_conn->cm_id = cma_id; - ret =isert_alloc_login_buf (isert_conn, cma_id->device); -if (ret) - goto out; - device =isert_device_get (cma_id);if (IS_ERR (device)) { ret =PTR_ERR (device); - goto out_rsp_dma_map; + goto out; } isert_conn->device = device; + ret =isert_alloc_login_buf (isert_conn, cma_id->device); +if (ret) + goto out_conn_dev; +isert_set_nego_params (isert_conn, &event->param.conn); isert_conn->qp =isert_create_qp (isert_conn, cma_id);if (IS_ERR (isert_conn->qp)) { ret =PTR_ERR (isert_conn->qp); - goto out_conn_dev; + goto out_rsp_dma_map; } ret =isert_login_post_recv (isert_conn);
@@ -473,10 +473,10 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) out_destroy_qp:isert_destroy_qp (isert_conn); -out_conn_dev: -isert_device_put (device); out_rsp_dma_map:isert_free_login_buf (isert_conn); +out_conn_dev: +isert_device_put (device); out:kfree (isert_conn);rdma_reject (cma_id,NULL ,0 ,IB_CM_REJ_CONSUMER_DEFINED );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 420/601 powerpc: Fix HAVE_HARDLOCKUP_DETECTOR_ARCH build configuration
In reply to Greg Kroah-HartmanFrom: Chen Huang <[email protected]>
[ Upstream commit 4fe529449d85e78972fa327999961ecc83a0b6db ]
When compiling the powerpc with the SMP disabled, it shows the issue:
arch/powerpc/kernel/watchdog.c: In function ‘watchdog_smp_panic’:arch/powerpc/kernel/watchdog.c:177:4: error: implicit declaration of function ‘smp_send_nmi_ipi’; did you mean ‘smp_send_stop’? [-Werror=implicit-function-declaration]
177 | smp_send_nmi_ipi(c, wd_lockup_ipi, 1000000);
| ^~~~~~~~~~~~~~~~
| smp_send_stopcc1: all warnings being treated as errors
make[2]: *** [scripts/Makefile.build:273: arch/powerpc/kernel/watchdog.o] Error 1 make[1]: *** [scripts/Makefile.build:534: arch/powerpc/kernel] Error 2
make: *** [Makefile:1980: arch/powerpc] Error 2
make: *** Waiting for unfinished jobs....
We found that powerpc used ipi to implement hardlockup watchdog, so the HAVE_HARDLOCKUP_DETECTOR_ARCH should depend on the SMP.
--- arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/Kconfig +1 -1
@@ -225,7 +225,7 @@ config PPC select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) - select HAVE_HARDLOCKUP_DETECTOR_ARCH if (PPC64 && PPC_BOOK3S) + select HAVE_HARDLOCKUP_DETECTOR_ARCH if PPC64 && PPC_BOOK3S && SMP select HAVE_OPROFILE select HAVE_OPTPROBES if PPC64 select HAVE_PERF_EVENTS
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 421/601 MIPS/bpf: Enable bpf_probe_read{, str}() on MIPS again
In reply to Greg Kroah-HartmanFrom: Tiezhu Yang <[email protected]>
[ Upstream commit 66633abd0642f1e89d26e15f36fb13d3a1c535ff ]
After commit 0ebeea8ca8a4 ("bpf: Restrict bpf_probe_read{, str}() only to archs where they work"), bpf_probe_read{, str}() functions were no longer available on MIPS, so there exist some errors when running bpf program:
root@linux:/home/loongson/bcc# python examples/tracing/task_switch.py bpf: Failed to load program: Invalid argument [...] 11: (85) call bpf_probe_read#4 unknown func bpf_probe_read#4 [...] Exception: Failed to load BPF program count_sched: Invalid argument
ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE should be restricted to archs with non-overlapping address ranges, but they can overlap in EVA mode on MIPS, so select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA in arch/mips/Kconfig, otherwise the bpf old helper bpf_probe_read() will not be available.
This is similar with the commit d195b1d1d119 ("powerpc/bpf: Enable bpf_probe_read{, str}() on powerpc again").
--- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/mips/Kconfig +1 -0
@@ -6,6 +6,7 @@ config MIPS select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_KCOV + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI) select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UBSAN_SANITIZE_ALL
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 422/601 gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP
In reply to Greg Kroah-HartmanFrom: Álvaro Fernández Rojas <[email protected]>
[ Upstream commit 9c7d24693d864f90b27aad5d15fbfe226c02898b ]
The current code doesn't check if GPIOLIB_IRQCHIP is enabled, which results in a compilation error when trying to build gpio-regmap if CONFIG_GPIOLIB_IRQCHIP isn't enabled.
--- include/linux/gpio/driver.h | 9 +++++++++ 1 file changed, 9 insertions(+)
include/linux/gpio/driver.h +9 -0
@@ -624,8 +624,17 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain,bool gpiochip_irqchip_irq_valid (const struct gpio_chip *gc,unsigned int offset); +#ifdef CONFIG_GPIOLIB_IRQCHIP int gpiochip_irqchip_add_domain (struct gpio_chip *gc,struct irq_domain *domain); +#else +static inline int gpiochip_irqchip_add_domain (struct gpio_chip *gc, +struct irq_domain *domain) +{ +WARN_ON (1 ); +return -EINVAL ; +} +#endif int gpiochip_generic_request (struct gpio_chip *gc,unsigned int offset);void gpiochip_generic_free (struct gpio_chip *gc,unsigned int offset);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 423/601 fs: dlm: fix missing unlock on error in accept_from_sock()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 2fd8db2dd05d895961c7c7b9fa02d72f385560e4 ]
Add the missing unlock before return from accept_from_sock() in the error handling case.
--- fs/dlm/lowcomms.c | 1 + 1 file changed, 1 insertion(+)
fs/dlm/lowcomms.c +1 -0
@@ -908,6 +908,7 @@ static int accept_from_sock(struct listen_connection *con) result =dlm_con_init (othercon, nodeid);if (result <0 ) {kfree (othercon); +mutex_unlock (&newcon->sock_mutex); goto accept_err; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 424/601 ASoC: q6afe-clocks: fix reprobing of the driver
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit 96fadf7e8ff49fdb74754801228942b67c3eeebd ]
Q6afe-clocks driver can get reprobed. For example if the APR services are restarted after the firmware crash. However currently Q6afe-clocks driver will oops because hw.init will get cleared during first _probe call. Rewrite the driver to fill the clock data at runtime rather than using big static array of clocks.
--- sound/soc/qcom/qdsp6/q6afe-clocks.c | 209 ++++++++++++++-------------- sound/soc/qcom/qdsp6/q6afe.c | 2 +- sound/soc/qcom/qdsp6/q6afe.h | 2 +- 3 files changed, 108 insertions(+), 105 deletions(-)
sound/soc/qcom/qdsp6/q6afe-clocks.c +106 -103
@@ -11,33 +11,29 @@#include <linux/slab.h> #include "q6afe.h" -#define Q6AFE_CLK (id) &(struct q6afe_clk) { \ +#define Q6AFE_CLK (id) { \ .clk_id = id, \ .afe_clk_id = Q6AFE_##id, \ .name = #id, \ - .attributes = LPASS_CLK_ATTRIBUTE_COUPLE_NO, \ .rate = 19200000, \ - .hw.init = &(struct clk_init_data) { \ - .ops = &clk_q6afe_ops, \ - .name = #id, \ - }, \ } -#define Q6AFE_VOTE_CLK (id, blkid, n) &(struct q6afe_clk) { \ +#define Q6AFE_VOTE_CLK (id, blkid, n) { \ .clk_id = id, \ .afe_clk_id = blkid, \ - .name = #n, \ - .hw.init = &(struct clk_init_data) { \ - .ops = &clk_vote_q6afe_ops, \ - .name = #id, \ - }, \ + .name = n, \ } -struct q6afe_clk { -struct device *dev; +struct q6afe_clk_init {int clk_id;int afe_clk_id;char *name; +int rate; +}; + +struct q6afe_clk { +struct device *dev; +int afe_clk_id;int attributes;int rate;uint32_t handle;
@@ -48,8 +44,7 @@ struct q6afe_clk {struct q6afe_cc {struct device *dev; -struct q6afe_clk **clks; -int num_clks; +struct q6afe_clk *clks[Q6AFE_MAX_CLK_ID ]; };static int clk_q6afe_prepare (struct clk_hw *hw)
@@ -105,7 +100,7 @@ static int clk_vote_q6afe_block(struct clk_hw *hw)struct q6afe_clk *clk =to_q6afe_clk (hw);return q6afe_vote_lpass_core_hw (clk->dev, clk->afe_clk_id, - clk->name, &clk->handle); +clk_hw_get_name (&clk->hw), &clk->handle); }static void clk_unvote_q6afe_block (struct clk_hw *hw)
@@ -120,84 +115,76 @@ static const struct clk_ops clk_vote_q6afe_ops = { .unprepare = clk_unvote_q6afe_block, }; -static struct q6afe_clk *q6afe_clks[Q6AFE_MAX_CLK_ID ] = { - [LPASS_CLK_ID_PRI_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_PRI_MI2S_IBIT ), - [LPASS_CLK_ID_PRI_MI2S_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_PRI_MI2S_EBIT ), - [LPASS_CLK_ID_SEC_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEC_MI2S_IBIT ), - [LPASS_CLK_ID_SEC_MI2S_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEC_MI2S_EBIT ), - [LPASS_CLK_ID_TER_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_TER_MI2S_IBIT ), - [LPASS_CLK_ID_TER_MI2S_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_TER_MI2S_EBIT ), - [LPASS_CLK_ID_QUAD_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUAD_MI2S_IBIT ), - [LPASS_CLK_ID_QUAD_MI2S_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUAD_MI2S_EBIT ), - [LPASS_CLK_ID_SPEAKER_I2S_IBIT ] = -Q6AFE_CLK (LPASS_CLK_ID_SPEAKER_I2S_IBIT ), - [LPASS_CLK_ID_SPEAKER_I2S_EBIT ] = -Q6AFE_CLK (LPASS_CLK_ID_SPEAKER_I2S_EBIT ), - [LPASS_CLK_ID_SPEAKER_I2S_OSR ] = -Q6AFE_CLK (LPASS_CLK_ID_SPEAKER_I2S_OSR ), - [LPASS_CLK_ID_QUI_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUI_MI2S_IBIT ), - [LPASS_CLK_ID_QUI_MI2S_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUI_MI2S_EBIT ), - [LPASS_CLK_ID_SEN_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEN_MI2S_IBIT ), - [LPASS_CLK_ID_SEN_MI2S_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEN_MI2S_EBIT ), - [LPASS_CLK_ID_INT0_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT0_MI2S_IBIT ), - [LPASS_CLK_ID_INT1_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT1_MI2S_IBIT ), - [LPASS_CLK_ID_INT2_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT2_MI2S_IBIT ), - [LPASS_CLK_ID_INT3_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT3_MI2S_IBIT ), - [LPASS_CLK_ID_INT4_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT4_MI2S_IBIT ), - [LPASS_CLK_ID_INT5_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT5_MI2S_IBIT ), - [LPASS_CLK_ID_INT6_MI2S_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_INT6_MI2S_IBIT ), - [LPASS_CLK_ID_QUI_MI2S_OSR ] =Q6AFE_CLK (LPASS_CLK_ID_QUI_MI2S_OSR ), - [LPASS_CLK_ID_PRI_PCM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_PRI_PCM_IBIT ), - [LPASS_CLK_ID_PRI_PCM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_PRI_PCM_EBIT ), - [LPASS_CLK_ID_SEC_PCM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEC_PCM_IBIT ), - [LPASS_CLK_ID_SEC_PCM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEC_PCM_EBIT ), - [LPASS_CLK_ID_TER_PCM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_TER_PCM_IBIT ), - [LPASS_CLK_ID_TER_PCM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_TER_PCM_EBIT ), - [LPASS_CLK_ID_QUAD_PCM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUAD_PCM_IBIT ), - [LPASS_CLK_ID_QUAD_PCM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUAD_PCM_EBIT ), - [LPASS_CLK_ID_QUIN_PCM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUIN_PCM_IBIT ), - [LPASS_CLK_ID_QUIN_PCM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUIN_PCM_EBIT ), - [LPASS_CLK_ID_QUI_PCM_OSR ] =Q6AFE_CLK (LPASS_CLK_ID_QUI_PCM_OSR ), - [LPASS_CLK_ID_PRI_TDM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_PRI_TDM_IBIT ), - [LPASS_CLK_ID_PRI_TDM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_PRI_TDM_EBIT ), - [LPASS_CLK_ID_SEC_TDM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEC_TDM_IBIT ), - [LPASS_CLK_ID_SEC_TDM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_SEC_TDM_EBIT ), - [LPASS_CLK_ID_TER_TDM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_TER_TDM_IBIT ), - [LPASS_CLK_ID_TER_TDM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_TER_TDM_EBIT ), - [LPASS_CLK_ID_QUAD_TDM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUAD_TDM_IBIT ), - [LPASS_CLK_ID_QUAD_TDM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUAD_TDM_EBIT ), - [LPASS_CLK_ID_QUIN_TDM_IBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUIN_TDM_IBIT ), - [LPASS_CLK_ID_QUIN_TDM_EBIT ] =Q6AFE_CLK (LPASS_CLK_ID_QUIN_TDM_EBIT ), - [LPASS_CLK_ID_QUIN_TDM_OSR ] =Q6AFE_CLK (LPASS_CLK_ID_QUIN_TDM_OSR ), - [LPASS_CLK_ID_MCLK_1 ] =Q6AFE_CLK (LPASS_CLK_ID_MCLK_1 ), - [LPASS_CLK_ID_MCLK_2 ] =Q6AFE_CLK (LPASS_CLK_ID_MCLK_2 ), - [LPASS_CLK_ID_MCLK_3 ] =Q6AFE_CLK (LPASS_CLK_ID_MCLK_3 ), - [LPASS_CLK_ID_MCLK_4 ] =Q6AFE_CLK (LPASS_CLK_ID_MCLK_4 ), - [LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE ] = -Q6AFE_CLK (LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE ), - [LPASS_CLK_ID_INT_MCLK_0 ] =Q6AFE_CLK (LPASS_CLK_ID_INT_MCLK_0 ), - [LPASS_CLK_ID_INT_MCLK_1 ] =Q6AFE_CLK (LPASS_CLK_ID_INT_MCLK_1 ), - [LPASS_CLK_ID_WSA_CORE_MCLK ] =Q6AFE_CLK (LPASS_CLK_ID_WSA_CORE_MCLK ), - [LPASS_CLK_ID_WSA_CORE_NPL_MCLK ] = -Q6AFE_CLK (LPASS_CLK_ID_WSA_CORE_NPL_MCLK ), - [LPASS_CLK_ID_VA_CORE_MCLK ] =Q6AFE_CLK (LPASS_CLK_ID_VA_CORE_MCLK ), - [LPASS_CLK_ID_TX_CORE_MCLK ] =Q6AFE_CLK (LPASS_CLK_ID_TX_CORE_MCLK ), - [LPASS_CLK_ID_TX_CORE_NPL_MCLK ] = -Q6AFE_CLK (LPASS_CLK_ID_TX_CORE_NPL_MCLK ), - [LPASS_CLK_ID_RX_CORE_MCLK ] =Q6AFE_CLK (LPASS_CLK_ID_RX_CORE_MCLK ), - [LPASS_CLK_ID_RX_CORE_NPL_MCLK ] = -Q6AFE_CLK (LPASS_CLK_ID_RX_CORE_NPL_MCLK ), - [LPASS_CLK_ID_VA_CORE_2X_MCLK ] = -Q6AFE_CLK (LPASS_CLK_ID_VA_CORE_2X_MCLK ), - [LPASS_HW_AVTIMER_VOTE ] =Q6AFE_VOTE_CLK (LPASS_HW_AVTIMER_VOTE , -Q6AFE_LPASS_CORE_AVTIMER_BLOCK , -"LPASS_AVTIMER_MACRO" ), - [LPASS_HW_MACRO_VOTE ] =Q6AFE_VOTE_CLK (LPASS_HW_MACRO_VOTE , -Q6AFE_LPASS_CORE_HW_MACRO_BLOCK , -"LPASS_HW_MACRO" ), - [LPASS_HW_DCODEC_VOTE ] =Q6AFE_VOTE_CLK (LPASS_HW_DCODEC_VOTE , -Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK , -"LPASS_HW_DCODEC" ), +static const struct q6afe_clk_init q6afe_clks[] = { +Q6AFE_CLK (LPASS_CLK_ID_PRI_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_PRI_MI2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEC_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEC_MI2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_TER_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_TER_MI2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUAD_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUAD_MI2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SPEAKER_I2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SPEAKER_I2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SPEAKER_I2S_OSR ), +Q6AFE_CLK (LPASS_CLK_ID_QUI_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUI_MI2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEN_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEN_MI2S_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT0_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT1_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT2_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT3_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT4_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT5_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_INT6_MI2S_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUI_MI2S_OSR ), +Q6AFE_CLK (LPASS_CLK_ID_PRI_PCM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_PRI_PCM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEC_PCM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEC_PCM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_TER_PCM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_TER_PCM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUAD_PCM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUAD_PCM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUIN_PCM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUIN_PCM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUI_PCM_OSR ), +Q6AFE_CLK (LPASS_CLK_ID_PRI_TDM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_PRI_TDM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEC_TDM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_SEC_TDM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_TER_TDM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_TER_TDM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUAD_TDM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUAD_TDM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUIN_TDM_IBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUIN_TDM_EBIT ), +Q6AFE_CLK (LPASS_CLK_ID_QUIN_TDM_OSR ), +Q6AFE_CLK (LPASS_CLK_ID_MCLK_1 ), +Q6AFE_CLK (LPASS_CLK_ID_MCLK_2 ), +Q6AFE_CLK (LPASS_CLK_ID_MCLK_3 ), +Q6AFE_CLK (LPASS_CLK_ID_MCLK_4 ), +Q6AFE_CLK (LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE ), +Q6AFE_CLK (LPASS_CLK_ID_INT_MCLK_0 ), +Q6AFE_CLK (LPASS_CLK_ID_INT_MCLK_1 ), +Q6AFE_CLK (LPASS_CLK_ID_WSA_CORE_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_WSA_CORE_NPL_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_VA_CORE_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_TX_CORE_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_TX_CORE_NPL_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_RX_CORE_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_RX_CORE_NPL_MCLK ), +Q6AFE_CLK (LPASS_CLK_ID_VA_CORE_2X_MCLK ), +Q6AFE_VOTE_CLK (LPASS_HW_AVTIMER_VOTE , +Q6AFE_LPASS_CORE_AVTIMER_BLOCK , +"LPASS_AVTIMER_MACRO" ), +Q6AFE_VOTE_CLK (LPASS_HW_MACRO_VOTE , +Q6AFE_LPASS_CORE_HW_MACRO_BLOCK , +"LPASS_HW_MACRO" ), +Q6AFE_VOTE_CLK (LPASS_HW_DCODEC_VOTE , +Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK , +"LPASS_HW_DCODEC" ), }; static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec,
@@ -207,7 +194,7 @@ static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec,unsigned int idx = clkspec->args[0 ];unsigned int attr = clkspec->args[1 ]; -if (idx >= cc->num_clks || attr >LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR ) { +if (idx >=Q6AFE_MAX_CLK_ID || attr >LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR ) {dev_err (cc->dev,"Invalid clk specifier (%d, %d)\n" , idx, attr);return ERR_PTR (-EINVAL ); }
@@ -230,20 +217,36 @@ static int q6afe_clock_dev_probe(struct platform_device *pdev)if (!cc)return -ENOMEM ; - cc->clks = &q6afe_clks[0 ]; - cc->num_clks =ARRAY_SIZE (q6afe_clks); + cc->dev = dev;for (i =0 ; i <ARRAY_SIZE (q6afe_clks); i++) { -if (!q6afe_clks[i]) -continue ; +unsigned int id = q6afe_clks[i].clk_id; +struct clk_init_data init = { + .name = q6afe_clks[i].name, + }; +struct q6afe_clk *clk; + + clk =devm_kzalloc (dev,sizeof (*clk),GFP_KERNEL ); +if (!clk) +return -ENOMEM ; + + clk->dev = dev; + clk->afe_clk_id = q6afe_clks[i].afe_clk_id; + clk->rate = q6afe_clks[i].rate; + clk->hw.init = &init; + +if (clk->rate) + init.ops = &clk_q6afe_ops; +else + init.ops = &clk_vote_q6afe_ops; - q6afe_clks[i]->dev = dev; + cc->clks[id] = clk; - ret =devm_clk_hw_register (dev, &q6afe_clks[i]->hw); + ret =devm_clk_hw_register (dev, &clk->hw);if (ret)return ret; } - ret =of_clk_add_hw_provider (dev->of_node, q6afe_of_clk_hw_get, cc); + ret =devm_of_clk_add_hw_provider (dev, q6afe_of_clk_hw_get, cc);if (ret)return ret;
sound/soc/qcom/qdsp6/q6afe.c +1 -1
@@ -1681,7 +1681,7 @@ int q6afe_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,EXPORT_SYMBOL (q6afe_unvote_lpass_core_hw);int q6afe_vote_lpass_core_hw (struct device *dev,uint32_t hw_block_id, -char *client_name,uint32_t *client_handle) +const char *client_name,uint32_t *client_handle) {struct q6afe *afe =dev_get_drvdata (dev->parent);struct afe_cmd_remote_lpass_core_hw_vote_request *vote_cfg;
sound/soc/qcom/qdsp6/q6afe.h +1 -1
@@ -236,7 +236,7 @@ int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,int q6afe_set_lpass_clock (struct device *dev,int clk_id,int clk_src,int clk_root,unsigned int freq);int q6afe_vote_lpass_core_hw (struct device *dev,uint32_t hw_block_id, -char *client_name,uint32_t *client_handle); +const char *client_name,uint32_t *client_handle);int q6afe_unvote_lpass_core_hw (struct device *dev,uint32_t hw_block_id,uint32_t client_handle);#endif /* __Q6AFE_H__ */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 425/601 ALSA: core: remove redundant spin_lock pair in snd_card_disconnect
In reply to Greg Kroah-HartmanFrom: Jia Zhou <[email protected]>
[ Upstream commit abc21649b3e5c34b143bf86f0c78e33d5815e250 ]
modification in commit 2a3f7221acdd ("ALSA: core: Fix card races between register and disconnect") resulting in this problem.
--- sound/core/init.c | 2 -- 1 file changed, 2 deletions(-)
sound/core/init.c +0 -2
@@ -388,10 +388,8 @@ int snd_card_disconnect(struct snd_card *card)return 0 ; } card->shutdown =1 ; -spin_unlock (&card->files_lock);/* replace file->f_op with special dummy operations */ -spin_lock (&card->files_lock);list_for_each_entry (mfile, &card->files_list, list) {/* it's critical part, use endless loop */ /* we have no room to fail */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 426/601 net: phy: lan87xx: fix access to wrong register of LAN87xx
In reply to Greg Kroah-HartmanFrom: Andre Edich <[email protected]>
[ Upstream commit fdb5cc6ab3b6a1c0122d3644a63ef9dc7a610d35 ]
The function lan87xx_config_aneg_ext was introduced to configure LAN95xxA but as well writes to undocumented register of LAN87xx. This fix prevents that access.
The function lan87xx_config_aneg_ext gets more suitable for the new behavior name.
--- drivers/net/phy/smsc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/phy/smsc.c +5 -2
@@ -185,10 +185,13 @@ static int lan87xx_config_aneg(struct phy_device *phydev)return genphy_config_aneg (phydev); } -static int lan87xx_config_aneg_ext (struct phy_device *phydev) +static int lan95xx_config_aneg_ext (struct phy_device *phydev) {int rc; +if (phydev->phy_id !=0x0007c0f0 )/* not (LAN9500A or LAN9505A) */ +return lan87xx_config_aneg (phydev); +/* Extend Manual AutoMDIX timer */ rc =phy_read (phydev,PHY_EDPD_CONFIG );if (rc <0 )
@@ -441,7 +444,7 @@ static struct phy_driver smsc_phy_driver[] = { .read_status = lan87xx_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, - .config_aneg = lan87xx_config_aneg_ext, + .config_aneg = lan95xx_config_aneg_ext,/* IRQ related */ .config_intr = smsc_phy_config_intr,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 427/601 udp: never accept GSO_FRAGLIST packets
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 78352f73dc5047f3f744764cc45912498c52f3c9 ]
Currently the UDP protocol delivers GSO_FRAGLIST packets to the sockets without the expected segmentation.
This change addresses the issue introducing and maintaining a couple of new fields to explicitly accept SKB_GSO_UDP_L4 or GSO_FRAGLIST packets. Additionally updates udp_unexpected_gso() accordingly.
UDP sockets enabling UDP_GRO stil keep accept_udp_fraglist zeroed.
v1 -> v2:
- use 2 bits instead of a whole GSO bitmask (Willem)
--- include/linux/udp.h | 16 +++++++++++++--- net/ipv4/udp.c | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-)
include/linux/udp.h +13 -3
@@ -51,7 +51,9 @@ struct udp_sock {* different encapsulation layer set * this */ - gro_enabled:1 ;/* Can accept GRO packets */ + gro_enabled:1, /* Request GRO aggregation */ + accept_udp_l4:1, + accept_udp_fraglist:1;/* * Following member retains the information to create a UDP header * when the socket is uncorked.
@@ -131,8 +133,16 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,static inline bool udp_unexpected_gso (struct sock *sk,struct sk_buff *skb) { -return !udp_sk (sk)->gro_enabled &&skb_is_gso (skb) && -skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 ; +if (!skb_is_gso (skb)) +return false; + +if (skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 && !udp_sk (sk)->accept_udp_l4) +return true; + +if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST && !udp_sk (sk)->accept_udp_fraglist) +return true; + +return false; }#define udp_portaddr_for_each_entry (__sk, list) \
net/ipv4/udp.c +3 -0
@@ -2659,9 +2659,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,case UDP_GRO :lock_sock (sk); + +/* when enabling GRO, accept the related GSO packet type */ if (valbool)udp_tunnel_encap_enable (sk->sk_socket); up->gro_enabled = valbool; + up->accept_udp_l4 = valbool;release_sock (sk);break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 428/601 powerpc/pseries: Only register vio drivers if vio bus exists
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit 11d92156f7a862091009d7655d19c1e7de37fc7a ]
The vio bus is a fake bus, which we use on pseries LPARs (guests) to discover devices provided by the hypervisor. There's no need or sense in creating the vio bus on bare metal systems.
Which is why commit 4336b9337824 ("powerpc/pseries: Make vio and ibmebus initcalls pseries specific") made the initialisation of the vio bus only happen in LPARs.
However as a result of that commit we now see errors at boot on bare metal systems:
Driver 'hvc_console' was unable to register with bus_type 'vio' because the bus was not initialized. Driver 'tpm_ibmvtpm' was unable to register with bus_type 'vio' because the bus was not initialized.
This happens because those drivers are built-in, and are calling vio_register_driver(). It in turn calls driver_register() with a reference to vio_bus_type, but we haven't registered vio_bus_type with the driver core.
Fix it by also guarding vio_register_driver() with a check to see if we are on pseries.
--- arch/powerpc/platforms/pseries/vio.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/powerpc/platforms/pseries/vio.c +4 -0
@@ -1286,6 +1286,10 @@ static int vio_bus_remove(struct device *dev)int __vio_register_driver (struct vio_driver *viodrv,struct module *owner,const char *mod_name) { +// vio_bus_type is only initialised for pseries +if (!machine_is (pseries)) +return -ENODEV ; +pr_debug ("%s: driver %s registering\n" , __func__, viodrv->name);/* fill in 'struct driver' fields */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 429/601 net/tipc: fix missing destroy_workqueue() on error in tipc_crypto_start()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit ac1db7acea67777be1ba86e36e058c479eab6508 ]
Add the missing destroy_workqueue() before return from tipc_crypto_start() in the error handling case.
--- net/tipc/crypto.c | 2 ++ 1 file changed, 2 insertions(+)
net/tipc/crypto.c +2 -0
@@ -1492,6 +1492,8 @@ int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,/* Allocate statistic structure */ c->stats = alloc_percpu_gfp(struct tipc_crypto_stats, GFP_ATOMIC);if (!c->stats) { +if (c->wq) +destroy_workqueue (c->wq);kfree_sensitive (c);return -ENOMEM ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 430/601 bug: Remove redundant condition check in report_bug
In reply to Greg Kroah-HartmanFrom: Andrew Scull <[email protected]>
[ Upstream commit 3ad1a6cb0abc63d036fc866bd7c2c5983516dec5 ]
report_bug() will return early if it cannot find a bug corresponding to the provided address. The subsequent test for the bug will always be true so remove it.
--- lib/bug.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-)
lib/bug.c +15 -18
@@ -158,30 +158,27 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) file =NULL ; line =0 ; - warning =0 ; -if (bug) {#ifdef CONFIG_DEBUG_BUGVERBOSE #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS - file = bug->file; + file = bug->file;#else - file = (const char *)bug + bug->file_disp; + file = (const char *)bug + bug->file_disp;#endif - line = bug->line; + line = bug->line;#endif - warning = (bug->flags &BUGFLAG_WARNING ) !=0 ; - once = (bug->flags &BUGFLAG_ONCE ) !=0 ; - done = (bug->flags &BUGFLAG_DONE ) !=0 ; - -if (warning && once) { -if (done) -return BUG_TRAP_TYPE_WARN ; - -/* -* Since this is the only store, concurrency is not an issue. -*/ - bug->flags |=BUGFLAG_DONE ; - } + warning = (bug->flags &BUGFLAG_WARNING ) !=0 ; + once = (bug->flags &BUGFLAG_ONCE ) !=0 ; + done = (bug->flags &BUGFLAG_DONE ) !=0 ; + +if (warning && once) { +if (done) +return BUG_TRAP_TYPE_WARN ; + +/* +* Since this is the only store, concurrency is not an issue. +*/ + bug->flags |=BUGFLAG_DONE ; }/*
Signature · 1 line
2.30.2