Hi Jean-Philippe, One comment below. Jean-Philippe Brucker <jean-philippe.brucker@xxxxxxx> writes: > In some cases device regions don't support mmap. They can still be made > available to the guest by trapping all accesses and forwarding reads or > writes to VFIO. Such regions may be: > > * PCI I/O port BARs. > * Sub-page regions, for example a 4kB region on a host with 64k pages. > * Similarly, sparse mmap regions. For example when VFIO allows to mmap > fragments of a PCI BAR and forbids accessing things like MSI-X tables. > We don't support the sparse capability at the moment, so trap these > regions instead (if VFIO rejects the mmap). > > Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@xxxxxxx> > --- > v3->v4: new. > --- > include/kvm/vfio.h | 3 + > vfio/core.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++------ > vfio/pci.c | 41 +++++++------ > 3 files changed, 176 insertions(+), 33 deletions(-) > [...] > diff --git a/vfio/pci.c b/vfio/pci.c > index 698b19582143..9c3ef2f1a373 100644 > --- a/vfio/pci.c > +++ b/vfio/pci.c [...] > @@ -785,6 +788,7 @@ static int vfio_pci_configure_bar(struct kvm *kvm, struct vfio_device *vdev, > size_t nr) > { > int ret; > + u32 bar; > size_t map_size; > struct vfio_pci_device *pdev = &vdev->pci; > struct vfio_region *region = &vdev->regions[nr]; > @@ -792,6 +796,10 @@ static int vfio_pci_configure_bar(struct kvm *kvm, struct vfio_device *vdev, > if (nr >= vdev->info.num_regions) > return 0; > > + bar = pdev->hdr.bar[nr]; > + > + region->vdev = vdev; > + region->is_ioport = !!(bar & PCI_BASE_ADDRESS_SPACE_IO); > region->info = (struct vfio_region_info) { > .argsz = sizeof(*region), sizeof(region->info)? Otherwise the patch looks good. Thanks, Punit > .index = nr, > @@ -819,14 +827,13 @@ static int vfio_pci_configure_bar(struct kvm *kvm, struct vfio_device *vdev, > } > } > > - /* Grab some MMIO space in the guest */ > - map_size = ALIGN(region->info.size, PAGE_SIZE); > - region->guest_phys_addr = pci_get_io_space_block(map_size); > + if (!region->is_ioport) { > + /* Grab some MMIO space in the guest */ > + map_size = ALIGN(region->info.size, PAGE_SIZE); > + region->guest_phys_addr = pci_get_io_space_block(map_size); > + } > > - /* > - * Map the BARs into the guest. We'll later need to update > - * configuration space to reflect our allocation. > - */ > + /* Map the BARs into the guest or setup a trap region. */ > ret = vfio_map_region(kvm, vdev, region); > if (ret) > return ret;