Commit ebfa440c authored by Alex Williamson's avatar Alex Williamson

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: abafbc55 ("vfio-pci: Invalidate mmaps and block MMIO access on disabled memory")
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent f751820b
...@@ -398,9 +398,15 @@ static inline void p_setd(struct perm_bits *p, int off, u32 virt, u32 write) ...@@ -398,9 +398,15 @@ static inline void p_setd(struct perm_bits *p, int off, u32 virt, u32 write)
/* Caller should hold memory_lock semaphore */ /* Caller should hold memory_lock semaphore */
bool __vfio_pci_memory_enabled(struct vfio_pci_device *vdev) bool __vfio_pci_memory_enabled(struct vfio_pci_device *vdev)
{ {
struct pci_dev *pdev = vdev->pdev;
u16 cmd = le16_to_cpu(*(__le16 *)&vdev->vconfig[PCI_COMMAND]); u16 cmd = le16_to_cpu(*(__le16 *)&vdev->vconfig[PCI_COMMAND]);
return cmd & PCI_COMMAND_MEMORY; /*
* SR-IOV VF memory enable is handled by the MSE bit in the
* PF SR-IOV capability, there's therefore no need to trigger
* faults based on the virtual value.
*/
return pdev->is_virtfn || (cmd & PCI_COMMAND_MEMORY);
} }
/* /*
...@@ -1728,6 +1734,15 @@ int vfio_config_init(struct vfio_pci_device *vdev) ...@@ -1728,6 +1734,15 @@ int vfio_config_init(struct vfio_pci_device *vdev)
vconfig[PCI_INTERRUPT_PIN]); vconfig[PCI_INTERRUPT_PIN]);
vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */ vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
/*
* VFs do no implement the memory enable bit of the COMMAND
* register therefore we'll not have it set in our initial
* copy of config space after pci_enable_device(). For
* consistency with PFs, set the virtual enable bit here.
*/
*(__le16 *)&vconfig[PCI_COMMAND] |=
cpu_to_le16(PCI_COMMAND_MEMORY);
} }
if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx) if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)
......
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