lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a6e7aed9-ecf1-4715-a422-962a720f4cb7@siemens.com>
Date: Wed, 9 Jul 2025 17:45:28 +0200
From: Jan Kiszka <jan.kiszka@...mens.com>
To: Ilya Leoshkevich <iii@...ux.ibm.com>, Kieran Bingham
 <kbingham@...nel.org>, Andrew Morton <akpm@...ux-foundation.org>
Cc: linux-kernel@...r.kernel.org, Heiko Carstens <hca@...ux.ibm.com>,
 Vasily Gorbik <gor@...ux.ibm.com>, Alexander Gordeev <agordeev@...ux.ibm.com>
Subject: Re: [PATCH 2/2] scripts/gdb/symbols: make lx-symbols skip the s390
 decompressor

On 09.07.25 16:37, Ilya Leoshkevich wrote:
> On Wed, 2025-07-09 at 13:40 +0200, Jan Kiszka wrote:
>> On 25.06.25 17:36, Ilya Leoshkevich wrote:
>>> When one starts QEMU with the -S flag and attaches GDB, the kernel
>>> is
>>> not yet loaded, and the current instruction is an entry point to
>>> the
>>> decompressor. In case the intention is to debug the early kernel
>>> boot,
>>> and not the decompressor, e.g., put a breakpoint on some kernel
>>> function and see all the invocations, one has to skip the
>>> decompressor.
>>>
>>> There are many ways to do this, and so far people wrote private
>>> scripts
>>> or memorized certain command sequences.
>>>
>>> Make it work out of the box like this:
>>>
>>>     $ gdb -ex 'target remote :6812' -ex 'source vmlinux-gdb.py'
>>> vmlinux
>>>     Remote debugging using :6812
>>>     0x0000000000010000 in ?? ()
>>>     (gdb) lx-symbols
>>>     loading vmlinux
>>>     (gdb) x/i $pc
>>>     => 0x3ffe0100000 <startup_continue>:    lghi    %r2,0
>>>
>>> Implement this by reading the address of the jump_to_kernel()
>>> function
>>> from the lowcore, and step until DAT is turned on.
>>
>> Why do you need to stepi until there? SW breakpoint will likely need
>> to
>> output of the decompressor first. No HW breakpoint available? Or
>> missing
>> <end-of-decompressor> address?
> 
> jump_to_kernel is <end-of-decompressor>; the code from this patch puts
> an SW breakpoint there, and this works fine.
> 
> However, the problem is that once jump_to_kernel is reached, even
> though the kernel is already in place, paging is still off.
> 
> jump_to_kernel contains a single "lpswe" instruction, which both jumps
> to kernel and enables paging, therefore, we must "stepi" over it. The
> loop is there just for future-proofing. Everything happens very
> quickly, there are no thousands of "stepi"s.
> 

OK, makes sense to me now.

>>> Signed-off-by: Ilya Leoshkevich <iii@...ux.ibm.com>
>>> ---
>>>  scripts/gdb/linux/symbols.py | 26 ++++++++++++++++++++++++++
>>>  1 file changed, 26 insertions(+)
>>>
>>> diff --git a/scripts/gdb/linux/symbols.py
>>> b/scripts/gdb/linux/symbols.py
>>> index 2332bd8eddf1..6edb99221675 100644
>>> --- a/scripts/gdb/linux/symbols.py
>>> +++ b/scripts/gdb/linux/symbols.py
>>> @@ -84,6 +84,30 @@ def get_kerneloffset():
>>>      return None
>>>  
>>>  
>>> +def is_in_s390_decompressor():
>>> +    # DAT is always off in decompressor. Use this as an indicator.
>>> +    # Note that in the kernel, DAT can be off during kexec() or
>>> restart.
>>> +    # Accept this imprecision in order to avoid complicating
>>> things.
>>> +    # It is unlikely that someone will run lx-symbols at these
>>> points.
>>> +    pswm = int(gdb.parse_and_eval("$pswm"))
>>> +    return (pswm & 0x0400000000000000) == 0
>>> +
>>> +
>>> +def skip_decompressor():
>>> +    if utils.is_target_arch("s390"):
>>> +        if is_in_s390_decompressor():
>>> +            # The address of the jump_to_kernel function is
>>> statically placed
>>> +            # into svc_old_psw.addr (see ipl_data.c); read it from
>>> there. DAT
>>> +            # is off, so we do not need to care about lowcore
>>> relocation.
>>> +            svc_old_pswa = 0x148
>>> +            jump_to_kernel = int(gdb.parse_and_eval("*(unsigned
>>> long long *)" +
>>> +                                                   
>>> hex(svc_old_pswa)))
>>> +            gdb.execute("tbreak *" + hex(jump_to_kernel))
>>> +            gdb.execute("continue")
>>> +            while is_in_s390_decompressor():
>>> +                gdb.execute("stepi")
>>> +
>>> +
>>>  class LxSymbols(gdb.Command):
>>>      """(Re-)load symbols of Linux kernel and currently loaded
>>> modules.
>>>  
>>> @@ -204,6 +228,8 @@ lx-symbols command."""
>>>              saved_state['breakpoint'].enabled =
>>> saved_state['enabled']
>>>  
>>>      def invoke(self, arg, from_tty):
>>> +        skip_decompressor()
>>> +
>>>          self.module_paths =
>>> [os.path.abspath(os.path.expanduser(p))
>>>                               for p in arg.split()]
>>>          self.module_paths.append(os.getcwd())
>>
>> Otherwise, this series looks good to me and could be picked up if
>> there
>> is no better way to reach the end of the decompressor.
> 
> Could you please ack this patch if the explanation above is
> satisfactory? We would like to take this series via the s390 tree,
> if possible.
> 

Sorry, should have also read your cover letter:

Acked-by: Jan Kiszka <jan.kiszka@...mens.com>

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ