arm64: compat: Implement misalignment fixups for multiword loads
PATCH v2 1/1 arm64: compat: Implement misalignment fixups for multiword loads
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned. This is not something that is supported by the architecture, but was done anyway to increase compatibility with user space software, which mostly targeted x86 at the time and did not care about aligned accesses.
This feature is one of the remaining impediments to being able to switch to 64-bit kernels on 64-bit capable hardware running 32-bit user space, so let's implement it for the arm64 compat layer as well.
Note that the intent is to implement the exact same handling of misaligned multi-word loads and stores as the 32-bit kernel does, including what appears to be missing support for user space programs that rely on SETEND to switch to a different byte order and back. Also, like the 32-bit ARM version, we rely on the faulting address reported by the CPU to infer the memory address, instead of decoding the instruction fully to obtain this information.
This implementation is taken from the 32-bit ARM tree, with all pieces removed that deal with instructions other than LDRD/STRD and LDM/STM, or that deal with alignment exceptions taken in kernel mode.
---
Note to cc'ees: if this is something you would like to see merged, please indicate so. This stuff is unlikely to get in if there are no users.
v2: - drop some obsolete comments
- emit a perf alignment-fault event for every handled instruction
- use arm64_skip_faulting_instruction() to get the correct behavior wrt IT state and single step
- use types with correct endianness annotation (instructions are always little endian on v7/v8+)
arch/arm64/Kconfig | 4 + arch/arm64/include/asm/exception.h | 1 + arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/compat_alignment.c | 389 ++++++++++++++++++++ arch/arm64/mm/fault.c | 3 + 5 files changed, 398 insertions(+)
arch/arm64/Kconfig +4 -0
@@ -1508,6 +1508,10 @@ config THUMB2_COMPAT_VDSO Compile the compat vDSO with '-mthumb -fomit-frame-pointer' if y, otherwise with '-marm'. +config COMPAT_ALIGNMENT_FIXUPS + bool "Fix up misaligned multi-word loads and stores in user space" + default y + menuconfig ARMV8_DEPRECATED bool "Emulate deprecated/obsolete ARMv8 instructions" depends on SYSCTL
arch/arm64/include/asm/exception.h +1 -0
@@ -70,6 +70,7 @@ void do_sysinstr(unsigned long esr, struct pt_regs *regs);void do_sp_pc_abort (unsigned long addr,unsigned long esr,struct pt_regs *regs);void bad_el0_sync (struct pt_regs *regs,int reason,unsigned long esr);void do_cp15instr (unsigned long esr,struct pt_regs *regs); +int do_compat_alignment_fixup (unsigned long addr,struct pt_regs *regs);void do_el0_svc (struct pt_regs *regs);void do_el0_svc_compat (struct pt_regs *regs);void do_ptrauth_fault (struct pt_regs *regs,unsigned long esr);
arch/arm64/kernel/Makefile +1 -0
@@ -40,6 +40,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ sys_compat.o obj-$(CONFIG_COMPAT) += sigreturn32.o +obj-$(CONFIG_COMPAT_ALIGNMENT_FIXUPS) += compat_alignment.o obj-$(CONFIG_KUSER_HELPERS) += kuser32.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o obj-$(CONFIG_MODULES) += module.o
arch/arm64/kernel/compat_alignment.c new file +387 -0
387 lines not on this page · raw message
arch/arm64/mm/fault.c +3 -0
@@ -687,6 +687,9 @@ static int __kprobes do_translation_fault(unsigned long far,static int do_alignment_fault (unsigned long far,unsigned long esr,struct pt_regs *regs) { +if (IS_ENABLED (CONFIG_COMPAT_ALIGNMENT_FIXUPS ) && +compat_user_mode (regs)) +return do_compat_alignment_fixup (far, regs);do_bad_area (far, esr, regs);return 0 ; }
Signature · 7 lines
2.35.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 7 lines · Ard Biesheuvel
v2: - drop some obsolete comments
- emit a perf alignment-fault event for every handled instruction
- usearm64_skip_faulting_instruction()to get the correct behavior wrt IT state and single step
- use types with correct endianness annotation (instructions are always little endian on v7/v8+)
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 11 lines · Ard Biesheuvel
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned.
This feature is one of the remaining impediments to being able to switch to 64-bit kernels on 64-bit capable hardware running 32-bit user space, so let's implement it for the arm64 compat layer as well.
Note to cc'ees: if this is something you would like to see merged, please indicate so. This stuff is unlikely to get in if there are no users.
Decent 32-bit arm hardware is thin on the ground these days. Debian still has some but it's getting old and flaky. Being able to build reliably on 64-bit hardware is important and useful. Unaligned accesses are much less of a problem than they used to be, but they can still happen, so having these fixups available is definitely a good thing.
Debian runs its 32-bit buildds with alignment fixups turned on. It looks like the boxes still hit about 1 per day.
We also do 32 bit builds on 64-bit kernels (in 32-bit userspaces) and it mostly works. We do have packages that fail on 64-bit kernels and have to be built on real 32-bit hardware, but I don't know how much of that would be fixed by this patch. Some, presumably.
So yes, cheers for this. It is helpful in the real world (or at least it should be).
Wookey
Signature · 2 lines
Principal hats: Debian, Wookware, ARM http://wookware.org/
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Hi,
Quoted 23 lines · Wookey
Quoted 11 lines · Ard Biesheuvel
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned.
This feature is one of the remaining impediments to being able to switch to 64-bit kernels on 64-bit capable hardware running 32-bit user space, so let's implement it for the arm64 compat layer as well.
Note to cc'ees: if this is something you would like to see merged, please indicate so. This stuff is unlikely to get in if there are no users.
Decent 32-bit arm hardware is thin on the ground these days. Debian still has some but it's getting old and flaky. Being able to build reliably on 64-bit hardware is important and useful. Unaligned accesses are much less of a problem than they used to be, but they can still happen, so having these fixups available is definitely a good thing.
Debian runs its 32-bit buildds with alignment fixups turned on. It looks like the boxes still hit about 1 per day.
Quoted 7 lines
We also do 32 bit builds on 64-bit kernels (in 32-bit userspaces) and it mostly works. We do have packages that fail on 64-bit kernels and have to be built on real 32-bit hardware, but I don't know how much of that would be fixed by this patch. Some, presumably.
So yes, cheers for this. It is helpful in the real world (or at least it should be).
I confirm that this would be very helpful to Debian, so that 32-bit binaries behaves the same with a 32-bit or a 64-bit kernel. Otherwise we need to keep running (old) 32-bit hardware.
What's the status of those patches?
Thanks
Aurelien
Signature · 2 lines
Aurelien Jarno GPG: 4096R/1DDD8C9B [email protected] http://www.aurel32.net
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 32 lines · Aurelien Jarno
Hi,
Quoted 28 lines · Wookey
Quoted 11 lines · Ard Biesheuvel
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned.
This feature is one of the remaining impediments to being able to switch to 64-bit kernels on 64-bit capable hardware running 32-bit user space, so let's implement it for the arm64 compat layer as well.
Note to cc'ees: if this is something you would like to see merged, please indicate so. This stuff is unlikely to get in if there are no users.
Decent 32-bit arm hardware is thin on the ground these days. Debian still has some but it's getting old and flaky. Being able to build reliably on 64-bit hardware is important and useful. Unaligned accesses are much less of a problem than they used to be, but they can still happen, so having these fixups available is definitely a good thing.
Debian runs its 32-bit buildds with alignment fixups turned on. It looks like the boxes still hit about 1 per day.
We also do 32 bit builds on 64-bit kernels (in 32-bit userspaces) and it mostly works. We do have packages that fail on 64-bit kernels and have to be built on real 32-bit hardware, but I don't know how much of that would be fixed by this patch. Some, presumably.
Quoted 9 lines
Quoted 2 lines
So yes, cheers for this. It is helpful in the real world (or at least it should be).
I confirm that this would be very helpful to Debian, so that 32-bit binaries behaves the same with a 32-bit or a 64-bit kernel. Otherwise we need to keep running (old) 32-bit hardware.
What's the status of those patches?
Thanks for chiming in.
At this point, it is really up to the maintainers to decide whether the maintenance burden is worth it. The code itself seems pretty uncontroversial afaict.
Might other distros be in a similar situation? Or is this specific to Debian?
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 8 lines · Ard Biesheuvel
Thanks for chiming in.
At this point, it is really up to the maintainers to decide whether the maintenance burden is worth it. The code itself seems pretty uncontroversial afaict.
Might other distros be in a similar situation? Or is this specific to Debian?
My guess is that this is the most prominent on Debian: Many others including have discontinued or reduced support for 32-bit builds across architectures:
Ubuntu only supports "Core" with fewer packages on Raspberry Pi 2 but not desktop or server, Opensuse Leap and Tumbleweed both distributes a lot of board specific images but you have to know where to look as the main page only advertises amd64/i686/arm64/ppc64le/s390x, Fedora stopped entirely.
Android may be an interesting distro here: there are still a lot of phones running a pure 32-bit userland on Cortex-A53/A55 CPUs, and there are a large number of applications built for this. As far as I can tell, they tend to run 32-bit kernels as well, but that is not going to work on newer processors starting with Cortex-A76 big cores or Cortex-A510 little cores.
archlinuxarm supports 32-bit and 64-bit machines equally, but they apparently avoid the build service problem by using distcc with x86-to-arm cross compilers, and they don't seem to support their 32-bit images on 64-bit hardware/kernel.
https://hub.docker.com/search?q=&source=verified&type=image&architecture=arm&image_filter=official
lists 98 "official" arm32 images plus countless ones in other categories. I think these are popular in memory-constrained cloud hosting setups on arm64, so the Alpine based images are probably the most interesting ones because of their size, but they would run under someone else's kernel.
Arnd
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Catalin Marinas
maintainerQuoted 33 lines · Ard Biesheuvel
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned. This is not something that is supported by the architecture, but was done anyway to increase compatibility with user space software, which mostly targeted x86 at the time and did not care about aligned accesses.
This feature is one of the remaining impediments to being able to switch to 64-bit kernels on 64-bit capable hardware running 32-bit user space, so let's implement it for the arm64 compat layer as well.
Note that the intent is to implement the exact same handling of misaligned multi-word loads and stores as the 32-bit kernel does, including what appears to be missing support for user space programs that rely on SETEND to switch to a different byte order and back. Also, like the 32-bit ARM version, we rely on the faulting address reported by the CPU to infer the memory address, instead of decoding the instruction fully to obtain this information.
This implementation is taken from the 32-bit ARM tree, with all pieces removed that deal with instructions other than LDRD/STRD and LDM/STM, or that deal with alignment exceptions taken in kernel mode.
Cc Vagrant Cascadian <[email protected]>Cc Riku Voipio <[email protected]>Cc Steve McIntyre <[email protected]>Signed-off-by Ard Biesheuvel <[email protected]>---
Note to cc'ees: if this is something you would like to see merged, please indicate so. This stuff is unlikely to get in if there are no users.
Quoted 6 lines
v2: - drop some obsolete comments
- emit a perf alignment-fault event for every handled instruction
- usearm64_skip_faulting_instruction()to get the correct behavior wrt IT state and single step
- use types with correct endianness annotation (instructions are always little endian on v7/v8+)
It looks like that's a fairly popular request from people running 32-bit user on AArch64 kernels, so happy to queue it for 6.1 (if it still applies cleanly). I'm not too keen on code duplication but it's a lot more hassle to create a common decoding/emulation library to share with arch/arm, especially as such code is not going to change in the future.
arch/arm64/Kconfig config THUMB2_COMPAT_VDSO · line 1513
Quoted 3 lines
arch/arm64/Kconfig +3
-0+config COMPAT_ALIGNMENT_FIXUPS + bool "Fix up misaligned multi-word loads and stores in user space" + default y
For consistency with ARMV8_DEPRECATED, I think we should keep this as default n.
Thanks.
Signature · 6 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 48 lines · Catalin Marinas
Quoted 33 lines · Ard Biesheuvel
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned. This is not something that is supported by the architecture, but was done anyway to increase compatibility with user space software, which mostly targeted x86 at the time and did not care about aligned accesses.
This feature is one of the remaining impediments to being able to switch to 64-bit kernels on 64-bit capable hardware running 32-bit user space,
soDocumentation/x86/boot.rstlet's implement it for the arm64 compat layer as well.Note that the intent is to implement the exact same handling of misaligned multi-word loads and stores as the 32-bit kernel does, including what appears to be missing support for user space programs that rely on SETEND to switch to a different byte order and back. Also, like the 32-bit ARM version, we rely on the faulting address reported by the CPU to infer the memory address, instead of decoding the instruction fully to obtain this information.
This implementation is taken from the 32-bit ARM tree, with all pieces removed that deal with instructions other than LDRD/STRD and LDM/STM, or that deal with alignment exceptions taken in kernel mode.
Cc Vagrant Cascadian <[email protected]>Cc Riku Voipio <[email protected]>Cc Steve McIntyre <[email protected]>Signed-off-by Ard Biesheuvel <[email protected]>---
Note to cc'ees: if this is something you would like to see merged, please indicate so. This stuff is unlikely to get in if there are no users.Quoted 6 lines
v2: - drop some obsolete comments
- emit a perf alignment-fault event for every handled instruction
- usearm64_skip_faulting_instruction()to get the correct behavior wrt IT state and single step
- use types with correct endianness annotation (instructions are always little endian on v7/v8+)It looks like that's a fairly popular request from people running 32-bit user on AArch64 kernels, so happy to queue it for 6.1 (if it still applies cleanly). I'm not too keen on code duplication but it's a lot more hassle to create a common decoding/emulation library to share with
arch/arm, especially as such code is not going to change in the future.
Quoted 7 lines
arch/arm64/Kconfig config THUMB2_COMPAT_VDSO · line 1513
Quoted 3 lines
arch/arm64/Kconfig +3
-0+config COMPAT_ALIGNMENT_FIXUPS + bool "Fix up misaligned multi-word loads and stores in user space" + default yFor consistency with
ARMV8_DEPRECATED, I think we should keep this as default n.
Fair enough. I take it you can fix this up while applying?
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Catalin Marinas
maintainerQuoted 10 lines · Ard Biesheuvel
Quoted 7 lines · Catalin Marinas
arch/arm64/Kconfig config THUMB2_COMPAT_VDSO · line 1513
Quoted 3 lines · Ard Biesheuvel
arch/arm64/Kconfig +3
-0+config COMPAT_ALIGNMENT_FIXUPS + bool "Fix up misaligned multi-word loads and stores in user space" + default yFor consistency with
ARMV8_DEPRECATED, I think we should keep this as default n.Fair enough. I take it you can fix this up while applying?
Yes.
Signature · 6 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 8 lines · Ard Biesheuvel
The 32-bit ARM kernel implements fixups on behalf of user space when using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit aligned. This is not something that is supported by the architecture, but was done anyway to increase compatibility with user space software, which mostly targeted x86 at the time and did not care about aligned accesses.
[...]
Applied to arm64 (for-next/misc), thanks!
[1/1] arm64: compat: Implement misalignment fixups for multiword loads
https://git.kernel.org/arm64/c/3fc24ef32d3b
Signature · 7 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel