|
|
3f3a1b |
* configure.ac (AC_CHECK_HEADERS_ONCE): Add feature detection for
|
|
|
3f3a1b |
sys/sdt.h probes.
|
|
|
3f3a1b |
* dfltcc.c (dfltcc_cc): Minor formatting improvements.
|
|
|
3f3a1b |
(HB_BITS): Remove.
|
|
|
3f3a1b |
(HB_SIZE): Likewise.
|
|
|
3f3a1b |
(is_dfltcc_enabled): Fix buffer overrun on newer models and incomplete
|
|
|
3f3a1b |
initialization on older models.
|
|
|
3f3a1b |
Add machine mode hint.
|
|
|
3f3a1b |
(dfltcc): Use sys/sdt.h feature detection.
|
|
|
3f3a1b |
(bi_load): New function.
|
|
|
3f3a1b |
(bi_close_block): Use bi_load.
|
|
|
3f3a1b |
(close_stream): Fix overwriting the End-of-block Symbol.
|
|
|
3f3a1b |
(dfltcc_deflate): Fix losing partial byte on flush.
|
|
|
3f3a1b |
Fix setting Block-Continuation Flag when DFLTCC-CMPR outputs 0 bits and
|
|
|
3f3a1b |
requests a retry.
|
|
|
3f3a1b |
Minor formatting improvements.
|
|
|
3f3a1b |
(dfltcc_inflate): Retry immediately if requested.
|
|
|
3f3a1b |
Print the hardware error code and flush the output buffer on error.
|
|
|
3f3a1b |
Minor formatting improvements.
|
|
|
3f3a1b |
* tests/hufts: Ignore the hardware error code.
|
|
|
3f3a1b |
---
|
|
|
3f3a1b |
configure.ac | 2 +-
|
|
|
3f3a1b |
dfltcc.c | 76 ++++++++++++++++++++++++++++++++++++----------------
|
|
|
3f3a1b |
tests/hufts | 2 ++
|
|
|
3f3a1b |
3 files changed, 56 insertions(+), 24 deletions(-)
|
|
|
3f3a1b |
|
|
|
3f3a1b |
diff --git a/configure.ac b/configure.ac
|
|
|
3f3a1b |
index 76ac26f..b4aea34 100644
|
|
|
3f3a1b |
--- a/configure.ac
|
|
|
3f3a1b |
+++ b/configure.ac
|
|
|
3f3a1b |
@@ -263,7 +263,7 @@ AC_SUBST([ASFLAGS_config])
|
|
|
3f3a1b |
AC_ISC_POSIX
|
|
|
3f3a1b |
AC_C_CONST
|
|
|
3f3a1b |
AC_HEADER_STDC
|
|
|
3f3a1b |
-AC_CHECK_HEADERS_ONCE(fcntl.h limits.h memory.h time.h)
|
|
|
3f3a1b |
+AC_CHECK_HEADERS_ONCE(fcntl.h limits.h memory.h time.h sys/sdt.h)
|
|
|
3f3a1b |
AC_CHECK_FUNCS_ONCE([chown fchmod fchown lstat siginterrupt])
|
|
|
3f3a1b |
AC_HEADER_DIRENT
|
|
|
3f3a1b |
AC_TYPE_SIGNAL
|
|
|
3f3a1b |
diff --git a/dfltcc.c b/dfltcc.c
|
|
|
3f3a1b |
index ba62968..ed3be8d 100644
|
|
|
3f3a1b |
--- a/dfltcc.c
|
|
|
3f3a1b |
+++ b/dfltcc.c
|
|
|
3f3a1b |
@@ -22,7 +22,7 @@
|
|
|
3f3a1b |
#include <stdbool.h>
|
|
|
3f3a1b |
#include <stdlib.h>
|
|
|
3f3a1b |
|
|
|
3f3a1b |
-#ifdef DFLTCC_USDT
|
|
|
3f3a1b |
+#ifdef HAVE_SYS_SDT_H
|
|
|
3f3a1b |
# include <sys/sdt.h>
|
|
|
3f3a1b |
#endif
|
|
|
3f3a1b |
|
|
|
3f3a1b |
@@ -39,11 +39,11 @@
|
|
|
3f3a1b |
|
|
|
3f3a1b |
typedef enum
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
- DFLTCC_CC_OK = 0,
|
|
|
3f3a1b |
- DFLTCC_CC_OP1_TOO_SHORT = 1,
|
|
|
3f3a1b |
- DFLTCC_CC_OP2_TOO_SHORT = 2,
|
|
|
3f3a1b |
- DFLTCC_CC_OP2_CORRUPT = 2,
|
|
|
3f3a1b |
- DFLTCC_CC_AGAIN = 3,
|
|
|
3f3a1b |
+ DFLTCC_CC_OK = 0,
|
|
|
3f3a1b |
+ DFLTCC_CC_OP1_TOO_SHORT = 1,
|
|
|
3f3a1b |
+ DFLTCC_CC_OP2_TOO_SHORT = 2,
|
|
|
3f3a1b |
+ DFLTCC_CC_OP2_CORRUPT = 2,
|
|
|
3f3a1b |
+ DFLTCC_CC_AGAIN = 3,
|
|
|
3f3a1b |
} dfltcc_cc;
|
|
|
3f3a1b |
|
|
|
3f3a1b |
#define DFLTCC_QAF 0
|
|
|
3f3a1b |
@@ -51,8 +51,6 @@ typedef enum
|
|
|
3f3a1b |
#define DFLTCC_CMPR 2
|
|
|
3f3a1b |
#define DFLTCC_XPND 4
|
|
|
3f3a1b |
#define HBT_CIRCULAR (1 << 7)
|
|
|
3f3a1b |
-/* #define HB_BITS 15 */
|
|
|
3f3a1b |
-/* #define HB_SIZE (1 << HB_BITS) */
|
|
|
3f3a1b |
#define DFLTCC_FACILITY 151
|
|
|
3f3a1b |
#define DFLTCC_FMT0 0
|
|
|
3f3a1b |
#define CVT_CRC32 0
|
|
|
3f3a1b |
@@ -155,9 +153,16 @@ is_dfltcc_enabled (void)
|
|
|
3f3a1b |
if (env && !strcmp (env, "0"))
|
|
|
3f3a1b |
return 0;
|
|
|
3f3a1b |
|
|
|
3f3a1b |
- register int r0 __asm__ ("r0") = sizeof facilities / 8;
|
|
|
3f3a1b |
- __asm__ ("stfle %[facilities]\n"
|
|
|
3f3a1b |
- : [facilities] "=Q"(facilities) : [r0] "r"(r0) : "cc", "memory");
|
|
|
3f3a1b |
+ memset (facilities, 0, sizeof facilities);
|
|
|
3f3a1b |
+ register char r0 __asm__ ("r0") = sizeof facilities / 8 - 1;
|
|
|
3f3a1b |
+ /* STFLE is supported since z9-109 and only in z/Architecture mode. When
|
|
|
3f3a1b |
+ * compiling with -m31, gcc defaults to ESA mode, however, since the kernel
|
|
|
3f3a1b |
+ * is 64-bit, it's always z/Architecture mode at runtime. */
|
|
|
3f3a1b |
+ __asm__ (".machinemode push\n"
|
|
|
3f3a1b |
+ ".machinemode zarch\n"
|
|
|
3f3a1b |
+ "stfle %[facilities]\n"
|
|
|
3f3a1b |
+ ".machinemode pop\n"
|
|
|
3f3a1b |
+ : [facilities] "=Q"(facilities), [r0] "+r"(r0) :: "cc");
|
|
|
3f3a1b |
return is_bit_set (facilities, DFLTCC_FACILITY);
|
|
|
3f3a1b |
}
|
|
|
3f3a1b |
|
|
|
3f3a1b |
@@ -180,12 +185,12 @@ dfltcc (int fn, void *param,
|
|
|
3f3a1b |
int cc;
|
|
|
3f3a1b |
|
|
|
3f3a1b |
__asm__ volatile (
|
|
|
3f3a1b |
-#ifdef DFLTCC_USDT
|
|
|
3f3a1b |
+#ifdef HAVE_SYS_SDT_H
|
|
|
3f3a1b |
STAP_PROBE_ASM (zlib, dfltcc_entry,
|
|
|
3f3a1b |
STAP_PROBE_ASM_TEMPLATE (5))
|
|
|
3f3a1b |
#endif
|
|
|
3f3a1b |
".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
|
|
|
3f3a1b |
-#ifdef DFLTCC_USDT
|
|
|
3f3a1b |
+#ifdef HAVE_SYS_SDT_H
|
|
|
3f3a1b |
STAP_PROBE_ASM (zlib, dfltcc_exit,
|
|
|
3f3a1b |
STAP_PROBE_ASM_TEMPLATE (5))
|
|
|
3f3a1b |
#endif
|
|
|
3f3a1b |
@@ -198,7 +203,7 @@ dfltcc (int fn, void *param,
|
|
|
3f3a1b |
: [r0] "r" (r0)
|
|
|
3f3a1b |
, [r1] "r" (r1)
|
|
|
3f3a1b |
, [hist] "r" (hist)
|
|
|
3f3a1b |
-#ifdef DFLTCC_USDT
|
|
|
3f3a1b |
+#ifdef HAVE_SYS_SDT_H
|
|
|
3f3a1b |
, STAP_PROBE_ASM_OPERANDS (5, r2, r3, r4, r5, hist)
|
|
|
3f3a1b |
#endif
|
|
|
3f3a1b |
: "cc", "memory");
|
|
|
3f3a1b |
@@ -264,10 +269,16 @@ init_param (union aligned_dfltcc_param_v0 *ctx)
|
|
|
3f3a1b |
}
|
|
|
3f3a1b |
|
|
|
3f3a1b |
static void
|
|
|
3f3a1b |
-bi_close_block (struct dfltcc_param_v0 *param)
|
|
|
3f3a1b |
+bi_load (struct dfltcc_param_v0 *param)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
bi_valid = param->sbb;
|
|
|
3f3a1b |
bi_buf = bi_valid == 0 ? 0 : outbuf[outcnt] & ((1 << bi_valid) - 1);
|
|
|
3f3a1b |
+}
|
|
|
3f3a1b |
+
|
|
|
3f3a1b |
+static void
|
|
|
3f3a1b |
+bi_close_block (struct dfltcc_param_v0 *param)
|
|
|
3f3a1b |
+{
|
|
|
3f3a1b |
+ bi_load (param);
|
|
|
3f3a1b |
send_bits (bi_reverse (param->eobs >> (15 - param->eobl), param->eobl),
|
|
|
3f3a1b |
param->eobl);
|
|
|
3f3a1b |
param->bcf = 0;
|
|
|
3f3a1b |
@@ -278,6 +289,7 @@ close_block (struct dfltcc_param_v0 *param)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
bi_close_block (param);
|
|
|
3f3a1b |
bi_windup ();
|
|
|
3f3a1b |
+ /* bi_windup has written out a possibly partial byte, fix up the position */
|
|
|
3f3a1b |
param->sbb = (param->sbb + param->eobl) % 8;
|
|
|
3f3a1b |
if (param->sbb != 0)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
@@ -291,6 +303,8 @@ close_stream (struct dfltcc_param_v0 *param)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
if (param->bcf)
|
|
|
3f3a1b |
bi_close_block (param);
|
|
|
3f3a1b |
+ else
|
|
|
3f3a1b |
+ bi_load (param);
|
|
|
3f3a1b |
send_bits (1, 3); /* BFINAL=1, BTYPE=00 */
|
|
|
3f3a1b |
bi_windup ();
|
|
|
3f3a1b |
put_short (0x0000);
|
|
|
3f3a1b |
@@ -334,7 +348,16 @@ dfltcc_deflate (int pack_level)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
/* Flush the output data. */
|
|
|
3f3a1b |
if (outcnt > OUTBUFSIZ - 8)
|
|
|
3f3a1b |
- flush_outbuf ();
|
|
|
3f3a1b |
+ {
|
|
|
3f3a1b |
+ if (param->sbb == 0)
|
|
|
3f3a1b |
+ flush_outbuf ();
|
|
|
3f3a1b |
+ else
|
|
|
3f3a1b |
+ {
|
|
|
3f3a1b |
+ uch partial = outbuf[outcnt];
|
|
|
3f3a1b |
+ flush_outbuf ();
|
|
|
3f3a1b |
+ outbuf[outcnt] = partial;
|
|
|
3f3a1b |
+ }
|
|
|
3f3a1b |
+ }
|
|
|
3f3a1b |
|
|
|
3f3a1b |
/* Close the block. */
|
|
|
3f3a1b |
if (param->bcf && total_in == block_threshold && !param->cf)
|
|
|
3f3a1b |
@@ -360,14 +383,16 @@ dfltcc_deflate (int pack_level)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
if (total_in == 0 && block_threshold > 0)
|
|
|
3f3a1b |
param->htt = HTT_FIXED;
|
|
|
3f3a1b |
- else {
|
|
|
3f3a1b |
- param->htt = HTT_DYNAMIC;
|
|
|
3f3a1b |
- dfltcc_gdht (param);
|
|
|
3f3a1b |
- }
|
|
|
3f3a1b |
+ else
|
|
|
3f3a1b |
+ {
|
|
|
3f3a1b |
+ param->htt = HTT_DYNAMIC;
|
|
|
3f3a1b |
+ dfltcc_gdht (param);
|
|
|
3f3a1b |
+ }
|
|
|
3f3a1b |
}
|
|
|
3f3a1b |
|
|
|
3f3a1b |
/* Compress inbuf into outbuf. */
|
|
|
3f3a1b |
- dfltcc_cmpr_xpnd (param, DFLTCC_CMPR);
|
|
|
3f3a1b |
+ while (dfltcc_cmpr_xpnd (param, DFLTCC_CMPR) == DFLTCC_CC_AGAIN)
|
|
|
3f3a1b |
+ ;
|
|
|
3f3a1b |
|
|
|
3f3a1b |
/* Unmask the input data. */
|
|
|
3f3a1b |
insize += extra;
|
|
|
3f3a1b |
@@ -413,7 +438,9 @@ dfltcc_inflate (void)
|
|
|
3f3a1b |
}
|
|
|
3f3a1b |
|
|
|
3f3a1b |
/* Decompress inbuf into outbuf. */
|
|
|
3f3a1b |
- dfltcc_cc cc = dfltcc_cmpr_xpnd (param, DFLTCC_XPND);
|
|
|
3f3a1b |
+ dfltcc_cc cc;
|
|
|
3f3a1b |
+ while ((cc = dfltcc_cmpr_xpnd (param, DFLTCC_XPND)) == DFLTCC_CC_AGAIN)
|
|
|
3f3a1b |
+ ;
|
|
|
3f3a1b |
if (cc == DFLTCC_CC_OK)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
/* The entire deflate stream has been successfully decompressed. */
|
|
|
3f3a1b |
@@ -422,6 +449,9 @@ dfltcc_inflate (void)
|
|
|
3f3a1b |
if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0)
|
|
|
3f3a1b |
{
|
|
|
3f3a1b |
/* The deflate stream is corrupted. */
|
|
|
3f3a1b |
+ fprintf (stderr, "Operation-Ending-Supplemental Code 0x%x\n",
|
|
|
3f3a1b |
+ param->oesc);
|
|
|
3f3a1b |
+ flush_outbuf ();
|
|
|
3f3a1b |
return 2;
|
|
|
3f3a1b |
}
|
|
|
3f3a1b |
/* There must be more data to decompress. */
|