5.19.17-rc1 review
Subsystems (9)
Greg Kroah-Hartman
maintainerPATCH 443/717 IB: Set IOVA/LENGTH on IB_MR in core/uverbs layers
In reply to Greg Kroah-HartmanFrom: Daisuke Matsuda <[email protected]>
[ Upstream commit 241f9a27e0fc0eaf23e3d52c8450f10648cd11f1 ]
Set 'iova' and 'length' on ib_mr in ib_uverbs and ib_core layers to let all drivers have the members filled. Also, this commit removes redundancy in the respective drivers.
Previously, commit 04c0a5fcfcf65 ("IB/uverbs: Set IOVA on IB MR in uverbs layer") changed to set 'iova', but seems to have missed 'length' and the ib_core layer at that time.
--- drivers/infiniband/core/uverbs_cmd.c | 5 ++++- drivers/infiniband/core/verbs.c | 2 ++ drivers/infiniband/hw/hns/hns_roce_mr.c | 1 - drivers/infiniband/hw/mlx4/mr.c | 1 - 4 files changed, 6 insertions(+), 3 deletions(-)
drivers/infiniband/core/uverbs_cmd.c +4 -1
@@ -739,6 +739,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs) mr->uobject = uobj;atomic_inc (&pd->usecnt); mr->iova = cmd.hca_va; + mr->length = cmd.length;rdma_restrack_new (&mr->res,RDMA_RESTRACK_MR );rdma_restrack_set_name (&mr->res,NULL );
@@ -861,8 +862,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) mr->pd = new_pd;atomic_inc (&new_pd->usecnt); } -if (cmd.flags &IB_MR_REREG_TRANS ) +if (cmd.flags &IB_MR_REREG_TRANS ) { mr->iova = cmd.hca_va; + mr->length = cmd.length; + } }memset (&resp,0 ,sizeof (resp));
drivers/infiniband/core/verbs.c +2 -0
@@ -2149,6 +2149,8 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mr->pd = pd; mr->dm =NULL ;atomic_inc (&pd->usecnt); + mr->iova = virt_addr; + mr->length = length;rdma_restrack_new (&mr->res,RDMA_RESTRACK_MR );rdma_restrack_parent_name (&mr->res, &pd->res);
drivers/infiniband/hw/hns/hns_roce_mr.c +0 -1
@@ -249,7 +249,6 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_alloc_pbl; mr->ibmr.rkey = mr->ibmr.lkey = mr->key; - mr->ibmr.length = length;return &mr->ibmr;
drivers/infiniband/hw/mlx4/mr.c +0 -1
@@ -439,7 +439,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_mr; mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; - mr->ibmr.length = length; mr->ibmr.page_size =1U << shift;return &mr->ibmr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 444/717 xhci: Dont show warning for reinit on known broken suspend
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 484d6f7aa3283d082c87654b7fe7a7f725423dfb ]
commit 8b328f8002bc ("xhci: re-initialize the HC during resume if HCE was set") introduced a new warning message when the host controller error was set and re-initializing.
This is expected behavior on some designs which already set xhci->broken_suspend so the new warning is alarming to some users.
Modify the code to only show the warning if this was a surprising behavior to the XHCI driver.
--- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/host/xhci.c +2 -1
@@ -1183,7 +1183,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)/* re-initialize the HC on Restore Error, or Host Controller Error */ if (temp & (STS_SRE |STS_HCE )) { reinit_xhc = true; -xhci_warn (xhci,"xHC error in resume, USBSTS 0x%x, Reinit\n" , temp); +if (!xhci->broken_suspend) +xhci_warn (xhci,"xHC error in resume, USBSTS 0x%x, Reinit\n" , temp); }if (reinit_xhc) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 445/717 usb: gadget: function: fix dangling pnp_string in f_printer.c
In reply to Greg Kroah-HartmanFrom: Albert Briscoe <[email protected]>
[ Upstream commit 24b7ba2f88e04800b54d462f376512e8c41b8a3c ]
When opts->pnp_string is changed with configfs, new memory is allocated for the string. It does not, however, update dev->pnp_string, even though the memory is freed. When rquesting the string, the host then gets old or corrupted data rather than the new string. The ieee 1284 id string should be allowed to change while the device is connected.
The bug was introduced in commit fdc01cc286be ("usb: gadget: printer:
Remove pnp_string static buffer"), which changed opts->pnp_string from a char[] to a char*.
This patch changes dev->pnp_string from a char* to a char** pointing to opts->pnp_string.
--- drivers/usb/gadget/function/f_printer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/usb/gadget/function/f_printer.c +6 -6
@@ -89,7 +89,7 @@ struct printer_dev {u8 printer_cdev_open;wait_queue_head_t wait;unsigned q_len; -char *pnp_string;/* We don't own memory! */ +char **pnp_string;/* We don't own memory! */ struct usb_function function; };
@@ -1000,16 +1000,16 @@ static int printer_func_setup(struct usb_function *f,if ((wIndex>>8 ) != dev->interface)break ; -if (!dev->pnp_string) { +if (!*dev->pnp_string) { value =0 ;break ; } - value =strlen (dev->pnp_string); + value =strlen (*dev->pnp_string); buf[0 ] = (value >>8 ) &0xFF ; buf[1 ] = value &0xFF ; -memcpy (buf +2 , dev->pnp_string, value); +memcpy (buf +2 , *dev->pnp_string, value);DBG (dev,"1284 PNP String: %x %s\n" , value, - dev->pnp_string); + *dev->pnp_string);break ;case GET_PORT_STATUS :/* Get Port Status */
@@ -1475,7 +1475,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi)kref_init (&dev->kref); ++opts->refcnt; dev->minor = opts->minor; - dev->pnp_string = opts->pnp_string; + dev->pnp_string = &opts->pnp_string; dev->q_len = opts->q_len;mutex_unlock (&opts->lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 446/717 usb: dwc3: core: fix some leaks in probe
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 2a735e4b5580a2a6bbd6572109b4c4f163c57462 ]
The dwc3_get_properties() function calls:
dwc->usb_psy = power_supply_get_by_name(usb_psy_name);
so there is some additional clean up required on these error paths.
--- drivers/usb/dwc3/core.c | 58 +++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 22 deletions(-)
drivers/usb/dwc3/core.c +36 -22
@@ -1678,8 +1678,10 @@ static int dwc3_probe(struct platform_device *pdev)dwc3_get_properties (dwc); dwc->reset =devm_reset_control_array_get_optional_shared (dev); -if (IS_ERR (dwc->reset)) -return PTR_ERR (dwc->reset); +if (IS_ERR (dwc->reset)) { + ret =PTR_ERR (dwc->reset); + goto put_usb_psy; + }if (dev->of_node) {/*
@@ -1689,45 +1691,57 @@ static int dwc3_probe(struct platform_device *pdev)* check for them to retain backwards compatibility. */ dwc->bus_clk =devm_clk_get_optional (dev,"bus_early" ); -if (IS_ERR (dwc->bus_clk)) -return dev_err_probe (dev,PTR_ERR (dwc->bus_clk), -"could not get bus clock\n" ); +if (IS_ERR (dwc->bus_clk)) { + ret =dev_err_probe (dev,PTR_ERR (dwc->bus_clk), +"could not get bus clock\n" ); + goto put_usb_psy; + }if (dwc->bus_clk ==NULL ) { dwc->bus_clk =devm_clk_get_optional (dev,"bus_clk" ); -if (IS_ERR (dwc->bus_clk)) -return dev_err_probe (dev,PTR_ERR (dwc->bus_clk), -"could not get bus clock\n" ); +if (IS_ERR (dwc->bus_clk)) { + ret =dev_err_probe (dev,PTR_ERR (dwc->bus_clk), +"could not get bus clock\n" ); + goto put_usb_psy; + } } dwc->ref_clk =devm_clk_get_optional (dev,"ref" ); -if (IS_ERR (dwc->ref_clk)) -return dev_err_probe (dev,PTR_ERR (dwc->ref_clk), -"could not get ref clock\n" ); +if (IS_ERR (dwc->ref_clk)) { + ret =dev_err_probe (dev,PTR_ERR (dwc->ref_clk), +"could not get ref clock\n" ); + goto put_usb_psy; + }if (dwc->ref_clk ==NULL ) { dwc->ref_clk =devm_clk_get_optional (dev,"ref_clk" ); -if (IS_ERR (dwc->ref_clk)) -return dev_err_probe (dev,PTR_ERR (dwc->ref_clk), -"could not get ref clock\n" ); +if (IS_ERR (dwc->ref_clk)) { + ret =dev_err_probe (dev,PTR_ERR (dwc->ref_clk), +"could not get ref clock\n" ); + goto put_usb_psy; + } } dwc->susp_clk =devm_clk_get_optional (dev,"suspend" ); -if (IS_ERR (dwc->susp_clk)) -return dev_err_probe (dev,PTR_ERR (dwc->susp_clk), -"could not get suspend clock\n" ); +if (IS_ERR (dwc->susp_clk)) { + ret =dev_err_probe (dev,PTR_ERR (dwc->susp_clk), +"could not get suspend clock\n" ); + goto put_usb_psy; + }if (dwc->susp_clk ==NULL ) { dwc->susp_clk =devm_clk_get_optional (dev,"suspend_clk" ); -if (IS_ERR (dwc->susp_clk)) -return dev_err_probe (dev,PTR_ERR (dwc->susp_clk), -"could not get suspend clock\n" ); +if (IS_ERR (dwc->susp_clk)) { + ret =dev_err_probe (dev,PTR_ERR (dwc->susp_clk), +"could not get suspend clock\n" ); + goto put_usb_psy; + } } } ret =reset_control_deassert (dwc->reset);if (ret) -return ret; + goto put_usb_psy; ret =dwc3_clk_enable (dwc);if (ret)
@@ -1827,7 +1841,7 @@ static int dwc3_probe(struct platform_device *pdev)dwc3_clk_disable (dwc); assert_reset:reset_control_assert (dwc->reset); - +put_usb_psy:if (dwc->usb_psy)power_supply_put (dwc->usb_psy);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 447/717 drivers: serial: jsm: fix some leaks in probe
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 1d5859ef229e381f4db38dce8ed58e4bf862006b ]
This error path needs to unwind instead of just returning directly.
--- drivers/tty/serial/jsm/jsm_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/jsm/jsm_driver.c +2 -1
@@ -211,7 +211,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)break ;default : -return -ENXIO ; + rc = -ENXIO ; + goto out_kfree_brd; } rc =request_irq (brd->irq, brd->bd_ops->intr,IRQF_SHARED ,"JSM" , brd);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 448/717 serial: 8250: Toggle IER bits on only after irq has been set up
In reply to Greg Kroah-HartmanFrom: Ilpo Järvinen <[email protected]>
[ Upstream commit 039d4926379b1d1c17b51cf21c500a5eed86899e ]
Invoking TIOCVHANGUP on 8250_mid port on Ice Lake-D and then reopening the port triggers these faults during serial8250_do_startup():
DMAR: DRHD: handling fault status reg 3
DMAR: [DMA Write NO_PASID] Request device [00:1a.0] fault addr 0x0 [fault reason 0x05] PTE Write access is not set
If the IRQ hasn't been set up yet, the UART will have zeroes in its MSI address/data registers. Disabling the IRQ at the interrupt controller won't stop the UART from performing a DMA write to the address programmed in its MSI address register (zero) when it wants to signal an interrupt.
The UARTs (in Ice Lake-D) implement PCI 2.1 style MSI without masking capability, so there is no way to mask the interrupt at the source PCI function level, except disabling the MSI capability entirely, but that would cause it to fall back to INTx# assertion, and the PCI specification prohibits disabling the MSI capability as a way to mask a function's interrupt service request.
The MSI address register is zeroed by the hangup as the irq is freed. The interrupt is signalled during serial8250_do_startup() performing a THRE test that temporarily toggles THRI in IER. The THRE test currently occurs before UART's irq (and MSI address) is properly set up.
Refactor serial8250_do_startup() such that irq is set up before the THRE test. The current irq setup code is intermixed with the timer setup code. As THRE test must be performed prior to the timer setup, extract it into own function and call it only after the THRE test.
The ->setup_timer() needs to be part of the struct uart_8250_ops in order to not create circular dependency between 8250 and 8250_base modules.
--- drivers/tty/serial/8250/8250_core.c | 16 +++++++++++----- drivers/tty/serial/8250/8250_port.c | 8 +++++--- include/linux/serial_8250.h | 1 + 3 files changed, 17 insertions(+), 8 deletions(-)
drivers/tty/serial/8250/8250_core.c +11 -5
@@ -298,10 +298,9 @@ static void serial8250_backup_timeout(struct timer_list *t) jiffies + uart_poll_timeout(&up->port) + HZ / 5); } -static int univ8250_setup_irq (struct uart_8250_port *up) +static void univ8250_setup_timer (struct uart_8250_port *up) {struct uart_port *port = &up->port; -int retval =0 ;/* * The above check will only give an accurate result the first time
@@ -322,10 +321,16 @@ static int univ8250_setup_irq(struct uart_8250_port *up)*/ if (!port->irq)mod_timer (&up->timer, jiffies +uart_poll_timeout (port)); -else - retval =serial_link_irq_chain (up); +} -return retval; +static int univ8250_setup_irq (struct uart_8250_port *up) +{ +struct uart_port *port = &up->port; + +if (port->irq) +return serial_link_irq_chain (up); + +return 0 ; }static void univ8250_release_irq (struct uart_8250_port *up)
@@ -381,6 +386,7 @@ static struct uart_ops univ8250_port_ops;static const struct uart_8250_ops univ8250_driver_ops = { .setup_irq = univ8250_setup_irq, .release_irq = univ8250_release_irq, + .setup_timer = univ8250_setup_timer, };static struct uart_8250_port serial8250_ports[UART_NR ];
drivers/tty/serial/8250/8250_port.c +5 -3
@@ -2303,6 +2303,10 @@ int serial8250_do_startup(struct uart_port *port)if (port->irq && (up->port.flags &UPF_SHARE_IRQ )) up->port.irqflags |=IRQF_SHARED ; + retval = up->ops->setup_irq (up); +if (retval) + goto out; +if (port->irq && !(up->port.flags &UPF_NO_THRE_TEST )) {unsigned char iir1;
@@ -2345,9 +2349,7 @@ int serial8250_do_startup(struct uart_port *port) } } - retval = up->ops->setup_irq (up); -if (retval) - goto out; + up->ops->setup_timer (up);/* * Now, initialize the UART
include/linux/serial_8250.h +1 -0
@@ -74,6 +74,7 @@ struct uart_8250_port;struct uart_8250_ops {int (*setup_irq)(struct uart_8250_port *);void (*release_irq)(struct uart_8250_port *); +void (*setup_timer)(struct uart_8250_port *); };struct uart_8250_em485 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 449/717 tty: serial: fsl_lpuart: disable dma rx/tx use flags in lpuart_dma_shutdown
In reply to Greg Kroah-HartmanFrom: Sherry Sun <[email protected]>
[ Upstream commit 316ae95c175a7d770d1bfe4c011192712f57aa4a ]
lpuart_dma_shutdown tears down lpuart dma, but lpuart_flush_buffer can still occur which in turn tries to access dma apis if lpuart_dma_tx_use flag is true. At this point since dma is torn down, these dma apis can abort. Set lpuart_dma_tx_use and the corresponding rx flag lpuart_dma_rx_use to false in lpuart_dma_shutdown so that dmas are not accessed after they are relinquished.
Otherwise, when try to kill btattach, kernel may panic. This patch may fix this issue.
root@imx8ulpevk:~# btattach -B /dev/ttyLP2 -S 115200 ^C[ 90.182296] Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP [ 90.189806] Modules linked in: moal(O) mlan(O) [ 90.194258] CPU: 0 PID: 503 Comm: btattach Tainted: G O 5.15.32-06136-g34eecdf2f9e4 #37 [ 90.203554] Hardware name: NXP i.MX8ULP 9X9 EVK (DT) [ 90.208513] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 90.215470] pc : fsl_edma3_disable_request+0x8/0x60 [ 90.220358] lr : fsl_edma3_terminate_all+0x34/0x20c [ 90.225237] sp : ffff800013f0bac0 [ 90.228548] x29: ffff800013f0bac0 x28: 0000000000000001 x27: ffff000008404800 [ 90.235681] x26: ffff000008404960 x25: ffff000008404a08 x24: ffff000008404a00 [ 90.242813] x23: ffff000008404a60 x22: 0000000000000002 x21: 0000000000000000 [ 90.249946] x20: ffff800013f0baf8 x19: ffff00000559c800 x18: 0000000000000000 [ 90.257078] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 [ 90.264211] x14: 0000000000000003 x13: 0000000000000000 x12: 0000000000000040 [ 90.271344] x11: ffff00000600c248 x10: ffff800013f0bb10 x9 : ffff000057bcb090 [ 90.278477] x8 : fffffc0000241a08 x7 : ffff00000534ee00 x6 : ffff000008404804 [ 90.285609] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff0000055b3480 [ 90.292742] x2 : ffff8000135c0000 x1 : ffff00000534ee00 x0 : ffff00000559c800 [ 90.299876] Call trace: [ 90.302321] fsl_edma3_disable_request+0x8/0x60 [ 90.306851] lpuart_flush_buffer+0x40/0x160 [ 90.311037] uart_flush_buffer+0x88/0x120 [ 90.315050] tty_driver_flush_buffer+0x20/0x30 [ 90.319496] hci_uart_flush+0x44/0x90 [ 90.323162] +0x34/0x12c [ 90.327253] tty_ldisc_close+0x38/0x70 [ 90.331005] tty_ldisc_release+0xa8/0x190 [ 90.335018] tty_release_struct+0x24/0x8c [ 90.339022] tty_release+0x3ec/0x4c0 [ 90.342593] __fput+0x70/0x234 [ 90.345652] ____fput+0x14/0x20 [ 90.348790] task_work_run+0x84/0x17c [ 90.352455] do_exit+0x310/0x96c [ 90.355688] do_group_exit+0x3c/0xa0 [ 90.359259] __arm64_sys_exit_group+0x1c/0x20 [ 90.363609] invoke_syscall+0x48/0x114 [ 90.367362] el0_svc_common.constprop.0+0xd4/0xfc [ 90.372068] do_el0_svc+0x2c/0x94 [ 90.375379] el0_svc+0x28/0x80 [ 90.378438] el0t_64_sync_handler+0xa8/0x130 [ 90.382711] el0t_64_sync+0x1a0/0x1a4 [ 90.386376] Code: 17ffffda d503201f d503233f f9409802 (b9400041) [ 90.392467] ---[ end trace 2f60524b4a43f1f6 ]--- [ 90.397073] note: btattach[503] exited with preempt_count 1 [ 90.402636] Fixing recursive fault but reboot is needed!
--- drivers/tty/serial/fsl_lpuart.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/serial/fsl_lpuart.c +2 -0
@@ -1768,6 +1768,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)if (sport->lpuart_dma_rx_use) {del_timer_sync (&sport->lpuart_timer);lpuart_dma_rx_free (&sport->port); + sport->lpuart_dma_rx_use = false; }if (sport->lpuart_dma_tx_use) {
@@ -1776,6 +1777,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) sport->dma_tx_in_progress = false;dmaengine_terminate_all (sport->dma_tx_chan); } + sport->lpuart_dma_tx_use = false; }if (sport->dma_tx_chan)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 450/717 phy: qualcomm: call clk_disable_unprepare in the error handling
In reply to Greg Kroah-HartmanFrom: Dongliang Mu <[email protected]>
[ Upstream commit c3966ced8eb8dc53b6c8d7f97d32cc8a2107d83e ]
Smatch reports the following error:
drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on()
warn: 'uphy->cal_clk' from clk_prepare_enable() not released on lines:
58.drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on()
warn: 'uphy->cal_sleep_clk' from clk_prepare_enable() not released on
lines: 58.drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on()
warn: 'uphy->phy_clk' from clk_prepare_enable() not released on lines:
58.
Fix this by calling proper clk_disable_unprepare calls.
--- drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/phy/qualcomm/phy-qcom-usb-hsic.c +4 -2
@@ -54,8 +54,10 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy)/* Configure pins for HSIC functionality */ pins_default =pinctrl_lookup_state (uphy->pctl,PINCTRL_STATE_DEFAULT ); -if (IS_ERR (pins_default)) -return PTR_ERR (pins_default); +if (IS_ERR (pins_default)) { + ret =PTR_ERR (pins_default); + goto err_ulpi; + } ret =pinctrl_select_state (uphy->pctl, pins_default);if (ret)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 451/717 staging: vt6655: fix some erroneous memory clean-up loops
In reply to Greg Kroah-HartmanFrom: Nam Cao <[email protected]>
[ Upstream commit 2a2db520e3ca5aafba7c211abfd397666c9b5f9d ]
In some initialization functions of this driver, memory is allocated with 'i' acting as an index variable and increasing from 0. The commit in "Fixes" introduces some clean-up codes in case of allocation failure, which free memory in reverse order with 'i' decreasing to 0. However, there are some problems:
- The case i=0 is left out. Thus memory is leaked.
- In case memory allocation fails right from the start, the memory freeing loops will start with i=-1 and invalid memory locations will be accessed.
One of these loops has been fixed in commit c8ff91535880 ("staging:
vt6655: fix potential memory leak"). Fix the remaining erroneous loops.
--- drivers/staging/vt6655/device_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/staging/vt6655/device_main.c +3 -3
@@ -564,7 +564,7 @@ static int device_init_rd0_ring(struct vnt_private *priv)kfree (desc->rd_info); err_free_desc: -while (--i) { +while (i--) { desc = &priv->aRD0Ring[i];device_free_rx_buf (priv, desc);kfree (desc->rd_info);
@@ -610,7 +610,7 @@ static int device_init_rd1_ring(struct vnt_private *priv)kfree (desc->rd_info); err_free_desc: -while (--i) { +while (i--) { desc = &priv->aRD1Ring[i];device_free_rx_buf (priv, desc);kfree (desc->rd_info);
@@ -715,7 +715,7 @@ static int device_init_td1_ring(struct vnt_private *priv)return 0 ; err_free_desc: -while (--i) { +while (i--) { desc = &priv->apTD1Rings[i];kfree (desc->td_info); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 452/717 slimbus: qcom-ngd-ctrl: allow compile testing without QCOM_RPROC_COMMON
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit e291691c69776ad278cd39dec2306dd39d681a9f ]
The Qualcomm common remote-proc code (CONFIG_QCOM_RPROC_COMMON) has necessary stubs, so it is not needed for compile testing.
Stable-dep-of: 42992cf187e4 ("slimbus: qcom-ngd: Add error handling in of_qcom_slim_ngd_register")
--- drivers/slimbus/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/slimbus/Kconfig +2 -1
@@ -22,7 +22,8 @@ config SLIM_QCOM_CTRL config SLIM_QCOM_NGD_CTRL tristate "Qualcomm SLIMbus Satellite Non-Generic Device Component" - depends on HAS_IOMEM && DMA_ENGINE && NET && QCOM_RPROC_COMMON + depends on HAS_IOMEM && DMA_ENGINE && NET + depends on QCOM_RPROC_COMMON || COMPILE_TEST depends on ARCH_QCOM || COMPILE_TEST select QCOM_QMI_HELPERS select QCOM_PDR_HELPERS
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 453/717 slimbus: qcom-ngd: Add error handling in of_qcom_slim_ngd_register
In reply to Greg Kroah-HartmanFrom: Lin Yujun <[email protected]>
[ Upstream commit 42992cf187e4e4bcfe3c58f8fc7b1832c5652d9f ]
No error handling is performed when platform_device_add() return fails. Refer to the error handling of driver_set_override(), add error handling for platform_device_add().
--- drivers/slimbus/qcom-ngd-ctrl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/slimbus/qcom-ngd-ctrl.c +7 -1
@@ -1470,7 +1470,13 @@ static int of_qcom_slim_ngd_register(struct device *parent, ngd->pdev->dev.of_node = node; ctrl->ngd = ngd; -platform_device_add (ngd->pdev); + ret =platform_device_add (ngd->pdev); +if (ret) { +platform_device_put (ngd->pdev); +kfree (ngd); +of_node_put (node); +return ret; + } ngd->base = ctrl->base + ngd->id * data->offset + (ngd->id -1 ) * data->size;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 454/717 firmware: google: Test spinlock on panic path to avoid lockups
In reply to Greg Kroah-HartmanFrom: Guilherme G. Piccoli <[email protected]>
[ Upstream commit 3e081438b8e639cc76ef1a5ce0c1bd8a154082c7 ]
Currently the gsmi driver registers a panic notifier as well as reboot and die notifiers. The callbacks registered are called in atomic and very limited context - for instance, panic disables preemption and local IRQs, also all secondary CPUs (not executing the panic path) are shutdown.
With that said, taking a spinlock in this scenario is a dangerous invitation for lockup scenarios. So, fix that by checking if the spinlock is free to acquire in the panic notifier callback - if not, bail-out and avoid a potential hang.
--- drivers/firmware/google/gsmi.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/firmware/google/gsmi.c +9 -0
@@ -681,6 +681,15 @@ static struct notifier_block gsmi_die_notifier = {static int gsmi_panic_callback (struct notifier_block *nb,unsigned long reason,void *arg) { + +/* +* Panic callbacks are executed with all other CPUs stopped, +* so we must not attempt to spin waiting for gsmi_dev.lock +* to be released. +*/ +if (spin_is_locked (&gsmi_dev.lock)) +return NOTIFY_DONE ; +gsmi_shutdown_reason (GSMI_SHUTDOWN_PANIC );return NOTIFY_DONE ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 455/717 serial: 8250: Fix restoring termios speed after suspend
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 379a33786d489ab81885ff0b3935cfeb36137fea ]
Since commit edc6afc54968 ("tty: switch to ktermios and new framework") termios speed is no longer stored only in c_cflag member but also in new additional c_ispeed and c_ospeed members. If BOTHER flag is set in c_cflag then termios speed is stored only in these new members.
Since commit 027b57170bf8 ("serial: core: Fix initializing and restoring termios speed") termios speed is available also in struct console.
So properly restore also c_ispeed and c_ospeed members after suspend to fix restoring termios speed which is not represented by Bnnn constant.
--- drivers/tty/serial/8250/8250_port.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/tty/serial/8250/8250_port.c +6 -1
@@ -3325,8 +3325,13 @@ static void serial8250_console_restore(struct uart_8250_port *up)unsigned int baud, quot, frac =0 ; termios.c_cflag = port->cons->cflag; -if (port->state->port.tty && termios.c_cflag ==0 ) + termios.c_ispeed = port->cons->ispeed; + termios.c_ospeed = port->cons->ospeed; +if (port->state->port.tty && termios.c_cflag ==0 ) { termios.c_cflag = port->state->port.tty->termios.c_cflag; + termios.c_ispeed = port->state->port.tty->termios.c_ispeed; + termios.c_ospeed = port->state->port.tty->termios.c_ospeed; + } baud =serial8250_get_baud_rate (port, &termios,NULL ); quot =serial8250_get_divisor (port, baud, &frac);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 456/717 scsi: libsas: Fix use-after-free bug in smp_execute_task_sg()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 46ba53c30666717cb06c2b3c5d896301cd00d0c0 ]
When executing SMP task failed, the smp_execute_task_sg() calls del_timer() to delete "slow_task->timer". However, if the timer handler sas_task_internal_timedout() is running, the del_timer() in smp_execute_task_sg() will not stop it and a UAF will happen. The process is shown below:
(thread 1) | (thread 2)
smp_execute_task_sg() | sas_task_internal_timedout()
... |
del_timer() |
... | ...
sas_free_task(task) |
kfree(task->slow_task) //FREE|
| task->slow_task->... //USEFix by calling del_timer_sync() in smp_execute_task_sg(), which makes sure the timer handler have finished before the "task->slow_task" is deallocated.
--- drivers/scsi/libsas/sas_expander.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/libsas/sas_expander.c +1 -1
@@ -67,7 +67,7 @@ static int smp_execute_task_sg(struct domain_device *dev, res = i->dft->lldd_execute_task (task,GFP_KERNEL );if (res) { -del_timer (&task->slow_task->timer); +del_timer_sync (&task->slow_task->timer);pr_notice ("executing SMP task failed:%d\n" , res);break ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 457/717 scsi: pm8001: Fix running_req for internal abort commands
In reply to Greg Kroah-HartmanFrom: John Garry <[email protected]>
[ Upstream commit d8c22c4697c11ed28062afe3c2b377025be11a23 ]
Disabling the remote phy for a SATA disk causes a hang:
root@(none)$ more /sys/class/sas_phy/phy-0:0:8/target_port_protocols sata root@(none)$ echo 0 > sys/class/sas_phy/phy-0:0:8/enable root@(none)$ [ 67.855950] sas: ex 500e004aaaaaaa1f phy08 change count has changed [ 67.920585] sd 0:0:2:0: [sdc] Synchronizing SCSI cache [ 67.925780] sd 0:0:2:0: [sdc] Synchronize Cache(10) failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK [ 67.935094] sd 0:0:2:0: [sdc] Stopping disk [ 67.939305] sd 0:0:2:0: [sdc] Start/Stop Unit failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK ... [ 123.998998] INFO: task kworker/u192:1:642 blocked for more than 30 seconds. [ 124.005960] Not tainted 6.0.0-rc1-205202-gf26f8f761e83 #218 [ 124.012049] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 124.019872] task:kworker/u192:1 state:D stack:0 pid: 642 ppid: 2 flags:0x00000008 [ 124.028223] Workqueue: 0000:04:00.0_event_q sas_port_event_worker [ 124.034319] Call trace: [ 124.036758] __switch_to+0x128/0x278 [ 124.040333] __schedule+0x434/0xa58 [ 124.043820] schedule+0x94/0x138 [ 124.047045] schedule_timeout+0x2fc/0x368 [ 124.051052] wait_for_completion+0xdc/0x200 [ 124.055234] __flush_workqueue+0x1a8/0x708 [ 124.059328] sas_porte_broadcast_rcvd+0xa8/0xc0 [ 124.063858] sas_port_event_worker+0x60/0x98 [ 124.068126] process_one_work+0x3f8/0x660 [ 124.072134] worker_thread+0x70/0x700 [ 124.075793] kthread+0x1a4/0x1b8 [ 124.079014] ret_from_fork+0x10/0x20
The issue is that the per-device running_req read in pm8001_dev_gone_notify() never goes to zero and we never make progress. This is caused by missing accounting for running_req for when an internal abort command completes.
In commit 2cbbf489778e ("scsi: pm8001: Use libsas internal abort support") we started to send internal abort commands as a proper sas_task. In this when we deliver a sas_task to HW the per-device running_req is incremented in pm8001_queue_command(). However it is never decremented for internal abort commnds, so decrement in pm8001_mpi_task_abort_resp().
--- drivers/scsi/pm8001/pm8001_hwi.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/scsi/pm8001/pm8001_hwi.c +4 -0
@@ -3608,6 +3608,10 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_dbg (pm8001_ha,FAIL ," TASK NULL. RETURNING !!!\n" );return -1 ; } + +if (t->task_proto ==SAS_PROTOCOL_INTERNAL_ABORT ) +atomic_dec (&pm8001_dev->running_req); + ts = &t->task_status;if (status !=0 ) pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 458/717 scsi: iscsi: Rename iscsi_conn_queue_work()
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 4b9f8ce4d5e823e42944c5a0a4842b0f936365ad ]
Rename iscsi_conn_queue_work() to iscsi_conn_queue_xmit() to reflect that it handles queueing of xmits only.
Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()")
--- drivers/scsi/cxgbi/libcxgbi.c | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libiscsi.c | 12 ++++++------ include/scsi/libiscsi.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-)
drivers/scsi/cxgbi/libcxgbi.c +1 -1
@@ -1455,7 +1455,7 @@ void cxgbi_conn_tx_open(struct cxgbi_sock *csk)if (conn) {log_debug (1 <<CXGBI_DBG_SOCK ,"csk 0x%p, cid %d.\n" , csk, conn->id); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); } }EXPORT_SYMBOL_GPL (cxgbi_conn_tx_open);
drivers/scsi/iscsi_tcp.c +1 -1
@@ -205,7 +205,7 @@ static void iscsi_sw_tcp_write_space(struct sock *sk)old_write_space (sk);ISCSI_SW_TCP_DBG (conn,"iscsi_write_space\n" ); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); }static void iscsi_sw_tcp_conn_set_callbacks (struct iscsi_conn *conn)
drivers/scsi/libiscsi.c +6 -6
@@ -83,7 +83,7 @@ MODULE_PARM_DESC(debug_libiscsi_eh, "%s " dbg_fmt, __func__, ##arg); \ }while (0 ); -inline void iscsi_conn_queue_work (struct iscsi_conn *conn) +inline void iscsi_conn_queue_xmit (struct iscsi_conn *conn) {struct Scsi_Host *shost = conn->session->host;struct iscsi_host *ihost =shost_priv (shost);
@@ -91,7 +91,7 @@ inline void iscsi_conn_queue_work(struct iscsi_conn *conn)if (ihost->workq)queue_work (ihost->workq, &conn->xmitwork); } -EXPORT_SYMBOL_GPL (iscsi_conn_queue_work); +EXPORT_SYMBOL_GPL (iscsi_conn_queue_xmit);static void __iscsi_update_cmdsn (struct iscsi_session *session,uint32_t exp_cmdsn,uint32_t max_cmdsn)
@@ -765,7 +765,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto free_task; }else {list_add_tail (&task->running, &conn->mgmtqueue); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); }return task;
@@ -1513,7 +1513,7 @@ void iscsi_requeue_task(struct iscsi_task *task)*/ iscsi_put_task (task); } -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn);spin_unlock_bh (&conn->session->frwd_lock); }EXPORT_SYMBOL_GPL (iscsi_requeue_task);
@@ -1782,7 +1782,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) } }else {list_add_tail (&task->running, &conn->cmdqueue); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); } session->queued_cmdsn++;
@@ -1963,7 +1963,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_tx);static void iscsi_start_tx (struct iscsi_conn *conn) {clear_bit (ISCSI_CONN_FLAG_SUSPEND_TX , &conn->flags); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); }/*
include/scsi/libiscsi.h +1 -1
@@ -453,7 +453,7 @@ extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, enum iscsi_param param, char *buf);extern void iscsi_suspend_tx (struct iscsi_conn *conn);extern void iscsi_suspend_queue (struct iscsi_conn *conn); -extern void iscsi_conn_queue_work (struct iscsi_conn *conn); +extern void iscsi_conn_queue_xmit (struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 459/717 scsi: iscsi: Add recv workqueue helpers
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 8af809966c0b34cfacd8da9a412689b8e9910354 ]
Add helpers to allow the drivers to run their recv paths from libiscsi's workqueue.
Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()")
--- drivers/scsi/libiscsi.c | 29 +++++++++++++++++++++++++++-- include/scsi/libiscsi.h | 4 ++++ 2 files changed, 31 insertions(+), 2 deletions(-)
drivers/scsi/libiscsi.c +27 -2
@@ -93,6 +93,16 @@ inline void iscsi_conn_queue_xmit(struct iscsi_conn *conn) }EXPORT_SYMBOL_GPL (iscsi_conn_queue_xmit); +inline void iscsi_conn_queue_recv (struct iscsi_conn *conn) +{ +struct Scsi_Host *shost = conn->session->host; +struct iscsi_host *ihost =shost_priv (shost); + +if (ihost->workq && !test_bit (ISCSI_CONN_FLAG_SUSPEND_RX , &conn->flags)) +queue_work (ihost->workq, &conn->recvwork); +} +EXPORT_SYMBOL_GPL (iscsi_conn_queue_recv); +static void __iscsi_update_cmdsn (struct iscsi_session *session,uint32_t exp_cmdsn,uint32_t max_cmdsn) {
@@ -1943,7 +1953,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_queue);/** * iscsi_suspend_tx - suspend iscsi_data_xmit -* @conn: iscsi conn tp stop processing IO on. +* @conn: iscsi conn to stop processing IO on. * * This function sets the suspend bit to prevent iscsi_data_xmit * from sending new IO, and if work is queued on the xmit thread
@@ -1956,7 +1966,7 @@ void iscsi_suspend_tx(struct iscsi_conn *conn)set_bit (ISCSI_CONN_FLAG_SUSPEND_TX , &conn->flags);if (ihost->workq) -flush_workqueue (ihost->workq); +flush_work (&conn->xmitwork); }EXPORT_SYMBOL_GPL (iscsi_suspend_tx);
@@ -1966,6 +1976,21 @@ static void iscsi_start_tx(struct iscsi_conn *conn)iscsi_conn_queue_xmit (conn); } +/** +* iscsi_suspend_rx - Prevent recvwork from running again. +* @conn: iscsi conn to stop. +*/ +void iscsi_suspend_rx (struct iscsi_conn *conn) +{ +struct Scsi_Host *shost = conn->session->host; +struct iscsi_host *ihost =shost_priv (shost); + +set_bit (ISCSI_CONN_FLAG_SUSPEND_RX , &conn->flags); +if (ihost->workq) +flush_work (&conn->recvwork); +} +EXPORT_SYMBOL_GPL (iscsi_suspend_rx); +/* * We want to make sure a ping is in flight. It has timed out. * And we are not busy processing a pdu that is making
include/scsi/libiscsi.h +4 -0
@@ -213,6 +213,8 @@ struct iscsi_conn {struct list_head cmdqueue;/* data-path cmd queue */ struct list_head requeue;/* tasks needing another run */ struct work_struct xmitwork;/* per-conn. xmit workqueue */ +/* recv */ +struct work_struct recvwork;unsigned long flags;/* ISCSI_CONN_FLAGs */ /* negotiated params */
@@ -452,8 +454,10 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,extern int iscsi_conn_get_addr_param (struct sockaddr_storage *addr,enum iscsi_param param,char *buf);extern void iscsi_suspend_tx (struct iscsi_conn *conn); +extern void iscsi_suspend_rx (struct iscsi_conn *conn);extern void iscsi_suspend_queue (struct iscsi_conn *conn);extern void iscsi_conn_queue_xmit (struct iscsi_conn *conn); +extern void iscsi_conn_queue_recv (struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 460/717 scsi: iscsi: Run recv path from workqueue
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit f1d269765ee29da56b32818b7a08054484ed89f2 ]
We don't always want to run the recv path from the network softirq because when we have to have multiple sessions sharing the same CPUs, some sessions can eat up the NAPI softirq budget and affect other sessions or users.
Allow us to queue the recv handling to the iscsi workqueue so we can have the scheduler/wq code try to balance the work and CPU use across all sessions' worker threads.
Note: It wasn't the original intent of the change but a nice side effect is that for some workloads/configs we get a nice performance boost. For a simple read heavy test:
fio --direct=1 --filename=/dev/dm-0 --rw=randread --bs=256K
--ioengine=libaio --iodepth=128 --numjobs=4where the iscsi threads, fio jobs, and rps_cpus share CPUs we see a 32% throughput boost. We also see increases for small I/O IOPs tests but it's not as high.
Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()")
--- drivers/scsi/iscsi_tcp.c | 65 ++++++++++++++++++++++++++++++++-------- drivers/scsi/iscsi_tcp.h | 2 ++ 2 files changed, 54 insertions(+), 13 deletions(-)
drivers/scsi/iscsi_tcp.c +52 -13
@@ -52,6 +52,10 @@ static struct iscsi_transport iscsi_sw_tcp_transport;static unsigned int iscsi_max_lun = ~0 ;module_param_named (max_lun, iscsi_max_lun, uint,S_IRUGO ); +static bool iscsi_recv_from_iscsi_q; +module_param_named (recv_from_iscsi_q, iscsi_recv_from_iscsi_q, bool,0644 ); +MODULE_PARM_DESC (recv_from_iscsi_q,"Set to true to read iSCSI data/headers from the iscsi_q workqueue. The default is false which will perform reads from the network softirq context." ); +static int iscsi_sw_tcp_dbg;module_param_named (debug_iscsi_tcp, iscsi_sw_tcp_dbg, int,S_IRUGO |S_IWUSR );
@@ -122,20 +126,13 @@ static inline int iscsi_sw_sk_state_check(struct sock *sk)return 0 ; } -static void iscsi_sw_tcp_data_ready (struct sock *sk) +static void iscsi_sw_tcp_recv_data (struct iscsi_conn *conn) { -struct iscsi_conn *conn; -struct iscsi_tcp_conn *tcp_conn; +struct iscsi_tcp_conn *tcp_conn = conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct sock *sk = tcp_sw_conn->sock->sk;read_descriptor_t rd_desc; -read_lock_bh (&sk->sk_callback_lock); - conn = sk->sk_user_data; -if (!conn) { -read_unlock_bh (&sk->sk_callback_lock); -return ; - } - tcp_conn = conn->dd_data; -/* * Use rd_desc to pass 'conn' to iscsi_tcp_recv. * We set count to 1 because we want the network layer to
@@ -144,13 +141,48 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)*/ rd_desc.arg.data = conn; rd_desc.count =1 ; -tcp_read_sock (sk, &rd_desc, iscsi_sw_tcp_recv); -iscsi_sw_sk_state_check (sk); +tcp_read_sock (sk, &rd_desc, iscsi_sw_tcp_recv);/* If we had to (atomically) map a highmem page, * unmap it now. */ iscsi_tcp_segment_unmap (&tcp_conn->in.segment); + +iscsi_sw_sk_state_check (sk); +} + +static void iscsi_sw_tcp_recv_data_work (struct work_struct *work) +{ + struct iscsi_conn *conn = container_of(work, struct iscsi_conn, + recvwork); +struct iscsi_tcp_conn *tcp_conn = conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct sock *sk = tcp_sw_conn->sock->sk; + +lock_sock (sk); +iscsi_sw_tcp_recv_data (conn); +release_sock (sk); +} + +static void iscsi_sw_tcp_data_ready (struct sock *sk) +{ +struct iscsi_sw_tcp_conn *tcp_sw_conn; +struct iscsi_tcp_conn *tcp_conn; +struct iscsi_conn *conn; + +read_lock_bh (&sk->sk_callback_lock); + conn = sk->sk_user_data; +if (!conn) { +read_unlock_bh (&sk->sk_callback_lock); +return ; + } + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + +if (tcp_sw_conn->queue_recv) +iscsi_conn_queue_recv (conn); +else +iscsi_sw_tcp_recv_data (conn);read_unlock_bh (&sk->sk_callback_lock); }
@@ -276,6 +308,9 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,if (segment->total_copied + segment->size < segment->total_size) flags |=MSG_MORE ; +if (tcp_sw_conn->queue_recv) + flags |=MSG_DONTWAIT ; +/* Use sendpage if we can; else fall back to sendmsg */ if (!segment->data) { sg = segment->sg;
@@ -557,6 +592,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session, conn = cls_conn->dd_data; tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; +INIT_WORK (&conn->recvwork, iscsi_sw_tcp_recv_data_work); + tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; tfm =crypto_alloc_ahash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC );if (IS_ERR (tfm))
@@ -610,6 +647,8 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)iscsi_sw_tcp_conn_restore_callbacks (conn);sock_put (sock->sk); +iscsi_suspend_rx (conn); +spin_lock_bh (&session->frwd_lock); tcp_sw_conn->sock =NULL ;spin_unlock_bh (&session->frwd_lock);
drivers/scsi/iscsi_tcp.h +2 -0
@@ -28,6 +28,8 @@ struct iscsi_sw_tcp_send {struct iscsi_sw_tcp_conn {struct socket *sock; +struct work_struct recvwork; +bool queue_recv;struct iscsi_sw_tcp_send out;/* old values for socket callbacks */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 461/717 scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 57569c37f0add1b6489e1a1563c71519daf732cf ]
Fix a NULL pointer crash that occurs when we are freeing the socket at the same time we access it via sysfs.
The problem is that:
1. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() take the frwd_lock and do sock_hold() then drop the frwd_lock. sock_hold() does a get on the "struct sock".
2. iscsi_sw_tcp_release_conn() does sockfd_put() which does the last put on the "struct socket" and that does __sock_release() which sets the sock->ops to NULL.
3. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() then
call kernel_getpeername() which accesses the NULL sock->ops.
Above we do a get on the "struct sock", but we needed a get on the "struct socket". Originally, we just held the frwd_lock the entire time but in commit bcf3a2953d36 ("scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername()") we switched to refcount based because the network layer changed and started taking a mutex in that path, so we could no longer hold the frwd_lock.
Instead of trying to maintain multiple refcounts, this just has us use a mutex for accessing the socket in the interface code paths.
--- drivers/scsi/iscsi_tcp.c | 73 ++++++++++++++++++++++++++++------------ drivers/scsi/iscsi_tcp.h | 3 ++ 2 files changed, 55 insertions(+), 21 deletions(-)
drivers/scsi/iscsi_tcp.c +52 -21
@@ -595,6 +595,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,INIT_WORK (&conn->recvwork, iscsi_sw_tcp_recv_data_work); tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; +mutex_init (&tcp_sw_conn->sock_lock); + tfm =crypto_alloc_ahash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC );if (IS_ERR (tfm)) goto free_conn;
@@ -629,11 +631,15 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,static void iscsi_sw_tcp_release_conn (struct iscsi_conn *conn) { -struct iscsi_session *session = conn->session;struct iscsi_tcp_conn *tcp_conn = conn->dd_data;struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;struct socket *sock = tcp_sw_conn->sock; +/* +* The iscsi transport class will make sure we are not called in +* parallel with start, stop, bind and destroys. However, this can be +* called twice if userspace does a stop then a destroy. +*/ if (!sock)return ;
@@ -649,9 +655,9 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)iscsi_suspend_rx (conn); -spin_lock_bh (&session->frwd_lock); +mutex_lock (&tcp_sw_conn->sock_lock); tcp_sw_conn->sock =NULL ; -spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&tcp_sw_conn->sock_lock);sockfd_put (sock); }
@@ -703,7 +709,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, int is_leading) { - struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn = cls_conn->dd_data;struct iscsi_tcp_conn *tcp_conn = conn->dd_data;struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
@@ -723,10 +728,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,if (err) goto free_socket; -spin_lock_bh (&session->frwd_lock); +mutex_lock (&tcp_sw_conn->sock_lock);/* bind iSCSI connection and socket */ tcp_sw_conn->sock = sock; -spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&tcp_sw_conn->sock_lock);/* setup Socket parameters */ sk = sock->sk;
@@ -763,8 +768,15 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,break ;case ISCSI_PARAM_DATADGST_EN :iscsi_set_param (cls_conn, param, buf, buflen); + +mutex_lock (&tcp_sw_conn->sock_lock); +if (!tcp_sw_conn->sock) { +mutex_unlock (&tcp_sw_conn->sock_lock); +return -ENOTCONN ; + } tcp_sw_conn->sendpage = conn->datadgst_en ? sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage; +mutex_unlock (&tcp_sw_conn->sock_lock);break ;case ISCSI_PARAM_MAX_R2T :return iscsi_tcp_set_max_r2t (conn, buf);
@@ -779,8 +791,8 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf) { struct iscsi_conn *conn = cls_conn->dd_data; -struct iscsi_tcp_conn *tcp_conn = conn->dd_data; -struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn; +struct iscsi_tcp_conn *tcp_conn;struct sockaddr_in6 addr;struct socket *sock;int rc;
@@ -790,21 +802,36 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,case ISCSI_PARAM_CONN_ADDRESS :case ISCSI_PARAM_LOCAL_PORT :spin_lock_bh (&conn->session->frwd_lock); -if (!tcp_sw_conn || !tcp_sw_conn->sock) { +if (!conn->session->leadconn) {spin_unlock_bh (&conn->session->frwd_lock);return -ENOTCONN ; } - sock = tcp_sw_conn->sock; -sock_hold (sock->sk); +/* +* The conn has been setup and bound, so just grab a ref +* incase a destroy runs while we are in the net layer. +*/ +iscsi_get_conn (conn->cls_conn);spin_unlock_bh (&conn->session->frwd_lock); + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + +mutex_lock (&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; +if (!sock) { + rc = -ENOTCONN ; + goto sock_unlock; + } +if (param ==ISCSI_PARAM_LOCAL_PORT ) rc =kernel_getsockname (sock, (struct sockaddr *)&addr);else rc =kernel_getpeername (sock, (struct sockaddr *)&addr); -sock_put (sock->sk); +sock_unlock: +mutex_unlock (&tcp_sw_conn->sock_lock); +iscsi_put_conn (conn->cls_conn);if (rc <0 )return rc;
@@ -842,17 +869,21 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, } tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; - sock = tcp_sw_conn->sock; -if (!sock) { -spin_unlock_bh (&session->frwd_lock); -return -ENOTCONN ; - } -sock_hold (sock->sk); +/* +* The conn has been setup and bound, so just grab a ref +* incase a destroy runs while we are in the net layer. +*/ +iscsi_get_conn (conn->cls_conn);spin_unlock_bh (&session->frwd_lock); - rc =kernel_getsockname (sock, - (struct sockaddr *)&addr); -sock_put (sock->sk); +mutex_lock (&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; +if (!sock) + rc = -ENOTCONN ; +else + rc =kernel_getsockname (sock, (struct sockaddr *)&addr); +mutex_unlock (&tcp_sw_conn->sock_lock); +iscsi_put_conn (conn->cls_conn);if (rc <0 )return rc;
drivers/scsi/iscsi_tcp.h +3 -0
@@ -28,6 +28,9 @@ struct iscsi_sw_tcp_send {struct iscsi_sw_tcp_conn {struct socket *sock; +/* Taken when accessing the sock from the netlink/sysfs interface */ +struct mutex sock_lock; +struct work_struct recvwork;bool queue_recv;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 462/717 clk: qcom: apss-ipq6018: mark apcs_alias0_core_clk as critical
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 86e78995c93ee182433f965babfccd48417d4dcf ]
While fixing up the driver I noticed that my IPQ8074 board was hanging after CPUFreq switched the frequency during boot, WDT would eventually reset it.
So mark apcs_alias0_core_clk as critical since its the clock feeding the CPU cluster and must never be disabled.
--- drivers/clk/qcom/apss-ipq6018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/apss-ipq6018.c +1 -1
@@ -57,7 +57,7 @@ static struct clk_branch apcs_alias0_cor .parent_hws = (const struct clk_hw *[]){ &apcs_alias0_clk_src.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, },
Greg Kroah-Hartman
maintainerPATCH 463/717 clk: qcom: gcc-sm6115: Override default Alpha PLL regs
In reply to Greg Kroah-HartmanFrom: Adam Skladowski <[email protected]>
[ Upstream commit 068a0605ef5a6b430e7278c169bfcd25b680b28f ]
The DEFAULT and BRAMMO PLL offsets are non-standard in downstream, but currently only BRAMMO ones are overridden. Override DEFAULT ones too.
A very similar thing is happening in gcc-qcm2290 driver.
--- drivers/clk/qcom/gcc-sm6115.c | 46 +++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-)
drivers/clk/qcom/gcc-sm6115.c +30 -16
@@ -53,11 +53,25 @@ static struct pll_vco gpll10_vco[] = { { 750000000, 1500000000, 1 }, }; +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_DEFAULT] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_ALPHA_VAL_U] = 0x0c, + [PLL_OFF_TEST_CTL] = 0x10, + [PLL_OFF_TEST_CTL_U] = 0x14, + [PLL_OFF_USER_CTL] = 0x18, + [PLL_OFF_USER_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_STATUS] = 0x24, + }, +}; + static struct clk_alpha_pll gpll0 = { .offset = 0x0, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(0),
@@ -83,7 +97,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { .post_div_table = post_div_table_gpll0_out_aux2, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll0_out_aux2" , .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -115,7 +129,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = { .post_div_table = post_div_table_gpll0_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll0_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -137,7 +151,7 @@ static struct clk_alpha_pll gpll10 = { .offset = 0xa000, .vco_table = gpll10_vco, .num_vco = ARRAY_SIZE(gpll10_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(10),
@@ -163,7 +177,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = { .post_div_table = post_div_table_gpll10_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll10_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
@@ -189,7 +203,7 @@ static struct clk_alpha_pll gpll11 = { .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), .flags = SUPPORTS_DYNAMIC_UPDATE, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(11),
@@ -215,7 +229,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = { .post_div_table = post_div_table_gpll11_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll11_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
@@ -229,7 +243,7 @@ static struct clk_alpha_pll gpll3 = { .offset = 0x3000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(3),
@@ -248,7 +262,7 @@ static struct clk_alpha_pll gpll4 = { .offset = 0x4000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(4),
@@ -274,7 +288,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = { .post_div_table = post_div_table_gpll4_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll4_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
@@ -287,7 +301,7 @@ static struct clk_alpha_pll gpll6 = { .offset = 0x6000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(6),
@@ -313,7 +327,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = { .post_div_table = post_div_table_gpll6_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll6_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
@@ -326,7 +340,7 @@ static struct clk_alpha_pll gpll7 = { .offset = 0x7000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(7),
@@ -352,7 +366,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = { .post_div_table = post_div_table_gpll7_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll7_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
@@ -380,7 +394,7 @@ static struct clk_alpha_pll gpll8 = { .offset = 0x8000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x79000,
@@ -407,7 +421,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = { .post_div_table = post_div_table_gpll8_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll8_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 464/717 RDMA/rxe: Fix resize_finish() in rxe_queue.c
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit fda5d0cf8aef12f0a4f714a96a4b2fce039a3e55 ]
Currently in resize_finish() in rxe_queue.c there is a loop which copies the entries in the original queue into a newly allocated queue. The termination logic for this loop is incorrect. The call to queue_next_index() updates cons but has no effect on whether the queue is empty. So if the queue starts out empty nothing is copied but if it is not then the loop will run forever. This patch changes the loop to compare the value of cons to the original producer index.
--- drivers/infiniband/sw/rxe/rxe_queue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/infiniband/sw/rxe/rxe_queue.c +7 -5
@@ -112,23 +112,25 @@ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q, unsigned int num_elem) {enum queue_type type = q->type; +u32 new_prod;u32 prod;u32 cons;if (!queue_empty (q, q->type) && (num_elem <queue_count (q, type)))return -EINVAL ; - prod =queue_get_producer (new_q, type); + new_prod =queue_get_producer (new_q, type); + prod =queue_get_producer (q, type); cons =queue_get_consumer (q, type); -while (!queue_empty (q, type)) { -memcpy (queue_addr_from_index (new_q, prod), +while ((prod - cons) & q->index_mask) { +memcpy (queue_addr_from_index (new_q, new_prod),queue_addr_from_index (q, cons), new_q->elem_size); - prod =queue_next_index (new_q, prod); + new_prod =queue_next_index (new_q, new_prod); cons =queue_next_index (q, cons); } - new_q->buf->producer_index = prod; + new_q->buf->producer_index = new_prod; q->buf->consumer_index = cons;/* update private index copies */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 465/717 fsi: core: Check error number after calling ida_simple_get
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 35af9fb49bc5c6d61ef70b501c3a56fe161cce3e ]
If allocation fails, the ida_simple_get() will return error number. So master->idx could be error number and be used in dev_set_name(). Therefore, it should be better to check it and return error if fails, like the ida_simple_get() in __fsi_get_new_minor().
--- drivers/fsi/fsi-core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/fsi/fsi-core.c +3 -0
@@ -1314,6 +1314,9 @@ int fsi_master_register(struct fsi_master *master)mutex_init (&master->scan_lock); master->idx =ida_simple_get (&master_ida,0 ,INT_MAX ,GFP_KERNEL ); +if (master->idx <0 ) +return master->idx; +dev_set_name (&master->dev,"fsi%d" , master->idx); master->dev.class = &fsi_master_class;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 466/717 mfd: intel_soc_pmic: Fix an error handling path in intel_soc_pmic_i2c_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 48749cabba109397b4e7dd556e85718ec0ec114d ]
The commit in Fixes: has added a pwm_add_table() call in the probe() and a pwm_remove_table() call in the remove(), but forget to update the error handling path of the probe.
Add the missing pwm_remove_table() call.
--- drivers/mfd/intel_soc_pmic_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/intel_soc_pmic_core.c +1 -0
@@ -77,6 +77,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,return 0 ; err_del_irq_chip: +pwm_remove_table (crc_pwm_lookup,ARRAY_SIZE (crc_pwm_lookup));regmap_del_irq_chip (pmic->irq, pmic->irq_chip_data);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 467/717 mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 3fa9e4cfb55da512ebfd57336fde468830719298 ]
If devm_of_platform_populate() fails, some resources need to be released.
Introduce a mx25_tsadc_unset_irq() function that undoes mx25_tsadc_setup_irq() and call it both from the new error handling path of the probe and in the remove function.
--- drivers/mfd/fsl-imx25-tsadc.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
drivers/mfd/fsl-imx25-tsadc.c +24 -8
@@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,return 0 ; } +static int mx25_tsadc_unset_irq (struct platform_device *pdev) +{ +struct mx25_tsadc *tsadc =platform_get_drvdata (pdev); +int irq =platform_get_irq (pdev,0 ); + +if (irq) { +irq_set_chained_handler_and_data (irq,NULL ,NULL ); +irq_domain_remove (tsadc->domain); + } + +return 0 ; +} +static void mx25_tsadc_setup_clk (struct platform_device *pdev,struct mx25_tsadc *tsadc) {
@@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev)platform_set_drvdata (pdev, tsadc); -return devm_of_platform_populate (dev); + ret =devm_of_platform_populate (dev); +if (ret) + goto err_irq; + +return 0 ; + +err_irq: +mx25_tsadc_unset_irq (pdev); + +return ret; }static int mx25_tsadc_remove (struct platform_device *pdev) { -struct mx25_tsadc *tsadc =platform_get_drvdata (pdev); -int irq =platform_get_irq (pdev,0 ); - -if (irq) { -irq_set_chained_handler_and_data (irq,NULL ,NULL ); -irq_domain_remove (tsadc->domain); - } +mx25_tsadc_unset_irq (pdev);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 468/717 mfd: lp8788: Fix an error handling path in lp8788_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit becfdcd75126b20b8ec10066c5e85b34f8994ad5 ]
Should an error occurs in mfd_add_devices(), some resources need to be released, as already done in the .remove() function.
Add an error handling path and a lp8788_irq_exit() call to undo a previous lp8788_irq_init().
--- drivers/mfd/lp8788.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/mfd/lp8788.c +10 -2
@@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)if (ret)return ret; -return mfd_add_devices (lp->dev,-1 , lp8788_devs, -ARRAY_SIZE (lp8788_devs),NULL ,0 ,NULL ); + ret =mfd_add_devices (lp->dev,-1 , lp8788_devs, +ARRAY_SIZE (lp8788_devs),NULL ,0 ,NULL ); +if (ret) + goto err_exit_irq; + +return 0 ; + +err_exit_irq: +lp8788_irq_exit (lp); +return ret; }static int lp8788_remove (struct i2c_client *cl)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 469/717 mfd: lp8788: Fix an error handling path in lp8788_irq_init() and lp8788_irq_init()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 557244f6284f30613f2d61f14b579303165876c3 ]
In lp8788_irq_init(), if an error occurs after a successful irq_domain_add_linear() call, it must be undone by a corresponding irq_domain_remove() call.
irq_domain_remove() should also be called in lp8788_irq_exit() for the same reason.
--- drivers/mfd/lp8788-irq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mfd/lp8788-irq.c +3 -0
@@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq)IRQF_TRIGGER_FALLING |IRQF_ONESHOT , "lp8788-irq", irqd);if (ret) { +irq_domain_remove (lp->irqdm);dev_err (lp->dev,"failed to create a thread for IRQ_N\n" );return ret; }
@@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp) {if (lp->irq)free_irq (lp->irq, lp->irqdm); +if (lp->irqdm) +irq_domain_remove (lp->irqdm); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 470/717 mfd: fsl-imx25: Fix check for platform_get_irq() errors
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 75db7907355ca5e2ff606e9dd3e86b6c3a455fe2 ]
The mx25_tsadc_remove() function assumes all non-zero returns are success but the platform_get_irq() function returns negative on error and positive non-zero values on success. It never returns zero, but if it did then treat that as a success.
--- drivers/mfd/fsl-imx25-tsadc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mfd/fsl-imx25-tsadc.c +2 -2
@@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,int irq; irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) +if (irq <0 )return irq; tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
@@ -89,7 +89,7 @@ static int mx25_tsadc_unset_irq(struct platform_device *pdev)struct mx25_tsadc *tsadc =platform_get_drvdata (pdev);int irq =platform_get_irq (pdev,0 ); -if (irq) { +if (irq >=0 ) {irq_set_chained_handler_and_data (irq,NULL ,NULL );irq_domain_remove (tsadc->domain); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 471/717 mfd: sm501: Add check for platform_driver_register()
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 8325a6c24ad78b8c1acc3c42b098ee24105d68e5 ]
As platform_driver_register() can return error numbers, it should be better to check platform_driver_register() and deal with the exception.
--- drivers/mfd/sm501.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mfd/sm501.c +6 -1
@@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = {static int __init sm501_base_init (void ) { -platform_driver_register (&sm501_plat_driver); +int ret; + + ret =platform_driver_register (&sm501_plat_driver); +if (ret <0 ) +return ret; +return pci_register_driver (&sm501_pci_driver); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 472/717 mfd: da9061: Fix Failed to set Two-Wire Bus Mode.
In reply to Greg Kroah-HartmanFrom: Jens Hillenstedt <[email protected]>
[ Upstream commit 834382ea32865a4bdeae83ec2dcb9321dc9489f2 ]
In da9062_i2c_probe() regmap_clear_bits() tries to access CONFIG_J register. As CONFIG_J is not present in da9061_aa_writeable_ranges[] probe of da9061 fails:
da9062 2-0058: Entering I2C mode!
da9062 2-0058: Failed to set Two-Wire Bus Mode.
da9062: probe of 2-0058 failed with error -5
Add CONFIG_J register to da9061_aa_writeable_ranges[].
--- drivers/mfd/da9062-core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/da9062-core.c +1 -0
@@ -453,6 +453,7 @@ static const struct regmap_range da9061_aa_writeable_ranges[] = {regmap_reg_range (DA9062AA_VBUCK1_B ,DA9062AA_VBUCK4_B ),regmap_reg_range (DA9062AA_VBUCK3_B ,DA9062AA_VBUCK3_B ),regmap_reg_range (DA9062AA_VLDO1_B ,DA9062AA_VLDO4_B ), +regmap_reg_range (DA9062AA_CONFIG_J ,DA9062AA_CONFIG_J ), regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 473/717 clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit 9f94f545f258b15bfa6357eb62e1e307b712851e ]
The only clock in the MT8183 MFGCFG block feeds the GPU. Propagate its rate change requests to its parent, so that DVFS for the GPU can work properly.
--- drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/mediatek/clk-mt8183-mfgcfg.c +3 -3
@@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = { .sta_ofs = 0x0, }; -#define GATE_MFG (_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ - &mtk_clk_gate_ops_setclr) +#define GATE_MFG (_id, _name, _parent, _shift) \ + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT)static const struct mtk_gate mfg_clks[] = {GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"mfg_sel" ,0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 474/717 clk: mediatek: clk-mt8195-mfg: Reparent mfg_bg3d and propagate rate changes
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit a5f7bf5458c2cf6730106e16a6373638a0e5ed1e ]
The MFG_BG3D is a gate to enable/disable clock output to the GPU, but the actual output is decided by multiple muxes; in particular:mfg_ck_fast_ref muxes between "slow" (top_mfg_core_tmp) and "fast" (MFGPLL) clock, while top_mfg_core_tmp muxes between the 26MHz clock and various system PLLs.
The clock gate comes after all the muxes, so its parent is mfg_ck_fast_reg, not top_mfg_core_tmp.
Reparent MFG_BG3D to the latter to match the hardware and add the CLK_SET_RATE_PARENT flag to it: this way we ensure propagating rate changes that are requested on MFG_BG3D along its entire clock tree.
--- drivers/clk/mediatek/clk-mt8195-mfg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clk/mediatek/clk-mt8195-mfg.c +4 -2
@@ -17,10 +17,12 @@ static const struct mtk_gate_regs mfg_cg_regs = { };#define GATE_MFG (_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, \ + _shift, &mtk_clk_gate_ops_setclr, \ + CLK_SET_RATE_PARENT)static const struct mtk_gate mfg_clks[] = { -GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"top_mfg_core_tmp" ,0 ), +GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"mfg_ck_fast_ref" ,0 ), };static const struct mtk_clk_desc mfg_desc = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 475/717 clk: mediatek: fix unregister function in mtk_clk_register_dividers cleanup
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit 20f7a0dba9075fb0e3d645495bc24d7025b58de1 ]
When the cleanup paths for the various clk register APIs in the MediaTek clk library were added, the one in the dividers type used the wrong type of unregister function. This would result in incorrect dereferencing of the clk pointer and freeing of invalid pointers.
Fix this by switching to the correct type of clk unregistration call.
--- drivers/clk/mediatek/clk-mtk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/mediatek/clk-mtk.c +1 -1
@@ -393,7 +393,7 @@ int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,if (IS_ERR_OR_NULL (clk_data->hws[mcd->id]))continue ; -mtk_clk_unregister_composite (clk_data->hws[mcd->id]); +clk_hw_unregister_divider (clk_data->hws[mcd->id]); clk_data->hws[mcd->id] =ERR_PTR (-ENOENT ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 476/717 clk: mediatek: Migrate remaining clk_unregister_*() to clk_hw_unregister_*()
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit fef14676fc4be40b8441745a3c96b7e7d7d8592d ]
During the previous |struct clk| to |struct clk_hw| clk provider API migration in commit 6f691a586296 ("clk: mediatek: Switch to clk_hw provider APIs"), a few clk_unregister_*() calls were missed.
Migrate the remaining ones to the |struct clk_hw| provider API, i.e. change clk_unregister_*() to clk_hw_unregister_*().
--- drivers/clk/mediatek/clk-mtk.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/clk/mediatek/clk-mtk.c +5 -5
@@ -80,7 +80,7 @@ int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[rc->id]))continue ; -clk_unregister_fixed_rate (clk_data->hws[rc->id]->clk); +clk_hw_unregister_fixed_rate (clk_data->hws[rc->id]); clk_data->hws[rc->id] =ERR_PTR (-ENOENT ); }
@@ -102,7 +102,7 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[rc->id]))continue ; -clk_unregister_fixed_rate (clk_data->hws[rc->id]->clk); +clk_hw_unregister_fixed_rate (clk_data->hws[rc->id]); clk_data->hws[rc->id] =ERR_PTR (-ENOENT ); } }
@@ -146,7 +146,7 @@ int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[ff->id]))continue ; -clk_unregister_fixed_factor (clk_data->hws[ff->id]->clk); +clk_hw_unregister_fixed_factor (clk_data->hws[ff->id]); clk_data->hws[ff->id] =ERR_PTR (-ENOENT ); }
@@ -168,7 +168,7 @@ void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[ff->id]))continue ; -clk_unregister_fixed_factor (clk_data->hws[ff->id]->clk); +clk_hw_unregister_fixed_factor (clk_data->hws[ff->id]); clk_data->hws[ff->id] =ERR_PTR (-ENOENT ); } }
@@ -414,7 +414,7 @@ void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,if (IS_ERR_OR_NULL (clk_data->hws[mcd->id]))continue ; -clk_unregister_divider (clk_data->hws[mcd->id]->clk); +clk_hw_unregister_divider (clk_data->hws[mcd->id]); clk_data->hws[mcd->id] =ERR_PTR (-ENOENT ); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 477/717 dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup()
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
[ Upstream commit 898ec89dbb55b8294695ad71694a0684e62b2a73 ]
User reports observing timer event report channel halted but no error observed in CHANERR register. The driver finished self-test and released channel resources. Debug shows that __cleanup() can call mod_timer() after the timer has been deleted and thus resurrect the timer. While harmless, it causes suprious error message to be emitted. Use mod_timer_pending() call to prevent deleted timer from being resurrected.
--- drivers/dma/ioat/dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/dma/ioat/dma.c +3 -3
@@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)if (active - i ==0 ) {dev_dbg (to_dev (ioat_chan),"%s: cancel completion timeout\n" , __func__); -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); }/* microsecond delay by sysfs variable per pending descriptor */
@@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan)if (chanerr & (IOAT_CHANERR_HANDLE_MASK |IOAT_CHANERR_RECOVER_MASK )) { -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT );ioat_eh (ioat_chan); } }
@@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan) }if (test_and_clear_bit (IOAT_CHAN_ACTIVE , &ioat_chan->state)) -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); }static void ioat_reboot_chan (struct ioatdma_chan *ioat_chan)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 478/717 usb: mtu3: fix failed runtime suspend in host only mode
In reply to Greg Kroah-HartmanFrom: Chunfeng Yun <[email protected]>
[ Upstream commit 1c703e29da5efac6180e4c189029fa34b7e48e97 ]
When the dr_mode is "host", after the host enter runtime suspend, the mtu3 can't do it, because the mtu3's device wakeup function is not enabled, instead it's enabled in gadget init function, to fix the issue, init wakeup early in mtu3's probe()
--- drivers/usb/mtu3/mtu3_core.c | 2 -- drivers/usb/mtu3/mtu3_plat.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/usb/mtu3/mtu3_core.c +0 -2
@@ -971,8 +971,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) goto irq_err; } -device_init_wakeup (dev, true); -/* power down device IP for power saving by default */ mtu3_stop (mtu);
drivers/usb/mtu3/mtu3_plat.c +2 -0
@@ -332,6 +332,8 @@ static int mtu3_probe(struct platform_device *pdev)pm_runtime_enable (dev);pm_runtime_get_sync (dev); +device_init_wakeup (dev, true); + ret =ssusb_rscs_init (ssusb);if (ret) goto comm_init_err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 479/717 spmi: pmic-arb: correct duplicate APID to PPID mapping logic
In reply to Greg Kroah-HartmanFrom: David Collins <[email protected]>
[ Upstream commit 1f1693118c2476cb1666ad357edcf3cf48bf9b16 ]
Correct the way that duplicate PPID mappings are handled for PMIC arbiter v5. The final APID mapped to a given PPID should be the one which has write owner = APPS EE, if it exists, or if not that, then the first APID mapped to the PPID, if it exists.
--- drivers/spmi/spmi-pmic-arb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/spmi/spmi-pmic-arb.c +7 -6
@@ -992,7 +992,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)* version 5, there is more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID -* for a given PPID will receive interrupts from the PPID. +* which has the IRQ owner bit set for a given PPID will receive +* interrupts from the PPID. */ for (i =0 ; ; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset (i);
@@ -1015,16 +1016,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID ; prev_apidd = &pmic_arb->apid_data[apid]; -if (valid && is_irq_ee && - prev_apidd->write_ee == pmic_arb->ee) { +if (!valid || apidd->write_ee == pmic_arb->ee) { +/* First PPID mapping or one for this EE */ + pmic_arb->ppid_to_apid[ppid] = i |PMIC_ARB_APID_VALID ; + }else if (valid && is_irq_ee && + prev_apidd->write_ee == pmic_arb->ee) {/* * Duplicate PPID mapping after the one for this EE; * override the irq owner */ prev_apidd->irq_ee = apidd->irq_ee; - }else if (!valid || is_irq_ee) { -/* First PPID mapping or duplicate for another EE */ - pmic_arb->ppid_to_apid[ppid] = i |PMIC_ARB_APID_VALID ; } apidd->ppid = ppid;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 480/717 clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit c388cc804016cf0f65afdc2362b120aa594ff3e6 ]
We have discovered random glitches during the system boot up procedure. The problem investigation led us to the weird outcomes: when none of the Renesas 5P49V6901 ports are explicitly enabled by the kernel driver, the glitches disappeared. It was a mystery since the SoC external clock domains were fed with different 5P49V6901 outputs. The driver code didn't seem like bogus either. We almost despaired to find out a root cause when the solution has been found for a more modern revision of the chip. It turned out the 5P49V6901 clock generator stopped its output for a short period of time during the VC5_OUT_DIV_CONTROL register writing. The same problem was found for the 5P49V6965 revision of the chip and was successfully fixed in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") by enabling the "bypass_sync" flag hidden inside "Unused Factory Reserved Register". Even though the 5P49V6901 registers description and programming guide doesn't provide any intel regarding that flag, setting it up anyway in the officially unused register completely eliminated the denoted glitches. Thus let's activate the functionality submitted in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") for the Renesas 5P49V6901 chip too in order to remove the ports implicit inter-dependency.
--- drivers/clk/clk-versaclock5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-versaclock5.c +1 -1
@@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = { .model = IDT_VC6_5P49V6901, .clk_fod_cnt = 4, .clk_out_cnt = 5, - .flags = VC5_HAS_PFD_FREQ_DBL, + .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT, };static const struct vc5_chip_info idt_5p49v6965_info = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 481/717 clk: baikal-t1: Fix invalid xGMAC PTP clock divider
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 3c742088686ce922704aec5b11d09bcc5a396589 ]
Most likely due to copy-paste mistake the divider has been set to 10 while according to the SoC reference manual it's supposed to be 8 thus having PTP clock frequency of 156.25 MHz.
--- drivers/clk/baikal-t1/clk-ccu-div.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/baikal-t1/clk-ccu-div.c +1 -1
@@ -207,7 +207,7 @@ static const struct ccu_div_info sys_info[] = {CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" ,"eth_clk" ,CCU_SYS_XGMAC_BASE ,8 ),CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_PTP_CLK ,"sys_xgmac_ptp_clk" , -"eth_clk" ,10 ), +"eth_clk" ,8 ),CCU_DIV_GATE_INFO (CCU_SYS_USB_CLK ,"sys_usb_clk" ,"eth_clk" ,CCU_SYS_USB_BASE ,10 ), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 482/717 clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit e2eef312762e0b5a5a70d29fe59a245c0a3cffa0 ]
Baikal-T1 CCU reference manual says that both xGMAC reference and xGMAC PTP clocks are generated by two different wrappers with the same constant divider thus each producing a 156.25 MHz signal. But for some reason both of these clock sources are gated by a single switch-flag in the CCU registers space - CCU_SYS_XGMAC_BASE.BIT(0). In order to make the clocks handled independently we need to define a shared parental gate so the base clock signal would be switched off only if both of the child-clocks are disabled.
Note the ID is intentionally set to -2 since we are going to add a one more internal clock identifier in the next commit.
--- drivers/clk/baikal-t1/ccu-div.c | 1 + drivers/clk/baikal-t1/ccu-div.h | 6 ++++++ drivers/clk/baikal-t1/clk-ccu-div.c | 8 +++++--- 3 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/baikal-t1/ccu-div.c +1 -0
@@ -579,6 +579,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) goto err_free_div; } parent_data.fw_name = div_init->parent_name; + parent_data.name = div_init->parent_name; hw_init.parent_data = &parent_data; hw_init.num_parents =1 ;
drivers/clk/baikal-t1/ccu-div.h +6 -0
@@ -13,6 +13,12 @@#include <linux/bits.h> #include <linux/of.h> +/* +* CCU Divider private clock IDs +* @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock +*/ +#define CCU_SYS_XGMAC_CLK -2 +/* * CCU Divider private flags * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
drivers/clk/baikal-t1/clk-ccu-div.c +5 -3
@@ -204,10 +204,12 @@ static const struct ccu_div_info sys_info[] = { "eth_clk", CCU_SYS_GMAC1_BASE, 5),CCU_DIV_FIXED_INFO (CCU_SYS_GMAC1_PTP_CLK ,"sys_gmac1_ptp_clk" ,"eth_clk" ,10 ), -CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" , -"eth_clk" ,CCU_SYS_XGMAC_BASE ,8 ), +CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_CLK ,"sys_xgmac_clk" , +"eth_clk" ,CCU_SYS_XGMAC_BASE ,1 ), +CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" , +"sys_xgmac_clk" ,8 ),CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_PTP_CLK ,"sys_xgmac_ptp_clk" , -"eth_clk" ,8 ), +"sys_xgmac_clk" ,8 ),CCU_DIV_GATE_INFO (CCU_SYS_USB_CLK ,"sys_usb_clk" ,"eth_clk" ,CCU_SYS_USB_BASE ,10 ), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 483/717 clk: baikal-t1: Add SATA internal ref clock buffer
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 081a9b7c74eae4e12b2cb1b86720f836a8f29247 ]
It turns out the internal SATA reference clock signal will stay unavailable for the SATA interface consumer until the buffer on it's way is ungated. So aside with having the actual clock divider enabled we need to ungate a buffer placed on the signal way to the SATA controller (most likely some rudiment from the initial SoC release). Seeing the switch flag is placed in the same register as the SATA-ref clock divider at a non-standard ffset, let's implement it as a separate clock controller with the set-rate propagation to the parental clock divider wrapper. As such we'll be able to disable/enable and still change the original clock source rate.
--- drivers/clk/baikal-t1/ccu-div.c | 64 +++++++++++++++++++++++++++++ drivers/clk/baikal-t1/ccu-div.h | 4 ++ drivers/clk/baikal-t1/clk-ccu-div.c | 18 +++++++- 3 files changed, 85 insertions(+), 1 deletion(-)
drivers/clk/baikal-t1/ccu-div.c +64 -0
@@ -34,6 +34,7 @@#define CCU_DIV_CTL_CLKDIV_MASK (_width) \ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)#define CCU_DIV_CTL_LOCK_SHIFTED BIT(27) +#define CCU_DIV_CTL_GATE_REF_BUF BIT(28)#define CCU_DIV_CTL_LOCK_NORMAL BIT(31)#define CCU_DIV_RST_DELAY_US 1
@@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)return !!(val &CCU_DIV_CTL_EN ); } +static int ccu_div_buf_enable (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +unsigned long flags; + +spin_lock_irqsave (&div->lock, flags); +regmap_update_bits (div->sys_regs, div->reg_ctl, +CCU_DIV_CTL_GATE_REF_BUF ,0 ); +spin_unlock_irqrestore (&div->lock, flags); + +return 0 ; +} + +static void ccu_div_buf_disable (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +unsigned long flags; + +spin_lock_irqsave (&div->lock, flags); +regmap_update_bits (div->sys_regs, div->reg_ctl, +CCU_DIV_CTL_GATE_REF_BUF ,CCU_DIV_CTL_GATE_REF_BUF ); +spin_unlock_irqrestore (&div->lock, flags); +} + +static int ccu_div_buf_is_enabled (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +u32 val =0 ; + +regmap_read (div->sys_regs, div->reg_ctl, &val); + +return !(val &CCU_DIV_CTL_GATE_REF_BUF ); +} +static unsigned long ccu_div_var_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) {
@@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {CCU_DIV_DBGFS_BIT_ATTR ("div_en" ,CCU_DIV_CTL_EN ),CCU_DIV_DBGFS_BIT_ATTR ("div_rst" ,CCU_DIV_CTL_RST ),CCU_DIV_DBGFS_BIT_ATTR ("div_bypass" ,CCU_DIV_CTL_SET_CLKDIV ), +CCU_DIV_DBGFS_BIT_ATTR ("div_buf" ,CCU_DIV_CTL_GATE_REF_BUF ), CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL) };
@@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)continue ; } +if (!strcmp ("div_buf" , name)) +continue ; + bits[didx] = ccu_div_bits[bidx]; bits[didx].div = div;
@@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) &ccu_div_dbgfs_fixed_clkdiv_fops); } +static void ccu_div_buf_debug_init (struct clk_hw *hw,struct dentry *dentry) +{ +struct ccu_div *div =to_ccu_div (hw); +struct ccu_div_dbgfs_bit *bit; + + bit =kmalloc (sizeof (*bit),GFP_KERNEL ); +if (!bit) +return ; + + *bit = ccu_div_bits[3 ]; + bit->div = div; +debugfs_create_file_unsafe (bit->name, ccu_div_dbgfs_mode, dentry, bit, + &ccu_div_dbgfs_bit_fops); +} +static void ccu_div_fixed_debug_init (struct clk_hw *hw,struct dentry *dentry) {struct ccu_div *div =to_ccu_div (hw);
@@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)#define ccu_div_var_debug_init NULL#define ccu_div_gate_debug_init NULL +#define ccu_div_buf_debug_init NULL#define ccu_div_fixed_debug_init NULL#endif /* !CONFIG_DEBUG_FS */
@@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = { .debug_init = ccu_div_gate_debug_init }; +static const struct clk_ops ccu_div_buf_ops = { + .enable = ccu_div_buf_enable, + .disable = ccu_div_buf_disable, + .is_enabled = ccu_div_buf_is_enabled, + .debug_init = ccu_div_buf_debug_init +}; +static const struct clk_ops ccu_div_fixed_ops = { .recalc_rate = ccu_div_fixed_recalc_rate, .round_rate = ccu_div_fixed_round_rate,
@@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) }else if (div_init->type ==CCU_DIV_GATE ) { hw_init.ops = &ccu_div_gate_ops; div->divider = div_init->divider; + }else if (div_init->type ==CCU_DIV_BUF ) { + hw_init.ops = &ccu_div_buf_ops; }else if (div_init->type ==CCU_DIV_FIXED ) { hw_init.ops = &ccu_div_fixed_ops; div->divider = div_init->divider;
drivers/clk/baikal-t1/ccu-div.h +4 -0
@@ -15,8 +15,10 @@/* * CCU Divider private clock IDs +* @CCU_SYS_SATA_CLK: CCU SATA internal clock * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock */ +#define CCU_SYS_SATA_CLK -1#define CCU_SYS_XGMAC_CLK -2/*
@@ -37,11 +39,13 @@* enum ccu_div_type - CCU Divider types * @CCU_DIV_VAR: Clocks gate with variable divider. * @CCU_DIV_GATE: Clocks gate with fixed divider. +* @CCU_DIV_BUF: Clock gate with no divider. * @CCU_DIV_FIXED: Ungateable clock with fixed divider. */ enum ccu_div_type {CCU_DIV_VAR ,CCU_DIV_GATE , +CCU_DIV_BUF ,CCU_DIV_FIXED };
drivers/clk/baikal-t1/clk-ccu-div.c +17 -1
@@ -76,6 +76,16 @@ .divider = _divider \ } +#define CCU_DIV_BUF_INFO (_id, _name, _pname, _base, _flags) \ + { \ + .id = _id, \ + .name = _name, \ + .parent_name = _pname, \ + .base = _base, \ + .type = CCU_DIV_BUF, \ + .flags = _flags \ + } +#define CCU_DIV_FIXED_INFO (_id, _name, _pname, _divider) \ { \ .id = _id, \
@@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = {* for the SoC devices registers IO-operations. */ static const struct ccu_div_info sys_info[] = { -CCU_DIV_VAR_INFO (CCU_SYS_SATA_REF_CLK ,"sys_sata_ref_clk" , +CCU_DIV_VAR_INFO (CCU_SYS_SATA_CLK ,"sys_sata_clk" ,"sata_clk" ,CCU_SYS_SATA_REF_BASE ,4 ,CLK_SET_RATE_GATE ,CCU_DIV_SKIP_ONE |CCU_DIV_LOCK_SHIFTED |CCU_DIV_RESET_DOMAIN ), +CCU_DIV_BUF_INFO (CCU_SYS_SATA_REF_CLK ,"sys_sata_ref_clk" , +"sys_sata_clk" ,CCU_SYS_SATA_REF_BASE , +CLK_SET_RATE_PARENT ),CCU_DIV_VAR_INFO (CCU_SYS_APB_CLK ,"sys_apb_clk" ,"pcie_clk" ,CCU_SYS_APB_BASE ,5 ,CLK_IS_CRITICAL ,CCU_DIV_RESET_DOMAIN ),
@@ -398,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data) init.base = info->base; init.sys_regs = data->sys_regs; init.divider = info->divider; + }else if (init.type ==CCU_DIV_BUF ) { + init.base = info->base; + init.sys_regs = data->sys_regs; }else { init.divider = info->divider; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 484/717 clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration
In reply to Greg Kroah-HartmanFrom: Stefan Wahren <[email protected]>
[ Upstream commit 0b919a3728691c172312dee99ba654055ccd8c84 ]
The return value of bcm2835_clock_rate_from_divisor is always unsigned and also all caller expect this. So fix the declaration accordingly.
--- drivers/clk/bcm/clk-bcm2835.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/bcm/clk-bcm2835.c +3 -3
@@ -966,9 +966,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,return div; } -static long bcm2835_clock_rate_from_divisor (struct bcm2835_clock *clock, -unsigned long parent_rate, -u32 div) +static unsigned long bcm2835_clock_rate_from_divisor (struct bcm2835_clock *clock, +unsigned long parent_rate, +u32 div) {const struct bcm2835_clock_data *data = clock->data;u64 temp;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 485/717 clk: imx: scu: fix memleak on platform_device_add() fails
In reply to Greg Kroah-HartmanFrom: Lin Yujun <[email protected]>
[ Upstream commit 855ae87a2073ebf1b395e020de54fdf9ce7d166f ]
No error handling is performed when platform_device_add() fails. Add error processing before return, and modified the return value.
--- drivers/clk/imx/clk-scu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/clk/imx/clk-scu.c +5 -1
@@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,pr_warn ("%s: failed to attached the power domain %d\n" , name, ret); -platform_device_add (pdev); + ret =platform_device_add (pdev); +if (ret) { +platform_device_put (pdev); +return ERR_PTR (ret); + }/* For API backwards compatiblilty, simply return NULL for success */ return NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 486/717 clk: ti: Balance of_node_get() calls for of_find_node_by_name()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 058a3996b888ab60eb1857fb4fd28f1b89a9a95a ]
In ti_find_clock_provider(), of_find_node_by_name() will call of_node_put() for the 'from' argument, possibly putting the node one too many times. Let's maintain the of_node_get() from the previous search and only put when we're exiting the function early. This should avoid a misbalanced reference count on the node.
[[email protected]: Rewrite commit text, maintain reference instead of get again]
--- drivers/clk/ti/clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/ti/clk.c +3 -2
@@ -148,11 +148,12 @@ static struct device_node *ti_find_clock_provider(struct device_node *from,break ; } } -of_node_put (from);kfree (tmp); -if (found) +if (found) { +of_node_put (from);return np; + }/* Fall back to using old node name base provider name */ return of_find_node_by_name (from, name);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 487/717 clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 9c59a01caba26ec06fefd6ca1f22d5fd1de57d63 ]
pm_runtime_get_sync() will increment pm usage counter. Forgetting to putting operation will result in reference leak. Add missing pm_runtime_put_sync in some error paths.
--- drivers/clk/ti/clk-dra7-atl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/ti/clk-dra7-atl.c +6 -3
@@ -253,14 +253,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)if (rc) {pr_err ("%s: failed to lookup atl clock %d\n" , __func__, i); -return -EINVAL ; + ret = -EINVAL ; + goto pm_put; } clk =of_clk_get_from_provider (&clkspec);if (IS_ERR (clk)) {pr_err ("%s: failed to get atl clock %d from provider\n" , __func__, i); -return PTR_ERR (clk); + ret =PTR_ERR (clk); + goto pm_put; } cdesc =to_atl_desc (__clk_get_hw (clk));
@@ -293,8 +295,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)if (cdesc->enabled)atl_clk_enable (__clk_get_hw (clk)); } -pm_runtime_put_sync (cinfo->dev); +pm_put: +pm_runtime_put_sync (cinfo->dev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 488/717 clk: ast2600: BCLK comes from EPLL
In reply to Greg Kroah-HartmanFrom: Joel Stanley <[email protected]>
[ Upstream commit b8c1dc9c00b252b3be853720a71b05ed451ddd9f ]
This correction was made in the u-boot SDK recently. There are no in-tree users of this clock so the impact is minimal.
--- drivers/clk/clk-ast2600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-ast2600.c +1 -1
@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)regmap_write (map,0x308 ,0x12000 );/* 3x3 = 9 */ /* P-Bus (BCLK) clock divider */ - hw =clk_hw_register_divider_table (dev,"bclk" ,"hpll" ,0 , + hw =clk_hw_register_divider_table (dev,"bclk" ,"epll" ,0 , scu_g6_base +ASPEED_G6_CLK_SELECTION1 ,20 ,3 ,0 , ast2600_div_table, &aspeed_g6_clk_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 489/717 mailbox: mpfs: fix handling of the reg property
In reply to Greg Kroah-HartmanFrom: Conor Dooley <[email protected]>
[ Upstream commit 2e10289d1f304f5082a4dda55a677b72b3bdb581 ]
The "data" region of the PolarFire SoC's system controller mailbox is not one continuous register space - the system controller's QSPI sits between the control and data registers. Split the "data" reg into two
parts: "data" & "control". Optionally get the "data" register address from the 3rd reg property in the devicetree & fall back to using the old base + MAILBOX_REG_OFFSET that the current code uses.
--- drivers/mailbox/mailbox-mpfs.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
drivers/mailbox/mailbox-mpfs.c +14 -10
@@ -62,6 +62,7 @@ struct mpfs_mbox {struct mbox_controller controller;struct device *dev;int irq; +void __iomem *ctrl_base;void __iomem *mbox_base;void __iomem *int_reg;struct mbox_chan chans[1 ];
@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) {u32 status; - status =readl_relaxed (mbox->mbox_base +SERVICES_SR_OFFSET ); + status =readl_relaxed (mbox->ctrl_base +SERVICES_SR_OFFSET );return status &SCB_STATUS_BUSY_MASK ; }
@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)for (index =0 ; index < (msg->cmd_data_size /4 ); index++)writel_relaxed (word_buf[index], - mbox->mbox_base +MAILBOX_REG_OFFSET + index *0x4 ); + mbox->mbox_base + index *0x4 );if (extra_bits) {u8 i;u8 byte_off =ALIGN_DOWN (msg->cmd_data_size,4 );u8 *byte_buf = msg->cmd_data + byte_off; - val =readl_relaxed (mbox->mbox_base + -MAILBOX_REG_OFFSET + index *0x4 ); + val =readl_relaxed (mbox->mbox_base + index *0x4 );for (i =0u ; i < extra_bits; i++) { val &= ~(0xffu << (i *8u ));
@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) }writel_relaxed (val, - mbox->mbox_base +MAILBOX_REG_OFFSET + index *0x4 ); + mbox->mbox_base + index *0x4 ); } } opt_sel = ((msg->mbox_offset <<7u ) | (msg->cmd_opcode &0x7fu )); tx_trigger = (opt_sel <<SCB_CTRL_POS ) &SCB_CTRL_MASK ; tx_trigger |=SCB_CTRL_REQ_MASK |SCB_STATUS_NOTIFY_MASK ; -writel_relaxed (tx_trigger, mbox->mbox_base +SERVICES_CR_OFFSET ); +writel_relaxed (tx_trigger, mbox->ctrl_base +SERVICES_CR_OFFSET );return 0 ; }
@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)if (!mpfs_mbox_busy (mbox)) {for (i =0 ; i < num_words; i++) { response->resp_msg[i] = -readl_relaxed (mbox->mbox_base +MAILBOX_REG_OFFSET +readl_relaxed (mbox->mbox_base + mbox->resp_offset + i *0x4 ); } }
@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)if (!mbox)return -ENOMEM ; - mbox->mbox_base =devm_platform_get_and_ioremap_resource (pdev,0 , ®s); -if (IS_ERR (mbox->mbox_base)) -return PTR_ERR (mbox->mbox_base); + mbox->ctrl_base =devm_platform_get_and_ioremap_resource (pdev,0 , ®s); +if (IS_ERR (mbox->ctrl_base)) +return PTR_ERR (mbox->ctrl_base); mbox->int_reg =devm_platform_get_and_ioremap_resource (pdev,1 , ®s);if (IS_ERR (mbox->int_reg))return PTR_ERR (mbox->int_reg); + mbox->mbox_base =devm_platform_get_and_ioremap_resource (pdev,2 , ®s); +if (IS_ERR (mbox->mbox_base))// account for the old dt-binding w/ 2 regs + mbox->mbox_base = mbox->ctrl_base +MAILBOX_REG_OFFSET ; + mbox->irq =platform_get_irq (pdev,0 );if (mbox->irq <0 )return mbox->irq;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 490/717 mailbox: mpfs: account for mbox offsets while sending
In reply to Greg Kroah-HartmanFrom: Conor Dooley <[email protected]>
[ Upstream commit 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 ]
The mailbox offset is not only used for receiving messages, but it is also used by messages sent to the system controller by Linux that have a payload, such as the "digital signature service". It is also overloaded by certain other services (reprogramming of the FPGA fabric, see Link:) to have a meaning other than the offset the system controller should read from.
When the driver was written, no such services of the latter type were in use & those of the former used an offset of zero so this has gone un-noticed.
--- drivers/mailbox/mailbox-mpfs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/mailbox/mailbox-mpfs.c +3 -4
@@ -100,21 +100,20 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)for (index =0 ; index < (msg->cmd_data_size /4 ); index++)writel_relaxed (word_buf[index], - mbox->mbox_base + index *0x4 ); + mbox->mbox_base + msg->mbox_offset + index *0x4 );if (extra_bits) {u8 i;u8 byte_off =ALIGN_DOWN (msg->cmd_data_size,4 );u8 *byte_buf = msg->cmd_data + byte_off; - val =readl_relaxed (mbox->mbox_base + index *0x4 ); + val =readl_relaxed (mbox->mbox_base + msg->mbox_offset + index *0x4 );for (i =0u ; i < extra_bits; i++) { val &= ~(0xffu << (i *8u )); val |= (byte_buf[i] << (i *8u )); } -writel_relaxed (val, - mbox->mbox_base + index *0x4 ); +writel_relaxed (val, mbox->mbox_base + msg->mbox_offset + index *0x4 ); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 491/717 mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 6b207ce8a96a71e966831e3a13c38143ba9a73c1 ]
dma_map_sg return 0 on error, fix the error check, and return -EIO to caller.
--- drivers/mailbox/bcm-flexrm-mailbox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mailbox/bcm-flexrm-mailbox.c +4 -4
@@ -632,15 +632,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg) rc =dma_map_sg (dev, msg->spu.src,sg_nents (msg->spu.src),DMA_TO_DEVICE ); -if (rc <0 ) -return rc; +if (!rc) +return -EIO ; rc =dma_map_sg (dev, msg->spu.dst,sg_nents (msg->spu.dst),DMA_FROM_DEVICE ); -if (rc <0 ) { +if (!rc) {dma_unmap_sg (dev, msg->spu.src,sg_nents (msg->spu.src),DMA_TO_DEVICE ); -return rc; +return -EIO ; }return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 492/717 ipc: mqueue: fix possible memory leak in init_mqueue_fs()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit c579d60f0d0cd87552f64fdebe68b5d941d20309 ]
commit db7cfc380900 ("ipc: Free mq_sysctls if ipc namespace creation failed")
Here's a similar memory leak to the one fixed by the patch above. retire_mq_sysctls need to be called when init_mqueue_fs fails after setup_mq_sysctls.
--- ipc/mqueue.c | 1 + 1 file changed, 1 insertion(+)
ipc/mqueue.c +1 -0
@@ -1746,6 +1746,7 @@ static int __init init_mqueue_fs(void)unregister_filesystem (&mqueue_fs_type); out_sysctl:kmem_cache_destroy (mqueue_inode_cachep); +retire_mq_sysctls (&init_ipc_ns);return error; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 493/717 powerpc/configs: Properly enable PAPR_SCM in pseries_defconfig
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit aa398d88aea4ec863bd7aea35d5035a37096dc59 ]
My commit to add PAPR_SCM to pseries_defconfig failed to add the required dependencies, meaning the driver doesn't get built.
Add the required LIBNVDIMM=m.
--- arch/powerpc/configs/pseries_defconfig | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/configs/pseries_defconfig +1 -0
@@ -40,6 +40,7 @@ CONFIG_PPC_SPLPAR=y CONFIG_DTL=y CONFIG_PPC_SMLPAR=y CONFIG_IBMEBUS=y +CONFIG_LIBNVDIMM=m CONFIG_PAPR_SCM=m CONFIG_PPC_SVM=y # CONFIG_PPC_PMAC is not set
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 494/717 powerpc/math_emu/efp: Include module.h
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit cfe0d370e0788625ce0df3239aad07a2506c1796 ]
When building with a recent version of clang, there are a couple of errors around the call to module_init():
arch/powerpc/math-emu/math_efp.c:927:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] module_init(spe_mathemu_init);
^
int
arch/powerpc/math-emu/math_efp.c:927:13: error: a parameter list without types is only allowed in a function definition
module_init(spe_mathemu_init);
^2 errors generated.
module_init() is a macro, which is not getting expanded because module.h is not included in this file. Add the include so that the macro can expand properly, clearing up the build failure.
--- arch/powerpc/math-emu/math_efp.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/math-emu/math_efp.c +1 -0
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/prctl.h> +#include <linux/module.h> #include <linux/uaccess.h> #include <asm/reg.h>
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 495/717 powerpc/sysdev/fsl_msi: Add missing of_node_put()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit def435c04ee984a5f9ed2711b2bfe946936c6a21 ]
In fsl_setup_msi_irqs(), use of_node_put() to drop the reference returned by of_parse_phandle().
--- arch/powerpc/sysdev/fsl_msi.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/sysdev/fsl_msi.c +2 -0
@@ -209,8 +209,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)dev_err (&pdev->dev,"node %pOF has an invalid fsl,msi phandle %u\n" , hose->dn, np->phandle); +of_node_put (np);return -EINVAL ; } +of_node_put (np); }msi_for_each_desc (entry, &pdev->dev,MSI_DESC_NOTASSOCIATED ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 496/717 powerpc/pci_dn: Add missing of_node_put()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 110a1fcb6c4d55144d8179983a475f17a1d6f832 ]
In pci_add_device_node_info(), use of_node_put() to drop the reference to 'parent' returned by of_get_parent() to keep refcount balance.
--- arch/powerpc/kernel/pci_dn.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/kernel/pci_dn.c +1 -0
@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,INIT_LIST_HEAD (&pdn->list); parent =of_get_parent (dn); pdn->parent = parent ?PCI_DN (parent) :NULL ; +of_node_put (parent);if (pdn->parent)list_add_tail (&pdn->list, &pdn->parent->child_list);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 497/717 powerpc/powernv: add missing of_node_put() in opal_export_attrs()
In reply to Greg Kroah-HartmanFrom: Zheng Yongjun <[email protected]>
[ Upstream commit 71a92e99c47900cc164620948b3863382cec4f1a ]
After using 'np' returned by of_find_node_by_path(), of_node_put() need be called to decrease the refcount.
--- arch/powerpc/platforms/powernv/opal.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/platforms/powernv/opal.c +1 -0
@@ -892,6 +892,7 @@ static void opal_export_attrs(void) kobj =kobject_create_and_add ("exports" , opal_kobj);if (!kobj) {pr_warn ("kobject_create_and_add() of exports failed\n" ); +of_node_put (np);return ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 498/717 cpuidle: riscv-sbi: Fix CPU_PM_CPU_IDLE_ENTER_xyz() macro usage
In reply to Greg Kroah-HartmanFrom: Anup Patel <[email protected]>
[ Upstream commit cfadbb9df8c4dc917787da4458327e5ec14743d4 ]
Currently, we are using CPU_PM_CPU_IDLE_ENTER_PARAM() for all SBI HSM suspend types so retentive suspend types are also treated non-retentive and kernel will do redundant additional work for these states.
The BIT[31] of SBI HSM suspend types allows us to differentiate between retentive and non-retentive suspend types so we should use this BIT to call appropriate CPU_PM_CPU_IDLE_ENTER_xyz() macro.
--- drivers/cpuidle/cpuidle-riscv-sbi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/cpuidle/cpuidle-riscv-sbi.c +6 -1
@@ -97,8 +97,13 @@ static int sbi_cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int idx) {u32 *states =__this_cpu_read (sbi_cpuidle_data.states); +u32 state = states[idx]; -return CPU_PM_CPU_IDLE_ENTER_PARAM (sbi_suspend, idx, states[idx]); +if (state &SBI_HSM_SUSP_NON_RET_BIT ) +return CPU_PM_CPU_IDLE_ENTER_PARAM (sbi_suspend, idx, state); +else +return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM (sbi_suspend, + idx, state); } static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 499/717 powerpc: Fix fallocate and fadvise64_64 compat parameter combination
In reply to Greg Kroah-HartmanFrom: Rohan McLure <[email protected]>
[ Upstream commit 016ff72bd2090903715c0f9422a44afbb966f4ee ]
As reported[1] by Arnd, the arch-specific fadvise64_64 and fallocate compatibility handlers assume parameters are passed with 32-bit big-endian ABI. This affects the assignment of odd-even parameter pairs to the high or low words of a 64-bit syscall parameter.
Fix fadvise64_64 fallocate compat handlers to correctly swap upper/lower 32 bits conditioned on endianness.
A future patch will replace the arch-specific compat fallocate with an asm-generic implementation. This patch is intended for ease of back-port.
[1]: https://lore.kernel.org/all/[email protected]/
--- arch/powerpc/include/asm/syscalls.h | 12 ++++++++++++ arch/powerpc/kernel/sys_ppc32.c | 14 +------------- arch/powerpc/kernel/syscalls.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-)
arch/powerpc/include/asm/syscalls.h +12 -0
@@ -8,6 +8,18 @@#include <linux/types.h> #include <linux/compat.h> +/* +* long long munging: +* The 32 bit ABI passes long longs in an odd even register pair. +* High and low parts are swapped depending on endian mode, +* so define a macro (similar to mips linux32) to handle that. +*/ +#ifdef __LITTLE_ENDIAN__ +#define merge_64 (low, high) (((u64)high << 32) | low) +#else +#define merge_64 (high, low) (((u64)high << 32) | low) +#endif +struct rtas_args ; asmlinkage long sys_mmap(unsigned long addr, size_t len,
arch/powerpc/kernel/sys_ppc32.c +1 -13
@@ -56,18 +56,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len,return sys_mmap (addr, len, prot, flags, fd, pgoff <<12 ); } -/* -* long long munging: -* The 32 bit ABI passes long longs in an odd even register pair. -* High and low parts are swapped depending on endian mode, -* so define a macro (similar to mips linux32) to handle that. -*/ -#ifdef __LITTLE_ENDIAN__ -#define merge_64 (low, high) ((u64)high << 32) | low -#else -#define merge_64 (high, low) ((u64)high << 32) | low -#endif -compat_ssize_t compat_sys_pread64 (unsigned int fd,char __user *ubuf,compat_size_t count,u32 reg6,u32 pos1,u32 pos2) {
@@ -94,7 +82,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,asmlinkage long compat_sys_fallocate (int fd,int mode,u32 offset1,u32 offset2,u32 len1,u32 len2) { -return ksys_fallocate (fd, mode, ((loff_t )offset1 <<32 ) | offset2, +return ksys_fallocate (fd, mode,merge_64 (offset1, offset2),merge_64 (len1, len2)); }
arch/powerpc/kernel/syscalls.c +2 -2
@@ -98,8 +98,8 @@ long ppc64_personality(unsigned long personality)long ppc_fadvise64_64 (int fd,int advice,u32 offset_high,u32 offset_low,u32 len_high,u32 len_low) { -return ksys_fadvise64_64 (fd, (u64 )offset_high <<32 | offset_low, - (u64 )len_high <<32 | len_low, advice); +return ksys_fadvise64_64 (fd,merge_64 (offset_high, offset_low), +merge_64 (len_high, len_low), advice); }SYSCALL_DEFINE0 (switch_endian)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 500/717 x86/hyperv: Fix struct hv_enlightened_vmcs definition
In reply to Greg Kroah-HartmanFrom: Vitaly Kuznetsov <[email protected]>
[ Upstream commit ea9da788a61e47e7ab9cbad397453e51cd82ac0d ]
Section 1.9 of TLFS v6.0b says:
"All structures are padded in such a way that fields are aligned naturally (that is, an 8-byte field is aligned to an offset of 8 bytes and so on)".
'struct enlightened_vmcs' has a glitch:
...
struct {
u32 nested_flush_hypercall:1; /* 836: 0 4 */
u32 msr_bitmap:1; /* 836: 1 4 */
u32 reserved:30; /* 836: 2 4 */
} hv_enlightenments_control; /* 836 4 */
u32 hv_vp_id; /* 840 4 */
u64 hv_vm_id; /* 844 8 */
u64 partition_assist_page; /* 852 8 */...
And the observed values in 'partition_assist_page' make no sense at all. Fix the layout by padding the structure properly.
--- arch/x86/include/asm/hyperv-tlfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/hyperv-tlfs.h +2 -2
@@ -546,7 +546,7 @@ struct hv_enlightened_vmcs {u64 guest_rip;u32 hv_clean_fields; -u32 hv_padding_32; +u32 padding32_1;u32 hv_synthetic_controls;struct {u32 nested_flush_hypercall:1 ;
@@ -554,7 +554,7 @@ struct hv_enlightened_vmcs { u32 reserved:30; }__packed hv_enlightenments_control;u32 hv_vp_id; - +u32 padding32_2;u64 hv_vm_id;u64 partition_assist_page;u64 padding64_4[4 ];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 501/717 powerpc/64s: Fix GENERIC_CPU build flags for PPC970 / G5
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 58ec7f06b74e0d6e76c4110afce367c8b5f0837d ]
Big-endian GENERIC_CPU supports 970, but builds with -mcpu=power5. POWER5 is ISA v2.02 whereas 970 is v2.01 plus Altivec. 2.02 added the popcntb instruction which a compiler might use.
Use -mcpu=power4.
--- arch/powerpc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/Makefile +1 -1
@@ -152,7 +152,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8 CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8) else CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5)) -CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4) +CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4 endif else ifdef CONFIG_PPC_BOOK3E_64 CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 502/717 powerpc/64: mark irqs hard disabled in boot paca
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 799f7063c7645f9a751d17f5dfd73b952f962cd2 ]
This prevents interrupts in early boot (e.g., program check) from enabling MSR[EE], potentially causing endian mismatch or other crashes when reporting early boot traps.
--- arch/powerpc/kernel/setup_64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/kernel/setup_64.c +3 -1
@@ -183,8 +183,10 @@ static void __init fixup_boot_paca(void)get_paca ()->cpu_start =1 ;/* Allow percpu accesses to work until we setup percpu data */ get_paca ()->data_offset =0 ; -/* Mark interrupts disabled in PACA */ +/* Mark interrupts soft and hard disabled in PACA */ irq_soft_mask_set (IRQS_DISABLED ); +get_paca ()->irq_happened =PACA_IRQ_HARD_DIS ; +WARN_ON (mfmsr () &MSR_EE ); }static void __init configure_exceptions (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 503/717 powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit e485f6c751e0a969327336c635ca602feea117f0 ]
If a synchronous interrupt (e.g., hash fault) is taken inside an irqs-disabled region which has MSR[EE]=1, then an asynchronous interrupt that is PACA_IRQ_MUST_HARD_MASK (e.g., PMI) is taken inside the synchronous interrupt handler, then the synchronous interrupt will return with MSR[EE]=1 and the asynchronous interrupt fires again.
If the asynchronous interrupt is a PMI and the original context does not have PMIs disabled (only Linux IRQs), the asynchronous interrupt will fire despite having the PMI marked soft pending. This can confuse the perf code and cause warnings.
This patch changes the interrupt return so that irqs-disabled MSR[EE]=1 contexts will be returned to with MSR[EE]=0 if a PACA_IRQ_MUST_HARD_MASK interrupt has become pending in the meantime.
The longer explanation for what happens:
1. local_irq_disable()
2. Hash fault interrupt fires, do_hash_fault handler runs
3. interrupt_enter_prepare() sets IRQS_ALL_DISABLED
4. interrupt_enter_prepare() sets MSR[EE]=1
5. PMU interrupt fires, masked handler runs
6. Masked handler marks PMI pending
7. Masked handler returns with PACA_IRQ_HARD_DIS set, MSR[EE]=0
8. do_hash_fault interrupt return handler runs
9. interrupt_exit_kernel_prepare() clears PACA_IRQ_HARD_DIS
10. interrupt returns with MSR[EE]=1
11. PMU interrupt fires, perf handler runs
--- arch/powerpc/kernel/interrupt.c | 10 --------- arch/powerpc/kernel/interrupt_64.S | 34 +++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 13 deletions(-)
arch/powerpc/kernel/interrupt.c +0 -10
@@ -592,16 +592,6 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)if (unlikely (stack_store))__hard_EE_RI_disable (); -/* -* Returning to a kernel context with local irqs disabled. -* Here, if EE was enabled in the interrupted context, enable -* it on return as well. A problem exists here where a soft -* masked interrupt may have cleared MSR[EE] and set HARD_DIS -* here, and it will still exist on return to the caller. This -* will be resolved by the masked interrupt firing again. -*/ -if (regs->msr &MSR_EE ) - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS ;#endif /* CONFIG_PPC64 */ }
arch/powerpc/kernel/interrupt_64.S +31 -3
@@ -559,15 +559,43 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel) ld r11,SOFTE(r1) cmpwi r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) - bne 1f + beq .Linterrupt_return_\srr\()_soft_enabled + + /* + * Returning to soft-disabled context. + * Check if a MUST_HARD_MASK interrupt has become pending, in which + * case we need to disable MSR[EE] in the return context. + */ + ld r12,_MSR(r1) + andi. r10,r12,MSR_EE + beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled + lbz r11,PACAIRQHAPPENED(r13) + andi. r10,r11,PACA_IRQ_MUST_HARD_MASK + beq 1f // No HARD_MASK pending + + /* Must clear MSR_EE from _MSR */ +#ifdef CONFIG_PPC_BOOK3S + li r10,0 + /* Clear valid before changing _MSR */ + .ifc \srr,srr + stb r10,PACASRR_VALID(r13) + .else + stb r10,PACAHSRR_VALID(r13) + .endif +#endif + xori r12,r12,MSR_EE + std r12,_MSR(r1) + b .Lfast_kernel_interrupt_return_\srr\() + +.Linterrupt_return_\srr\()_soft_enabled: #ifdef CONFIG_PPC_BOOK3S lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- interrupt_return_\srr\()_kernel_restart #endif - li r11,0 - stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS 1: + li r11,0 + stb r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS .Lfast_kernel_interrupt_return_\srr\(): cmpdi cr1,r3,0
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 504/717 powerpc: Fix SPE Power ISA properties for e500v1 platforms
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 37b9345ce7f4ab17538ea62def6f6d430f091355 ]
Commit 2eb28006431c ("powerpc/e500v2: Add Power ISA properties to comply with ePAPR 1.1") introduced new include file e500v2_power_isa.dtsi and should have used it for all e500v2 platforms. But apparently it was used also for e500v1 platforms mpc8540, mpc8541, mpc8555 and mpc8560.
e500v1 cores compared to e500v2 do not support double precision floating point SPE instructions. Hence power-isa-sp.fd should not be set on e500v1 platforms, which is in e500v2_power_isa.dtsi include file.
Fix this issue by introducing a new e500v1_power_isa.dtsi include file and use it in all e500v1 device tree files.
--- .../boot/dts/fsl/e500v1_power_isa.dtsi | 51 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/mpc8540ads.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8541cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8555cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8560ads.dts | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi new file +51 -0
@@ -0,0 +1,51 @@ +/* + * e500v1 Power ISA Device Tree Source (include) + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/ { + cpus { + power-isa-version = "2.03"; + power-isa-b; // Base + power-isa-e; // Embedded + power-isa-atb; // Alternate Time Base + power-isa-cs; // Cache Specification + power-isa-e.le; // Embedded.Little-Endian + power-isa-e.pm; // Embedded.Performance Monitor + power-isa-ecl; // Embedded Cache Locking + power-isa-mmc; // Memory Coherence + power-isa-sp; // Signal Processing Engine + power-isa-sp.fs; // SPE.Embedded Float Scalar Single + power-isa-sp.fv; // SPE.Embedded Float Vector + mmu-type = "power-embedded"; + }; +};
arch/powerpc/boot/dts/fsl/mpc8540ads.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8540ADS";
arch/powerpc/boot/dts/fsl/mpc8541cds.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8541CDS";
arch/powerpc/boot/dts/fsl/mpc8555cds.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8555CDS";
arch/powerpc/boot/dts/fsl/mpc8560ads.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8560ADS";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 505/717 powerpc/kprobes: Fix null pointer reference in arch_prepare_kprobe()
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
[ Upstream commit 97f88a3d723162781d6cbfdc7b9617eefab55b19 ]
I found a null pointer reference in arch_prepare_kprobe():
# echo 'p cmdline_proc_show' > kprobe_events
# echo 'p cmdline_proc_show+16' >> kprobe_events
Kernel attempted to read user page (0) - exploit attempt? (uid: 0)
BUG: Kernel NULL pointer dereference on read at 0x00000000
Faulting instruction address: 0xc000000000050bfc
Oops: Kernel access of bad area, sig: 11 [#1]
LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
Modules linked in:
CPU: 0 PID: 122 Comm: sh Not tainted 6.0.0-rc3-00007-gdcf8e5633e2e #10
NIP: c000000000050bfc LR: c000000000050bec CTR: 0000000000005bdc
REGS: c0000000348475b0 TRAP: 0300 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e)
MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 88002444 XER: 20040006
CFAR: c00000000022d100 DAR: 0000000000000000 DSISR: 40000000 IRQMASK: 0
...
NIP arch_prepare_kprobe+0x10c/0x2d0
LR arch_prepare_kprobe+0xfc/0x2d0
Call Trace:
0xc0000000012f77a0 (unreliable)
register_kprobe+0x3c0/0x7a0
__register_trace_kprobe+0x140/0x1a0
__trace_kprobe_create+0x794/0x1040
trace_probe_create+0xc4/0xe0
create_or_delete_trace_kprobe+0x2c/0x80
trace_parse_run_command+0xf0/0x210
probes_write+0x20/0x40
vfs_write+0xfc/0x450
ksys_write+0x84/0x140
system_call_exception+0x17c/0x3a0
system_call_vectored_common+0xe8/0x278
--- interrupt: 3000 at 0x7fffa5682de0
NIP: 00007fffa5682de0 LR: 0000000000000000 CTR: 0000000000000000
REGS: c000000034847e80 TRAP: 3000 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e)
MSR: 900000000280f033 <SF,HV,VEC,VSX,EE,PR,FP,ME,IR,DR,RI,LE> CR: 44002408 XER: 00000000The address being probed has some special:
cmdline_proc_show: Probe based on ftrace
cmdline_proc_show+16: Probe for the next instruction at the ftrace location
The ftrace-based kprobe does not generate kprobe::ainsn::insn, it gets set to NULL. In arch_prepare_kprobe() it will check for:
...
prev = get_kprobe(p->addr - 1);
preempt_enable_no_resched();
if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
...If prev is based on ftrace, 'ppc_inst_read(prev->ainsn.insn)' will occur with a null pointer reference. At this point prev->addr will not be a prefixed instruction, so the check can be skipped.
Check if prev is ftrace-based kprobe before reading 'prev->ainsn.insn' to fix this problem.
--- arch/powerpc/kernel/kprobes.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/powerpc/kernel/kprobes.c +7 -1
@@ -161,7 +161,13 @@ int arch_prepare_kprobe(struct kprobe *p)preempt_disable (); prev =get_kprobe (p->addr -1 );preempt_enable_no_resched (); -if (prev &&ppc_inst_prefixed (ppc_inst_read (prev->ainsn.insn))) { + +/* +* When prev is a ftrace-based kprobe, we don't have an insn, and it +* doesn't probe for prefixed instruction. +*/ +if (prev && !kprobe_ftrace (prev) && +ppc_inst_prefixed (ppc_inst_read (prev->ainsn.insn))) {printk ("Cannot register a kprobe on the second word of prefixed instruction\n" ); ret = -EINVAL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 506/717 powerpc/pseries/vas: Pass hw_cpu_id to node associativity HCALL
In reply to Greg Kroah-HartmanFrom: Haren Myneni <[email protected]>
[ Upstream commit f3e5d9e53e74d77e711a2c90a91a8b0836a9e0b3 ]
Generally the hypervisor decides to allocate a window on different VAS instances. But if user space wishes to allocate on the current VAS instance where the process is executing, the kernel has to pass associativity domain IDs to allocate VAS window HCALL.
To determine the associativity domain IDs for the current CPU, smp_processor_id() is passed to node associativity HCALL which may return H_P2 (-55) error during DLPAR CPU event. This is because Linux CPU numbers (smp_processor_id()) are not the same as the hypervisor's view of CPU numbers.
Fix the issue by passing hard_smp_processor_id() with VPHN_FLAG_VCPU flag (PAPR 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY).
--- arch/powerpc/platforms/pseries/vas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/pseries/vas.c +1 -1
@@ -332,7 +332,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,* So no unpacking needs to be done. */ rc =plpar_hcall9 (H_HOME_NODE_ASSOCIATIVITY , domain, -VPHN_FLAG_VCPU ,smp_processor_id ()); +VPHN_FLAG_VCPU ,hard_smp_processor_id ());if (rc !=H_SUCCESS ) {pr_err ("H_HOME_NODE_ASSOCIATIVITY error: %d\n" , rc); goto out;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 507/717 crypto: sahara - dont sleep when in softirq
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 108586eba094b318e6a831f977f4ddcc403a15da ]
Function of sahara_aes_crypt maybe could be called by function of crypto_skcipher_encrypt during the rx softirq, so it is not allowed to use mutex lock.
--- drivers/crypto/sahara.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/crypto/sahara.c +9 -9
@@ -26,10 +26,10 @@#include <linux/kernel.h> #include <linux/kthread.h> #include <linux/module.h> -#include <linux/mutex.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/spinlock.h> #define SHA_BUFFER_LEN PAGE_SIZE#define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
@@ -196,7 +196,7 @@ struct sahara_dev {void __iomem *regs_base;struct clk *clk_ipg;struct clk *clk_ahb; -struct mutex queue_mutex; +spinlock_t queue_spinlock;struct task_struct *kthread;struct completion dma_completion;
@@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) rctx->mode = mode; -mutex_lock (&dev->queue_mutex); +spin_lock_bh (&dev->queue_spinlock); err =crypto_enqueue_request (&dev->queue, &req->base); -mutex_unlock (&dev->queue_mutex); +spin_unlock_bh (&dev->queue_spinlock);wake_up_process (dev->kthread);
@@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data) do { __set_current_state(TASK_INTERRUPTIBLE); - mutex_lock(&dev->queue_mutex); + spin_lock_bh(&dev->queue_spinlock); backlog = crypto_get_backlog(&dev->queue); async_req = crypto_dequeue_request(&dev->queue); - mutex_unlock(&dev->queue_mutex); + spin_unlock_bh(&dev->queue_spinlock); if (backlog) backlog->complete(backlog, -EINPROGRESS);
@@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) rctx->first =1 ; } -mutex_lock (&dev->queue_mutex); +spin_lock_bh (&dev->queue_spinlock); ret =crypto_enqueue_request (&dev->queue, &req->base); -mutex_unlock (&dev->queue_mutex); +spin_unlock_bh (&dev->queue_spinlock);wake_up_process (dev->kthread);
@@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev)crypto_init_queue (&dev->queue,SAHARA_QUEUE_LENGTH ); -mutex_init (&dev->queue_mutex); +spin_lock_init (&dev->queue_spinlock); dev_ptr = dev;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 508/717 crypto: hisilicon/zip - fix mismatch in get/set sgl_sge_nr
In reply to Greg Kroah-HartmanFrom: Ye Weihua <[email protected]>
[ Upstream commit d74f9340097a881869c4c22ca376654cc2516ecc ]
KASAN reported this Bug:
[17619.659757] BUG: KASAN: global-out-of-bounds in param_get_int+0x34/0x60 [17619.673193] Read of size 4 at addr fffff01332d7ed00 by task read_all/1507958 ... [17619.698934] The buggy address belongs to the variable: [17619.708371] sgl_sge_nr+0x0/0xffffffffffffa300 [hisi_zip]
There is a mismatch in hisi_zip when get/set the variable sgl_sge_nr. The type of sgl_sge_nr is u16, and get/set sgl_sge_nr by param_get/set_int.
Replacing param_get/set_int to param_get/set_ushort can fix this bug.
--- drivers/crypto/hisilicon/zip/zip_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/crypto/hisilicon/zip/zip_crypto.c +2 -2
@@ -122,12 +122,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)if (ret || n ==0 || n >HISI_ACC_SGL_SGE_NR_MAX )return -EINVAL ; -return param_set_int (val, kp); +return param_set_ushort (val, kp); }static const struct kernel_param_ops sgl_sge_nr_ops = { .set = sgl_sge_nr_set, - .get = param_get_int, + .get = param_get_ushort, };static u16 sgl_sge_nr =HZIP_SGL_SGE_NR ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 509/717 hwrng: arm-smccc-trng - fix NO_ENTROPY handling
In reply to Greg Kroah-HartmanFrom: James Cowgill <[email protected]>
[ Upstream commit 042b4b169c6fb9d4df268d66282d7302dd73d37b ]
The SMCCC_RET_TRNG_NO_ENTROPY switch arm is never used because the NO_ENTROPY return value is negative and negative values are handled above the switch by immediately returning.
Fix by handling errors using a default arm in the switch.
--- drivers/char/hw_random/arm_smccc_trng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/hw_random/arm_smccc_trng.c +2 -2
@@ -71,8 +71,6 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait) MAX_BITS_PER_CALL);arm_smccc_1_1_invoke (ARM_SMCCC_TRNG_RND , bits, &res); -if ((int )res.a0 <0 ) -return (int )res.a0;switch ((int )res.a0) {case SMCCC_RET_SUCCESS :
@@ -88,6 +86,8 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)return copied;cond_resched ();break ; +default : +return -EIO ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 510/717 crypto: ccp - Fail the PSP initialization when writing psp data file failed
In reply to Greg Kroah-HartmanFrom: Jacky Li <[email protected]>
[ Upstream commit efb4b01c1c993d245e6608076684ff2162cf9dc6 ]
Currently the OS continues the PSP initialization when there is a write failure to the init_ex_file. Therefore, the userspace would be told that SEV is properly INIT'd even though the psp data file is not updated. This is problematic because later when asked for the SEV data, the OS won't be able to provide it.
--- drivers/crypto/ccp/sev-dev.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/crypto/ccp/sev-dev.c +15 -11
@@ -231,7 +231,7 @@ static int sev_read_init_ex_file(void)return 0 ; } -static void sev_write_init_ex_file (void ) +static int sev_write_init_ex_file (void ) {struct sev_device *sev = psp_master->sev_data;struct file *fp;
@@ -241,14 +241,16 @@ static void sev_write_init_ex_file(void)lockdep_assert_held (&sev_cmd_mutex);if (!sev_init_ex_buffer) -return ; +return 0 ; fp =open_file_as_root (init_ex_path,O_CREAT |O_WRONLY ,0600 );if (IS_ERR (fp)) { +int ret =PTR_ERR (fp); +dev_err (sev->dev, -"SEV: could not open file for write, error %ld\n" , -PTR_ERR (fp)); -return ; +"SEV: could not open file for write, error %d\n" , + ret); +return ret; } nwrite =kernel_write (fp, sev_init_ex_buffer,NV_LENGTH , &offset);
@@ -259,18 +261,20 @@ static void sev_write_init_ex_file(void)dev_err (sev->dev,"SEV: failed to write %u bytes to non volatile memory area, ret %ld\n" ,NV_LENGTH , nwrite); -return ; +return -EIO ; }dev_dbg (sev->dev,"SEV: write successful to NV file\n" ); + +return 0 ; } -static void sev_write_init_ex_file_if_required (int cmd_id) +static int sev_write_init_ex_file_if_required (int cmd_id) {lockdep_assert_held (&sev_cmd_mutex);if (!sev_init_ex_buffer) -return ; +return 0 ;/* * Only a few platform commands modify the SPI/NV area, but none of the
@@ -285,10 +289,10 @@ static void sev_write_init_ex_file_if_required(int cmd_id)case SEV_CMD_PEK_GEN :break ;default : -return ; +return 0 ; } -sev_write_init_ex_file (); +return sev_write_init_ex_file (); }static int __sev_do_cmd_locked (int cmd,void *data,int *psp_ret)
@@ -361,7 +365,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) cmd, reg & PSP_CMDRESP_ERR_MASK); ret = -EIO ; }else { -sev_write_init_ex_file_if_required (cmd); + ret =sev_write_init_ex_file_if_required (cmd); } print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 511/717 cgroup: Honor callers cgroup NS when resolving path
In reply to Greg Kroah-HartmanFrom: Michal Koutný <[email protected]>
[ Upstream commit 74e4b956eb1cac0e4c10c240339b1bbfbc9a4c48 ]
cgroup_get_from_path() is not widely used function. Its callers presume the path is resolved under cgroup namespace. (There is one caller currently and resolving in init NS won't make harm (netfilter). However, future users may be subject to different effects when resolving globally.)
Since, there's currently no use for the global resolution, modify the existing function to take cgroup NS into account.
--- kernel/cgroup/cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/cgroup/cgroup.c +5 -1
@@ -6615,8 +6615,12 @@ struct cgroup *cgroup_get_from_path(const char *path) {struct kernfs_node *kn;struct cgroup *cgrp =ERR_PTR (-ENOENT ); +struct cgroup *root_cgrp; - kn =kernfs_walk_and_get (cgrp_dfl_root.cgrp.kn, path); +spin_lock_irq (&css_set_lock); + root_cgrp =current_cgns_cgroup_from_root (&cgrp_dfl_root); + kn =kernfs_walk_and_get (root_cgrp->kn, path); +spin_unlock_irq (&css_set_lock);if (!kn) goto out;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 512/717 hwrng: imx-rngc - Moving IRQ handler registering after imx_rngc_irq_mask_clear()
In reply to Greg Kroah-HartmanFrom: Kshitiz Varshney <[email protected]>
[ Upstream commit 10a2199caf437e893d9027d97700b3c6010048b7 ]
Issue:
While servicing interrupt, if the IRQ happens to be because of a SEED_DONE due to a previous boot stage, you end up completing the completion prematurely, hence causing kernel to crash while booting.
Fix:
Moving IRQ handler registering after imx_rngc_irq_mask_clear()
--- drivers/char/hw_random/imx-rngc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/char/hw_random/imx-rngc.c +7 -7
@@ -270,13 +270,6 @@ static int imx_rngc_probe(struct platfor goto err; } - ret =devm_request_irq (&pdev->dev, - irq, imx_rngc_irq,0 , pdev->name, (void *)rngc); -if (ret) { -dev_err (rngc->dev,"Can't get interrupt working.\n" ); - goto err; - } -init_completion (&rngc->rng_op_done); rngc->rng.name = pdev->name;
@@ -290,6 +283,13 @@ static int imx_rngc_probe(struct platforimx_rngc_irq_mask_clear (rngc); + ret =devm_request_irq (&pdev->dev, + irq, imx_rngc_irq,0 , pdev->name, (void *)rngc); +if (ret) { +dev_err (rngc->dev,"Can't get interrupt working.\n" ); +return ret; + } +if (self_test) { ret =imx_rngc_self_test (rngc);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 513/717 crypto: qat - fix default value of WDT timer
In reply to Greg Kroah-HartmanFrom: Lucas Segarra Fernandez <[email protected]>
[ Upstream commit cc40b04c08400d86d2d6ea0159e0617e717f729c ]
The QAT HW supports an hardware mechanism to detect an accelerator hang. The reporting of a hang occurs after a watchdog timer (WDT) expires.
The value of the WDT set previously was too small and was causing false positives.
Change the default value of the WDT to 0x7000000ULL to avoid this.
--- drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +1 -1
@@ -107,7 +107,7 @@ do { \* Timeout is in cycles. Clock speed may vary across products but this * value should be a few milli-seconds. */ -#define ADF_SSM_WDT_DEFAULT_VALUE 0x200000 +#define ADF_SSM_WDT_DEFAULT_VALUE 0x7000000ULL#define ADF_SSM_WDT_PKE_DEFAULT_VALUE 0x8000000#define ADF_SSMWDTL_OFFSET 0x54#define ADF_SSMWDTH_OFFSET 0x5C
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 514/717 crypto: hisilicon/qm - fix missing put dfx access
In reply to Greg Kroah-HartmanFrom: Weili Qian <[email protected]>
[ Upstream commit 5afc904f443de2afd31c4e0686ba178beede86fe ]
In function qm_cmd_write(), if function returns from branch 'atomic_read(&qm->status.flags) == QM_STOP', the got dfx access is forgotten to put.
--- drivers/crypto/hisilicon/qm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/hisilicon/qm.c +4 -2
@@ -2229,8 +2229,10 @@ static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer,return ret;/* Judge if the instance is being reset. */ -if (unlikely (atomic_read (&qm->status.flags) ==QM_STOP )) -return 0 ; +if (unlikely (atomic_read (&qm->status.flags) ==QM_STOP )) { + ret =0 ; + goto put_dfx_access; + }if (count >QM_DBG_WRITE_LEN ) { ret = -ENOSPC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 515/717 cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit ec5fbdfb99d18482619ac42605cb80fbb56068ee ]
Previously, update_tasks_cpumask() is not supposed to be called with top cpuset. With cpuset partition that takes CPUs away from the top cpuset, adjusting the cpus_mask of the tasks in the top cpuset is necessary. Percpu kthreads, however, are ignored.
--- kernel/cgroup/cpuset.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
kernel/cgroup/cpuset.c +11 -7
@@ -33,6 +33,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/kmod.h> +#include <linux/kthread.h> #include <linux/list.h> #include <linux/mempolicy.h> #include <linux/mm.h>
@@ -1127,10 +1128,18 @@ static void update_tasks_cpumask(struct cpuset *cs) {struct css_task_iter it;struct task_struct *task; +bool top_cs = cs == &top_cpuset;css_task_iter_start (&cs->css,0 , &it); -while ((task =css_task_iter_next (&it))) +while ((task =css_task_iter_next (&it))) { +/* +* Percpu kthreads in top_cpuset are ignored +*/ +if (top_cs && (task->flags &PF_KTHREAD ) && +kthread_is_per_cpu (task)) +continue ;set_cpus_allowed_ptr (task, cs->effective_cpus); + }css_task_iter_end (&it); }
@@ -2092,12 +2101,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)update_flag (CS_CPU_EXCLUSIVE , cs,0 ); } -/* -* Update cpumask of parent's tasks except when it is the top -* cpuset as some system daemons cannot be mapped to other CPUs. -*/ -if (parent != &top_cpuset) -update_tasks_cpumask (parent); +update_tasks_cpumask (parent);if (parent->child_ecpus_count)update_sibling_cpumasks (parent, cs, &tmpmask);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 516/717 iommu/omap: Fix buffer overflow in debugfs
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 184233a5202786b20220acd2d04ddf909ef18f29 ]
There are two issues here:
1) The "len" variable needs to be checked before the very first write. Otherwise if omap2_iommu_dump_ctx() with "bytes" less than 32 it is a buffer overflow.
2) The snprintf() function returns the number of bytes that *would* have been copied if there were enough space. But we want to know the number of bytes which were *actually* copied so use scnprintf() instead.
--- drivers/iommu/omap-iommu-debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/omap-iommu-debug.c +3 -3
@@ -32,12 +32,12 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj)ssize_t bytes; \const char *str ="%20s: %08x\n" ; \const int maxcol =32 ; \ - bytes =snprintf (p, maxcol, str,__stringify (name), \ +if (len < maxcol) \ + goto out; \ + bytes =scnprintf (p, maxcol, str,__stringify (name), \ iommu_read_reg(obj, MMU_##name)); \ p += bytes; \ len -= bytes; \ -if (len < maxcol) \ - goto out; \ }while (0 ) static ssize_t
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 517/717 crypto: akcipher - default implementation for setting a private key
In reply to Greg Kroah-HartmanFrom: Ignat Korchagin <[email protected]>
[ Upstream commit bc155c6c188c2f0c5749993b1405673d25a80389 ]
Changes from v1:
* removed the default implementation from set_pub_key: it is assumed that an implementation must always have this callback defined as there are no use case for an algorithm, which doesn't need a public key
Many akcipher implementations (like ECDSA) support only signature verifications, so they don't have all callbacks defined.
Commit 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") introduced default callbacks for sign/verify operations, which just return an error code.
However, these are not enough, because before calling sign the caller would likely call set_priv_key first on the instantiated transform (as the in-kernel testmgr does). This function does not have a default stub, so the kernel crashes, when trying to set a private key on an akcipher, which doesn't support signature generation.
I've noticed this, when trying to add a KAT vector for ECDSA signature to the testmgr.
With this patch the testmgr returns an error in dmesg (as it should) instead of crashing the kernel NULL ptr dereference.
--- crypto/akcipher.c | 8 ++++++++ 1 file changed, 8 insertions(+)
crypto/akcipher.c +8 -0
@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)return -ENOSYS ; } +static int akcipher_default_set_key (struct crypto_akcipher *tfm, +const void *key,unsigned int keylen) +{ +return -ENOSYS ; +} +int crypto_register_akcipher (struct akcipher_alg *alg) {struct crypto_alg *base = &alg->base;
@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg) alg->encrypt = akcipher_default_op;if (!alg->decrypt) alg->decrypt = akcipher_default_op; +if (!alg->set_priv_key) + alg->set_priv_key = akcipher_default_set_key;akcipher_prepare_alg (alg);return crypto_register_alg (base);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 518/717 crypto: ccp - Release dma channels before dmaengine unrgister
In reply to Greg Kroah-HartmanFrom: Koba Ko <[email protected]>
[ Upstream commit 68dbe80f5b510c66c800b9e8055235c5b07e37d1 ]
A warning is shown during shutdown,
__dma_async_device_channel_unregister called while 2 clients hold a reference
WARNING: CPU: 15 PID: 1 at drivers/dma/dmaengine.c:1110 __dma_async_device_channel_unregister+0xb7/0xc0
Call dma_release_channel for occupied channles before dma_async_device_unregister.
--- drivers/crypto/ccp/ccp-dmaengine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/crypto/ccp/ccp-dmaengine.c +5 -1
@@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp)for (i =0 ; i < ccp->cmd_q_count; i++) { chan = ccp->ccp_dma_chan + i; dma_chan = &chan->dma_chan; + +if (dma_chan->client_count) +dma_release_channel (dma_chan); +tasklet_kill (&chan->cleanup_tasklet);list_del_rcu (&dma_chan->device_node); }
@@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)if (!dmaengine)return ; -dma_async_device_unregister (dma_dev);ccp_dma_release (ccp); +dma_async_device_unregister (dma_dev);kmem_cache_destroy (ccp->dma_desc_cache);kmem_cache_destroy (ccp->dma_cmd_cache);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 519/717 crypto: inside-secure - Change swab to swab32
In reply to Greg Kroah-HartmanFrom: Peter Harliman Liem <[email protected]>
[ Upstream commit 664593407e936b6438fbfaaf98876910fd31cf9a ]
The use of swab() is causing failures in 64-bit arch, as it translates to __swab64() instead of the intended __swab32(). It eventually causes wrong results in xcbcmac & cmac algo.
--- drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/inside-secure/safexcel_hash.c +4 -4
@@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,u32 x; x = ipad[i] ^ ipad[i +4 ]; - cache[i] ^=swab (x); + cache[i] ^=swab32 (x); } } cache_len =AES_BLOCK_SIZE ;
@@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq)u32 *result = (void *)areq->result;/* K3 */ - result[i] =swab (ctx->base.ipad.word[i +4 ]); + result[i] =swab32 (ctx->base.ipad.word[i +4 ]); } areq->result[0 ] ^=0x80 ;// 10- padding crypto_cipher_encrypt_one (ctx->kaes, areq->result, areq->result);
@@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,crypto_cipher_encrypt_one (ctx->kaes, (u8 *)key_tmp +AES_BLOCK_SIZE ,"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" );for (i =0 ; i <3 *AES_BLOCK_SIZE /sizeof (u32); i++) - ctx->base.ipad.word[i] =swab (key_tmp[i]); + ctx->base.ipad.word[i] =swab32 (key_tmp[i]);crypto_cipher_clear_flags (ctx->kaes,CRYPTO_TFM_REQ_MASK ); crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
@@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,return ret;for (i =0 ; i < len /sizeof (u32); i++) - ctx->base.ipad.word[i +8 ] =swab (aes.key_enc[i]); + ctx->base.ipad.word[i +8 ] =swab32 (aes.key_enc[i]);/* precompute the CMAC key material */ crypto_cipher_clear_flags (ctx->kaes,CRYPTO_TFM_REQ_MASK );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 520/717 crypto: qat - fix DMA transfer direction
In reply to Greg Kroah-HartmanFrom: Damian Muszynski <[email protected]>
[ Upstream commit cf5bb835b7c8a5fee7f26455099cca7feb57f5e9 ]
When CONFIG_DMA_API_DEBUG is selected, while running the crypto self test on the QAT crypto algorithms, the function add_dma_entry() reports a warning similar to the one below, saying that overlapping mappings are not supported. This occurs in tests where the input and the output scatter list point to the same buffers (i.e. two different scatter lists which point to the same chunks of memory).
The logic that implements the mapping uses the flag DMA_BIDIRECTIONAL for both the input and the output scatter lists which leads to overlapped write mappings. These are not supported by the DMA layer.
Fix by specifying the correct DMA transfer directions when mapping buffers. For in-place operations where the input scatter list matches the output scatter list, buffers are mapped once with DMA_BIDIRECTIONAL, otherwise input buffers are mapped using the flag DMA_TO_DEVICE and output buffers are mapped with DMA_FROM_DEVICE. Overlapping a read mapping with a write mapping is a valid case in dma-coherent devices like QAT.
The function that frees and unmaps the buffers, qat_alg_free_bufl() has been changed accordingly to the changes to the mapping function.
DMA-API: 4xxx 0000:06:00.0: cacheline tracking EEXIST, overlapping mappings aren't supported
WARNING: CPU: 53 PID: 4362 at kernel/dma/debug.c:570 add_dma_entry+0x1e9/0x270 ... Call Trace: dma_map_page_attrs+0x82/0x2d0 ? preempt_count_add+0x6a/0xa0 qat_alg_sgl_to_bufl+0x45b/0x990 [intel_qat] qat_alg_aead_dec+0x71/0x250 [intel_qat] crypto_aead_decrypt+0x3d/0x70 test_aead_vec_cfg+0x649/0x810 ? number+0x310/0x3a0 ? vsnprintf+0x2a3/0x550 ? scnprintf+0x42/0x70 ? valid_sg_divisions.constprop.0+0x86/0xa0 ? test_aead_vec+0xdf/0x120 test_aead_vec+0xdf/0x120 alg_test_aead+0x185/0x400 alg_test+0x3d8/0x500 ? crypto_acomp_scomp_free_ctx+0x30/0x30 ? __schedule+0x32a/0x12a0 ? ttwu_queue_wakelist+0xbf/0x110 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? try_to_wake_up+0x83/0x570 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? __set_cpus_allowed_ptr_locked+0xea/0x1b0 ? crypto_acomp_scomp_free_ctx+0x30/0x30 cryptomgr_test+0x27/0x50 kthread+0xe6/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30
--- drivers/crypto/qat/qat_common/qat_algs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/crypto/qat/qat_common/qat_algs.c +12 -6
@@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,dma_addr_t blpout = qat_req->buf.bloutp;size_t sz = qat_req->buf.sz;size_t sz_out = qat_req->buf.sz_out; +int bl_dma_dir;int i; + bl_dma_dir = blp != blpout ?DMA_TO_DEVICE :DMA_BIDIRECTIONAL ; +for (i =0 ; i < bl->num_bufs; i++)dma_unmap_single (dev, bl->bufers[i].addr, - bl->bufers[i].len,DMA_BIDIRECTIONAL ); + bl->bufers[i].len, bl_dma_dir);dma_unmap_single (dev, blp, sz,DMA_TO_DEVICE );
@@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,for (i = bufless; i < blout->num_bufs; i++) {dma_unmap_single (dev, blout->bufers[i].addr, blout->bufers[i].len, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE ); }dma_unmap_single (dev, blpout, sz_out,DMA_TO_DEVICE );
@@ -716,6 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,struct scatterlist *sg;size_t sz_out, sz =struct_size (bufl, bufers, n);int node =dev_to_node (&GET_DEV (inst->accel_dev)); +int bufl_dma_dir;if (unlikely (!n))return -EINVAL ;
@@ -733,6 +737,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, qat_req->buf.sgl_src_valid = true; } + bufl_dma_dir = sgl != sglout ?DMA_TO_DEVICE :DMA_BIDIRECTIONAL ; +for_each_sg (sgl, sg, n, i) bufl->bufers[i].addr =DMA_MAPPING_ERROR ;
@@ -744,7 +750,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufl->bufers[y].addr =dma_map_single (dev,sg_virt (sg), sg->length, -DMA_BIDIRECTIONAL ); + bufl_dma_dir); bufl->bufers[y].len = sg->length;if (unlikely (dma_mapping_error (dev, bufl->bufers[y].addr))) goto err_in;
@@ -787,7 +793,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufers[y].addr =dma_map_single (dev,sg_virt (sg), sg->length, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE );if (unlikely (dma_mapping_error (dev, bufers[y].addr))) goto err_out; bufers[y].len = sg->length;
@@ -817,7 +823,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,if (!dma_mapping_error (dev, buflout->bufers[i].addr))dma_unmap_single (dev, buflout->bufers[i].addr, buflout->bufers[i].len, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE );if (!qat_req->buf.sgl_dst_valid)kfree (buflout);
@@ -831,7 +837,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,if (!dma_mapping_error (dev, bufl->bufers[i].addr))dma_unmap_single (dev, bufl->bufers[i].addr, bufl->bufers[i].len, -DMA_BIDIRECTIONAL ); + bufl_dma_dir);if (!qat_req->buf.sgl_src_valid)kfree (bufl);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 521/717 clocksource/drivers/arm_arch_timer: Fix handling of ARM erratum 858921
In reply to Greg Kroah-HartmanFrom: Kunkun Jiang <[email protected]>
[ Upstream commit 6c3b62d93e195f78c1437c8fa7581e9b2f00886e ]
The commit a38b71b0833e ("clocksource/drivers/arm_arch_timer:
Move system register timer programming over to CVAL") moves the programming of the timers from the countdown timer (TVAL) over to the comparator (CVAL). This makes it necessary to read the counter when programming next event. However, the workaround of Cortex-A73 erratum 858921 does not set the corresponding set_next_event_phys and set_next_event_virt.
Add the appropriate hooks to apply the erratum mitigation when programming the next timer event.
--- drivers/clocksource/arm_arch_timer.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clocksource/arm_arch_timer.c +2 -0
@@ -473,6 +473,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .desc = "ARM erratum 858921", .read_cntpct_el0 = arm64_858921_read_cntpct_el0, .read_cntvct_el0 = arm64_858921_read_cntvct_el0, + .set_next_event_phys = erratum_set_next_event_phys, + .set_next_event_virt = erratum_set_next_event_virt, },#endif #ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 522/717 clocksource/drivers/timer-gxp: Add missing error handling in gxp_timer_probe
In reply to Greg Kroah-HartmanFrom: Lin Yujun <[email protected]>
[ Upstream commit 0e2c8e6d769bcdc4f6634a02c545356282275e68 ]
Add platform_device_put() to make sure to free the platform device in the event platform_device_add() fails.
--- drivers/clocksource/timer-gxp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/clocksource/timer-gxp.c +6 -1
@@ -171,6 +171,7 @@ static int gxp_timer_probe(struct platform_device *pdev) {struct platform_device *gxp_watchdog_device;struct device *dev = &pdev->dev; +int ret;if (!gxp_timer) {pr_err ("Gxp Timer not initialized, cannot create watchdog" );
@@ -187,7 +188,11 @@ static int gxp_timer_probe(struct platform_device *pdev) gxp_watchdog_device->dev.platform_data = gxp_timer->counter; gxp_watchdog_device->dev.parent = dev; -return platform_device_add (gxp_watchdog_device); + ret =platform_device_add (gxp_watchdog_device); +if (ret) +platform_device_put (gxp_watchdog_device); + +return ret; }static const struct of_device_id gxp_timer_of_match[] = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 523/717 cifs: return correct error in ->calc_signature()
In reply to Greg Kroah-HartmanFrom: Enzo Matsumiya <[email protected]>
[ Upstream commit 09a1f9a168ae1f69f701689429871793174417d2 ]
If an error happens while getting the key or session in the ->calc_signature implementations, 0 (success) is returned. Fix it by returning a proper error code.
Since it seems to be highly unlikely to happen wrap the rc check in unlikely() too.
--- fs/cifs/smb2transport.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/cifs/smb2transport.c +6 -4
@@ -225,9 +225,9 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,struct smb_rqst drqst; ses =smb2_find_smb_ses (server,le64_to_cpu (shdr->SessionId)); -if (!ses) { +if (unlikely (!ses)) {cifs_server_dbg (VFS ,"%s: Could not find session\n" , __func__); -return 0 ; +return -ENOENT ; }memset (smb2_signature,0x0 ,SMB2_HMACSHA256_SIZE );
@@ -557,8 +557,10 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,u8 key[SMB3_SIGN_KEY_SIZE ]; rc =smb2_get_sign_key (le64_to_cpu (shdr->SessionId), server, key); -if (rc) -return 0 ; +if (unlikely (rc)) { +cifs_server_dbg (VFS ,"%s: Could not get signing key\n" , __func__); +return rc; + }if (allocate_crypto) { rc =cifs_alloc_hash ("cmac(aes)" , &hash, &sdesc);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 524/717 iommu/iova: Fix module config properly
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 4f58330fcc8482aa90674e1f40f601e82f18ed4a ]
IOMMU_IOVA is intended to be an optional library for users to select as and when they desire. Since it can be a module now, this means that built-in code which has chosen not to select it should not fail to link if it happens to have selected as a module by someone else. Replace IS_ENABLED() with IS_REACHABLE() to do the right thing.
--- include/linux/iova.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/iova.h +1 -1
@@ -75,7 +75,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)return iova >>iova_shift (iovad); } -#if IS_ENABLED (CONFIG_IOMMU_IOVA ) +#if IS_REACHABLE (CONFIG_IOMMU_IOVA )int iova_cache_get (void );void iova_cache_put (void );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 525/717 tracing: kprobe: Fix kprobe event gen test module on exit
In reply to Greg Kroah-HartmanFrom: Yipeng Zou <[email protected]>
[ Upstream commit ac48e189527fae87253ef2bf58892e782fb36874 ]
Correct gen_kretprobe_test clr event para on module exit. This will make it can't to delete.
--- kernel/trace/kprobe_event_gen_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/kprobe_event_gen_test.c +1 -1
@@ -206,7 +206,7 @@ static void __exit kprobe_event_gen_test_exit(void)WARN_ON (kprobe_event_delete ("gen_kprobe_test" ));/* Disable the event or you can't remove it */ -WARN_ON (trace_array_set_clr_event (gen_kprobe_test->tr, +WARN_ON (trace_array_set_clr_event (gen_kretprobe_test->tr,"kprobes" ,"gen_kretprobe_test" , false));
Signature · 9 lines
2.35.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Greg Kroah-Hartman
maintainerPATCH 526/717 tracing: kprobe: Make gen test module work in arm and riscv
In reply to Greg Kroah-HartmanFrom: Yipeng Zou <[email protected]>
[ Upstream commit d8ef45d66c01425ff748e13ef7dd1da7a91cc93c ]
For now, this selftest module can only work in x86 because of the kprobe cmd was fixed use of x86 registers.
This patch adapted to register names under arm and riscv, So that this module can be worked on those platform.
--- kernel/trace/kprobe_event_gen_test.c | 47 +++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-)
kernel/trace/kprobe_event_gen_test.c +43 -4
@@ -35,6 +35,45 @@static struct trace_event_file *gen_kprobe_test;static struct trace_event_file *gen_kretprobe_test; +#define KPROBE_GEN_TEST_FUNC "do_sys_open" + +/* X86 */ +#if defined(CONFIG_X86_64 ) || defined(CONFIG_X86_32 ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%ax" +#define KPROBE_GEN_TEST_ARG1 "filename=%dx" +#define KPROBE_GEN_TEST_ARG2 "flags=%cx" +#define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)" + +/* ARM64 */ +#elif defined(CONFIG_ARM64 ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%x0" +#define KPROBE_GEN_TEST_ARG1 "filename=%x1" +#define KPROBE_GEN_TEST_ARG2 "flags=%x2" +#define KPROBE_GEN_TEST_ARG3 "mode=%x3" + +/* ARM */ +#elif defined(CONFIG_ARM ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%r0" +#define KPROBE_GEN_TEST_ARG1 "filename=%r1" +#define KPROBE_GEN_TEST_ARG2 "flags=%r2" +#define KPROBE_GEN_TEST_ARG3 "mode=%r3" + +/* RISCV */ +#elif defined(CONFIG_RISCV ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%a0" +#define KPROBE_GEN_TEST_ARG1 "filename=%a1" +#define KPROBE_GEN_TEST_ARG2 "flags=%a2" +#define KPROBE_GEN_TEST_ARG3 "mode=%a3" + +/* others */ +#else +#define KPROBE_GEN_TEST_ARG0 NULL +#define KPROBE_GEN_TEST_ARG1 NULL +#define KPROBE_GEN_TEST_ARG2 NULL +#define KPROBE_GEN_TEST_ARG3 NULL +#endif + +/* * Test to make sure we can create a kprobe event, then add more * fields.
@@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void)* fields. */ ret =kprobe_event_gen_cmd_start (&cmd,"gen_kprobe_test" , -"do_sys_open" , -"dfd=%ax" ,"filename=%dx" ); +KPROBE_GEN_TEST_FUNC , +KPROBE_GEN_TEST_ARG0 ,KPROBE_GEN_TEST_ARG1 );if (ret) goto free;/* Use kprobe_event_add_fields to add the rest of the fields */ - ret =kprobe_event_add_fields (&cmd,"flags=%cx" ,"mode=+4($stack)" ); + ret =kprobe_event_add_fields (&cmd,KPROBE_GEN_TEST_ARG2 ,KPROBE_GEN_TEST_ARG3 );if (ret) goto free;
@@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void)* Define the kretprobe event. */ ret =kretprobe_event_gen_cmd_start (&cmd,"gen_kretprobe_test" , -"do_sys_open" , +KPROBE_GEN_TEST_FUNC ,"$retval" );if (ret) goto free;
Signature · 9 lines
2.35.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Greg Kroah-Hartman
maintainerPATCH 527/717 tracing/osnoise: Fix possible recursive locking in stop_per_cpu_kthreads
In reply to Greg Kroah-HartmanFrom: Nico Pache <[email protected]>
[ Upstream commit 99ee9317a1305cd5626736785c8cb38b0e47686c ]
There is a recursive lock on the cpu_hotplug_lock.
In kernel/trace/trace_osnoise.c:<start/stop>_per_cpu_kthreads:
- start_per_cpu_kthreads calls cpus_read_lock() and if start_kthreads returns a error it will call stop_per_cpu_kthreads.
- stop_per_cpu_kthreads then calls cpus_read_lock() again causing deadlock.
Fix this by calling cpus_read_unlock() before calling stop_per_cpu_kthreads. This behavior can also be seen in commit f46b16520a08 ("trace/hwlat: Implement the per-cpu mode").
This error was noticed during the LTP ftrace-stress-test:
WARNING: possible recursive locking detected
--------------------------------------------
sh/275006 is trying to acquire lock:ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: stop_per_cpu_kthreads
but task is already holding lock:ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(cpu_hotplug_lock);
lock(cpu_hotplug_lock);
*** DEADLOCK ***
May be due to missing lock nesting notation
3 locks held by sh/275006:
#0: ffff8881023f0470 (sb_writers#24){.+.+}-{0:0}, at: ksys_write #1: ffffffffb084f430 (trace_types_lock){+.+.}-{3:3}, at: rb_simple_write #2: ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads
--- kernel/trace/trace_osnoise.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace_osnoise.c +2 -1
@@ -1786,8 +1786,9 @@ static int start_per_cpu_kthreads(void)for_each_cpu (cpu, current_mask) { retval =start_kthread (cpu);if (retval) { +cpus_read_unlock ();stop_per_cpu_kthreads (); -break ; +return retval; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 528/717 kbuild: remove the target in signal traps when interrupted
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit a7f3257da8a86b96fb9bf1bba40ae0bbd7f1885a ]
When receiving some signal, GNU Make automatically deletes the target if it has already been changed by the interrupted recipe.
If the target is possibly incomplete due to interruption, it must be deleted so that it will be remade from scratch on the next run of make. Otherwise, the target would remain corrupted permanently because its timestamp had already been updated.
Thanks to this behavior of Make, you can stop the build any time by pressing Ctrl-C, and just run 'make' to resume it.
Kbuild also relies on this feature, but it is equivalently important for any build systems that make decisions based on timestamps (if you want to support Ctrl-C reliably).
However, this does not always work as claimed; Make immediately dies with Ctrl-C if its stderr goes into a pipe.
[Test Makefile]
foo:
echo hello > $@
sleep 3
echo world >> $@
[Test Result]
$ make # hit Ctrl-C
echo hello > foo
sleep 3
^Cmake: *** Deleting file 'foo'
make: *** [Makefile:3: foo] Interrupt $ make 2>&1 | cat # hit Ctrl-C
echo hello > foo
sleep 3
^C$ # 'foo' is often left-overThe reason is because SIGINT is sent to the entire process group. In this example, SIGINT kills 'cat', and 'make' writes the message to the closed pipe, then dies with SIGPIPE before cleaning the target.
A typical bad scenario (as reported by [1], [2]) is to save build log by using the 'tee' command:
$ make 2>&1 | tee log
This can be problematic for any build systems based on Make, so I hope it will be fixed in GNU Make. The maintainer of GNU Make stated this is a long-standing issue and difficult to fix [3]. It has not been fixed yet as of writing.
So, we cannot rely on Make cleaning the target. We can do it by ourselves, in signal traps.
As far as I understand, Make takes care of SIGHUP, SIGINT, SIGQUIT, and SITERM for the target removal. I added the traps for them, and also for SIGPIPE just in case cmd_* rule prints something to stdout or stderr (but I did not observe an actual case where SIGPIPE was triggered).
[Note 1]
The trap handler might be worth explaining.
rm -f $@; trap - $(sig); kill -s $(sig) $$
This lets the shell kill itself by the signal it caught, so the parent process can tell the child has exited on the signal. Generally, this is a proper manner for handling signals, in case the calling program (like Bash) may monitor WIFSIGNALED() and WTERMSIG() for WCE although this may not be a big deal here because GNU Make handles SIGHUP, SIGINT, SIGQUIT in WUE and SIGTERM in IUE.
IUE - Immediate Unconditional Exit
WUE - Wait and Unconditional Exit
WCE - Wait and Cooperative Exit
For details, see "Proper handling of SIGINT/SIGQUIT" [4].
[Note 2]
Reverting 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") would directly address [1], but it only saves if_changed_dep. As reported in [2], all commands that use redirection can potentially leave an empty (i.e. broken) target.
[Note 3]
Another (even safer) approach might be to always write to a temporary file, and rename it to $@ at the end of the recipe.
<command> > $(tmp-target) mv $(tmp-target) $@
It would require a lot of Makefile changes, and result in ugly code, so I did not take it.
[Note 4]
A little more thoughts about a pattern rule with multiple targets (or a grouped target).
%.x %.y: %.z
<recipe>When interrupted, GNU Make deletes both %.x and %.y, while this solution only deletes $@. Probably, this is not a big deal. The next run of make will execute the rule again to create $@ along with the other files.
[1]: https://lore.kernel.org/all/[email protected]/
[2]: https://lore.kernel.org/all/[email protected]/
[3]: https://lists.gnu.org/archive/html/help-make/2021-06/msg00001.html
[4]: https://www.cons.org/cracauer/sigint.html
--- scripts/Kbuild.include | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
scripts/Kbuild.include +22 -1
@@ -100,8 +100,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\ quiet_redirect := silent_redirect := exec >/dev/null; +# Delete the target on interruption +# +# GNU Make automatically deletes the target if it has already been changed by +# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make +# will delete incomplete targets), and resume it later. +# +# However, this does not work when the stderr is piped to another program, like +# $ make >&2 | tee log +# Make dies with SIGPIPE before cleaning the targets. +# +# To address it, we clean the target in signal traps. +# +# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. +# So, we cover them, and also SIGPIPE just in case. +# +# Of course, this is unneeded for phony targets. +delete-on-interrupt = \ + $(if $(filter-out $(PHONY), $@), \ + $(foreach sig, HUP INT QUIT TERM PIPE, \ + trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) + # printing commands -cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1)) +cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1)) ### # if_changed - execute command if any prerequisite is newer than
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 529/717 linux/export: use inline assembler to populate symbol CRCs
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit f3304ecd7f060db1d4197fbdce5a503259f770d3 ]
Since commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS"), the module versioning on the (non-upstreamed-yet) kvx Linux port is broken due to unexpected padding for __crc_* symbols. The kvx GCC adds padding so u32 gets 8-byte alignment instead of 4.
I do not know if this happens for upstream architectures in general, but any compiler has the freedom to insert padding for faster access.
Use the inline assembler to directly specify the wanted data layout. This is how we previously did before the breakage.
--- include/linux/export-internal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/export-internal.h +4 -2
@@ -10,8 +10,10 @@#include <linux/compiler.h> #include <linux/types.h> -/* __used is needed to keep __crc_* for LTO */ #define SYMBOL_CRC (sym, crc, sec) \ - u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc + asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ + "__crc_" #sym ":" "\n" \ + ".long " #crc "\n" \ + ".previous" "\n")#endif /* __LINUX_EXPORT_INTERNAL_H__ */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 530/717 kbuild: rpm-pkg: fix breakage when V=1 is used
In reply to Greg Kroah-HartmanFrom: Janis Schoetterl-Glausch <[email protected]>
[ Upstream commit 2e07005f4813a9ff6e895787e0c2d1fea859b033 ]
Doing make V=1 binrpm-pkg results in:
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.EgV6qJ
+ umask 022
+ cd .
+ /bin/rm -rf /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x
+ /bin/mkdir -p /home/scgl/rpmbuild/BUILDROOT
+ /bin/mkdir /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x
+ mkdir -p /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot
+ make -f ./Makefile image_name
+ cp test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \ echo >&2; \ echo >&2 " ERROR: Kernel configuration is invalid."; \ echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\ echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo >&2 ; \ /bin/false) arch/s390/boot/bzImage /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot/vmlinuz-6.0.0-rc5+
cp: invalid option -- 'e'
Try 'cp --help' for more information.
error: Bad exit status from /var/tmp/rpm-tmp.EgV6qJ (%install)
Because the make call to get the image name is verbose and prints additional information.
--- scripts/package/mkspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/package/mkspec +2 -2
@@ -85,10 +85,10 @@ $S mkdir -p %{buildroot}/boot %ifarch ia64 mkdir -p %{buildroot}/boot/efi - cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ %else - cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE %endif $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 531/717 crypto: marvell/octeontx - prevent integer overflows
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit caca37cf6c749ff0303f68418cfe7b757a4e0697 ]
The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly.
The "code_length * 2" can overflow. The round_up(ucode_size, 16) + sizeof() expression can overflow too. Prevent these overflows.
--- .../crypto/marvell/octeontx/otx_cptpf_ucode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +16 -2
@@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev,struct tar_ucode_info_t *tar_info;struct otx_cpt_ucode_hdr *ucode_hdr;int ucode_type, ucode_size; +unsigned int code_length;/* * If size is less than microcode header size then don't report
@@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev,if (get_ucode_type (ucode_hdr, &ucode_type))return 0 ; - ucode_size =ntohl (ucode_hdr->code_length) *2 ; + code_length =ntohl (ucode_hdr->code_length); +if (code_length >=INT_MAX /2 ) { +dev_err (dev,"Invalid code_length %u\n" , code_length); +return -EINVAL ; + } + + ucode_size = code_length *2 ;if (!ucode_size || (size <round_up (ucode_size,16 ) +sizeof (struct otx_cpt_ucode_hdr ) +OTX_CPT_UCODE_SIGN_LEN )) {dev_err (dev,"Ucode %s invalid size\n" , filename);
@@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, {struct otx_cpt_ucode_hdr *ucode_hdr;const struct firmware *fw; +unsigned int code_length;int ret;set_ucode_filename (ucode, ucode_filename);
@@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;memcpy (ucode->ver_str, ucode_hdr->ver_str,OTX_CPT_UCODE_VER_STR_SZ ); ucode->ver_num = ucode_hdr->ver_num; - ucode->size =ntohl (ucode_hdr->code_length) *2 ; + code_length =ntohl (ucode_hdr->code_length); +if (code_length >=INT_MAX /2 ) { +dev_err (dev,"Ucode invalid code_length %u\n" , code_length); + ret = -EINVAL ; + goto release_fw; + } + ucode->size = code_length *2 ;if (!ucode->size || (fw->size <round_up (ucode->size,16 ) +sizeof (struct otx_cpt_ucode_hdr ) +OTX_CPT_UCODE_SIGN_LEN )) {dev_err (dev,"Ucode %s invalid size\n" , ucode_filename);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 532/717 crypto: cavium - prevent integer overflow loading firmware
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 2526d6bf27d15054bb0778b2f7bc6625fd934905 ]
The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly.
The "ntohl(ucode->code_length) * 2" multiplication can have an integer overflow.
--- drivers/crypto/cavium/cpt/cptpf_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/cavium/cpt/cptpf_main.c +4 -2
@@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)const struct firmware *fw_entry;struct device *dev = &cpt->pdev->dev;struct ucode_header *ucode; +unsigned int code_length;struct microcode *mcode;int j, ret =0 ;
@@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) ucode = (struct ucode_header *)fw_entry->data; mcode = &cpt->mcode[cpt->next_mc_idx];memcpy (mcode->version, (u8 *)fw_entry->data,CPT_UCODE_VERSION_SZ ); - mcode->code_size =ntohl (ucode->code_length) *2 ; -if (!mcode->code_size) { + code_length =ntohl (ucode->code_length); +if (code_length ==0 || code_length >=INT_MAX /2 ) { ret = -EINVAL ; goto fw_release; } + mcode->code_size = code_length *2 ; mcode->is_ae = is_ae; mcode->core_mask =0ULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 533/717 random: schedule jitter credit for next jiffy, not in two jiffies
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit 122733471384be8c23f019fbbd46bdf7be561dcd ]
Counterintuitively, mod_timer(..., jiffies + 1) will cause the timer to fire not in the next jiffy, but in two jiffies. The way to cause the timer to fire in the next jiffy is with mod_timer(..., jiffies). Doing so then lets us bump the upper bound back up again.
--- drivers/char/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/random.c +2 -2
@@ -1178,7 +1178,7 @@ static void __cold entropy_timer(struct timer_list *timer)*/ static void __cold try_to_generate_entropy (void ) { -enum {NUM_TRIAL_SAMPLES =8192 ,MAX_SAMPLES_PER_BIT =HZ /30 }; +enum {NUM_TRIAL_SAMPLES =8192 ,MAX_SAMPLES_PER_BIT =HZ /15 };struct entropy_timer_state stack;unsigned int i, num_different =0 ;unsigned long last =random_get_entropy ();
@@ -1197,7 +1197,7 @@ static void __cold try_to_generate_entropy(void)timer_setup_on_stack (&stack.timer, entropy_timer,0 );while (!crng_ready () && !signal_pending (current)) {if (!timer_pending (&stack.timer)) -mod_timer (&stack.timer, jiffies +1 ); +mod_timer (&stack.timer, jiffies);mix_pool_bytes (&stack.entropy,sizeof (stack.entropy));schedule (); stack.entropy =random_get_entropy ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 534/717 thermal/drivers/qcom/tsens-v0_1: Fix MSM8939 fourth sensor hw_id
In reply to Greg Kroah-HartmanFrom: Vincent Knecht <[email protected]>
[ Upstream commit b0c883e900702f408d62cf92b0ef01303ed69be9 ]
Reading temperature from this sensor fails with 'Invalid argument'.
Looking at old vendor dts [1], its hw_id should be 3 instead of 4. Change this hw_id accordingly.
--- drivers/thermal/qcom/tsens-v0_1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/qcom/tsens-v0_1.c +1 -1
@@ -604,7 +604,7 @@ static const struct tsens_ops ops_8939 = {struct tsens_plat_data data_8939 = { .num_sensors =10 , .ops = &ops_8939, - .hw_ids = (unsigned int []){0 ,1 ,2 ,4 ,5 ,6 ,7 ,8 ,9 ,10 }, + .hw_ids = (unsigned int []){0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9 ,10 }, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 535/717 ACPI: APEI: do not add task_work to kernel thread to avoid memory leak
In reply to Greg Kroah-HartmanFrom: Shuai Xue <[email protected]>
[ Upstream commit 415fed694fe11395df56e05022d6e7cee1d39dd3 ]
If an error is detected as a result of user-space process accessing a corrupt memory location, the CPU may take an abort. Then the platform firmware reports kernel via NMI like notifications, e.g. NOTIFY_SEA, NOTIFY_SOFTWARE_DELEGATED, etc.
For NMI like notifications, commit 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors") keep track of whether memory_failure() work was queued, and make task_work pending to flush out the queue so that the work is processed before return to user-space.
The code use init_mm to check whether the error occurs in user space:
if (current->mm != &init_mm)
The condition is always true, becase _nobody_ ever has "init_mm" as a real VM any more.
In addition to abort, errors can also be signaled as asynchronous exceptions, such as interrupt and SError. In such case, the interrupted current process could be any kind of thread. When a kernel thread is interrupted, the work ghes_kick_task_work deferred to task_work will never be processed because entry_handler returns to call ret_to_kernel() instead of ret_to_user(). Consequently, the estatus_node alloced from ghes_estatus_pool in ghes_in_nmi_queue_one_entry() will not be freed. After around 200 allocations in our platform, the ghes_estatus_pool will run of memory and ghes_in_nmi_queue_one_entry() returns ENOMEM. As a result, the event failed to be processed.
sdei: event 805 on CPU 113 failed with error: -2
Finally, a lot of unhandled events may cause platform firmware to exceed some threshold and reboot.
The condition should generally just do
if (current->mm)
as described in active_mm.rst documentation.
Then if an asynchronous error is detected when a kernel thread is running, (e.g. when detected by a background scrubber), do not add task_work to it as the original patch intends to do.
--- drivers/acpi/apei/ghes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/apei/ghes.c +1 -1
@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)ghes_estatus_cache_add (generic, estatus); } -if (task_work_pending && current->mm != &init_mm) { +if (task_work_pending && current->mm) { estatus_node->task_work.func = ghes_kick_task_work; estatus_node->task_work_cpu =smp_processor_id (); ret = task_work_add(current, &estatus_node->task_work,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 536/717 f2fs: fix race condition on setting FI_NO_EXTENT flag
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 07725adc55c0a414c10acb5c8c86cea34b95ddef ]
The following scenarios exist.
process A: process B:
->f2fs_drop_extent_tree ->f2fs_update_extent_cache_range
->f2fs_update_extent_tree_range
->write_lock
->set_inode_flag
->is_inode_flag_set
->__free_extent_tree // Shouldn't
// have been
// cleaned up
// here->write_lock
In this case, the "FI_NO_EXTENT" flag is set between f2fs_update_extent_tree_range and is_inode_flag_set by other process. it leads to clearing the whole exten tree which should not have happened. And we fix it by move the setting it to the range of write_lock.
--- fs/f2fs/extent_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/f2fs/extent_cache.c +1 -2
@@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode)if (!f2fs_may_extent_tree (inode))return ; -set_inode_flag (inode,FI_NO_EXTENT ); -write_lock (&et->lock); +set_inode_flag (inode,FI_NO_EXTENT );__free_extent_tree (sbi, et);if (et->largest.len) { et->largest.len =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 537/717 f2fs: fix to account FS_CP_DATA_IO correctly
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit d80afefb17e01aa0c46a8eebc01882e0ebd8b0f6 ]
f2fs_inode_info.cp_task was introduced for FS_CP_DATA_IO accounting since commit b0af6d491a6b ("f2fs: add app/fs io stat").
However, cp_task usage coverage has been increased due to below commits:
commit 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") commit 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush")
So that, if data_flush mountoption is on, when data flush was triggered from background, the IO from data flush will be accounted as checkpoint IO type incorrectly.
In order to fix this issue, this patch splits cp_task into two:
a) cp_task: used for IO accounting
b) wb_task: used to avoid deadlock
--- fs/f2fs/checkpoint.c | 13 +++++++++---- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/segment.c | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-)
fs/f2fs/checkpoint.c +9 -4
@@ -1063,7 +1063,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)spin_unlock (&sbi->inode_lock[type]); } -int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type) +int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type, +bool from_cp) {struct list_head *head;struct inode *inode;
@@ -1098,11 +1099,15 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)if (inode) {unsigned long cur_ino = inode->i_ino; -F2FS_I (inode)->cp_task = current; +if (from_cp) +F2FS_I (inode)->cp_task = current; +F2FS_I (inode)->wb_task = current;filemap_fdatawrite (inode->i_mapping); -F2FS_I (inode)->cp_task =NULL ; +F2FS_I (inode)->wb_task =NULL ; +if (from_cp) +F2FS_I (inode)->cp_task =NULL ;iput (inode);/* We need to give cpu to another writers. */
@@ -1231,7 +1236,7 @@ static int block_operations(struct f2fs_sb_info *sbi)/* write all the dirty dentry pages */ if (get_pages (sbi,F2FS_DIRTY_DENTS )) {f2fs_unlock_all (sbi); - err =f2fs_sync_dirty_inodes (sbi,DIR_INODE ); + err =f2fs_sync_dirty_inodes (sbi,DIR_INODE , true);if (err)return err;cond_resched ();
fs/f2fs/data.c +2 -2
@@ -2843,7 +2843,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, }unlock_page (page);if (!S_ISDIR (inode->i_mode) && !IS_NOQUOTA (inode) && - !F2FS_I (inode)->cp_task && allow_balance) + !F2FS_I (inode)->wb_task && allow_balance)f2fs_balance_fs (sbi, need_balance_fs);if (unlikely (f2fs_cp_error (sbi))) {
@@ -3141,7 +3141,7 @@ static inline bool __should_serialize_io(struct inode *inode, struct writeback_control *wbc) {/* to avoid deadlock in path of data flush */ -if (F2FS_I (inode)->cp_task) +if (F2FS_I (inode)->wb_task)return false;if (!S_ISREG (inode->i_mode))
fs/f2fs/f2fs.h +3 -1
@@ -784,6 +784,7 @@ struct f2fs_inode_info {unsigned int clevel;/* maximum level of given file name */ struct task_struct *task;/* lookup and create consistency */ struct task_struct *cp_task;/* separate cp/wb IO stats*/ +struct task_struct *wb_task;/* indicate inode is in context of writeback */ nid_t i_xattr_nid;/* node id that contains xattrs */ loff_t last_disk_size;/* lastly written file size */ spinlock_t i_size_lock;/* protect last_disk_size */
@@ -3710,7 +3711,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);int f2fs_get_valid_checkpoint (struct f2fs_sb_info *sbi);void f2fs_update_dirty_folio (struct inode *inode,struct folio *folio);void f2fs_remove_dirty_inode (struct inode *inode); -int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type); +int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type, +bool from_cp);void f2fs_wait_on_all_pages (struct f2fs_sb_info *sbi,int type);u64 f2fs_get_sectors_written (struct f2fs_sb_info *sbi);int f2fs_write_checkpoint (struct f2fs_sb_info *sbi,struct cp_control *cpc);
fs/f2fs/segment.c +1 -1
@@ -469,7 +469,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg)mutex_lock (&sbi->flush_lock);blk_start_plug (&plug); -f2fs_sync_dirty_inodes (sbi,FILE_INODE ); +f2fs_sync_dirty_inodes (sbi,FILE_INODE , false);blk_finish_plug (&plug);mutex_unlock (&sbi->flush_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 538/717 selftest: tpm2: Add Client.__del__() to close /dev/tpm* handle
In reply to Greg Kroah-HartmanFrom: Stefan Berger <[email protected]>
[ Upstream commit 2d869f0b458547386fbcd8cf3004b271b7347b7f ]
The following output can bee seen when the test is executed:
test_flush_context (tpm2_tests.SpaceTest) ... \
/usr/lib64/python3.6/unittest/case.py:605: ResourceWarning: \
unclosed file <_io.FileIO name='/dev/tpmrm0' mode='rb+' closefd=True>An instance of Client does not implicitly close /dev/tpm* handle, once it gets destroyed. Close the file handle in the class destructor Client.__del__().
--- tools/testing/selftests/tpm2/tpm2.py | 4 ++++ 1 file changed, 4 insertions(+)
tools/testing/selftests/tpm2/tpm2.py +4 -0
@@ -371,6 +371,10 @@ class Client: fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags) self.tpm_poll = select.poll() + def __del__(self): + if self.tpm: + self.tpm.close() + def close(self): self.tpm.close()
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 539/717 module: tracking: Keep a record of tainted unloaded modules only
In reply to Greg Kroah-HartmanFrom: Aaron Tomlin <[email protected]>
[ Upstream commit 47cc75aa92837a9d3f15157d6272ff285585d75d ]
This ensures that no module record/or entry is added to the unloaded_tainted_modules list if it does not carry a taint.
--- kernel/module/tracking.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/module/tracking.c +3 -0
@@ -21,6 +21,9 @@ int try_add_tainted_module(struct module *mod)module_assert_mutex_or_preempt (); +if (!mod->taints) + goto out; +list_for_each_entry_rcu (mod_taint, &unloaded_tainted_modules, list,lockdep_is_held (&module_mutex)) { if (!strcmp(mod_taint->name, mod->name) &&
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 540/717 fs: dlm: fix race in lowcomms
In reply to Greg Kroah-HartmanFrom: Alexander Aring <[email protected]>
[ Upstream commit 30ea3257e8766027c4d8d609dcbd256ff9a76073 ]
This patch fixes a race between queue_work() in _dlm_lowcomms_commit_msg() and srcu_read_unlock(). The queue_work() can take the final reference of a dlm_msg and so msg->idx can contain garbage which is signaled by the following warning:
[ 676.237050] ------------[ cut here ]------------ [ 676.237052] WARNING: CPU: 0 PID: 1060 at include/linux/srcu.h:189 dlm_lowcomms_commit_msg+0x41/0x50 [ 676.238945] Modules linked in: dlm_locktorture torture rpcsec_gss_krb5 intel_rapl_msr intel_rapl_common iTCO_wdt iTCO_vendor_support qxl kvm_intel drm_ttm_helper vmw_vsock_virtio_transport kvm vmw_vsock_virtio_transport_common ttm irqbypass crc32_pclmul joydev crc32c_intel serio_raw drm_kms_helper vsock virtio_scsi virtio_console virtio_balloon snd_pcm drm syscopyarea sysfillrect sysimgblt snd_timer fb_sys_fops i2c_i801 lpc_ich snd i2c_smbus soundcore pcspkr [ 676.244227] CPU: 0 PID: 1060 Comm: lock_torture_wr Not tainted 5.19.0-rc3+ #1546 [ 676.245216] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-2.module+el8.7.0+15506+033991b0 04/01/2014 [ 676.246460] RIP: 0010:dlm_lowcomms_commit_msg+0x41/0x50 [ 676.247132] Code: fe ff ff ff 75 24 48 c7 c6 bd 0f 49 bb 48 c7 c7 38 7c 01 bd e8 00 e7 ca ff 89 de 48 c7 c7 60 78 01 bd e8 42 3d cd ff 5b 5d c3 <0f> 0b eb d8 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 [ 676.249253] RSP: 0018:ffffa401c18ffc68 EFLAGS: 00010282 [ 676.249855] RAX: 0000000000000001 RBX: 00000000ffff8b76 RCX: 0000000000000006 [ 676.250713] RDX: 0000000000000000 RSI: ffffffffbccf3a10 RDI: ffffffffbcc7b62e [ 676.251610] RBP: ffffa401c18ffc70 R08: 0000000000000001 R09: 0000000000000001 [ 676.252481] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000005 [ 676.253421] R13: ffff8b76786ec370 R14: ffff8b76786ec370 R15: ffff8b76786ec480 [ 676.254257] FS: 0000000000000000(0000) GS:ffff8b7777800000(0000) knlGS:0000000000000000 [ 676.255239] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 676.255897] CR2: 00005590205d88b8 CR3: 000000017656c003 CR4: 0000000000770ee0 [ 676.256734] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 676.257567] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 676.258397] PKRU: 55555554 [ 676.258729] Call Trace: [ 676.259063] <TASK> [ 676.259354] dlm_midcomms_commit_mhandle+0xcc/0x110 [ 676.259964] queue_bast+0x8b/0xb0 [ 676.260423] grant_pending_locks+0x166/0x1b0 [ 676.261007] _unlock_lock+0x75/0x90 [ 676.261469] unlock_lock.isra.57+0x62/0xa0 [ 676.262009] dlm_unlock+0x21e/0x330 [ 676.262457] ? lock_torture_stats+0x80/0x80 [dlm_locktorture] [ 676.263183] torture_unlock+0x5a/0x90 [dlm_locktorture] [ 676.263815] ? preempt_count_sub+0xba/0x100 [ 676.264361] ? complete+0x1d/0x60 [ 676.264777] lock_torture_writer+0xb8/0x150 [dlm_locktorture] [ 676.265555] kthread+0x10a/0x130 [ 676.266007] ? kthread_complete_and_exit+0x20/0x20 [ 676.266616] ret_from_fork+0x22/0x30 [ 676.267097] </TASK> [ 676.267381] irq event stamp: 9579855 [ 676.267824] hardirqs last enabled at (9579863): [<ffffffffbb14e6f8>] __up_console_sem+0x58/0x60 [ 676.268896] hardirqs last disabled at (9579872): [<ffffffffbb14e6dd>] __up_console_sem+0x3d/0x60 [ 676.270008] softirqs last enabled at (9579798): [<ffffffffbc200349>] __do_softirq+0x349/0x4c7 [ 676.271438] softirqs last disabled at (9579897): [<ffffffffbb0d54c0>] irq_exit_rcu+0xb0/0xf0 [ 676.272796] ---[ end trace 0000000000000000 ]---
I reproduced this warning with dlm_locktorture test which is currently not upstream. However this patch fix the issue by make a additional refcount between dlm_lowcomms_new_msg() and dlm_lowcomms_commit_msg(). In case of the race the kref_put() in dlm_lowcomms_commit_msg() will be the final put.
--- fs/dlm/lowcomms.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/dlm/lowcomms.c +4 -0
@@ -1336,6 +1336,8 @@ struct dlm_msg *dlm_lowcomms_new_msg(int nodeid, int len, gfp_t allocation,return NULL ; } +/* for dlm_lowcomms_commit_msg() */ +kref_get (&msg->ref);/* we assume if successful commit must called */ msg->idx = idx;return msg;
@@ -1375,6 +1377,8 @@ void dlm_lowcomms_commit_msg(struct dlm_msg *msg) {_dlm_lowcomms_commit_msg (msg);srcu_read_unlock (&connections_srcu, msg->idx); +/* because dlm_lowcomms_new_msg() */ +kref_put (&msg->ref, dlm_msg_release); }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 541/717 rcu: Avoid triggering strict-GP irq-work when RCU is idle
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
[ Upstream commit 621189a1fe93cb2b34d62c5cdb9e258bca044813 ]
Kernels built with PREEMPT_RCU=y and RCU_STRICT_GRACE_PERIOD=y trigger irq-work from rcu_read_unlock(), and the resulting irq-work handler invokes rcu_preempt_deferred_qs_handle(). The point of this triggering is to force grace periods to end quickly in order to give tools like KASAN a better chance of detecting RCU usage bugs such as leaking RCU-protected pointers out of an RCU read-side critical section.
However, this irq-work triggering is unconditional. This works, but there is no point in doing this irq-work unless the current grace period is waiting on the running CPU or task, which is not the common case. After all, in the common case there are many rcu_read_unlock() calls per CPU per grace period.
This commit therefore triggers the irq-work only when the current grace period is waiting on the running CPU or task.
This change was tested as follows on a four-CPU system:
echo rcu_preempt_deferred_qs_handler > /sys/kernel/debug/tracing/set_ftrace_filter echo 1 > /sys/kernel/debug/tracing/function_profile_enabled
insmod rcutorture.ko
sleep 20
rmmod rcutorture.ko
echo 0 > /sys/kernel/debug/tracing/function_profile_enabled
echo > /sys/kernel/debug/tracing/set_ftrace_filter
This procedure produces results in this per-CPU set of files:
/sys/kernel/debug/tracing/trace_stat/function*
Sample output from one of these files is as follows:
Function Hit Time Avg s^2 -------- --- ---- --- --- rcu_preempt_deferred_qs_handle 838746 182650.3 us 0.217 us 0.004 us
The baseline sum of the "Hit" values (the number of calls to this function) was 3,319,015. With this commit, that sum was 1,140,359, for a 2.9x reduction. The worst-case variance across the CPUs was less than 25%, so this large effect size is statistically significant.
The raw data is available in the Link: URL.
--- kernel/rcu/tree_plugin.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/rcu/tree_plugin.h +2 -1
@@ -641,7 +641,8 @@ static void rcu_read_unlock_special(struct task_struct *t) expboost = (t->rcu_blocked_node &&READ_ONCE (t->rcu_blocked_node->exp_tasks)) || (rdp->grpmask &READ_ONCE (rnp->expmask)) || -IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) || + (IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) && + ((rdp->grpmask &READ_ONCE (rnp->qsmask)) || t->rcu_blocked_node)) || (IS_ENABLED (CONFIG_RCU_BOOST ) && irqs_were_disabled && t->rcu_blocked_node);// Need to defer quiescent state until everything is enabled.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 542/717 rcu: Back off upon fill_page_cache_func() allocation failure
In reply to Greg Kroah-HartmanFrom: Michal Hocko <[email protected]>
[ Upstream commit 093590c16b447f53e66771c8579ae66c96f6ef61 ]
The fill_page_cache_func() function allocates couple of pages to store kvfree_rcu_bulk_data structures. This is a lightweight (GFP_NORETRY) allocation which can fail under memory pressure. The function will, however keep retrying even when the previous attempt has failed.
This retrying is in theory correct, but in practice the allocation is invoked from workqueue context, which means that if the memory reclaim gets stuck, these retries can hog the worker for quite some time. Although the workqueues subsystem automatically adjusts concurrency, such adjustment is not guaranteed to happen until the worker context sleeps. And the fill_page_cache_func() function's retry loop is not guaranteed to sleep (see the should_reclaim_retry() function).
And we have seen this function cause workqueue lockups:
kernel: BUG: workqueue lockup - pool cpus=93 node=1 flags=0x1 nice=0 stuck for 32s! [...]
kernel: pool 74: cpus=37 node=0 flags=0x1 nice=0 hung=32s workers=2 manager: 2146 kernel: pwq 498: cpus=249 node=1 flags=0x1 nice=0 active=4/256 refcnt=5 kernel: in-flight: 1917:fill_page_cache_func kernel: pending: dbs_work_handler, free_work, kfree_rcu_monitor
Originally, we thought that the root cause of this lockup was several retries with direct reclaim, but this is not yet confirmed. Furthermore, we have seen similar lockups without any heavy memory pressure. This suggests that there are other factors contributing to these lockups. However, it is not really clear that endless retries are desireable.
So let's make the fill_page_cache_func() function back off after allocation failure.
--- kernel/rcu/tree.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/rcu/tree.c +9 -8
@@ -3508,15 +3508,16 @@ static void fill_page_cache_func(struct work_struct *work) bnode = (struct kvfree_rcu_bulk_data *)__get_free_page (GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); -if (bnode) { -raw_spin_lock_irqsave (&krcp->lock, flags); - pushed =put_cached_bnode (krcp, bnode); -raw_spin_unlock_irqrestore (&krcp->lock, flags); +if (!bnode) +break ; -if (!pushed) { -free_page ((unsigned long ) bnode); -break ; - } +raw_spin_lock_irqsave (&krcp->lock, flags); + pushed =put_cached_bnode (krcp, bnode); +raw_spin_unlock_irqrestore (&krcp->lock, flags); + +if (!pushed) { +free_page ((unsigned long ) bnode); +break ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 543/717 cpufreq: amd_pstate: fix wrong lowest perf fetch
In reply to Greg Kroah-HartmanFrom: Perry Yuan <[email protected]>
[ Upstream commit b185c5053c65b7704ead4537e4d4d9b33dc398dc ]
Fix the wrong lowest perf value reading which is used for new des_perf calculation by governor requested, the incorrect min_perf will get incorrect des_perf to be set , that will cause the system frequency changing unexpectedly.
--- drivers/cpufreq/amd-pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/amd-pstate.c +1 -1
@@ -322,7 +322,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy,return -ENODEV ; cap_perf =READ_ONCE (cpudata->highest_perf); - min_perf =READ_ONCE (cpudata->lowest_nonlinear_perf); + min_perf =READ_ONCE (cpudata->lowest_perf); max_perf = cap_perf; freqs.old = policy->cur;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 544/717 ACPI: video: Add Toshiba Satellite/Portege Z830 quirk
In reply to Greg Kroah-HartmanFrom: Arvid Norlander <[email protected]>
[ Upstream commit 574160b8548deff8b80b174f03201e94ab8431e2 ]
Toshiba Satellite Z830 needs the quirk video_disable_backlight_sysfs_if for proper backlight control after suspend/resume cycles.
Toshiba Portege Z830 is simply the same laptop rebranded for certain markets (I looked through the manual to other language sections to confirm this) and thus also needs this quirk.
Thanks to Hans de Goede for suggesting this fix.
--- drivers/acpi/acpi_video.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/acpi/acpi_video.c +16 -0
@@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), }, }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Satellite Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"), + }, + }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Portege Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"), + }, + }, /* * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set * but the IDs actually follow the Device ID Scheme.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 545/717 fortify: Fix __compiletime_strlen() under UBSAN_BOUNDS_LOCAL
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit d07c0acb4f41cc42a0d97530946965b3e4fa68c1 ]
With CONFIG_FORTIFY=y and CONFIG_UBSAN_LOCAL_BOUNDS=y enabled, we observe a runtime panic while running Android's Compatibility Test Suite's (CTS) android.hardware.input.cts.tests. This is stemming from a strlen() call in hidinput_allocate().
__compiletime_strlen() is implemented in terms of __builtin_object_size(), then does an array access to check for NUL-termination. A quirk of __builtin_object_size() is that for strings whose values are runtime dependent, __builtin_object_size(str, 1 or 0) returns the maximum size of possible values when those sizes are determinable at compile time. Example:
static const char *v = "FOO BAR";
static const char *y = "FOO BA";
unsigned long x (int z) {
// Returns 8, which is:
// max(__builtin_object_size(v, 1), __builtin_object_size(y, 1))
return __builtin_object_size(z ? v : y, 1);}
So when FORTIFY_SOURCE is enabled, the current implementation of __compiletime_strlen() will try to access beyond the end of y at runtime using the size of v. Mixed with UBSAN_LOCAL_BOUNDS we get a fault.
hidinput_allocate() has a local C string whose value is control flow dependent on a switch statement, so __builtin_object_size(str, 1) evaluates to the maximum string length, making all other cases fault on the last character check. hidinput_allocate() could be cleaned up to avoid runtime calls to strlen() since the local variable can only have literal values, so there's no benefit to trying to fortify the strlen call site there.
Perform a __builtin_constant_p() check against index 0 earlier in the macro to filter out the control-flow-dependant case. Add a KUnit test for checking the expected behavioral characteristics of FORTIFY_SOURCE internals.
--- include/linux/fortify-string.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/fortify-string.h +2 -1
@@ -19,7 +19,8 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("unsigned char *__p = (unsigned char *)(p); \size_t __ret = (size_t )-1 ; \size_t __p_size =__builtin_object_size (p,1 ); \ -if (__p_size != (size_t )-1 ) { \ +if (__p_size != (size_t )-1 && \ +__builtin_constant_p (*__p)) { \size_t __p_len = __p_size -1 ; \if (__builtin_constant_p (__p[__p_len]) && \ __p[__p_len] =='\0' ) \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 546/717 ACPI: tables: FPDT: Dont call acpi_os_map_memory() on invalid phys address
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 211391bf04b3c74e250c566eeff9cf808156c693 ]
On a Packard Bell Dot SC (Intel Atom N2600 model) there is a FPDT table which contains invalid physical addresses, with high bits set which fall outside the range of the CPU-s supported physical address range.
Calling acpi_os_map_memory() on such an invalid phys address leads to the below WARN_ON in ioremap triggering resulting in an oops/stacktrace.
Add code to verify the physical address before calling acpi_os_map_memory() to fix / avoid the oops.
[ 1.226900] ioremap: invalid physical address 3001000000000000 [ 1.226949] ------------[ cut here ]------------ [ 1.226962] WARNING: CPU: 1 PID: 1 at arch/x86/mm/ioremap.c:200 __ioremap_caller.cold+0x43/0x5f [ 1.226996] Modules linked in: [ 1.227016] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc3+ #490 [ 1.227029] Hardware name: Packard Bell dot s/SJE01_CT, BIOS V1.10 07/23/2013 [ 1.227038] RIP: 0010:__ioremap_caller.cold+0x43/0x5f [ 1.227054] Code: 96 00 00 e9 f8 af 24 ff 89 c6 48 c7 c7 d8 0c 84 99 e8 6a 96 00 00 e9 76 af 24 ff 48 89 fe 48 c7 c7 a8 0c 84 99 e8 56 96 00 00 <0f> 0b e9 60 af 24 ff 48 8b 34 24 48 c7 c7 40 0d 84 99 e8 3f 96 00 [ 1.227067] RSP: 0000:ffffb18c40033d60 EFLAGS: 00010286 [ 1.227084] RAX: 0000000000000032 RBX: 3001000000000000 RCX: 0000000000000000 [ 1.227095] RDX: 0000000000000001 RSI: 00000000ffffdfff RDI: 00000000ffffffff [ 1.227105] RBP: 3001000000000000 R08: 0000000000000000 R09: ffffb18c40033c18 [ 1.227115] R10: 0000000000000003 R11: ffffffff99d62fe8 R12: 0000000000000008 [ 1.227124] R13: 0003001000000000 R14: 0000000000001000 R15: 3001000000000000 [ 1.227135] FS: 0000000000000000(0000) GS:ffff913a3c080000(0000) knlGS:0000000000000000 [ 1.227146] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1.227156] CR2: 0000000000000000 CR3: 0000000018c26000 CR4: 00000000000006e0 [ 1.227167] Call Trace: [ 1.227176] <TASK> [ 1.227185] ? acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227215] ? kmem_cache_alloc_trace+0x187/0x370 [ 1.227254] acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227288] acpi_init_fpdt+0xa8/0x253 [ 1.227308] ? acpi_debugfs_init+0x1f/0x1f [ 1.227339] do_one_initcall+0x5a/0x300 [ 1.227406] ? rcu_read_lock_sched_held+0x3f/0x80 [ 1.227442] kernel_init_freeable+0x28b/0x2cc [ 1.227512] ? rest_init+0x170/0x170 [ 1.227538] kernel_init+0x16/0x140 [ 1.227552] ret_from_fork+0x1f/0x30 [ 1.227639] </TASK> [ 1.227647] irq event stamp: 186819 [ 1.227656] hardirqs last enabled at (186825): [<ffffffff98184a6e>] __up_console_sem+0x5e/0x70 [ 1.227672] hardirqs last disabled at (186830): [<ffffffff98184a53>] __up_console_sem+0x43/0x70 [ 1.227686] softirqs last enabled at (186576): [<ffffffff980fbc9d>] __irq_exit_rcu+0xed/0x160 [ 1.227701] softirqs last disabled at (186569): [<ffffffff980fbc9d>] __irq_exit_rcu+0xed/0x160 [ 1.227715] ---[ end trace 0000000000000000 ]---
--- drivers/acpi/acpi_fpdt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/acpi/acpi_fpdt.c +22 -0
@@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = {static struct kobject *fpdt_kobj; +#if definedCONFIG_X86 && definedCONFIG_PHYS_ADDR_T_64BIT +#include <linux/processor.h> +static bool fpdt_address_valid (u64 address) +{ +/* +* On some systems the table contains invalid addresses +* with unsuppored high address bits set, check for this. +*/ +return !(address >> boot_cpu_data.x86_phys_bits); +} +#else +static bool fpdt_address_valid (u64 address) +{ +return true; +} +#endif +static int fpdt_process_subtable (u64 address,u32 subtable_type) {struct fpdt_subtable_header *subtable_header;
@@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)u32 length, offset;int result; +if (!fpdt_address_valid (address)) { +pr_info (FW_BUG "invalid physical address: 0x%llx!\n" , address); +return -EINVAL ; + } + subtable_header =acpi_os_map_memory (address,sizeof (*subtable_header));if (!subtable_header)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 547/717 cpufreq: intel_pstate: Add Tigerlake support in no-HWP mode
In reply to Greg Kroah-HartmanFrom: Doug Smythies <[email protected]>
[ Upstream commit 71bb5c82aaaea007167f3ba68d3a669c74d7d55d ]
Users may disable HWP in firmware, in which case intel_pstate wouldn't load unless the CPU model is explicitly supported.
Add TIGERLAKE to the list of CPUs that can register intel_pstate while not advertising the HWP capability. Without this change, an TIGERLAKE in no-HWP mode could only use the acpi_cpufreq frequency scaling driver.
See also commits:d8de7a44e11f: cpufreq: intel_pstate: Add Skylake servers supportfbdc21e9b038: cpufreq: intel_pstate: Add Icelake servers support in no-HWP mode 706c5328851d: cpufreq: intel_pstate: Add Cometlake support in no-HWP mode
Reported by: M. Cargi Ari <[email protected]>
--- drivers/cpufreq/intel_pstate.c | 1 + 1 file changed, 1 insertion(+)
drivers/cpufreq/intel_pstate.c +1 -0
@@ -2416,6 +2416,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {X86_MATCH (SKYLAKE_X , core_funcs),X86_MATCH (COMETLAKE , core_funcs),X86_MATCH (ICELAKE_X , core_funcs), +X86_MATCH (TIGERLAKE , core_funcs), {} };MODULE_DEVICE_TABLE (x86cpu, intel_pstate_cpu_ids);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 548/717 MIPS: BCM47XX: Cast memcmp() of function to (void *)
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 0dedcf6e3301836eb70cfa649052e7ce4fcd13ba ]
Clang is especially sensitive about argument type matching when using __overloaded functions (like memcmp(), etc). Help it see that function pointers are just "void *". Avoids this error:
arch/mips/bcm47xx/prom.c:89:8: error: no matching function for call to 'memcmp'
if (!memcmp(prom_init, prom_init + mem, 32))
^~~~~~include/linux/string.h:156:12: note: candidate function not viable: no known conversion from 'void (void)' to 'const void *' for 1st argument extern int memcmp(const void *,const void *,__kernel_size_t);
--- arch/mips/bcm47xx/prom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/bcm47xx/prom.c +2 -2
@@ -86,7 +86,7 @@ static __init void prom_init_mem(void)pr_debug ("Assume 128MB RAM\n" );break ; } -if (!memcmp (prom_init, prom_init + mem,32 )) +if (!memcmp ((void *)prom_init, (void *)prom_init + mem,32 ))break ; } lowmem = mem;
@@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void) off =EXTVBASE +__pa (off);for (extmem =128 <<20 ; extmem <512 <<20 ; extmem <<=1 ) { -if (!memcmp (prom_init, (void *)(off + extmem),16 )) +if (!memcmp ((void *)prom_init, (void *)(off + extmem),16 ))break ; } extmem -= lowmem;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 549/717 powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue
In reply to Greg Kroah-HartmanFrom: Chao Qin <[email protected]>
[ Upstream commit 2d93540014387d1c73b9ccc4d7895320df66d01b ]
When value < time_unit, the parameter of ilog2() will be zero and the return value is -1. u64(-1) is too large for shift exponent and then will trigger shift-out-of-bounds:
shift exponent 18446744073709551615 is too large for 32-bit type 'int'
Call Trace: rapl_compute_time_window_core rapl_write_data_raw set_time_window store_constraint_time_window_us
--- drivers/powercap/intel_rapl_common.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/powercap/intel_rapl_common.c +3 -0
@@ -994,6 +994,9 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value, y = value &0x1f ; value = (1 << y) * (4 + f) * rp->time_unit /4 ; }else { +if (value < rp->time_unit) +return 0 ; +do_div (value, rp->time_unit); y =ilog2 (value); f =div64_u64 (4 * (value - (1 << y)),1 << y);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 550/717 thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash
In reply to Greg Kroah-HartmanFrom: Srinivas Pandruvada <[email protected]>
[ Upstream commit 68b99e94a4a2db6ba9b31fe0485e057b9354a640 ]
When CPU 0 is offline and intel_powerclamp is used to inject idle, it generates kernel BUG:
BUG: using smp_processor_id() in preemptible [00000000] code: bash/15687 caller is debug_smp_processor_id+0x17/0x20 CPU: 4 PID: 15687 Comm: bash Not tainted 5.19.0-rc7+ #57 Call Trace: <TASK> dump_stack_lvl+0x49/0x63 dump_stack+0x10/0x16 check_preemption_disabled+0xdd/0xe0 debug_smp_processor_id+0x17/0x20 powerclamp_set_cur_state+0x7f/0xf9 [intel_powerclamp]
...
...
Here CPU 0 is the control CPU by default and changed to the current CPU, if CPU 0 offlined. This check has to be performed under cpus_read_lock(), hence the above warning.
Use get_cpu() instead of smp_processor_id() to avoid this BUG.
--- drivers/thermal/intel/intel_powerclamp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/thermal/intel/intel_powerclamp.c +4 -2
@@ -532,8 +532,10 @@ static int start_power_clamp(void)/* prefer BSP */ control_cpu =0 ; -if (!cpu_online (control_cpu)) - control_cpu =smp_processor_id (); +if (!cpu_online (control_cpu)) { + control_cpu =get_cpu (); +put_cpu (); + } clamping = true;schedule_delayed_work (&poll_pkg_cstate_work,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 551/717 ARM: decompressor: Include .data.rel.ro.local
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 1b64daf413acd86c2c13f5443f6b4ef3690c8061 ]
The .data.rel.ro.local section has the same semantics as .data.rel.ro here, so include it in the .rodata section of the decompressor. Additionally since the .printk_index section isn't usable outside of the core kernel, discard it in the decompressor. Avoids these warnings:
arm-linux-gnueabi-ld: warning: orphan section .data.rel.ro.local' from arch/arm/boot/compressed/fdt_rw.o' being placed in section `.data.rel.ro.local'
arm-linux-gnueabi-ld: warning: orphan section .printk_index' from arch/arm/boot/compressed/fdt_rw.o' being placed in section `.printk_index'
--- arch/arm/boot/compressed/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/boot/compressed/vmlinux.lds.S +2 -0
@@ -23,6 +23,7 @@ SECTIONS *(.ARM.extab*) *(.note.*) *(.rel.*) + *(.printk_index) /* * Discard any r/w data - this produces a link error if we have any, * which is required for PIC decompression. Local data generates
@@ -57,6 +58,7 @@ SECTIONS *(.rodata) *(.rodata.*) *(.data.rel.ro) + *(.data.rel.ro.*) } .piggydata : { *(.piggydata)
Signature · 9 lines
2.35.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Greg Kroah-Hartman
maintainerPATCH 552/717 ACPI: x86: Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 018d6711c26e4bd26e20a819fcc7f8ab902608f3 ]
Dell Inspiron 14 2-in-1 has two ACPI nodes under GPP1 both with _ADR of 0, both without _HID. It's ambiguous which the kernel should take, but it seems to take "DEV0". Unfortunately "DEV0" is missing the device property StorageD3Enable which is present on "NVME".
To avoid this causing problems for suspend, add a quirk for this system to behave like StorageD3Enable property was found.
--- drivers/acpi/x86/utils.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
drivers/acpi/x86/utils.c +18 -1
@@ -207,9 +207,26 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = { {} }; +static const struct dmi_system_id force_storage_d3_dmi[] = { + { +/* +* _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME +* but .NVME is needed to get StorageD3Enable node +* https://bugzilla.kernel.org/show_bug.cgi?id=216440 +*/ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Dell Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"Inspiron 14 7425 2-in-1" ), + } + }, + {} +}; +bool force_storage_d3 (void ) { -return x86_match_cpu (storage_d3_cpu_ids); +const struct dmi_system_id *dmi_id =dmi_first_match (force_storage_d3_dmi); + +return dmi_id ||x86_match_cpu (storage_d3_cpu_ids); }/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 553/717 x86/entry: Work around Clang __bdos() bug
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 3e1730842f142add55dc658929221521a9ea62b6 ]
Clang produces a false positive when building with CONFIG_FORTIFY_SOURCE=y and CONFIG_UBSAN_BOUNDS=y when operating on an array with a dynamic offset. Work around this by using a direct assignment of an empty instance. Avoids this warning:
../include/linux/fortify-string.h:309:4: warning: call to __write_overflow_field declared with 'warn ing' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wat tribute-warning]
__write_overflow_field(p_size_field, size);
^which was isolated to the memset() call in xen_load_idt().
Note that this looks very much like another bug that was worked around:
https://github.com/ClangBuiltLinux/linux/issues/1592
--- arch/x86/xen/enlighten_pv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/xen/enlighten_pv.c +2 -1
@@ -765,6 +765,7 @@ static void xen_load_idt(const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ]; +static const struct trap_info zero = { };unsigned out;trace_xen_cpu_load_idt (desc);
@@ -774,7 +775,7 @@ static void xen_load_idt(const struct desc_ptr *desc)memcpy (this_cpu_ptr (&idt_desc), desc,sizeof (idt_desc)); out =xen_convert_trap_info (desc, traps, false); -memset (&traps[out],0 ,sizeof (traps[0 ])); + traps[out] = zero;xen_mc_flush ();if (HYPERVISOR_set_trap_table (traps))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 554/717 NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data
In reply to Greg Kroah-HartmanFrom: Anna Schumaker <[email protected]>
[ Upstream commit 06981d560606ac48d61e5f4fff6738b925c93173 ]
This was discussed with Chuck as part of this patch set. Returning nfserr_resource was decided to not be the best error message here, and he suggested changing to nfserr_serverfault instead.
--- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
@@ -3995,7 +3995,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,if (resp->xdr->buf->page_len &&test_bit (RQ_SPLICE_OK , &resp->rqstp->rq_flags)) {WARN_ON_ONCE (1 ); -return nfserr_resource; +return nfserr_serverfault; }xdr_commit_encode (xdr);
Signature · 1 line
2.35.1
Re: [PATCH 5.19 554/717] NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data
Quoted 25 lines · Greg Kroah-Hartman
From: Anna Schumaker <[email protected]>
[ Upstream commit
06981d560606ac48d61e5f4fff6738b925c93173]This was discussed with Chuck as part of this patch set. Returning
nfserr_resourcewas decided to not be the best error message here, and he suggested changing tonfserr_serverfaultinstead.Signed-off-by Anna Schumaker <[email protected]>Signed-off-by Chuck Lever <[email protected]>Signed-off-by Sasha Levin <[email protected]>---
fs/nfsd/nfs4xdr.c| 2 +-1 file changed, 1 insertion(+), 1 deletion(-)fs/nfsd/nfs4xdr.c +0
-0
fs/nfsd/nfs4xdr.c nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, · line 4000
Quoted 7 lines
fs/nfsd/nfs4xdr.c +1
-1@@ -3995,7 +3995,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,if (resp->xdr->buf->page_len &&test_bit (RQ_SPLICE_OK , &resp->rqstp->rq_flags)) {WARN_ON_ONCE (1 ); -return nfserr_resource; +return nfserr_serverfault; }xdr_commit_encode (xdr);
Why is this change to be included in stable kernels?
--
Chuck Lever
Greg Kroah-Hartman
maintainerRe: [PATCH 5.19 554/717] NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data
Quoted 20 lines · Chuck Lever III
Quoted 20 lines · Greg Kroah-Hartman
From: Anna Schumaker <[email protected]>
[ Upstream commit
06981d560606ac48d61e5f4fff6738b925c93173]This was discussed with Chuck as part of this patch set. Returning
nfserr_resourcewas decided to not be the best error message here, and he suggested changing tonfserr_serverfaultinstead.Signed-off-by Anna Schumaker <[email protected]>Signed-off-by Chuck Lever <[email protected]>Signed-off-by Sasha Levin <[email protected]>---
fs/nfsd/nfs4xdr.c| 2 +-1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 14 lines
fs/nfsd/nfs4xdr.c nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, · line 4000
Quoted 12 lines
fs/nfsd/nfs4xdr.c +1
-1@@ -3995,7 +3995,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,if (resp->xdr->buf->page_len &&test_bit (RQ_SPLICE_OK , &resp->rqstp->rq_flags)) {WARN_ON_ONCE (1 ); -return nfserr_resource; +return nfserr_serverfault; }xdr_commit_encode (xdr);Why is this change to be included in stable kernels?
Is it not a valid bugfix? If so, I will be glad to drop it, but in reading the changelog text and the code change itself, it seems like a valid fix to be backporting to stable kernels.
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 555/717 NFSD: fix use-after-free on source server when doing inter-server copy
In reply to Greg Kroah-HartmanFrom: Dai Ngo <[email protected]>
[ Upstream commit 019805fea91599b22dfa62ffb29c022f35abeb06 ]
Use-after-free occurred when the laundromat tried to free expired cpntf_state entry on the s2s_cp_stateids list after inter-server copy completed. The sc_cp_list that the expired copy state was inserted on was already freed.
When COPY completes, the Linux client normally sends LOCKU(lock_state x), FREE_STATEID(lock_state x) and CLOSE(open_state y) to the source server. The nfs4_put_stid call from nfsd4_free_stateid cleans up the copy state from the s2s_cp_stateids list before freeing the lock state's stid.
However, sometimes the CLOSE was sent before the FREE_STATEID request. When this happens, the nfsd4_close_open_stateid call from nfsd4_close frees all lock states on its st_locks list without cleaning up the copy state on the sc_cp_list list. When the time the FREE_STATEID arrives the server returns BAD_STATEID since the lock state was freed. This causes the use-after-free error to occur when the laundromat tries to free the expired cpntf_state.
This patch adds a call to nfs4_free_cpntf_statelist in nfsd4_close_open_stateid to clean up the copy state before calling free_ol_stateid_reaplist to free the lock state's stid on the reaplist.
--- fs/nfsd/nfs4state.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/nfsd/nfs4state.c +5 -0
@@ -1049,6 +1049,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)static void nfs4_free_deleg (struct nfs4_stid *stid) { +WARN_ON (!list_empty (&stid->sc_cp_list));kmem_cache_free (deleg_slab, stid);atomic_long_dec (&num_delegations); }
@@ -1463,6 +1464,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)release_all_access (stp);if (stp->st_stateowner)nfs4_put_stateowner (stp->st_stateowner); +WARN_ON (!list_empty (&stid->sc_cp_list));kmem_cache_free (stateid_slab, stid); }
@@ -6608,6 +6610,7 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)struct nfs4_client *clp = s->st_stid.sc_client;bool unhashed;LIST_HEAD (reaplist); +struct nfs4_ol_stateid *stp;spin_lock (&clp->cl_lock); unhashed =unhash_open_stateid (s, &reaplist);
@@ -6616,6 +6619,8 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)if (unhashed)put_ol_stateid_locked (s, &reaplist);spin_unlock (&clp->cl_lock); +list_for_each_entry (stp, &reaplist, st_locks) +nfs4_free_cpntf_statelist (clp->net, &stp->st_stid);free_ol_stateid_reaplist (&reaplist); }else {spin_unlock (&clp->cl_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 556/717 wifi: ath10k: Set tx credit to one for WCN3990 snoc based devices
In reply to Greg Kroah-HartmanFrom: Youghandhar Chintala <[email protected]>
[ Upstream commit d81bbb684c250a637186d9286d75b1cb04d2986c ]
Currently host can send two WMI commands at once. There is possibility to cause SMMU issues or corruption, if host wants to initiate 2 DMA transfers, it is possible when copy complete interrupt for first DMA reaches host, CE has already updated SRRI (Source ring read index) for both DMA transfers and is in the middle of 2nd DMA. Host uses SRRI (Source ring read index) to interpret how many DMA’s have been completed and tries to unmap/free both the DMA entries. Hence now it is limiting to one.Because CE is still in the middle of 2nd DMA which can cause these issues when handling two DMA transfers.
This change will not impact other targets, as it is only for WCN3990.
Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.2.0-01387-QCAHLSWMTPLZ-1
--- drivers/net/wireless/ath/ath10k/core.c | 16 ++++++++++++++++ drivers/net/wireless/ath/ath10k/htc.c | 11 ++++++++--- drivers/net/wireless/ath/ath10k/hw.h | 2 ++ 3 files changed, 26 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/ath10k/core.c +16 -0
@@ -95,6 +95,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = true, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA988X_HW_2_0_VERSION,
@@ -133,6 +134,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = true, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA9887_HW_1_0_VERSION,
@@ -172,6 +174,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA6174_HW_3_2_VERSION,
@@ -206,6 +209,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .supports_peer_stats_info = true, .dynamic_sar_support = true, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA6174_HW_2_1_VERSION,
@@ -244,6 +248,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA6174_HW_2_1_VERSION,
@@ -282,6 +287,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA6174_HW_3_0_VERSION,
@@ -320,6 +326,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA6174_HW_3_2_VERSION,
@@ -362,6 +369,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .supports_peer_stats_info = true, .dynamic_sar_support = true, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -406,6 +414,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA9984_HW_1_0_DEV_VERSION,
@@ -457,6 +466,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA9888_HW_2_0_DEV_VERSION,
@@ -505,6 +515,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA9377_HW_1_0_DEV_VERSION,
@@ -543,6 +554,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -583,6 +595,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -614,6 +627,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .credit_size_workaround = true, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = QCA4019_HW_1_0_DEV_VERSION,
@@ -659,6 +673,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = false, .hw_restart_disconnect = false, + .use_fw_tx_credits = true, }, { .id = WCN3990_HW_1_0_DEV_VERSION,
@@ -690,6 +705,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .tx_stats_over_pktlog = false, .dynamic_sar_support = true, .hw_restart_disconnect = true, + .use_fw_tx_credits = false, }, };
drivers/net/wireless/ath/ath10k/htc.c +8 -3
@@ -947,13 +947,18 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)return -ECOMM ; } - htc->total_transmit_credits =__le16_to_cpu (msg->ready.credit_count); +if (ar->hw_params.use_fw_tx_credits) + htc->total_transmit_credits =__le16_to_cpu (msg->ready.credit_count); +else + htc->total_transmit_credits =1 ; + htc->target_credit_size =__le16_to_cpu (msg->ready.credit_size);ath10k_dbg (ar,ATH10K_DBG_HTC , -"Target ready! transmit resources: %d size:%d\n" , +"Target ready! transmit resources: %d size:%d actual credits:%d\n" , htc->total_transmit_credits, - htc->target_credit_size); + htc->target_credit_size, + msg->ready.credit_count);if ((htc->total_transmit_credits ==0 ) || (htc->target_credit_size ==0 )) {
drivers/net/wireless/ath/ath10k/hw.h +2 -0
@@ -635,6 +635,8 @@ struct ath10k_hw_params {bool dynamic_sar_support;bool hw_restart_disconnect; + +bool use_fw_tx_credits; };struct htt_resp ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 557/717 wifi: brcmfmac: fix invalid address access when enabling SCAN log level
In reply to Greg Kroah-HartmanFrom: Wright Feng <[email protected]>
[ Upstream commit aa666b68e73fc06d83c070d96180b9010cf5a960 ]
The variable i is changed when setting random MAC address and causes invalid address access when printing the value of pi->reqs[i]->reqid.
We replace reqs index with ri to fix the issue.
[ 136.726473] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000 [ 136.737365] Mem abort info: [ 136.740172] ESR = 0x96000004 [ 136.743359] Exception class = DABT (current EL), IL = 32 bits [ 136.749294] SET = 0, FnV = 0 [ 136.752481] EA = 0, S1PTW = 0 [ 136.755635] Data abort info: [ 136.758514] ISV = 0, ISS = 0x00000004 [ 136.762487] CM = 0, WnR = 0 [ 136.765522] user pgtable: 4k pages, 48-bit VAs, pgdp = 000000005c4e2577 [ 136.772265] [0000000000000000] pgd=0000000000000000 [ 136.777160] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 136.782732] Modules linked in: brcmfmac(O) brcmutil(O) cfg80211(O) compat(O) [ 136.789788] Process wificond (pid: 3175, stack limit = 0x00000000053048fb) [ 136.796664] CPU: 3 PID: 3175 Comm: wificond Tainted: G O 4.19.42-00001-g531a5f5 #1 [ 136.805532] Hardware name: Freescale i.MX8MQ EVK (DT) [ 136.810584] pstate: 60400005 (nZCv daif +PAN -UAO) [ 136.815429] pc : brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.821811] lr : brcmf_pno_config_sched_scans+0x67c/0xa80 [brcmfmac] [ 136.828162] sp : ffff00000e9a3880 [ 136.831475] x29: ffff00000e9a3890 x28: ffff800020543400 [ 136.836786] x27: ffff8000b1008880 x26: ffff0000012bf6a0 [ 136.842098] x25: ffff80002054345c x24: ffff800088d22400 [ 136.847409] x23: ffff0000012bf638 x22: ffff0000012bf6d8 [ 136.852721] x21: ffff8000aced8fc0 x20: ffff8000ac164400 [ 136.858032] x19: ffff00000e9a3946 x18: 0000000000000000 [ 136.863343] x17: 0000000000000000 x16: 0000000000000000 [ 136.868655] x15: ffff0000093f3b37 x14: 0000000000000050 [ 136.873966] x13: 0000000000003135 x12: 0000000000000000 [ 136.879277] x11: 0000000000000000 x10: ffff000009a61888 [ 136.884589] x9 : 000000000000000f x8 : 0000000000000008 [ 136.889900] x7 : 303a32303d726464 x6 : ffff00000a1f957d [ 136.895211] x5 : 0000000000000000 x4 : ffff00000e9a3942 [ 136.900523] x3 : 0000000000000000 x2 : ffff0000012cead8 [ 136.905834] x1 : ffff0000012bf6d8 x0 : 0000000000000000 [ 136.911146] Call trace: [ 136.913623] brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.919658] brcmf_pno_start_sched_scan+0xa4/0x118 [brcmfmac] [ 136.925430] brcmf_cfg80211_sched_scan_start+0x80/0xe0 [brcmfmac] [ 136.931636] nl80211_start_sched_scan+0x140/0x308 [cfg80211] [ 136.937298] genl_rcv_msg+0x358/0x3f4 [ 136.940960] netlink_rcv_skb+0xb4/0x118 [ 136.944795] genl_rcv+0x34/0x48 [ 136.947935] netlink_unicast+0x264/0x300 [ 136.951856] netlink_sendmsg+0x2e4/0x33c [ 136.955781] __sys_sendto+0x120/0x19c
--- .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +6 -6
@@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)struct brcmf_pno_macaddr_le pfn_mac;u8 *mac_addr =NULL ;u8 *mac_mask =NULL ; -int err, i; +int err, i, ri; -for (i =0 ; i < pi->n_reqs; i++) -if (pi->reqs[i]->flags &NL80211_SCAN_FLAG_RANDOM_ADDR ) { - mac_addr = pi->reqs[i]->mac_addr; - mac_mask = pi->reqs[i]->mac_addr_mask; +for (ri =0 ; ri < pi->n_reqs; ri++) +if (pi->reqs[ri]->flags &NL80211_SCAN_FLAG_RANDOM_ADDR ) { + mac_addr = pi->reqs[ri]->mac_addr; + mac_mask = pi->reqs[ri]->mac_addr_mask;break ; }
@@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) pfn_mac.mac[0 ] |=0x02 ;brcmf_dbg (SCAN ,"enabling random mac: reqid=%llu mac=%pM\n" , - pi->reqs[i]->reqid, pfn_mac.mac); + pi->reqs[ri]->reqid, pfn_mac.mac); err =brcmf_fil_iovar_data_set (ifp,"pfn_macaddr" , &pfn_mac,sizeof (pfn_mac));if (err)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 558/717 bpftool: Clear errno after libcaps checks
In reply to Greg Kroah-HartmanFrom: Quentin Monnet <[email protected]>
[ Upstream commit cea558855c39b7f1f02ff50dcf701ca6596bc964 ]
When bpftool is linked against libcap, the library runs a "constructor" function to compute the number of capabilities of the running kernel [0], at the beginning of the execution of the program. As part of this, it performs multiple calls to prctl(). Some of these may fail, and set errno to a non-zero value:
# strace -e prctl ./bpftool version
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
** fprintf added at the top of main(): we have errno == 1
./bpftool v7.0.0
using libbpf v1.0
features: libbfd, libbpf_strict, skeletons
+++ exited with 0 +++This has been addressed in libcap 2.63 [1], but until this version is available everywhere, we can fix it on bpftool side.
Let's clean errno at the beginning of the main() function, to make sure that these checks do not interfere with the batch mode, where we error out if errno is set after a bpftool command.
[0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/tree/libcap/cap_alloc.c?h=libcap-2.65#n20
[1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=f25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0
--- tools/bpf/bpftool/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/bpf/bpftool/main.c +10 -0
@@ -435,6 +435,16 @@ int main(int argc, char **argv)setlinebuf (stdout); +#ifdef USE_LIBCAP +/* Libcap < 2.63 hooks before main() to compute the number of +* capabilities of the running kernel, and doing so it calls prctl() +* which may fail and set errno to non-zero. +* Let's reset errno to make sure this does not interfere with the +* batch mode. +*/ + errno =0 ; +#endif + last_do_help = do_help; pretty_output = false; json_output = false;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 559/717 ice: set tx_tstamps when creating new Tx rings via ethtool
In reply to Greg Kroah-HartmanFrom: Jacob Keller <[email protected]>
[ Upstream commit b3b173745c8cab1e24d6821488b60abed3acb24d ]
When the user changes the number of queues via ethtool, the driver allocates new rings. This allocation did not initialize tx_tstamps. This results in the tx_tstamps field being zero (due to kcalloc allocation), and would result in a NULL pointer dereference when attempting a transmit timestamp on the new ring.
--- drivers/net/ethernet/intel/ice/ice_ethtool.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/ice/ice_ethtool.c +1 -0
@@ -2826,6 +2826,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, tx_rings[i].count = new_tx_cnt; tx_rings[i].desc =NULL ; tx_rings[i].tx_buf =NULL ; + tx_rings[i].tx_tstamps = &pf->ptp.port.tx; err =ice_setup_tx_ring (&tx_rings[i]);if (err) {while (i--)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 560/717 net: ethernet: ti: davinci_mdio: Add workaround for errata i2329
In reply to Greg Kroah-HartmanFrom: Ravi Gunasekaran <[email protected]>
[ Upstream commit d04807b80691c6041ca8e3dcf1870d1bf1082c22 ]
On the CPSW and ICSS peripherals, there is a possibility that the MDIO interface returns corrupt data on MDIO reads or writes incorrect data on MDIO writes. There is also a possibility for the MDIO interface to become unavailable until the next peripheral reset.
The workaround is to configure the MDIO in manual mode and disable the MDIO state machine and emulate the MDIO protocol by reading and writing appropriate fields in MDIO_MANUAL_IF_REG register of the MDIO controller to manipulate the MDIO clock and data pins.
More details about the errata i2329 and the workaround is available in:
https://www.ti.com/lit/er/sprz487a/sprz487a.pdf
Add implementation to disable MDIO state machine, configure MDIO in manual mode and achieve MDIO read and writes via MDIO Bitbanging
--- drivers/net/ethernet/ti/davinci_mdio.c | 242 +++++++++++++++++++++++-- 1 file changed, 231 insertions(+), 11 deletions(-)
drivers/net/ethernet/ti/davinci_mdio.c +231 -11
@@ -26,6 +26,8 @@#include <linux/of_device.h> #include <linux/of_mdio.h> #include <linux/pinctrl/consumer.h> +#include <linux/mdio-bitbang.h> +#include <linux/sys_soc.h> /* * This timeout definition is a worst-case ultra defensive measure against
@@ -41,6 +43,7 @@struct davinci_mdio_of_param {int autosuspend_delay_ms; +bool manual_mode; };struct davinci_mdio_regs {
@@ -49,6 +52,15 @@ struct davinci_mdio_regs {#define CONTROL_IDLE BIT(31)#define CONTROL_ENABLE BIT(30)#define CONTROL_MAX_DIV (0xffff) +#define CONTROL_CLKDIV GENMASK(15, 0) + +#define MDIO_MAN_MDCLK_O BIT(2) +#define MDIO_MAN_OE BIT(1) +#define MDIO_MAN_PIN BIT(0) +#define MDIO_MANUALMODE BIT(31) + +#define MDIO_PIN 0 +u32 alive;u32 link;
@@ -59,7 +71,9 @@ struct davinci_mdio_regs {u32 userintmasked;u32 userintmaskset;u32 userintmaskclr; -u32 __reserved_1[20 ]; +u32 manualif; +u32 poll; +u32 __reserved_1[18 ];struct {u32 access;
@@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = {struct davinci_mdio_data {struct mdio_platform_data pdata; +struct mdiobb_ctrl bb_ctrl;struct davinci_mdio_regs __iomem *regs;struct clk *clk;struct device *dev;
@@ -90,6 +105,7 @@ struct davinci_mdio_data {*/ bool skip_scan;u32 clk_div; +bool manual_mode; };static void davinci_mdio_init_clk (struct davinci_mdio_data *data)
@@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)writel (data->clk_div |CONTROL_ENABLE , &data->regs->control); } -static int davinci_mdio_reset (struct mii_bus *bus) +static void davinci_mdio_disable (struct davinci_mdio_data *data) +{ +u32 reg; + +/* Disable MDIO state machine */ + reg =readl (&data->regs->control); + + reg &= ~CONTROL_CLKDIV ; + reg |= data->clk_div; + + reg &= ~CONTROL_ENABLE ; +writel (reg, &data->regs->control); +} + +static void davinci_mdio_enable_manual_mode (struct davinci_mdio_data *data) +{ +u32 reg; +/* set manual mode */ + reg =readl (&data->regs->poll); + reg |=MDIO_MANUALMODE ; +writel (reg, &data->regs->poll); +} + +static void davinci_set_mdc (struct mdiobb_ctrl *ctrl,int level) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (level) + reg |=MDIO_MAN_MDCLK_O ; +else + reg &= ~MDIO_MAN_MDCLK_O ; + +writel (reg, &data->regs->manualif); +} + +static void davinci_set_mdio_dir (struct mdiobb_ctrl *ctrl,int output) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (output) + reg |=MDIO_MAN_OE ; +else + reg &= ~MDIO_MAN_OE ; + +writel (reg, &data->regs->manualif); +} + +static void davinci_set_mdio_data (struct mdiobb_ctrl *ctrl,int value) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (value) + reg |=MDIO_MAN_PIN ; +else + reg &= ~MDIO_MAN_PIN ; + +writel (reg, &data->regs->manualif); +} + +static int davinci_get_mdio_data (struct mdiobb_ctrl *ctrl) +{ +struct davinci_mdio_data *data; +unsigned long reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); +return test_bit (MDIO_PIN , ®); +} + +static int davinci_mdiobb_read (struct mii_bus *bus,int phy,int reg) +{ +int ret; + + ret =pm_runtime_resume_and_get (bus->parent); +if (ret <0 ) +return ret; + + ret =mdiobb_read (bus, phy, reg); + +pm_runtime_mark_last_busy (bus->parent); +pm_runtime_put_autosuspend (bus->parent); + +return ret; +} + +static int davinci_mdiobb_write (struct mii_bus *bus,int phy,int reg, +u16 val) +{ +int ret; + + ret =pm_runtime_resume_and_get (bus->parent); +if (ret <0 ) +return ret; + + ret =mdiobb_write (bus, phy, reg, val); + +pm_runtime_mark_last_busy (bus->parent); +pm_runtime_put_autosuspend (bus->parent); + +return ret; +} + +static int davinci_mdio_common_reset (struct davinci_mdio_data *data) { -struct davinci_mdio_data *data = bus->priv;u32 phy_mask, ver;int ret;
@@ -138,6 +267,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)if (ret <0 )return ret; +if (data->manual_mode) { +davinci_mdio_disable (data); +davinci_mdio_enable_manual_mode (data); + } +/* wait for scan logic to settle */ msleep (PHY_MAX_ADDR * data->access_time);
@@ -171,6 +305,23 @@ static int davinci_mdio_reset(struct mii_bus *bus)return 0 ; } +static int davinci_mdio_reset (struct mii_bus *bus) +{ +struct davinci_mdio_data *data = bus->priv; + +return davinci_mdio_common_reset (data); +} + +static int davinci_mdiobb_reset (struct mii_bus *bus) +{ +struct mdiobb_ctrl *ctrl = bus->priv; +struct davinci_mdio_data *data; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + +return davinci_mdio_common_reset (data); +} +/* wait until hardware is ready for another user access */ static inline int wait_for_user_access (struct davinci_mdio_data *data) {
@@ -318,6 +469,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data,return 0 ; } +struct k3_mdio_soc_data { +bool manual_mode; +}; + +static const struct k3_mdio_soc_data am65_mdio_soc_data = { + .manual_mode = true, +}; + +static const struct soc_device_attribute k3_mdio_socinfo[] = { + { .family ="AM62X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM64X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM64X" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="AM65X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM65X" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J7200" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="J7200" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J721E" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="J721E" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J721S2" , .revision ="SR1.0" , .data = &am65_mdio_soc_data}, + {/* sentinel */ }, +}; +#if IS_ENABLED (CONFIG_OF )static const struct davinci_mdio_of_param of_cpsw_mdio_data = { .autosuspend_delay_ms = 100,
@@ -331,6 +504,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {MODULE_DEVICE_TABLE (of, davinci_mdio_of_mtable);#endif +static const struct mdiobb_ops davinci_mdiobb_ops = { + .owner =THIS_MODULE , + .set_mdc = davinci_set_mdc, + .set_mdio_dir = davinci_set_mdio_dir, + .set_mdio_data = davinci_set_mdio_data, + .get_mdio_data = davinci_get_mdio_data, +}; +static int davinci_mdio_probe (struct platform_device *pdev) {struct mdio_platform_data *pdata =dev_get_platdata (&pdev->dev);
@@ -345,7 +526,26 @@ static int davinci_mdio_probe(struct platform_device *pdev)if (!data)return -ENOMEM ; - data->bus =devm_mdiobus_alloc (dev); + data->manual_mode = false; + data->bb_ctrl.ops = &davinci_mdiobb_ops; + +if (IS_ENABLED (CONFIG_OF ) && dev->of_node) { +const struct soc_device_attribute *soc_match_data; + + soc_match_data =soc_device_match (k3_mdio_socinfo); +if (soc_match_data && soc_match_data->data) { +const struct k3_mdio_soc_data *socdata = + soc_match_data->data; + + data->manual_mode = socdata->manual_mode; + } + } + +if (data->manual_mode) + data->bus =alloc_mdio_bitbang (&data->bb_ctrl); +else + data->bus =devm_mdiobus_alloc (dev); +if (!data->bus) {dev_err (dev,"failed to alloc mii bus\n" );return -ENOMEM ;
@@ -371,11 +571,20 @@ static int davinci_mdio_probe(struct platform_device *pdev) } data->bus->name =dev_name (dev); - data->bus->read = davinci_mdio_read; - data->bus->write = davinci_mdio_write; - data->bus->reset = davinci_mdio_reset; + +if (data->manual_mode) { + data->bus->read = davinci_mdiobb_read; + data->bus->write = davinci_mdiobb_write; + data->bus->reset = davinci_mdiobb_reset; + +dev_info (dev,"Configuring MDIO in manual mode\n" ); + }else { + data->bus->read = davinci_mdio_read; + data->bus->write = davinci_mdio_write; + data->bus->reset = davinci_mdio_reset; + data->bus->priv = data; + } data->bus->parent = dev; - data->bus->priv = data; data->clk =devm_clk_get (dev,"fck" );if (IS_ERR (data->clk)) {
@@ -433,9 +642,13 @@ static int davinci_mdio_remove(struct platform_device *pdev) {struct davinci_mdio_data *data =platform_get_drvdata (pdev); -if (data->bus) +if (data->bus) {mdiobus_unregister (data->bus); +if (data->manual_mode) +free_mdio_bitbang (data->bus); + } +pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_disable (&pdev->dev);
@@ -452,7 +665,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev) ctrl =readl (&data->regs->control); ctrl &= ~CONTROL_ENABLE ;writel (ctrl, &data->regs->control); -wait_for_idle (data); + +if (!data->manual_mode) +wait_for_idle (data);return 0 ; }
@@ -461,7 +676,12 @@ static int davinci_mdio_runtime_resume(struct device *dev) {struct davinci_mdio_data *data =dev_get_drvdata (dev); -davinci_mdio_enable (data); +if (data->manual_mode) { +davinci_mdio_disable (data); +davinci_mdio_enable_manual_mode (data); + }else { +davinci_mdio_enable (data); + }return 0 ; }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 561/717 openvswitch: Fix double reporting of drops in dropwatch
In reply to Greg Kroah-HartmanFrom: Mike Pattrick <[email protected]>
[ Upstream commit 1100248a5c5ccd57059eb8d02ec077e839a23826 ]
Frames sent to userspace can be reported as dropped in ovs_dp_process_packet, however, if they are dropped in the netlink code then netlink_attachskb will report the same frame as dropped.
This patch checks for error codes which indicate that the frame has already been freed.
--- net/openvswitch/datapath.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
net/openvswitch/datapath.c +10 -3
@@ -252,10 +252,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.mru =OVS_CB (skb)->mru; error =ovs_dp_upcall (dp, skb, key, &upcall,0 ); -if (unlikely (error)) -kfree_skb (skb); -else +switch (error) { +case 0 : +case -EAGAIN : +case -ERESTARTSYS : +case -EINTR :consume_skb (skb); +break ; +default : +kfree_skb (skb); +break ; + } stats_counter = &stats->n_missed; goto out; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 562/717 openvswitch: Fix overreporting of drops in dropwatch
In reply to Greg Kroah-HartmanFrom: Mike Pattrick <[email protected]>
[ Upstream commit c21ab2afa2c64896a7f0e3cbc6845ec63dcfad2e ]
Currently queue_userspace_packet will call kfree_skb for all frames, whether or not an error occurred. This can result in a single dropped frame being reported as multiple drops in dropwatch. This functions caller may also call kfree_skb in case of an error. This patch will consume the skbs instead and allow caller's to use kfree_skb.
--- net/openvswitch/datapath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/openvswitch/datapath.c +3 -2
@@ -558,8 +558,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, out:if (err)skb_tx_error (skb); -kfree_skb (user_skb); -kfree_skb (nskb); +consume_skb (user_skb); +consume_skb (nskb); +return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 563/717 tcp: annotate data-race around tcp_md5sig_pool_populated
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit aacd467c0a576e5e44d2de4205855dc0fe43f6fb ]
tcp_md5sig_pool_populated can be read while another thread changes its value.
The race has no consequence because allocations are protected with tcp_md5sig_mutex.
This patch adds READ_ONCE() and WRITE_ONCE() to document the race and silence KCSAN.
--- net/ipv4/tcp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
net/ipv4/tcp.c +10 -4
@@ -4349,12 +4349,16 @@ static void __tcp_alloc_md5sig_pool(void)* to memory. See smp_rmb() in tcp_get_md5sig_pool() */ smp_wmb (); - tcp_md5sig_pool_populated = true; +/* Paired with READ_ONCE() from tcp_alloc_md5sig_pool() +* and tcp_get_md5sig_pool(). +*/ +WRITE_ONCE (tcp_md5sig_pool_populated, true); }bool tcp_alloc_md5sig_pool (void ) { -if (unlikely (!tcp_md5sig_pool_populated)) { +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +if (unlikely (!READ_ONCE (tcp_md5sig_pool_populated))) {mutex_lock (&tcp_md5sig_mutex);if (!tcp_md5sig_pool_populated) {
@@ -4365,7 +4369,8 @@ bool tcp_alloc_md5sig_pool(void)mutex_unlock (&tcp_md5sig_mutex); } -return tcp_md5sig_pool_populated; +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +return READ_ONCE (tcp_md5sig_pool_populated); }EXPORT_SYMBOL (tcp_alloc_md5sig_pool);
@@ -4381,7 +4386,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) {local_bh_disable (); -if (tcp_md5sig_pool_populated) { +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +if (READ_ONCE (tcp_md5sig_pool_populated)) {/* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */ smp_rmb ();return this_cpu_ptr (&tcp_md5sig_pool);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 564/717 x86/mce: Retrieve poison range from hardware
In reply to Greg Kroah-HartmanFrom: Jane Chu <[email protected]>
[ Upstream commit f9781bb18ed828e7b83b7bac4a4ad7cd497ee7d7 ]
When memory poison consumption machine checks fire, MCE notifier handlers like nfit_handle_mce() record the impacted physical address range which is reported by the hardware in the MCi_MISC MSR. The error information includes data about blast radius, i.e. how many cachelines did the hardware determine are impacted. A recent change
7917f9cdb503 ("acpi/nfit: rely on mce->misc to determine poison granularity")
updated nfit_handle_mce() to stop hard coding the blast radius value of 1 cacheline, and instead rely on the blast radius reported in 'struct mce' which can be up to 4K (64 cachelines).
It turns out that apei_mce_report_mem_error() had a similar problem in that it hard coded a blast radius of 4K rather than reading the blast radius from the error information. Fix apei_mce_report_mem_error() to convey the proper poison granularity.
--- arch/x86/kernel/cpu/mce/apei.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/mce/apei.c +12 -1
@@ -29,15 +29,26 @@void apei_mce_report_mem_error (int severity,struct cper_sec_mem_err *mem_err) {struct mce m; +int lsb;if (!(mem_err->validation_bits &CPER_MEM_VALID_PA ))return ; +/* +* Even if the ->validation_bits are set for address mask, +* to be extra safe, check and reject an error radius '0', +* and fall back to the default page size. +*/ +if (mem_err->validation_bits &CPER_MEM_VALID_PA_MASK ) + lsb =find_first_bit ((void *)&mem_err->physical_addr_mask,PAGE_SHIFT ); +else + lsb =PAGE_SHIFT ; +mce_setup (&m); m.bank =-1 ;/* Fake a memory read error with unknown channel */ m.status =MCI_STATUS_VAL |MCI_STATUS_EN |MCI_STATUS_ADDRV |MCI_STATUS_MISCV |0x9f ; - m.misc = (MCI_MISC_ADDR_PHYS <<6 ) |PAGE_SHIFT ; + m.misc = (MCI_MISC_ADDR_PHYS <<6 ) | lsb;if (severity >=GHES_SEV_RECOVERABLE ) m.status |=MCI_STATUS_UC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 565/717 wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit b383e8abed41cc6ff1a3b34de75df9397fa4878c ]
syzbot is reporting uninit value at ath9k_htc_rx_msg() [1], for ioctl(USB_RAW_IOCTL_EP_WRITE) can call ath9k_hif_usb_rx_stream() with pkt_len = 0 but ath9k_hif_usb_rx_stream() uses __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC) based on an assumption that pkt_len is valid. As a result, ath9k_hif_usb_rx_stream() allocates skb with uninitialized memory and ath9k_htc_rx_msg() is reading from uninitialized memory.
Since bytes accessed by ath9k_htc_rx_msg() is not known until ath9k_htc_rx_msg() is called, it would be difficult to check minimal valid pkt_len at "if (pkt_len > 2 * MAX_RX_BUF_SIZE) {" line in ath9k_hif_usb_rx_stream().
We have two choices. One is to workaround by adding __GFP_ZERO so that ath9k_htc_rx_msg() sees 0 if pkt_len is invalid. The other is to let ath9k_htc_rx_msg() validate pkt_len before accessing. This patch chose the latter.
Note that I'm not sure threshold condition is correct, for I can't find details on possible packet length used by this protocol.
--- drivers/net/wireless/ath/ath9k/htc_hst.c | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-)
drivers/net/wireless/ath/ath9k/htc_hst.c +28 -15
@@ -364,33 +364,27 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, }static void ath9k_htc_fw_panic_report (struct htc_target *htc_handle, -struct sk_buff *skb) +struct sk_buff *skb,u32 len) {uint32_t *pattern = (uint32_t *)skb->data; -switch (*pattern) { -case 0x33221199 : - { +if (*pattern ==0x33221199 && len >=sizeof (struct htc_panic_bad_vaddr )) {struct htc_panic_bad_vaddr *htc_panic; htc_panic = (struct htc_panic_bad_vaddr *) skb->data;dev_err (htc_handle->dev,"ath: firmware panic! " "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n" , htc_panic->exccause, htc_panic->pc, htc_panic->badvaddr); -break ; - } -case 0x33221299 : - { +return ; + } +if (*pattern ==0x33221299 ) {struct htc_panic_bad_epid *htc_panic; htc_panic = (struct htc_panic_bad_epid *) skb->data;dev_err (htc_handle->dev,"ath: firmware panic! " "bad epid: 0x%08x\n" , htc_panic->epid); -break ; - } -default : -dev_err (htc_handle->dev,"ath: unknown panic pattern!\n" ); -break ; +return ; } +dev_err (htc_handle->dev,"ath: unknown panic pattern!\n" ); }/*
@@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,if (!htc_handle || !skb)return ; +/* A valid message requires len >= 8. +* +* sizeof(struct htc_frame_hdr) == 8 +* sizeof(struct htc_ready_msg) == 8 +* sizeof(struct htc_panic_bad_vaddr) == 16 +* sizeof(struct htc_panic_bad_epid) == 8 +*/ +if (unlikely (len <sizeof (struct htc_frame_hdr ))) + goto invalid; htc_hdr = (struct htc_frame_hdr *) skb->data; epid = htc_hdr->endpoint_id;if (epid ==0x99 ) { -ath9k_htc_fw_panic_report (htc_handle, skb); +ath9k_htc_fw_panic_report (htc_handle, skb, len);kfree_skb (skb);return ; }if (epid <0 || epid >=ENDPOINT_MAX ) { +invalid:if (pipe_id !=USB_REG_IN_PIPE )dev_kfree_skb_any (skb);else
@@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,/* Handle trailer */ if (htc_hdr->flags &HTC_FLAGS_RECV_TRAILER ) { -if (be32_to_cpu (*(__be32 *) skb->data) ==0x00C60000 ) +if (be32_to_cpu (*(__be32 *) skb->data) ==0x00C60000 ) {/* Move past the Watchdog pattern */ htc_hdr = (struct htc_frame_hdr *)(skb->data +4 ); + len -=4 ; + } }/* Get the message ID */ +if (unlikely (len <sizeof (struct htc_frame_hdr ) +sizeof (__be16))) + goto invalid; msg_id = (__be16 *) ((void *) htc_hdr +sizeof (struct htc_frame_hdr ));/* Now process HTC messages */ switch (be16_to_cpu (*msg_id)) {case HTC_MSG_READY_ID : +if (unlikely (len <sizeof (struct htc_ready_msg ))) + goto invalid;htc_process_target_rdy (htc_handle, htc_hdr);break ;case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID : +if (unlikely (len <sizeof (struct htc_frame_hdr ) + +sizeof (struct htc_conn_svc_rspmsg ))) + goto invalid;htc_process_conn_rsp (htc_handle, htc_hdr);break ;default :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 566/717 thunderbolt: Add back Intel Falcon Ridge end-to-end flow control workaround
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 54669e2f17cb5a4c41ade89427f074dc22cecb17 ]
As we are now enabling full end-to-end flow control to the Thunderbolt networking driver, in order for it to work properly on second generation Thunderbolt hardware (Falcon Ridge), we need to add back the workaround that was removed with commit 53f13319d131 ("thunderbolt: Get rid of E2E workaround"). However, this time we only apply it for Falcon Ridge controllers as a form of an additional quirk. For non-Falcon Ridge this does nothing.
While there fix a typo 'reqister' -> 'register' in the comment.
--- drivers/thunderbolt/nhi.c | 49 +++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-)
drivers/thunderbolt/nhi.c +42 -7
@@ -28,7 +28,11 @@#define RING_TYPE (ring) ((ring)->is_tx ? "TX ring" : "RX ring")#define RING_FIRST_USABLE_HOPID 1 - +/* +* Used with QUIRK_E2E to specify an unused HopID the Rx credits are +* transferred. +*/ +#define RING_E2E_RESERVED_HOPID RING_FIRST_USABLE_HOPID/* * Minimal number of vectors when we use MSI-X. Two for control channel * Rx/Tx and the rest four are for cross domain DMA paths.
@@ -38,7 +42,9 @@#define NHI_MAILBOX_TIMEOUT 500/* ms */ +/* Host interface quirks */ #define QUIRK_AUTO_CLEAR_INT BIT(0) +#define QUIRK_E2E BIT(1)static int ring_interrupt_index (struct tb_ring *ring) {
@@ -458,8 +464,18 @@ static void ring_release_msix(struct tb_ring *ring)static int nhi_alloc_hop (struct tb_nhi *nhi,struct tb_ring *ring) { +unsigned int start_hop =RING_FIRST_USABLE_HOPID ;int ret =0 ; +if (nhi->quirks &QUIRK_E2E ) { + start_hop =RING_FIRST_USABLE_HOPID +1 ; +if (ring->flags &RING_FLAG_E2E && !ring->is_tx) { +dev_dbg (&nhi->pdev->dev,"quirking E2E TX HopID %u -> %u\n" , + ring->e2e_tx_hop,RING_E2E_RESERVED_HOPID ); + ring->e2e_tx_hop =RING_E2E_RESERVED_HOPID ; + } + } +spin_lock_irq (&nhi->lock);if (ring->hop <0 ) {
@@ -469,7 +485,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)* Automatically allocate HopID from the non-reserved * range 1 .. hop_count - 1. */ -for (i =RING_FIRST_USABLE_HOPID ; i < nhi->hop_count; i++) { +for (i = start_hop; i < nhi->hop_count; i++) {if (ring->is_tx) {if (!nhi->tx_rings[i]) { ring->hop = i;
@@ -484,6 +500,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring) } } +if (ring->hop >0 && ring->hop < start_hop) { +dev_warn (&nhi->pdev->dev,"invalid hop: %d\n" , ring->hop); + ret = -EINVAL ; + goto err_unlock; + }if (ring->hop <0 || ring->hop >= nhi->hop_count) {dev_warn (&nhi->pdev->dev,"invalid hop: %d\n" , ring->hop); ret = -EINVAL ;
@@ -1097,12 +1118,26 @@ static void nhi_shutdown(struct tb_nhi *nhi)static void nhi_check_quirks (struct tb_nhi *nhi) { -/* -* Intel hardware supports auto clear of the interrupt status -* reqister right after interrupt is being issued. -*/ -if (nhi->pdev->vendor ==PCI_VENDOR_ID_INTEL ) +if (nhi->pdev->vendor ==PCI_VENDOR_ID_INTEL ) { +/* +* Intel hardware supports auto clear of the interrupt +* status register right after interrupt is being +* issued. +*/ nhi->quirks |=QUIRK_AUTO_CLEAR_INT ; + +switch (nhi->pdev->device) { +case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI : +case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI : +/* +* Falcon Ridge controller needs the end-to-end +* flow control workaround to avoid losing Rx +* packets when RING_FLAG_E2E is set. +*/ + nhi->quirks |=QUIRK_E2E ; +break ; + } + } }static int nhi_check_iommu_pdev (struct pci_dev *pdev,void *data)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 567/717 x86/apic: Dont disable x2APIC if locked
In reply to Greg Kroah-HartmanFrom: Daniel Sneddon <[email protected]>
[ Upstream commit b8d1d163604bd1e600b062fb00de5dc42baa355f ]
The APIC supports two modes, legacy APIC (or xAPIC), and Extended APIC (or x2APIC). X2APIC mode is mostly compatible with legacy APIC, but it disables the memory-mapped APIC interface in favor of one that uses MSRs. The APIC mode is controlled by the EXT bit in the APIC MSR.
The MMIO/xAPIC interface has some problems, most notably the APIC LEAK [1]. This bug allows an attacker to use the APIC MMIO interface to extract data from the SGX enclave.
Introduce support for a new feature that will allow the BIOS to lock the APIC in x2APIC mode. If the APIC is locked in x2APIC mode and the kernel tries to disable the APIC or revert to legacy APIC mode a GP fault will occur.
Introduce support for a new MSR (IA32_XAPIC_DISABLE_STATUS) and handle the new locked mode when the LEGACY_XAPIC_DISABLED bit is set by preventing the kernel from trying to disable the x2APIC.
On platforms with the IA32_XAPIC_DISABLE_STATUS MSR, if SGX or TDX are enabled the LEGACY_XAPIC_DISABLED will be set by the BIOS. If legacy APIC is required, then it SGX and TDX need to be disabled in the BIOS.
[1]: https://aepicleak.com/aepicleak.pdf
--- .../admin-guide/kernel-parameters.txt | 4 ++ arch/x86/Kconfig | 7 ++- arch/x86/include/asm/cpu.h | 2 + arch/x86/include/asm/msr-index.h | 13 ++++++ arch/x86/kernel/apic/apic.c | 44 +++++++++++++++++-- 5 files changed, 65 insertions(+), 5 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +4 -0
@@ -3765,6 +3765,10 @@ nox2apic [X86-64,APIC] Do not enable x2APIC mode. + NOTE: this parameter will be ignored on systems with the + LEGACY_XAPIC_DISABLED bit set in the + IA32_XAPIC_DISABLE_STATUS MSR. + nps_mtm_hs_ctr= [KNL,ARC] This parameter sets the maximum duration, in cycles, each HW thread of the CTOP can run
arch/x86/Kconfig +6 -1
@@ -450,6 +450,11 @@ config X86_X2APIC This allows 32-bit apic IDs (so it can support very large systems), and accesses the local apic via MSRs not via mmio. + Some Intel systems circa 2022 and later are locked into x2APIC mode + and can not fall back to the legacy APIC modes if SGX or TDX are + enabled in the BIOS. They will be unable to boot without enabling + this option. + If you don't know what to do here, say N. config X86_MPPARSE
@@ -1930,7 +1935,7 @@ endchoice config X86_SGX bool "Software Guard eXtensions (SGX)" - depends on X86_64 && CPU_SUP_INTEL + depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC depends on CRYPTO=y depends on CRYPTO_SHA256=y select SRCU
arch/x86/include/asm/cpu.h +2 -0
@@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1, return p1 & p2; } +extern u64 x86_read_arch_cap_msr (void ); +#endif /* _ASM_X86_CPU_H */
arch/x86/include/asm/msr-index.h +13 -0
@@ -155,6 +155,11 @@* Return Stack Buffer Predictions. */ +#define ARCH_CAP_XAPIC_DISABLE BIT(21)/* +* IA32_XAPIC_DISABLE_STATUS MSR +* supported +*/ +#define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/* * Writeback and invalidate the
@@ -1046,4 +1051,12 @@#define MSR_IA32_HW_FEEDBACK_PTR 0x17d0#define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1 +/* x2APIC locked status */ +#define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD +#define LEGACY_XAPIC_DISABLED BIT(0)/* +* x2APIC mode is locked and +* disabling x2APIC will cause +* a #GP +*/ +#endif /* _ASM_X86_MSR_INDEX_H */
arch/x86/kernel/apic/apic.c +40 -4
86 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 568/717 net: axienet: Switch to 64-bit RX/TX statistics
In reply to Greg Kroah-HartmanFrom: Robert Hancock <[email protected]>
[ Upstream commit cb45a8bf4693965e89d115cd2c510f12bc127c37 ]
The RX and TX byte/packet statistics in this driver could be overflowed relatively quickly on a 32-bit platform. Switch these stats to use the u64_stats infrastructure to avoid this.
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 12 ++++++ .../net/ethernet/xilinx/xilinx_axienet_main.c | 37 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +12 -0
@@ -402,6 +402,9 @@ struct axidma_bd {* @rx_bd_num: Size of RX buffer descriptor ring * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being * accessed currently. +* @rx_packets: RX packet count for statistics +* @rx_bytes: RX byte count for statistics +* @rx_stat_sync: Synchronization object for RX stats * @napi_tx: NAPI TX control structure * @tx_dma_cr: Nominal content of TX DMA control register * @tx_bd_v: Virtual address of the TX buffer descriptor ring
@@ -411,6 +414,9 @@ struct axidma_bd {* complete. Only updated at runtime by TX NAPI poll. * @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring * to be populated. +* @tx_packets: TX packet count for statistics +* @tx_bytes: TX byte count for statistics +* @tx_stat_sync: Synchronization object for TX stats * @dma_err_task: Work structure to process Axi DMA errors * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number
@@ -458,6 +464,9 @@ struct axienet_local {dma_addr_t rx_bd_p;u32 rx_bd_num;u32 rx_bd_ci; +u64_stats_t rx_packets; +u64_stats_t rx_bytes; +struct u64_stats_sync rx_stat_sync;struct napi_struct napi_tx;u32 tx_dma_cr;
@@ -466,6 +475,9 @@ struct axienet_local {u32 tx_bd_num;u32 tx_bd_ci;u32 tx_bd_tail; +u64_stats_t tx_packets; +u64_stats_t tx_bytes; +struct u64_stats_sync tx_stat_sync;struct work_struct dma_err_task;
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +33 -4
@@ -752,8 +752,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)if (lp->tx_bd_ci >= lp->tx_bd_num) lp->tx_bd_ci %= lp->tx_bd_num; - ndev->stats.tx_packets += packets; - ndev->stats.tx_bytes += size; +u64_stats_update_begin (&lp->tx_stat_sync); +u64_stats_add (&lp->tx_packets, packets); +u64_stats_add (&lp->tx_bytes, size); +u64_stats_update_end (&lp->tx_stat_sync);/* Matches barrier in axienet_start_xmit */ smp_mb ();
@@ -984,8 +986,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget) cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; } - lp->ndev->stats.rx_packets += packets; - lp->ndev->stats.rx_bytes += size; +u64_stats_update_begin (&lp->rx_stat_sync); +u64_stats_add (&lp->rx_packets, packets); +u64_stats_add (&lp->rx_bytes, size); +u64_stats_update_end (&lp->rx_stat_sync);if (tail_p)axienet_dma_out_addr (lp,XAXIDMA_RX_TDESC_OFFSET , tail_p);
@@ -1292,10 +1296,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)return phylink_mii_ioctl (lp->phylink, rq, cmd); } +static void +axienet_get_stats64 (struct net_device *dev,struct rtnl_link_stats64 *stats) +{ +struct axienet_local *lp =netdev_priv (dev); +unsigned int start; + +netdev_stats_to_stats64 (stats, &dev->stats); + +do { + start =u64_stats_fetch_begin_irq (&lp->rx_stat_sync); + stats->rx_packets =u64_stats_read (&lp->rx_packets); + stats->rx_bytes =u64_stats_read (&lp->rx_bytes); + }while (u64_stats_fetch_retry_irq (&lp->rx_stat_sync, start)); + +do { + start =u64_stats_fetch_begin_irq (&lp->tx_stat_sync); + stats->tx_packets =u64_stats_read (&lp->tx_packets); + stats->tx_bytes =u64_stats_read (&lp->tx_bytes); + }while (u64_stats_fetch_retry_irq (&lp->tx_stat_sync, start)); +} +static const struct net_device_ops axienet_netdev_ops = { .ndo_open = axienet_open, .ndo_stop = axienet_stop, .ndo_start_xmit = axienet_start_xmit, + .ndo_get_stats64 = axienet_get_stats64, .ndo_change_mtu = axienet_change_mtu, .ndo_set_mac_address = netdev_set_mac_address, .ndo_validate_addr = eth_validate_addr,
@@ -1850,6 +1876,9 @@ static int axienet_probe(struct platform_device *pdev) lp->rx_bd_num =RX_BD_NUM_DEFAULT ; lp->tx_bd_num =TX_BD_NUM_DEFAULT ; +u64_stats_init (&lp->rx_stat_sync); +u64_stats_init (&lp->tx_stat_sync); +netif_napi_add (ndev, &lp->napi_rx, axienet_rx_poll,NAPI_POLL_WEIGHT );netif_napi_add (ndev, &lp->napi_tx, axienet_tx_poll,NAPI_POLL_WEIGHT );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 569/717 net-next: Fix IP_UNICAST_IF option behavior for connected sockets
In reply to Greg Kroah-HartmanFrom: Richard Gobert <[email protected]>
[ Upstream commit 0e4d354762cefd3e16b4cff8988ff276e45effc4 ]
The IP_UNICAST_IF socket option is used to set the outgoing interface for outbound packets.
The IP_UNICAST_IF socket option was added as it was needed by the Wine project, since no other existing option (SO_BINDTODEVICE socket option, IP_PKTINFO socket option or the bind function) provided the needed characteristics needed by the IP_UNICAST_IF socket option. [1] The IP_UNICAST_IF socket option works well for unconnected sockets, that is, the interface specified by the IP_UNICAST_IF socket option is taken into consideration in the route lookup process when a packet is being sent. However, for connected sockets, the outbound interface is chosen when connecting the socket, and in the route lookup process which is done when a packet is being sent, the interface specified by the IP_UNICAST_IF socket option is being ignored.
This inconsistent behavior was reported and discussed in an issue opened on systemd's GitHub project [2]. Also, a bug report was submitted in the kernel's bugzilla [3].
To understand the problem in more detail, we can look at what happens for UDP packets over IPv4 (The same analysis was done separately in the referenced systemd issue).
When a UDP packet is sent the udp_sendmsg function gets called and the following happens:
1. The oif member of the struct ipcm_cookie ipc (which stores the output interface of the packet) is initialized by the ipcm_init_sk function to inet->sk.sk_bound_dev_if (the device set by the SO_BINDTODEVICE socket option).
2. If the IP_PKTINFO socket option was set, the oif member gets overridden by the call to the ip_cmsg_send function.
3. If no output interface was selected yet, the interface specified by the IP_UNICAST_IF socket option is used.
4. If the socket is connected and no destination address is specified in the send function, the struct ipcm_cookie ipc is not taken into consideration and the cached route, that was calculated in the connect function is being used.
Thus, for a connected socket, the IP_UNICAST_IF sockopt isn't taken into consideration.
This patch corrects the behavior of the IP_UNICAST_IF socket option for connect()ed sockets by taking into consideration the IP_UNICAST_IF sockopt when connecting the socket.
In order to avoid reconnecting the socket, this option is still ignored when applied on an already connected socket until connect() is called again by the Richard Gobert.
Change the __ip4_datagram_connect function, which is called during socket connection, to take into consideration the interface set by the IP_UNICAST_IF socket option, in a similar way to what is done in the udp_sendmsg function.
[1] https://lore.kernel.org/netdev/1328685717.4736.4.camel@edumazet-laptop/T/
[2] https://github.com/systemd/systemd/issues/11935#issuecomment-618691018
[3] https://bugzilla.kernel.org/show_bug.cgi?id=210255
--- net/ipv4/datagram.c | 2 ++ tools/testing/selftests/net/fcnal-test.sh | 30 +++++++++++++++++++++++ tools/testing/selftests/net/nettest.c | 16 ++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-)
net/ipv4/datagram.c +2 -0
@@ -42,6 +42,8 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len oif = inet->mc_index;if (!saddr) saddr = inet->mc_addr; + }else if (!oif) { + oif = inet->uc_index; } fl4 = &inet->cork.fl.u.ip4; rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr, oif,
tools/testing/selftests/net/fcnal-test.sh +30 -0
@@ -1466,6 +1466,13 @@ ipv4_udp_novrf() run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF" + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} -U + log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF, with connect()" + + log_start show_hint "Should fail 'Connection refused'" run_cmd nettest -D -r ${a}
@@ -1525,6 +1532,13 @@ ipv4_udp_novrf() run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection" + log_start + run_cmd nettest -s -D & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} -U + log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection, with connect()" + + # IPv4 with device bind has really weird behavior - it overrides the # fib lookup, generates an rtable and tries to send the packet. This # causes failures for local traffic at different places
@@ -1550,6 +1564,15 @@ ipv4_udp_novrf() sleep 1 run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection" + + log_start + show_hint "Should fail since addresses on loopback are out of device scope" + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -U + log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()" + + done a=${NSA_IP}
@@ -3157,6 +3180,13 @@ ipv6_udp_novrf() sleep 1 run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection" + + log_start + show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S -U + log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()" done a=${NSA_IP6}
tools/testing/selftests/net/nettest.c +14 -2
@@ -127,6 +127,9 @@ struct sock_args {/* ESP in UDP encap test */ int use_xfrm; + +/* use send() and connect() instead of sendto */ +int datagram_connect; };static int server_mode;
@@ -979,6 +982,11 @@ static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)log_err_errno ("write failed sending msg to peer" );return 1 ; } + }else if (args->datagram_connect) { +if (send (sd, msg, msglen,0 ) <0 ) { +log_err_errno ("send failed sending msg to peer" ); +return 1 ; + } }else if (args->ifindex && args->use_cmsg) {if (send_msg_cmsg (sd, addr, alen, args->ifindex, args->version))return 1 ;
@@ -1659,7 +1667,7 @@ static int connectsock(void *addr, socklen_t alen, struct sock_args *args)if (args->has_local_ip &&bind_socket (sd, args)) goto err; -if (args->type !=SOCK_STREAM ) +if (args->type !=SOCK_STREAM && !args->datagram_connect) goto out;if (args->password &&tcp_md5sig (sd, addr, alen, args))
@@ -1854,7 +1862,7 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)return client_status; } -#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf" +#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SUCi6xL:0:1:2:3:Fbqf"#define OPT_FORCE_BIND_KEY_IFINDEX 1001#define OPT_NO_BIND_KEY_IFINDEX 1002
@@ -1891,6 +1899,7 @@ static void print_usage(char *prog)" -I dev bind socket to given device name - server mode\n" " -S use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n" " to set device binding\n" +" -U Use connect() and send() for datagram sockets\n" " -f bind socket with the IP[V6]_FREEBIND option\n" " -C use cmsg and IP_PKTINFO to specify device binding\n" "\n"
@@ -2074,6 +2083,9 @@ int main(int argc, char *argv[])case 'x' : args.use_xfrm =1 ;break ; +case 'U' : + args.datagram_connect =1 ; +break ;default :print_usage (argv[0 ]);return 1 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 570/717 xfrm: Update ipcomp_scratches with NULL when freed
In reply to Greg Kroah-HartmanFrom: Khalid Masum <[email protected]>
[ Upstream commit 8a04d2fc700f717104bfb95b0f6694e448a4537f ]
Currently if ipcomp_alloc_scratches() fails to allocate memory ipcomp_scratches holds obsolete address. So when we try to free the percpu scratches using ipcomp_free_scratches() it tries to vfree non existent vm area. Described below:
static void * __percpu *ipcomp_alloc_scratches(void)
{
...
scratches = alloc_percpu(void *);
if (!scratches)
return NULL;
ipcomp_scratches does not know about this allocation failure.
Therefore holding the old obsolete address.
...
}So when we free,
static void ipcomp_free_scratches(void)
{
...
scratches = ipcomp_scratches;Assigning obsolete address from ipcomp_scratches
if (!scratches)
return;
for_each_possible_cpu(i)
vfree(*per_cpu_ptr(scratches, i));
Trying to free non existent page, causing warning: trying to vfree
existent vm area.
...
}Fix this breakage by updating ipcomp_scrtches with NULL when scratches is freed
--- net/xfrm/xfrm_ipcomp.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_ipcomp.c +1 -0
@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)vfree (*per_cpu_ptr (scratches, i));free_percpu (scratches); + ipcomp_scratches =NULL ; }static void *__percpu *ipcomp_alloc_scratches (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 571/717 wifi: ath11k: Register shutdown handler for WCN6750
In reply to Greg Kroah-HartmanFrom: Manikanta Pubbisetty <[email protected]>
[ Upstream commit ac41c2b642b136a1e633379fcb87a9db0ee07f5b ]
When the system shuts down, SMMU driver will be stopped and will not assist in IOVA translations. SMMU driver expects all of its consumers to shutdown before shutting down itself. WCN6750 being one of the consumer device should not perform any DMA operations after the SMMU has shutdown which will otherwise result in SMMU faults.
SMMU driver will call the shutdown() callback of all its consumer devices and the consumers shall stop further DMA activity after the invocation of their respective shutdown() callbacks.
Register the shutdown() callback to the platform core for WCN6750. Change will not impact other AHB ath11k devices.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
--- drivers/net/wireless/ath/ath11k/ahb.c | 58 ++++++++++++++++++++------ drivers/net/wireless/ath/ath11k/core.c | 2 + 2 files changed, 47 insertions(+), 13 deletions(-)
drivers/net/wireless/ath/ath11k/ahb.c +45 -13
@@ -1088,20 +1088,10 @@ static int ath11k_ahb_probe(struct platform_device *pdev)return ret; } -static int ath11k_ahb_remove (struct platform_device *pdev) +static void ath11k_ahb_remove_prepare (struct ath11k_base *ab) { -struct ath11k_base *ab =platform_get_drvdata (pdev);unsigned long left; -if (test_bit (ATH11K_FLAG_QMI_FAIL , &ab->dev_flags)) { -ath11k_ahb_power_down (ab); -ath11k_debugfs_soc_destroy (ab); -ath11k_qmi_deinit_service (ab); - goto qmi_fail; - } - -reinit_completion (&ab->driver_recovery); -if (test_bit (ATH11K_FLAG_RECOVERY , &ab->dev_flags)) { left =wait_for_completion_timeout (&ab->driver_recovery,ATH11K_AHB_RECOVERY_TIMEOUT );
@@ -1111,19 +1101,60 @@ static int ath11k_ahb_remove(struct platform_device *pdev)set_bit (ATH11K_FLAG_UNREGISTERING , &ab->dev_flags);cancel_work_sync (&ab->restart_work); +cancel_work_sync (&ab->qmi.event_work); +} + +static void ath11k_ahb_free_resources (struct ath11k_base *ab) +{ +struct platform_device *pdev = ab->pdev; -ath11k_core_deinit (ab); -qmi_fail:ath11k_ahb_free_irq (ab);ath11k_hal_srng_deinit (ab);ath11k_ahb_fw_resource_deinit (ab);ath11k_ce_free_pipes (ab);ath11k_core_free (ab);platform_set_drvdata (pdev,NULL ); +} + +static int ath11k_ahb_remove (struct platform_device *pdev) +{ +struct ath11k_base *ab =platform_get_drvdata (pdev); + +if (test_bit (ATH11K_FLAG_QMI_FAIL , &ab->dev_flags)) { +ath11k_ahb_power_down (ab); +ath11k_debugfs_soc_destroy (ab); +ath11k_qmi_deinit_service (ab); + goto qmi_fail; + } + +ath11k_ahb_remove_prepare (ab); +ath11k_core_deinit (ab); + +qmi_fail: +ath11k_ahb_free_resources (ab);return 0 ; } +static void ath11k_ahb_shutdown (struct platform_device *pdev) +{ +struct ath11k_base *ab =platform_get_drvdata (pdev); + +/* platform shutdown() & remove() are mutually exclusive. +* remove() is invoked during rmmod & shutdown() during +* system reboot/shutdown. +*/ +ath11k_ahb_remove_prepare (ab); + +if (!(test_bit (ATH11K_FLAG_REGISTERED , &ab->dev_flags))) + goto free_resources; + +ath11k_core_deinit (ab); + +free_resources: +ath11k_ahb_free_resources (ab); +} +static struct platform_driver ath11k_ahb_driver = { .driver = { .name ="ath11k" ,
@@ -1131,6 +1162,7 @@ static struct platform_driver ath11k_ahb_driver = { }, .probe = ath11k_ahb_probe, .remove = ath11k_ahb_remove, + .shutdown = ath11k_ahb_shutdown, };static int ath11k_ahb_init (void )
drivers/net/wireless/ath/ath11k/core.c +2 -0
@@ -1635,6 +1635,8 @@ static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)wake_up (&ab->wmi_ab.tx_credits_wq);wake_up (&ab->peer_mapping_wq); + +reinit_completion (&ab->driver_recovery); }static void ath11k_core_post_reconfigure_recovery (struct ath11k_base *ab)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 572/717 rtw89: ser: leave lps with mutex
In reply to Greg Kroah-HartmanFrom: Zong-Zhe Yang <[email protected]>
[ Upstream commit 8676031bae1c91037d06341214f4150b33707c68 ]
Calling rtw89_leave_lps() should hold rtwdev::mutex. So, fix it.
--- drivers/net/wireless/realtek/rtw89/ser.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/realtek/rtw89/ser.c +3 -0
@@ -152,7 +152,10 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)rtw89_debug (rtwdev,RTW89_DBG_SER ,"ser: %s receive %s\n" ,ser_st_name (ser),ser_ev_name (ser, evt)); +mutex_lock (&rtwdev->mutex);rtw89_leave_lps (rtwdev); +mutex_unlock (&rtwdev->mutex); + ser->st_tbl[ser->state].st_func (ser, evt); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 573/717 iavf: Fix race between iavf_close and iavf_reset_task
In reply to Greg Kroah-HartmanFrom: Michal Jaron <[email protected]>
[ Upstream commit 11c12adcbc1598d91e73ab6ddfa41d25a01478ed ]
During stress tests with adding VF to namespace and changing vf's trust there was a race between iavf_reset_task and iavf_close. Sometimes when IAVF_FLAG_AQ_DISABLE_QUEUES from iavf_close was sent to PF after reset and before IAVF_AQ_GET_CONFIG was sent then PF returns error IAVF_NOT_SUPPORTED to disable queues request and following requests. There is need to get_config before other aq_required will be send but iavf_close clears all flags, if get_config was not sent before iavf_close, then it will not be send at all.
In case when IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS was sent before IAVF_FLAG_AQ_DISABLE_QUEUES then there was rtnl_lock deadlock between iavf_close and iavf_adminq_task until iavf_close timeouts and disable queues was sent after iavf_close ends.
There was also a problem with sending delete/add filters. Sometimes when filters was not yet added to PF and in iavf_close all filters was set to remove there might be a try to remove nonexistent filters on PF.
Add aq_required_tmp to save aq_required flags and send them after disable_queues will be handled. Clear flags given to iavf_down different than IAVF_FLAG_AQ_GET_CONFIG as this flag is necessary to sent other aq_required. Remove some flags that we don't want to send as we are in iavf_close and we want to disable interface. Remove filters which was not yet sent and send del filters flags only when there are filters to remove.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 177 ++++++++++++++++---- 1 file changed, 141 insertions(+), 36 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +141 -36
@@ -1184,66 +1184,138 @@ static void iavf_up_complete(struct iavf_adapter *adapter) }/** -* iavf_down - Shutdown the connection processing +* iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF +* yet and mark other to be removed. * @adapter: board private structure -* -* Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock. **/ -void iavf_down (struct iavf_adapter *adapter) +static void iavf_clear_mac_vlan_filters (struct iavf_adapter *adapter) { -struct net_device *netdev = adapter->netdev; -struct iavf_vlan_filter *vlf; -struct iavf_cloud_filter *cf; -struct iavf_fdir_fltr *fdir; -struct iavf_mac_filter *f; -struct iavf_adv_rss *rss; - -if (adapter->state <= __IAVF_DOWN_PENDING) -return ; - -netif_carrier_off (netdev); -netif_tx_disable (netdev); - adapter->link_up = false; -iavf_napi_disable_all (adapter); -iavf_irq_disable (adapter); +struct iavf_vlan_filter *vlf, *vlftmp; +struct iavf_mac_filter *f, *ftmp;spin_lock_bh (&adapter->mac_vlan_list_lock); -/* clear the sync flag on all filters */ __dev_uc_unsync (adapter->netdev,NULL );__dev_mc_unsync (adapter->netdev,NULL );/* remove all MAC filters */ -list_for_each_entry (f, &adapter->mac_filter_list, list) { - f->remove = true; +list_for_each_entry_safe (f, ftmp, &adapter->mac_filter_list, + list) { +if (f->add) { +list_del (&f->list); +kfree (f); + }else { + f->remove = true; + } }/* remove all VLAN filters */ -list_for_each_entry (vlf, &adapter->vlan_filter_list, list) { - vlf->remove = true; +list_for_each_entry_safe (vlf, vlftmp, &adapter->vlan_filter_list, + list) { +if (vlf->add) { +list_del (&vlf->list); +kfree (vlf); + }else { + vlf->remove = true; + } } -spin_unlock_bh (&adapter->mac_vlan_list_lock); +} + +/** +* iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and +* mark other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_cloud_filters (struct iavf_adapter *adapter) +{ +struct iavf_cloud_filter *cf, *cftmp;/* remove all cloud filters */ spin_lock_bh (&adapter->cloud_filter_list_lock); -list_for_each_entry (cf, &adapter->cloud_filter_list, list) { - cf->del = true; +list_for_each_entry_safe (cf, cftmp, &adapter->cloud_filter_list, + list) { +if (cf->add) { +list_del (&cf->list); +kfree (cf); + adapter->num_cloud_filters--; + }else { + cf->del = true; + } }spin_unlock_bh (&adapter->cloud_filter_list_lock); +} + +/** +* iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark +* other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_fdir_filters (struct iavf_adapter *adapter) +{ +struct iavf_fdir_fltr *fdir, *fdirtmp;/* remove all Flow Director filters */ spin_lock_bh (&adapter->fdir_fltr_lock); -list_for_each_entry (fdir, &adapter->fdir_list_head, list) { - fdir->state =IAVF_FDIR_FLTR_DEL_REQUEST ; +list_for_each_entry_safe (fdir, fdirtmp, &adapter->fdir_list_head, + list) { +if (fdir->state ==IAVF_FDIR_FLTR_ADD_REQUEST ) { +list_del (&fdir->list); +kfree (fdir); + adapter->fdir_active_fltr--; + }else { + fdir->state =IAVF_FDIR_FLTR_DEL_REQUEST ; + } }spin_unlock_bh (&adapter->fdir_fltr_lock); +} + +/** +* iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark +* other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_adv_rss_conf (struct iavf_adapter *adapter) +{ +struct iavf_adv_rss *rss, *rsstmp;/* remove all advance RSS configuration */ spin_lock_bh (&adapter->adv_rss_lock); -list_for_each_entry (rss, &adapter->adv_rss_list_head, list) - rss->state =IAVF_ADV_RSS_DEL_REQUEST ; +list_for_each_entry_safe (rss, rsstmp, &adapter->adv_rss_list_head, + list) { +if (rss->state ==IAVF_ADV_RSS_ADD_REQUEST ) { +list_del (&rss->list); +kfree (rss); + }else { + rss->state =IAVF_ADV_RSS_DEL_REQUEST ; + } + }spin_unlock_bh (&adapter->adv_rss_lock); +} + +/** +* iavf_down - Shutdown the connection processing +* @adapter: board private structure +* +* Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock. +**/ +void iavf_down (struct iavf_adapter *adapter) +{ +struct net_device *netdev = adapter->netdev; + +if (adapter->state <= __IAVF_DOWN_PENDING) +return ; + +netif_carrier_off (netdev); +netif_tx_disable (netdev); + adapter->link_up = false; +iavf_napi_disable_all (adapter); +iavf_irq_disable (adapter); + +iavf_clear_mac_vlan_filters (adapter); +iavf_clear_cloud_filters (adapter); +iavf_clear_fdir_filters (adapter); +iavf_clear_adv_rss_conf (adapter);if (!(adapter->flags &IAVF_FLAG_PF_COMMS_FAILED )) {/* cancel any current operation */
@@ -1252,11 +1324,16 @@ void iavf_down(struct iavf_adapter *adapter)* here for this to complete. The watchdog is still running * and it will take care of this. */ - adapter->aq_required =IAVF_FLAG_AQ_DEL_MAC_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_FDIR_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_ADV_RSS_CFG ; +if (!list_empty (&adapter->mac_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_MAC_FILTER ; +if (!list_empty (&adapter->vlan_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ; +if (!list_empty (&adapter->cloud_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ; +if (!list_empty (&adapter->fdir_list_head)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_FDIR_FILTER ; +if (!list_empty (&adapter->adv_rss_list_head)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_ADV_RSS_CFG ; adapter->aq_required |=IAVF_FLAG_AQ_DISABLE_QUEUES ; }
@@ -4082,6 +4159,7 @@ static int iavf_open(struct net_device *netdev)static int iavf_close (struct net_device *netdev) {struct iavf_adapter *adapter =netdev_priv (netdev); +u64 aq_to_restore;int status;mutex_lock (&adapter->crit_lock);
@@ -4094,6 +4172,29 @@ static int iavf_close(struct net_device *netdev)set_bit (__IAVF_VSI_DOWN, adapter->vsi.state);if (CLIENT_ENABLED (adapter)) adapter->flags |=IAVF_FLAG_CLIENT_NEEDS_CLOSE ; +/* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before +* IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl +* deadlock with adminq_task() until iavf_close timeouts. We must send +* IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make +* disable queues possible for vf. Give only necessary flags to +* iavf_down and save other to set them right before iavf_close() +* returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and +* iavf will be in DOWN state. +*/ + aq_to_restore = adapter->aq_required; + adapter->aq_required &=IAVF_FLAG_AQ_GET_CONFIG ; + +/* Remove flags which we do not want to send after close or we want to +* send before disable queues. +*/ + aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG | +IAVF_FLAG_AQ_ENABLE_QUEUES | +IAVF_FLAG_AQ_CONFIGURE_QUEUES | +IAVF_FLAG_AQ_ADD_VLAN_FILTER | +IAVF_FLAG_AQ_ADD_MAC_FILTER | +IAVF_FLAG_AQ_ADD_CLOUD_FILTER | +IAVF_FLAG_AQ_ADD_FDIR_FILTER | +IAVF_FLAG_AQ_ADD_ADV_RSS_CFG );iavf_down (adapter);iavf_change_state (adapter, __IAVF_DOWN_PENDING);
@@ -4117,6 +4218,10 @@ static int iavf_close(struct net_device *netdev) msecs_to_jiffies(500));if (!status)netdev_warn (netdev,"Device resources not yet released\n" ); + +mutex_lock (&adapter->crit_lock); + adapter->aq_required |= aq_to_restore; +mutex_unlock (&adapter->crit_lock);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 574/717 wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit()
In reply to Greg Kroah-HartmanFrom: Alexander Coffin <[email protected]>
[ Upstream commit 3f42faf6db431e04bf942d2ebe3ae88975723478 ]
Quoted 1 line
ret =
brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
may be schedule, and then complete before the line
Quoted 1 line
ndev->stats.tx_bytes+=skb->len;
[ 46.912801] ================================================================== [ 46.920552] BUG: KASAN: use-after-free in brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.928673] Read of size 4 at addr ffffff803f5882e8 by task systemd-resolve/328 [ 46.935991] [ 46.937514] CPU: 1 PID: 328 Comm: systemd-resolve Tainted: G O 5.4.199-[REDACTED] #1 [ 46.947255] Hardware name: [REDACTED] [ 46.954568] Call trace: [ 46.957037] dump_backtrace+0x0/0x2b8 [ 46.960719] show_stack+0x24/0x30 [ 46.964052] dump_stack+0x128/0x194 [ 46.967557] print_address_description.isra.0+0x64/0x380 [ 46.972877] __kasan_report+0x1d4/0x240 [ 46.976723] kasan_report+0xc/0x18 [ 46.980138] __asan_report_load4_noabort+0x18/0x20 [ 46.985027] brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.990613] dev_hard_start_xmit+0x1bc/0xda0 [ 46.994894] sch_direct_xmit+0x198/0xd08 [ 46.998827] __qdisc_run+0x37c/0x1dc0 [ 47.002500] __dev_queue_xmit+0x1528/0x21f8 [ 47.006692] dev_queue_xmit+0x24/0x30 [ 47.010366] neigh_resolve_output+0x37c/0x678 [ 47.014734] ip_finish_output2+0x598/0x2458 [ 47.018927] __ip_finish_output+0x300/0x730 [ 47.023118] ip_output+0x2e0/0x430 [ 47.026530] ip_local_out+0x90/0x140 [ 47.030117] igmpv3_sendpack+0x14c/0x228 [ 47.034049] igmpv3_send_cr+0x384/0x6b8 [ 47.037895] igmp_ifc_timer_expire+0x4c/0x118 [ 47.042262] call_timer_fn+0x1cc/0xbe8 [ 47.046021] __run_timers+0x4d8/0xb28 [ 47.049693] run_timer_softirq+0x24/0x40 [ 47.053626] __do_softirq+0x2c0/0x117c [ 47.057387] irq_exit+0x2dc/0x388 [ 47.060715] __handle_domain_irq+0xb4/0x158 [ 47.064908] gic_handle_irq+0x58/0xb0 [ 47.068581] el0_irq_naked+0x50/0x5c [ 47.072162] [ 47.073665] Allocated by task 328: [ 47.077083] save_stack+0x24/0xb0 [ 47.080410] __kasan_kmalloc.isra.0+0xc0/0xe0 [ 47.084776] kasan_slab_alloc+0x14/0x20 [ 47.088622] kmem_cache_alloc+0x15c/0x468 [ 47.092643] __alloc_skb+0xa4/0x498 [ 47.096142] igmpv3_newpack+0x158/0xd78 [ 47.099987] add_grhead+0x210/0x288 [ 47.103485] add_grec+0x6b0/0xb70 [ 47.106811] igmpv3_send_cr+0x2e0/0x6b8 [ 47.110657] igmp_ifc_timer_expire+0x4c/0x118 [ 47.115027] call_timer_fn+0x1cc/0xbe8 [ 47.118785] __run_timers+0x4d8/0xb28 [ 47.122457] run_timer_softirq+0x24/0x40 [ 47.126389] __do_softirq+0x2c0/0x117c [ 47.130142] [ 47.131643] Freed by task 180: [ 47.134712] save_stack+0x24/0xb0 [ 47.138041] __kasan_slab_free+0x108/0x180 [ 47.142146] kasan_slab_free+0x10/0x18 [ 47.145904] slab_free_freelist_hook+0xa4/0x1b0 [ 47.150444] kmem_cache_free+0x8c/0x528 [ 47.154292] kfree_skbmem+0x94/0x108 [ 47.157880] consume_skb+0x10c/0x5a8 [ 47.161466] __dev_kfree_skb_any+0x88/0xa0 [ 47.165598] brcmu_pkt_buf_free_skb+0x44/0x68 [brcmutil] [ 47.171023] brcmf_txfinalize+0xec/0x190 [brcmfmac] [ 47.176016] brcmf_proto_bcdc_txcomplete+0x1c0/0x210 [brcmfmac] [ 47.182056] brcmf_sdio_sendfromq+0x8dc/0x1e80 [brcmfmac] [ 47.187568] brcmf_sdio_dpc+0xb48/0x2108 [brcmfmac] [ 47.192529] brcmf_sdio_dataworker+0xc8/0x238 [brcmfmac] [ 47.197859] process_one_work+0x7fc/0x1a80 [ 47.201965] worker_thread+0x31c/0xc40 [ 47.205726] kthread+0x2d8/0x370 [ 47.208967] ret_from_fork+0x10/0x18 [ 47.212546] [ 47.214051] The buggy address belongs to the object at ffffff803f588280 [ 47.214051] which belongs to the cache skbuff_head_cache of size 208 [ 47.227086] The buggy address is located 104 bytes inside of [ 47.227086] 208-byte region [ffffff803f588280, ffffff803f588350) [ 47.238814] The buggy address belongs to the page: [ 47.243618] page:ffffffff00dd6200 refcount:1 mapcount:0 mapping:ffffff804b6bf800 index:0xffffff803f589900 compound_mapcount: 0 [ 47.255007] flags: 0x10200(slab|head) [ 47.258689] raw: 0000000000010200 ffffffff00dfa980 0000000200000002 ffffff804b6bf800 [ 47.266439] raw: ffffff803f589900 0000000080190018 00000001ffffffff 0000000000000000 [ 47.274180] page dumped because: kasan: bad access detected [ 47.279752] [ 47.281251] Memory state around the buggy address: [ 47.286051] ffffff803f588180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.293277] ffffff803f588200: fb fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 47.300502] >ffffff803f588280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.307723] ^ [ 47.314343] ffffff803f588300: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc [ 47.321569] ffffff803f588380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb [ 47.328789] ==================================================================
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +2 -1
@@ -296,6 +296,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,struct brcmf_pub *drvr = ifp->drvr;struct ethhdr *eh;int head_delta; +unsigned int tx_bytes = skb->len;brcmf_dbg (DATA ,"Enter, bsscfgidx=%d\n" , ifp->bsscfgidx);
@@ -370,7 +371,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, ndev->stats.tx_dropped++; }else { ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += tx_bytes; }/* Return ok: we always eat the packet */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 575/717 Bluetooth: btintel: Mark Intel controller to support LE_STATES quirk
In reply to Greg Kroah-HartmanFrom: Kiran K <[email protected]>
[ Upstream commit dd0a1794f4334ddbf9b7c5e7d642aaffff38c69b ]
HarrrisonPeak, CyclonePeak, SnowFieldPeak and SandyPeak controllers are marked to support HCI_QUIRK_LE_STATES.
--- drivers/bluetooth/btintel.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/bluetooth/btintel.c +8 -9
@@ -2439,15 +2439,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) INTEL_ROM_LEGACY_NO_WBS_SUPPORT)) set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); +if (ver.hw_variant ==0x08 && ver.fw_variant ==0x22 ) +set_bit (HCI_QUIRK_VALID_LE_STATES , + &hdev->quirks); err =btintel_legacy_rom_setup (hdev, &ver);break ;case 0x0b :/* SfP */ -case 0x0c :/* WsP */ case 0x11 :/* JfP */ case 0x12 :/* ThP */ case 0x13 :/* HrP */ case 0x14 :/* CcP */ +set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks); + fallthrough; +case 0x0c :/* WsP */ /* Apply the device specific HCI quirks * * All Legacy bootloader devices support WBS
@@ -2455,11 +2460,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks); -/* Valid LE States quirk for JfP/ThP familiy */ -if (ver.hw_variant ==0x11 || ver.hw_variant ==0x12 ) -set_bit (HCI_QUIRK_VALID_LE_STATES , - &hdev->quirks); -/* Setup MSFT Extension support */ btintel_set_msft_opcode (hdev, ver.hw_variant);
@@ -2530,9 +2530,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)*/ set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks); -/* Valid LE States quirk for JfP/ThP familiy */ -if (ver.hw_variant ==0x11 || ver.hw_variant ==0x12 ) -set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks); +/* Set Valid LE States quirk */ +set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks);/* Setup MSFT Extension support */ btintel_set_msft_opcode (hdev, ver.hw_variant);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 576/717 regulator: core: Prevent integer underflow
In reply to Greg Kroah-HartmanFrom: Patrick Rudolph <[email protected]>
[ Upstream commit 8d8e16592022c9650df8aedfe6552ed478d7135b ]
By using a ratio of delay to poll_enabled_time that is not integer time_remaining underflows and does not exit the loop as expected. As delay could be derived from DT and poll_enabled_time is defined in the driver this can easily happen.
Use a signed iterator to make sure that the loop exits once the remaining time is negative.
--- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/core.c +1 -1
@@ -2680,7 +2680,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)* return -ETIMEDOUT. */ if (rdev->desc->poll_enabled_time) { -unsigned int time_remaining = delay; +int time_remaining = delay;while (time_remaining >0 ) {_regulator_delay_helper (rdev->desc->poll_enabled_time);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 577/717 wifi: ath11k: mhi: fix potential memory leak in ath11k_mhi_register()
In reply to Greg Kroah-HartmanFrom: Jianglei Nie <[email protected]>
[ Upstream commit 43e7c3505ec70db3d3c6458824d5fa40f62e3e7b ]
mhi_alloc_controller() allocates a memory space for mhi_ctrl. When gets some error, mhi_ctrl should be freed with mhi_free_controller(). But when ath11k_mhi_read_addr_from_dt() fails, the function returns without calling mhi_free_controller(), which will lead to a memory leak.
We can fix it by calling mhi_free_controller() when ath11k_mhi_read_addr_from_dt() fails.
--- drivers/net/wireless/ath/ath11k/mhi.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath11k/mhi.c +10 -7
@@ -402,8 +402,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) ret =ath11k_mhi_get_msi (ab_pci);if (ret) {ath11k_err (ab,"failed to get msi for mhi\n" ); -mhi_free_controller (mhi_ctrl); -return ret; + goto free_controller; }if (!test_bit (ATH11K_FLAG_MULTI_MSI_VECTORS , &ab->dev_flags))
@@ -412,7 +411,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)if (test_bit (ATH11K_FLAG_FIXED_MEM_RGN , &ab->dev_flags)) { ret =ath11k_mhi_read_addr_from_dt (mhi_ctrl);if (ret <0 ) -return ret; + goto free_controller; }else { mhi_ctrl->iova_start =0 ; mhi_ctrl->iova_stop =0xFFFFFFFF ;
@@ -440,18 +439,22 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)default :ath11k_err (ab,"failed assign mhi_config for unknown hw rev %d\n" , ab->hw_rev); -mhi_free_controller (mhi_ctrl); -return -EINVAL ; + ret = -EINVAL ; + goto free_controller; } ret =mhi_register_controller (mhi_ctrl, ath11k_mhi_config);if (ret) {ath11k_err (ab,"failed to register to mhi bus, err = %d\n" , ret); -mhi_free_controller (mhi_ctrl); -return ret; + goto free_controller; }return 0 ; + +free_controller: +mhi_free_controller (mhi_ctrl); + ab_pci->mhi_ctrl =NULL ; +return ret; }void ath11k_mhi_unregister (struct ath11k_pci *ab_pci)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 578/717 wifi: mt76: mt7921: reset msta->airtime_ac while clearing up hw value
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 1bf66dc31032ff5292f4d5b76436653f269fcfbd ]
We should reset mstat->airtime_ac along with clear up the entries in the hardware WLAN table for the Rx and Rx accumulative airtime. Otherwsie, the value msta->airtime_ac - [tx, rx]_last may be a negative and that is not the actual airtime the device took in the last run.
--- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +1 -0
@@ -738,6 +738,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,mt7921_mac_wtbl_update (dev, msta->wcid.idx,MT_WTBL_UPDATE_ADM_COUNT_CLEAR ); +memset (msta->airtime_ac,0 ,sizeof (msta->airtime_ac));mt7921_mcu_sta_update (dev, sta, vif, true,MT76_STA_INFO_STATE_ASSOC );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 579/717 wifi: rtw89: free unused skb to prevent memory leak
In reply to Greg Kroah-HartmanFrom: Po-Hao Huang <[email protected]>
[ Upstream commit eae672f386049146058b9e5d3d33e9e4af9dca1d ]
This avoid potential memory leak under power saving mode.
--- drivers/net/wireless/realtek/rtw89/core.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/realtek/rtw89/core.c +1 -0
@@ -860,6 +860,7 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev,rtw89_debug (rtwdev,RTW89_DBG_FW ,"ignore h2c due to power is off with firmware state=%d\n" ,test_bit (RTW89_FLAG_FW_RDY , rtwdev->flags)); +dev_kfree_skb (skb);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 580/717 wifi: rtw89: fix rx filter after scan
In reply to Greg Kroah-HartmanFrom: Po-Hao Huang <[email protected]>
[ Upstream commit 812825c2b204c491f1a5586c602e4ac75060493a ]
In monitor mode we should be able to received all packets even if it's not destined to us. But after scan, the configuration was wrongly set, so we fix it.
--- drivers/net/wireless/realtek/rtw89/fw.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +5 -7
@@ -2288,6 +2288,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, {struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;struct cfg80211_scan_request *req = &scan_req->req; +u32 rx_fltr = rtwdev->hal.rx_fltr;u8 mac_addr[ETH_ALEN ]; rtwdev->scan_info.scanning_vif = vif;
@@ -2302,13 +2303,13 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,ether_addr_copy (mac_addr, vif->addr);rtw89_core_scan_start (rtwdev, rtwvif, mac_addr, true); - rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN ; - rtwdev->hal.rx_fltr &= ~B_AX_A_BC ; - rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH ; + rx_fltr &= ~B_AX_A_BCN_CHK_EN ; + rx_fltr &= ~B_AX_A_BC ; + rx_fltr &= ~B_AX_A_A1_MATCH ;rtw89_write32_mask (rtwdev,rtw89_mac_reg_by_idx (R_AX_RX_FLTR_OPT ,RTW89_MAC_0 ),B_AX_RX_FLTR_CFG_MASK , - rtwdev->hal.rx_fltr); + rx_fltr); } void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
@@ -2322,9 +2323,6 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,if (!vif)return ; - rtwdev->hal.rx_fltr |=B_AX_A_BCN_CHK_EN ; - rtwdev->hal.rx_fltr |=B_AX_A_BC ; - rtwdev->hal.rx_fltr |=B_AX_A_A1_MATCH ; rtw89_write32_mask(rtwdev, rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), B_AX_RX_FLTR_CFG_MASK,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 581/717 Bluetooth: L2CAP: initialize delayed works at l2cap_chan_create()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 2d2cb3066f2c90cd8ca540b36ba7a55e7f2406e0 ]
syzbot is reporting cancel_delayed_work() without INIT_DELAYED_WORK() at l2cap_chan_del() [1], for CONF_NOT_COMPLETE flag (which meant to prevent l2cap_chan_del() from calling cancel_delayed_work()) is cleared by timer which fires before l2cap_chan_del() is called by closing file descriptor created by socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP).
l2cap_bredr_sig_cmd(L2CAP_CONF_REQ) and l2cap_bredr_sig_cmd(L2CAP_CONF_RSP) are calling l2cap_ertm_init(chan), and they call l2cap_chan_ready() (which clears CONF_NOT_COMPLETE flag) only when l2cap_ertm_init(chan) succeeded.
l2cap_sock_init() does not call l2cap_ertm_init(chan), and it instead sets CONF_NOT_COMPLETE flag by calling l2cap_chan_set_defaults(). However, when connect() is requested, "command 0x0409 tx timeout" happens after 2 seconds
from connect() request, and CONF_NOT_COMPLETE flag is cleared after 4
seconds from connect() request, for l2cap_conn_start() from l2cap_info_timeout() callback scheduled by
schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
in l2cap_connect() is calling l2cap_chan_ready().
Fix this problem by initializing delayed works used by L2CAP_MODE_ERTM mode as soon as l2cap_chan_create() allocates a channel, like I did in commit be8597239379f0f5 ("Bluetooth: initialize skb_queue_head at l2cap_chan_create()").
--- net/bluetooth/l2cap_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/bluetooth/l2cap_core.c +6 -4
@@ -61,6 +61,9 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);static void l2cap_tx (struct l2cap_chan *chan,struct l2cap_ctrl *control,struct sk_buff_head *skbs,u8 event); +static void l2cap_retrans_timeout (struct work_struct *work); +static void l2cap_monitor_timeout (struct work_struct *work); +static void l2cap_ack_timeout (struct work_struct *work);static inline u8 bdaddr_type (u8 link_type,u8 bdaddr_type) {
@@ -476,6 +479,9 @@ struct l2cap_chan *l2cap_chan_create(void)write_unlock (&chan_list_lock);INIT_DELAYED_WORK (&chan->chan_timer, l2cap_chan_timeout); +INIT_DELAYED_WORK (&chan->retrans_timer, l2cap_retrans_timeout); +INIT_DELAYED_WORK (&chan->monitor_timer, l2cap_monitor_timeout); +INIT_DELAYED_WORK (&chan->ack_timer, l2cap_ack_timeout); chan->state =BT_OPEN ;
@@ -3319,10 +3325,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan) chan->rx_state =L2CAP_RX_STATE_RECV ; chan->tx_state =L2CAP_TX_STATE_XMIT ; -INIT_DELAYED_WORK (&chan->retrans_timer, l2cap_retrans_timeout); -INIT_DELAYED_WORK (&chan->monitor_timer, l2cap_monitor_timeout); -INIT_DELAYED_WORK (&chan->ack_timer, l2cap_ack_timeout); -skb_queue_head_init (&chan->srej_q); err =l2cap_seq_list_init (&chan->srej_list, chan->tx_win);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 582/717 Bluetooth: hci_sysfs: Fix attempting to call device_add multiple times
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 448a496f760664d3e2e79466aa1787e6abc922b5 ]
device_add shall not be called multiple times as stated in its documentation:
'Do not call this routine or device_register() more than once for any device structure'
Syzkaller reports a bug as follows [1]:
------------[ cut here ]------------ kernel BUG at lib/list_debug.c:33! invalid opcode: 0000 [#1] PREEMPT SMP KASAN [...] Call Trace: <TASK> __list_add include/linux/list.h:69 [inline] list_add_tail include/linux/list.h:102 [inline] kobj_kset_join lib/kobject.c:164 [inline] kobject_add_internal+0x18f/0x8f0 lib/kobject.c:214 kobject_add_varg lib/kobject.c:358 [inline] kobject_add+0x150/0x1c0 lib/kobject.c:410 device_add+0x368/0x1e90 drivers/base/core.c:3452 hci_conn_add_sysfs+0x9b/0x1b0 net/bluetooth/hci_sysfs.c:53 hci_le_cis_estabilished_evt+0x57c/0xae0 net/bluetooth/hci_event.c:6799 hci_le_meta_evt+0x2b8/0x510 net/bluetooth/hci_event.c:7110 hci_event_func net/bluetooth/hci_event.c:7440 [inline] hci_event_packet+0x63d/0xfd0 net/bluetooth/hci_event.c:7495 hci_rx_work+0xae7/0x1230 net/bluetooth/hci_core.c:4007 process_one_work+0x991/0x1610 kernel/workqueue.c:2289 worker_thread+0x665/0x1080 kernel/workqueue.c:2436 kthread+0x2e4/0x3a0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 </TASK>
--- net/bluetooth/hci_sysfs.c | 3 +++ 1 file changed, 3 insertions(+)
net/bluetooth/hci_sysfs.c +3 -0
@@ -48,6 +48,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn)BT_DBG ("conn %p" , conn); +if (device_is_registered (&conn->dev)) +return ; +dev_set_name (&conn->dev,"%s:%d" , hdev->name, conn->handle);if (device_add (&conn->dev) <0 ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 583/717 bnxt_en: replace reset with config timestamps
In reply to Greg Kroah-HartmanFrom: Vadim Fedorenko <[email protected]>
[ Upstream commit 8db3d514e96715c897fe793c4d5fc0fd86aca517 ]
Any change to the hardware timestamps configuration triggers nic restart, which breaks transmition and reception of network packets for a while. But there is no need to fully restart the device because while configuring hardware timestamps. The code for changing configuration runs after all of the initialisation, when the NIC is actually up and running. This patch changes the code that ioctl will only update configuration registers and will not trigger carrier status change, but in case of timestamps for all rx packetes it fallbacks to close()/open() sequnce because of synchronization issues in the hardware. Tested on BCM57504.
--- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +7 -3
@@ -505,9 +505,13 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) ptp->tstamp_filters = flags;if (netif_running (bp->dev)) { - rc =bnxt_close_nic (bp, false, false); -if (!rc) - rc =bnxt_open_nic (bp, false, false); +if (ptp->rx_filter ==HWTSTAMP_FILTER_ALL ) { + rc =bnxt_close_nic (bp, false, false); +if (!rc) + rc =bnxt_open_nic (bp, false, false); + }else { +bnxt_ptp_cfg_tstamp_filters (bp); + }if (!rc && !ptp->tstamp_filters) rc = -EIO ; }
Signature · 1 line
2.35.1