Commit c2c0b4c5434c0a25f7f7796b29155d53805909f5
Committed by
David S. Miller
1 parent
c3d4f44f50
Exists in
master
and in
7 other branches
[2/4] I/OAT: fix dma_pin_iovec_pages() error handling
Error handling needs to be modified in dma_pin_iovec_pages(). It should return NULL instead of ERR_PTR (pinned_list is checked for NULL in tcp_recvmsg() to determine if iovec pages have been successfully pinned down). In case of error for the first iovec, local_list->nr_iovecs needs to be initialized. Cc: <stable@kernel.org> Signed-off-by: Maciej Sosnowski <maciej.sosnowski@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 6 additions and 11 deletions Side-by-side Diff
drivers/dma/iovlock.c
... | ... | @@ -55,7 +55,6 @@ |
55 | 55 | int nr_iovecs = 0; |
56 | 56 | int iovec_len_used = 0; |
57 | 57 | int iovec_pages_used = 0; |
58 | - long err; | |
59 | 58 | |
60 | 59 | /* don't pin down non-user-based iovecs */ |
61 | 60 | if (segment_eq(get_fs(), KERNEL_DS)) |
62 | 61 | |
63 | 62 | |
64 | 63 | |
65 | 64 | |
... | ... | @@ -72,23 +71,21 @@ |
72 | 71 | local_list = kmalloc(sizeof(*local_list) |
73 | 72 | + (nr_iovecs * sizeof (struct dma_page_list)) |
74 | 73 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); |
75 | - if (!local_list) { | |
76 | - err = -ENOMEM; | |
74 | + if (!local_list) | |
77 | 75 | goto out; |
78 | - } | |
79 | 76 | |
80 | 77 | /* list of pages starts right after the page list array */ |
81 | 78 | pages = (struct page **) &local_list->page_list[nr_iovecs]; |
82 | 79 | |
80 | + local_list->nr_iovecs = 0; | |
81 | + | |
83 | 82 | for (i = 0; i < nr_iovecs; i++) { |
84 | 83 | struct dma_page_list *page_list = &local_list->page_list[i]; |
85 | 84 | |
86 | 85 | len -= iov[i].iov_len; |
87 | 86 | |
88 | - if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) { | |
89 | - err = -EFAULT; | |
87 | + if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) | |
90 | 88 | goto unpin; |
91 | - } | |
92 | 89 | |
93 | 90 | page_list->nr_pages = num_pages_spanned(&iov[i]); |
94 | 91 | page_list->base_address = iov[i].iov_base; |
95 | 92 | |
... | ... | @@ -109,10 +106,8 @@ |
109 | 106 | NULL); |
110 | 107 | up_read(¤t->mm->mmap_sem); |
111 | 108 | |
112 | - if (ret != page_list->nr_pages) { | |
113 | - err = -ENOMEM; | |
109 | + if (ret != page_list->nr_pages) | |
114 | 110 | goto unpin; |
115 | - } | |
116 | 111 | |
117 | 112 | local_list->nr_iovecs = i + 1; |
118 | 113 | } |
... | ... | @@ -122,7 +117,7 @@ |
122 | 117 | unpin: |
123 | 118 | dma_unpin_iovec_pages(local_list); |
124 | 119 | out: |
125 | - return ERR_PTR(err); | |
120 | + return NULL; | |
126 | 121 | } |
127 | 122 | |
128 | 123 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) |