#include <linux/module.h>
 #include <linux/crypto.h>
 #include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <linux/lzo.h>
 
 struct lzo_ctx {
 {
        struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
 
-       ctx->lzo_comp_mem = vmalloc(LZO1X_MEM_COMPRESS);
+       ctx->lzo_comp_mem = kmalloc(LZO1X_MEM_COMPRESS,
+                                   GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
+       if (!ctx->lzo_comp_mem)
+               ctx->lzo_comp_mem = vmalloc(LZO1X_MEM_COMPRESS);
        if (!ctx->lzo_comp_mem)
                return -ENOMEM;
 
 {
        struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
 
-       vfree(ctx->lzo_comp_mem);
+       if (is_vmalloc_addr(ctx->lzo_comp_mem))
+               vfree(ctx->lzo_comp_mem);
+       else
+               kfree(ctx->lzo_comp_mem);
 }
 
 static int lzo_compress(struct crypto_tfm *tfm, const u8 *src,