On Mon, Apr 12, 2010 at 04:07:35AM +0900, takas...@ops.dti.ne.jp wrote: > rlim_t conversion between host and target added. > Otherwise there are some incorrect case like > - RLIM_INFINITY on 32bit target -> 64bit host. > - RLIM_INFINITY on 64bit host -> mips and sparc target ? > - Big value(for 32bit target) on 64bit host -> 32bit target. > > One is added into getrlimit, setrlimit, and ugetrlimit. It converts both > RLIM_INFINITY and value bigger than target can hold(>31bit) to RLIM_INFINITY. > > Another one is added to guest_stack_size calculation introduced by > 703e0e89. The rule is mostly same except the result on the case is keeping > the value of guest_stack_size. > > Slightly tested for SH4, and x86_64 -linux-user on x86_64-pc-linux host. > > Signed-off-by: Takashi YOSHII <takas...@ops.dti.ne.jp>
Thanks, applied. > --- > linux-user/main.c | 3 ++- > linux-user/syscall.c | 30 ++++++++++++++++++++++-------- > linux-user/syscall_defs.h | 8 ++++++++ > 3 files changed, 32 insertions(+), 9 deletions(-) > > diff --git a/linux-user/main.c b/linux-user/main.c > index b394c00..60eea3a 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -2645,7 +2645,8 @@ int main(int argc, char **argv, char **envp) > { > struct rlimit lim; > if (getrlimit(RLIMIT_STACK, &lim) == 0 > - && lim.rlim_cur != RLIM_INFINITY) { > + && lim.rlim_cur != RLIM_INFINITY > + && lim.rlim_cur == (target_long)lim.rlim_cur) { > guest_stack_size = lim.rlim_cur; > } > } > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index a03e432..cfc91d1 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -831,6 +831,22 @@ static inline abi_long host_to_target_rusage(abi_ulong > target_addr, > return 0; > } > > +static inline rlim_t target_to_host_rlim(target_ulong target_rlim) > +{ > + if (target_rlim == TARGET_RLIM_INFINITY) > + return RLIM_INFINITY; > + else > + return tswapl(target_rlim); > +} > + > +static inline target_ulong host_to_target_rlim(rlim_t rlim) > +{ > + if (rlim == RLIM_INFINITY || rlim != (target_long)rlim) > + return TARGET_RLIM_INFINITY; > + else > + return tswapl(rlim); > +} > + > static inline abi_long copy_from_user_timeval(struct timeval *tv, > abi_ulong target_tv_addr) > { > @@ -5124,21 +5140,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > break; > case TARGET_NR_setrlimit: > { > - /* XXX: convert resource ? */ > int resource = arg1; > struct target_rlimit *target_rlim; > struct rlimit rlim; > if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) > goto efault; > - rlim.rlim_cur = tswapl(target_rlim->rlim_cur); > - rlim.rlim_max = tswapl(target_rlim->rlim_max); > + rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur); > + rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max); > unlock_user_struct(target_rlim, arg2, 0); > ret = get_errno(setrlimit(resource, &rlim)); > } > break; > case TARGET_NR_getrlimit: > { > - /* XXX: convert resource ? */ > int resource = arg1; > struct target_rlimit *target_rlim; > struct rlimit rlim; > @@ -5147,8 +5161,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > if (!is_error(ret)) { > if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) > goto efault; > - target_rlim->rlim_cur = tswapl(rlim.rlim_cur); > - target_rlim->rlim_max = tswapl(rlim.rlim_max); > + target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur); > + target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max); > unlock_user_struct(target_rlim, arg2, 1); > } > } > @@ -6233,8 +6247,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > struct target_rlimit *target_rlim; > if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) > goto efault; > - target_rlim->rlim_cur = tswapl(rlim.rlim_cur); > - target_rlim->rlim_max = tswapl(rlim.rlim_max); > + target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur); > + target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max); > unlock_user_struct(target_rlim, arg2, 1); > } > break; > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h > index 63c2bc3..255e89c 100644 > --- a/linux-user/syscall_defs.h > +++ b/linux-user/syscall_defs.h > @@ -669,6 +669,14 @@ struct target_rlimit { > abi_ulong rlim_max; > }; > > +#if defined(TARGET_ALPHA) > +#define TARGET_RLIM_INFINITY 0x7ffffffffffffffful > +#elif defined(TARGET_MIPS) || defined(TARGET_SPARC) > +#define TARGET_RLIM_INFINITY 0x7fffffffUL > +#else > +#define TARGET_RLIM_INFINITY ((target_ulong)~0UL) > +#endif > + > struct target_pollfd { > int fd; /* file descriptor */ > short events; /* requested events */ > -- > 1.6.5 > > > >