Commit db83c269 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/host-vmd'

  - Save VMD's pci_dev in x86 struct pci_sysdata (Jon Derrick)

  - Add pci_real_dma_dev() for DMA aliases not on the same bus as requester
    (Jon Derrick)

  - Add IOMMU mappings for pci_real_dma_dev() (Jon Derrick)

  - Remove IOMMU sanity checks for VMD devices (Jon Derrick)

  - Remove VMD dma_map_ops overrides (Jon Derrick)

  - Remove unused X86_DEV_DMA_OPS (Christoph Hellwig)

  - Add VMD device IDs that need bus restriction mode (Sushma Kalakota)

* pci/host-vmd:
  PCI: vmd: Add two VMD Device IDs
  x86/PCI: Remove X86_DEV_DMA_OPS
  PCI: vmd: Remove dma_map_ops overrides
  iommu/vt-d: Remove VMD child device sanity check
  iommu/vt-d: Use pci_real_dma_dev() for mapping
  PCI: Introduce pci_real_dma_dev()
  x86/PCI: Expose VMD's pci_dev in struct pci_sysdata
  x86/PCI: Add to_pci_sysdata() helper
parents c7417cf3 db51b4c8
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -2955,9 +2955,6 @@ config HAVE_ATOMIC_IOMAP
	def_bool y
	depends on X86_32

config X86_DEV_DMA_OPS
	bool

source "drivers/firmware/Kconfig"

source "arch/x86/kvm/Kconfig"
+0 −10
Original line number Diff line number Diff line
@@ -8,16 +8,6 @@ struct dev_archdata {
#endif
};

#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
struct dma_domain {
	struct list_head node;
	const struct dma_map_ops *dma_ops;
	int domain_nr;
};
void add_dma_domain(struct dma_domain *domain);
void del_dma_domain(struct dma_domain *domain);
#endif

struct pdev_archdata {
};

+14 −17
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ struct pci_sysdata {
	void		*fwnode;	/* IRQ domain for MSI assignment */
#endif
#if IS_ENABLED(CONFIG_VMD)
	bool vmd_domain;		/* True if in Intel VMD domain */
	struct pci_dev	*vmd_dev;	/* VMD Device if in Intel VMD domain */
#endif
};

@@ -35,12 +35,15 @@ extern int noioapicreroute;

#ifdef CONFIG_PCI

static inline struct pci_sysdata *to_pci_sysdata(const struct pci_bus *bus)
{
	return bus->sysdata;
}

#ifdef CONFIG_PCI_DOMAINS
static inline int pci_domain_nr(struct pci_bus *bus)
{
	struct pci_sysdata *sd = bus->sysdata;

	return sd->domain;
	return to_pci_sysdata(bus)->domain;
}

static inline int pci_proc_domain(struct pci_bus *bus)
@@ -52,24 +55,20 @@ static inline int pci_proc_domain(struct pci_bus *bus)
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
{
	struct pci_sysdata *sd = bus->sysdata;

	return sd->fwnode;
	return to_pci_sysdata(bus)->fwnode;
}

#define pci_root_bus_fwnode	_pci_root_bus_fwnode
#endif

#if IS_ENABLED(CONFIG_VMD)
static inline bool is_vmd(struct pci_bus *bus)
{
#if IS_ENABLED(CONFIG_VMD)
	struct pci_sysdata *sd = bus->sysdata;

	return sd->vmd_domain;
#else
	return false;
#endif
	return to_pci_sysdata(bus)->vmd_dev != NULL;
}
#else
#define is_vmd(bus)		false
#endif /* CONFIG_VMD */

/* Can be used to override the logic in pci_scan_bus for skipping
   already-configured bus numbers - to be used for buggy BIOSes
@@ -124,9 +123,7 @@ void native_restore_msi_irqs(struct pci_dev *dev);
/* Returns the node based on pci bus */
static inline int __pcibus_to_node(const struct pci_bus *bus)
{
	const struct pci_sysdata *sd = bus->sysdata;

	return sd->node;
	return to_pci_sysdata(bus)->node;
}

static inline const struct cpumask *
+10 −38
Original line number Diff line number Diff line
@@ -625,43 +625,6 @@ unsigned int pcibios_assign_all_busses(void)
	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
}

#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
static LIST_HEAD(dma_domain_list);
static DEFINE_SPINLOCK(dma_domain_list_lock);

void add_dma_domain(struct dma_domain *domain)
{
	spin_lock(&dma_domain_list_lock);
	list_add(&domain->node, &dma_domain_list);
	spin_unlock(&dma_domain_list_lock);
}
EXPORT_SYMBOL_GPL(add_dma_domain);

void del_dma_domain(struct dma_domain *domain)
{
	spin_lock(&dma_domain_list_lock);
	list_del(&domain->node);
	spin_unlock(&dma_domain_list_lock);
}
EXPORT_SYMBOL_GPL(del_dma_domain);

static void set_dma_domain_ops(struct pci_dev *pdev)
{
	struct dma_domain *domain;

	spin_lock(&dma_domain_list_lock);
	list_for_each_entry(domain, &dma_domain_list, node) {
		if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
			pdev->dev.dma_ops = domain->dma_ops;
			break;
		}
	}
	spin_unlock(&dma_domain_list_lock);
}
#else
static void set_dma_domain_ops(struct pci_dev *pdev) {}
#endif

static void set_dev_domain_options(struct pci_dev *pdev)
{
	if (is_vmd(pdev->bus))
@@ -697,7 +660,6 @@ int pcibios_add_device(struct pci_dev *dev)
		pa_data = data->next;
		memunmap(data);
	}
	set_dma_domain_ops(dev);
	set_dev_domain_options(dev);
	return 0;
}
@@ -736,3 +698,13 @@ int pci_ext_cfg_avail(void)
	else
		return 0;
}

#if IS_ENABLED(CONFIG_VMD)
struct pci_dev *pci_real_dma_dev(struct pci_dev *dev)
{
	if (is_vmd(dev->bus))
		return to_pci_sysdata(dev->bus)->vmd_dev;

	return dev;
}
#endif
+4 −7
Original line number Diff line number Diff line
@@ -774,13 +774,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
	if (dev_is_pci(dev)) {
		struct pci_dev *pf_pdev;

		pdev = to_pci_dev(dev);

#ifdef CONFIG_X86
		/* VMD child devices currently cannot be handled individually */
		if (is_vmd(pdev->bus))
			return NULL;
#endif
		pdev = pci_real_dma_dev(to_pci_dev(dev));

		/* VFs aren't listed in scope tables; we need to look up
		 * the PF instead to find the IOMMU. */
@@ -2428,6 +2422,9 @@ static struct dmar_domain *find_domain(struct device *dev)
		     dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO))
		return NULL;

	if (dev_is_pci(dev))
		dev = &pci_real_dma_dev(to_pci_dev(dev))->dev;

	/* No lock here, assumes no domain exit in normal case */
	info = dev->archdata.iommu;
	if (likely(info))
Loading