]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK
authorJan Glauber <jglauber@cavium.com>
Tue, 27 Mar 2018 10:31:53 +0000 (12:31 +0200)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Tue, 27 Mar 2018 20:08:25 +0000 (17:08 -0300)
BugLink: http://bugs.launchpad.net/bugs/1755073
Enabling virtual mapped kernel stacks breaks the thunderx_zip
driver. On compression or decompression the executing CPU hangs
in an endless loop. The reason for this is the usage of __pa()
by the driver that does not work for an address that is
not part of the 1:1 mapping.

The zip driver allocates a result struct on the stack and needs
to tell the hardware the pysical address within this struct
that is used to signal the completion of the request.
With CONFIG_VMAP_STACK __pa() is no longer usable for a stack address.

As the hardware gets the wrong address it writes the result byte
to an arbitrary address. The zip driver then waits forever for the
completion byte to contain a non-zero value.

Allocating the result struct from 1:1 mapped memory resolves this
bug.

Note that there are more outstanding issues with the used completion
mechanism:
- volatile is used for a bitfield
- no barriers at all re used
- the completion loop should have a retry counter and not run forever
- polling for the result should use a delay
- interrupts for completion and error notification should be used

Signed-off-by: Jan Glauber <jglauber@cavium.com>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
drivers/crypto/cavium/zip/zip_crypto.c

index 8df4d26cf9d46894e68c86f2032fb3f9b4ca899d..2fc9b03e1b40f9268599cd2822b97a6118668033 100644 (file)
@@ -124,7 +124,7 @@ int zip_compress(const u8 *src, unsigned int slen,
                 struct zip_kernel_ctx *zip_ctx)
 {
        struct zip_operation  *zip_ops   = NULL;
-       struct zip_state      zip_state;
+       struct zip_state      *zip_state;
        struct zip_device     *zip = NULL;
        int ret;
 
@@ -135,20 +135,23 @@ int zip_compress(const u8 *src, unsigned int slen,
        if (!zip)
                return -ENODEV;
 
-       memset(&zip_state, 0, sizeof(struct zip_state));
+       zip_state = kzalloc(sizeof(*zip_state), GFP_KERNEL);
+       if (!zip_state)
+               return -ENOMEM;
+
        zip_ops = &zip_ctx->zip_comp;
 
        zip_ops->input_len  = slen;
        zip_ops->output_len = *dlen;
        memcpy(zip_ops->input, src, slen);
 
-       ret = zip_deflate(zip_ops, &zip_state, zip);
+       ret = zip_deflate(zip_ops, zip_state, zip);
 
        if (!ret) {
                *dlen = zip_ops->output_len;
                memcpy(dst, zip_ops->output, *dlen);
        }
-
+       kfree(zip_state);
        return ret;
 }
 
@@ -157,7 +160,7 @@ int zip_decompress(const u8 *src, unsigned int slen,
                   struct zip_kernel_ctx *zip_ctx)
 {
        struct zip_operation  *zip_ops   = NULL;
-       struct zip_state      zip_state;
+       struct zip_state      *zip_state;
        struct zip_device     *zip = NULL;
        int ret;
 
@@ -168,7 +171,10 @@ int zip_decompress(const u8 *src, unsigned int slen,
        if (!zip)
                return -ENODEV;
 
-       memset(&zip_state, 0, sizeof(struct zip_state));
+       zip_state = kzalloc(sizeof(*zip_state), GFP_KERNEL);
+       if (!zip_state)
+               return -ENOMEM;
+
        zip_ops = &zip_ctx->zip_decomp;
        memcpy(zip_ops->input, src, slen);
 
@@ -179,13 +185,13 @@ int zip_decompress(const u8 *src, unsigned int slen,
        zip_ops->input_len  = slen;
        zip_ops->output_len = *dlen;
 
-       ret = zip_inflate(zip_ops, &zip_state, zip);
+       ret = zip_inflate(zip_ops, zip_state, zip);
 
        if (!ret) {
                *dlen = zip_ops->output_len;
                memcpy(dst, zip_ops->output, *dlen);
        }
-
+       kfree(zip_state);
        return ret;
 }