Commit a13b6459 authored by Alex Williamson's avatar Alex Williamson

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: default avatarAlex Williamson <alex.williamson@redhat.com>
parent f572a960
...@@ -609,8 +609,14 @@ static long vfio_pci_ioctl(void *device_data, ...@@ -609,8 +609,14 @@ static long vfio_pci_ioctl(void *device_data,
/* Report the BAR size, not the ROM size */ /* Report the BAR size, not the ROM size */
info.size = pci_resource_len(pdev, info.index); info.size = pci_resource_len(pdev, info.index);
if (!info.size) if (!info.size) {
break; /* 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? */ /* Is it really there? */
io = pci_map_rom(pdev, &size); io = pci_map_rom(pdev, &size);
......
...@@ -475,14 +475,19 @@ static void vfio_bar_fixup(struct vfio_pci_device *vdev) ...@@ -475,14 +475,19 @@ static void vfio_bar_fixup(struct vfio_pci_device *vdev)
bar = (__le32 *)&vdev->vconfig[PCI_ROM_ADDRESS]; bar = (__le32 *)&vdev->vconfig[PCI_ROM_ADDRESS];
/* /*
* NB. we expose the actual BAR size here, regardless of whether * NB. REGION_INFO will have reported zero size if we weren't able
* we can read it. When we report the REGION_INFO for the ROM * to read the ROM, but we still return the actual BAR size here if
* we report what PCI tells us is the actual ROM size. * it exists (or the shadow ROM space).
*/ */
if (pci_resource_start(pdev, PCI_ROM_RESOURCE)) { if (pci_resource_start(pdev, PCI_ROM_RESOURCE)) {
mask = ~(pci_resource_len(pdev, PCI_ROM_RESOURCE) - 1); mask = ~(pci_resource_len(pdev, PCI_ROM_RESOURCE) - 1);
mask |= PCI_ROM_ADDRESS_ENABLE; mask |= PCI_ROM_ADDRESS_ENABLE;
*bar &= cpu_to_le32((u32)mask); *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 } else
*bar = 0; *bar = 0;
......
...@@ -124,11 +124,14 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf, ...@@ -124,11 +124,14 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
void __iomem *io; void __iomem *io;
ssize_t done; 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; return -EINVAL;
end = pci_resource_len(pdev, bar);
if (pos >= end) if (pos >= end)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment