From 3760c445867681d0b150f7cbc344e1e5d075c0e6 Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 13 Nov 2020 03:31:51 +0100 Subject: [PATCH] linux5.9: enable ppcle support --- srcpkgs/linux5.9/files/ppc64le-dotconfig | 1 + .../linux5.9/patches/ppcle-broken-vdso.patch | 17 +++ srcpkgs/linux5.9/patches/ppcle-enable.patch | 33 ++++++ .../patches/ppcle-ll-compat-sys.patch | 107 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 srcpkgs/linux5.9/patches/ppcle-broken-vdso.patch create mode 100644 srcpkgs/linux5.9/patches/ppcle-enable.patch create mode 100644 srcpkgs/linux5.9/patches/ppcle-ll-compat-sys.patch diff --git a/srcpkgs/linux5.9/files/ppc64le-dotconfig b/srcpkgs/linux5.9/files/ppc64le-dotconfig index 15cf7b5c68..2cd4fa11a3 100644 --- a/srcpkgs/linux5.9/files/ppc64le-dotconfig +++ b/srcpkgs/linux5.9/files/ppc64le-dotconfig @@ -281,6 +281,7 @@ CONFIG_NR_CPUS=2048 CONFIG_PPC_DOORBELL=y # end of Processor support +CONFIG_VDSO32=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_PPC64_BOOT_WRAPPER=y diff --git a/srcpkgs/linux5.9/patches/ppcle-broken-vdso.patch b/srcpkgs/linux5.9/patches/ppcle-broken-vdso.patch new file mode 100644 index 0000000000..38563abaf1 --- /dev/null +++ b/srcpkgs/linux5.9/patches/ppcle-broken-vdso.patch @@ -0,0 +1,17 @@ +Disable vDSOs which are broken on 32 bit LE. + +Source: @eerykitty + +diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S +index ce3e7f3e5..7600f9c11 100644 +--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S ++++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S +@@ -144,7 +144,7 @@ VERSION + __kernel_datapage_offset; + + __kernel_get_syscall_map; +-#ifndef CONFIG_PPC_BOOK3S_601 ++#if !defined(__LITTLE_ENDIAN__) && !defined(CONFIG_PPC_BOOK3S_601) + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; diff --git a/srcpkgs/linux5.9/patches/ppcle-enable.patch b/srcpkgs/linux5.9/patches/ppcle-enable.patch new file mode 100644 index 0000000000..c9f0567d5c --- /dev/null +++ b/srcpkgs/linux5.9/patches/ppcle-enable.patch @@ -0,0 +1,33 @@ +These are experimental fixes for running 32-bit little endian binaries on +Linux/ppc64le. While this may seem pointless, it does work, does not break +anything, and may allow enablement of things we couldn't do before (e.g. +support for box86 and thus reasonably fast emulation of 32-bit x86 games). + +The first part is a signal handler fix, the second part enables the 32-bit +VDSO by removing the ppc32/big endian restriction. + +Source: @eerykitty + +--- a/arch/powerpc/kernel/signal_32.c ++++ b/arch/powerpc/kernel/signal_32.c +@@ -1427,8 +1427,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, + regs->gpr[3] = ksig->sig; + regs->gpr[4] = (unsigned long) sc; + regs->nip = (unsigned long) (unsigned long)ksig->ka.sa.sa_handler; +- /* enter the signal handler in big-endian mode */ ++ /* enter the signal handler in native-endian mode */ + regs->msr &= ~MSR_LE; ++ regs->msr |= (MSR_KERNEL & MSR_LE); + return 0; + + badframe: +--- a/arch/powerpc/platforms/Kconfig.cputype ++++ b/arch/powerpc/platforms/Kconfig.cputype +@@ -484,7 +484,6 @@ endmenu + + config VDSO32 + def_bool y +- depends on PPC32 || CPU_BIG_ENDIAN + help + This symbol controls whether we build the 32-bit VDSO. We obviously + want to do that if we're building a 32-bit kernel. If we're building diff --git a/srcpkgs/linux5.9/patches/ppcle-ll-compat-sys.patch b/srcpkgs/linux5.9/patches/ppcle-ll-compat-sys.patch new file mode 100644 index 0000000000..19b9530a51 --- /dev/null +++ b/srcpkgs/linux5.9/patches/ppcle-ll-compat-sys.patch @@ -0,0 +1,107 @@ +From 98014e4b27063ed74313878233e91b7b52b2a031 Mon Sep 17 00:00:00 2001 +From: Will Springer +Date: Tue, 9 Jun 2020 02:11:36 -0700 +Subject: [PATCH] powerpc/compat32: swap hi/lo parts of 64-bit syscall args on + 32LE + +This allows compat_sys calls with 64-bit args to function correctly +when called by ppcle userlands on ppc64le. + +Tested with `file /bin/bash` (pread64) and `truncate -s 5G test` (ftruncate64). +--- + arch/powerpc/kernel/sys_ppc32.c | 49 +++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 21 deletions(-) + +diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c +index d36c6391eaf5..16ff0399a257 100644 +--- a/arch/powerpc/kernel/sys_ppc32.c ++++ b/arch/powerpc/kernel/sys_ppc32.c +@@ -59,57 +59,64 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len, + /* + * long long munging: + * The 32 bit ABI passes long longs in an odd even register pair. ++ * High and low parts are swapped depending on endian mode, ++ * so define a macro (similar to mips linux32) to handle that. + */ ++#ifdef __LITTLE_ENDIAN__ ++#define merge_64(low, high) ((u64)high << 32) | low ++#else ++#define merge_64(high, low) ((u64)high << 32) | low ++#endif + + compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, +- u32 reg6, u32 poshi, u32 poslo) ++ u32 reg6, u32 pos1, u32 pos2) + { +- return ksys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); ++ return ksys_pread64(fd, ubuf, count, merge_64(pos1, pos2)); + } + + compat_ssize_t compat_sys_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, +- u32 reg6, u32 poshi, u32 poslo) ++ u32 reg6, u32 pos1, u32 pos2) + { +- return ksys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); ++ return ksys_pwrite64(fd, ubuf, count, merge_64(pos1, pos2)); + } + +-compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) ++compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offset1, u32 offset2, u32 count) + { +- return ksys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); ++ return ksys_readahead(fd, merge_64(offset1, offset2), count); + } + + asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, +- unsigned long high, unsigned long low) ++ unsigned long len1, unsigned long len2) + { +- return ksys_truncate(path, (high << 32) | low); ++ return ksys_truncate(path, merge_64(len1, len2)); + } + +-asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, +- u32 lenhi, u32 lenlo) ++asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2, ++ u32 len1, u32 len2) + { +- return ksys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, +- ((loff_t)lenhi << 32) | lenlo); ++ return ksys_fallocate(fd, mode, ((loff_t)offset1 << 32) | offset2, ++ merge_64(len1, len2)); + } + +-asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, +- unsigned long low) ++asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long len1, ++ unsigned long len2) + { +- return ksys_ftruncate(fd, (high << 32) | low); ++ return ksys_ftruncate(fd, merge_64(len1, len2)); + } + +-long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, ++long ppc32_fadvise64(int fd, u32 unused, u32 offset1, u32 offset2, + size_t len, int advice) + { +- return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low, len, ++ return ksys_fadvise64_64(fd, merge_64(offset1, offset2), len, + advice); + } + + asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, +- unsigned offset_hi, unsigned offset_lo, +- unsigned nbytes_hi, unsigned nbytes_lo) ++ unsigned offset1, unsigned offset2, ++ unsigned nbytes1, unsigned nbytes2) + { +- loff_t offset = ((loff_t)offset_hi << 32) | offset_lo; +- loff_t nbytes = ((loff_t)nbytes_hi << 32) | nbytes_lo; ++ loff_t offset = merge_64(offset1, offset2); ++ loff_t nbytes = merge_64(nbytes1, nbytes2); + + return ksys_sync_file_range(fd, offset, nbytes, flags); + } +-- +2.26.2 +