[PATCH] rust: io: mem: Fix exclusive MMIO region requests

From: Kwanghoon Son

Date: Tue Oct 27 2026 - 22:01:42 EST


C's request_mem_region() reserves MMIO in the global resource tree.
Rust's ExclusiveIoMem reserves it under the device's resource instead,
so the global tree may not see the reservation.

Request the region from iomem_resource, matching request_mem_region()
and the existing release_mem_region() call.

Fixes: 1d0d4b28513b ("rust: io: mem: add a generic iomem abstraction")

Signed-off-by: Kwanghoon Son <asdfkwang@xxxxxxxxx>
---
The bug can be reproduced with QEMU arm64 virt's existing DT node
(CONFIG_FW_CFG_SYSFS=n):

fw-cfg@9020000 {
compatible = "qemu,fw-cfg-mmio";
reg = <0 0x09020000 0 0x18>;
};

A small Rust platform driver matches this node. Its probe maps the
resource and returns the mapping as driver data (excerpt):

let io = pdev.io_request_by_index(0).ok_or(ENODEV)?
.iomap_exclusive()?
.into_devres()?;

Unbind and bind that driver again:

cd /sys/bus/platform/drivers/mmio_repro
echo 9020000.fw-cfg > unbind
echo 9020000.fw-cfg > bind

Before the fix, unbind prints "Trying to free nonexistent resource"
and bind fails with EBUSY. With the fix, 100 cycles pass. This was
repeated in three fresh guests for each kernel.
---
rust/kernel/io/mem.rs | 2 +-
rust/kernel/io/resource.rs | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs
index 32a919099dcda79bc4b795a8a1c5f553c989b9b7..80da665821c036257900c6ea45b9419cb573c187 100644
--- a/rust/kernel/io/mem.rs
+++ b/rust/kernel/io/mem.rs
@@ -196,7 +196,7 @@ fn ioremap(dev: &'a Device<Bound>, resource: &Resource) -> Result<Self> {
let size = resource.size();
let name = resource.name().unwrap_or_default();

- let region = resource
+ let region = Resource::iomem()
.request_region(
start,
size,
diff --git a/rust/kernel/io/resource.rs b/rust/kernel/io/resource.rs
index 758ce62b3cce33c14e1e4c56a793af0e00657aa6..c99a2530186fc56bdc3405adc15d0801b98eae08 100644
--- a/rust/kernel/io/resource.rs
+++ b/rust/kernel/io/resource.rs
@@ -79,6 +79,12 @@ unsafe impl Sync for Region {}
pub struct Resource(Opaque<bindings::resource>);

impl Resource {
+ /// Returns the global I/O memory resource root.
+ pub(crate) fn iomem() -> &'static Self {
+ // SAFETY: iomem_resource is permanent; C serializes resource-tree updates.
+ unsafe { Self::from_raw(&raw mut bindings::iomem_resource) }
+ }
+
/// Creates a reference to a [`Resource`] from a valid pointer.
///
/// # Safety

---
base-commit: 8a36f53fd5ec3eff01f1b637d42cbdc3821d0493
change-id: 20261027-b4-rust-iomem-origin-master-fix-885f1ea244fb

Best regards,
--
Kwanghoon Son <asdfkwang@xxxxxxxxx>