Lines Matching +full:gpa +full:- +full:1

8  * the COPYING file in the top-level directory.
18 #include "exec/address-spaces.h"
20 #include "hw/vfio/vfio-common.h"
23 #include "qemu/error-report.h"
37 if (memory_region_is_iommu(section->mr)) { in vfio_prereg_listener_skipped_section()
41 return !memory_region_is_ram(section->mr) || in vfio_prereg_listener_skipped_section()
42 memory_region_is_ram_device(section->mr); in vfio_prereg_listener_skipped_section()
45 static void *vfio_prereg_gpa_to_vaddr(MemoryRegionSection *section, hwaddr gpa) in vfio_prereg_gpa_to_vaddr() argument
47 return memory_region_get_ram_ptr(section->mr) + in vfio_prereg_gpa_to_vaddr()
48 section->offset_within_region + in vfio_prereg_gpa_to_vaddr()
49 (gpa - section->offset_within_address_space); in vfio_prereg_gpa_to_vaddr()
57 VFIOContainer *container = &scontainer->container; in vfio_prereg_listener_region_add()
58 VFIOContainerBase *bcontainer = &container->bcontainer; in vfio_prereg_listener_region_add()
59 const hwaddr gpa = section->offset_within_address_space; in vfio_prereg_listener_region_add() local
70 section->offset_within_address_space, in vfio_prereg_listener_region_add()
71 section->offset_within_address_space + in vfio_prereg_listener_region_add()
72 int128_get64(int128_sub(section->size, int128_one()))); in vfio_prereg_listener_region_add()
76 if (unlikely((section->offset_within_address_space & ~page_mask) || in vfio_prereg_listener_region_add()
77 (section->offset_within_region & ~page_mask) || in vfio_prereg_listener_region_add()
78 (int128_get64(section->size) & ~page_mask))) { in vfio_prereg_listener_region_add()
83 end = section->offset_within_address_space + int128_get64(section->size); in vfio_prereg_listener_region_add()
84 if (gpa >= end) { in vfio_prereg_listener_region_add()
88 memory_region_ref(section->mr); in vfio_prereg_listener_region_add()
90 reg.vaddr = (uintptr_t) vfio_prereg_gpa_to_vaddr(section, gpa); in vfio_prereg_listener_region_add()
91 reg.size = end - gpa; in vfio_prereg_listener_region_add()
93 ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_REGISTER_MEMORY, &reg); in vfio_prereg_listener_region_add()
94 trace_vfio_prereg_register(reg.vaddr, reg.size, ret ? -errno : 0); in vfio_prereg_listener_region_add()
101 if (!bcontainer->initialized) { in vfio_prereg_listener_region_add()
102 if (!bcontainer->error) { in vfio_prereg_listener_region_add()
103 error_setg_errno(&bcontainer->error, -ret, in vfio_prereg_listener_region_add()
117 VFIOContainer *container = &scontainer->container; in vfio_prereg_listener_region_del()
118 const hwaddr gpa = section->offset_within_address_space; in vfio_prereg_listener_region_del() local
129 section->offset_within_address_space, in vfio_prereg_listener_region_del()
130 section->offset_within_address_space + in vfio_prereg_listener_region_del()
131 int128_get64(int128_sub(section->size, int128_one()))); in vfio_prereg_listener_region_del()
135 if (unlikely((section->offset_within_address_space & ~page_mask) || in vfio_prereg_listener_region_del()
136 (section->offset_within_region & ~page_mask) || in vfio_prereg_listener_region_del()
137 (int128_get64(section->size) & ~page_mask))) { in vfio_prereg_listener_region_del()
142 end = section->offset_within_address_space + int128_get64(section->size); in vfio_prereg_listener_region_del()
143 if (gpa >= end) { in vfio_prereg_listener_region_del()
147 reg.vaddr = (uintptr_t) vfio_prereg_gpa_to_vaddr(section, gpa); in vfio_prereg_listener_region_del()
148 reg.size = end - gpa; in vfio_prereg_listener_region_del()
150 ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY, &reg); in vfio_prereg_listener_region_del()
151 trace_vfio_prereg_unregister(reg.vaddr, reg.size, ret ? -errno : 0); in vfio_prereg_listener_region_del()
155 .name = "vfio-pre-reg",
165 QLIST_FOREACH(hostwin, &scontainer->hostwin_list, hostwin_next) { in vfio_host_win_add()
166 if (ranges_overlap(hostwin->min_iova, in vfio_host_win_add()
167 hostwin->max_iova - hostwin->min_iova + 1, in vfio_host_win_add()
169 max_iova - min_iova + 1)) { in vfio_host_win_add()
176 hostwin->min_iova = min_iova; in vfio_host_win_add()
177 hostwin->max_iova = max_iova; in vfio_host_win_add()
178 hostwin->iova_pgsizes = iova_pgsizes; in vfio_host_win_add()
179 QLIST_INSERT_HEAD(&scontainer->hostwin_list, hostwin, hostwin_next); in vfio_host_win_add()
187 QLIST_FOREACH(hostwin, &scontainer->hostwin_list, hostwin_next) { in vfio_host_win_del()
188 if (hostwin->min_iova == min_iova && hostwin->max_iova == max_iova) { in vfio_host_win_del()
195 return -1; in vfio_host_win_del()
204 QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { in vfio_find_hostwin()
205 if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { in vfio_find_hostwin()
223 ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_REMOVE, &remove); in vfio_spapr_remove_window()
227 return -errno; in vfio_spapr_remove_window()
240 VFIOContainerBase *bcontainer = &container->bcontainer; in vfio_spapr_create_window()
241 IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); in vfio_spapr_create_window()
254 pgmask = bcontainer->pgsizes & (pagesize | (pagesize - 1)); in vfio_spapr_create_window()
255 pagesize = pgmask ? (1ULL << (63 - clz64(pgmask))) : 0; in vfio_spapr_create_window()
260 bcontainer->pgsizes); in vfio_spapr_create_window()
261 return -EINVAL; in vfio_spapr_create_window()
270 create.window_size = int128_get64(section->size); in vfio_spapr_create_window()
299 max_levels = (64 - create.page_shift) / ctz64(qemu_real_host_page_size()); in vfio_spapr_create_window()
301 ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create); in vfio_spapr_create_window()
308 return -errno; in vfio_spapr_create_window()
311 if (create.start_addr != section->offset_within_address_space) { in vfio_spapr_create_window()
315 section->offset_within_address_space, in vfio_spapr_create_window()
317 return -EINVAL; in vfio_spapr_create_window()
346 if (container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { in vfio_spapr_container_add_section_window()
349 iova = section->offset_within_address_space; in vfio_spapr_container_add_section_window()
350 end = iova + int128_get64(section->size) - 1; in vfio_spapr_container_add_section_window()
361 if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) { in vfio_spapr_container_add_section_window()
366 QLIST_FOREACH(hostwin, &scontainer->hostwin_list, hostwin_next) { in vfio_spapr_container_add_section_window()
367 if (ranges_overlap(hostwin->min_iova, in vfio_spapr_container_add_section_window()
368 hostwin->max_iova - hostwin->min_iova + 1, in vfio_spapr_container_add_section_window()
369 section->offset_within_address_space, in vfio_spapr_container_add_section_window()
370 int128_get64(section->size))) { in vfio_spapr_container_add_section_window()
374 section->offset_within_address_space, in vfio_spapr_container_add_section_window()
375 section->offset_within_address_space + in vfio_spapr_container_add_section_window()
376 int128_get64(section->size) - 1, in vfio_spapr_container_add_section_window()
377 hostwin->min_iova, hostwin->max_iova); in vfio_spapr_container_add_section_window()
384 error_setg_errno(errp, -ret, "Failed to create SPAPR window"); in vfio_spapr_container_add_section_window()
388 vfio_host_win_add(scontainer, section->offset_within_address_space, in vfio_spapr_container_add_section_window()
389 section->offset_within_address_space + in vfio_spapr_container_add_section_window()
390 int128_get64(section->size) - 1, pgsize); in vfio_spapr_container_add_section_window()
394 IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); in vfio_spapr_container_add_section_window()
404 QLIST_FOREACH(group, &container->group_list, container_next) { in vfio_spapr_container_add_section_window()
405 param.groupfd = group->fd; in vfio_spapr_container_add_section_window()
430 if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) { in vfio_spapr_container_del_section_window()
435 section->offset_within_address_space); in vfio_spapr_container_del_section_window()
437 section->offset_within_address_space, in vfio_spapr_container_del_section_window()
438 section->offset_within_address_space + in vfio_spapr_container_del_section_window()
439 int128_get64(section->size) - 1) < 0) { in vfio_spapr_container_del_section_window()
441 __func__, section->offset_within_address_space); in vfio_spapr_container_del_section_window()
453 if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { in vfio_spapr_container_release()
454 memory_listener_unregister(&scontainer->prereg_listener); in vfio_spapr_container_release()
456 QLIST_FOREACH_SAFE(hostwin, &scontainer->hostwin_list, hostwin_next, in vfio_spapr_container_release()
471 bool v2 = container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU; in vfio_spapr_container_setup()
472 int ret, fd = container->fd; in vfio_spapr_container_setup()
474 QLIST_INIT(&scontainer->hostwin_list); in vfio_spapr_container_setup()
488 scontainer->prereg_listener = vfio_prereg_listener; in vfio_spapr_container_setup()
490 memory_listener_register(&scontainer->prereg_listener, in vfio_spapr_container_setup()
492 if (bcontainer->error) { in vfio_spapr_container_setup()
493 error_propagate_prepend(errp, bcontainer->error, in vfio_spapr_container_setup()
508 bcontainer->pgsizes = info.ddw.pgsizes; in vfio_spapr_container_setup()
517 error_setg_errno(errp, -ret, in vfio_spapr_container_setup()
523 bcontainer->pgsizes = 0x1000; in vfio_spapr_container_setup()
526 info.dma32_window_size - 1, in vfio_spapr_container_setup()
534 memory_listener_unregister(&scontainer->prereg_listener); in vfio_spapr_container_setup()
543 vioc->add_window = vfio_spapr_container_add_section_window; in vfio_iommu_spapr_class_init()
544 vioc->del_window = vfio_spapr_container_del_section_window; in vfio_iommu_spapr_class_init()
545 vioc->release = vfio_spapr_container_release; in vfio_iommu_spapr_class_init()
546 vioc->setup = vfio_spapr_container_setup; in vfio_iommu_spapr_class_init()