On 2017-06-12 11:11, Andy Shevchenko wrote: > On Mon, Jun 12, 2017 at 6:42 AM, Song liwei <liwei.song@xxxxxxxxxxxxx> wrote: >> From: Liwei Song <liwei.song@xxxxxxxxxxxxx> >> > >> Fix the following calltrace: > > No, you don't fix a call trace, you are fixing a bug. > >> This happen When run "i2cdetect -y 0" detect SMBus iSMT adapter. >> >> After finished I2C block read/write, when unmap the data buffer, >> a wrong device address was pass to dma_unmap_single(), > > >> the right >> device address should be "dev" not "&adap->dev", the relation is >> *(&adap->dev) == dev. > > This is confusing. You are telling that there are two copies of struct > device here? Yes, there are two copies. There's the local dev variable that is like this: struct device *dev = &priv->pci_dev->dev; And then there's the adapter device in adap->dev (inlined in adap, so the explanation that the relations is "*(&adap->dev) == dev" is doubly wrong). The bug is that the first argument to dma_unmap_single is not the same as the first argument to dma_map_single that appears a few lines up. I cannot tell if that argument should be "dev" or "&adap->dev" though, but the two calls must refer to the same struct device *. Cheers, peda > Otherwise if one is a pointer to the real struct device, there > shouldn't be a problem. > >> When come into Intel IOMMU routine, the wrong >> devices address was operated. > > This basically duplicates what you have said previously. > >> To fix this, give dma_unmap_single() the "dev" parameter, just like >> what dma_map_single() does, then unmap can find the right devices. > > Fix per se looks good, explanation is confusing. > >> >> Signed-off-by: Liwei Song <liwei.song@xxxxxxxxxxxxx> >> --- >> drivers/i2c/busses/i2c-ismt.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c >> index 1db3e0d..605d44e 100644 >> --- a/drivers/i2c/busses/i2c-ismt.c >> +++ b/drivers/i2c/busses/i2c-ismt.c >> @@ -585,7 +585,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, >> >> /* unmap the data buffer */ >> if (dma_size != 0) >> - dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction); >> + dma_unmap_single(dev, dma_addr, dma_size, dma_direction); >> >> if (unlikely(!time_left)) { >> dev_err(dev, "completion wait timed out\n"); >> -- >> 2.7.4 >> > > > -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html