diff options
Diffstat (limited to 'drivers/crypto/caam/sg_sw_sec4.h')
-rw-r--r-- | drivers/crypto/caam/sg_sw_sec4.h | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h index e0037c8ee243..b12ff85f4241 100644 --- a/drivers/crypto/caam/sg_sw_sec4.h +++ b/drivers/crypto/caam/sg_sw_sec4.h | |||
@@ -117,6 +117,21 @@ static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg, | |||
117 | return nents; | 117 | return nents; |
118 | } | 118 | } |
119 | 119 | ||
120 | /* Map SG page in kernel virtual address space and copy */ | ||
121 | static inline void sg_map_copy(u8 *dest, struct scatterlist *sg, | ||
122 | int len, int offset) | ||
123 | { | ||
124 | u8 *mapped_addr; | ||
125 | |||
126 | /* | ||
127 | * Page here can be user-space pinned using get_user_pages | ||
128 | * Same must be kmapped before use and kunmapped subsequently | ||
129 | */ | ||
130 | mapped_addr = kmap_atomic(sg_page(sg)); | ||
131 | memcpy(dest, mapped_addr + offset, len); | ||
132 | kunmap_atomic(mapped_addr); | ||
133 | } | ||
134 | |||
120 | /* Copy from len bytes of sg to dest, starting from beginning */ | 135 | /* Copy from len bytes of sg to dest, starting from beginning */ |
121 | static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) | 136 | static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) |
122 | { | 137 | { |
@@ -124,15 +139,15 @@ static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) | |||
124 | int cpy_index = 0, next_cpy_index = current_sg->length; | 139 | int cpy_index = 0, next_cpy_index = current_sg->length; |
125 | 140 | ||
126 | while (next_cpy_index < len) { | 141 | while (next_cpy_index < len) { |
127 | memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg), | 142 | sg_map_copy(dest + cpy_index, current_sg, current_sg->length, |
128 | current_sg->length); | 143 | current_sg->offset); |
129 | current_sg = scatterwalk_sg_next(current_sg); | 144 | current_sg = scatterwalk_sg_next(current_sg); |
130 | cpy_index = next_cpy_index; | 145 | cpy_index = next_cpy_index; |
131 | next_cpy_index += current_sg->length; | 146 | next_cpy_index += current_sg->length; |
132 | } | 147 | } |
133 | if (cpy_index < len) | 148 | if (cpy_index < len) |
134 | memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg), | 149 | sg_map_copy(dest + cpy_index, current_sg, len-cpy_index, |
135 | len - cpy_index); | 150 | current_sg->offset); |
136 | } | 151 | } |
137 | 152 | ||
138 | /* Copy sg data, from to_skip to end, to dest */ | 153 | /* Copy sg data, from to_skip to end, to dest */ |
@@ -140,7 +155,7 @@ static inline void sg_copy_part(u8 *dest, struct scatterlist *sg, | |||
140 | int to_skip, unsigned int end) | 155 | int to_skip, unsigned int end) |
141 | { | 156 | { |
142 | struct scatterlist *current_sg = sg; | 157 | struct scatterlist *current_sg = sg; |
143 | int sg_index, cpy_index; | 158 | int sg_index, cpy_index, offset; |
144 | 159 | ||
145 | sg_index = current_sg->length; | 160 | sg_index = current_sg->length; |
146 | while (sg_index <= to_skip) { | 161 | while (sg_index <= to_skip) { |
@@ -148,9 +163,10 @@ static inline void sg_copy_part(u8 *dest, struct scatterlist *sg, | |||
148 | sg_index += current_sg->length; | 163 | sg_index += current_sg->length; |
149 | } | 164 | } |
150 | cpy_index = sg_index - to_skip; | 165 | cpy_index = sg_index - to_skip; |
151 | memcpy(dest, (u8 *) sg_virt(current_sg) + | 166 | offset = current_sg->offset + current_sg->length - cpy_index; |
152 | current_sg->length - cpy_index, cpy_index); | 167 | sg_map_copy(dest, current_sg, cpy_index, offset); |
153 | current_sg = scatterwalk_sg_next(current_sg); | 168 | if (end - sg_index) { |
154 | if (end - sg_index) | 169 | current_sg = scatterwalk_sg_next(current_sg); |
155 | sg_copy(dest + cpy_index, current_sg, end - sg_index); | 170 | sg_copy(dest + cpy_index, current_sg, end - sg_index); |
171 | } | ||
156 | } | 172 | } |