diff options
Diffstat (limited to 'drivers/pci/controller/vmd.c')
| -rw-r--r-- | drivers/pci/controller/vmd.c | 20 | 
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 9d9596947350..e619accca49d 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -17,6 +17,8 @@  #include <linux/rculist.h>  #include <linux/rcupdate.h> +#include <xen/xen.h> +  #include <asm/irqdomain.h>  #define VMD_CFGBAR	0 @@ -970,6 +972,24 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)  	struct vmd_dev *vmd;  	int err; +	if (xen_domain()) { +		/* +		 * Xen doesn't have knowledge about devices in the VMD bus +		 * because the config space of devices behind the VMD bridge is +		 * not known to Xen, and hence Xen cannot discover or configure +		 * them in any way. +		 * +		 * Bypass of MSI remapping won't work in that case as direct +		 * write by Linux to the MSI entries won't result in functional +		 * interrupts, as Xen is the entity that manages the host +		 * interrupt controller and must configure interrupts.  However +		 * multiplexing of interrupts by the VMD bridge will work under +		 * Xen, so force the usage of that mode which must always be +		 * supported by VMD bridges. +		 */ +		features &= ~VMD_FEAT_CAN_BYPASS_MSI_REMAP; +	} +  	if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20))  		return -ENOMEM;  | 
