brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 1050927 Raw
132 lines · c
1// SPDX-License-Identifier: Zlib2#ifndef DFLTCC_UTIL_H3#define DFLTCC_UTIL_H4 5#include "dfltcc.h"6#include <linux/kmsan-checks.h>7#include <linux/zutil.h>8 9/*10 * C wrapper for the DEFLATE CONVERSION CALL instruction.11 */12typedef enum {13    DFLTCC_CC_OK = 0,14    DFLTCC_CC_OP1_TOO_SHORT = 1,15    DFLTCC_CC_OP2_TOO_SHORT = 2,16    DFLTCC_CC_OP2_CORRUPT = 2,17    DFLTCC_CC_AGAIN = 3,18} dfltcc_cc;19 20#define DFLTCC_QAF 021#define DFLTCC_GDHT 122#define DFLTCC_CMPR 223#define DFLTCC_XPND 424#define HBT_CIRCULAR (1 << 7)25#define DFLTCC_FN_MASK ((1 << 7) - 1)26#define HB_BITS 1527#define HB_SIZE (1 << HB_BITS)28 29static inline dfltcc_cc dfltcc(30    int fn,31    void *param,32    Byte **op1,33    size_t *len1,34    const Byte **op2,35    size_t *len2,36    void *hist37)38{39    Byte *t2 = op1 ? *op1 : NULL;40    unsigned char *orig_t2 = t2;41    size_t t3 = len1 ? *len1 : 0;42    const Byte *t4 = op2 ? *op2 : NULL;43    size_t t5 = len2 ? *len2 : 0;44    register int r0 __asm__("r0") = fn;45    register void *r1 __asm__("r1") = param;46    register Byte *r2 __asm__("r2") = t2;47    register size_t r3 __asm__("r3") = t3;48    register const Byte *r4 __asm__("r4") = t4;49    register size_t r5 __asm__("r5") = t5;50    int cc;51 52    __asm__ volatile(53                     ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"54                     "ipm %[cc]\n"55                     : [r2] "+r" (r2)56                     , [r3] "+r" (r3)57                     , [r4] "+r" (r4)58                     , [r5] "+r" (r5)59                     , [cc] "=r" (cc)60                     : [r0] "r" (r0)61                     , [r1] "r" (r1)62                     , [hist] "r" (hist)63                     : "cc", "memory");64    t2 = r2; t3 = r3; t4 = r4; t5 = r5;65 66    /*67     * Unpoison the parameter block and the output buffer.68     * This is a no-op in non-KMSAN builds.69     */70    switch (fn & DFLTCC_FN_MASK) {71    case DFLTCC_QAF:72        kmsan_unpoison_memory(param, sizeof(struct dfltcc_qaf_param));73        break;74    case DFLTCC_GDHT:75        kmsan_unpoison_memory(param, offsetof(struct dfltcc_param_v0, csb));76        break;77    case DFLTCC_CMPR:78        kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));79        kmsan_unpoison_memory(80                orig_t2,81                t2 - orig_t2 +82                    (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));83        break;84    case DFLTCC_XPND:85        kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));86        kmsan_unpoison_memory(orig_t2, t2 - orig_t2);87        break;88    }89 90    if (op1)91        *op1 = t2;92    if (len1)93        *len1 = t3;94    if (op2)95        *op2 = t4;96    if (len2)97        *len2 = t5;98    return (cc >> 28) & 3;99}100 101static inline int is_bit_set(102    const char *bits,103    int n104)105{106    return bits[n / 8] & (1 << (7 - (n % 8)));107}108 109static inline void turn_bit_off(110    char *bits,111    int n112)113{114    bits[n / 8] &= ~(1 << (7 - (n % 8)));115}116 117static inline int dfltcc_are_params_ok(118    int level,119    uInt window_bits,120    int strategy,121    uLong level_mask122)123{124    return (level_mask & (1 << level)) != 0 &&125        (window_bits == HB_BITS) &&126        (strategy == Z_DEFAULT_STRATEGY);127}128 129char *oesc_msg(char *buf, int oesc);130 131#endif /* DFLTCC_UTIL_H */132