qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Re: [PATCH] efault - add data type to put_user()/get_us


From: Fabrice Bellard
Subject: Re: [Qemu-devel] Re: [PATCH] efault - add data type to put_user()/get_user()
Date: Tue, 06 Nov 2007 00:33:29 +0100
User-agent: Thunderbird 1.5.0.9 (X11/20070212)

Thayne Harbaugh wrote:
> On Mon, 2007-11-05 at 22:42 +0100, Fabrice Bellard wrote:
>> Thayne Harbaugh wrote:
>>> On Sat, 2007-11-03 at 20:05 +0100, Fabrice Bellard wrote:
>>>> I think that using host addresses in __put_user and __get_user is not
>>>> logical. They should use target addresses as get_user and put_user. As
>>>> Paul said, It is not worth mixing get/put/copy and lock/unlock functions.
>>> Please see the "RFC: x86_64 Best way to fix 'cast to pointer'" email for
>>> some discussion of get/put/copy and lock/unlock.  {get,put}_user() is
>>> used for individual ints or other atomically writable types that are
>>> passed as pointers into a syscall.  copy_{to,from}_user_<struct>() are
>>> used for structures that are passed to a syscall.  lock/unlock() will be
>>> used internally in these because lock/unlock does address translation.
>>> lock/unlock() are still needed and are independent.  __{get,put}_user()
>>> will operate internally in these functions on structure data members
>>> where lock/unlock() access_ok() have already been called.
>> I believed I was clear : once you keep lock/unlock, there is no point in
>> modifying the code to use put_user/get_user and copy[to,from]_user.
> 
> without lock/unlock how do you propose that target/host address
> translation be performed?  Are you suggesting a g2h() inside of
> copy_{to,from}_user()?

Yes.

Keep in mind that g2h() is only the simple case in case the target
address space is directly addressable. I don't want that the API makes
this supposition, so in the general case copy_[to,from]user are the only
method you have to exchange data with the user space.

>> So either you keep the code as it is and extend lock and unlock to
>> return an error code or you suppress all lock/unlock to use a Linux like
>> API (i.e. put_user/get_user , copy[to,from]_user, access_ok,
>> __put_user/__get_user).
> 
> The error code because lock/unlock_user would then call access_ok()?

Of course.

>> So for gettimeofday, if we exclude the fact that the conversion of
>> struct timeval will be factorized, you have either:
>>
>>         {
>>             struct timeval tv;
>>             ret = get_errno(gettimeofday(&tv, NULL));
>>             if (!is_error(ret)) {
>>                  struct target_timeval *target_tv;
>>
>>                  lock_user_struct(target_tv, arg1, 0);
>>                  target_tv->tv_sec = tswapl(tv->tv_sec);
>>                  target_tv->tv_usec = tswapl(tv->tv_usec);
>>                  if (unlock_user_struct(target_tv, arg1, 1)) {
>>                      ret = -TARGET_EFAULT;
>>                      goto fail;
>>                  }
>>             }
>>         }
>>
>> Or
>>
>>         {
>>             struct timeval tv;
>>             ret = get_errno(gettimeofday(&tv, NULL));
>>             if (!is_error(ret)) {
>>                  struct target_timeval target_tv;
>>
>>                  target_tv.tv_sec = tswapl(tv->tv_sec);
>>                  target_tv.tv_usec = tswapl(tv->tv_usec);
>>                  if (copy_to_user(arg1, &target_tv, sizeof(target_tv)) {
>>                      ret = -TARGET_EFAULT;
>>                      goto fail;
>>                  }
>>             }
>>         }
> 
> I don't see where the second one is handling target/host address
> translation.

copy_to_user() does it.

> A problem with both of the above examples is that they use tswapl().
> Without the proper type casting tswapl() doesn't do proper sign
> extension when dealing with 64bit/32bit host/target relationships.  I've
> fixed more than one location where this has resulted in bugs. 

This is an unrelated problem. If tswapl is not sufficient then another
function can be added.

> [...]

Regards,

Fabrice.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]