[PATCH v6 13/25] powerpc: Remove direct call to mmap2 syscall handlers
Michael Ellerman
mpe at ellerman.id.au
Wed Sep 28 22:15:05 AEST 2022
Rohan McLure <rmclure at linux.ibm.com> writes:
> Syscall handlers should not be invoked internally by their symbol names,
> as these symbols defined by the architecture-defined SYSCALL_DEFINE
> macro. Move the compatibility syscall definition for mmap2 to
> syscalls.c, so that all mmap implementations can share a helper function.
>
> Remove 'inline' on static mmap helper.
>
> Signed-off-by: Rohan McLure <rmclure at linux.ibm.com>
> Reviewed-by: Nicholas Piggin <npiggin at gmail.com>
> ---
> V2: Move mmap2 compat implementation to asm/kernel/syscalls.c.
> V4: Move to be applied before syscall wrapper introduced.
> V5: Remove 'inline' in helper.
> ---
> arch/powerpc/kernel/sys_ppc32.c | 9 ---------
> arch/powerpc/kernel/syscalls.c | 17 ++++++++++++++---
> 2 files changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
> index d961634976d8..776ae7565fc5 100644
> --- a/arch/powerpc/kernel/sys_ppc32.c
> +++ b/arch/powerpc/kernel/sys_ppc32.c
> @@ -25,7 +25,6 @@
> #include <linux/poll.h>
> #include <linux/personality.h>
> #include <linux/stat.h>
> -#include <linux/mman.h>
> #include <linux/in.h>
> #include <linux/syscalls.h>
> #include <linux/unistd.h>
> @@ -48,14 +47,6 @@
> #include <asm/syscalls.h>
> #include <asm/switch_to.h>
>
> -unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
> - unsigned long prot, unsigned long flags,
> - unsigned long fd, unsigned long pgoff)
> -{
> - /* This should remain 12 even if PAGE_SIZE changes */
> - return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
> -}
> -
> compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
> u32 reg6, u32 pos1, u32 pos2)
> {
> diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
> index a04c97faa21a..9830957498b0 100644
> --- a/arch/powerpc/kernel/syscalls.c
> +++ b/arch/powerpc/kernel/syscalls.c
> @@ -36,9 +36,9 @@
> #include <asm/time.h>
> #include <asm/unistd.h>
>
> -static inline long do_mmap2(unsigned long addr, size_t len,
> - unsigned long prot, unsigned long flags,
> - unsigned long fd, unsigned long off, int shift)
> +static long do_mmap2(unsigned long addr, size_t len,
> + unsigned long prot, unsigned long flags,
> + unsigned long fd, unsigned long off, int shift)
> {
> if (!arch_validate_prot(prot, addr))
> return -EINVAL;
> @@ -56,6 +56,17 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, size_t, len,
> return do_mmap2(addr, len, prot, flags, fd, pgoff, PAGE_SHIFT-12);
> }
>
> +#ifdef CONFIG_COMPAT
> +COMPAT_SYSCALL_DEFINE6(mmap2,
> + unsigned long, addr, size_t, len,
> + unsigned long, prot, unsigned long, flags,
> + unsigned long, fd, unsigned long, pgoff)
> +{
> + /* This should remain 12 even if PAGE_SIZE changes */
> + return do_mmap2(addr, len, prot, flags, fd, pgoff << 12, PAGE_SHIFT-12);
This isn't quite right.
The comment about it remaining 12 is kind of misleading, it was true
when compat_sys_mmap2() called sys_mmap(), but it's wrong now that we're
calling do_mmap2().
The incoming "pgoff" here is in units of 4K.
do_mmap2() takes "off" in whatever units, but also takes "shift", which
has to tell us how to shift "off" into PAGE_SIZE units.
If we pass off = pgoff << 12, that's in bytes, so we need to page
shift = PAGE_SHIFT.
But I think it makes more sense to do the same as mmap2() and pass the
4K offset through, and pass shift = PAGE_SHIFT - 12. I also borrowed the
"off_4k" name from arm64. End result:
#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE6(mmap2,
unsigned long, addr, size_t, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, off_4k)
{
return do_mmap2(addr, len, prot, flags, fd, off_4k, PAGE_SHIFT-12);
}
#endif
With that my G5 boots again :)
cheers
More information about the Linuxppc-dev
mailing list