aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonidas Da Silva Barbosa <leosilva@linux.vnet.ibm.com>2015-04-23 16:40:30 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-04-26 02:33:18 -0400
commitc3365ce130e50176533debe1cabebcdb8e61156c (patch)
tree226e366d051aae476f6fa8dacb68143b64f2e757
parent21a6dd5b391e419efb227251745b08d5838f09db (diff)
crypto: nx - Fixing NX data alignment with nx_sg list
In NX we need to pass always a 16 multiple size nx_sg_list to co processor. Trim function handle with this assuring all nx_sg_lists are 16 multiple size, although data was not being considerated when crop was done. It was causing an unalignment between size of the list and data, corrupting csbcpb fields returning a -23 H_ST_PARM error, or invalid operation. This patch fix this recalculating how much data should be put back in to_process variable what assures the size of sg_list will be correct with size of the data. Signed-off-by: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/nx/nx.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c
index 1da6dc59d0dd..4856f7287eae 100644
--- a/drivers/crypto/nx/nx.c
+++ b/drivers/crypto/nx/nx.c
@@ -215,8 +215,15 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *nx_dst,
215 * @delta: is the amount we need to crop in order to bound the list. 215 * @delta: is the amount we need to crop in order to bound the list.
216 * 216 *
217 */ 217 */
218static long int trim_sg_list(struct nx_sg *sg, struct nx_sg *end, unsigned int delta) 218static long int trim_sg_list(struct nx_sg *sg,
219 struct nx_sg *end,
220 unsigned int delta,
221 unsigned int *nbytes)
219{ 222{
223 long int oplen;
224 long int data_back;
225 unsigned int is_delta = delta;
226
220 while (delta && end > sg) { 227 while (delta && end > sg) {
221 struct nx_sg *last = end - 1; 228 struct nx_sg *last = end - 1;
222 229
@@ -228,7 +235,20 @@ static long int trim_sg_list(struct nx_sg *sg, struct nx_sg *end, unsigned int d
228 delta -= last->len; 235 delta -= last->len;
229 } 236 }
230 } 237 }
231 return (sg - end) * sizeof(struct nx_sg); 238
239 /* There are cases where we need to crop list in order to make it
240 * a block size multiple, but we also need to align data. In order to
241 * that we need to calculate how much we need to put back to be
242 * processed
243 */
244 oplen = (sg - end) * sizeof(struct nx_sg);
245 if (is_delta) {
246 data_back = (abs(oplen) / AES_BLOCK_SIZE) * sg->len;
247 data_back = *nbytes - (data_back & ~(AES_BLOCK_SIZE - 1));
248 *nbytes -= data_back;
249 }
250
251 return oplen;
232} 252}
233 253
234/** 254/**
@@ -330,8 +350,8 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx,
330 /* these lengths should be negative, which will indicate to phyp that 350 /* these lengths should be negative, which will indicate to phyp that
331 * the input and output parameters are scatterlists, not linear 351 * the input and output parameters are scatterlists, not linear
332 * buffers */ 352 * buffers */
333 nx_ctx->op.inlen = trim_sg_list(nx_ctx->in_sg, nx_insg, delta); 353 nx_ctx->op.inlen = trim_sg_list(nx_ctx->in_sg, nx_insg, delta, nbytes);
334 nx_ctx->op.outlen = trim_sg_list(nx_ctx->out_sg, nx_outsg, delta); 354 nx_ctx->op.outlen = trim_sg_list(nx_ctx->out_sg, nx_outsg, delta, nbytes);
335 355
336 return 0; 356 return 0;
337} 357}