diff --git a/drivers/net/e1000d/src/device.rs b/drivers/net/e1000d/src/device.rs index 0e42d72b2e..840cc3a9fa 100644 --- a/drivers/net/e1000d/src/device.rs +++ b/drivers/net/e1000d/src/device.rs @@ -135,6 +135,11 @@ impl NetworkAdapter for Intel8254x { fn read_packet(&mut self, buf: &mut [u8]) -> Result> { let desc = unsafe { &mut *(self.receive_ring.as_ptr().add(self.receive_index) as *mut Rd) }; + // Acquire fence pairs the device's store to desc.status with our + // load of desc.length; without it the compiler can reorder + // and we read a stale length on weakly-ordered architectures. + self.receive_buffer[self.receive_index].sync_for_cpu(); + if desc.status & RD_DD == RD_DD { desc.status = 0; @@ -143,6 +148,7 @@ impl NetworkAdapter for Intel8254x { let i = cmp::min(buf.len(), data.len()); buf[..i].copy_from_slice(&data[..i]); + self.receive_buffer[self.receive_index].sync_for_device(); unsafe { self.write_reg(RDT, self.receive_index as u32) }; self.receive_index = wrap_ring(self.receive_index, self.receive_ring.len()); @@ -200,6 +206,7 @@ impl NetworkAdapter for Intel8254x { self.transmit_index = wrap_ring(self.transmit_index, self.transmit_ring.len()); self.transmit_ring_free -= 1; + self.transmit_buffer[self.transmit_index].sync_for_device(); unsafe { self.write_reg(TDT, self.transmit_index as u32) }; Ok(i)