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> --- v1 -> v2: - also re-enable in case of error --- drivers/vfio/pci/vfio_pci.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index ff60bd1ea587..721aa55424a4 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,15 +725,28 @@ 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) { info.size = 0; - break; + goto rom_info_out; } pci_unmap_rom(pdev, io); info.flags = VFIO_REGION_INFO_FLAG_READ; +rom_info_out: + if (mem_access_disabled) { + cmd &= ~PCI_COMMAND_MEMORY; + pci_write_config_word(pdev, PCI_COMMAND, cmd); + } + break; } case VFIO_PCI_VGA_REGION_INDEX: -- 2.20.1