Skip to content

Commit bc489dd

Browse files
authored
[vsock] wait for device readiness (#1112)
1 parent fcf37ae commit bc489dd

4 files changed

Lines changed: 193 additions & 23 deletions

File tree

lib/propolis/src/hw/virtio/vsock.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,21 @@ impl VsockVq {
110110
/// Returns `Some(RxPermit)` if a descriptor chain is available,
111111
/// `None` if the rx queue is full.
112112
pub fn try_rx_permit(&mut self) -> Option<RxPermit<'_>> {
113+
let vq = self.queues.get(VSOCK_RX_QUEUE as usize)?;
114+
// See propolis#1110 & propolis#1115
115+
// If propolis-server has started the vsock device but a different
116+
// device has encountered an error at startup there's a good chance
117+
// we attempt to access guest memory and panic. A way of preventing
118+
// us from doing that is to first check if the virtqueue is alive. A
119+
// virtqueue only becomes alive once a guest vCPU has ran.
120+
if !vq.is_alive() {
121+
return None;
122+
}
123+
113124
// Reuse cached chain or pop a new one
114125
if self.rx_chain.is_none() {
115126
// TODO: cannot access memory?
116127
let mem = self.acc_mem.access().expect("mem access for write");
117-
let vq = self.queues.get(VSOCK_RX_QUEUE as usize)?;
118128
let mut chain = Chain::with_capacity(10);
119129
if let Some(_) = vq.pop_avail(&mut chain, &mem) {
120130
self.rx_chain = Some(chain);
@@ -201,7 +211,7 @@ impl PciVirtioSock {
201211
);
202212
let port_mappings = port_mappings.into_iter().collect();
203213

204-
let backend = VsockProxy::new(cid, vvq, log, port_mappings);
214+
let backend = VsockProxy::new(log, cid, vvq, port_mappings);
205215

206216
Arc::new(Self { cid, backend, virtio_state, pci_state })
207217
}
@@ -262,6 +272,10 @@ impl Lifecycle for PciVirtioSock {
262272
fn type_name(&self) -> &'static str {
263273
"pci-virtio-socket"
264274
}
275+
fn start(&self) -> Result<(), anyhow::Error> {
276+
self.backend.start();
277+
Ok(())
278+
}
265279
fn pause(&self) {
266280
let _ = self.backend.pause();
267281
self.backend.wait_stopped();

0 commit comments

Comments
 (0)