Message ID | 20200108133948.1.I35ceb4db3ad8cfab78f7cd51494aeff4891339f5@changeid |
---|---|
State | Accepted |
Commit | b8d40d7712f10475effc4552eda96b9d44822cfb |
Headers | show |
Series | spi: spi-qcom-qspi: Use device managed memory for clk_bulk_data | expand |
Hi, On Wed, Jan 8, 2020 at 1:40 PM Matthias Kaehlcke <mka@chromium.org> wrote: > > Currrently the memory for the clk_bulk_data of the QSPI controller > is allocated with spi_alloc_master(). The bulk data pointer is passed > to devm_clk_bulk_get() which saves it in clk_bulk_devres->clks. When > the device is removed later devm_clk_bulk_release() is called and > uses the bulk data referenced by the pointer to release the clocks. > For this driver this results in accessing memory that has already > been freed, since the memory allocated with spi_alloc_master() is > released by spi_controller_release(), which is called before the > managed resources are released. > > Use device managed memory for the clock bulk data to fix the issue > described above. > > Signed-off-by: Matthias Kaehlcke <mka@chromium.org> > --- > > drivers/spi/spi-qcom-qspi.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) It's a little ugly, but it seems somewhat same. Basically we're saying that the caller of devm_clk_bulk_get() is in charge of keeping the list of clocks readable for the devm free function. Maybe we should also fix devm_clk_bulk_get() to always make a copy of the clocks so we can relax this limitation (though that's a lot of extra copying for the uncommon case), but even if we do change that your change would still be OK. ...so from my point of view: Reviewed-by: Douglas Anderson <dianders@chromium.org> -Doug
diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index 250fd60e167821..3c4f83bf7084c8 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -137,7 +137,7 @@ enum qspi_clocks { struct qcom_qspi { void __iomem *base; struct device *dev; - struct clk_bulk_data clks[QSPI_NUM_CLKS]; + struct clk_bulk_data *clks; struct qspi_xfer xfer; /* Lock to protect xfer and IRQ accessed registers */ spinlock_t lock; @@ -445,6 +445,13 @@ static int qcom_qspi_probe(struct platform_device *pdev) goto exit_probe_master_put; } + ctrl->clks = devm_kcalloc(dev, QSPI_NUM_CLKS, + sizeof(*ctrl->clks), GFP_KERNEL); + if (!ctrl->clks) { + ret = -ENOMEM; + goto exit_probe_master_put; + } + ctrl->clks[QSPI_CLK_CORE].id = "core"; ctrl->clks[QSPI_CLK_IFACE].id = "iface"; ret = devm_clk_bulk_get(dev, QSPI_NUM_CLKS, ctrl->clks);
Currrently the memory for the clk_bulk_data of the QSPI controller is allocated with spi_alloc_master(). The bulk data pointer is passed to devm_clk_bulk_get() which saves it in clk_bulk_devres->clks. When the device is removed later devm_clk_bulk_release() is called and uses the bulk data referenced by the pointer to release the clocks. For this driver this results in accessing memory that has already been freed, since the memory allocated with spi_alloc_master() is released by spi_controller_release(), which is called before the managed resources are released. Use device managed memory for the clock bulk data to fix the issue described above. Signed-off-by: Matthias Kaehlcke <mka@chromium.org> --- drivers/spi/spi-qcom-qspi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)