pci_map_rom/pci_get_rom_size() performs memory access in the ROM. In case the Memory Space accesses were disabled, readw() is likely to crash the host with a synchronous external abort (aarch64). In case memory accesses were disabled, re-enable them before the call and disable them back again just after. Signed-off-by: Eric Auger <eric.auger@xxxxxxxxxx> --- drivers/vfio/pci/vfio_pci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index ff60bd1ea587..96b8bbd909d7 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -706,8 +706,10 @@ static long vfio_pci_ioctl(void *device_data, break; case VFIO_PCI_ROM_REGION_INDEX: { + bool mem_access_disabled; void __iomem *io; size_t size; + u16 cmd; info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); info.flags = 0; @@ -723,6 +725,13 @@ static long vfio_pci_ioctl(void *device_data, break; } + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + mem_access_disabled = !(cmd & PCI_COMMAND_MEMORY); + if (mem_access_disabled) { + cmd |= PCI_COMMAND_MEMORY; + pci_write_config_word(pdev, PCI_COMMAND, cmd); + } + /* Is it really there? */ io = pci_map_rom(pdev, &size); if (!io || !size) { @@ -731,6 +740,11 @@ static long vfio_pci_ioctl(void *device_data, } pci_unmap_rom(pdev, io); + if (mem_access_disabled) { + cmd &= ~PCI_COMMAND_MEMORY; + pci_write_config_word(pdev, PCI_COMMAND, cmd); + } + info.flags = VFIO_REGION_INFO_FLAG_READ; break; } -- 2.20.1