(
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap<AtomicBitmap>>,
mut state: PercpuInitState,
PvmemcontrolTransportRegister { buf_phys_addr }: PvmemcontrolTransportRegister,
| 284 | |
| 285 | impl PvmemcontrolDevice { |
| 286 | fn register_percpu_buf( |
| 287 | guest_memory: &GuestMemoryAtomic<GuestMemoryMmap<AtomicBitmap>>, |
| 288 | mut state: PercpuInitState, |
| 289 | PvmemcontrolTransportRegister { buf_phys_addr }: PvmemcontrolTransportRegister, |
| 290 | ) -> Self { |
| 291 | // access to this address is checked |
| 292 | let buf_phys_addr = GuestAddress(buf_phys_addr.into()); |
| 293 | if !guest_memory.memory().check_range( |
| 294 | buf_phys_addr, |
| 295 | std::mem::size_of::<PvmemcontrolResp>().max(std::mem::size_of::<PvmemcontrolReq>()), |
| 296 | ) { |
| 297 | warn!("guest sent invalid phys addr {:#x}", buf_phys_addr.0); |
| 298 | return PvmemcontrolDevice::new( |
| 299 | PvmemcontrolTransport::error(), |
| 300 | PvmemcontrolState::Broken, |
| 301 | ); |
| 302 | } |
| 303 | |
| 304 | let conn = { |
| 305 | // find an available port+byte combination, and fail if full |
| 306 | let mut next_conn = state.next_conn; |
| 307 | while state.port_buf_map.contains_key(&next_conn) { |
| 308 | next_conn = next_conn.next(); |
| 309 | if next_conn == state.next_conn { |
| 310 | warn!("connections exhausted"); |
| 311 | return PvmemcontrolDevice::new( |
| 312 | PvmemcontrolTransport::error(), |
| 313 | PvmemcontrolState::Broken, |
| 314 | ); |
| 315 | } |
| 316 | } |
| 317 | next_conn |
| 318 | }; |
| 319 | state.next_conn = conn.next(); |
| 320 | state.port_buf_map.insert(conn, buf_phys_addr); |
| 321 | |
| 322 | // inform guest of the connection |
| 323 | let response = PvmemcontrolTransport::register_response(conn.command); |
| 324 | |
| 325 | PvmemcontrolDevice::new(response, PvmemcontrolState::PercpuInit(state)) |
| 326 | } |
| 327 | |
| 328 | fn reset() -> Self { |
| 329 | PvmemcontrolDevice::new( |
nothing calls this directly
no test coverage detected