^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Sami Tolvanen <samitolvanen@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef DM_VERITY_FEC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define DM_VERITY_FEC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "dm-verity.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/rslib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* Reed-Solomon(M, N) parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define DM_VERITY_FEC_RSM 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define DM_VERITY_FEC_MAX_RSN 253
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define DM_VERITY_FEC_MIN_RSN 231 /* ~10% space overhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* buffers for deinterleaving and decoding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DM_VERITY_FEC_BUF_PREALLOC 1 /* buffers to preallocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DM_VERITY_FEC_BUF_RS_BITS 4 /* 1 << RS blocks per buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* we need buffers for at most 1 << block size RS blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define DM_VERITY_FEC_BUF_MAX \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* maximum recursion level for verity_fec_decode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DM_VERITY_FEC_MAX_RECURSION 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define DM_VERITY_OPT_FEC_START "fec_start"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DM_VERITY_OPT_FEC_ROOTS "fec_roots"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct dm_verity_fec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct dm_dev *dev; /* parity data device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct dm_bufio_client *data_bufio; /* for data dev access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct dm_bufio_client *bufio; /* for parity data access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) size_t io_size; /* IO size for roots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) sector_t start; /* parity data start in blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) sector_t blocks; /* number of blocks covered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) sector_t rounds; /* number of interleaving rounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) sector_t hash_blocks; /* blocks covered after v->hash_start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned char roots; /* number of parity bytes, M-N of RS(M, N) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned char rsn; /* N of RS(M, N) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mempool_t rs_pool; /* mempool for fio->rs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mempool_t prealloc_pool; /* mempool for preallocated buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) mempool_t extra_pool; /* mempool for extra buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mempool_t output_pool; /* mempool for output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct kmem_cache *cache; /* cache for buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* per-bio data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct dm_verity_fec_io {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct rs_control *rs; /* Reed-Solomon state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int erasures[DM_VERITY_FEC_MAX_RSN]; /* erasures for decode_rs8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 *bufs[DM_VERITY_FEC_BUF_MAX]; /* bufs for deinterleaving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned nbufs; /* number of buffers allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u8 *output; /* buffer for corrected output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) size_t output_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned level; /* recursion level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #ifdef CONFIG_DM_VERITY_FEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* each feature parameter requires a value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define DM_VERITY_OPTS_FEC 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) extern bool verity_fec_is_enabled(struct dm_verity *v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) extern int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) enum verity_block_type type, sector_t block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 *dest, struct bvec_iter *iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) extern unsigned verity_fec_status_table(struct dm_verity *v, unsigned sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) char *result, unsigned maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) extern void verity_fec_finish_io(struct dm_verity_io *io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) extern void verity_fec_init_io(struct dm_verity_io *io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) extern bool verity_is_fec_opt_arg(const char *arg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) extern int verity_fec_parse_opt_args(struct dm_arg_set *as,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct dm_verity *v, unsigned *argc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char *arg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) extern void verity_fec_dtr(struct dm_verity *v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) extern int verity_fec_ctr_alloc(struct dm_verity *v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) extern int verity_fec_ctr(struct dm_verity *v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #else /* !CONFIG_DM_VERITY_FEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define DM_VERITY_OPTS_FEC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static inline bool verity_fec_is_enabled(struct dm_verity *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline int verity_fec_decode(struct dm_verity *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct dm_verity_io *io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) enum verity_block_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sector_t block, u8 *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct bvec_iter *iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static inline unsigned verity_fec_status_table(struct dm_verity *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned sz, char *result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static inline void verity_fec_finish_io(struct dm_verity_io *io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static inline void verity_fec_init_io(struct dm_verity_io *io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static inline bool verity_is_fec_opt_arg(const char *arg_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline int verity_fec_parse_opt_args(struct dm_arg_set *as,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct dm_verity *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned *argc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) const char *arg_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static inline void verity_fec_dtr(struct dm_verity *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static inline int verity_fec_ctr_alloc(struct dm_verity *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static inline int verity_fec_ctr(struct dm_verity *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #endif /* CONFIG_DM_VERITY_FEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #endif /* DM_VERITY_FEC_H */