xref: /openbmc/qemu/hw/vfio/container-base.c (revision 3966bca5)
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 
vfio_container_dma_map(VFIOContainerBase * bcontainer,hwaddr iova,ram_addr_t size,void * vaddr,bool readonly)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 {
2241d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
2341d698b8SCédric Le Goater 
2441d698b8SCédric Le Goater     g_assert(vioc->dma_map);
2541d698b8SCédric Le Goater     return vioc->dma_map(bcontainer, iova, size, vaddr, readonly);
26b08501a9SEric Auger }
27b08501a9SEric Auger 
vfio_container_dma_unmap(VFIOContainerBase * bcontainer,hwaddr iova,ram_addr_t size,IOMMUTLBEntry * iotlb)28b08501a9SEric Auger int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
29b08501a9SEric Auger                              hwaddr iova, ram_addr_t size,
30b08501a9SEric Auger                              IOMMUTLBEntry *iotlb)
31b08501a9SEric Auger {
3241d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
3341d698b8SCédric Le Goater 
3441d698b8SCédric Le Goater     g_assert(vioc->dma_unmap);
3541d698b8SCédric Le Goater     return vioc->dma_unmap(bcontainer, iova, size, iotlb);
36b08501a9SEric Auger }
37ed2f7f80SZhenzhong Duan 
vfio_container_add_section_window(VFIOContainerBase * bcontainer,MemoryRegionSection * section,Error ** errp)3833e4c22fSZhenzhong Duan bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
39233309e8SZhenzhong Duan                                        MemoryRegionSection *section,
40233309e8SZhenzhong Duan                                        Error **errp)
41233309e8SZhenzhong Duan {
4241d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
4341d698b8SCédric Le Goater 
4441d698b8SCédric Le Goater     if (!vioc->add_window) {
4533e4c22fSZhenzhong Duan         return true;
46233309e8SZhenzhong Duan     }
47233309e8SZhenzhong Duan 
4841d698b8SCédric Le Goater     return vioc->add_window(bcontainer, section, errp);
49233309e8SZhenzhong Duan }
50233309e8SZhenzhong Duan 
vfio_container_del_section_window(VFIOContainerBase * bcontainer,MemoryRegionSection * section)51233309e8SZhenzhong Duan void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
52233309e8SZhenzhong Duan                                        MemoryRegionSection *section)
53233309e8SZhenzhong Duan {
5441d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
5541d698b8SCédric Le Goater 
5641d698b8SCédric Le Goater     if (!vioc->del_window) {
57233309e8SZhenzhong Duan         return;
58233309e8SZhenzhong Duan     }
59233309e8SZhenzhong Duan 
6041d698b8SCédric Le Goater     return vioc->del_window(bcontainer, section);
61233309e8SZhenzhong Duan }
62233309e8SZhenzhong Duan 
vfio_container_set_dirty_page_tracking(VFIOContainerBase * bcontainer,bool start,Error ** errp)63bb424490SEric Auger int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
64836bb308SCédric Le Goater                                            bool start, Error **errp)
65bb424490SEric Auger {
6641d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
6741d698b8SCédric Le Goater 
6836e84d0cSZhenzhong Duan     if (!bcontainer->dirty_pages_supported) {
6936e84d0cSZhenzhong Duan         return 0;
7036e84d0cSZhenzhong Duan     }
7136e84d0cSZhenzhong Duan 
7241d698b8SCédric Le Goater     g_assert(vioc->set_dirty_page_tracking);
7341d698b8SCédric Le Goater     return vioc->set_dirty_page_tracking(bcontainer, start, errp);
74bb424490SEric Auger }
75bb424490SEric Auger 
vfio_container_query_dirty_bitmap(const VFIOContainerBase * bcontainer,VFIOBitmap * vbmap,hwaddr iova,hwaddr size,Error ** errp)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 {
7941d698b8SCédric Le Goater     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
8041d698b8SCédric Le Goater 
8141d698b8SCédric Le Goater     g_assert(vioc->query_dirty_bitmap);
8241d698b8SCédric Le Goater     return vioc->query_dirty_bitmap(bcontainer, vbmap, iova, size,
832da5f9e4SCédric Le Goater                                                errp);
84bb424490SEric Auger }
85bb424490SEric Auger 
copy_iova_range(gconstpointer src,gpointer data)86*3966bca5SEric Auger static gpointer copy_iova_range(gconstpointer src, gpointer data)
87*3966bca5SEric Auger {
88*3966bca5SEric Auger      Range *source = (Range *)src;
89*3966bca5SEric Auger      Range *dest = g_new(Range, 1);
90*3966bca5SEric Auger 
91*3966bca5SEric Auger      range_set_bounds(dest, range_lob(source), range_upb(source));
92*3966bca5SEric Auger      return dest;
93*3966bca5SEric Auger }
94*3966bca5SEric Auger 
vfio_container_get_iova_ranges(const VFIOContainerBase * bcontainer)95*3966bca5SEric Auger GList *vfio_container_get_iova_ranges(const VFIOContainerBase *bcontainer)
96*3966bca5SEric Auger {
97*3966bca5SEric Auger     assert(bcontainer);
98*3966bca5SEric Auger     return g_list_copy_deep(bcontainer->iova_ranges, copy_iova_range, NULL);
99*3966bca5SEric Auger }
100*3966bca5SEric Auger 
vfio_container_instance_finalize(Object * obj)10196b7af43SCédric Le Goater static void vfio_container_instance_finalize(Object *obj)
102ed2f7f80SZhenzhong Duan {
10396b7af43SCédric Le Goater     VFIOContainerBase *bcontainer = VFIO_IOMMU(obj);
104dddf83abSEric Auger     VFIOGuestIOMMU *giommu, *tmp;
105dddf83abSEric Auger 
106e5597063SEric Auger     QLIST_REMOVE(bcontainer, next);
107e5597063SEric Auger 
108dddf83abSEric Auger     QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) {
109dddf83abSEric Auger         memory_region_unregister_iommu_notifier(
110dddf83abSEric Auger                 MEMORY_REGION(giommu->iommu_mr), &giommu->n);
111dddf83abSEric Auger         QLIST_REMOVE(giommu, giommu_next);
112dddf83abSEric Auger         g_free(giommu);
113dddf83abSEric Auger     }
114f79baf8cSZhenzhong Duan 
115f79baf8cSZhenzhong Duan     g_list_free_full(bcontainer->iova_ranges, g_free);
116ed2f7f80SZhenzhong Duan }
117fdaa774eSCédric Le Goater 
vfio_container_instance_init(Object * obj)1182137d2fdSCédric Le Goater static void vfio_container_instance_init(Object *obj)
1192137d2fdSCédric Le Goater {
1202137d2fdSCédric Le Goater     VFIOContainerBase *bcontainer = VFIO_IOMMU(obj);
1212137d2fdSCédric Le Goater 
1222137d2fdSCédric Le Goater     bcontainer->error = NULL;
1232137d2fdSCédric Le Goater     bcontainer->dirty_pages_supported = false;
1242137d2fdSCédric Le Goater     bcontainer->dma_max_mappings = 0;
1252137d2fdSCédric Le Goater     bcontainer->iova_ranges = NULL;
1262137d2fdSCédric Le Goater     QLIST_INIT(&bcontainer->giommu_list);
1272137d2fdSCédric Le Goater     QLIST_INIT(&bcontainer->vrdl_list);
1282137d2fdSCédric Le Goater }
1292137d2fdSCédric Le Goater 
130fdaa774eSCédric Le Goater static const TypeInfo types[] = {
131fdaa774eSCédric Le Goater     {
132fdaa774eSCédric Le Goater         .name = TYPE_VFIO_IOMMU,
133504d297eSCédric Le Goater         .parent = TYPE_OBJECT,
1342137d2fdSCédric Le Goater         .instance_init = vfio_container_instance_init,
13596b7af43SCédric Le Goater         .instance_finalize = vfio_container_instance_finalize,
136504d297eSCédric Le Goater         .instance_size = sizeof(VFIOContainerBase),
137fdaa774eSCédric Le Goater         .class_size = sizeof(VFIOIOMMUClass),
138504d297eSCédric Le Goater         .abstract = true,
139fdaa774eSCédric Le Goater     },
140fdaa774eSCédric Le Goater };
141fdaa774eSCédric Le Goater 
142fdaa774eSCédric Le Goater DEFINE_TYPES(types)
143