diff --git a/src/coreclr/pal/src/arch/arm64/context2.S b/src/coreclr/pal/src/arch/arm64/context2.S index 5cc537ab84bca9..40f46957025dc6 100644 --- a/src/coreclr/pal/src/arch/arm64/context2.S +++ b/src/coreclr/pal/src/arch/arm64/context2.S @@ -296,11 +296,3 @@ LEAF_END RestoreCompleteContext, _TEXT #endif // __APPLE__ -// Incoming: -// None -// -.arch_extension sve - LEAF_ENTRY CONTEXT_GetSveLengthFromOS, _TEXT - rdvl x0, 1 - ret lr - LEAF_END CONTEXT_GetSveLengthFromOS, _TEXT diff --git a/src/coreclr/pal/src/include/pal/context.h b/src/coreclr/pal/src/include/pal/context.h index 8658cdebb25cbc..9d5e3f01e5f59c 100644 --- a/src/coreclr/pal/src/include/pal/context.h +++ b/src/coreclr/pal/src/include/pal/context.h @@ -1622,21 +1622,6 @@ DWORD CONTEXTGetExceptionCodeForSignal(const siginfo_t *siginfo, #endif // HAVE_MACH_EXCEPTIONS else -#if defined(HOST_ARM64) -/*++ -Function : - CONTEXT_GetSveLengthFromOS - - Gets the SVE vector length -Parameters : - None -Return value : - The SVE vector length in bytes ---*/ -DWORD64 -CONTEXT_GetSveLengthFromOS( - ); -#endif // HOST_ARM64 #ifdef __cplusplus } diff --git a/src/coreclr/pal/src/thread/context.cpp b/src/coreclr/pal/src/thread/context.cpp index 522fe66aad1282..16964ce4e885ed 100644 --- a/src/coreclr/pal/src/thread/context.cpp +++ b/src/coreclr/pal/src/thread/context.cpp @@ -896,11 +896,17 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native) if (sve && sve->head.size >= SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve->vl))) { //TODO-SVE: This only handles vector lengths of 128bits. - if (CONTEXT_GetSveLengthFromOS() == 16) + // Use sve->vl from the signal frame to avoid SIGILL on platforms that + // provide an SVE context record without supporting SVE instructions + // (e.g. Apple M4 with SME streaming SVE under Virtualization.Framework). + if (sve->vl == 16) { _ASSERT((lpContext->XStateFeaturesMask & XSTATE_MASK_ARM64_SVE) == XSTATE_MASK_ARM64_SVE); - uint16_t vq = sve_vq_from_vl(lpContext->Vl); + // Derive vq from the signal frame's vl (the authoritative layout) + // rather than lpContext->Vl, to ensure offset calculations always + // match the actual frame even in non-debug builds. + uint16_t vq = sve_vq_from_vl(sve->vl); // Vector length should not have changed. _ASSERTE(lpContext->Vl == sve->vl); @@ -1255,9 +1261,12 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex if (sve && sve->head.size >= SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve->vl))) { //TODO-SVE: This only handles vector lengths of 128bits. - if (CONTEXT_GetSveLengthFromOS() == 16) + // Use sve->vl from the signal frame to avoid SIGILL on platforms that + // provide an SVE context record without supporting SVE instructions + // (e.g. Apple M4 with SME streaming SVE under Virtualization.Framework). + if (sve->vl == 16) { - _ASSERTE((sve->vl > 0) && (sve->vl % 16 == 0)); + _ASSERTE(sve->head.size >= SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(16))); lpContext->Vl = sve->vl; uint16_t vq = sve_vq_from_vl(sve->vl);