On Tuesday 10 November 2015 23:07:42 Bamvor Jian Zhang wrote:
The y2038 issue for ppdev is changes of timeval in the ioctl (PPSETTIME and PPGETTIME). The size of struct timeval changes from 8bytes to 16bytes due to the changes of time_t. It lead to the changes of the command of ioctl, e.g. for PPGETTIME, We have:
on 32-bit (old): 0x80087095 on 32-bit (new): 0x80107095 on 64-bit : 0x80107095
This patch define these two ioctl commands to support the y2038 safe and y2038 unsafe application at the same time.
Signed-off-by: Bamvor Jian Zhang bamvor.zhangjian@linaro.org
Looks all correct to me, nice work!
A few minor comments on coding style:
to_jiffies = ROUND_UP(time32[1], 1000000/HZ);
This could be simplified using usecs_to_jiffies.
/*
* Avoid 64bit division on 32bit platform:
* timeval here is an offset of the real time. It should be
* safe to use 32bit time.
*/
if (!IS_ENABLED(CONFIG_64BIT))
to_jiffies = (long)ROUND_UP((s32)time64[1], 1000000/HZ);
else
to_jiffies = (long)ROUND_UP(time64[1], 1000000/HZ);
Here too, and you can also avoid the condition that way.
to_jiffies += (long)(time64[0] * (long)HZ);
if (to_jiffies <= 0)
return -EINVAL;
pp->pdev->timeout = to_jiffies;
return 0;
As this part is duplicated, you could perhaps move it into a separate function that takes the pdev, seconds and microseconds as arguments.
- case PPGETTIME_unsafe: to_jiffies = pp->pdev->timeout;
memset(&par_timeout, 0, sizeof(par_timeout));
par_timeout.tv_sec = to_jiffies / HZ;
par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
memset(time32, 0, sizeof(time32));
time32[0] = (s32)(to_jiffies / HZ);
time32[1] = (s32)((to_jiffies % (long)HZ) * (1000000/HZ));
if (copy_to_user(time32, argp, sizeof(time32))) return -EFAULT;
The memset isn't really required here. Again, jiffies_to_usecs or possibly jiffies_to_timespec64 might make this more understandable.
Arnd