Hi All, In _stack_init function of crt0.S file, when the current mode is not user mode, all the processor modes are parsed and the corresponding stack limit are set for these modes for all A-profile and R-profile CPU's. But when the current processor mode is hypervisor mode, changing to any other mode using CPSR will result in an illegal instruction as per Arm-arm and simulator throws undefined instruction exception. This patch prevent the change of hypervisor mode to any other mode in _stack_init function in crt0.S files. Regression tested on arm-none-eabi target for newlib and newlib-nano and found no regressions. Ok for newlib master? Regards, Srinath. libgloss/ChangeLog: 2022-11-28 Srinath Parvathaneni * arm/crt0.S (_stack_init): Add check for hypervisor mode. newlib/ChangeLog: 2022-11-28 Srinath Parvathaneni * libc/sys/arm/crt0.S (_stack_init): Add check for hypervisor mode. ############### Attachment also inlined for ease of reply ############### diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index 78515180bf06f1da37669e4c7e6608c76e1b096d..e3c0ca00fd5d25e8059be07a0fb62490350b4dcb 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -148,13 +148,17 @@ /* M profile doesn't have CPSR register. */ #if (__ARM_ARCH_PROFILE != 'M') /* Following code is compatible for both ARM and Thumb ISA. */ - mrs r4, CPSR - /* Test mode bits - in User of all are 0. */ - tst r4, #(CPSR_M_MASK) + mrs r4, CPSR + mov r3, sp /* Save input SP value. */ + /* Test mode bits - in User mode all are 0. */ + ands r1, r4, #(CPSR_M_MASK) /* "eq" means r4 AND #0x0F is 0. */ beq .Lskip_cpu_modes - mov r3, sp /* Save input SP value. */ + /* Test mode bits - in Hypervisor Mode value is 0X0A. */ + cmp r1, #(CPSR_M_HYP) + /* "eq" means hypervisor mode and change of mode is not acceptable. */ + beq .Lskip_cpu_hyp_mode /* FIQ mode, interrupts disabled. */ mov r1, #(CPSR_M_FIQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) @@ -236,6 +240,7 @@ sub sl, r3, #64 << 10 #endif #endif +.Lskip_cpu_hyp_mode: FN_RETURN FN_EH_END diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 6b01d8a88b77f44b1ba495aa1f69156f12749527..b974c36c92c8f092643f63d2056927a107a1e85b 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -148,13 +148,17 @@ /* M profile doesn't have CPSR register. */ #if (__ARM_ARCH_PROFILE != 'M') /* Following code is compatible for both ARM and Thumb ISA. */ - mrs r4, CPSR - /* Test mode bits - in User of all are 0. */ - tst r4, #(CPSR_M_MASK) + mrs r4, CPSR + mov r3, sp /* Save input SP value. */ + /* Test mode bits - in User mode all are 0. */ + ands r1, r4, #(CPSR_M_MASK) /* "eq" means r4 AND #0x0F is 0. */ - beq .Lskip_cpu_modes + beq .Lskip_cpu_modes - mov r3, sp /* Save input SP value. */ + /* Test mode bits - in Hypervisor Mode value is 0X0A. */ + cmp r1, #(CPSR_M_HYP) + /* "eq" means hypervisor mode and change of mode is not acceptable. */ + beq .Lskip_cpu_hyp_mode /* FIQ mode, interrupts disabled. */ mov r1, #(CPSR_M_FIQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) @@ -236,6 +240,7 @@ sub sl, r3, #64 << 10 #endif #endif +.Lskip_cpu_hyp_mode: FN_RETURN FN_EH_END