]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/scsi-ibmvscsi-vio_leak.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / scsi-ibmvscsi-vio_leak.patch
1 Subject: Correct VIO bus/device CMO accounting problems
2 From: Robert Jennings <rcj@linux.vnet.ibm.com>
3 References: 468304 - LTC51205
4
5 This corrects three entitlement accounting issues that are all small in
6 scope but at least two of them are critical.
7
8 In the VIO bus code the wrappers for dma alloc_coherent and free_coherent
9 calls are rounding to IOMMU_PAGE_SIZE. Taking a look at the underlying
10 calls, the actual mapping is promoted to PAGE_SIZE. Changing the
11 rounding in these two functions fixes under reporting the entitlement
12 used. Without this change, the system could run out of entitlement before
13 it believes it has and incur mapping failures at the firmware level.
14
15 Also in the VIO bus code, the wrapper for dma map_sg is not exiting in
16 an error path where it should. Rather than fall through to code for the
17 success case, this patch adds the return that is needed in the error path.
18
19 The ibmvscsi client driver is not unmapping the scsi command after
20 encountering a dma mapping error while trying to map an indirect
21 scattergather list. This leads to a leak of dma entitlement that could
22 result in the device failing future dma operations.
23
24 Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
25 Signed-off-by: Olaf Hering <olh@suse.de>
26
27 --
28 arch/powerpc/kernel/vio.c | 7 ++++---
29 drivers/scsi/ibmvscsi/ibmvfc.c | 4 +++-
30 drivers/scsi/ibmvscsi/ibmvscsi.c | 1 +
31 3 files changed, 8 insertions(+), 4 deletions(-)
32
33 --- a/arch/powerpc/kernel/vio.c
34 +++ b/arch/powerpc/kernel/vio.c
35 @@ -492,14 +492,14 @@ static void *vio_dma_iommu_alloc_coheren
36 struct vio_dev *viodev = to_vio_dev(dev);
37 void *ret;
38
39 - if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE))) {
40 + if (vio_cmo_alloc(viodev, roundup(size, PAGE_SIZE))) {
41 atomic_inc(&viodev->cmo.allocs_failed);
42 return NULL;
43 }
44
45 ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag);
46 if (unlikely(ret == NULL)) {
47 - vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
48 + vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
49 atomic_inc(&viodev->cmo.allocs_failed);
50 }
51
52 @@ -513,7 +513,7 @@ static void vio_dma_iommu_free_coherent(
53
54 dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle);
55
56 - vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
57 + vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
58 }
59
60 static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr,
61 @@ -572,6 +572,7 @@ static int vio_dma_iommu_map_sg(struct d
62 if (unlikely(!ret)) {
63 vio_cmo_dealloc(viodev, alloc_size);
64 atomic_inc(&viodev->cmo.allocs_failed);
65 + return ret;
66 }
67
68 for (sgl = sglist, count = 0; count < ret; count++, sgl++)
69 --- a/drivers/scsi/ibmvscsi/ibmvfc.c
70 +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
71 @@ -1323,7 +1323,9 @@ static int ibmvfc_map_sg_data(struct scs
72 &evt->ext_list_token);
73
74 if (!evt->ext_list) {
75 - scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
76 + scsi_dma_unmap(scmd);
77 + if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
78 + scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
79 return -ENOMEM;
80 }
81 }
82 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c
83 +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
84 @@ -435,6 +435,7 @@ static int map_sg_data(struct scsi_cmnd
85 sdev_printk(KERN_ERR, cmd->device,
86 "Can't allocate memory "
87 "for indirect table\n");
88 + scsi_dma_unmap(cmd);
89 return 0;
90 }
91 }