提交 0ba3e101 编写于 作者: N Nathan Fontenot 提交者: Benjamin Herrenschmidt

crypto/nx/nx-842: Fix handling of vmalloc addresses

The powerpc specific nx-842 compression driver does not currently
handle translating a vmalloc address to a physical address.

The current driver uses __pa() for all addresses which does not
properly handle vmalloc addresses and thus causes a failure since
we do not pass a proper physical address to the hypervisor.

This patch adds a routine to convert an address to a physical
address by checking for vmalloc addresses and handling them properly.
Signed-off-by: NNathan Fontenot <nfont@linux.vnet.ibm.com>
 ---
 drivers/crypto/nx/nx-842.c |   29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 8d4887ee
...@@ -158,6 +158,15 @@ static inline unsigned long nx842_get_scatterlist_size( ...@@ -158,6 +158,15 @@ static inline unsigned long nx842_get_scatterlist_size(
return sl->entry_nr * sizeof(struct nx842_slentry); return sl->entry_nr * sizeof(struct nx842_slentry);
} }
static inline unsigned long nx842_get_pa(void *addr)
{
if (is_vmalloc_addr(addr))
return page_to_phys(vmalloc_to_page(addr))
+ offset_in_page(addr);
else
return __pa(addr);
}
static int nx842_build_scatterlist(unsigned long buf, int len, static int nx842_build_scatterlist(unsigned long buf, int len,
struct nx842_scatterlist *sl) struct nx842_scatterlist *sl)
{ {
...@@ -168,7 +177,7 @@ static int nx842_build_scatterlist(unsigned long buf, int len, ...@@ -168,7 +177,7 @@ static int nx842_build_scatterlist(unsigned long buf, int len,
entry = sl->entries; entry = sl->entries;
while (len) { while (len) {
entry->ptr = __pa(buf); entry->ptr = nx842_get_pa((void *)buf);
nextpage = ALIGN(buf + 1, NX842_HW_PAGE_SIZE); nextpage = ALIGN(buf + 1, NX842_HW_PAGE_SIZE);
if (nextpage < buf + len) { if (nextpage < buf + len) {
/* we aren't at the end yet */ /* we aren't at the end yet */
...@@ -370,8 +379,8 @@ int nx842_compress(const unsigned char *in, unsigned int inlen, ...@@ -370,8 +379,8 @@ int nx842_compress(const unsigned char *in, unsigned int inlen,
op.flags = NX842_OP_COMPRESS; op.flags = NX842_OP_COMPRESS;
csbcpb = &workmem->csbcpb; csbcpb = &workmem->csbcpb;
memset(csbcpb, 0, sizeof(*csbcpb)); memset(csbcpb, 0, sizeof(*csbcpb));
op.csbcpb = __pa(csbcpb); op.csbcpb = nx842_get_pa(csbcpb);
op.out = __pa(slout.entries); op.out = nx842_get_pa(slout.entries);
for (i = 0; i < hdr->blocks_nr; i++) { for (i = 0; i < hdr->blocks_nr; i++) {
/* /*
...@@ -401,13 +410,13 @@ int nx842_compress(const unsigned char *in, unsigned int inlen, ...@@ -401,13 +410,13 @@ int nx842_compress(const unsigned char *in, unsigned int inlen,
*/ */
if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) { if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) {
/* Create direct DDE */ /* Create direct DDE */
op.in = __pa(inbuf); op.in = nx842_get_pa((void *)inbuf);
op.inlen = max_sync_size; op.inlen = max_sync_size;
} else { } else {
/* Create indirect DDE (scatterlist) */ /* Create indirect DDE (scatterlist) */
nx842_build_scatterlist(inbuf, max_sync_size, &slin); nx842_build_scatterlist(inbuf, max_sync_size, &slin);
op.in = __pa(slin.entries); op.in = nx842_get_pa(slin.entries);
op.inlen = -nx842_get_scatterlist_size(&slin); op.inlen = -nx842_get_scatterlist_size(&slin);
} }
...@@ -565,7 +574,7 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen, ...@@ -565,7 +574,7 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen,
op.flags = NX842_OP_DECOMPRESS; op.flags = NX842_OP_DECOMPRESS;
csbcpb = &workmem->csbcpb; csbcpb = &workmem->csbcpb;
memset(csbcpb, 0, sizeof(*csbcpb)); memset(csbcpb, 0, sizeof(*csbcpb));
op.csbcpb = __pa(csbcpb); op.csbcpb = nx842_get_pa(csbcpb);
/* /*
* max_sync_size may have changed since compression, * max_sync_size may have changed since compression,
...@@ -597,12 +606,12 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen, ...@@ -597,12 +606,12 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen,
if (likely((inbuf & NX842_HW_PAGE_MASK) == if (likely((inbuf & NX842_HW_PAGE_MASK) ==
((inbuf + hdr->sizes[i] - 1) & NX842_HW_PAGE_MASK))) { ((inbuf + hdr->sizes[i] - 1) & NX842_HW_PAGE_MASK))) {
/* Create direct DDE */ /* Create direct DDE */
op.in = __pa(inbuf); op.in = nx842_get_pa((void *)inbuf);
op.inlen = hdr->sizes[i]; op.inlen = hdr->sizes[i];
} else { } else {
/* Create indirect DDE (scatterlist) */ /* Create indirect DDE (scatterlist) */
nx842_build_scatterlist(inbuf, hdr->sizes[i] , &slin); nx842_build_scatterlist(inbuf, hdr->sizes[i] , &slin);
op.in = __pa(slin.entries); op.in = nx842_get_pa(slin.entries);
op.inlen = -nx842_get_scatterlist_size(&slin); op.inlen = -nx842_get_scatterlist_size(&slin);
} }
...@@ -613,12 +622,12 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen, ...@@ -613,12 +622,12 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen,
*/ */
if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) { if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) {
/* Create direct DDE */ /* Create direct DDE */
op.out = __pa(outbuf); op.out = nx842_get_pa((void *)outbuf);
op.outlen = max_sync_size; op.outlen = max_sync_size;
} else { } else {
/* Create indirect DDE (scatterlist) */ /* Create indirect DDE (scatterlist) */
nx842_build_scatterlist(outbuf, max_sync_size, &slout); nx842_build_scatterlist(outbuf, max_sync_size, &slout);
op.out = __pa(slout.entries); op.out = nx842_get_pa(slout.entries);
op.outlen = -nx842_get_scatterlist_size(&slout); op.outlen = -nx842_get_scatterlist_size(&slout);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册