#include <asm/pstate.h>
 #include <asm/elf.h>
+#include <asm/unaligned.h>
 
 #include "opcodes.h"
 
 
        if (keylen != sizeof(u32))
                return -EINVAL;
-       *mctx = le32_to_cpup((__le32 *)key);
+       *mctx = get_unaligned_le32(key);
        return 0;
 }
 
 
 extern void crc32c_sparc64(u32 *crcp, const u64 *data, unsigned int len);
 
-static void crc32c_compute(u32 *crcp, const u64 *data, unsigned int len)
+static u32 crc32c_compute(u32 crc, const u8 *data, unsigned int len)
 {
-       unsigned int asm_len;
-
-       asm_len = len & ~7U;
-       if (asm_len) {
-               crc32c_sparc64(crcp, data, asm_len);
-               data += asm_len / 8;
-               len -= asm_len;
+       unsigned int n = -(uintptr_t)data & 7;
+
+       if (n) {
+               /* Data isn't 8-byte aligned.  Align it. */
+               n = min(n, len);
+               crc = __crc32c_le(crc, data, n);
+               data += n;
+               len -= n;
+       }
+       n = len & ~7U;
+       if (n) {
+               crc32c_sparc64(&crc, (const u64 *)data, n);
+               data += n;
+               len -= n;
        }
        if (len)
-               *crcp = __crc32c_le(*crcp, (const unsigned char *) data, len);
+               crc = __crc32c_le(crc, data, len);
+       return crc;
 }
 
 static int crc32c_sparc64_update(struct shash_desc *desc, const u8 *data,
 {
        u32 *crcp = shash_desc_ctx(desc);
 
-       crc32c_compute(crcp, (const u64 *) data, len);
-
+       *crcp = crc32c_compute(*crcp, data, len);
        return 0;
 }
 
-static int __crc32c_sparc64_finup(u32 *crcp, const u8 *data, unsigned int len,
-                                 u8 *out)
+static int __crc32c_sparc64_finup(const u32 *crcp, const u8 *data,
+                                 unsigned int len, u8 *out)
 {
-       u32 tmp = *crcp;
-
-       crc32c_compute(&tmp, (const u64 *) data, len);
-
-       *(__le32 *) out = ~cpu_to_le32(tmp);
+       put_unaligned_le32(~crc32c_compute(*crcp, data, len), out);
        return 0;
 }
 
 {
        u32 *crcp = shash_desc_ctx(desc);
 
-       *(__le32 *) out = ~cpu_to_le32p(crcp);
+       put_unaligned_le32(~*crcp, out);
        return 0;
 }
 
                .cra_flags              =       CRYPTO_ALG_OPTIONAL_KEY,
                .cra_blocksize          =       CHKSUM_BLOCK_SIZE,
                .cra_ctxsize            =       sizeof(u32),
-               .cra_alignmask          =       7,
                .cra_module             =       THIS_MODULE,
                .cra_init               =       crc32c_sparc64_cra_init,
        }