Skip to content

Commit ebfa440

Browse files
committed
vfio/pci: Fix SR-IOV VF handling with MMIO blocking
SR-IOV VFs do not implement the memory enable bit of the command register, therefore this bit is not set in config space after pci_enable_device(). This leads to an unintended difference between PF and VF in hand-off state to the user. We can correct this by setting the initial value of the memory enable bit in our virtualized config space. There's really no need however to ever fault a user on a VF though as this would only indicate an error in the user's management of the enable bit, versus a PF where the same access could trigger hardware faults. Fixes: abafbc5 ("vfio-pci: Invalidate mmaps and block MMIO access on disabled memory") Signed-off-by: Alex Williamson <[email protected]>
1 parent f751820 commit ebfa440

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

drivers/vfio/pci/vfio_pci_config.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,15 @@ static inline void p_setd(struct perm_bits *p, int off, u32 virt, u32 write)
398398
/* Caller should hold memory_lock semaphore */
399399
bool __vfio_pci_memory_enabled(struct vfio_pci_device *vdev)
400400
{
401+
struct pci_dev *pdev = vdev->pdev;
401402
u16 cmd = le16_to_cpu(*(__le16 *)&vdev->vconfig[PCI_COMMAND]);
402403

403-
return cmd & PCI_COMMAND_MEMORY;
404+
/*
405+
* SR-IOV VF memory enable is handled by the MSE bit in the
406+
* PF SR-IOV capability, there's therefore no need to trigger
407+
* faults based on the virtual value.
408+
*/
409+
return pdev->is_virtfn || (cmd & PCI_COMMAND_MEMORY);
404410
}
405411

406412
/*
@@ -1728,6 +1734,15 @@ int vfio_config_init(struct vfio_pci_device *vdev)
17281734
vconfig[PCI_INTERRUPT_PIN]);
17291735

17301736
vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
1737+
1738+
/*
1739+
* VFs do no implement the memory enable bit of the COMMAND
1740+
* register therefore we'll not have it set in our initial
1741+
* copy of config space after pci_enable_device(). For
1742+
* consistency with PFs, set the virtual enable bit here.
1743+
*/
1744+
*(__le16 *)&vconfig[PCI_COMMAND] |=
1745+
cpu_to_le16(PCI_COMMAND_MEMORY);
17311746
}
17321747

17331748
if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)

0 commit comments

Comments
 (0)