xref: /openbmc/qemu/hw/vfio/container-base.c (revision 2137d2fd)
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