| From cfc4b7072b27f6fb4a380a4414d37cc308dd4157 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 15 Feb 2019 17:16:06 +0100 |
| Subject: vfio_pci: Enable memory accesses before calling pci_map_rom |
| |
| From: Eric Auger <eric.auger@redhat.com> |
| |
| [ Upstream commit 0cfd027be1d6def4a462cdc180c055143af24069 ] |
| |
| 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 trigger a synchronous external abort on some platforms. |
| |
| In case memory accesses were disabled, re-enable them before the |
| call and disable them back again just after. |
| |
| Fixes: 89e1f7d4c66d ("vfio: Add PCI device driver") |
| Signed-off-by: Eric Auger <eric.auger@redhat.com> |
| Suggested-by: Alex Williamson <alex.williamson@redhat.com> |
| Signed-off-by: Alex Williamson <alex.williamson@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/vfio/pci/vfio_pci.c | 19 ++++++++++++++----- |
| 1 file changed, 14 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c |
| index da3f0ed18c769..c94167d871789 100644 |
| --- a/drivers/vfio/pci/vfio_pci.c |
| +++ b/drivers/vfio/pci/vfio_pci.c |
| @@ -729,6 +729,7 @@ static long vfio_pci_ioctl(void *device_data, |
| { |
| void __iomem *io; |
| size_t size; |
| + u16 orig_cmd; |
| |
| info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); |
| info.flags = 0; |
| @@ -744,15 +745,23 @@ static long vfio_pci_ioctl(void *device_data, |
| break; |
| } |
| |
| - /* Is it really there? */ |
| + /* |
| + * Is it really there? Enable memory decode for |
| + * implicit access in pci_map_rom(). |
| + */ |
| + pci_read_config_word(pdev, PCI_COMMAND, &orig_cmd); |
| + pci_write_config_word(pdev, PCI_COMMAND, |
| + orig_cmd | PCI_COMMAND_MEMORY); |
| + |
| io = pci_map_rom(pdev, &size); |
| - if (!io || !size) { |
| + if (io) { |
| + info.flags = VFIO_REGION_INFO_FLAG_READ; |
| + pci_unmap_rom(pdev, io); |
| + } else { |
| info.size = 0; |
| - break; |
| } |
| - pci_unmap_rom(pdev, io); |
| |
| - info.flags = VFIO_REGION_INFO_FLAG_READ; |
| + pci_write_config_word(pdev, PCI_COMMAND, orig_cmd); |
| break; |
| } |
| case VFIO_PCI_VGA_REGION_INDEX: |
| -- |
| 2.20.1 |
| |