1b08501a9SEric Auger /* 2b08501a9SEric Auger * VFIO BASE CONTAINER 3b08501a9SEric Auger * 4b08501a9SEric Auger * Copyright (C) 2023 Intel Corporation. 5b08501a9SEric Auger * Copyright Red Hat, Inc. 2023 6b08501a9SEric Auger * 7b08501a9SEric Auger * Authors: Yi Liu <yi.l.liu@intel.com> 8b08501a9SEric Auger * Eric Auger <eric.auger@redhat.com> 9b08501a9SEric Auger * 10b08501a9SEric Auger * SPDX-License-Identifier: GPL-2.0-or-later 11b08501a9SEric Auger */ 12b08501a9SEric Auger 13b08501a9SEric Auger #include "qemu/osdep.h" 14b08501a9SEric Auger #include "qapi/error.h" 15b08501a9SEric Auger #include "qemu/error-report.h" 16b08501a9SEric Auger #include "hw/vfio/vfio-container-base.h" 17b08501a9SEric Auger 18b08501a9SEric Auger int vfio_container_dma_map(VFIOContainerBase *bcontainer, 19b08501a9SEric Auger hwaddr iova, ram_addr_t size, 20b08501a9SEric Auger void *vaddr, bool readonly) 21b08501a9SEric Auger { 22b08501a9SEric Auger g_assert(bcontainer->ops->dma_map); 23b08501a9SEric Auger return bcontainer->ops->dma_map(bcontainer, iova, size, vaddr, readonly); 24b08501a9SEric Auger } 25b08501a9SEric Auger 26b08501a9SEric Auger int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, 27b08501a9SEric Auger hwaddr iova, ram_addr_t size, 28b08501a9SEric Auger IOMMUTLBEntry *iotlb) 29b08501a9SEric Auger { 30b08501a9SEric Auger g_assert(bcontainer->ops->dma_unmap); 31b08501a9SEric Auger return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); 32b08501a9SEric Auger } 33ed2f7f80SZhenzhong Duan 34233309e8SZhenzhong Duan int vfio_container_add_section_window(VFIOContainerBase *bcontainer, 35233309e8SZhenzhong Duan MemoryRegionSection *section, 36233309e8SZhenzhong Duan Error **errp) 37233309e8SZhenzhong Duan { 38233309e8SZhenzhong Duan if (!bcontainer->ops->add_window) { 39233309e8SZhenzhong Duan return 0; 40233309e8SZhenzhong Duan } 41233309e8SZhenzhong Duan 42233309e8SZhenzhong Duan return bcontainer->ops->add_window(bcontainer, section, errp); 43233309e8SZhenzhong Duan } 44233309e8SZhenzhong Duan 45233309e8SZhenzhong Duan void vfio_container_del_section_window(VFIOContainerBase *bcontainer, 46233309e8SZhenzhong Duan MemoryRegionSection *section) 47233309e8SZhenzhong Duan { 48233309e8SZhenzhong Duan if (!bcontainer->ops->del_window) { 49233309e8SZhenzhong Duan return; 50233309e8SZhenzhong Duan } 51233309e8SZhenzhong Duan 52233309e8SZhenzhong Duan return bcontainer->ops->del_window(bcontainer, section); 53233309e8SZhenzhong Duan } 54233309e8SZhenzhong Duan 55bb424490SEric Auger int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, 56836bb308SCédric Le Goater bool start, Error **errp) 57bb424490SEric Auger { 5836e84d0cSZhenzhong Duan if (!bcontainer->dirty_pages_supported) { 5936e84d0cSZhenzhong Duan return 0; 6036e84d0cSZhenzhong Duan } 6136e84d0cSZhenzhong Duan 62bb424490SEric Auger g_assert(bcontainer->ops->set_dirty_page_tracking); 63836bb308SCédric Le Goater return bcontainer->ops->set_dirty_page_tracking(bcontainer, start, errp); 64bb424490SEric Auger } 65bb424490SEric Auger 664517c33cSZhenzhong Duan int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, 67*2da5f9e4SCédric Le Goater VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp) 68bb424490SEric Auger { 69bb424490SEric Auger g_assert(bcontainer->ops->query_dirty_bitmap); 70*2da5f9e4SCédric Le Goater return bcontainer->ops->query_dirty_bitmap(bcontainer, vbmap, iova, size, 71*2da5f9e4SCédric Le Goater errp); 72bb424490SEric Auger } 73bb424490SEric Auger 74e5597063SEric Auger void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, 75fdaa774eSCédric Le Goater const VFIOIOMMUClass *ops) 76ed2f7f80SZhenzhong Duan { 77ed2f7f80SZhenzhong Duan bcontainer->ops = ops; 78e5597063SEric Auger bcontainer->space = space; 79c7b313d3SEric Auger bcontainer->error = NULL; 80bb424490SEric Auger bcontainer->dirty_pages_supported = false; 817ab1cb74SEric Auger bcontainer->dma_max_mappings = 0; 82f79baf8cSZhenzhong Duan bcontainer->iova_ranges = NULL; 83dddf83abSEric Auger QLIST_INIT(&bcontainer->giommu_list); 84dc74a4b0SZhenzhong Duan QLIST_INIT(&bcontainer->vrdl_list); 85ed2f7f80SZhenzhong Duan } 86ed2f7f80SZhenzhong Duan 87ed2f7f80SZhenzhong Duan void vfio_container_destroy(VFIOContainerBase *bcontainer) 88ed2f7f80SZhenzhong Duan { 89dddf83abSEric Auger VFIOGuestIOMMU *giommu, *tmp; 90dddf83abSEric Auger 91e5597063SEric Auger QLIST_REMOVE(bcontainer, next); 92e5597063SEric Auger 93dddf83abSEric Auger QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) { 94dddf83abSEric Auger memory_region_unregister_iommu_notifier( 95dddf83abSEric Auger MEMORY_REGION(giommu->iommu_mr), &giommu->n); 96dddf83abSEric Auger QLIST_REMOVE(giommu, giommu_next); 97dddf83abSEric Auger g_free(giommu); 98dddf83abSEric Auger } 99f79baf8cSZhenzhong Duan 100f79baf8cSZhenzhong Duan g_list_free_full(bcontainer->iova_ranges, g_free); 101ed2f7f80SZhenzhong Duan } 102fdaa774eSCédric Le Goater 103fdaa774eSCédric Le Goater static const TypeInfo types[] = { 104fdaa774eSCédric Le Goater { 105fdaa774eSCédric Le Goater .name = TYPE_VFIO_IOMMU, 106fdaa774eSCédric Le Goater .parent = TYPE_INTERFACE, 107fdaa774eSCédric Le Goater .class_size = sizeof(VFIOIOMMUClass), 108fdaa774eSCédric Le Goater }, 109fdaa774eSCédric Le Goater }; 110fdaa774eSCédric Le Goater 111fdaa774eSCédric Le Goater DEFINE_TYPES(types) 112