Skip to content

Commit 0c86e76

Browse files
committed
Merge tag 'vfio-v4.20-rc1.v2' of git://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - EDID interfaces for vfio devices supporting display extensions (Gerd Hoffmann) - Generically select Type-1 IOMMU model support on ARM/ARM64 (Geert Uytterhoeven) - Quirk for VFs reporting INTx pin (Alex Williamson) - Fix error path memory leak in MSI support (Li Qiang) * tag 'vfio-v4.20-rc1.v2' of git://github.com/awilliam/linux-vfio: vfio: add edid support to mbochs sample driver vfio: add edid api for display (vgpu) devices. drivers/vfio: Allow type-1 IOMMU instantiation with all ARM/ARM64 IOMMUs vfio/pci: Mask buggy SR-IOV VF INTx support vfio/pci: Fix potential memory leak in vfio_msi_cap_len
2 parents b3491d8 + 104c740 commit 0c86e76

File tree

5 files changed

+204
-23
lines changed

5 files changed

+204
-23
lines changed

drivers/vfio/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ config VFIO_VIRQFD
2121
menuconfig VFIO
2222
tristate "VFIO Non-Privileged userspace driver framework"
2323
depends on IOMMU_API
24-
select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM_SMMU || ARM_SMMU_V3)
24+
select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64)
2525
select ANON_INODES
2626
help
2727
VFIO provides a framework for secure userspace device drivers.

drivers/vfio/pci/vfio_pci.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,14 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type)
434434
{
435435
if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) {
436436
u8 pin;
437+
438+
if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) ||
439+
vdev->nointx || vdev->pdev->is_virtfn)
440+
return 0;
441+
437442
pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin);
438-
if (IS_ENABLED(CONFIG_VFIO_PCI_INTX) && !vdev->nointx && pin)
439-
return 1;
440443

444+
return pin ? 1 : 0;
441445
} else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) {
442446
u8 pos;
443447
u16 flags;

drivers/vfio/pci/vfio_pci_config.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,8 +1180,10 @@ static int vfio_msi_cap_len(struct vfio_pci_device *vdev, u8 pos)
11801180
return -ENOMEM;
11811181

11821182
ret = init_pci_cap_msi_perm(vdev->msi_perm, len, flags);
1183-
if (ret)
1183+
if (ret) {
1184+
kfree(vdev->msi_perm);
11841185
return ret;
1186+
}
11851187

11861188
return len;
11871189
}
@@ -1609,6 +1611,15 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev)
16091611
return 0;
16101612
}
16111613

1614+
/*
1615+
* Nag about hardware bugs, hopefully to have vendors fix them, but at least
1616+
* to collect a list of dependencies for the VF INTx pin quirk below.
1617+
*/
1618+
static const struct pci_device_id known_bogus_vf_intx_pin[] = {
1619+
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x270c) },
1620+
{}
1621+
};
1622+
16121623
/*
16131624
* For each device we allocate a pci_config_map that indicates the
16141625
* capability occupying each dword and thus the struct perm_bits we
@@ -1674,6 +1685,24 @@ int vfio_config_init(struct vfio_pci_device *vdev)
16741685
if (pdev->is_virtfn) {
16751686
*(__le16 *)&vconfig[PCI_VENDOR_ID] = cpu_to_le16(pdev->vendor);
16761687
*(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device);
1688+
1689+
/*
1690+
* Per SR-IOV spec rev 1.1, 3.4.1.18 the interrupt pin register
1691+
* does not apply to VFs and VFs must implement this register
1692+
* as read-only with value zero. Userspace is not readily able
1693+
* to identify whether a device is a VF and thus that the pin
1694+
* definition on the device is bogus should it violate this
1695+
* requirement. We already virtualize the pin register for
1696+
* other purposes, so we simply need to replace the bogus value
1697+
* and consider VFs when we determine INTx IRQ count.
1698+
*/
1699+
if (vconfig[PCI_INTERRUPT_PIN] &&
1700+
!pci_match_id(known_bogus_vf_intx_pin, pdev))
1701+
pci_warn(pdev,
1702+
"Hardware bug: VF reports bogus INTx pin %d\n",
1703+
vconfig[PCI_INTERRUPT_PIN]);
1704+
1705+
vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
16771706
}
16781707

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

include/uapi/linux/vfio.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,56 @@ struct vfio_region_info_cap_type {
303303
#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
304304
#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
305305

306+
#define VFIO_REGION_TYPE_GFX (1)
307+
#define VFIO_REGION_SUBTYPE_GFX_EDID (1)
308+
309+
/**
310+
* struct vfio_region_gfx_edid - EDID region layout.
311+
*
312+
* Set display link state and EDID blob.
313+
*
314+
* The EDID blob has monitor information such as brand, name, serial
315+
* number, physical size, supported video modes and more.
316+
*
317+
* This special region allows userspace (typically qemu) set a virtual
318+
* EDID for the virtual monitor, which allows a flexible display
319+
* configuration.
320+
*
321+
* For the edid blob spec look here:
322+
* https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
323+
*
324+
* On linux systems you can find the EDID blob in sysfs:
325+
* /sys/class/drm/${card}/${connector}/edid
326+
*
327+
* You can use the edid-decode ulility (comes with xorg-x11-utils) to
328+
* decode the EDID blob.
329+
*
330+
* @edid_offset: location of the edid blob, relative to the
331+
* start of the region (readonly).
332+
* @edid_max_size: max size of the edid blob (readonly).
333+
* @edid_size: actual edid size (read/write).
334+
* @link_state: display link state (read/write).
335+
* VFIO_DEVICE_GFX_LINK_STATE_UP: Monitor is turned on.
336+
* VFIO_DEVICE_GFX_LINK_STATE_DOWN: Monitor is turned off.
337+
* @max_xres: max display width (0 == no limitation, readonly).
338+
* @max_yres: max display height (0 == no limitation, readonly).
339+
*
340+
* EDID update protocol:
341+
* (1) set link-state to down.
342+
* (2) update edid blob and size.
343+
* (3) set link-state to up.
344+
*/
345+
struct vfio_region_gfx_edid {
346+
__u32 edid_offset;
347+
__u32 edid_max_size;
348+
__u32 edid_size;
349+
__u32 max_xres;
350+
__u32 max_yres;
351+
__u32 link_state;
352+
#define VFIO_DEVICE_GFX_LINK_STATE_UP 1
353+
#define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2
354+
};
355+
306356
/*
307357
* The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
308358
* which allows direct access to non-MSIX registers which happened to be within

0 commit comments

Comments
 (0)