xref: /openbmc/qemu/hw/vfio/container-base.c (revision 09181a8e)
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 
74*09181a8eSCédric Le Goater void vfio_container_init(VFIOContainerBase *bcontainer,
75fdaa774eSCédric Le Goater                          const VFIOIOMMUClass *ops)
76ed2f7f80SZhenzhong Duan {
77ed2f7f80SZhenzhong Duan     bcontainer->ops = ops;
78c7b313d3SEric Auger     bcontainer->error = NULL;
79bb424490SEric Auger     bcontainer->dirty_pages_supported = false;
807ab1cb74SEric Auger     bcontainer->dma_max_mappings = 0;
81f79baf8cSZhenzhong Duan     bcontainer->iova_ranges = NULL;
82dddf83abSEric Auger     QLIST_INIT(&bcontainer->giommu_list);
83dc74a4b0SZhenzhong Duan     QLIST_INIT(&bcontainer->vrdl_list);
84ed2f7f80SZhenzhong Duan }
85ed2f7f80SZhenzhong Duan 
86ed2f7f80SZhenzhong Duan void vfio_container_destroy(VFIOContainerBase *bcontainer)
87ed2f7f80SZhenzhong Duan {
88dddf83abSEric Auger     VFIOGuestIOMMU *giommu, *tmp;
89dddf83abSEric Auger 
90e5597063SEric Auger     QLIST_REMOVE(bcontainer, next);
91e5597063SEric Auger 
92dddf83abSEric Auger     QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) {
93dddf83abSEric Auger         memory_region_unregister_iommu_notifier(
94dddf83abSEric Auger                 MEMORY_REGION(giommu->iommu_mr), &giommu->n);
95dddf83abSEric Auger         QLIST_REMOVE(giommu, giommu_next);
96dddf83abSEric Auger         g_free(giommu);
97dddf83abSEric Auger     }
98f79baf8cSZhenzhong Duan 
99f79baf8cSZhenzhong Duan     g_list_free_full(bcontainer->iova_ranges, g_free);
100ed2f7f80SZhenzhong Duan }
101fdaa774eSCédric Le Goater 
102fdaa774eSCédric Le Goater static const TypeInfo types[] = {
103fdaa774eSCédric Le Goater     {
104fdaa774eSCédric Le Goater         .name = TYPE_VFIO_IOMMU,
105fdaa774eSCédric Le Goater         .parent = TYPE_INTERFACE,
106fdaa774eSCédric Le Goater         .class_size = sizeof(VFIOIOMMUClass),
107fdaa774eSCédric Le Goater     },
108fdaa774eSCédric Le Goater };
109fdaa774eSCédric Le Goater 
110fdaa774eSCédric Le Goater DEFINE_TYPES(types)
111