Message ID | 1464705911-28960-3-git-send-email-peter.maydell@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Le 31/05/2016 à 16:45, Peter Maydell a écrit : > Fix errors in the implementation of NR_fadvise64 and NR_fadvise64_64 > for 32-bit guests, which pass their off_t values in register pairs. > We can't use the 64-bit code path for this, so split out the 32-bit > cases, so that we can correctly handle the "only offset is 64-bit" > and "both offset and length are 64-bit" syscall flavours, and > "uses aligned register pairs" and "does not" flavours of target. > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> > --- > linux-user/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 40 insertions(+) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 4894919..638b455 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -9340,6 +9340,44 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, > ret = -host_to_target_errno(ret); > break; > #endif > + > +#if TARGET_ABI_BITS == 32 > + > +#ifdef TARGET_NR_fadvise64_64 > + case TARGET_NR_fadvise64_64: > + /* 6 args: fd, offset (high, low), len (high, low), advice */ > + if (regpairs_aligned(cpu_env)) { > + /* offset is in (3,4), len in (5,6) and advice in 7 */ > + arg2 = arg3; > + arg3 = arg4; > + arg4 = arg5; > + arg5 = arg6; > + arg6 = arg7; > + } > + ret = -host_to_target_errno(posix_fadvise(arg1, > + target_offset64(arg2, arg3), > + target_offset64(arg4, arg5), > + arg6)); > + break; > +#endif > + > +#ifdef TARGET_NR_fadvise64 > + case TARGET_NR_fadvise64: > + /* 5 args: fd, offset (high, low), len, advice */ > + if (regpairs_aligned(cpu_env)) { > + /* offset is in (3,4), len in 5 and advice in 6 */ > + arg2 = arg3; > + arg3 = arg4; > + arg4 = arg5; > + arg5 = arg6; > + } > + ret = -host_to_target_errno(posix_fadvise(arg1, > + target_offset64(arg2, arg3), > + arg4, arg5)); > + break; > +#endif > + > +#else /* not a 32-bit ABI */ > #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64) > #ifdef TARGET_NR_fadvise64_64 > case TARGET_NR_fadvise64_64: > @@ -9359,6 +9397,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, > ret = -posix_fadvise(arg1, arg2, arg3, arg4); > break; > #endif > +#endif /* end of 64-bit ABI fadvise handling */ > + > #ifdef TARGET_NR_madvise > case TARGET_NR_madvise: > /* A straight passthrough may not be safe because qemu sometimes >
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 4894919..638b455 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9340,6 +9340,44 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = -host_to_target_errno(ret); break; #endif + +#if TARGET_ABI_BITS == 32 + +#ifdef TARGET_NR_fadvise64_64 + case TARGET_NR_fadvise64_64: + /* 6 args: fd, offset (high, low), len (high, low), advice */ + if (regpairs_aligned(cpu_env)) { + /* offset is in (3,4), len in (5,6) and advice in 7 */ + arg2 = arg3; + arg3 = arg4; + arg4 = arg5; + arg5 = arg6; + arg6 = arg7; + } + ret = -host_to_target_errno(posix_fadvise(arg1, + target_offset64(arg2, arg3), + target_offset64(arg4, arg5), + arg6)); + break; +#endif + +#ifdef TARGET_NR_fadvise64 + case TARGET_NR_fadvise64: + /* 5 args: fd, offset (high, low), len, advice */ + if (regpairs_aligned(cpu_env)) { + /* offset is in (3,4), len in 5 and advice in 6 */ + arg2 = arg3; + arg3 = arg4; + arg4 = arg5; + arg5 = arg6; + } + ret = -host_to_target_errno(posix_fadvise(arg1, + target_offset64(arg2, arg3), + arg4, arg5)); + break; +#endif + +#else /* not a 32-bit ABI */ #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64) #ifdef TARGET_NR_fadvise64_64 case TARGET_NR_fadvise64_64: @@ -9359,6 +9397,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = -posix_fadvise(arg1, arg2, arg3, arg4); break; #endif +#endif /* end of 64-bit ABI fadvise handling */ + #ifdef TARGET_NR_madvise case TARGET_NR_madvise: /* A straight passthrough may not be safe because qemu sometimes
Fix errors in the implementation of NR_fadvise64 and NR_fadvise64_64 for 32-bit guests, which pass their off_t values in register pairs. We can't use the 64-bit code path for this, so split out the 32-bit cases, so that we can correctly handle the "only offset is 64-bit" and "both offset and length are 64-bit" syscall flavours, and "uses aligned register pairs" and "does not" flavours of target. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- linux-user/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)