[v2,1/2] v4l2: v4l2_compat: Handle __ioctl_time64
diff mbox series

Message ID 20261023041954.913108-1-ragaprasanth@gmail.com
State Superseded
Headers show
Series
  • [v2,1/2] v4l2: v4l2_compat: Handle __ioctl_time64
Related show

Commit Message

Prasanth Ramesh Oct. 23, 2026, 4:19 a.m. UTC
From: Paul Elder <paul.elder@ideasonboard.com>

On 32-bit systems, ioctl is redirected to __ioctl_time64, so the latter
needs to be intercepted and handled as well. Add support for this.

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/290
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Prasanth R <ragaprasanth@gmail.com>
Signed-off-by: Prasanth R <ragaprasanth@gmail.com>
---
 src/v4l2/v4l2_compat.cpp         | 21 +++++++++++++++++++++
 src/v4l2/v4l2_compat_manager.cpp | 10 ++++++++++
 src/v4l2/v4l2_compat_manager.h   |  2 ++
 3 files changed, 33 insertions(+)

Comments

Laurent Pinchart Oct. 27, 2026, 10:02 p.m. UTC | #1
On Fri, Oct 23, 2026 at 01:19:53PM +0900, Prasanth R wrote:
> From: Paul Elder <paul.elder@ideasonboard.com>
> 
> On 32-bit systems, ioctl is redirected to __ioctl_time64, so the latter
> needs to be intercepted and handled as well. Add support for this.
> 
> Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/290

I think we need patch 2/2 to close the issue. Let's move the tag to the
next patch, and update the commit message to indicate this isn't a full
solution.


On 32-bit systems with 64-bit time_t (except x32), ioctl is redirected
to __ioctl_time64. The v4l2-compat layer only intercepts the former, we
need to intercept and handle the latter as well. In order to correctly
support those systems, translation between 32-bit and 64-bit ioctl
structures also need to be implemented. This will be done in a
subsequent patch.

> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> Tested-by: Prasanth R <ragaprasanth@gmail.com>
> Signed-off-by: Prasanth R <ragaprasanth@gmail.com>
> ---
>  src/v4l2/v4l2_compat.cpp         | 21 +++++++++++++++++++++
>  src/v4l2/v4l2_compat_manager.cpp | 10 ++++++++++
>  src/v4l2/v4l2_compat_manager.h   |  2 ++
>  3 files changed, 33 insertions(+)
> 
> diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp
> index ff833f57..10421cef 100644
> --- a/src/v4l2/v4l2_compat.cpp
> +++ b/src/v4l2/v4l2_compat.cpp
> @@ -165,4 +165,25 @@ LIBCAMERA_PUBLIC int ioctl(int fd, unsigned long request, ...)
>  	return V4L2CompatManager::instance()->ioctl(fd, request, arg);
>  }
>  
> +/*
> + * __USE_TIME64_REDIRECTS redirects ioctl to __ioctl_time64. Disable the
> + * -Wmissing-declarations warnings, as the functions won't be declared if
> + *  __USE_TIME64_REDIRECTS is not in use.

Extraneous space before __USE_TIME64_REDIRECTS.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> + */
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wmissing-declarations"
> +
> +#if HAVE_POSIX_IOCTL
> +LIBCAMERA_PUBLIC int __ioctl_time64(int fd, int request, ...)
> +#else
> +LIBCAMERA_PUBLIC int __ioctl_time64(int fd, unsigned long request, ...)
> +#endif
> +{
> +	void *arg;
> +	extract_va_arg(void *, arg, request);
> +
> +	return V4L2CompatManager::instance()->ioctl_time64(fd, request, arg);
> +}
> +
> +#pragma GCC diagnostic pop
>  }
> diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp
> index b07f865f..65cce7e1 100644
> --- a/src/v4l2/v4l2_compat_manager.cpp
> +++ b/src/v4l2/v4l2_compat_manager.cpp
> @@ -46,6 +46,7 @@ V4L2CompatManager::V4L2CompatManager()
>  	get_symbol(fops_.dup, "dup");
>  	get_symbol(fops_.close, "close");
>  	get_symbol(fops_.ioctl, "ioctl");
> +	get_symbol(fops_.ioctl_time64, "__ioctl_time64");
>  	get_symbol(fops_.mmap, "mmap64");
>  	get_symbol(fops_.munmap, "munmap");
>  }
> @@ -243,3 +244,12 @@ int V4L2CompatManager::ioctl(int fd, unsigned long request, void *arg)
>  
>  	return file->proxy()->ioctl(file.get(), request, arg);
>  }
> +
> +int V4L2CompatManager::ioctl_time64(int fd, unsigned long request, void *arg)
> +{
> +	std::shared_ptr<V4L2CameraFile> file = cameraFile(fd);
> +	if (!file)
> +		return fops_.ioctl_time64(fd, request, arg);
> +
> +	return file->proxy()->ioctl(file.get(), request, arg);
> +}
> diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h
> index 13673d60..1093505a 100644
> --- a/src/v4l2/v4l2_compat_manager.h
> +++ b/src/v4l2/v4l2_compat_manager.h
> @@ -34,6 +34,7 @@ public:
>  		dup_func_t dup;
>  		close_func_t close;
>  		ioctl_func_t ioctl;
> +		ioctl_func_t ioctl_time64;
>  		mmap_func_t mmap;
>  		munmap_func_t munmap;
>  	};
> @@ -50,6 +51,7 @@ public:
>  		   int fd, off64_t offset);
>  	int munmap(void *addr, size_t length);
>  	int ioctl(int fd, unsigned long request, void *arg);
> +	int ioctl_time64(int fd, unsigned long request, void *arg);
>  
>  private:
>  	V4L2CompatManager();

Patch
diff mbox series

diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp
index ff833f57..10421cef 100644
--- a/src/v4l2/v4l2_compat.cpp
+++ b/src/v4l2/v4l2_compat.cpp
@@ -165,4 +165,25 @@  LIBCAMERA_PUBLIC int ioctl(int fd, unsigned long request, ...)
 	return V4L2CompatManager::instance()->ioctl(fd, request, arg);
 }
 
+/*
+ * __USE_TIME64_REDIRECTS redirects ioctl to __ioctl_time64. Disable the
+ * -Wmissing-declarations warnings, as the functions won't be declared if
+ *  __USE_TIME64_REDIRECTS is not in use.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+
+#if HAVE_POSIX_IOCTL
+LIBCAMERA_PUBLIC int __ioctl_time64(int fd, int request, ...)
+#else
+LIBCAMERA_PUBLIC int __ioctl_time64(int fd, unsigned long request, ...)
+#endif
+{
+	void *arg;
+	extract_va_arg(void *, arg, request);
+
+	return V4L2CompatManager::instance()->ioctl_time64(fd, request, arg);
+}
+
+#pragma GCC diagnostic pop
 }
diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp
index b07f865f..65cce7e1 100644
--- a/src/v4l2/v4l2_compat_manager.cpp
+++ b/src/v4l2/v4l2_compat_manager.cpp
@@ -46,6 +46,7 @@  V4L2CompatManager::V4L2CompatManager()
 	get_symbol(fops_.dup, "dup");
 	get_symbol(fops_.close, "close");
 	get_symbol(fops_.ioctl, "ioctl");
+	get_symbol(fops_.ioctl_time64, "__ioctl_time64");
 	get_symbol(fops_.mmap, "mmap64");
 	get_symbol(fops_.munmap, "munmap");
 }
@@ -243,3 +244,12 @@  int V4L2CompatManager::ioctl(int fd, unsigned long request, void *arg)
 
 	return file->proxy()->ioctl(file.get(), request, arg);
 }
+
+int V4L2CompatManager::ioctl_time64(int fd, unsigned long request, void *arg)
+{
+	std::shared_ptr<V4L2CameraFile> file = cameraFile(fd);
+	if (!file)
+		return fops_.ioctl_time64(fd, request, arg);
+
+	return file->proxy()->ioctl(file.get(), request, arg);
+}
diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h
index 13673d60..1093505a 100644
--- a/src/v4l2/v4l2_compat_manager.h
+++ b/src/v4l2/v4l2_compat_manager.h
@@ -34,6 +34,7 @@  public:
 		dup_func_t dup;
 		close_func_t close;
 		ioctl_func_t ioctl;
+		ioctl_func_t ioctl_time64;
 		mmap_func_t mmap;
 		munmap_func_t munmap;
 	};
@@ -50,6 +51,7 @@  public:
 		   int fd, off64_t offset);
 	int munmap(void *addr, size_t length);
 	int ioctl(int fd, unsigned long request, void *arg);
+	int ioctl_time64(int fd, unsigned long request, void *arg);
 
 private:
 	V4L2CompatManager();