]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
IBM Z DFLTCC: fix 31-bit build
authorIlya Leoshkevich <iii@linux.ibm.com>
Mon, 8 Jul 2019 13:23:12 +0000 (15:23 +0200)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Thu, 18 Jul 2019 09:23:50 +0000 (11:23 +0200)
* Add machine mode hint for STFLE.
* Adjust offset calculations.

arch/s390/dfltcc_common.c
arch/s390/dfltcc_detail.h

index 2f2e22fd091e0a84909f0af0506b478fc99c09eb..91a242f514e7dd4c9942233c4e3198c1cc3d363c 100644 (file)
@@ -19,13 +19,21 @@ static inline int is_dfltcc_enabled(void)
 
     memset(facilities, 0, sizeof(facilities));
     r0 = sizeof(facilities) / sizeof(facilities[0]) - 1;
-    __asm__ volatile("stfle %[facilities]\n" : [facilities] "=Q" (facilities), [r0] "+r" (r0) :: "cc");
+    /* STFLE is supported since z9-109 and only in z/Architecture mode. When
+     * compiling with -m31, gcc defaults to ESA mode, however, since the kernel
+     * is 64-bit, it's always z/Architecture mode at runtime.
+     */
+    __asm__ volatile(".machinemode push\n"
+                     ".machinemode zarch\n"
+                     "stfle %[facilities]\n"
+                     ".machinemode pop\n"
+                     : [facilities] "=Q" (facilities), [r0] "+r" (r0) :: "cc");
     return is_bit_set((const char *)facilities, DFLTCC_FACILITY);
 }
 
 void ZLIB_INTERNAL dfltcc_reset(PREFIX3(streamp) strm, uInt size)
 {
-    struct dfltcc_state *dfltcc_state = (struct dfltcc_state *)((char *)strm->state + size);
+    struct dfltcc_state *dfltcc_state = (struct dfltcc_state *)((char *)strm->state + ALIGN_UP(size, 8));
     struct dfltcc_qaf_param *param = (struct dfltcc_qaf_param *)&dfltcc_state->param;
 
     /* Initialize available functions */
@@ -49,20 +57,16 @@ void ZLIB_INTERNAL dfltcc_reset(PREFIX3(streamp) strm, uInt size)
 
 void ZLIB_INTERNAL *dfltcc_alloc_state(PREFIX3(streamp) strm, uInt items, uInt size)
 {
-    Assert((items * size) % 8 == 0,
-           "The size of zlib-ng state must be a multiple of 8");
-    return ZALLOC(strm, items * size + sizeof(struct dfltcc_state), sizeof(unsigned char));
+    return ZALLOC(strm, ALIGN_UP(items * size, 8) + sizeof(struct dfltcc_state), sizeof(unsigned char));
 }
 
 void ZLIB_INTERNAL dfltcc_copy_state(void *dst, const void *src, uInt size)
 {
-    memcpy(dst, src, size + sizeof(struct dfltcc_state));
+    memcpy(dst, src, ALIGN_UP(size, 8) + sizeof(struct dfltcc_state));
 }
 
 static const int PAGE_ALIGN = 0x1000;
 
-#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
-
 void ZLIB_INTERNAL *dfltcc_alloc_window(PREFIX3(streamp) strm, uInt items, uInt size)
 {
     void *p;
index 156b2a289f13cfcea4b0aa7367139d2ef775445f..513aa954facc78a8d7b684c2ea52970e69b4abda 100644 (file)
@@ -198,4 +198,6 @@ struct dfltcc_state {
     char msg[64];                      /* Buffer for strm->msg */
 };
 
-#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((state) + 1))
+#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
+
+#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8)))