Skip to content

Commit 157a1b7

Browse files
committed
Update test case:
1. confirm that we cannot read SME/SVE regs when not in SSVE mode. 2. Make it clearer how I'm modifying all of the SVE/SME registers, then instruction stepping, then reading them back to confirm that they were modified. Remove `DNBArchMachARM64::get_svl_bytes`, depend entirely on the hw.optional.arm.sme_max_svl_b sysctl to get the system's maximum SVL, instead of debugserver's maximum SVL. They're always the same today, but it's possible to imagine it not being like that in the future.
1 parent 1c94310 commit 157a1b7

File tree

4 files changed

+73
-33
lines changed

4 files changed

+73
-33
lines changed

lldb/test/API/macosx/sme-registers/TestSMERegistersDarwin.py

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,49 @@ def test(self):
1919
"""Test that we can read the contents of the SME/SVE registers on Darwin"""
2020
self.build()
2121
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
22-
self, "break here", lldb.SBFileSpec("main.c")
22+
self, "break before sme", lldb.SBFileSpec("main.c")
2323
)
2424
frame = thread.GetFrameAtIndex(0)
2525
self.assertTrue(frame.IsValid())
2626

27+
self.assertTrue(
28+
target.BreakpointCreateBySourceRegex(
29+
"break while sme", lldb.SBFileSpec("main.c")
30+
).IsValid()
31+
)
32+
self.assertTrue(
33+
target.BreakpointCreateBySourceRegex(
34+
"break after sme", lldb.SBFileSpec("main.c")
35+
).IsValid()
36+
)
37+
2738
if self.TraceOn():
2839
self.runCmd("reg read -a")
2940

30-
svl_reg = frame.register["svl"]
31-
svl = svl_reg.GetValueAsUnsigned()
41+
self.assertTrue(frame.register["svl"].GetError().Fail())
42+
self.assertTrue(frame.register["z0"].GetError().Fail())
43+
self.assertTrue(frame.register["p0"].GetError().Fail())
44+
self.assertTrue(frame.register["za"].GetError().Fail())
45+
self.assertTrue(frame.register["zt0"].GetError().Fail())
46+
47+
process.Continue()
48+
frame = thread.GetFrameAtIndex(0)
49+
self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
50+
51+
# Now in SME enabled mode
52+
self.assertTrue(frame.register["svl"].GetError().Success())
53+
self.assertTrue(frame.register["z0"].GetError().Success())
54+
self.assertTrue(frame.register["p0"].GetError().Success())
55+
self.assertTrue(frame.register["za"].GetError().Success())
56+
self.assertTrue(frame.register["zt0"].GetError().Success())
3257

3358
# SSVE and SME modes should be enabled (reflecting PSTATE.SM and PSTATE.ZA)
3459
svcr = frame.register["svcr"]
3560
self.assertEqual(svcr.GetValueAsUnsigned(), 3)
3661

62+
svl_reg = frame.register["svl"]
63+
svl = svl_reg.GetValueAsUnsigned()
64+
3765
z0 = frame.register["z0"]
3866
self.assertEqual(z0.GetNumChildren(), svl)
3967
self.assertEqual(z0.GetChildAtIndex(0).GetValueAsUnsigned(), 0x1)
@@ -72,50 +100,66 @@ def test(self):
72100
zt0_final = zt0.GetChildAtIndex(63)
73101
self.assertEqual(zt0_final.GetValueAsUnsigned(), 63)
74102

103+
# Modify all of the registers, instruction step, confirm that the
104+
# registers have the new values. Without the instruction step, it's
105+
# possible debugserver or lldb could lie about the write succeeding.
106+
75107
z0_old_values = []
108+
z0_new_values = []
76109
z0_new_str = '"{'
77110
for i in range(svl):
78111
z0_old_values.append(z0.GetChildAtIndex(i).GetValueAsUnsigned())
112+
z0_new_values.append(z0.GetChildAtIndex(i).GetValueAsUnsigned() + 5)
79113
z0_new_str = z0_new_str + ("0x%02x " % (z0_old_values[i] + 5))
80114
z0_new_str = z0_new_str + '}"'
81115
self.runCmd("reg write z0 %s" % z0_new_str)
82116

83117
z31_old_values = []
118+
z31_new_values = []
84119
z31_new_str = '"{'
85120
for i in range(svl):
86121
z31_old_values.append(z31.GetChildAtIndex(i).GetValueAsUnsigned())
122+
z31_new_values.append(z31.GetChildAtIndex(i).GetValueAsUnsigned() + 3)
87123
z31_new_str = z31_new_str + ("0x%02x " % (z31_old_values[i] + 3))
88124
z31_new_str = z31_new_str + '}"'
89125
self.runCmd("reg write z31 %s" % z31_new_str)
90126

91127
p0_old_values = []
128+
p0_new_values = []
92129
p0_new_str = '"{'
93130
for i in range(int(svl / 8)):
94131
p0_old_values.append(p0.GetChildAtIndex(i).GetValueAsUnsigned())
132+
p0_new_values.append(p0.GetChildAtIndex(i).GetValueAsUnsigned() - 5)
95133
p0_new_str = p0_new_str + ("0x%02x " % (p0_old_values[i] - 5))
96134
p0_new_str = p0_new_str + '}"'
97135
self.runCmd("reg write p0 %s" % p0_new_str)
98136

99137
p15_old_values = []
138+
p15_new_values = []
100139
p15_new_str = '"{'
101140
for i in range(int(svl / 8)):
102141
p15_old_values.append(p15.GetChildAtIndex(i).GetValueAsUnsigned())
142+
p15_new_values.append(p15.GetChildAtIndex(i).GetValueAsUnsigned() - 8)
103143
p15_new_str = p15_new_str + ("0x%02x " % (p15_old_values[i] - 8))
104144
p15_new_str = p15_new_str + '}"'
105145
self.runCmd("reg write p15 %s" % p15_new_str)
106146

107147
za_old_values = []
148+
za_new_values = []
108149
za_new_str = '"{'
109150
for i in range(svl * svl):
110151
za_old_values.append(za.GetChildAtIndex(i).GetValueAsUnsigned())
152+
za_new_values.append(za.GetChildAtIndex(i).GetValueAsUnsigned() + 7)
111153
za_new_str = za_new_str + ("0x%02x " % (za_old_values[i] + 7))
112154
za_new_str = za_new_str + '}"'
113155
self.runCmd("reg write za %s" % za_new_str)
114156

115157
zt0_old_values = []
158+
zt0_new_values = []
116159
zt0_new_str = '"{'
117160
for i in range(64):
118161
zt0_old_values.append(zt0.GetChildAtIndex(i).GetValueAsUnsigned())
162+
zt0_new_values.append(zt0.GetChildAtIndex(i).GetValueAsUnsigned() + 2)
119163
zt0_new_str = zt0_new_str + ("0x%02x " % (zt0_old_values[i] + 2))
120164
zt0_new_str = zt0_new_str + '}"'
121165
self.runCmd("reg write zt0 %s" % zt0_new_str)
@@ -129,35 +173,45 @@ def test(self):
129173
z0 = frame.register["z0"]
130174
for i in range(z0.GetNumChildren()):
131175
self.assertEqual(
132-
z0_old_values[i] + 5, z0.GetChildAtIndex(i).GetValueAsUnsigned()
176+
z0_new_values[i], z0.GetChildAtIndex(i).GetValueAsUnsigned()
133177
)
134178

135179
z31 = frame.register["z31"]
136180
for i in range(z31.GetNumChildren()):
137181
self.assertEqual(
138-
z31_old_values[i] + 3, z31.GetChildAtIndex(i).GetValueAsUnsigned()
182+
z31_new_values[i], z31.GetChildAtIndex(i).GetValueAsUnsigned()
139183
)
140184

141185
p0 = frame.register["p0"]
142186
for i in range(p0.GetNumChildren()):
143187
self.assertEqual(
144-
p0_old_values[i] - 5, p0.GetChildAtIndex(i).GetValueAsUnsigned()
188+
p0_new_values[i], p0.GetChildAtIndex(i).GetValueAsUnsigned()
145189
)
146190

147191
p15 = frame.register["p15"]
148192
for i in range(p15.GetNumChildren()):
149193
self.assertEqual(
150-
p15_old_values[i] - 8, p15.GetChildAtIndex(i).GetValueAsUnsigned()
194+
p15_new_values[i], p15.GetChildAtIndex(i).GetValueAsUnsigned()
151195
)
152196

153197
za = frame.register["za"]
154198
for i in range(za.GetNumChildren()):
155199
self.assertEqual(
156-
za_old_values[i] + 7, za.GetChildAtIndex(i).GetValueAsUnsigned()
200+
za_new_values[i], za.GetChildAtIndex(i).GetValueAsUnsigned()
157201
)
158202

159203
zt0 = frame.register["zt0"]
160204
for i in range(zt0.GetNumChildren()):
161205
self.assertEqual(
162-
zt0_old_values[i] + 2, zt0.GetChildAtIndex(i).GetValueAsUnsigned()
206+
zt0_new_values[i], zt0.GetChildAtIndex(i).GetValueAsUnsigned()
163207
)
208+
209+
process.Continue()
210+
frame = thread.GetFrameAtIndex(0)
211+
self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
212+
213+
self.assertTrue(frame.register["svl"].GetError().Fail())
214+
self.assertTrue(frame.register["z0"].GetError().Fail())
215+
self.assertTrue(frame.register["p0"].GetError().Fail())
216+
self.assertTrue(frame.register["za"].GetError().Fail())
217+
self.assertTrue(frame.register["zt0"].GetError().Fail())

lldb/test/API/macosx/sme-registers/main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void arm_sme2_set_zt0() {
9393
}
9494

9595
int main() {
96-
printf("Enable SME mode\n");
96+
printf("Enable SME mode\n"); // break before sme
9797

9898
asm volatile("smstart");
9999

@@ -103,9 +103,11 @@ int main() {
103103

104104
arm_sme2_set_zt0();
105105

106-
int c = 10; // break here
106+
int c = 10; // break while sme
107107
c += 5;
108108
c += 5;
109109

110110
asm volatile("smstop");
111+
112+
printf("SME mode disabled\n"); // break after sme
111113
}

lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,11 @@ unsigned int DNBArchMachARM64::GetSMEMaxSVL() {
127127
if (sysctlbyname("hw.optional.arm.sme_max_svl_b", &ret, &size, NULL, 0) !=
128128
-1)
129129
g_sme_max_svl = ret;
130-
else
131-
g_sme_max_svl = get_svl_bytes();
132130
}
133131
});
134132
return g_sme_max_svl;
135133
}
136134

137-
// This function can only be called on systems with hw.optional.arm.FEAT_SME
138-
// It will return the maximum SVL length for this process.
139-
uint16_t __attribute__((target("sme"))) DNBArchMachARM64::get_svl_bytes(void) {
140-
uint64_t ret = 0;
141-
asm volatile("rdsvl %[ret], #1" : [ret] "=r"(ret));
142-
return (uint16_t)ret;
143-
}
144-
145135
static uint64_t clear_pac_bits(uint64_t value) {
146136
uint32_t addressing_bits = 0;
147137
if (!DNBGetAddressingBits(addressing_bits))
@@ -2721,8 +2711,7 @@ bool DNBArchMachARM64::GetRegisterValue(uint32_t set, uint32_t reg,
27212711
memcpy(&value->value.v_uint8, &m_state.context.sve.z[reg - sve_z0],
27222712
max_svl_bytes);
27232713
return true;
2724-
}
2725-
if (reg >= sve_p0 && reg <= sve_p15) {
2714+
} else if (reg >= sve_p0 && reg <= sve_p15) {
27262715
memset(&value->value.v_uint8, 0, max_svl_bytes / 8);
27272716
memcpy(&value->value.v_uint8, &m_state.context.sve.p[reg - sve_p0],
27282717
max_svl_bytes / 8);
@@ -2737,21 +2726,17 @@ bool DNBArchMachARM64::GetRegisterValue(uint32_t set, uint32_t reg,
27372726
if (reg == sme_svcr) {
27382727
value->value.uint64 = m_state.context.sme.svcr;
27392728
return true;
2740-
}
2741-
if (reg == sme_tpidr2) {
2729+
} else if (reg == sme_tpidr2) {
27422730
value->value.uint64 = m_state.context.sme.tpidr2;
27432731
return true;
2744-
}
2745-
if (reg == sme_svl_b) {
2732+
} else if (reg == sme_svl_b) {
27462733
value->value.uint64 = m_state.context.sme.svl_b;
27472734
return true;
2748-
}
2749-
if (reg == sme_za) {
2735+
} else if (reg == sme_za) {
27502736
memcpy(&value->value.v_uint8, m_state.context.sme.za.data(),
27512737
max_svl_bytes * max_svl_bytes);
27522738
return true;
2753-
}
2754-
if (reg == sme_zt0) {
2739+
} else if (reg == sme_zt0) {
27552740
memcpy(&value->value.v_uint8, &m_state.context.sme.zt0, 64);
27562741
return true;
27572742
}
@@ -2872,7 +2857,7 @@ bool DNBArchMachARM64::SetRegisterValue(uint32_t set, uint32_t reg,
28722857
}
28732858
if (reg >= sve_p0 && reg <= sve_p15) {
28742859
memcpy(&m_state.context.sve.p[reg - sve_p0], &value->value.v_uint8,
2875-
256 / 8);
2860+
max_svl_bytes / 8);
28762861
success = true;
28772862
}
28782863
break;

lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ class DNBArchMachARM64 : public DNBArchProtocol {
295295
static bool CPUHasSME();
296296
static bool CPUHasSME2();
297297
static unsigned int GetSMEMaxSVL();
298-
static uint16_t __attribute__((target("sme"))) get_svl_bytes();
299298

300299
private:
301300
static DNBRegisterInfo *get_vfp_registerinfo(size_t &num_vfp_registers);

0 commit comments

Comments
 (0)