Bug 188591

Summary: Function ioat_dma_self_test() does not set error code when the call to dma_mapping_error() fails
Product: Drivers Reporter: bianpan (bianpan2010)
Component: Infiniband/RDMAAssignee: drivers_infiniband-rdma
Status: RESOLVED CODE_FIX    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: linux-4.9-rc6 Subsystem:
Regression: No Bisected commit-id:
Attachments: The patch fixes the bug

Description bianpan 2016-11-25 10:39:16 UTC
Function dma_mapping_error() returns a NULL pointer on failure. In function ioat_dma_self_test() defined in file drivers/dma/ioat/init.c, variable err takes the error code. However, the value of err is 0 (indicates success) even when the calls to dma_mapping_error() fail at line 341 or 346. Though this error may occur rarely, it is better to assgin "-ENOMEM" to err before the jump instructions at lines 343 and 348. Codes related to these two bugs are summarised as follows.

ioat_dma_self_test @@ drivers/dma/ioat/init.c
 302 static int ioat_dma_self_test(struct ioatdma_device *ioat_dma)
 303 {
         ...
 313     int err = 0;
         ...
 332     dma_chan = container_of(dma->channels.next, struct dma_chan,
 333                 device_node);
 334     if (dma->device_alloc_chan_resources(dma_chan) < 1) {
 335         dev_err(dev, "selftest cannot allocate chan resource\n");
 336         err = -ENODEV;
 337         goto out;
 338     }
 339 
 340     dma_src = dma_map_single(dev, src, IOAT_TEST_SIZE, DMA_TO_DEVICE);
 341     if (dma_mapping_error(dev, dma_src)) {
 342         dev_err(dev, "mapping src buffer failed\n");
 343         goto free_resources;      // insert "err = -ENOMEM" before this jump instruction?
 344     }
 345     dma_dest = dma_map_single(dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE);
 346     if (dma_mapping_error(dev, dma_dest)) {
 347         dev_err(dev, "mapping dest buffer failed\n");
 348         goto unmap_src;   // insert "err = -ENOMEM" before this jump instruction?
 349     }
         ...
 387 unmap_dma:
 388     dma_unmap_single(dev, dma_dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE);
 389 unmap_src:
 390     dma_unmap_single(dev, dma_src, IOAT_TEST_SIZE, DMA_TO_DEVICE);
 391 free_resources:
 392     dma->device_free_chan_resources(dma_chan);
 393 out:
 394     kfree(src);
 395     kfree(dest);
 396     return err;
 397 }
 
Thanks very much!
Comment 1 bianpan 2017-05-11 09:26:00 UTC
Created attachment 256377 [details]
The patch fixes the bug

The patch has been merged into the lastest version. So I will close the bug.