2828#define BUS_RESTRICT_CAP (vmcap ) (vmcap & 0x1)
2929#define PCI_REG_VMCONFIG 0x44
3030#define BUS_RESTRICT_CFG (vmcfg ) ((vmcfg >> 8) & 0x3)
31+ #define VMCONFIG_MSI_REMAP 0x2
3132#define PCI_REG_VMLOCK 0x70
3233#define MB2_SHADOW_EN (vmlock ) (vmlock & 0x2)
3334
@@ -59,6 +60,13 @@ enum vmd_features {
5960 * be used for MSI remapping
6061 */
6162 VMD_FEAT_OFFSET_FIRST_VECTOR = (1 << 3 ),
63+
64+ /*
65+ * Device can bypass remapping MSI-X transactions into its MSI-X table,
66+ * avoiding the requirement of a VMD MSI domain for child device
67+ * interrupt handling.
68+ */
69+ VMD_FEAT_CAN_BYPASS_MSI_REMAP = (1 << 4 ),
6270};
6371
6472/*
@@ -306,6 +314,16 @@ static struct msi_domain_info vmd_msi_domain_info = {
306314 .chip = & vmd_msi_controller ,
307315};
308316
317+ static void vmd_set_msi_remapping (struct vmd_dev * vmd , bool enable )
318+ {
319+ u16 reg ;
320+
321+ pci_read_config_word (vmd -> dev , PCI_REG_VMCONFIG , & reg );
322+ reg = enable ? (reg & ~VMCONFIG_MSI_REMAP ) :
323+ (reg | VMCONFIG_MSI_REMAP );
324+ pci_write_config_word (vmd -> dev , PCI_REG_VMCONFIG , reg );
325+ }
326+
309327static int vmd_create_irq_domain (struct vmd_dev * vmd )
310328{
311329 struct fwnode_handle * fn ;
@@ -325,6 +343,13 @@ static int vmd_create_irq_domain(struct vmd_dev *vmd)
325343
326344static void vmd_remove_irq_domain (struct vmd_dev * vmd )
327345{
346+ /*
347+ * Some production BIOS won't enable remapping between soft reboots.
348+ * Ensure remapping is restored before unloading the driver.
349+ */
350+ if (!vmd -> msix_count )
351+ vmd_set_msi_remapping (vmd , true);
352+
328353 if (vmd -> irq_domain ) {
329354 struct fwnode_handle * fn = vmd -> irq_domain -> fwnode ;
330355
@@ -679,15 +704,32 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
679704
680705 sd -> node = pcibus_to_node (vmd -> dev -> bus );
681706
682- ret = vmd_create_irq_domain (vmd );
683- if (ret )
684- return ret ;
685-
686707 /*
687- * Override the irq domain bus token so the domain can be distinguished
688- * from a regular PCI/MSI domain.
708+ * Currently MSI remapping must be enabled in guest passthrough mode
709+ * due to some missing interrupt remapping plumbing. This is probably
710+ * acceptable because the guest is usually CPU-limited and MSI
711+ * remapping doesn't become a performance bottleneck.
689712 */
690- irq_domain_update_bus_token (vmd -> irq_domain , DOMAIN_BUS_VMD_MSI );
713+ if (!(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP ) ||
714+ offset [0 ] || offset [1 ]) {
715+ ret = vmd_alloc_irqs (vmd );
716+ if (ret )
717+ return ret ;
718+
719+ vmd_set_msi_remapping (vmd , true);
720+
721+ ret = vmd_create_irq_domain (vmd );
722+ if (ret )
723+ return ret ;
724+
725+ /*
726+ * Override the IRQ domain bus token so the domain can be
727+ * distinguished from a regular PCI/MSI domain.
728+ */
729+ irq_domain_update_bus_token (vmd -> irq_domain , DOMAIN_BUS_VMD_MSI );
730+ } else {
731+ vmd_set_msi_remapping (vmd , false);
732+ }
691733
692734 pci_add_resource (& resources , & vmd -> resources [0 ]);
693735 pci_add_resource_offset (& resources , & vmd -> resources [1 ], offset [0 ]);
@@ -753,10 +795,6 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
753795 if (features & VMD_FEAT_OFFSET_FIRST_VECTOR )
754796 vmd -> first_vec = 1 ;
755797
756- err = vmd_alloc_irqs (vmd );
757- if (err )
758- return err ;
759-
760798 spin_lock_init (& vmd -> cfg_lock );
761799 pci_set_drvdata (dev , vmd );
762800 err = vmd_enable_domain (vmd , features );
@@ -825,7 +863,8 @@ static const struct pci_device_id vmd_ids[] = {
825863 .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP ,},
826864 {PCI_DEVICE (PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_VMD_28C0 ),
827865 .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW |
828- VMD_FEAT_HAS_BUS_RESTRICTIONS ,},
866+ VMD_FEAT_HAS_BUS_RESTRICTIONS |
867+ VMD_FEAT_CAN_BYPASS_MSI_REMAP ,},
829868 {PCI_DEVICE (PCI_VENDOR_ID_INTEL , 0x467f ),
830869 .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP |
831870 VMD_FEAT_HAS_BUS_RESTRICTIONS |
0 commit comments