mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +00:00
virtio-devices: iommu: Report request error back to guest
Improve the request parsing/handling code by allowing an error status to be returned back to the guest driver before we return an error internally. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
bbd0667b98
commit
6df8f0bbf3
@ -403,10 +403,14 @@ impl Request {
|
||||
|
||||
// Create the reply
|
||||
let mut reply: Vec<u8> = Vec::new();
|
||||
let mut status = VIRTIO_IOMMU_S_OK;
|
||||
let mut hdr_len = 0;
|
||||
|
||||
let hdr_len = match req_head.type_ {
|
||||
let result = (|| {
|
||||
match req_head.type_ {
|
||||
VIRTIO_IOMMU_T_ATTACH => {
|
||||
if desc_size_left != size_of::<VirtioIommuReqAttach>() {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidAttachRequest);
|
||||
}
|
||||
|
||||
@ -436,11 +440,10 @@ impl Request {
|
||||
bypass,
|
||||
};
|
||||
domains.entry(domain_id).or_insert_with(|| domain);
|
||||
|
||||
0
|
||||
}
|
||||
VIRTIO_IOMMU_T_DETACH => {
|
||||
if desc_size_left != size_of::<VirtioIommuReqDetach>() {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidDetachRequest);
|
||||
}
|
||||
|
||||
@ -471,11 +474,10 @@ impl Request {
|
||||
{
|
||||
mapping.domains.write().unwrap().remove(&domain_id);
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
VIRTIO_IOMMU_T_MAP => {
|
||||
if desc_size_left != size_of::<VirtioIommuReqMap>() {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidMapRequest);
|
||||
}
|
||||
|
||||
@ -490,9 +492,11 @@ impl Request {
|
||||
|
||||
if let Some(domain) = mapping.domains.read().unwrap().get(&domain_id) {
|
||||
if domain.bypass {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidMapRequestBypassDomain);
|
||||
}
|
||||
} else {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidMapRequestMissingDomain);
|
||||
}
|
||||
|
||||
@ -531,11 +535,10 @@ impl Request {
|
||||
size: req.virt_end - req.virt_start + 1,
|
||||
},
|
||||
);
|
||||
|
||||
0
|
||||
}
|
||||
VIRTIO_IOMMU_T_UNMAP => {
|
||||
if desc_size_left != size_of::<VirtioIommuReqUnmap>() {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidUnmapRequest);
|
||||
}
|
||||
|
||||
@ -551,9 +554,11 @@ impl Request {
|
||||
|
||||
if let Some(domain) = mapping.domains.read().unwrap().get(&domain_id) {
|
||||
if domain.bypass {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidUnmapRequestBypassDomain);
|
||||
}
|
||||
} else {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidUnmapRequestMissingDomain);
|
||||
}
|
||||
|
||||
@ -586,11 +591,10 @@ impl Request {
|
||||
.unwrap()
|
||||
.mappings
|
||||
.remove(&virt_start);
|
||||
|
||||
0
|
||||
}
|
||||
VIRTIO_IOMMU_T_PROBE => {
|
||||
if desc_size_left != size_of::<VirtioIommuReqProbe>() {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidProbeRequest);
|
||||
}
|
||||
|
||||
@ -614,10 +618,15 @@ impl Request {
|
||||
};
|
||||
reply.extend_from_slice(resv_mem.as_slice());
|
||||
|
||||
PROBE_PROP_SIZE
|
||||
hdr_len = PROBE_PROP_SIZE;
|
||||
}
|
||||
_ => return Err(Error::InvalidRequest),
|
||||
};
|
||||
_ => {
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidRequest);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
let status_desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
|
||||
|
||||
@ -631,16 +640,21 @@ impl Request {
|
||||
}
|
||||
|
||||
let tail = VirtioIommuReqTail {
|
||||
status: VIRTIO_IOMMU_S_OK,
|
||||
status,
|
||||
..Default::default()
|
||||
};
|
||||
reply.extend_from_slice(tail.as_slice());
|
||||
|
||||
// Make sure we return the result of the request to the guest before
|
||||
// we return a potential error internally.
|
||||
desc_chain
|
||||
.memory()
|
||||
.write_slice(reply.as_slice(), status_desc.addr())
|
||||
.map_err(Error::GuestMemory)?;
|
||||
|
||||
// Return the error if the result was not Ok().
|
||||
result?;
|
||||
|
||||
Ok((hdr_len as usize) + size_of::<VirtioIommuReqTail>())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user