mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
virtio: convert to use DMA api
Currently, all virtio devices bypass IOMMU completely. This is because address_space_memory is assumed and used during DMA emulation. This patch converts the virtio core API to use DMA API. This idea is - introducing a new transport specific helper to query the dma address space. (only pci version is implemented). - query and use this address space during virtio device guest memory accessing when iommu platform (VIRTIO_F_IOMMU_PLATFORM) was enabled for this device. Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Stefan Hajnoczi <stefanha@redhat.com> Cc: Kevin Wolf <kwolf@redhat.com> Cc: Amit Shah <amit.shah@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: qemu-block@nongnu.org Signed-off-by: Jason Wang <jasowang@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
a08aaff811
commit
8607f5c307
9 changed files with 93 additions and 36 deletions
|
@ -17,6 +17,7 @@
|
|||
#define QEMU_VIRTIO_ACCESS_H
|
||||
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "exec/address-spaces.h"
|
||||
|
||||
#if defined(TARGET_PPC64) || defined(TARGET_ARM)
|
||||
|
@ -40,45 +41,55 @@ static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
|
|||
|
||||
static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
|
||||
{
|
||||
AddressSpace *dma_as = vdev->dma_as;
|
||||
|
||||
if (virtio_access_is_big_endian(vdev)) {
|
||||
return lduw_be_phys(&address_space_memory, pa);
|
||||
return lduw_be_phys(dma_as, pa);
|
||||
}
|
||||
return lduw_le_phys(&address_space_memory, pa);
|
||||
return lduw_le_phys(dma_as, pa);
|
||||
}
|
||||
|
||||
static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
|
||||
{
|
||||
AddressSpace *dma_as = vdev->dma_as;
|
||||
|
||||
if (virtio_access_is_big_endian(vdev)) {
|
||||
return ldl_be_phys(&address_space_memory, pa);
|
||||
return ldl_be_phys(dma_as, pa);
|
||||
}
|
||||
return ldl_le_phys(&address_space_memory, pa);
|
||||
return ldl_le_phys(dma_as, pa);
|
||||
}
|
||||
|
||||
static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
|
||||
{
|
||||
AddressSpace *dma_as = vdev->dma_as;
|
||||
|
||||
if (virtio_access_is_big_endian(vdev)) {
|
||||
return ldq_be_phys(&address_space_memory, pa);
|
||||
return ldq_be_phys(dma_as, pa);
|
||||
}
|
||||
return ldq_le_phys(&address_space_memory, pa);
|
||||
return ldq_le_phys(dma_as, pa);
|
||||
}
|
||||
|
||||
static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
|
||||
uint16_t value)
|
||||
{
|
||||
AddressSpace *dma_as = vdev->dma_as;
|
||||
|
||||
if (virtio_access_is_big_endian(vdev)) {
|
||||
stw_be_phys(&address_space_memory, pa, value);
|
||||
stw_be_phys(dma_as, pa, value);
|
||||
} else {
|
||||
stw_le_phys(&address_space_memory, pa, value);
|
||||
stw_le_phys(dma_as, pa, value);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
|
||||
uint32_t value)
|
||||
{
|
||||
AddressSpace *dma_as = vdev->dma_as;
|
||||
|
||||
if (virtio_access_is_big_endian(vdev)) {
|
||||
stl_be_phys(&address_space_memory, pa, value);
|
||||
stl_be_phys(dma_as, pa, value);
|
||||
} else {
|
||||
stl_le_phys(&address_space_memory, pa, value);
|
||||
stl_le_phys(dma_as, pa, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue