]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
IBM Z DFLTCC: Test with MSan
authorIlya Leoshkevich <iii@linux.ibm.com>
Tue, 14 Jun 2022 09:19:29 +0000 (11:19 +0200)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Fri, 17 Mar 2023 20:27:56 +0000 (21:27 +0100)
* Add __msan_unpoison() calls to DFLTCC inline assembly.
* Make parameter block sizes symbolic constants.
* Move dfltcc() definition after struct dfltcc_param_v0 definition.

Backported from commit 1f5ddcc009ac3511e99fc88736a9e1a6381168c5.

arch/s390/dfltcc_detail.h
arch/s390/self-hosted-builder/actions-runner.Dockerfile

index 4ec03f8097dc650b80086ae91bc9a21c9f4eb1eb..411e9f6c7d3b9015fc8979c310382c0e8e12d7b9 100644 (file)
 #define DFLTCC_RIBM 0
 #endif
 
-/*
-   C wrapper for the DEFLATE CONVERSION CALL instruction.
- */
-typedef enum {
-    DFLTCC_CC_OK = 0,
-    DFLTCC_CC_OP1_TOO_SHORT = 1,
-    DFLTCC_CC_OP2_TOO_SHORT = 2,
-    DFLTCC_CC_OP2_CORRUPT = 2,
-    DFLTCC_CC_AGAIN = 3,
-} dfltcc_cc;
-
-#define DFLTCC_QAF 0
-#define DFLTCC_GDHT 1
-#define DFLTCC_CMPR 2
-#define DFLTCC_XPND 4
-#define HBT_CIRCULAR (1 << 7)
-#define HB_BITS 15
-#define HB_SIZE (1 << HB_BITS)
-#define DFLTCC_FACILITY 151
-
-static inline dfltcc_cc dfltcc(int fn, void *param,
-                               unsigned char **op1, size_t *len1, z_const unsigned char **op2, size_t *len2, void *hist) {
-    unsigned char *t2 = op1 ? *op1 : NULL;
-    size_t t3 = len1 ? *len1 : 0;
-    z_const unsigned char *t4 = op2 ? *op2 : NULL;
-    size_t t5 = len2 ? *len2 : 0;
-    Z_REGISTER int r0 __asm__("r0") = fn;
-    Z_REGISTER void *r1 __asm__("r1") = param;
-    Z_REGISTER unsigned char *r2 __asm__("r2") = t2;
-    Z_REGISTER size_t r3 __asm__("r3") = t3;
-    Z_REGISTER z_const unsigned char *r4 __asm__("r4") = t4;
-    Z_REGISTER size_t r5 __asm__("r5") = t5;
-    int cc;
-
-    __asm__ volatile(
-#ifdef HAVE_SYS_SDT_H
-                     STAP_PROBE_ASM(zlib, dfltcc_entry, STAP_PROBE_ASM_TEMPLATE(5))
-#endif
-                     ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
-#ifdef HAVE_SYS_SDT_H
-                     STAP_PROBE_ASM(zlib, dfltcc_exit, STAP_PROBE_ASM_TEMPLATE(5))
-#endif
-                     "ipm %[cc]\n"
-                     : [r2] "+r" (r2)
-                     , [r3] "+r" (r3)
-                     , [r4] "+r" (r4)
-                     , [r5] "+r" (r5)
-                     , [cc] "=r" (cc)
-                     : [r0] "r" (r0)
-                     , [r1] "r" (r1)
-                     , [hist] "r" (hist)
-#ifdef HAVE_SYS_SDT_H
-                     , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist)
-#endif
-                     : "cc", "memory");
-    t2 = r2; t3 = r3; t4 = r4; t5 = r5;
-
-    if (op1)
-        *op1 = t2;
-    if (len1)
-        *len1 = t3;
-    if (op2)
-        *op2 = t4;
-    if (len2)
-        *len2 = t5;
-    return (cc >> 28) & 3;
-}
-
 /*
    Parameter Block for Query Available Functions.
  */
@@ -105,7 +37,8 @@ struct dfltcc_qaf_param {
     char reserved2[6];
 };
 
-static_assert(sizeof(struct dfltcc_qaf_param) == 32, sizeof_struct_dfltcc_qaf_param_is_32);
+#define DFLTCC_SIZEOF_QAF 32
+static_assert(sizeof(struct dfltcc_qaf_param) == DFLTCC_SIZEOF_QAF, qaf);
 
 static inline int is_bit_set(const char *bits, int n) {
     return bits[n / 8] & (1 << (7 - (n % 8)));
@@ -115,6 +48,8 @@ static inline void clear_bit(char *bits, int n) {
     bits[n / 8] &= ~(1 << (7 - (n % 8)));
 }
 
+#define DFLTCC_FACILITY 151
+
 #define DFLTCC_FMT0 0
 
 /*
@@ -165,12 +100,16 @@ struct dfltcc_param_v0 {
     uint16_t cdhtl : 12;               /* Compressed-Dynamic-Huffman Table
                                           Length */
     uint8_t reserved464[6];
-    uint8_t cdht[288];
-    uint8_t reserved[32];
-    uint8_t csb[1152];
+    uint8_t cdht[288];                 /* Compressed-Dynamic-Huffman Table */
+    uint8_t reserved[24];
+    uint8_t ribm2[8];                  /* Reserved for IBM use */
+    uint8_t csb[1152];                 /* Continuation-State Buffer */
 };
 
-static_assert(sizeof(struct dfltcc_param_v0) == 1536, sizeof_struct_dfltcc_param_v0_is_1536);
+#define DFLTCC_SIZEOF_GDHT_V0 384
+#define DFLTCC_SIZEOF_CMPR_XPND_V0 1536
+static_assert(offsetof(struct dfltcc_param_v0, csb) == DFLTCC_SIZEOF_GDHT_V0, gdht_v0);
+static_assert(sizeof(struct dfltcc_param_v0) == DFLTCC_SIZEOF_CMPR_XPND_V0, cmpr_xpnd_v0);
 
 static inline z_const char *oesc_msg(char *buf, int oesc) {
     if (oesc == 0x00)
@@ -181,6 +120,97 @@ static inline z_const char *oesc_msg(char *buf, int oesc) {
     }
 }
 
+/*
+   C wrapper for the DEFLATE CONVERSION CALL instruction.
+ */
+typedef enum {
+    DFLTCC_CC_OK = 0,
+    DFLTCC_CC_OP1_TOO_SHORT = 1,
+    DFLTCC_CC_OP2_TOO_SHORT = 2,
+    DFLTCC_CC_OP2_CORRUPT = 2,
+    DFLTCC_CC_AGAIN = 3,
+} dfltcc_cc;
+
+#define DFLTCC_QAF 0
+#define DFLTCC_GDHT 1
+#define DFLTCC_CMPR 2
+#define DFLTCC_XPND 4
+#define HBT_CIRCULAR (1 << 7)
+#define DFLTCC_FN_MASK ((1 << 7) - 1)
+#define HB_BITS 15
+#define HB_SIZE (1 << HB_BITS)
+
+static inline dfltcc_cc dfltcc(int fn, void *param,
+                               unsigned char **op1, size_t *len1,
+                               z_const unsigned char **op2, size_t *len2, void *hist) {
+    unsigned char *t2 = op1 ? *op1 : NULL;
+#ifdef Z_MEMORY_SANITIZER
+    unsigned char *orig_t2 = t2;
+#endif
+    size_t t3 = len1 ? *len1 : 0;
+    z_const unsigned char *t4 = op2 ? *op2 : NULL;
+    size_t t5 = len2 ? *len2 : 0;
+    Z_REGISTER int r0 __asm__("r0") = fn;
+    Z_REGISTER void *r1 __asm__("r1") = param;
+    Z_REGISTER unsigned char *r2 __asm__("r2") = t2;
+    Z_REGISTER size_t r3 __asm__("r3") = t3;
+    Z_REGISTER z_const unsigned char *r4 __asm__("r4") = t4;
+    Z_REGISTER size_t r5 __asm__("r5") = t5;
+    int cc;
+
+    __asm__ volatile(
+#ifdef HAVE_SYS_SDT_H
+                     STAP_PROBE_ASM(zlib, dfltcc_entry, STAP_PROBE_ASM_TEMPLATE(5))
+#endif
+                     ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
+#ifdef HAVE_SYS_SDT_H
+                     STAP_PROBE_ASM(zlib, dfltcc_exit, STAP_PROBE_ASM_TEMPLATE(5))
+#endif
+                     "ipm %[cc]\n"
+                     : [r2] "+r" (r2)
+                     , [r3] "+r" (r3)
+                     , [r4] "+r" (r4)
+                     , [r5] "+r" (r5)
+                     , [cc] "=r" (cc)
+                     : [r0] "r" (r0)
+                     , [r1] "r" (r1)
+                     , [hist] "r" (hist)
+#ifdef HAVE_SYS_SDT_H
+                     , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist)
+#endif
+                     : "cc", "memory");
+    t2 = r2; t3 = r3; t4 = r4; t5 = r5;
+
+#ifdef Z_MEMORY_SANITIZER
+    switch (fn & DFLTCC_FN_MASK) {
+    case DFLTCC_QAF:
+        __msan_unpoison(param, DFLTCC_SIZEOF_QAF);
+        break;
+    case DFLTCC_GDHT:
+        __msan_unpoison(param, DFLTCC_SIZEOF_GDHT_V0);
+        break;
+    case DFLTCC_CMPR:
+        __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0);
+        __msan_unpoison(orig_t2, t2 - orig_t2 + (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));
+        break;
+    case DFLTCC_XPND:
+        __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0);
+        __msan_unpoison(orig_t2, t2 - orig_t2);
+        break;
+    }
+#endif
+
+    if (op1)
+        *op1 = t2;
+    if (len1)
+        *len1 = t3;
+    if (op2)
+        *op2 = t4;
+    if (len2)
+        *len2 = t5;
+    return (cc >> 28) & 3;
+}
+
 /*
    Extension of inflate_state and deflate_state. Must be doubleword-aligned.
 */
index a4bb774ab00fe5f4828f799f17e4d297cff73190..a55a74df4ff4a7dab10628f955a472544f56218f 100644 (file)
@@ -11,11 +11,13 @@ FROM s390x/ubuntu:20.04
 # Packages for zlib-ng testing.
 ENV DEBIAN_FRONTEND=noninteractive
 RUN apt-get update && apt-get -y install \
+        clang-11 \
         cmake \
         curl \
         gcc \
         git \
         jq \
+        llvm-11-tools \
         ninja-build \
         python-is-python3 \
         python3 \