mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
vfio/pci: Replace vfio_pci_core_setup_barmap() with vfio_pci_core_get_iomap()
Since "vfio/pci: Set up barmap in vfio_pci_core_enable()", the resource request and iomap for the BARs was performed early, and vfio_pci_core_setup_barmap() just checks those actions succeeded. Move this logic to a new helper that checks success and returns the iomap address, replacing the various bare vdev->barmap[] lookups. This maintains the error behaviour of the previous on-demand vfio_pci_core_setup_barmap() scheme. Signed-off-by: Matt Evans <mattev@meta.com> Link: https://lore.kernel.org/r/20260511145829.2993601-4-mattev@meta.com Signed-off-by: Alex Williamson <alex@shazbot.org>
This commit is contained in:
parent
a6e4e72660
commit
859dc0f625
|
|
@ -61,6 +61,7 @@ struct nvgrace_gpu_pci_core_device {
|
|||
struct mem_region resmem;
|
||||
/* Lock to control device memory kernel mapping */
|
||||
struct mutex remap_lock;
|
||||
void __iomem *bar0_base;
|
||||
bool has_mig_hw_bug;
|
||||
/* GPU has just been reset */
|
||||
bool reset_done;
|
||||
|
|
@ -171,6 +172,7 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
|
|||
struct nvgrace_gpu_pci_core_device *nvdev =
|
||||
container_of(core_vdev, struct nvgrace_gpu_pci_core_device,
|
||||
core_device.vdev);
|
||||
void __iomem *io;
|
||||
int ret;
|
||||
|
||||
ret = vfio_pci_core_enable(vdev);
|
||||
|
|
@ -184,14 +186,14 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
|
|||
|
||||
/*
|
||||
* GPU readiness is checked by reading the BAR0 registers.
|
||||
*
|
||||
* ioremap BAR0 to ensure that the BAR0 mapping is present before
|
||||
* register reads on first fault before establishing any GPU
|
||||
* memory mapping.
|
||||
* The BAR map was just set up by vfio_pci_core_enable(), so
|
||||
* bail early if that wasn't successful:
|
||||
*/
|
||||
ret = vfio_pci_core_setup_barmap(vdev, 0);
|
||||
if (ret)
|
||||
io = vfio_pci_core_get_iomap(vdev, 0);
|
||||
if (IS_ERR(io)) {
|
||||
ret = PTR_ERR(io);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (nvdev->resmem.memlength) {
|
||||
ret = nvgrace_gpu_vfio_pci_register_pfn_range(core_vdev, &nvdev->resmem);
|
||||
|
|
@ -204,6 +206,8 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
|
|||
goto register_mem_failed;
|
||||
|
||||
vfio_pci_core_finish_enable(vdev);
|
||||
nvdev->bar0_base = io;
|
||||
|
||||
return 0;
|
||||
|
||||
register_mem_failed:
|
||||
|
|
@ -220,6 +224,8 @@ static void nvgrace_gpu_close_device(struct vfio_device *core_vdev)
|
|||
container_of(core_vdev, struct nvgrace_gpu_pci_core_device,
|
||||
core_device.vdev);
|
||||
|
||||
nvdev->bar0_base = NULL;
|
||||
|
||||
if (nvdev->resmem.memlength)
|
||||
unregister_pfn_address_space(&nvdev->resmem.pfn_address_space);
|
||||
|
||||
|
|
@ -275,7 +281,7 @@ nvgrace_gpu_check_device_ready(struct nvgrace_gpu_pci_core_device *nvdev)
|
|||
if (!__vfio_pci_memory_enabled(vdev))
|
||||
return -EIO;
|
||||
|
||||
ret = nvgrace_gpu_wait_device_ready(vdev->barmap[0]);
|
||||
ret = nvgrace_gpu_wait_device_ready(nvdev->bar0_base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -1762,7 +1762,7 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
|
|||
struct pci_dev *pdev = vdev->pdev;
|
||||
unsigned int index;
|
||||
u64 phys_len, req_len, pgoff, req_start;
|
||||
int ret;
|
||||
void __iomem *bar_io;
|
||||
|
||||
index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
|
||||
|
||||
|
|
@ -1796,12 +1796,11 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
|
|||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Even though we don't make use of the barmap for the mmap,
|
||||
* we need to request the region and the barmap tracks that.
|
||||
* Ensure the BAR resource region is reserved for use.
|
||||
*/
|
||||
ret = vfio_pci_core_setup_barmap(vdev, index);
|
||||
if (ret)
|
||||
return ret;
|
||||
bar_io = vfio_pci_core_get_iomap(vdev, index);
|
||||
if (IS_ERR(bar_io))
|
||||
return PTR_ERR(bar_io);
|
||||
|
||||
vma->vm_private_data = vdev;
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
|
|||
* else. Check that PCI resources have been claimed for it.
|
||||
*/
|
||||
if (get_dma_buf.region_index >= VFIO_PCI_ROM_REGION_INDEX ||
|
||||
vfio_pci_core_setup_barmap(vdev, get_dma_buf.region_index))
|
||||
IS_ERR(vfio_pci_core_get_iomap(vdev, get_dma_buf.region_index)))
|
||||
return -ENODEV;
|
||||
|
||||
dma_ranges = memdup_array_user(&arg->dma_ranges, get_dma_buf.nr_ranges,
|
||||
|
|
|
|||
|
|
@ -198,19 +198,6 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_pci_core_do_io_rw);
|
||||
|
||||
/*
|
||||
* The barmap is set up in vfio_pci_core_enable(). Callers use this
|
||||
* function to check that the BAR resources are requested or that the
|
||||
* pci_iomap() was done.
|
||||
*/
|
||||
int vfio_pci_core_setup_barmap(struct vfio_pci_core_device *vdev, int bar)
|
||||
{
|
||||
if (IS_ERR(vdev->barmap[bar]))
|
||||
return PTR_ERR(vdev->barmap[bar]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_pci_core_setup_barmap);
|
||||
|
||||
ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
||||
size_t count, loff_t *ppos, bool iswrite)
|
||||
{
|
||||
|
|
@ -262,13 +249,11 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
|||
*/
|
||||
max_width = VFIO_PCI_IO_WIDTH_4;
|
||||
} else {
|
||||
int ret = vfio_pci_core_setup_barmap(vdev, bar);
|
||||
if (ret) {
|
||||
done = ret;
|
||||
io = vfio_pci_core_get_iomap(vdev, bar);
|
||||
if (IS_ERR(io)) {
|
||||
done = PTR_ERR(io);
|
||||
goto out;
|
||||
}
|
||||
|
||||
io = vdev->barmap[bar];
|
||||
}
|
||||
|
||||
if (bar == vdev->msix_bar) {
|
||||
|
|
@ -423,6 +408,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
|
|||
loff_t pos = offset & VFIO_PCI_OFFSET_MASK;
|
||||
int ret, bar = VFIO_PCI_OFFSET_TO_INDEX(offset);
|
||||
struct vfio_pci_ioeventfd *ioeventfd;
|
||||
void __iomem *io;
|
||||
|
||||
/* Only support ioeventfds into BARs */
|
||||
if (bar > VFIO_PCI_BAR5_REGION_INDEX)
|
||||
|
|
@ -440,9 +426,9 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
|
|||
if (count == 8)
|
||||
return -EINVAL;
|
||||
|
||||
ret = vfio_pci_core_setup_barmap(vdev, bar);
|
||||
if (ret)
|
||||
return ret;
|
||||
io = vfio_pci_core_get_iomap(vdev, bar);
|
||||
if (IS_ERR(io))
|
||||
return PTR_ERR(io);
|
||||
|
||||
mutex_lock(&vdev->ioeventfds_lock);
|
||||
|
||||
|
|
@ -479,7 +465,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
|
|||
}
|
||||
|
||||
ioeventfd->vdev = vdev;
|
||||
ioeventfd->addr = vdev->barmap[bar] + pos;
|
||||
ioeventfd->addr = io + pos;
|
||||
ioeventfd->data = data;
|
||||
ioeventfd->pos = pos;
|
||||
ioeventfd->bar = bar;
|
||||
|
|
|
|||
|
|
@ -298,19 +298,18 @@ int virtiovf_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
|
|||
static int virtiovf_set_notify_addr(struct virtiovf_pci_core_device *virtvdev)
|
||||
{
|
||||
struct vfio_pci_core_device *core_device = &virtvdev->core_device;
|
||||
int ret;
|
||||
void __iomem *io;
|
||||
|
||||
/*
|
||||
* Setup the BAR where the 'notify' exists to be used by vfio as well
|
||||
* This will let us mmap it only once and use it when needed.
|
||||
*/
|
||||
ret = vfio_pci_core_setup_barmap(core_device,
|
||||
virtvdev->notify_bar);
|
||||
if (ret)
|
||||
return ret;
|
||||
io = vfio_pci_core_get_iomap(core_device,
|
||||
virtvdev->notify_bar);
|
||||
if (IS_ERR(io))
|
||||
return PTR_ERR(io);
|
||||
|
||||
virtvdev->notify_addr = core_device->barmap[virtvdev->notify_bar] +
|
||||
virtvdev->notify_offset;
|
||||
virtvdev->notify_addr = io + virtvdev->notify_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,6 @@ int vfio_pci_core_match_token_uuid(struct vfio_device *core_vdev,
|
|||
int vfio_pci_core_enable(struct vfio_pci_core_device *vdev);
|
||||
void vfio_pci_core_disable(struct vfio_pci_core_device *vdev);
|
||||
void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev);
|
||||
int vfio_pci_core_setup_barmap(struct vfio_pci_core_device *vdev, int bar);
|
||||
pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
|
||||
pci_channel_state_t state);
|
||||
ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
|
||||
|
|
@ -234,6 +233,25 @@ static inline bool is_aligned_for_order(struct vm_area_struct *vma,
|
|||
!IS_ALIGNED(pfn, 1 << order)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a BAR's iomap base or an ERR_PTR() if, for example, the
|
||||
* BAR isn't valid, its resource wasn't acquired, or its iomap
|
||||
* failed. This shall only be used after vfio_pci_core_enable()
|
||||
* has set up the BAR maps and before vfio_pci_core_disable()
|
||||
* tears them down.
|
||||
*/
|
||||
static inline void __iomem __must_check *
|
||||
vfio_pci_core_get_iomap(struct vfio_pci_core_device *vdev, unsigned int bar)
|
||||
{
|
||||
if (WARN_ON_ONCE(bar >= PCI_STD_NUM_BARS))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (WARN_ON_ONCE(!vdev->barmap[bar]))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return vdev->barmap[bar];
|
||||
}
|
||||
|
||||
int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,
|
||||
struct phys_vec *phys);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user