xref: /openbmc/qemu/hw/vfio/container-base.c (revision 41d698b8)
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 {
22*41d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
23*41d698b8SCédric Le Goater 
24*41d698b8SCédric Le Goater     g_assert(vioc->dma_map);
25*41d698b8SCédric Le Goater     return vioc->dma_map(bcontainer, iova, size, vaddr, readonly);
26b08501a9SEric Auger }
27b08501a9SEric Auger 
28b08501a9SEric Auger int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
29b08501a9SEric Auger                              hwaddr iova, ram_addr_t size,
30b08501a9SEric Auger                              IOMMUTLBEntry *iotlb)
31b08501a9SEric Auger {
32*41d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
33*41d698b8SCédric Le Goater 
34*41d698b8SCédric Le Goater     g_assert(vioc->dma_unmap);
35*41d698b8SCédric Le Goater     return vioc->dma_unmap(bcontainer, iova, size, iotlb);
36b08501a9SEric Auger }
37ed2f7f80SZhenzhong Duan 
3833e4c22fSZhenzhong Duan bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
39233309e8SZhenzhong Duan                                        MemoryRegionSection *section,
40233309e8SZhenzhong Duan                                        Error **errp)
41233309e8SZhenzhong Duan {
42*41d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
43*41d698b8SCédric Le Goater 
44*41d698b8SCédric Le Goater     if (!vioc->add_window) {
4533e4c22fSZhenzhong Duan         return true;
46233309e8SZhenzhong Duan     }
47233309e8SZhenzhong Duan 
48*41d698b8SCédric Le Goater     return vioc->add_window(bcontainer, section, errp);
49233309e8SZhenzhong Duan }
50233309e8SZhenzhong Duan 
51233309e8SZhenzhong Duan void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
52233309e8SZhenzhong Duan                                        MemoryRegionSection *section)
53233309e8SZhenzhong Duan {
54*41d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
55*41d698b8SCédric Le Goater 
56*41d698b8SCédric Le Goater     if (!vioc->del_window) {
57233309e8SZhenzhong Duan         return;
58233309e8SZhenzhong Duan     }
59233309e8SZhenzhong Duan 
60*41d698b8SCédric Le Goater     return vioc->del_window(bcontainer, section);
61233309e8SZhenzhong Duan }
62233309e8SZhenzhong Duan 
63bb424490SEric Auger int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
64836bb308SCédric Le Goater                                            bool start, Error **errp)
65bb424490SEric Auger {
66*41d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
67*41d698b8SCédric Le Goater 
6836e84d0cSZhenzhong Duan     if (!bcontainer->dirty_pages_supported) {
6936e84d0cSZhenzhong Duan         return 0;
7036e84d0cSZhenzhong Duan     }
7136e84d0cSZhenzhong Duan 
72*41d698b8SCédric Le Goater     g_assert(vioc->set_dirty_page_tracking);
73*41d698b8SCédric Le Goater     return vioc->set_dirty_page_tracking(bcontainer, start, errp);
74bb424490SEric Auger }
75bb424490SEric Auger 
764517c33cSZhenzhong Duan int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
772da5f9e4SCédric Le Goater                    VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp)
78bb424490SEric Auger {
79*41d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
80*41d698b8SCédric Le Goater 
81*41d698b8SCédric Le Goater     g_assert(vioc->query_dirty_bitmap);
82*41d698b8SCédric Le Goater     return vioc->query_dirty_bitmap(bcontainer, vbmap, iova, size,
832da5f9e4SCédric Le Goater                                                errp);
84bb424490SEric Auger }
85bb424490SEric Auger 
8609181a8eSCédric Le Goater void vfio_container_init(VFIOContainerBase *bcontainer,
87fdaa774eSCédric Le Goater                          const VFIOIOMMUClass *ops)
88ed2f7f80SZhenzhong Duan {
89ed2f7f80SZhenzhong Duan }
90ed2f7f80SZhenzhong Duan 
91ed2f7f80SZhenzhong Duan void vfio_container_destroy(VFIOContainerBase *bcontainer)
92ed2f7f80SZhenzhong Duan {
93dddf83abSEric Auger     VFIOGuestIOMMU *giommu, *tmp;
94dddf83abSEric Auger 
95e5597063SEric Auger     QLIST_REMOVE(bcontainer, next);
96e5597063SEric Auger 
97dddf83abSEric Auger     QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) {
98dddf83abSEric Auger         memory_region_unregister_iommu_notifier(
99dddf83abSEric Auger                 MEMORY_REGION(giommu->iommu_mr), &giommu->n);
100dddf83abSEric Auger         QLIST_REMOVE(giommu, giommu_next);
101dddf83abSEric Auger         g_free(giommu);
102dddf83abSEric Auger     }
103f79baf8cSZhenzhong Duan 
104f79baf8cSZhenzhong Duan     g_list_free_full(bcontainer->iova_ranges, g_free);
105ed2f7f80SZhenzhong Duan }
106fdaa774eSCédric Le Goater 
1072137d2fdSCédric Le Goater static void vfio_container_instance_init(Object *obj)
1082137d2fdSCédric Le Goater {
1092137d2fdSCédric Le Goater     VFIOContainerBase *bcontainer = VFIO_IOMMU(obj);
1102137d2fdSCédric Le Goater 
1112137d2fdSCédric Le Goater     bcontainer->error = NULL;
1122137d2fdSCédric Le Goater     bcontainer->dirty_pages_supported = false;
1132137d2fdSCédric Le Goater     bcontainer->dma_max_mappings = 0;
1142137d2fdSCédric Le Goater     bcontainer->iova_ranges = NULL;
1152137d2fdSCédric Le Goater     QLIST_INIT(&bcontainer->giommu_list);
1162137d2fdSCédric Le Goater     QLIST_INIT(&bcontainer->vrdl_list);
1172137d2fdSCédric Le Goater }
1182137d2fdSCédric Le Goater 
119fdaa774eSCédric Le Goater static const TypeInfo types[] = {
120fdaa774eSCédric Le Goater     {
121fdaa774eSCédric Le Goater         .name = TYPE_VFIO_IOMMU,
122504d297eSCédric Le Goater         .parent = TYPE_OBJECT,
1232137d2fdSCédric Le Goater         .instance_init = vfio_container_instance_init,
124504d297eSCédric Le Goater         .instance_size = sizeof(VFIOContainerBase),
125fdaa774eSCédric Le Goater         .class_size = sizeof(VFIOIOMMUClass),
126504d297eSCédric Le Goater         .abstract = true,
127fdaa774eSCédric Le Goater     },
128fdaa774eSCédric Le Goater };
129fdaa774eSCédric Le Goater 
130fdaa774eSCédric Le Goater DEFINE_TYPES(types)
131