From 6cedb8b377bba6520508399b74754b9a0ca06edf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 29 May 2018 16:16:06 +0200 Subject: drm/msm: avoid using 'timespec' The timespec structure and associated interfaces are deprecated and will be removed in the future because of the y2038 overflow. The use of ktime_to_timespec() in timeout_to_jiffies() does not suffer from that overflow, but is easy to avoid by just converting the ktime_t into jiffies directly. Reviewed-by: Jordan Crouse Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/msm/msm_drv.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 71547e756e29..740bf7c70d8f 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -454,8 +454,7 @@ static inline unsigned long timeout_to_jiffies(const ktime_t *timeout) remaining_jiffies = 0; } else { ktime_t rem = ktime_sub(*timeout, now); - struct timespec ts = ktime_to_timespec(rem); - remaining_jiffies = timespec_to_jiffies(&ts); + remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ); } return remaining_jiffies; -- cgit v1.2.3 From 245595e83fbedda9e107eb0b37cec0ad07733778 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 11 Nov 2019 17:20:04 +0100 Subject: drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC Most kernel interfaces that take a timespec require normalized representation with tv_nsec between 0 and NSEC_PER_SEC. Passing values larger than 0x100000000ull further behaves differently on 32-bit and 64-bit kernels, and can cause the latter to spend a long time counting seconds in timespec64_sub()/set_normalized_timespec64(). Reject those large values at the user interface to enforce sane and portable behavior. Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 1f9c01be40d7..95d72dc00280 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -297,6 +297,9 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, if (args->op & ~(ETNA_PREP_READ | ETNA_PREP_WRITE | ETNA_PREP_NOSYNC)) return -EINVAL; + if (args->timeout.tv_nsec > NSEC_PER_SEC) + return -EINVAL; + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -360,6 +363,9 @@ static int etnaviv_ioctl_wait_fence(struct drm_device *dev, void *data, if (args->flags & ~(ETNA_WAIT_NONBLOCK)) return -EINVAL; + if (args->timeout.tv_nsec > NSEC_PER_SEC) + return -EINVAL; + if (args->pipe >= ETNA_MAX_PIPES) return -EINVAL; @@ -411,6 +417,9 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data, if (args->flags & ~(ETNA_WAIT_NONBLOCK)) return -EINVAL; + if (args->timeout.tv_nsec > NSEC_PER_SEC) + return -EINVAL; + if (args->pipe >= ETNA_MAX_PIPES) return -EINVAL; -- cgit v1.2.3 From 38c4a4cf02513a7904b9db0a668b7e50145ea696 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 6 Nov 2017 13:28:52 +0100 Subject: drm/etnaviv: avoid deprecated timespec struct timespec is being removed from the kernel because it often leads to code that is not y2038-safe. In the etnaviv driver, monotonic timestamps are used, which do not suffer from overflow, but the usage of timespec here gets in the way of removing the interface completely. Pass down the user-supplied 64-bit value here rather than converting it to an intermediate timespec to avoid the conversion. The conversion is transparent for all regular CLOCK_MONOTONIC values, but is a small change in behavior for excessively large values: the existing code would treat e.g. tv_sec=0x100000000 the same as tv_sec=0 and not block, while the new code it would block for up to 2^31 seconds. The new behavior is more logical here, but if it causes problems, the truncation can be put back. Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 11 +++-------- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 11 ++++++----- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 4 ++-- drivers/gpu/drm/etnaviv/etnaviv_gem.h | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 5 +++-- drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 5 +++-- 6 files changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 95d72dc00280..3eb0f9223bea 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -282,11 +282,6 @@ static int etnaviv_ioctl_gem_new(struct drm_device *dev, void *data, args->flags, &args->handle); } -#define TS(t) ((struct timespec){ \ - .tv_sec = (t).tv_sec, \ - .tv_nsec = (t).tv_nsec \ -}) - static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, struct drm_file *file) { @@ -304,7 +299,7 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, if (!obj) return -ENOENT; - ret = etnaviv_gem_cpu_prep(obj, args->op, &TS(args->timeout)); + ret = etnaviv_gem_cpu_prep(obj, args->op, &args->timeout); drm_gem_object_put_unlocked(obj); @@ -357,7 +352,7 @@ static int etnaviv_ioctl_wait_fence(struct drm_device *dev, void *data, { struct drm_etnaviv_wait_fence *args = data; struct etnaviv_drm_private *priv = dev->dev_private; - struct timespec *timeout = &TS(args->timeout); + struct drm_etnaviv_timespec *timeout = &args->timeout; struct etnaviv_gpu *gpu; if (args->flags & ~(ETNA_WAIT_NONBLOCK)) @@ -409,7 +404,7 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data, { struct etnaviv_drm_private *priv = dev->dev_private; struct drm_etnaviv_gem_wait *args = data; - struct timespec *timeout = &TS(args->timeout); + struct drm_etnaviv_timespec *timeout = &args->timeout; struct drm_gem_object *obj; struct etnaviv_gpu *gpu; int ret; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 32cfa5a48d42..efc656efeb0f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -61,7 +61,7 @@ int etnaviv_gem_prime_pin(struct drm_gem_object *obj); void etnaviv_gem_prime_unpin(struct drm_gem_object *obj); void *etnaviv_gem_vmap(struct drm_gem_object *obj); int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op, - struct timespec *timeout); + struct drm_etnaviv_timespec *timeout); int etnaviv_gem_cpu_fini(struct drm_gem_object *obj); void etnaviv_gem_free_object(struct drm_gem_object *obj); int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, @@ -107,11 +107,12 @@ static inline size_t size_vstruct(size_t nelem, size_t elem_size, size_t base) * between the specified timeout and the current CLOCK_MONOTONIC time. */ static inline unsigned long etnaviv_timeout_to_jiffies( - const struct timespec *timeout) + const struct drm_etnaviv_timespec *timeout) { - struct timespec64 ts, to; - - to = timespec_to_timespec64(*timeout); + struct timespec64 ts, to = { + .tv_sec = timeout->tv_sec, + .tv_nsec = timeout->tv_nsec, + }; ktime_get_ts64(&ts); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index cb1faaac380a..6adea180d629 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -373,7 +373,7 @@ static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) } int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op, - struct timespec *timeout) + struct drm_etnaviv_timespec *timeout) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); struct drm_device *dev = obj->dev; @@ -431,7 +431,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj) } int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj, - struct timespec *timeout) + struct drm_etnaviv_timespec *timeout) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h index d6270acce619..6b68fe16041b 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h @@ -112,7 +112,7 @@ struct etnaviv_gem_submit { void etnaviv_submit_put(struct etnaviv_gem_submit * submit); int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj, - struct timespec *timeout); + struct drm_etnaviv_timespec *timeout); int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags, const struct etnaviv_gem_ops *ops, struct etnaviv_gem_object **res); void etnaviv_gem_obj_add(struct drm_device *dev, struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index d47d1a8e0219..799ec20b267d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1132,7 +1132,7 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event) * Cmdstream submission/retirement: */ int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, - u32 id, struct timespec *timeout) + u32 id, struct drm_etnaviv_timespec *timeout) { struct dma_fence *fence; int ret; @@ -1179,7 +1179,8 @@ int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, * that lock in this function while waiting. */ int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu, - struct etnaviv_gem_object *etnaviv_obj, struct timespec *timeout) + struct etnaviv_gem_object *etnaviv_obj, + struct drm_etnaviv_timespec *timeout) { unsigned long remaining; long ret; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 8f9bd4edc96a..97bb48042b4d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -169,9 +169,10 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m); void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu); void etnaviv_gpu_retire(struct etnaviv_gpu *gpu); int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, - u32 fence, struct timespec *timeout); + u32 fence, struct drm_etnaviv_timespec *timeout); int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu, - struct etnaviv_gem_object *etnaviv_obj, struct timespec *timeout); + struct etnaviv_gem_object *etnaviv_obj, + struct drm_etnaviv_timespec *timeout); struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit); int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu); void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu); -- cgit v1.2.3 From c4e71212a245017d2ab05f322f7722f0b87a55da Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Jan 2020 14:01:52 +0100 Subject: Revert "drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 245595e83fbedda9e107eb0b37cec0ad07733778. Guido Günther reported issues with this patch that broke existing user space. Let's revert it for now and fix it properly later on. Link: https://patchwork.kernel.org/patch/11291089/ https://lore.kernel.org/lkml/20200121114553.2667556-1-arnd@arndb.de/ Cc: Guido Günther Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 3eb0f9223bea..ac26c084f30d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -292,9 +292,6 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, if (args->op & ~(ETNA_PREP_READ | ETNA_PREP_WRITE | ETNA_PREP_NOSYNC)) return -EINVAL; - if (args->timeout.tv_nsec > NSEC_PER_SEC) - return -EINVAL; - obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -358,9 +355,6 @@ static int etnaviv_ioctl_wait_fence(struct drm_device *dev, void *data, if (args->flags & ~(ETNA_WAIT_NONBLOCK)) return -EINVAL; - if (args->timeout.tv_nsec > NSEC_PER_SEC) - return -EINVAL; - if (args->pipe >= ETNA_MAX_PIPES) return -EINVAL; @@ -412,9 +406,6 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data, if (args->flags & ~(ETNA_WAIT_NONBLOCK)) return -EINVAL; - if (args->timeout.tv_nsec > NSEC_PER_SEC) - return -EINVAL; - if (args->pipe >= ETNA_MAX_PIPES) return -EINVAL; -- cgit v1.2.3