1616#include <linux/console.h>
1717#include <linux/module.h>
1818#include <linux/pstore.h>
19- #include <linux/crypto.h>
2019#include <linux/string.h>
2120#include <linux/timer.h>
2221#include <linux/slab.h>
2322#include <linux/uaccess.h>
2423#include <linux/jiffies.h>
24+ #include <linux/vmalloc.h>
2525#include <linux/workqueue.h>
26+ #include <linux/zlib.h>
2627
2728#include "internal.h"
2829
@@ -71,12 +72,21 @@ static char *backend;
7172module_param (backend , charp , 0444 );
7273MODULE_PARM_DESC (backend , "specific backend to use" );
7374
74- static char * compress =
75- #ifdef CONFIG_PSTORE_COMPRESS_DEFAULT
76- CONFIG_PSTORE_COMPRESS_DEFAULT ;
77- #else
78- NULL ;
79- #endif
75+ /*
76+ * pstore no longer implements compression via the crypto API, and only
77+ * supports zlib deflate compression implemented using the zlib library
78+ * interface. This removes additional complexity which is hard to justify for a
79+ * diagnostic facility that has to operate in conditions where the system may
80+ * have become unstable. Zlib deflate is comparatively small in terms of code
81+ * size, and compresses ASCII text comparatively well. In terms of compression
82+ * speed, deflate is not the best performer but for recording the log output on
83+ * a kernel panic, this is not considered critical.
84+ *
85+ * The only remaining arguments supported by the compress= module parameter are
86+ * 'deflate' and 'none'. To retain compatibility with existing installations,
87+ * all other values are logged and replaced with 'deflate'.
88+ */
89+ static char * compress = "deflate" ;
8090module_param (compress , charp , 0444 );
8191MODULE_PARM_DESC (compress , "compression to use" );
8292
@@ -85,8 +95,7 @@ unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES;
8595module_param (kmsg_bytes , ulong , 0444 );
8696MODULE_PARM_DESC (kmsg_bytes , "amount of kernel log to snapshot (in bytes)" );
8797
88- /* Compression parameters */
89- static struct crypto_comp * tfm ;
98+ static void * compress_workspace ;
9099
91100static char * big_oops_buf ;
92101
@@ -156,36 +165,49 @@ static bool pstore_cannot_block_path(enum kmsg_dump_reason reason)
156165static int pstore_compress (const void * in , void * out ,
157166 unsigned int inlen , unsigned int outlen )
158167{
168+ struct z_stream_s zstream = {
169+ .next_in = in ,
170+ .avail_in = inlen ,
171+ .next_out = out ,
172+ .avail_out = outlen ,
173+ .workspace = compress_workspace ,
174+ };
159175 int ret ;
160176
161177 if (!IS_ENABLED (CONFIG_PSTORE_COMPRESS ))
162178 return - EINVAL ;
163179
164- ret = crypto_comp_compress (tfm , in , inlen , out , & outlen );
165- if (ret ) {
166- pr_err ("crypto_comp_compress failed, ret = %d!\n" , ret );
167- return ret ;
168- }
180+ ret = zlib_deflateInit2 (& zstream , Z_DEFAULT_COMPRESSION , Z_DEFLATED ,
181+ - MAX_WBITS , DEF_MEM_LEVEL , Z_DEFAULT_STRATEGY );
182+ if (ret != Z_OK )
183+ return - EINVAL ;
169184
170- return outlen ;
185+ ret = zlib_deflate (& zstream , Z_FINISH );
186+ if (ret != Z_STREAM_END )
187+ return - EINVAL ;
188+
189+ ret = zlib_deflateEnd (& zstream );
190+ if (ret != Z_OK )
191+ pr_warn_once ("zlib_deflateEnd() failed: %d\n" , ret );
192+
193+ return zstream .total_out ;
171194}
172195
173196static void allocate_buf_for_compression (void )
174197{
175- struct crypto_comp * ctx ;
176198 char * buf ;
177199
178- /* Skip if not built-in or compression backend not selected yet. */
179- if (!IS_ENABLED (CONFIG_PSTORE_COMPRESS ) || !compress )
180- return ;
181-
182- /* Skip if no pstore backend yet or compression init already done. */
183- if (!psinfo || tfm )
200+ /* Skip if not built-in or compression disabled. */
201+ if (!IS_ENABLED (CONFIG_PSTORE_COMPRESS ) || !compress ||
202+ !strcmp (compress , "none" )) {
203+ compress = NULL ;
184204 return ;
205+ }
185206
186- if (!crypto_has_comp (compress , 0 , 0 )) {
187- pr_err ("Unknown compression: %s\n" , compress );
188- return ;
207+ if (strcmp (compress , "deflate" )) {
208+ pr_err ("Unsupported compression '%s', falling back to deflate\n" ,
209+ compress );
210+ compress = "deflate" ;
189211 }
190212
191213 /*
@@ -200,27 +222,27 @@ static void allocate_buf_for_compression(void)
200222 return ;
201223 }
202224
203- ctx = crypto_alloc_comp (compress , 0 , 0 );
204- if (IS_ERR_OR_NULL (ctx )) {
225+ compress_workspace =
226+ vmalloc (zlib_deflate_workspacesize (MAX_WBITS , DEF_MEM_LEVEL ));
227+ if (!compress_workspace ) {
228+ pr_err ("Failed to allocate zlib deflate workspace\n" );
205229 kfree (buf );
206- pr_err ("crypto_alloc_comp('%s') failed: %ld\n" , compress ,
207- PTR_ERR (ctx ));
208230 return ;
209231 }
210232
211233 /* A non-NULL big_oops_buf indicates compression is available. */
212- tfm = ctx ;
213234 big_oops_buf = buf ;
214235
215236 pr_info ("Using crash dump compression: %s\n" , compress );
216237}
217238
218239static void free_buf_for_compression (void )
219240{
220- if (IS_ENABLED (CONFIG_PSTORE_COMPRESS ) && tfm ) {
221- crypto_free_comp ( tfm );
222- tfm = NULL ;
241+ if (IS_ENABLED (CONFIG_PSTORE_COMPRESS ) && compress_workspace ) {
242+ vfree ( compress_workspace );
243+ compress_workspace = NULL ;
223244 }
245+
224246 kfree (big_oops_buf );
225247 big_oops_buf = NULL ;
226248}
@@ -531,7 +553,8 @@ void pstore_unregister(struct pstore_info *psi)
531553}
532554EXPORT_SYMBOL_GPL (pstore_unregister );
533555
534- static void decompress_record (struct pstore_record * record )
556+ static void decompress_record (struct pstore_record * record ,
557+ struct z_stream_s * zstream )
535558{
536559 int ret ;
537560 int unzipped_len ;
@@ -547,26 +570,37 @@ static void decompress_record(struct pstore_record *record)
547570 }
548571
549572 /* Missing compression buffer means compression was not initialized. */
550- if (!big_oops_buf ) {
573+ if (!zstream -> workspace ) {
551574 pr_warn ("no decompression method initialized!\n" );
552575 return ;
553576 }
554577
578+ ret = zlib_inflateReset (zstream );
579+ if (ret != Z_OK ) {
580+ pr_err ("zlib_inflateReset() failed, ret = %d!\n" , ret );
581+ return ;
582+ }
583+
555584 /* Allocate enough space to hold max decompression and ECC. */
556585 workspace = kmalloc (psinfo -> bufsize + record -> ecc_notice_size ,
557586 GFP_KERNEL );
558587 if (!workspace )
559588 return ;
560589
561- /* After decompression "unzipped_len" is almost certainly smaller. */
562- ret = crypto_comp_decompress (tfm , record -> buf , record -> size ,
563- workspace , & unzipped_len );
564- if (ret ) {
565- pr_err ("crypto_comp_decompress failed, ret = %d!\n" , ret );
590+ zstream -> next_in = record -> buf ;
591+ zstream -> avail_in = record -> size ;
592+ zstream -> next_out = workspace ;
593+ zstream -> avail_out = psinfo -> bufsize ;
594+
595+ ret = zlib_inflate (zstream , Z_FINISH );
596+ if (ret != Z_STREAM_END ) {
597+ pr_err ("zlib_inflate() failed, ret = %d!\n" , ret );
566598 kfree (workspace );
567599 return ;
568600 }
569601
602+ unzipped_len = zstream -> total_out ;
603+
570604 /* Append ECC notice to decompressed buffer. */
571605 memcpy (workspace + unzipped_len , record -> buf + record -> size ,
572606 record -> ecc_notice_size );
@@ -596,10 +630,17 @@ void pstore_get_backend_records(struct pstore_info *psi,
596630{
597631 int failed = 0 ;
598632 unsigned int stop_loop = 65536 ;
633+ struct z_stream_s zstream = {};
599634
600635 if (!psi || !root )
601636 return ;
602637
638+ if (IS_ENABLED (CONFIG_PSTORE_COMPRESS ) && compress ) {
639+ zstream .workspace = kvmalloc (zlib_inflate_workspacesize (),
640+ GFP_KERNEL );
641+ zlib_inflateInit2 (& zstream , - DEF_WBITS );
642+ }
643+
603644 mutex_lock (& psi -> read_mutex );
604645 if (psi -> open && psi -> open (psi ))
605646 goto out ;
@@ -628,7 +669,7 @@ void pstore_get_backend_records(struct pstore_info *psi,
628669 break ;
629670 }
630671
631- decompress_record (record );
672+ decompress_record (record , & zstream );
632673 rc = pstore_mkfile (root , record );
633674 if (rc ) {
634675 /* pstore_mkfile() did not take record, so free it. */
@@ -644,6 +685,12 @@ void pstore_get_backend_records(struct pstore_info *psi,
644685out :
645686 mutex_unlock (& psi -> read_mutex );
646687
688+ if (IS_ENABLED (CONFIG_PSTORE_COMPRESS ) && compress ) {
689+ if (zlib_inflateEnd (& zstream ) != Z_OK )
690+ pr_warn ("zlib_inflateEnd() failed\n" );
691+ kvfree (zstream .workspace );
692+ }
693+
647694 if (failed )
648695 pr_warn ("failed to create %d record(s) from '%s'\n" ,
649696 failed , psi -> name );
@@ -671,13 +718,6 @@ static int __init pstore_init(void)
671718{
672719 int ret ;
673720
674- /*
675- * Check if any pstore backends registered earlier but did not
676- * initialize compression because crypto was not ready. If so,
677- * initialize compression now.
678- */
679- allocate_buf_for_compression ();
680-
681721 ret = pstore_init_fs ();
682722 if (ret )
683723 free_buf_for_compression ();
0 commit comments