linux-4.4-rc8/arch/arm64/kernel/module.c:78: 32/64 bit problem ?
Will Deacon
will.deacon at arm.com
Mon Jan 4 06:16:58 PST 2016
On Mon, Jan 04, 2016 at 08:25:30AM +0000, David Binderman wrote:
> Hello there,
Hi David,
> [linux-4.4-rc8/arch/arm64/kernel/module.c:78] ->
> [linux-4.4-rc8/arch/arm64/kernel/module.c:88]: (warning) Shifting 32-bit
> value by 64 bits is undefined behaviour. See condition at line 88.
Curious, but how are you seeing this warning? GCC is silent for me...
> Source code is
>
> u64 imm_mask = (1 << len) - 1;
> s64 sval = do_reloc(op, place, val);
>
> switch (len) {
> case 16:
> *(s16 *)place = sval;
> break;
> case 32:
> *(s32 *)place = sval;
> break;
> case 64:
>
> So it seems that len can be 64. Suggest new code
>
> u64 imm_mask = (1UL << len) - 1;
That still ends up shifting by the width of the type when len == 64,
which is potentially still broken. We're better off using GENMASK.
Will
--->8
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index f4bc779e62e8..266e7490e85c 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -75,7 +75,7 @@ static u64 do_reloc(enum aarch64_reloc_op reloc_op, void *place, u64 val)
static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
{
- u64 imm_mask = (1 << len) - 1;
+ u64 imm_mask = GENMASK(len - 1, 0);
s64 sval = do_reloc(op, place, val);
switch (len) {
More information about the linux-arm-kernel
mailing list