Remove critical sections from PeripheralMutex interrupt handler by checking the interrupt's priority on startup.

Since `PeripheralMutex` is the only way to safely maintain state across interrupts, and it no longer allows setting the interrupt's priority, the priority changing isn't a concern.

This also prevents other causes of UB due to the interrupt being exposed during `with`, and allowing enabling the interrupt and setting its context to a bogus pointer.
This commit is contained in:
Liam Murphy
2021-07-27 17:28:52 +10:00
parent 1b7ad7080e
commit 079526559f
5 changed files with 187 additions and 48 deletions

View File

@ -161,7 +161,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
let mut mutex = unsafe { Pin::new_unchecked(&mut this.state) };
mutex.as_mut().register_interrupt();
mutex.with(|s, _| {
mutex.with(|s| {
s.desc_ring.init();
fence(Ordering::SeqCst);
@ -237,7 +237,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Pin<&mut Ethernet<
let this = unsafe { self.as_mut().get_unchecked_mut() };
let mutex = unsafe { Pin::new_unchecked(&mut this.state) };
mutex.with(|s, _| s.desc_ring.tx.available())
mutex.with(|s| s.desc_ring.tx.available())
}
fn transmit(&mut self, pkt: PacketBuf) {
@ -245,7 +245,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Pin<&mut Ethernet<
let this = unsafe { self.as_mut().get_unchecked_mut() };
let mutex = unsafe { Pin::new_unchecked(&mut this.state) };
mutex.with(|s, _| unwrap!(s.desc_ring.tx.transmit(pkt)));
mutex.with(|s| unwrap!(s.desc_ring.tx.transmit(pkt)));
}
fn receive(&mut self) -> Option<PacketBuf> {
@ -253,7 +253,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Pin<&mut Ethernet<
let this = unsafe { self.as_mut().get_unchecked_mut() };
let mutex = unsafe { Pin::new_unchecked(&mut this.state) };
mutex.with(|s, _| s.desc_ring.rx.pop_packet())
mutex.with(|s| s.desc_ring.rx.pop_packet())
}
fn register_waker(&mut self, waker: &Waker) {