diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index 2a507b9bb8318025..07f05a31261c1b25 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -121,12 +121,6 @@ int V4L2Camera::configure(StreamConfiguration *streamConfigOut,
 	return 0;
 }
 
-void *V4L2Camera::mmap(unsigned int index)
-{
-	Stream *stream = *camera_->streams().begin();
-	return stream->buffers()[index].planes()[0].mem();
-}
-
 int V4L2Camera::allocBuffers(unsigned int count)
 {
 	int ret = camera_->allocateBuffers();
@@ -138,6 +132,12 @@ void V4L2Camera::freeBuffers()
 	camera_->freeBuffers();
 }
 
+FileDescriptor V4L2Camera::getBufferFd(unsigned int index)
+{
+	Stream *stream = *camera_->streams().begin();
+	return FileDescriptor(stream->buffers()[index].planes()[0].dmabuf());
+}
+
 int V4L2Camera::streamOn()
 {
 	if (isRunning_)
diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
index 81f7908e5e8a6beb..f760316c854fba2f 100644
--- a/src/v4l2/v4l2_camera.h
+++ b/src/v4l2/v4l2_camera.h
@@ -14,6 +14,7 @@
 
 #include <libcamera/buffer.h>
 #include <libcamera/camera.h>
+#include <libcamera/file_descriptor.h>
 
 #include "semaphore.h"
 
@@ -53,14 +54,14 @@ public:
 	void getStreamConfig(StreamConfiguration *streamConfig);
 	std::vector<V4L2FrameMetadata> completedBuffers();
 
-	void *mmap(unsigned int index);
-
 	int configure(StreamConfiguration *streamConfigOut,
 		      const Size &size, PixelFormat pixelformat,
 		      unsigned int bufferCount);
 
 	int allocBuffers(unsigned int count);
 	void freeBuffers();
+	FileDescriptor getBufferFd(unsigned int index);
+
 	int streamOn();
 	int streamOff();
 
diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index 52f8468cdaa06a7a..b4a9e2107c0f9f28 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -75,7 +75,8 @@ void V4L2CameraProxy::close()
 	vcam_->invokeMethod(&V4L2Camera::close, ConnectionTypeBlocking);
 }
 
-void *V4L2CameraProxy::mmap(size_t length, int prot, int flags, off_t offset)
+void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags,
+			    off_t offset)
 {
 	LOG(V4L2Compat, Debug) << "Servicing mmap";
 
@@ -91,13 +92,22 @@ void *V4L2CameraProxy::mmap(size_t length, int prot, int flags, off_t offset)
 		return MAP_FAILED;
 	}
 
-	void *val = vcam_->invokeMethod(&V4L2Camera::mmap,
-					ConnectionTypeBlocking, index);
+	FileDescriptor fd = vcam_->invokeMethod(&V4L2Camera::getBufferFd,
+						ConnectionTypeBlocking, index);
+	if (!fd.isValid()) {
+		errno = EINVAL;
+		return MAP_FAILED;
+	}
+
+	void *map = V4L2CompatManager::instance()->fops().mmap(addr, length, prot,
+							       flags, fd.fd(), 0);
+	if (map == MAP_FAILED)
+		return map;
 
 	buffers_[index].flags |= V4L2_BUF_FLAG_MAPPED;
-	mmaps_[val] = index;
+	mmaps_[map] = index;
 
-	return val;
+	return map;
 }
 
 int V4L2CameraProxy::munmap(void *addr, size_t length)
@@ -110,6 +120,10 @@ int V4L2CameraProxy::munmap(void *addr, size_t length)
 		return -1;
 	}
 
+	if (V4L2CompatManager::instance()->fops().munmap(addr, length))
+		LOG(V4L2Compat, Error) << "Unmapping " << addr
+				       << " with length " << length;
+
 	buffers_[iter->second].flags &= ~V4L2_BUF_FLAG_MAPPED;
 	mmaps_.erase(iter);
 
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index b59d19d707590d88..c8e61adf80f1b93b 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -28,7 +28,7 @@ public:
 	int open(bool nonBlocking);
 	void dup();
 	void close();
-	void *mmap(size_t length, int prot, int flags, off_t offset);
+	void *mmap(void *addr, size_t length, int prot, int flags, off_t offset);
 	int munmap(void *addr, size_t length);
 
 	int ioctl(unsigned long request, void *arg);
diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp
index fe453445a9fb2cdd..f5a7b2ac4229d5d5 100644
--- a/src/v4l2/v4l2_compat_manager.cpp
+++ b/src/v4l2/v4l2_compat_manager.cpp
@@ -223,7 +223,7 @@ void *V4L2CompatManager::mmap(void *addr, size_t length, int prot, int flags,
 	if (!proxy)
 		return fops_.mmap(addr, length, prot, flags, fd, offset);
 
-	void *map = proxy->mmap(length, prot, flags, offset);
+	void *map = proxy->mmap(addr, length, prot, flags, offset);
 	if (map == MAP_FAILED)
 		return map;
 
