(
&self,
PvmemcontrolReq {
func_code,
addr,
length,
arg,
}: PvmemcontrolReq,
)
| 542 | } |
| 543 | |
| 544 | fn handle_request( |
| 545 | &self, |
| 546 | PvmemcontrolReq { |
| 547 | func_code, |
| 548 | addr, |
| 549 | length, |
| 550 | arg, |
| 551 | }: PvmemcontrolReq, |
| 552 | ) -> Result<PvmemcontrolResp, Error> { |
| 553 | let (func_code, addr, length, arg) = ( |
| 554 | func_code.to_native(), |
| 555 | addr.to_native(), |
| 556 | length.to_native(), |
| 557 | arg.to_native(), |
| 558 | ); |
| 559 | |
| 560 | let resp_or_err = FunctionCode::try_from(func_code) |
| 561 | .map_err(|_| Error::UnknownFunctionCode(func_code)) |
| 562 | .and_then(|func_code| self.process_request(func_code, addr, length, arg)); |
| 563 | |
| 564 | let resp = match resp_or_err { |
| 565 | Ok(resp) => resp, |
| 566 | Err(e) => match e { |
| 567 | Error::InvalidArgument(arg) => PvmemcontrolResp { |
| 568 | ret_errno: (libc::EINVAL as u32).into(), |
| 569 | ret_code: (arg as u32).into(), |
| 570 | ..Default::default() |
| 571 | }, |
| 572 | Error::LibcFail(err) => PvmemcontrolResp { |
| 573 | ret_errno: (err.raw_os_error().unwrap_or(libc::EFAULT) as u32).into(), |
| 574 | ret_code: 0u32.into(), |
| 575 | ..Default::default() |
| 576 | }, |
| 577 | Error::UnknownFunctionCode(func_code) => PvmemcontrolResp { |
| 578 | ret_errno: (libc::EOPNOTSUPP as u32).into(), |
| 579 | ret_code: (func_code as u32).into(), |
| 580 | ..Default::default() |
| 581 | }, |
| 582 | Error::GuestMemory(err) => { |
| 583 | warn!("{err}"); |
| 584 | PvmemcontrolResp { |
| 585 | ret_errno: (libc::EINVAL as u32).into(), |
| 586 | ret_code: (func_code as u32).into(), |
| 587 | ..Default::default() |
| 588 | } |
| 589 | } |
| 590 | // device error, stop responding |
| 591 | other => return Err(other), |
| 592 | }, |
| 593 | }; |
| 594 | Ok(resp) |
| 595 | } |
| 596 | |
| 597 | fn handle_pvmemcontrol_request(&self, guest_addr: GuestAddress) { |
| 598 | let request: PvmemcontrolReq = if let Ok(x) = self.mem.memory().read_obj(guest_addr) { |
no test coverage detected