Ver Fonte

Copy data back and forth to new buffer in fake HAL share. (#97)

This helps ensure in tests that drivers aren't sharing with the wrong
direction or forgetting to unshare.
Andrew Walbran há 1 ano atrás
pai
commit
9145a6c85e
2 ficheiros alterados com 41 adições e 6 exclusões
  1. 3 0
      Cargo.toml
  2. 38 6
      src/hal/fake.rs

+ 3 - 0
Cargo.toml

@@ -22,3 +22,6 @@ zerocopy = "0.6.1"
 [features]
 default = ["alloc"]
 alloc = ["zerocopy/alloc"]
+
+[dev-dependencies]
+zerocopy = { version = "0.6.1", features = ["alloc"] }

+ 38 - 6
src/hal/fake.rs

@@ -4,7 +4,11 @@
 
 use crate::{BufferDirection, Hal, PhysAddr, PAGE_SIZE};
 use alloc::alloc::{alloc_zeroed, dealloc, handle_alloc_error};
-use core::{alloc::Layout, ptr::NonNull};
+use core::{
+    alloc::Layout,
+    ptr::{self, NonNull},
+};
+use zerocopy::FromBytes;
 
 #[derive(Debug)]
 pub struct FakeHal;
@@ -38,18 +42,46 @@ unsafe impl Hal for FakeHal {
         NonNull::new(paddr as _).unwrap()
     }
 
-    unsafe fn share(buffer: NonNull<[u8]>, _direction: BufferDirection) -> PhysAddr {
-        let vaddr = buffer.as_ptr() as *mut u8 as usize;
+    unsafe fn share(buffer: NonNull<[u8]>, direction: BufferDirection) -> PhysAddr {
+        // To ensure that the driver is handling and unsharing buffers properly, allocate a new
+        // buffer and copy to it if appropriate.
+        let mut shared_buffer = u8::new_box_slice_zeroed(buffer.len());
+        if let BufferDirection::DriverToDevice | BufferDirection::Both = direction {
+            unsafe {
+                buffer
+                    .as_ptr()
+                    .cast::<u8>()
+                    .copy_to(shared_buffer.as_mut_ptr(), buffer.len());
+            }
+        }
+        let vaddr = Box::into_raw(shared_buffer) as *mut u8 as usize;
         // Nothing to do, as the host already has access to all memory.
         virt_to_phys(vaddr)
     }
 
-    unsafe fn unshare(_paddr: PhysAddr, _buffer: NonNull<[u8]>, _direction: BufferDirection) {
-        // Nothing to do, as the host already has access to all memory and we didn't copy the buffer
-        // anywhere else.
+    unsafe fn unshare(paddr: PhysAddr, buffer: NonNull<[u8]>, direction: BufferDirection) {
+        let vaddr = phys_to_virt(paddr);
+        let shared_buffer = unsafe {
+            Box::from_raw(ptr::slice_from_raw_parts_mut(
+                vaddr as *mut u8,
+                buffer.len(),
+            ))
+        };
+        if let BufferDirection::DeviceToDriver | BufferDirection::Both = direction {
+            unsafe {
+                buffer
+                    .as_ptr()
+                    .cast::<u8>()
+                    .copy_from(shared_buffer.as_ptr(), buffer.len());
+            }
+        }
     }
 }
 
 fn virt_to_phys(vaddr: usize) -> PhysAddr {
     vaddr
 }
+
+fn phys_to_virt(paddr: PhysAddr) -> usize {
+    paddr
+}