Page MenuHomeFreeBSD

Add a Saved Process Status Register bit for AArch32 execution mode.
ClosedPublic

Authored by ed on Nov 18 2017, 7:28 PM.
Referenced Files
Unknown Object (File)
Feb 24 2024, 6:05 AM
Unknown Object (File)
Feb 23 2024, 9:09 PM
Unknown Object (File)
Feb 6 2024, 4:42 AM
Unknown Object (File)
Feb 3 2024, 10:14 PM
Unknown Object (File)
Dec 28 2023, 9:39 PM
Unknown Object (File)
Dec 28 2023, 9:39 PM
Unknown Object (File)
Dec 24 2023, 11:33 PM
Unknown Object (File)
Dec 24 2023, 11:27 AM
Subscribers

Details

Summary

The documentation on the Saved Process Status Register (SPSR) is a bit
weird; the M[4] bit is documented separately from M[3:0]. The M[4] bit
can be toggled to switch to 32-bit execution mode. This functionality is
orthogonal to M[3:0].

Change the definition of PSR_M_MASK to no longer include M[4]. Add a new
definition, PSR_AARCH32 that can be used to toggle 32-bit independently.
This bit will be used by the cloudabi32 code to force execution of
userspace code in 32-bit mode.

Test Plan

This change, and others, allow me to run CloudABI's unit
testing binary properly.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

andrew requested changes to this revision.Nov 19 2017, 11:33 AM

This will allow userspace to switch between AArch64 and AArch32 via sigreturn. sys_sigreturn has checks on the PSR bits to ensure they are safe to install that this will break.

This revision now requires changes to proceed.Nov 19 2017, 11:33 AM

This will allow userspace to switch between AArch64 and AArch32 via sigreturn. sys_sigreturn has checks on the PSR bits to ensure they are safe to install that this will break.

This would be benign, right? For the kernel, it is irrelevant whether user space sets or clears this flag. Just like NZCV, etc.

In D13148#273913, @ed wrote:

This would be benign, right? For the kernel, it is irrelevant whether user space sets or clears this flag. Just like NZCV, etc.

I'm not sure how the kernel would handle userspace changing between 64 and 32 bit code. From discussions with an ARM Linux developer it sounds like they had issues with this. While M[3:0] doesn't have any shared values between AArch32 and AArch64 I wouldn't want to rely on this as future architectures may change this.

In D13148#273913, @ed wrote:

This would be benign, right? For the kernel, it is irrelevant whether user space sets or clears this flag. Just like NZCV, etc.

I'm not sure how the kernel would handle userspace changing between 64 and 32 bit code.

It's pretty straight-forward how that's handled, right? The only way this can take effect is by going through EL1, the kernel, first. For the CPU, it would just be an ordinary context switch like any other.

From discussions with an ARM Linux developer it sounds like they had issues with this.

Maybe you're referring to switching between 64-bit and 32-bit code without going through EL1 first. This is explicitly documented as unsupported.

In D13148#273977, @ed wrote:
In D13148#273913, @ed wrote:

This would be benign, right? For the kernel, it is irrelevant whether user space sets or clears this flag. Just like NZCV, etc.

I'm not sure how the kernel would handle userspace changing between 64 and 32 bit code.

It's pretty straight-forward how that's handled, right? The only way this can take effect is by going through EL1, the kernel, first. For the CPU, it would just be an ordinary context switch like any other.

Yes, but what would happen if we start running 32 bit code when the kernel thinks the process is 64 bit, or vice versa?

From discussions with an ARM Linux developer it sounds like they had issues with this.

Maybe you're referring to switching between 64-bit and 32-bit code without going through EL1 first. This is explicitly documented as unsupported.

No, from memory it was an incorrect check the value passed to the kernel from userspace was wrong. I did make sure we have a check on signal return, however for it to work we need to check M[4] is set correctly. With this change the user could change this bit.

As part of this I have found a security issue with the handling of spsr, and fixed in rS326137. You should add a check to set_mcontext to ensure M[4] is set correctly.

Don't allow PSR_AARCH32 to be set in sigreturn().

Maybe you're referring to switching between 64-bit and 32-bit code without going through EL1 first. This is explicitly documented as unsupported.

No, from memory it was an incorrect check the value passed to the kernel from userspace was wrong. I did make sure we have a check on signal return, however for it to work we need to check M[4] is set correctly. With this change the user could change this bit.

Fair enough. I've just extended this patch to disallow PSR_AARCH32 in sigreturn().

sys/arm64/arm64/machdep.c
542 ↗(On Diff #35800)

You need to rebase, this has moved.

This revision is now accepted and ready to land.Nov 26 2017, 2:55 PM
This revision was automatically updated to reflect the committed changes.