diff --git a/include/libcamera/ipa/vimc.mojom b/include/libcamera/ipa/vimc.mojom
index ee66353d..8cb240d3 100644
--- a/include/libcamera/ipa/vimc.mojom
+++ b/include/libcamera/ipa/vimc.mojom
@@ -26,6 +26,9 @@ interface IPAVimcInterface {
 
 	start() => (int32 ret);
 	stop();
+
+	mapBuffers(array<libcamera.IPABuffer> buffers);
+	unmapBuffers(array<uint32> ids);
 };
 
 interface IPAVimcEventInterface {
diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
index fb134084..7d9d22d0 100644
--- a/src/ipa/vimc/vimc.cpp
+++ b/src/ipa/vimc/vimc.cpp
@@ -19,6 +19,8 @@
 #include <libcamera/ipa/ipa_interface.h>
 #include <libcamera/ipa/ipa_module_info.h>
 
+#include "libcamera/internal/mapped_framebuffer.h"
+
 namespace libcamera {
 
 LOG_DEFINE_CATEGORY(IPAVimc)
@@ -38,11 +40,15 @@ public:
 		      const std::map<unsigned int, IPAStream> &streamConfig,
 		      const std::map<unsigned int, ControlInfoMap> &entityControls) override;
 
+	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
+	void unmapBuffers(const std::vector<unsigned int> &ids) override;
+
 private:
 	void initTrace();
 	void trace(enum ipa::vimc::IPAOperationCode operation);
 
 	int fd_;
+	std::map<unsigned int, MappedFrameBuffer> buffers_;
 };
 
 IPAVimc::IPAVimc()
@@ -99,6 +105,27 @@ int IPAVimc::configure([[maybe_unused]] const IPACameraSensorInfo &sensorInfo,
 	return 0;
 }
 
+void IPAVimc::mapBuffers(const std::vector<IPABuffer> &buffers)
+{
+	for (const IPABuffer &buffer : buffers) {
+		const FrameBuffer fb(buffer.planes);
+		buffers_.emplace(std::piecewise_construct,
+				 std::forward_as_tuple(buffer.id),
+				 std::forward_as_tuple(&fb, MappedFrameBuffer::MapFlag::Read));
+	}
+}
+
+void IPAVimc::unmapBuffers(const std::vector<unsigned int> &ids)
+{
+	for (unsigned int id : ids) {
+		auto it = buffers_.find(id);
+		if (it == buffers_.end())
+			continue;
+
+		buffers_.erase(it);
+	}
+}
+
 void IPAVimc::initTrace()
 {
 	struct stat fifoStat;
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 2dfa1418..b08325c2 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -334,6 +334,15 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] const ControlLis
 	if (ret < 0)
 		return ret;
 
+	/* Map the mock IPA buffers to VIMC IPA to exercise IPC code paths */
+	unsigned int ipaBufferId = 1;
+	std::vector<IPABuffer> ipaBuffers;
+	for (auto [i, buffer] : utils::enumerate(data->mockIPABufs_)) {
+		buffer->setCookie(ipaBufferId++);
+		ipaBuffers.emplace_back(buffer->cookie(), buffer->planes());
+	}
+	data->ipa_->mapBuffers(ipaBuffers);
+
 	ret = data->ipa_->start();
 	if (ret) {
 		data->video_->releaseBuffers();
@@ -354,7 +363,13 @@ void PipelineHandlerVimc::stop(Camera *camera)
 {
 	VimcCameraData *data = cameraData(camera);
 	data->video_->streamOff();
+
+	std::vector<unsigned int> ids;
+	for (const std::unique_ptr<FrameBuffer> &buffer : data->mockIPABufs_)
+		ids.push_back(buffer->cookie());
+	data->ipa_->unmapBuffers(ids);
 	data->ipa_->stop();
+
 	data->video_->releaseBuffers();
 }
 
