| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * OMAP Crypto driver common support routines. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2017 Texas Instruments Incorporated |
|---|
| 5 | 6 | * Tero Kristo <t-kristo@ti.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as published |
|---|
| 9 | | - * by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | |
|---|
| 12 | 9 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 157 | 154 | } |
|---|
| 158 | 155 | EXPORT_SYMBOL_GPL(omap_crypto_align_sg); |
|---|
| 159 | 156 | |
|---|
| 157 | +static void omap_crypto_copy_data(struct scatterlist *src, |
|---|
| 158 | + struct scatterlist *dst, |
|---|
| 159 | + int offset, int len) |
|---|
| 160 | +{ |
|---|
| 161 | + int amt; |
|---|
| 162 | + void *srcb, *dstb; |
|---|
| 163 | + int srco = 0, dsto = offset; |
|---|
| 164 | + |
|---|
| 165 | + while (src && dst && len) { |
|---|
| 166 | + if (srco >= src->length) { |
|---|
| 167 | + srco -= src->length; |
|---|
| 168 | + src = sg_next(src); |
|---|
| 169 | + continue; |
|---|
| 170 | + } |
|---|
| 171 | + |
|---|
| 172 | + if (dsto >= dst->length) { |
|---|
| 173 | + dsto -= dst->length; |
|---|
| 174 | + dst = sg_next(dst); |
|---|
| 175 | + continue; |
|---|
| 176 | + } |
|---|
| 177 | + |
|---|
| 178 | + amt = min(src->length - srco, dst->length - dsto); |
|---|
| 179 | + amt = min(len, amt); |
|---|
| 180 | + |
|---|
| 181 | + srcb = kmap_atomic(sg_page(src)) + srco + src->offset; |
|---|
| 182 | + dstb = kmap_atomic(sg_page(dst)) + dsto + dst->offset; |
|---|
| 183 | + |
|---|
| 184 | + memcpy(dstb, srcb, amt); |
|---|
| 185 | + |
|---|
| 186 | + if (!PageSlab(sg_page(dst))) |
|---|
| 187 | + flush_kernel_dcache_page(sg_page(dst)); |
|---|
| 188 | + |
|---|
| 189 | + kunmap_atomic(srcb); |
|---|
| 190 | + kunmap_atomic(dstb); |
|---|
| 191 | + |
|---|
| 192 | + srco += amt; |
|---|
| 193 | + dsto += amt; |
|---|
| 194 | + len -= amt; |
|---|
| 195 | + } |
|---|
| 196 | +} |
|---|
| 197 | + |
|---|
| 160 | 198 | void omap_crypto_cleanup(struct scatterlist *sg, struct scatterlist *orig, |
|---|
| 161 | 199 | int offset, int len, u8 flags_shift, |
|---|
| 162 | 200 | unsigned long flags) |
|---|
| .. | .. |
|---|
| 174 | 212 | pages = get_order(len); |
|---|
| 175 | 213 | |
|---|
| 176 | 214 | if (orig && (flags & OMAP_CRYPTO_COPY_MASK)) |
|---|
| 177 | | - scatterwalk_map_and_copy(buf, orig, offset, len, 1); |
|---|
| 215 | + omap_crypto_copy_data(sg, orig, offset, len); |
|---|
| 178 | 216 | |
|---|
| 179 | 217 | if (flags & OMAP_CRYPTO_DATA_COPIED) |
|---|
| 180 | 218 | free_pages((unsigned long)buf, pages); |
|---|