Author: David Spickett Date: 2023-10-20T14:06:06+01:00 New Revision: bb826951dcf35628cf73235e0e96a0d8ac9c0c49
URL: https://github.com/llvm/llvm-project/commit/bb826951dcf35628cf73235e0e96a0d8ac9c0c49 DIFF: https://github.com/llvm/llvm-project/commit/bb826951dcf35628cf73235e0e96a0d8ac9c0c49.diff LOG: [lldb][AArch64] Add release notes and documentation for SME (#66767) This adds a release note for all the SME support now in LLDB and a page where I have documented the user experience (for want of a better term) when using SVE and SME. This includes things like which mode transitions can or cannot be triggered from within LLDB. I hope this will serve to A: document what I've implemented and B: be a user's guide to these extensions. (though it is not a design document, read the commits and code for that sort of detail) Added: lldb/docs/use/aarch64-linux.rst Modified: lldb/docs/index.rst llvm/docs/ReleaseNotes.rst Removed: ################################################################################ diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index 2eb57cefbd883ea..2fff25b27b974ea 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -125,6 +125,7 @@ interesting areas to contribute to lldb. use/qemu-testing use/intel_pt use/ondemand + use/aarch64-linux use/troubleshooting use/links Man Page <man/lldb> diff --git a/lldb/docs/use/aarch64-linux.rst b/lldb/docs/use/aarch64-linux.rst new file mode 100644 index 000000000000000..707087a9bd72ea2 --- /dev/null +++ b/lldb/docs/use/aarch64-linux.rst @@ -0,0 +1,204 @@ +Using LLDB On AArch64 Linux +=========================== + +This page explains the details of debugging certain AArch64 extensions using +LLDB. If something is not mentioned here, it likely works as you would expect. + +This is not a replacement for ptrace and Linux Kernel documentation. This covers +how LLDB has chosen to use those things and how that effects your experience as +a user. + +Scalable Vector Extension (SVE) +------------------------------- + +See `here <https://developer.arm.com/Architectures/Scalable%20Vector%20Extensions>`__ +to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sve.html>`__ +for the Linux Kernel's handling of it. + +In LLDB you will be able to see the following new registers: + +* ``z0-z31`` vector registers, each one has size equal to the vector length. +* ``p0-p15`` predicate registers, each one containing 1 bit per byte in the vector + length. Making each one vector length / 8 sized. +* ``ffr`` the first fault register, same size as a predicate register. +* ``vg``, the vector length in "granules". Each granule is 8 bytes. + +.. code-block:: + + Scalable Vector Extension Registers: + vg = 0x0000000000000002 + z0 = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> } + <...> + p0 = {0xff 0xff} + <...> + ffr = {0xff 0xff} + +The example above has a vector length of 16 bytes. Within LLDB you will always +see "vg" as in the ``vg`` register, which is 2 in this case (8*2 = 16). +Elsewhere in kernel code or applications, you may see "vq" which is the vector +length in quadwords (16 bytes). Where you see "vl", it is in bytes. + +While you can count the size of a P or Z register, it is intended that ``vg`` be +used to find the current vector length. + +Changing the Vector Length +.......................... + +The ``vg`` register can be written during a debug session. Writing the current +vector length changes nothing. If you increase the vector length, the registers +will likely be reset to 0. If you decrease it, LLDB will truncate the Z +registers but everything else will be reset to 0. + +You should not assume that SVE state after changing the vector length is in any +way the same as it was previously. Whether that is done from within the +debuggee, or by LLDB. If you need to change the vector length, do so before a +function's first use of SVE. + +Z Register Presentation +....................... + +LLDB makes no attempt to predict how SVE Z registers will be used. Since LLDB +does not know what sort of elements future instructions will interpret the +register as. It therefore does not change the visualisation of the register +and always defaults to showing a vector of byte sized elements. + +If you know what format you are going to use, give a format option:: + + (lldb) register read z0 -f uint32_t[] + z0 = {0x01010101 0x01010101 0x01010101 0x01010101} + +FPSIMD and SVE Modes +.................... + +Prior to the debugee's first use of SVE, it is in what the Linux Kernel terms +SIMD mode. Only the FPU is being used. In this state LLDB will still show the +SVE registers however the values are simply the FPU values zero extended up to +the vector length. + +On first access to SVE, the process goes into SVE mode. Now the Z values are +in the real Z registers. + +You can also trigger this with LLDB by writing to an SVE register. Note that +there is no way to undo this change from within LLDB. However, the debugee +itself could do something to end up back in SIMD mode. + +Expression evaluation +..................... + +If you evaluate an expression, all SVE state is saved prior to, and restored +after the expression has been evaluated. Including the register values and +vector length. + +Scalable Matrix Extension (SME) +------------------------------- + +See `here <https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture>`__ +to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sme.html>`__ +for the Linux Kernel's handling of it. + +SME adds a "Streaming Mode" to SVE, and this mode has its own vector length +known as the "Streaming Vector Length". + +In LLDB you will see the following new registers: + +* ``tpidr2``, an extra per thread pointer reserved for use by the SME ABI. + This is not scalable, just pointer sized aka 64 bit. +* ``z0-z31`` streaming SVE registers. These have the same names as the + non-streaming registers and therefore you will only see the active set in + LLDB. You cannot read or write the inactive mode's registers. Their size + is the same as the streaming vector length. +* ``za`` the Array Storage register. The "Matrix" part of "Scalable Matrix + Extension". This is a square made up of rows of length equal to the streaming + vector length (svl). Meaning that the total size is svl * svl. +* ``svcr`` the Streaming Vector Control Register. This is actually a pseduo + register but it matches the content of the architecturaly defined ``SVCR``. + This is the register you should use to check whether streaming mode and/or + ``za`` is active. This register is read only. +* ``svg`` the streaming vector length in granules. This value is not connected + to the vector length of non-streaming mode and may change independently. This + register is read only. + +.. note:: + While in non-streaming mode, the ``vg`` register shows the non-streaming + vector length, and the ``svg`` register shows the streaming vector length. + When in streaming mode, both ``vg`` and ``svg`` show the streaming mode vector + length. Therefore it is not possible at this time to read the non-streaming + vector length within LLDB, while in streaming mode. This is a limitation of + the LLDB implementation not the architecture, which stores both lengths + independently. + +In the example below, the streaming vector length is 16 bytes and we are in +streaming mode. Note that bits 0 and 1 of ``svcr`` are set, indicating that we +are in streaming mode and ZA is active. ``vg`` and ``svg`` report the same value +as ``vg`` is showing the streaming mode vector length:: + + Scalable Vector Extension Registers: + vg = 0x0000000000000002 + z0 = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> } + <...> + p0 = {0xff 0xff} + <...> + ffr = {0xff 0xff} + + <...> + + Thread Local Storage Registers: + tpidr = 0x0000fffff7ff4320 + tpidr2 = 0x1122334455667788 + + Scalable Matrix Array Storage Registers: + za = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> } + + Scalable Matrix Extension Registers: + svg = 0x0000000000000002 + svcr = 0x0000000000000003 + +Changing the Streaming Vector Length +.................................... + +To reduce complexity for LLDB, ``svg`` is read only. This means that you can +only change the streaming vector length using LLDB when the debugee is in +streaming mode. + +As for non-streaming SVE, doing so will essentially make the content of the SVE +registers undefined. It will also disable ZA, which follows what the Linux +Kernel does. + +Visibility of an Inactive ZA Register +..................................... + +LLDB does not handle registers that can come and go at runtime (SVE changes +size but it does not dissappear). Therefore when ``za`` is not enabled, LLDB +will return a block of 0s instead. This block will match the expected size of +``za``:: + + (lldb) register read za svg svcr + za = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 <...> } + svg = 0x0000000000000002 + svcr = 0x0000000000000001 + +Note that ``svcr`` bit 2 is not set, meaning ``za`` is inactive. + +If you were to write to ``za`` from LLDB, ``za`` will be made active. There is +no way from within LLDB to reverse this change. As for changing the vector +length, the debugee could still do something that would disable ``za`` again. + +If you want to know whether ``za`` is active or not, refer to bit 2 of the +``svcr`` register, otherwise known as ``SVCR.ZA``. + +ZA Register Presentation +........................ + +As for SVE, LLDB does not know how the debugee will use ``za``, and therefore +does not know how it would be best to display it. At any time any given +instrucion could interpret its contents as many kinds and sizes of data. + +So LLDB will default to showing ``za`` as one large vector of individual bytes. +You can override this with a format option (see the SVE example above). + +Expression evaluation +..................... + +The mode (streaming or non-streaming), streaming vector length and ZA state will +be restored after expression evaluation. On top of all the things saved for SVE +in general. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 6830285483e28d9..bdd250657bafab5 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -209,6 +209,10 @@ Changes to LLDB instructions have been updated to reflect this. The underlying functionality remains unchanged. +* LLDB now supports debugging the Scalable Matrix Extension (SME) on AArch64 + Linux for both running processes and core files. For details refer to the + `AArch64 Linux documentation <https://lldb.llvm.org/use/aarch64-linux.html>`_. + Changes to Sanitizers --------------------- * HWASan now defaults to detecting use-after-scope bugs. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits