All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Christophe Leroy <christophe.leroy@csgroup.eu>,
	Segher Boessenkool <segher@kernel.crashing.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.14 12/29] powerpc/bitops: Fix possible undefined behaviour with fls() and fls64()
Date: Thu,  7 Jan 2021 15:31:27 +0100	[thread overview]
Message-ID: <20210107143054.693870389@linuxfoundation.org> (raw)
In-Reply-To: <20210107143052.973437064@linuxfoundation.org>

From: Christophe Leroy <christophe.leroy@csgroup.eu>

[ Upstream commit 1891ef21d92c4801ea082ee8ed478e304ddc6749 ]

fls() and fls64() are using __builtin_ctz() and _builtin_ctzll().
On powerpc, those builtins trivially use ctlzw and ctlzd power
instructions.

Allthough those instructions provide the expected result with
input argument 0, __builtin_ctz() and __builtin_ctzll() are
documented as undefined for value 0.

The easiest fix would be to use fls() and fls64() functions
defined in include/asm-generic/bitops/builtin-fls.h and
include/asm-generic/bitops/fls64.h, but GCC output is not optimal:

00000388 <testfls>:
 388:   2c 03 00 00     cmpwi   r3,0
 38c:   41 82 00 10     beq     39c <testfls+0x14>
 390:   7c 63 00 34     cntlzw  r3,r3
 394:   20 63 00 20     subfic  r3,r3,32
 398:   4e 80 00 20     blr
 39c:   38 60 00 00     li      r3,0
 3a0:   4e 80 00 20     blr

000003b0 <testfls64>:
 3b0:   2c 03 00 00     cmpwi   r3,0
 3b4:   40 82 00 1c     bne     3d0 <testfls64+0x20>
 3b8:   2f 84 00 00     cmpwi   cr7,r4,0
 3bc:   38 60 00 00     li      r3,0
 3c0:   4d 9e 00 20     beqlr   cr7
 3c4:   7c 83 00 34     cntlzw  r3,r4
 3c8:   20 63 00 20     subfic  r3,r3,32
 3cc:   4e 80 00 20     blr
 3d0:   7c 63 00 34     cntlzw  r3,r3
 3d4:   20 63 00 40     subfic  r3,r3,64
 3d8:   4e 80 00 20     blr

When the input of fls(x) is a constant, just check x for nullity and
return either 0 or __builtin_clz(x). Otherwise, use cntlzw instruction
directly.

For fls64() on PPC64, do the same but with __builtin_clzll() and
cntlzd instruction. On PPC32, lets take the generic fls64() which
will use our fls(). The result is as expected:

00000388 <testfls>:
 388:   7c 63 00 34     cntlzw  r3,r3
 38c:   20 63 00 20     subfic  r3,r3,32
 390:   4e 80 00 20     blr

000003a0 <testfls64>:
 3a0:   2c 03 00 00     cmpwi   r3,0
 3a4:   40 82 00 10     bne     3b4 <testfls64+0x14>
 3a8:   7c 83 00 34     cntlzw  r3,r4
 3ac:   20 63 00 20     subfic  r3,r3,32
 3b0:   4e 80 00 20     blr
 3b4:   7c 63 00 34     cntlzw  r3,r3
 3b8:   20 63 00 40     subfic  r3,r3,64
 3bc:   4e 80 00 20     blr

Fixes: 2fcff790dcb4 ("powerpc: Use builtin functions for fls()/__fls()/fls64()")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: Segher Boessenkool <segher@kernel.crashing.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/348c2d3f19ffcff8abe50d52513f989c4581d000.1603375524.git.christophe.leroy@csgroup.eu
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/powerpc/include/asm/bitops.h | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index b750ffef83c7d..0ec93d940d12c 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -220,15 +220,34 @@ static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
  */
 static __inline__ int fls(unsigned int x)
 {
-	return 32 - __builtin_clz(x);
+	int lz;
+
+	if (__builtin_constant_p(x))
+		return x ? 32 - __builtin_clz(x) : 0;
+	asm("cntlzw %0,%1" : "=r" (lz) : "r" (x));
+	return 32 - lz;
 }
 
 #include <asm-generic/bitops/builtin-__fls.h>
 
+/*
+ * 64-bit can do this using one cntlzd (count leading zeroes doubleword)
+ * instruction; for 32-bit we use the generic version, which does two
+ * 32-bit fls calls.
+ */
+#ifdef CONFIG_PPC64
 static __inline__ int fls64(__u64 x)
 {
-	return 64 - __builtin_clzll(x);
+	int lz;
+
+	if (__builtin_constant_p(x))
+		return x ? 64 - __builtin_clzll(x) : 0;
+	asm("cntlzd %0,%1" : "=r" (lz) : "r" (x));
+	return 64 - lz;
 }
+#else
+#include <asm-generic/bitops/fls64.h>
+#endif
 
 #ifdef CONFIG_PPC64
 unsigned int __arch_hweight8(unsigned int w);
-- 
2.27.0




  parent reply	other threads:[~2021-01-07 14:31 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-07 14:31 [PATCH 4.14 00/29] 4.14.214-rc1 review Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 01/29] x86/entry/64: Add instruction suffix Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 02/29] md/raid10: initialize r10_bio->read_slot before use Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 03/29] ALSA: hda/ca0132 - Fix work handling in delayed HP detection Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 04/29] ALSA: usb-audio: simplify set_sync_ep_implicit_fb_quirk Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 05/29] ALSA: usb-audio: fix sync-ep altsetting sanity check Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 06/29] mm: memcontrol: eliminate raw access to stat and event counters Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 07/29] mm: memcontrol: implement lruvec stat functions on top of each other Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 08/29] mm: memcontrol: fix excessive complexity in memory.stat reporting Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 09/29] vfio/pci: Move dummy_resources_list init in vfio_pci_probe() Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 10/29] s390/dasd: fix hanging device offline processing Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 11/29] USB: serial: digi_acceleport: fix write-wakeup deadlocks Greg Kroah-Hartman
2021-01-07 14:31 ` Greg Kroah-Hartman [this message]
2021-01-07 14:31 ` [PATCH 4.14 13/29] uapi: move constants from <linux/kernel.h> to <linux/const.h> Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 14/29] of: fix linker-section match-table corruption Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 15/29] reiserfs: add check for an invalid ih_entry_count Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 16/29] misc: vmw_vmci: fix kernel info-leak by initializing dbells in vmci_ctx_get_chkpt_doorbells() Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 17/29] media: gp8psk: initialize stats at power control logic Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 18/29] ALSA: seq: Use bool for snd_seq_queue internal flags Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 19/29] rtc: sun6i: Fix memleak in sun6i_rtc_clk_init Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 20/29] module: set MODULE_STATE_GOING state when a module fails to load Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 21/29] quota: Dont overflow quota file offsets Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 22/29] powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe() Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 23/29] module: delay kobject uevent until after module init call Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 24/29] ALSA: pcm: Clear the full allocated memory at hw_params Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 25/29] dm verity: skip verity work if I/O error when system is shutting down Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 26/29] kdev_t: always inline major/minor helper functions Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 27/29] iio:imu:bmi160: Fix alignment and data leak issues Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 28/29] iio:magnetometer:mag3110: " Greg Kroah-Hartman
2021-01-07 14:31 ` [PATCH 4.14 29/29] mwifiex: Fix possible buffer overflows in mwifiex_cmd_802_11_ad_hoc_start Greg Kroah-Hartman
2021-01-07 20:20 ` [PATCH 4.14 00/29] 4.14.214-rc1 review Jon Hunter
2021-01-08  7:35 ` Naresh Kamboju
2021-01-08 17:38 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210107143054.693870389@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=christophe.leroy@csgroup.eu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=sashal@kernel.org \
    --cc=segher@kernel.crashing.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.