From: Ilya Leoshkevich Date: Mon, 3 Jun 2019 14:47:14 +0000 (+0200) Subject: IBM Z DFLTCC: fix STFLE usage X-Git-Tag: 1.9.9-b1~476 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=563263bb1c508cf74314f8d623477898ea7a996a;p=thirdparty%2Fzlib-ng.git IBM Z DFLTCC: fix STFLE usage QEMU maintainers have found and issue related to incorrect usage of STFLE instruction [1], which is used to get features supported by the machine. There are three potential problems with the current usage: - R0 must contain the number of requested doublewords *minus one*. The existing code lacks the "minus one" part. - Older machines may not fill all the doublewords - this is fixed by calling `memset`. - STFLE updates R0, but we don't tell the compiler about this - this is fixed by using a `+` constraint. - Not really a problem, but it's enough to load 8 bits into R0, so its type was changed to `uint8_t`. Also, STFLE only writes to `facilities` variable, therefore memory clobber is unnecessary. [1] https://lists.gnu.org/archive/html/qemu-devel/2019-06/msg00113.html --- diff --git a/arch/s390/dfltcc_common.c b/arch/s390/dfltcc_common.c index 98c9765b9..2f2e22fd0 100644 --- a/arch/s390/dfltcc_common.c +++ b/arch/s390/dfltcc_common.c @@ -15,13 +15,11 @@ static inline int is_dfltcc_enabled(void) { uint64_t facilities[(DFLTCC_FACILITY / 64) + 1]; - register int r0 __asm__("r0"); + register uint8_t r0 __asm__("r0"); - r0 = sizeof(facilities) / sizeof(facilities[0]); - __asm__ volatile("stfle %[facilities]\n" - : [facilities] "=Q" (facilities) - : [r0] "r" (r0) - : "cc", "memory"); + memset(facilities, 0, sizeof(facilities)); + r0 = sizeof(facilities) / sizeof(facilities[0]) - 1; + __asm__ volatile("stfle %[facilities]\n" : [facilities] "=Q" (facilities), [r0] "+r" (r0) :: "cc"); return is_bit_set((const char *)facilities, DFLTCC_FACILITY); }