s390/disassembler: don't hide instruction addresses
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 31 Oct 2019 17:25:16 +0000 (18:25 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 31 Dec 2019 15:45:23 +0000 (16:45 +0100)
[ Upstream commit 544f1d62e3e6c6e6d17a5e56f6139208acb5ff46 ]

Due to kptr_restrict, JITted BPF code is now displayed like this:

000000000b6ed1b2ebdff0800024  stmg    %r13,%r15,128(%r15)
000000004cde2ba041d0f040      la      %r13,64(%r15)
00000000fbad41b0a7fbffa0      aghi    %r15,-96

Leaking kernel addresses to dmesg is not a concern in this case, because
this happens only when JIT debugging is explicitly activated, which only
root can do.

Use %px in this particular instance, and also to print an instruction
address in show_code and PCREL (e.g. brasl) arguments in print_insn.
While at present functionally equivalent to %016lx, %px is recommended
by Documentation/core-api/printk-formats.rst for such cases.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/s390/kernel/dis.c

index 7abe6ae261b42b71e1b7f778bf52d62b8214d3bf..f304802ecf7becab43acb74228aa00e44d5dd40b 100644 (file)
@@ -461,10 +461,11 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
                                ptr += sprintf(ptr, "%%c%i", value);
                        else if (operand->flags & OPERAND_VR)
                                ptr += sprintf(ptr, "%%v%i", value);
-                       else if (operand->flags & OPERAND_PCREL)
-                               ptr += sprintf(ptr, "%lx", (signed int) value
-                                                                     + addr);
-                       else if (operand->flags & OPERAND_SIGNED)
+                       else if (operand->flags & OPERAND_PCREL) {
+                               void *pcrel = (void *)((int)value + addr);
+
+                               ptr += sprintf(ptr, "%px", pcrel);
+                       } else if (operand->flags & OPERAND_SIGNED)
                                ptr += sprintf(ptr, "%i", value);
                        else
                                ptr += sprintf(ptr, "%u", value);
@@ -536,7 +537,7 @@ void show_code(struct pt_regs *regs)
                else
                        *ptr++ = ' ';
                addr = regs->psw.addr + start - 32;
-               ptr += sprintf(ptr, "%016lx: ", addr);
+               ptr += sprintf(ptr, "%px: ", (void *)addr);
                if (start + opsize >= end)
                        break;
                for (i = 0; i < opsize; i++)
@@ -564,7 +565,7 @@ void print_fn_code(unsigned char *code, unsigned long len)
                opsize = insn_length(*code);
                if (opsize > len)
                        break;
-               ptr += sprintf(ptr, "%p: ", code);
+               ptr += sprintf(ptr, "%px: ", code);
                for (i = 0; i < opsize; i++)
                        ptr += sprintf(ptr, "%02x", code[i]);
                *ptr++ = '\t';