Skip to content

Commit bb82695

Browse files
[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)
1 parent 11a7195 commit bb82695

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed

lldb/docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ interesting areas to contribute to lldb.
125125
use/qemu-testing
126126
use/intel_pt
127127
use/ondemand
128+
use/aarch64-linux
128129
use/troubleshooting
129130
use/links
130131
Man Page <man/lldb>

lldb/docs/use/aarch64-linux.rst

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
Using LLDB On AArch64 Linux
2+
===========================
3+
4+
This page explains the details of debugging certain AArch64 extensions using
5+
LLDB. If something is not mentioned here, it likely works as you would expect.
6+
7+
This is not a replacement for ptrace and Linux Kernel documentation. This covers
8+
how LLDB has chosen to use those things and how that effects your experience as
9+
a user.
10+
11+
Scalable Vector Extension (SVE)
12+
-------------------------------
13+
14+
See `here <https://developer.arm.com/Architectures/Scalable%20Vector%20Extensions>`__
15+
to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sve.html>`__
16+
for the Linux Kernel's handling of it.
17+
18+
In LLDB you will be able to see the following new registers:
19+
20+
* ``z0-z31`` vector registers, each one has size equal to the vector length.
21+
* ``p0-p15`` predicate registers, each one containing 1 bit per byte in the vector
22+
length. Making each one vector length / 8 sized.
23+
* ``ffr`` the first fault register, same size as a predicate register.
24+
* ``vg``, the vector length in "granules". Each granule is 8 bytes.
25+
26+
.. code-block::
27+
28+
Scalable Vector Extension Registers:
29+
vg = 0x0000000000000002
30+
z0 = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> }
31+
<...>
32+
p0 = {0xff 0xff}
33+
<...>
34+
ffr = {0xff 0xff}
35+
36+
The example above has a vector length of 16 bytes. Within LLDB you will always
37+
see "vg" as in the ``vg`` register, which is 2 in this case (8*2 = 16).
38+
Elsewhere in kernel code or applications, you may see "vq" which is the vector
39+
length in quadwords (16 bytes). Where you see "vl", it is in bytes.
40+
41+
While you can count the size of a P or Z register, it is intended that ``vg`` be
42+
used to find the current vector length.
43+
44+
Changing the Vector Length
45+
..........................
46+
47+
The ``vg`` register can be written during a debug session. Writing the current
48+
vector length changes nothing. If you increase the vector length, the registers
49+
will likely be reset to 0. If you decrease it, LLDB will truncate the Z
50+
registers but everything else will be reset to 0.
51+
52+
You should not assume that SVE state after changing the vector length is in any
53+
way the same as it was previously. Whether that is done from within the
54+
debuggee, or by LLDB. If you need to change the vector length, do so before a
55+
function's first use of SVE.
56+
57+
Z Register Presentation
58+
.......................
59+
60+
LLDB makes no attempt to predict how SVE Z registers will be used. Since LLDB
61+
does not know what sort of elements future instructions will interpret the
62+
register as. It therefore does not change the visualisation of the register
63+
and always defaults to showing a vector of byte sized elements.
64+
65+
If you know what format you are going to use, give a format option::
66+
67+
(lldb) register read z0 -f uint32_t[]
68+
z0 = {0x01010101 0x01010101 0x01010101 0x01010101}
69+
70+
FPSIMD and SVE Modes
71+
....................
72+
73+
Prior to the debugee's first use of SVE, it is in what the Linux Kernel terms
74+
SIMD mode. Only the FPU is being used. In this state LLDB will still show the
75+
SVE registers however the values are simply the FPU values zero extended up to
76+
the vector length.
77+
78+
On first access to SVE, the process goes into SVE mode. Now the Z values are
79+
in the real Z registers.
80+
81+
You can also trigger this with LLDB by writing to an SVE register. Note that
82+
there is no way to undo this change from within LLDB. However, the debugee
83+
itself could do something to end up back in SIMD mode.
84+
85+
Expression evaluation
86+
.....................
87+
88+
If you evaluate an expression, all SVE state is saved prior to, and restored
89+
after the expression has been evaluated. Including the register values and
90+
vector length.
91+
92+
Scalable Matrix Extension (SME)
93+
-------------------------------
94+
95+
See `here <https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture>`__
96+
to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sme.html>`__
97+
for the Linux Kernel's handling of it.
98+
99+
SME adds a "Streaming Mode" to SVE, and this mode has its own vector length
100+
known as the "Streaming Vector Length".
101+
102+
In LLDB you will see the following new registers:
103+
104+
* ``tpidr2``, an extra per thread pointer reserved for use by the SME ABI.
105+
This is not scalable, just pointer sized aka 64 bit.
106+
* ``z0-z31`` streaming SVE registers. These have the same names as the
107+
non-streaming registers and therefore you will only see the active set in
108+
LLDB. You cannot read or write the inactive mode's registers. Their size
109+
is the same as the streaming vector length.
110+
* ``za`` the Array Storage register. The "Matrix" part of "Scalable Matrix
111+
Extension". This is a square made up of rows of length equal to the streaming
112+
vector length (svl). Meaning that the total size is svl * svl.
113+
* ``svcr`` the Streaming Vector Control Register. This is actually a pseduo
114+
register but it matches the content of the architecturaly defined ``SVCR``.
115+
This is the register you should use to check whether streaming mode and/or
116+
``za`` is active. This register is read only.
117+
* ``svg`` the streaming vector length in granules. This value is not connected
118+
to the vector length of non-streaming mode and may change independently. This
119+
register is read only.
120+
121+
.. note::
122+
While in non-streaming mode, the ``vg`` register shows the non-streaming
123+
vector length, and the ``svg`` register shows the streaming vector length.
124+
When in streaming mode, both ``vg`` and ``svg`` show the streaming mode vector
125+
length. Therefore it is not possible at this time to read the non-streaming
126+
vector length within LLDB, while in streaming mode. This is a limitation of
127+
the LLDB implementation not the architecture, which stores both lengths
128+
independently.
129+
130+
In the example below, the streaming vector length is 16 bytes and we are in
131+
streaming mode. Note that bits 0 and 1 of ``svcr`` are set, indicating that we
132+
are in streaming mode and ZA is active. ``vg`` and ``svg`` report the same value
133+
as ``vg`` is showing the streaming mode vector length::
134+
135+
Scalable Vector Extension Registers:
136+
vg = 0x0000000000000002
137+
z0 = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> }
138+
<...>
139+
p0 = {0xff 0xff}
140+
<...>
141+
ffr = {0xff 0xff}
142+
143+
<...>
144+
145+
Thread Local Storage Registers:
146+
tpidr = 0x0000fffff7ff4320
147+
tpidr2 = 0x1122334455667788
148+
149+
Scalable Matrix Array Storage Registers:
150+
za = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> }
151+
152+
Scalable Matrix Extension Registers:
153+
svg = 0x0000000000000002
154+
svcr = 0x0000000000000003
155+
156+
Changing the Streaming Vector Length
157+
....................................
158+
159+
To reduce complexity for LLDB, ``svg`` is read only. This means that you can
160+
only change the streaming vector length using LLDB when the debugee is in
161+
streaming mode.
162+
163+
As for non-streaming SVE, doing so will essentially make the content of the SVE
164+
registers undefined. It will also disable ZA, which follows what the Linux
165+
Kernel does.
166+
167+
Visibility of an Inactive ZA Register
168+
.....................................
169+
170+
LLDB does not handle registers that can come and go at runtime (SVE changes
171+
size but it does not dissappear). Therefore when ``za`` is not enabled, LLDB
172+
will return a block of 0s instead. This block will match the expected size of
173+
``za``::
174+
175+
(lldb) register read za svg svcr
176+
za = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 <...> }
177+
svg = 0x0000000000000002
178+
svcr = 0x0000000000000001
179+
180+
Note that ``svcr`` bit 2 is not set, meaning ``za`` is inactive.
181+
182+
If you were to write to ``za`` from LLDB, ``za`` will be made active. There is
183+
no way from within LLDB to reverse this change. As for changing the vector
184+
length, the debugee could still do something that would disable ``za`` again.
185+
186+
If you want to know whether ``za`` is active or not, refer to bit 2 of the
187+
``svcr`` register, otherwise known as ``SVCR.ZA``.
188+
189+
ZA Register Presentation
190+
........................
191+
192+
As for SVE, LLDB does not know how the debugee will use ``za``, and therefore
193+
does not know how it would be best to display it. At any time any given
194+
instrucion could interpret its contents as many kinds and sizes of data.
195+
196+
So LLDB will default to showing ``za`` as one large vector of individual bytes.
197+
You can override this with a format option (see the SVE example above).
198+
199+
Expression evaluation
200+
.....................
201+
202+
The mode (streaming or non-streaming), streaming vector length and ZA state will
203+
be restored after expression evaluation. On top of all the things saved for SVE
204+
in general.

llvm/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ Changes to LLDB
209209
instructions have been updated to reflect this. The underlying functionality
210210
remains unchanged.
211211

212+
* LLDB now supports debugging the Scalable Matrix Extension (SME) on AArch64
213+
Linux for both running processes and core files. For details refer to the
214+
`AArch64 Linux documentation <https://lldb.llvm.org/use/aarch64-linux.html>`_.
215+
212216
Changes to Sanitizers
213217
---------------------
214218
* HWASan now defaults to detecting use-after-scope bugs.

0 commit comments

Comments
 (0)