rslib: Split rs control struct

The decoder library uses variable length arrays on stack. To get rid of
them it would be simple to allocate fixed length arrays on stack, but those
might become rather large. The other solution is to allocate the buffers in
the rs control structure, but this cannot be done as long as the structure
can be shared by several users. Sharing is desired because the RS polynom
tables are large and initialization is time consuming.

To solve this split the codec information out of the control structure and
have a pointer to a shared codec in it. Instantiate the control structure
for each user, create a new codec if no shareable is avaiable yet.  Adjust
all affected usage sites to the new scheme.

This allows to add per instance decoder buffers to the control structure
later on.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Boris Brezillon <boris.brezillon@bootlin.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Segher Boessenkool <segher@kernel.crashing.org>
Cc: Kernel Hardening <kernel-hardening@lists.openwall.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Mike Snitzer <snitzer@redhat.com>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Colin Cross <ccross@android.com>
Cc: Andrew Morton <akpm@linuxfoundation.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Alasdair Kergon <agk@redhat.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
Thomas Gleixner
2018-04-22 18:23:53 +02:00
committed by Kees Cook
parent a85e126abf
commit 2163398192
6 changed files with 100 additions and 70 deletions

View File

@@ -15,7 +15,7 @@
#include <linux/gfp.h> /* for GFP_KERNEL */
/**
* struct rs_control - rs control structure
* struct rs_codec - rs codec data
*
* @mm: Bits per symbol
* @nn: Symbols per block (= (1<<mm)-1)
@@ -29,9 +29,9 @@
* @gfpoly: The primitive generator polynominal
* @gffunc: Function to generate the field, if non-canonical representation
* @users: Users of this structure
* @list: List entry for the rs control list
* @list: List entry for the rs codec list
*/
struct rs_control {
struct rs_codec {
int mm;
int nn;
uint16_t *alpha_to;
@@ -47,6 +47,14 @@ struct rs_control {
struct list_head list;
};
/**
* struct rs_control - rs control structure per instance
* @codec: The codec used for this instance
*/
struct rs_control {
struct rs_codec *codec;
};
/* General purpose RS codec, 8-bit data width, symbol width 1-15 bit */
#ifdef CONFIG_REED_SOLOMON_ENC8
int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
@@ -69,7 +77,6 @@ int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
uint16_t *corr);
#endif
/* Create or get a matching rs control structure */
struct rs_control *init_rs_gfp(int symsize, int gfpoly, int fcr, int prim,
int nroots, gfp_t gfp);
@@ -100,7 +107,7 @@ void free_rs(struct rs_control *rs);
/** modulo replacement for galois field arithmetics
*
* @rs: the rs control structure
* @rs: Pointer to the RS codec
* @x: the value to reduce
*
* where
@@ -110,7 +117,7 @@ void free_rs(struct rs_control *rs);
* Simple arithmetic modulo would return a wrong result for values
* >= 3 * rs->nn
*/
static inline int rs_modnn(struct rs_control *rs, int x)
static inline int rs_modnn(struct rs_codec *rs, int x)
{
while (x >= rs->nn) {
x -= rs->nn;