mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-30 05:21:55 -06:00
vfio/container: Move vfio_container_add/del_section_window into spapr.c
vfio_container_add/del_section_window are spapr specific functions, so move them into spapr.c to make container.c cleaner. No functional changes intended. Suggested-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
54876d25fe
commit
521c8f4ebc
2 changed files with 90 additions and 90 deletions
|
@ -20,9 +20,6 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#ifdef CONFIG_KVM
|
|
||||||
#include <linux/kvm.h>
|
|
||||||
#endif
|
|
||||||
#include <linux/vfio.h>
|
#include <linux/vfio.h>
|
||||||
|
|
||||||
#include "hw/vfio/vfio-common.h"
|
#include "hw/vfio/vfio-common.h"
|
||||||
|
@ -32,7 +29,6 @@
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/range.h"
|
#include "qemu/range.h"
|
||||||
#include "sysemu/kvm.h"
|
|
||||||
#include "sysemu/reset.h"
|
#include "sysemu/reset.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
@ -204,92 +200,6 @@ int vfio_dma_map(VFIOContainer *container, hwaddr iova,
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfio_container_add_section_window(VFIOContainer *container,
|
|
||||||
MemoryRegionSection *section,
|
|
||||||
Error **errp)
|
|
||||||
{
|
|
||||||
VFIOHostDMAWindow *hostwin;
|
|
||||||
hwaddr pgsize = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For now intersections are not allowed, we may relax this later */
|
|
||||||
QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
|
|
||||||
if (ranges_overlap(hostwin->min_iova,
|
|
||||||
hostwin->max_iova - hostwin->min_iova + 1,
|
|
||||||
section->offset_within_address_space,
|
|
||||||
int128_get64(section->size))) {
|
|
||||||
error_setg(errp,
|
|
||||||
"region [0x%"PRIx64",0x%"PRIx64"] overlaps with existing"
|
|
||||||
"host DMA window [0x%"PRIx64",0x%"PRIx64"]",
|
|
||||||
section->offset_within_address_space,
|
|
||||||
section->offset_within_address_space +
|
|
||||||
int128_get64(section->size) - 1,
|
|
||||||
hostwin->min_iova, hostwin->max_iova);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = vfio_spapr_create_window(container, section, &pgsize);
|
|
||||||
if (ret) {
|
|
||||||
error_setg_errno(errp, -ret, "Failed to create SPAPR window");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
vfio_host_win_add(container, section->offset_within_address_space,
|
|
||||||
section->offset_within_address_space +
|
|
||||||
int128_get64(section->size) - 1, pgsize);
|
|
||||||
#ifdef CONFIG_KVM
|
|
||||||
if (kvm_enabled()) {
|
|
||||||
VFIOGroup *group;
|
|
||||||
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
|
|
||||||
struct kvm_vfio_spapr_tce param;
|
|
||||||
struct kvm_device_attr attr = {
|
|
||||||
.group = KVM_DEV_VFIO_GROUP,
|
|
||||||
.attr = KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE,
|
|
||||||
.addr = (uint64_t)(unsigned long)¶m,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_SPAPR_TCE_FD,
|
|
||||||
¶m.tablefd)) {
|
|
||||||
QLIST_FOREACH(group, &container->group_list, container_next) {
|
|
||||||
param.groupfd = group->fd;
|
|
||||||
if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
|
|
||||||
error_setg_errno(errp, errno,
|
|
||||||
"vfio: failed GROUP_SET_SPAPR_TCE for "
|
|
||||||
"KVM VFIO device %d and group fd %d",
|
|
||||||
param.tablefd, param.groupfd);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
trace_vfio_spapr_group_attach(param.groupfd, param.tablefd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vfio_container_del_section_window(VFIOContainer *container,
|
|
||||||
MemoryRegionSection *section)
|
|
||||||
{
|
|
||||||
if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vfio_spapr_remove_window(container,
|
|
||||||
section->offset_within_address_space);
|
|
||||||
if (vfio_host_win_del(container,
|
|
||||||
section->offset_within_address_space,
|
|
||||||
section->offset_within_address_space +
|
|
||||||
int128_get64(section->size) - 1) < 0) {
|
|
||||||
hw_error("%s: Cannot delete missing window at %"HWADDR_PRIx,
|
|
||||||
__func__, section->offset_within_address_space);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start)
|
int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <linux/vfio.h>
|
#include <linux/vfio.h>
|
||||||
|
#ifdef CONFIG_KVM
|
||||||
|
#include <linux/kvm.h>
|
||||||
|
#endif
|
||||||
|
#include "sysemu/kvm.h"
|
||||||
|
|
||||||
#include "hw/vfio/vfio-common.h"
|
#include "hw/vfio/vfio-common.h"
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
|
@ -253,3 +257,89 @@ int vfio_spapr_remove_window(VFIOContainer *container,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vfio_container_add_section_window(VFIOContainer *container,
|
||||||
|
MemoryRegionSection *section,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
VFIOHostDMAWindow *hostwin;
|
||||||
|
hwaddr pgsize = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For now intersections are not allowed, we may relax this later */
|
||||||
|
QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
|
||||||
|
if (ranges_overlap(hostwin->min_iova,
|
||||||
|
hostwin->max_iova - hostwin->min_iova + 1,
|
||||||
|
section->offset_within_address_space,
|
||||||
|
int128_get64(section->size))) {
|
||||||
|
error_setg(errp,
|
||||||
|
"region [0x%"PRIx64",0x%"PRIx64"] overlaps with existing"
|
||||||
|
"host DMA window [0x%"PRIx64",0x%"PRIx64"]",
|
||||||
|
section->offset_within_address_space,
|
||||||
|
section->offset_within_address_space +
|
||||||
|
int128_get64(section->size) - 1,
|
||||||
|
hostwin->min_iova, hostwin->max_iova);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = vfio_spapr_create_window(container, section, &pgsize);
|
||||||
|
if (ret) {
|
||||||
|
error_setg_errno(errp, -ret, "Failed to create SPAPR window");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfio_host_win_add(container, section->offset_within_address_space,
|
||||||
|
section->offset_within_address_space +
|
||||||
|
int128_get64(section->size) - 1, pgsize);
|
||||||
|
#ifdef CONFIG_KVM
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
VFIOGroup *group;
|
||||||
|
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
|
||||||
|
struct kvm_vfio_spapr_tce param;
|
||||||
|
struct kvm_device_attr attr = {
|
||||||
|
.group = KVM_DEV_VFIO_GROUP,
|
||||||
|
.attr = KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE,
|
||||||
|
.addr = (uint64_t)(unsigned long)¶m,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_SPAPR_TCE_FD,
|
||||||
|
¶m.tablefd)) {
|
||||||
|
QLIST_FOREACH(group, &container->group_list, container_next) {
|
||||||
|
param.groupfd = group->fd;
|
||||||
|
if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
|
||||||
|
error_setg_errno(errp, errno,
|
||||||
|
"vfio: failed GROUP_SET_SPAPR_TCE for "
|
||||||
|
"KVM VFIO device %d and group fd %d",
|
||||||
|
param.tablefd, param.groupfd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
trace_vfio_spapr_group_attach(param.groupfd, param.tablefd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vfio_container_del_section_window(VFIOContainer *container,
|
||||||
|
MemoryRegionSection *section)
|
||||||
|
{
|
||||||
|
if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfio_spapr_remove_window(container,
|
||||||
|
section->offset_within_address_space);
|
||||||
|
if (vfio_host_win_del(container,
|
||||||
|
section->offset_within_address_space,
|
||||||
|
section->offset_within_address_space +
|
||||||
|
int128_get64(section->size) - 1) < 0) {
|
||||||
|
hw_error("%s: Cannot delete missing window at %"HWADDR_PRIx,
|
||||||
|
__func__, section->offset_within_address_space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue