@@ -147,6 +147,7 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
147
147
::memset (&m_sve_header, 0 , sizeof (m_sve_header));
148
148
::memset (&m_pac_mask, 0 , sizeof (m_pac_mask));
149
149
::memset (&m_tls_regs, 0 , sizeof (m_tls_regs));
150
+ ::memset (&m_sme_pseudo_regs, 0 , sizeof (m_sme_pseudo_regs));
150
151
151
152
m_mte_ctrl_reg = 0 ;
152
153
@@ -329,30 +330,40 @@ NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
329
330
assert (offset < GetMTEControlSize ());
330
331
src = (uint8_t *)GetMTEControl () + offset;
331
332
} else if (IsSME (reg)) {
332
- error = ReadZAHeader ();
333
- if (error.Fail ())
334
- return error;
333
+ if (GetRegisterInfo ().IsSMERegZA (reg)) {
334
+ error = ReadZAHeader ();
335
+ if (error.Fail ())
336
+ return error;
335
337
336
- // If there is only a header and no registers, ZA is inactive. Read as 0
337
- // in this case.
338
- if (m_za_header.size == sizeof (m_za_header)) {
339
- // This will get reconfigured/reset later, so we are safe to use it.
340
- // ZA is a square of VL * VL and the ptrace buffer also includes the
341
- // header itself.
342
- m_za_ptrace_payload.resize (((m_za_header.vl ) * (m_za_header.vl )) +
343
- GetZAHeaderSize ());
344
- std::fill (m_za_ptrace_payload.begin (), m_za_ptrace_payload.end (), 0 );
338
+ // If there is only a header and no registers, ZA is inactive. Read as 0
339
+ // in this case.
340
+ if (m_za_header.size == sizeof (m_za_header)) {
341
+ // This will get reconfigured/reset later, so we are safe to use it.
342
+ // ZA is a square of VL * VL and the ptrace buffer also includes the
343
+ // header itself.
344
+ m_za_ptrace_payload.resize (((m_za_header.vl ) * (m_za_header.vl )) +
345
+ GetZAHeaderSize ());
346
+ std::fill (m_za_ptrace_payload.begin (), m_za_ptrace_payload.end (), 0 );
347
+ } else {
348
+ // ZA is active, read the real register.
349
+ error = ReadZA ();
350
+ if (error.Fail ())
351
+ return error;
352
+ }
353
+
354
+ // ZA is part of the SME set but uses a seperate member buffer for
355
+ // storage. Therefore its effective byte offset is always 0 even if it
356
+ // isn't 0 within the SME register set.
357
+ src = (uint8_t *)GetZABuffer () + GetZAHeaderSize ();
345
358
} else {
346
- // ZA is active, read the real register.
347
- error = ReadZA ();
359
+ error = ReadSMESVG ();
348
360
if (error.Fail ())
349
361
return error;
350
- }
351
362
352
- // ZA is part of the SME set but uses a seperate member buffer for storage.
353
- // Therefore its effective byte offset is always 0 even if it isn't 0 within
354
- // the SME register set.
355
- src = ( uint8_t *) GetZABuffer () + GetZAHeaderSize ();
363
+ offset = reg_info-> byte_offset - GetRegisterInfo (). GetSMEOffset ();
364
+ assert ( offset < GetSMEPseudoBufferSize ());
365
+ src = ( uint8_t *) GetSMEPseudoBuffer () + offset;
366
+ }
356
367
} else
357
368
return Status (" failed - register wasn't recognized to be a GPR or an FPR, "
358
369
" write strategy unknown" );
@@ -538,6 +549,9 @@ Status NativeRegisterContextLinux_arm64::WriteRegister(
538
549
539
550
return WriteTLS ();
540
551
} else if (IsSME (reg)) {
552
+ if (!GetRegisterInfo ().IsSMERegZA (reg))
553
+ return Status (" Writing to SVG is not supported." );
554
+
541
555
error = ReadZA ();
542
556
if (error.Fail ())
543
557
return error;
@@ -1357,13 +1371,27 @@ uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1357
1371
return sve_reg_offset;
1358
1372
}
1359
1373
1374
+ Status NativeRegisterContextLinux_arm64::ReadSMESVG () {
1375
+ // This register is the streaming vector length, so we will get it from
1376
+ // NT_ARM_ZA regardless of the current streaming mode.
1377
+ Status error = ReadZAHeader ();
1378
+ if (error.Success ())
1379
+ m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8 ;
1380
+
1381
+ return error;
1382
+ }
1383
+
1360
1384
std::vector<uint32_t > NativeRegisterContextLinux_arm64::GetExpeditedRegisters (
1361
1385
ExpeditedRegs expType) const {
1362
1386
std::vector<uint32_t > expedited_reg_nums =
1363
1387
NativeRegisterContext::GetExpeditedRegisters (expType);
1364
1388
// SVE, non-streaming vector length.
1365
1389
if (m_sve_state == SVEState::FPSIMD || m_sve_state == SVEState::Full)
1366
1390
expedited_reg_nums.push_back (GetRegisterInfo ().GetRegNumSVEVG ());
1391
+ // SME, streaming vector length. This is used by the ZA register which is
1392
+ // present even when streaming mode is not enabled.
1393
+ if (GetRegisterInfo ().IsSSVEEnabled ())
1394
+ expedited_reg_nums.push_back (GetRegisterInfo ().GetRegNumSMESVG ());
1367
1395
1368
1396
return expedited_reg_nums;
1369
1397
}
0 commit comments