Skip to content

Commit 4e40c7c

Browse files
authored
[lldb][debugserver] Save and restore the SVE/SME register state (#134184)
debugserver isn't saving and restoring the SVE/SME register state around inferior function calls. Making arbitrary function calls while in Streaming SVE mode is generally a poor idea because a NEON instruction can be hit and crash the expression execution, which is how I missed this, but they should be handled correctly if the user knows it is safe to do. rdar://146886210
1 parent 6a46c6c commit 4e40c7c

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

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

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2952,8 +2952,15 @@ kern_return_t DNBArchMachARM64::SetRegisterState(int set) {
29522952
return err;
29532953

29542954
switch (set) {
2955-
case e_regSetALL:
2956-
return SetGPRState() | SetVFPState() | SetEXCState() | SetDBGState(false);
2955+
case e_regSetALL: {
2956+
kern_return_t ret =
2957+
SetGPRState() | SetVFPState() | SetEXCState() | SetDBGState(false);
2958+
if (CPUHasSME()) {
2959+
ret |= SetSVEState();
2960+
ret |= SetSMEState();
2961+
}
2962+
return ret;
2963+
}
29572964
case e_regSetGPR:
29582965
return SetGPRState();
29592966
case e_regSetVFP:
@@ -3119,9 +3126,20 @@ uint32_t DNBArchMachARM64::SaveRegisterState() {
31193126
"error: GPR regs failed to read: %u ",
31203127
kret);
31213128
} else if ((kret = GetVFPState(force)) != KERN_SUCCESS) {
3122-
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () "
3123-
"error: %s regs failed to read: %u",
3129+
DNBLogThreadedIf(LOG_THREAD,
3130+
"DNBArchMachARM64::SaveRegisterState () "
3131+
"error: %s regs failed to read: %u",
31243132
"VFP", kret);
3133+
} else if (CPUHasSME() && (kret = SetSVEState() != KERN_SUCCESS)) {
3134+
DNBLogThreadedIf(LOG_THREAD,
3135+
"DNBArchMachARM64::SaveRegisterState () "
3136+
"error: %s regs failed to read: %u",
3137+
"SVE", kret);
3138+
} else if (CPUHasSME() && (kret = SetSMEState() != KERN_SUCCESS)) {
3139+
DNBLogThreadedIf(LOG_THREAD,
3140+
"DNBArchMachARM64::SaveRegisterState () "
3141+
"error: %s regs failed to read: %u",
3142+
"SME", kret);
31253143
} else {
31263144
const uint32_t save_id = GetNextRegisterStateSaveID();
31273145
m_saved_register_states[save_id] = m_state.context;
@@ -3144,11 +3162,26 @@ bool DNBArchMachARM64::RestoreRegisterState(uint32_t save_id) {
31443162
save_id, kret);
31453163
success = false;
31463164
} else if ((kret = SetVFPState()) != KERN_SUCCESS) {
3147-
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::RestoreRegisterState "
3148-
"(save_id = %u) error: %s regs failed to "
3149-
"write: %u",
3165+
DNBLogThreadedIf(LOG_THREAD,
3166+
"DNBArchMachARM64::RestoreRegisterState "
3167+
"(save_id = %u) error: %s regs failed to "
3168+
"write: %u",
31503169
save_id, "VFP", kret);
31513170
success = false;
3171+
} else if ((kret = SetSVEState()) != KERN_SUCCESS) {
3172+
DNBLogThreadedIf(LOG_THREAD,
3173+
"DNBArchMachARM64::RestoreRegisterState "
3174+
"(save_id = %u) error: %s regs failed to "
3175+
"write: %u",
3176+
save_id, "SVE", kret);
3177+
success = false;
3178+
} else if ((kret = SetSMEState()) != KERN_SUCCESS) {
3179+
DNBLogThreadedIf(LOG_THREAD,
3180+
"DNBArchMachARM64::RestoreRegisterState "
3181+
"(save_id = %u) error: %s regs failed to "
3182+
"write: %u",
3183+
save_id, "SME", kret);
3184+
success = false;
31523185
}
31533186
m_saved_register_states.erase(pos);
31543187
return success;

0 commit comments

Comments
 (0)