From 1ea06fb7d6559d740d9fbaf59980951e48edbe3d Mon Sep 17 00:00:00 2001 From: eternalcomet Date: Mon, 16 Jun 2025 10:12:12 +0800 Subject: [PATCH] fix[addr_space]: ensure data is copied to kernel address space before convert VA to PA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Underlying driver assumes a linear mapping between virtual address and physical address when converting them, which is only present in kernel address space. So under circumstance related to physical address, we should copy the buffer to kernel space. - `sys_write` will finally call `axfs::dev::Disk::write_one` in dev.rs, which will use the buffer directly. - read from stdin will finally call `console_read_bytes`, which will also use the buffer directly. --- modules/axfs/src/dev.rs | 6 +++++- modules/axhal/src/mem.rs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/axfs/src/dev.rs b/modules/axfs/src/dev.rs index f7832db623..17871f42fe 100644 --- a/modules/axfs/src/dev.rs +++ b/modules/axfs/src/dev.rs @@ -70,7 +70,11 @@ impl Disk { pub fn write_one(&mut self, buf: &[u8]) -> DevResult { let write_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE { // whole block - self.dev.write_block(self.block_id, &buf[0..BLOCK_SIZE])?; + // copy data to kernel address space + // Because underlying driver assumes a linear mapping between virtual address and + // physical address when converting them, which is only present in kernel address space. + let data = buf[0..BLOCK_SIZE].to_vec(); + self.dev.write_block(self.block_id, &data)?; self.block_id += 1; BLOCK_SIZE } else { diff --git a/modules/axhal/src/mem.rs b/modules/axhal/src/mem.rs index e4e15747d3..23de880d45 100644 --- a/modules/axhal/src/mem.rs +++ b/modules/axhal/src/mem.rs @@ -54,6 +54,10 @@ pub struct MemRegion { /// `paddr = vaddr - PHYS_VIRT_OFFSET`. #[inline] pub const fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr { + assert!( + vaddr.as_usize() >= PHYS_VIRT_OFFSET, + "Converted address is invalid, check if the virtual address is in kernel space" + ); pa!(vaddr.as_usize() - PHYS_VIRT_OFFSET) }