From 6f9a22bc5775d231ab8fbe2c2f3c88e45e3e7c28 Mon Sep 17 00:00:00 2001 From: Michael Hernandez Date: Thu, 18 May 2017 10:47:47 -0700 Subject: PCI/MSI: Ignore affinity if pre/post vector count is more than min_vecs min_vecs is the minimum amount of vectors needed to operate in MSI-X mode which may just include the vectors that don't need affinity. Disabling affinity settings causes the qla2xxx driver scsi_add_host() to fail when blk_mq is enabled as the blk_mq_pci_map_queues() expects affinity masks on each vector. Fixes: dfef358bd1be ("PCI/MSI: Don't apply affinity if there aren't enough vectors left") Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Bjorn Helgaas Reviewed-by: Christoph Hellwig Cc: stable@vger.kernel.org # v4.10+ --- include/linux/interrupt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index a6fba4804672..0991f973f8ca 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -291,7 +291,7 @@ extern int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify); struct cpumask *irq_create_affinity_masks(int nvec, const struct irq_affinity *affd); -int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd); +int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd); #else /* CONFIG_SMP */ @@ -331,7 +331,7 @@ irq_create_affinity_masks(int nvec, const struct irq_affinity *affd) } static inline int -irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd) +irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd) { return maxvec; } -- cgit v1.2.3 From a4f4fa681add289ebfec6d776376ad7a2ffda669 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Tue, 30 May 2017 09:25:48 -0700 Subject: PCI: Cache PRI and PASID bits in pci_dev Device drivers need to check if an IOMMU enabled ATS, PRI and PASID in order to know when they can use the SVM API. Cache PRI and PASID bits in the pci_dev structure, similarly to what is currently done for ATS. Signed-off-by: Jean-Philippe Brucker Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 33c2b0b77429..f612c1d85863 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -356,6 +356,8 @@ struct pci_dev { unsigned int msix_enabled:1; unsigned int ari_enabled:1; /* ARI forwarding */ unsigned int ats_enabled:1; /* Address Translation Service */ + unsigned int pasid_enabled:1; /* Process Address Space ID */ + unsigned int pri_enabled:1; /* Page Request Interface */ unsigned int is_managed:1; unsigned int needs_freset:1; /* Dev requires fundamental reset */ unsigned int state_saved:1; -- cgit v1.2.3 From 4ebeb1ec56d4c54a56b6f43c2603d9a4688c83ba Mon Sep 17 00:00:00 2001 From: CQ Tang Date: Tue, 30 May 2017 09:25:49 -0700 Subject: PCI: Restore PRI and PASID state after Function-Level Reset After a Function-Level Reset, PCI states need to be restored. Save PASID features and PRI reqs cached. [bhelgaas: search for capability only if PRI/PASID were enabled] Signed-off-by: CQ Tang Signed-off-by: Ashok Raj Signed-off-by: Bjorn Helgaas Cc: Joerg Roedel Cc: Jean-Phillipe Brucker Cc: David Woodhouse --- include/linux/pci-ats.h | 10 ++++++++++ include/linux/pci.h | 6 ++++++ 2 files changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h index 57e0b8250947..782fb8e0755f 100644 --- a/include/linux/pci-ats.h +++ b/include/linux/pci-ats.h @@ -7,6 +7,7 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs); void pci_disable_pri(struct pci_dev *pdev); +void pci_restore_pri_state(struct pci_dev *pdev); int pci_reset_pri(struct pci_dev *pdev); #else /* CONFIG_PCI_PRI */ @@ -20,6 +21,10 @@ static inline void pci_disable_pri(struct pci_dev *pdev) { } +static inline void pci_restore_pri_state(struct pci_dev *pdev) +{ +} + static inline int pci_reset_pri(struct pci_dev *pdev) { return -ENODEV; @@ -31,6 +36,7 @@ static inline int pci_reset_pri(struct pci_dev *pdev) int pci_enable_pasid(struct pci_dev *pdev, int features); void pci_disable_pasid(struct pci_dev *pdev); +void pci_restore_pasid_state(struct pci_dev *pdev); int pci_pasid_features(struct pci_dev *pdev); int pci_max_pasids(struct pci_dev *pdev); @@ -45,6 +51,10 @@ static inline void pci_disable_pasid(struct pci_dev *pdev) { } +static inline void pci_restore_pasid_state(struct pci_dev *pdev) +{ +} + static inline int pci_pasid_features(struct pci_dev *pdev) { return -EINVAL; diff --git a/include/linux/pci.h b/include/linux/pci.h index f612c1d85863..c7cfdff2529c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -400,6 +400,12 @@ struct pci_dev { u16 ats_cap; /* ATS Capability offset */ u8 ats_stu; /* ATS Smallest Translation Unit */ atomic_t ats_ref_cnt; /* number of VFs with ATS enabled */ +#endif +#ifdef CONFIG_PCI_PRI + u32 pri_reqs_alloc; /* Number of PRI requests allocated */ +#endif +#ifdef CONFIG_PCI_PASID + u16 pasid_features; #endif phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */ size_t romlen; /* Length of ROM if it's not from the BAR */ -- cgit v1.2.3 From 99b3c58f7ba7fae801e501b45c5fcf6e08d9247f Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Fri, 26 May 2017 22:02:25 +0100 Subject: PCI: Test INTx masking during enumeration, not at run-time The test for INTx masking via PCI_COMMAND_INTX_DISABLE performed in pci_intx_mask_supported() should be done before the device can be used. This is to avoid writing PCI_COMMAND while the driver owns the device, in case that has any effect on MSI/MSI-X interrupts. Move the content of pci_intx_mask_supported() to pci_intx_mask_broken() and call it from pci_setup_device(). The test result can be queried at any time later using the same pci_intx_mask_supported() interface as before (though with changed implementation), so callers (uio, vfio) should be unaffected. Signed-off-by: Piotr Gregor [bhelgaas: changelog, remove quirk check, remove locking, move dev->broken_intx_masking assignment to caller] Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Williamson Acked-by: Michael S. Tsirkin --- include/linux/pci.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 33c2b0b77429..4f0613d5d2d9 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -366,7 +366,7 @@ struct pci_dev { unsigned int is_thunderbolt:1; /* Thunderbolt controller */ unsigned int __aer_firmware_first_valid:1; unsigned int __aer_firmware_first:1; - unsigned int broken_intx_masking:1; + unsigned int broken_intx_masking:1; /* INTx masking can't be used */ unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ unsigned int irq_managed:1; unsigned int has_secondary_link:1; @@ -1003,6 +1003,15 @@ int __must_check pci_reenable_device(struct pci_dev *); int __must_check pcim_enable_device(struct pci_dev *pdev); void pcim_pin_device(struct pci_dev *pdev); +static inline bool pci_intx_mask_supported(struct pci_dev *pdev) +{ + /* + * INTx masking is supported if PCI_COMMAND_INTX_DISABLE is + * writable and no quirk has marked the feature broken. + */ + return !pdev->broken_intx_masking; +} + static inline int pci_is_enabled(struct pci_dev *pdev) { return (atomic_read(&pdev->enable_cnt) > 0); @@ -1026,7 +1035,6 @@ int __must_check pci_set_mwi(struct pci_dev *dev); int pci_try_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); void pci_intx(struct pci_dev *dev, int enable); -bool pci_intx_mask_supported(struct pci_dev *dev); bool pci_check_and_mask_intx(struct pci_dev *dev); bool pci_check_and_unmask_intx(struct pci_dev *dev); int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask); -- cgit v1.2.3 From dff79b91b8f3279cbe60727368adff1f3a5ab16e Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 28 Jun 2017 15:13:52 -0500 Subject: PCI: Add pci_free_host_bridge() interface Commit a52d1443bba1 ("PCI: Export host bridge registration interface") exported the pci_alloc_host_bridge() interface so that PCI host controllers drivers can make use of it. Introduce pci_alloc_host_bridge() kernel counterpart to free the host bridge data structures, pci_free_host_bridge(), export it and update kernel functions releasing host bridge objects allocated memory to make use of it. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Cc: Arnd Bergmann --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 33c2b0b77429..9095b38c2fa3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -458,6 +458,7 @@ static inline struct pci_host_bridge *pci_host_bridge_from_priv(void *priv) } struct pci_host_bridge *pci_alloc_host_bridge(size_t priv); +void pci_free_host_bridge(struct pci_host_bridge *bridge); int pci_register_host_bridge(struct pci_host_bridge *bridge); struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus); -- cgit v1.2.3 From 5c3f18cce08364ef68163228c0b42725d64cd353 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 28 Jun 2017 15:13:53 -0500 Subject: PCI: Add devm_pci_alloc_host_bridge() interface Struct pci_host_bridge can be allocated by PCI host bridge drivers which usually allocate and map memory through devm managed interfaces. Add a devm version for the pci_alloc_host_bridge() interface to simplify PCI host controller driver porting and simplify the driver failure paths. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Cc: Arnd Bergmann --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 9095b38c2fa3..d39a66dc67aa 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -458,6 +458,8 @@ static inline struct pci_host_bridge *pci_host_bridge_from_priv(void *priv) } struct pci_host_bridge *pci_alloc_host_bridge(size_t priv); +struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, + size_t priv); void pci_free_host_bridge(struct pci_host_bridge *bridge); int pci_register_host_bridge(struct pci_host_bridge *bridge); struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus); -- cgit v1.2.3 From 1228c4b6c19a76a2691cfb1403ad1eebf5852b76 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 28 Jun 2017 15:13:55 -0500 Subject: PCI: Add pci_scan_root_bus_bridge() interface The current pci_scan_root_bus() interface is made up of two main code paths: - pci_create_root_bus() - pci_scan_child_bus() pci_create_root_bus() is a wrapper function that allows to create a struct pci_host_bridge structure, initialize it with the passed parameters and register it with the kernel. As the struct pci_host_bridge require additional struct members, pci_create_root_bus() parameters list has grown in time, making it unwieldy to add further parameters to it in case the struct pci_host_bridge gains more members fields to augment its functionality. Since PCI core code provides functions to allocate struct pci_host_bridge, instead of forcing the pci_create_root_bus() interface to add new parameters to cater for new struct pci_host_bridge functionality, it is more suitable to add an interface in PCI core code to scan a PCI bus straight from a struct pci_host_bridge created and customized by each specific PCI host controller driver. Add a pci_scan_root_bus_bridge() function to allow PCI host controller drivers to create and initialize struct pci_host_bridge and scan the resulting bus. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Cc: Arnd Bergmann --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index d39a66dc67aa..fe1eafd637c3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -857,6 +857,7 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus, struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge); struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); void pcie_update_link_speed(struct pci_bus *bus, u16 link_status); -- cgit v1.2.3 From cea9bc0be624fb0dc488cb10df40be1323b6b758 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 28 Jun 2017 15:13:55 -0500 Subject: PCI: Make pci_register_host_bridge() PCI core internal With the introduction of pci_scan_root_bus_bridge() there is no need to export pci_register_host_bridge() to other kernel subsystems other than the PCI compilation unit that needs it. Make pci_register_host_bridge() static to its compilation unit and convert the existing drivers usage over to pci_scan_root_bus_bridge(). Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Cc: Arnd Bergmann --- include/linux/pci.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index fe1eafd637c3..b56dc13f47c2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -461,7 +461,6 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv); struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, size_t priv); void pci_free_host_bridge(struct pci_host_bridge *bridge); -int pci_register_host_bridge(struct pci_host_bridge *bridge); struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus); void pci_set_host_bridge_release(struct pci_host_bridge *bridge, -- cgit v1.2.3 From 9ee8a1c4a0e232e9b86e03f7c628ff0286444e00 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 28 Jun 2017 15:14:01 -0500 Subject: PCI: Remove pci_scan_root_bus_msi() The pci_scan_root_bus_bridge() function allows passing a parameterized struct pci_host_bridge and scanning the resulting PCI bus; since the struct msi_controller is part of the struct pci_host_bridge and the struct pci_host_bridge can now be passed to pci_scan_root_bus_bridge() explicitly, there is no need for a scan interface with a MSI controller parameter. With all PCI host controller drivers and platform code relying on pci_scan_root_bus_msi() converted over to pci_scan_root_bus_bridge() the pci_scan_root_bus_msi() becomes obsolete and can be removed. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index b56dc13f47c2..9022b542556a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -849,10 +849,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus, - struct pci_ops *ops, void *sysdata, - struct list_head *resources, - struct msi_controller *msi); struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); -- cgit v1.2.3 From 3aa8a41e0bf5565946082d23ae589c1a8559494a Mon Sep 17 00:00:00 2001 From: Matthew Minter Date: Wed, 28 Jun 2017 15:14:02 -0500 Subject: PCI: Add IRQ mapping function pointers to pci_host_bridge struct In order to defer IRQ assignment arches must be able to register functions to map and swizzle interrupts. These registered functions are stored in the pci_host_bridge struct. Signed-off-by: Matthew Minter Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 9022b542556a..3c5d8b026d6e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -432,6 +432,8 @@ struct pci_host_bridge { void *sysdata; int busnr; struct list_head windows; /* resource_entry */ + u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* platform IRQ swizzler */ + int (*map_irq)(const struct pci_dev *, u8, u8); void (*release_fn)(struct pci_host_bridge *); void *release_data; struct msi_controller *msi; -- cgit v1.2.3 From 47a650f2795b00297a5a3eab7aaa46bdb2bbe304 Mon Sep 17 00:00:00 2001 From: Matthew Minter Date: Wed, 28 Jun 2017 15:14:02 -0500 Subject: PCI: Add pci_assign_irq() function and have pci_fixup_irqs() use it Here we delete the static pdev_fixup_irq() function which is currently what pci_fixup_irqs() uses to actually assign the IRQs and replace it with the pci_assign_irq() function which changes the interface and uses the new function pointers stored in the host bridge structure. Eventually this will allow pci_fixup_irqs() to be removed entirely and the new deferred assignment code path will call pci_assign_irq() directly. However to ensure current users continue to work, a new implementation of pci_fixup_irqs() is introduced which simply wraps the functionality of pci_assign_irq(). Signed-off-by: Matthew Minter [lorenzo.pieralisi@arm.com: reworked comments/log] Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 3c5d8b026d6e..5c1c0ae38dd3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1147,6 +1147,7 @@ void pdev_enable_device(struct pci_dev *); int pci_enable_resources(struct pci_dev *, int mask); void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), int (*)(const struct pci_dev *, u8, u8)); +void pci_assign_irq(struct pci_dev *dev); struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res); #define HAVE_PCI_REQ_REGIONS 2 int __must_check pci_request_regions(struct pci_dev *, const char *); -- cgit v1.2.3 From 775755ed3c65fb2d31f9268162495d76eaa2c281 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 1 Jun 2017 13:10:38 +0200 Subject: PCI: Split ->reset_notify() method into ->reset_prepare() and ->reset_done() The pci_error_handlers->reset_notify() method had a flag to indicate whether to prepare for or clean up after a reset. The prepare and done cases have no shared functionality whatsoever, so split them into separate methods. [bhelgaas: changelog, update locking comments] Link: http://lkml.kernel.org/r/20170601111039.8913-3-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index c7cfdff2529c..c5937ee7e774 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -698,7 +698,8 @@ struct pci_error_handlers { pci_ers_result_t (*slot_reset)(struct pci_dev *dev); /* PCI function reset prepare or completed */ - void (*reset_notify)(struct pci_dev *dev, bool prepare); + void (*reset_prepare)(struct pci_dev *dev); + void (*reset_done)(struct pci_dev *dev); /* Device driver may resume normal operations */ void (*resume)(struct pci_dev *dev); -- cgit v1.2.3 From 5e14e9fac308daf5607362f879e6de67e0b8dd5b Mon Sep 17 00:00:00 2001 From: Marc Gonzalez Date: Tue, 20 Jun 2017 10:17:40 +0200 Subject: PCI: tango: Add Sigma Designs Tango SMP8759 PCIe host bridge support This driver is required to work around several hardware bugs in the PCIe controller. The SMP8759 does not support legacy interrupts or IO space. Signed-off-by: Marc Gonzalez [bhelgaas: add CONFIG_BROKEN dependency, various cleanups] Signed-off-by: Bjorn Helgaas --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5f6b71d15393..c71e532da458 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1373,6 +1373,8 @@ #define PCI_DEVICE_ID_TTI_HPT374 0x0008 #define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /* apparently a 372N variant? */ +#define PCI_VENDOR_ID_SIGMA 0x1105 + #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_DEVICE_ID_VIA_8763_0 0x0198 #define PCI_DEVICE_ID_VIA_8380_0 0x0204 -- cgit v1.2.3