vfio/pci: Expose shadow ROM as PCI option ROM
Integrated graphics may have their ROM shadowed at 0xc0000 rather than implement a PCI option ROM. Make this ROM appear to the user using the ROM BAR. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
f572a960a1
commit
a13b645917
|
@ -609,8 +609,14 @@ static long vfio_pci_ioctl(void *device_data,
|
|||
|
||||
/* Report the BAR size, not the ROM size */
|
||||
info.size = pci_resource_len(pdev, info.index);
|
||||
if (!info.size)
|
||||
break;
|
||||
if (!info.size) {
|
||||
/* Shadow ROMs appear as PCI option ROMs */
|
||||
if (pdev->resource[PCI_ROM_RESOURCE].flags &
|
||||
IORESOURCE_ROM_SHADOW)
|
||||
info.size = 0x20000;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* Is it really there? */
|
||||
io = pci_map_rom(pdev, &size);
|
||||
|
|
|
@ -475,14 +475,19 @@ static void vfio_bar_fixup(struct vfio_pci_device *vdev)
|
|||
bar = (__le32 *)&vdev->vconfig[PCI_ROM_ADDRESS];
|
||||
|
||||
/*
|
||||
* NB. we expose the actual BAR size here, regardless of whether
|
||||
* we can read it. When we report the REGION_INFO for the ROM
|
||||
* we report what PCI tells us is the actual ROM size.
|
||||
* NB. REGION_INFO will have reported zero size if we weren't able
|
||||
* to read the ROM, but we still return the actual BAR size here if
|
||||
* it exists (or the shadow ROM space).
|
||||
*/
|
||||
if (pci_resource_start(pdev, PCI_ROM_RESOURCE)) {
|
||||
mask = ~(pci_resource_len(pdev, PCI_ROM_RESOURCE) - 1);
|
||||
mask |= PCI_ROM_ADDRESS_ENABLE;
|
||||
*bar &= cpu_to_le32((u32)mask);
|
||||
} else if (pdev->resource[PCI_ROM_RESOURCE].flags &
|
||||
IORESOURCE_ROM_SHADOW) {
|
||||
mask = ~(0x20000 - 1);
|
||||
mask |= PCI_ROM_ADDRESS_ENABLE;
|
||||
*bar &= cpu_to_le32((u32)mask);
|
||||
} else
|
||||
*bar = 0;
|
||||
|
||||
|
|
|
@ -124,11 +124,14 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
|
|||
void __iomem *io;
|
||||
ssize_t done;
|
||||
|
||||
if (!pci_resource_start(pdev, bar))
|
||||
if (pci_resource_start(pdev, bar))
|
||||
end = pci_resource_len(pdev, bar);
|
||||
else if (bar == PCI_ROM_RESOURCE &&
|
||||
pdev->resource[bar].flags & IORESOURCE_ROM_SHADOW)
|
||||
end = 0x20000;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
end = pci_resource_len(pdev, bar);
|
||||
|
||||
if (pos >= end)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
Loading…
Reference in a new issue