Hi Danilo, > > We can easily build abstractions that ensure that the address a driver is trying > to access is mapped properly, such that you can't have accidential out-of-bound > accesses. > > Those can be implemented by the corresponding subsystem / bus that the resource > originates from. > > In fact, we already have abstractions for that on the way, a generic I/O > abstraction [1] as base implementation and a specific abstraction for PCI bars > [2]. > > Of course, if the MMIO region comes from let's say the device tree, we still > have to assume that the information in the DT is correct, but the driver does > not need unsafe code for this. > > [1] https://lore.kernel.org/rust-for-linux/20240618234025.15036-8-dakr@xxxxxxxxxx/ > [2] https://lore.kernel.org/rust-for-linux/20240618234025.15036-11-dakr@xxxxxxxxxx/ > Thanks for pointing that out. So from this: +impl<const SIZE: usize> Io<SIZE> { + /// + /// + /// # Safety + /// + /// Callers must ensure that `addr` is the start of a valid I/O mapped memory region of size + /// `maxsize`. + pub unsafe fn new(addr: usize, maxsize: usize) -> Result<Self> { + if maxsize < SIZE { + return Err(EINVAL); + } + + Ok(Self { addr, maxsize }) + } It looks like one can do this: let io = unsafe { Io::new(<some address>, <some size>)? }; let value = io.readb(<some offset>)?; Where <some address> has already been mapped for <some size> at an earlier point? That’s fine, as I said, if an abstraction makes sense, I have nothing against it. My point is more that we shouldn’t enact a blanket ban on 'unsafe' in drivers because corner cases do exist. But it’s good to know that this particular example I gave does not apply. >> >> If a driver is written partially in Rust, and partially in C, and it gets a >> pointer to some kcalloc’d memory in C, should It be forbidden to use unsafe >> in order to build a slice from that pointer? How can you possibly design a >> general abstraction for something that is, essentially, a driver-internal API? > > That sounds perfectly valid to me. > — Daniel