diff mbox

[20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

Message ID 573305A8.50406@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

zhangjian May 11, 2016, 10:12 a.m. UTC
Hi, Arnd

On 2016/5/11 16:09, Arnd Bergmann wrote:
 > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
 >>> I don't remember. It's probably not important whether we have the shift
 >>> in there, as long as it's independent of the actual kernel page size and
 >>> user space and kernel agree on the calling conventions.
 >> Well. I am ok with where to shift the pages size because we get the same
 >> result. I was just thinking if we should get rid of the name of mmap2 in our
 >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
 >> if they do not know the implementations.
 >
 > That is a good point: If the implementation matches the mmap() behavior rather than
 > mmap2(), we should rename the macro by doing
 >
 > #undef __NR_mmap2
 > #define __NR_mmap 222
 >
 > in the uapi/asm/unistd.h file for ilp32 mode.
Do you mean define the following things in kernel:
```
```
Then glibc could call mmap instead of mmap2.
I could not try it now. Because after change off_t to 64bit in glibc, stat
is fail. I may need to revert the stat relative patch.

 > Alternatively we can keep the
 > __NR_mmap2 definition but then we need to pass the pgoff (value shifted by
 > 12 bits) argument rather than the size in bytes.
It means that we could reuse the existing code of mmap2 in kernel and glibc.
But we need to shift twice when kernel is 64k page.
It seems that the first method is more clear. Suggestion?

Regards

Bamvor
 >
 >   Arnd
 >

Comments

zhangjian May 11, 2016, 11:16 a.m. UTC | #1
Hi,

On 2016/5/11 18:12, Zhangjian (Bamvor) wrote:
> Hi, Arnd
>
> On 2016/5/11 16:09, Arnd Bergmann wrote:
>  > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
>  >>> I don't remember. It's probably not important whether we have the shift
>  >>> in there, as long as it's independent of the actual kernel page size and
>  >>> user space and kernel agree on the calling conventions.
>  >> Well. I am ok with where to shift the pages size because we get the same
>  >> result. I was just thinking if we should get rid of the name of mmap2 in our
>  >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
>  >> if they do not know the implementations.
>  >
>  > That is a good point: If the implementation matches the mmap() behavior rather than
>  > mmap2(), we should rename the macro by doing
>  >
>  > #undef __NR_mmap2
>  > #define __NR_mmap 222
>  >
>  > in the uapi/asm/unistd.h file for ilp32 mode.
> Do you mean define the following things in kernel:
> ```
> diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
> index 1caadc2..3f79640 100644
> --- a/arch/arm64/include/uapi/asm/unistd.h
> +++ b/arch/arm64/include/uapi/asm/unistd.h
> @@ -14,3 +14,9 @@
>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>    */
>   #include <asm-generic/unistd.h>
> +
> +#ifdef __ILP32__
> +#undef __NR_mmap2
> +#define __NR_mmap 222
> +#endif /* #ifdef __ILP32__ */
> +
> ```
> Then glibc could call mmap instead of mmap2.
> I could not try it now. Because after change off_t to 64bit in glibc, stat
> is fail. I may need to revert the stat relative patch.
After revert stat relative patch in glibc, mmap01-mmap14 success. But mmap16
success with segfault. I will investigate it later.

There is pointer and size_t in mmap, so, IIUC, we need to clear the top halves
of register by using COMPAT_SYSCALL_WRAP6. And after check the function in
arch/s390/kernel/compat_linux.c, I feel that we need to do the same thing for
pread64 and pwrite64.

But I got following error when I try to add
COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
size_t, count, loff_t, pos);
COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
size_t, count, loff_t, pos);

The error message:
kernel/compat_wrapper.c: In function 'compat_SyS_pread64':
include/linux/compiler.h:429:38: error: call to '__compiletime_assert_308' declared with attribute error: BUILD_BUG_ON failed: (sizeof(loff_t) > 4) && !__TYPE_IS_L(loff_t) && !__TYPE_IS_UL(loff_t) && !__TYPE_IS_PTR(loff_t)
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:412:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^
include/linux/compiler.h:429:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/bug.h:50:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^
include/linux/bug.h:74:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
^
include/linux/compat.h:749:2: note: in expansion of macro 'BUILD_BUG_ON'
BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \
^
include/linux/syscalls.h:38:23: note: in expansion of macro '__SC_COMPAT_CAST'
#define __MAP1(m,t,a) m(t,a)
^
include/linux/syscalls.h:39:35: note: in expansion of macro '__MAP1'
#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
^
include/linux/syscalls.h:40:35: note: in expansion of macro '__MAP2'
#define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
^
include/linux/syscalls.h:41:35: note: in expansion of macro '__MAP3'
#define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
^
include/linux/syscalls.h:44:22: note: in expansion of macro '__MAP4'
#define __MAP(n,...) __MAP##n(__VA_ARGS__)
^
include/linux/compat.h:777:19: note: in expansion of macro '__MAP'
return sys##name(__MAP(x, __SC_COMPAT_CAST, __VA_ARGS__)); \
^
include/linux/compat.h:735:41: note: in expansion of macro 'COMPAT_SYSCALL_WRAPx'
#define COMPAT_SYSCALL_WRAP4(name, ...) COMPAT_SYSCALL_WRAPx(4, _##name,\
^
kernel/compat_wrapper.c:307:1: note: in expansion of macro 'COMPAT_SYSCALL_WRAP4'
COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
^

Because the loff_t is not the long, unsigned long or pointer.

Regards

Bamvor
>  > Alternatively we can keep the
>  > __NR_mmap2 definition but then we need to pass the pgoff (value shifted by
>  > 12 bits) argument rather than the size in bytes.
> It means that we could reuse the existing code of mmap2 in kernel and glibc.
> But we need to shift twice when kernel is 64k page.
> It seems that the first method is more clear. Suggestion?
>
> Regards
>
> Bamvor
>  >
>  >   Arnd
>  >
>
Arnd Bergmann May 11, 2016, 2:50 p.m. UTC | #2
On Wednesday 11 May 2016 19:16:44 Zhangjian wrote:
> Hi,
> 
> On 2016/5/11 18:12, Zhangjian (Bamvor) wrote:
> > Hi, Arnd
> >
> > On 2016/5/11 16:09, Arnd Bergmann wrote:
> >  > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
> >  >>> I don't remember. It's probably not important whether we have the shift
> >  >>> in there, as long as it's independent of the actual kernel page size and
> >  >>> user space and kernel agree on the calling conventions.
> >  >> Well. I am ok with where to shift the pages size because we get the same
> >  >> result. I was just thinking if we should get rid of the name of mmap2 in our
> >  >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> >  >> if they do not know the implementations.
> >  >
> >  > That is a good point: If the implementation matches the mmap() behavior rather than
> >  > mmap2(), we should rename the macro by doing
> >  >
> >  > #undef __NR_mmap2
> >  > #define __NR_mmap 222
> >  >
> >  > in the uapi/asm/unistd.h file for ilp32 mode.
> > Do you mean define the following things in kernel:
> > ```
> > diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
> > index 1caadc2..3f79640 100644
> > --- a/arch/arm64/include/uapi/asm/unistd.h
> > +++ b/arch/arm64/include/uapi/asm/unistd.h
> > @@ -14,3 +14,9 @@
> >    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >    */
> >   #include <asm-generic/unistd.h>
> > +
> > +#ifdef __ILP32__
> > +#undef __NR_mmap2
> > +#define __NR_mmap 222
> > +#endif /* #ifdef __ILP32__ */
> > +
> > ```
> > Then glibc could call mmap instead of mmap2.
> > I could not try it now. Because after change off_t to 64bit in glibc, stat
> > is fail. I may need to revert the stat relative patch.
> After revert stat relative patch in glibc, mmap01-mmap14 success. But mmap16
> success with segfault. I will investigate it later.
> 
> There is pointer and size_t in mmap, so, IIUC, we need to clear the top halves
> of register by using COMPAT_SYSCALL_WRAP6.

Correct, good catch!

> And after check the function in
> arch/s390/kernel/compat_linux.c, I feel that we need to do the same thing for
> pread64 and pwrite64.
> 

> But I got following error when I try to add
> COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
> size_t, count, loff_t, pos);
> COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
> size_t, count, loff_t, pos);
> 

Hmm, that is indeed tricky. I think COMPAT_SYSCALL_WRAP4 rightfully
refuses the loff_t argument here, as the common case is that this is
not possible.

Can you open-code this using a COMPAT_SYSCALL4 definition similar to what
arch/tile has, but without the merging of the two halves of the argument?

	Arnd
diff mbox

Patch

diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
index 1caadc2..3f79640 100644
--- a/arch/arm64/include/uapi/asm/unistd.h
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -14,3 +14,9 @@ 
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #include <asm-generic/unistd.h>
+
+#ifdef __ILP32__
+#undef __NR_mmap2
+#define __NR_mmap 222
+#endif /* #ifdef __ILP32__ */
+