16
16
#include <linux/console.h>
17
17
#include <linux/module.h>
18
18
#include <linux/pstore.h>
19
- #include <linux/crypto.h>
20
19
#include <linux/string.h>
21
20
#include <linux/timer.h>
22
21
#include <linux/slab.h>
23
22
#include <linux/uaccess.h>
24
23
#include <linux/jiffies.h>
24
+ #include <linux/vmalloc.h>
25
25
#include <linux/workqueue.h>
26
+ #include <linux/zlib.h>
26
27
27
28
#include "internal.h"
28
29
@@ -71,12 +72,21 @@ static char *backend;
71
72
module_param (backend , charp , 0444 );
72
73
MODULE_PARM_DESC (backend , "specific backend to use" );
73
74
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" ;
80
90
module_param (compress , charp , 0444 );
81
91
MODULE_PARM_DESC (compress , "compression to use" );
82
92
@@ -85,8 +95,7 @@ unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES;
85
95
module_param (kmsg_bytes , ulong , 0444 );
86
96
MODULE_PARM_DESC (kmsg_bytes , "amount of kernel log to snapshot (in bytes)" );
87
97
88
- /* Compression parameters */
89
- static struct crypto_comp * tfm ;
98
+ static void * compress_workspace ;
90
99
91
100
static char * big_oops_buf ;
92
101
@@ -156,36 +165,49 @@ static bool pstore_cannot_block_path(enum kmsg_dump_reason reason)
156
165
static int pstore_compress (const void * in , void * out ,
157
166
unsigned int inlen , unsigned int outlen )
158
167
{
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
+ };
159
175
int ret ;
160
176
161
177
if (!IS_ENABLED (CONFIG_PSTORE_COMPRESS ))
162
178
return - EINVAL ;
163
179
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 ;
169
184
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 ;
171
194
}
172
195
173
196
static void allocate_buf_for_compression (void )
174
197
{
175
- struct crypto_comp * ctx ;
176
198
char * buf ;
177
199
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 ;
184
204
return ;
205
+ }
185
206
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" ;
189
211
}
190
212
191
213
/*
@@ -200,27 +222,27 @@ static void allocate_buf_for_compression(void)
200
222
return ;
201
223
}
202
224
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" );
205
229
kfree (buf );
206
- pr_err ("crypto_alloc_comp('%s') failed: %ld\n" , compress ,
207
- PTR_ERR (ctx ));
208
230
return ;
209
231
}
210
232
211
233
/* A non-NULL big_oops_buf indicates compression is available. */
212
- tfm = ctx ;
213
234
big_oops_buf = buf ;
214
235
215
236
pr_info ("Using crash dump compression: %s\n" , compress );
216
237
}
217
238
218
239
static void free_buf_for_compression (void )
219
240
{
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 ;
223
244
}
245
+
224
246
kfree (big_oops_buf );
225
247
big_oops_buf = NULL ;
226
248
}
@@ -531,7 +553,8 @@ void pstore_unregister(struct pstore_info *psi)
531
553
}
532
554
EXPORT_SYMBOL_GPL (pstore_unregister );
533
555
534
- static void decompress_record (struct pstore_record * record )
556
+ static void decompress_record (struct pstore_record * record ,
557
+ struct z_stream_s * zstream )
535
558
{
536
559
int ret ;
537
560
int unzipped_len ;
@@ -547,26 +570,37 @@ static void decompress_record(struct pstore_record *record)
547
570
}
548
571
549
572
/* Missing compression buffer means compression was not initialized. */
550
- if (!big_oops_buf ) {
573
+ if (!zstream -> workspace ) {
551
574
pr_warn ("no decompression method initialized!\n" );
552
575
return ;
553
576
}
554
577
578
+ ret = zlib_inflateReset (zstream );
579
+ if (ret != Z_OK ) {
580
+ pr_err ("zlib_inflateReset() failed, ret = %d!\n" , ret );
581
+ return ;
582
+ }
583
+
555
584
/* Allocate enough space to hold max decompression and ECC. */
556
585
workspace = kmalloc (psinfo -> bufsize + record -> ecc_notice_size ,
557
586
GFP_KERNEL );
558
587
if (!workspace )
559
588
return ;
560
589
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 );
566
598
kfree (workspace );
567
599
return ;
568
600
}
569
601
602
+ unzipped_len = zstream -> total_out ;
603
+
570
604
/* Append ECC notice to decompressed buffer. */
571
605
memcpy (workspace + unzipped_len , record -> buf + record -> size ,
572
606
record -> ecc_notice_size );
@@ -596,10 +630,17 @@ void pstore_get_backend_records(struct pstore_info *psi,
596
630
{
597
631
int failed = 0 ;
598
632
unsigned int stop_loop = 65536 ;
633
+ struct z_stream_s zstream = {};
599
634
600
635
if (!psi || !root )
601
636
return ;
602
637
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
+
603
644
mutex_lock (& psi -> read_mutex );
604
645
if (psi -> open && psi -> open (psi ))
605
646
goto out ;
@@ -628,7 +669,7 @@ void pstore_get_backend_records(struct pstore_info *psi,
628
669
break ;
629
670
}
630
671
631
- decompress_record (record );
672
+ decompress_record (record , & zstream );
632
673
rc = pstore_mkfile (root , record );
633
674
if (rc ) {
634
675
/* pstore_mkfile() did not take record, so free it. */
@@ -644,6 +685,12 @@ void pstore_get_backend_records(struct pstore_info *psi,
644
685
out :
645
686
mutex_unlock (& psi -> read_mutex );
646
687
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
+
647
694
if (failed )
648
695
pr_warn ("failed to create %d record(s) from '%s'\n" ,
649
696
failed , psi -> name );
@@ -671,13 +718,6 @@ static int __init pstore_init(void)
671
718
{
672
719
int ret ;
673
720
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
-
681
721
ret = pstore_init_fs ();
682
722
if (ret )
683
723
free_buf_for_compression ();
0 commit comments