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 3433e4c22fSZhenzhong Duan bool vfio_container_add_section_window(VFIOContainerBase *bcontainer, 35233309e8SZhenzhong Duan MemoryRegionSection *section, 36233309e8SZhenzhong Duan Error **errp) 37233309e8SZhenzhong Duan { 38233309e8SZhenzhong Duan if (!bcontainer->ops->add_window) { 3933e4c22fSZhenzhong Duan return true; 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, 672da5f9e4SCédric Le Goater VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp) 68bb424490SEric Auger { 69bb424490SEric Auger g_assert(bcontainer->ops->query_dirty_bitmap); 702da5f9e4SCédric Le Goater return bcontainer->ops->query_dirty_bitmap(bcontainer, vbmap, iova, size, 712da5f9e4SCédric Le Goater errp); 72bb424490SEric Auger } 73bb424490SEric Auger 7409181a8eSCédric Le Goater void vfio_container_init(VFIOContainerBase *bcontainer, 75fdaa774eSCédric Le Goater const VFIOIOMMUClass *ops) 76ed2f7f80SZhenzhong Duan { 77ed2f7f80SZhenzhong Duan bcontainer->ops = ops; 78ed2f7f80SZhenzhong Duan } 79ed2f7f80SZhenzhong Duan 80ed2f7f80SZhenzhong Duan void vfio_container_destroy(VFIOContainerBase *bcontainer) 81ed2f7f80SZhenzhong Duan { 82dddf83abSEric Auger VFIOGuestIOMMU *giommu, *tmp; 83dddf83abSEric Auger 84e5597063SEric Auger QLIST_REMOVE(bcontainer, next); 85e5597063SEric Auger 86dddf83abSEric Auger QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) { 87dddf83abSEric Auger memory_region_unregister_iommu_notifier( 88dddf83abSEric Auger MEMORY_REGION(giommu->iommu_mr), &giommu->n); 89dddf83abSEric Auger QLIST_REMOVE(giommu, giommu_next); 90dddf83abSEric Auger g_free(giommu); 91dddf83abSEric Auger } 92f79baf8cSZhenzhong Duan 93f79baf8cSZhenzhong Duan g_list_free_full(bcontainer->iova_ranges, g_free); 94ed2f7f80SZhenzhong Duan } 95fdaa774eSCédric Le Goater 96*2137d2fdSCédric Le Goater static void vfio_container_instance_init(Object *obj) 97*2137d2fdSCédric Le Goater { 98*2137d2fdSCédric Le Goater VFIOContainerBase *bcontainer = VFIO_IOMMU(obj); 99*2137d2fdSCédric Le Goater 100*2137d2fdSCédric Le Goater bcontainer->error = NULL; 101*2137d2fdSCédric Le Goater bcontainer->dirty_pages_supported = false; 102*2137d2fdSCédric Le Goater bcontainer->dma_max_mappings = 0; 103*2137d2fdSCédric Le Goater bcontainer->iova_ranges = NULL; 104*2137d2fdSCédric Le Goater QLIST_INIT(&bcontainer->giommu_list); 105*2137d2fdSCédric Le Goater QLIST_INIT(&bcontainer->vrdl_list); 106*2137d2fdSCédric Le Goater } 107*2137d2fdSCédric Le Goater 108fdaa774eSCédric Le Goater static const TypeInfo types[] = { 109fdaa774eSCédric Le Goater { 110fdaa774eSCédric Le Goater .name = TYPE_VFIO_IOMMU, 111504d297eSCédric Le Goater .parent = TYPE_OBJECT, 112*2137d2fdSCédric Le Goater .instance_init = vfio_container_instance_init, 113504d297eSCédric Le Goater .instance_size = sizeof(VFIOContainerBase), 114fdaa774eSCédric Le Goater .class_size = sizeof(VFIOIOMMUClass), 115504d297eSCédric Le Goater .abstract = true, 116fdaa774eSCédric Le Goater }, 117fdaa774eSCédric Le Goater }; 118fdaa774eSCédric Le Goater 119fdaa774eSCédric Le Goater DEFINE_TYPES(types) 120