virtio-iommu: Decode the command payload
This patch adds the command payload decoding and introduces the functions that will do the actual command handling. Those functions are not yet implemented. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20200214132745.23392-3-eric.auger@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
22c37a10f3
commit
5442b854ea
@ -60,3 +60,7 @@ virtio_iommu_get_features(uint64_t features) "device supports features=0x%"PRIx6
|
|||||||
virtio_iommu_device_status(uint8_t status) "driver status = %d"
|
virtio_iommu_device_status(uint8_t status) "driver status = %d"
|
||||||
virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_range=%d probe_size=0x%x"
|
virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_range=%d probe_size=0x%x"
|
||||||
virtio_iommu_set_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_bits=%d probe_size=0x%x"
|
virtio_iommu_set_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_bits=%d probe_size=0x%x"
|
||||||
|
virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
|
||||||
|
virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
|
||||||
|
virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d"
|
||||||
|
virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
|
||||||
|
@ -34,31 +34,83 @@
|
|||||||
/* Max size */
|
/* Max size */
|
||||||
#define VIOMMU_DEFAULT_QUEUE_SIZE 256
|
#define VIOMMU_DEFAULT_QUEUE_SIZE 256
|
||||||
|
|
||||||
static int virtio_iommu_handle_attach(VirtIOIOMMU *s,
|
static int virtio_iommu_attach(VirtIOIOMMU *s,
|
||||||
struct iovec *iov,
|
struct virtio_iommu_req_attach *req)
|
||||||
unsigned int iov_cnt)
|
|
||||||
{
|
{
|
||||||
|
uint32_t domain_id = le32_to_cpu(req->domain);
|
||||||
|
uint32_t ep_id = le32_to_cpu(req->endpoint);
|
||||||
|
|
||||||
|
trace_virtio_iommu_attach(domain_id, ep_id);
|
||||||
|
|
||||||
return VIRTIO_IOMMU_S_UNSUPP;
|
return VIRTIO_IOMMU_S_UNSUPP;
|
||||||
}
|
}
|
||||||
static int virtio_iommu_handle_detach(VirtIOIOMMU *s,
|
|
||||||
struct iovec *iov,
|
static int virtio_iommu_detach(VirtIOIOMMU *s,
|
||||||
unsigned int iov_cnt)
|
struct virtio_iommu_req_detach *req)
|
||||||
{
|
{
|
||||||
|
uint32_t domain_id = le32_to_cpu(req->domain);
|
||||||
|
uint32_t ep_id = le32_to_cpu(req->endpoint);
|
||||||
|
|
||||||
|
trace_virtio_iommu_detach(domain_id, ep_id);
|
||||||
|
|
||||||
return VIRTIO_IOMMU_S_UNSUPP;
|
return VIRTIO_IOMMU_S_UNSUPP;
|
||||||
}
|
}
|
||||||
static int virtio_iommu_handle_map(VirtIOIOMMU *s,
|
|
||||||
struct iovec *iov,
|
static int virtio_iommu_map(VirtIOIOMMU *s,
|
||||||
unsigned int iov_cnt)
|
struct virtio_iommu_req_map *req)
|
||||||
{
|
{
|
||||||
|
uint32_t domain_id = le32_to_cpu(req->domain);
|
||||||
|
uint64_t phys_start = le64_to_cpu(req->phys_start);
|
||||||
|
uint64_t virt_start = le64_to_cpu(req->virt_start);
|
||||||
|
uint64_t virt_end = le64_to_cpu(req->virt_end);
|
||||||
|
uint32_t flags = le32_to_cpu(req->flags);
|
||||||
|
|
||||||
|
trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, flags);
|
||||||
|
|
||||||
return VIRTIO_IOMMU_S_UNSUPP;
|
return VIRTIO_IOMMU_S_UNSUPP;
|
||||||
}
|
}
|
||||||
static int virtio_iommu_handle_unmap(VirtIOIOMMU *s,
|
|
||||||
struct iovec *iov,
|
static int virtio_iommu_unmap(VirtIOIOMMU *s,
|
||||||
unsigned int iov_cnt)
|
struct virtio_iommu_req_unmap *req)
|
||||||
{
|
{
|
||||||
|
uint32_t domain_id = le32_to_cpu(req->domain);
|
||||||
|
uint64_t virt_start = le64_to_cpu(req->virt_start);
|
||||||
|
uint64_t virt_end = le64_to_cpu(req->virt_end);
|
||||||
|
|
||||||
|
trace_virtio_iommu_unmap(domain_id, virt_start, virt_end);
|
||||||
|
|
||||||
return VIRTIO_IOMMU_S_UNSUPP;
|
return VIRTIO_IOMMU_S_UNSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int virtio_iommu_iov_to_req(struct iovec *iov,
|
||||||
|
unsigned int iov_cnt,
|
||||||
|
void *req, size_t req_sz)
|
||||||
|
{
|
||||||
|
size_t sz, payload_sz = req_sz - sizeof(struct virtio_iommu_req_tail);
|
||||||
|
|
||||||
|
sz = iov_to_buf(iov, iov_cnt, 0, req, payload_sz);
|
||||||
|
if (unlikely(sz != payload_sz)) {
|
||||||
|
return VIRTIO_IOMMU_S_INVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define virtio_iommu_handle_req(__req) \
|
||||||
|
static int virtio_iommu_handle_ ## __req(VirtIOIOMMU *s, \
|
||||||
|
struct iovec *iov, \
|
||||||
|
unsigned int iov_cnt) \
|
||||||
|
{ \
|
||||||
|
struct virtio_iommu_req_ ## __req req; \
|
||||||
|
int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); \
|
||||||
|
\
|
||||||
|
return ret ? ret : virtio_iommu_ ## __req(s, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
|
virtio_iommu_handle_req(attach)
|
||||||
|
virtio_iommu_handle_req(detach)
|
||||||
|
virtio_iommu_handle_req(map)
|
||||||
|
virtio_iommu_handle_req(unmap)
|
||||||
|
|
||||||
static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
|
static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
|
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
|
||||||
|
Loading…
Reference in New Issue
Block a user