[PATCH 3.2 061/101] scsi: aacraid: Fix memory leak in fib init path

From: Ben Hutchings
Date: Thu Jun 01 2017 - 13:02:35 EST


3.2.89-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@xxxxxxxxxxxxx>

commit 1bff5abca65d4b9761fcc992ab6288243220003d upstream.

aac_fib_map_free frees misaligned fib dma memory, additionally it does not
free up the whole memory.

Fixed by changing the code to free up the correct and full memory
allocation.

Fixes: e8b12f0fb835223 ([SCSI] aacraid: Add new code for PMC-Sierra's SRC based controller family)
Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@xxxxxxxxxxxxx>
Reviewed-by: David Carroll <David.Carroll@xxxxxxxxxxxxx>
Reviewed-by: Johannes Thumshirn <jthumshirn@xxxxxxx>
Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
[bwh: Backported to 3.2: s/max_cmd_size/max_fib_size/]
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
drivers/scsi/aacraid/commsup.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)

--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -83,12 +83,20 @@ static int fib_map_alloc(struct aac_dev

void aac_fib_map_free(struct aac_dev *dev)
{
- if (dev->hw_fib_va && dev->max_fib_size) {
- pci_free_consistent(dev->pdev,
- (dev->max_fib_size *
- (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
- dev->hw_fib_va, dev->hw_fib_pa);
- }
+ size_t alloc_size;
+ size_t fib_size;
+ int num_fibs;
+
+ if(!dev->hw_fib_va || !dev->max_fib_size)
+ return;
+
+ num_fibs = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
+ fib_size = dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
+ alloc_size = fib_size * num_fibs + ALIGN32 - 1;
+
+ pci_free_consistent(dev->pdev, alloc_size, dev->hw_fib_va,
+ dev->hw_fib_pa);
+
dev->hw_fib_va = NULL;
dev->hw_fib_pa = 0;
}
@@ -116,22 +124,20 @@ int aac_fib_setup(struct aac_dev * dev)
if (i<0)
return -ENOMEM;

- /* 32 byte alignment for PMC */
- hw_fib_pa = (dev->hw_fib_pa + (ALIGN32 - 1)) & ~(ALIGN32 - 1);
- dev->hw_fib_va = (struct hw_fib *)((unsigned char *)dev->hw_fib_va +
- (hw_fib_pa - dev->hw_fib_pa));
- dev->hw_fib_pa = hw_fib_pa;
memset(dev->hw_fib_va, 0,
(dev->max_fib_size + sizeof(struct aac_fib_xporthdr)) *
(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));

+ /* 32 byte alignment for PMC */
+ hw_fib_pa = (dev->hw_fib_pa + (ALIGN32 - 1)) & ~(ALIGN32 - 1);
+ hw_fib = (struct hw_fib *)((unsigned char *)dev->hw_fib_va +
+ (hw_fib_pa - dev->hw_fib_pa));
+
/* add Xport header */
- dev->hw_fib_va = (struct hw_fib *)((unsigned char *)dev->hw_fib_va +
+ hw_fib = (struct hw_fib *)((unsigned char *)hw_fib +
sizeof(struct aac_fib_xporthdr));
- dev->hw_fib_pa += sizeof(struct aac_fib_xporthdr);
+ hw_fib_pa += sizeof(struct aac_fib_xporthdr);

- hw_fib = dev->hw_fib_va;
- hw_fib_pa = dev->hw_fib_pa;
/*
* Initialise the fibs
*/