Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/gic-v3: Drop support for custom PPI partitions

The only thing getting in the way of correctly handling PPIs the way they
were intended is the GICv3 hack that deals with PPI partitions.

Remove that code, allowing the common code to kick in.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Will Deacon <will@kernel.org>
Link: https://patch.msgid.link/20251020122944.3074811-22-maz@kernel.org

authored by

Marc Zyngier and committed by
Thomas Gleixner
64b9738e 4cdf4813

+8 -126
-1
drivers/irqchip/Kconfig
··· 36 36 config ARM_GIC_V3 37 37 bool 38 38 select IRQ_DOMAIN_HIERARCHY 39 - select PARTITION_PERCPU 40 39 select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP 41 40 select HAVE_ARM_SMCCC_DISCOVERY 42 41 select IRQ_MSI_IOMMU
+8 -125
drivers/irqchip/irq-gic-v3.c
··· 26 26 #include <linux/irqchip/arm-gic-common.h> 27 27 #include <linux/irqchip/arm-gic-v3.h> 28 28 #include <linux/irqchip/arm-gic-v3-prio.h> 29 - #include <linux/irqchip/irq-partition-percpu.h> 30 29 #include <linux/bitfield.h> 31 30 #include <linux/bits.h> 32 31 #include <linux/arm-smccc.h> ··· 44 45 #define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) 45 46 #define FLAGS_WORKAROUND_ASR_ERRATUM_8601001 (1ULL << 2) 46 47 #define FLAGS_WORKAROUND_INSECURE (1ULL << 3) 47 - 48 - #define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1) 49 48 50 49 static struct cpumask broken_rdists __read_mostly __maybe_unused; 51 50 ··· 65 68 u64 flags; 66 69 bool has_rss; 67 70 unsigned int ppi_nr; 68 - struct partition_desc **ppi_descs; 69 71 struct partition_affinity *parts; 70 72 unsigned int nr_parts; 73 + }; 74 + 75 + struct partition_affinity { 76 + cpumask_t mask; 77 + struct fwnode_handle *partition_id; 71 78 }; 72 79 73 80 #define T241_CHIPS_MAX 4 ··· 592 591 offset = convert_offset_index(d, GICD_IPRIORITYR, &index); 593 592 594 593 writeb_relaxed(prio, base + offset + index); 595 - } 596 - 597 - static u32 __gic_get_ppi_index(irq_hw_number_t hwirq) 598 - { 599 - switch (__get_intid_range(hwirq)) { 600 - case PPI_RANGE: 601 - return hwirq - 16; 602 - case EPPI_RANGE: 603 - return hwirq - EPPI_BASE_INTID + 16; 604 - default: 605 - unreachable(); 606 - } 607 594 } 608 595 609 596 static int gic_irq_nmi_setup(struct irq_data *d) ··· 1617 1628 case GIC_IRQ_TYPE_LPI: /* LPI */ 1618 1629 *hwirq = fwspec->param[1]; 1619 1630 break; 1620 - case GIC_IRQ_TYPE_PARTITION: 1621 - *hwirq = fwspec->param[1]; 1622 - if (fwspec->param[1] >= 16) 1623 - *hwirq += EPPI_BASE_INTID - 16; 1624 - else 1625 - *hwirq += 16; 1626 - break; 1627 1631 default: 1628 1632 return -EINVAL; 1629 1633 } ··· 1625 1643 1626 1644 /* 1627 1645 * Make it clear that broken DTs are... broken. 1628 - * Partitioned PPIs are an unfortunate exception. 1629 1646 */ 1630 - WARN_ON(*type == IRQ_TYPE_NONE && 1631 - fwspec->param[0] != GIC_IRQ_TYPE_PARTITION); 1647 + WARN_ON(*type == IRQ_TYPE_NONE); 1632 1648 return 0; 1633 1649 } 1634 1650 ··· 1683 1703 } 1684 1704 } 1685 1705 1686 - static bool fwspec_is_partitioned_ppi(struct irq_fwspec *fwspec, 1687 - irq_hw_number_t hwirq) 1688 - { 1689 - enum gic_intid_range range; 1690 - 1691 - if (!gic_data.ppi_descs) 1692 - return false; 1693 - 1694 - if (!is_of_node(fwspec->fwnode)) 1695 - return false; 1696 - 1697 - if (fwspec->param_count < 4 || !fwspec->param[3]) 1698 - return false; 1699 - 1700 - range = __get_intid_range(hwirq); 1701 - if (range != PPI_RANGE && range != EPPI_RANGE) 1702 - return false; 1703 - 1704 - return true; 1705 - } 1706 - 1707 1706 static int gic_irq_domain_select(struct irq_domain *d, 1708 1707 struct irq_fwspec *fwspec, 1709 1708 enum irq_domain_bus_token bus_token) 1710 1709 { 1711 - unsigned int type, ppi_idx; 1712 1710 irq_hw_number_t hwirq; 1711 + unsigned int type; 1713 1712 int ret; 1714 1713 1715 1714 /* Not for us */ ··· 1707 1748 if (WARN_ON_ONCE(ret)) 1708 1749 return 0; 1709 1750 1710 - if (!fwspec_is_partitioned_ppi(fwspec, hwirq)) 1711 - return d == gic_data.domain; 1712 - 1713 - /* 1714 - * If this is a PPI and we have a 4th (non-null) parameter, 1715 - * then we need to match the partition domain. 1716 - */ 1717 - ppi_idx = __gic_get_ppi_index(hwirq); 1718 - return d == partition_get_domain(gic_data.ppi_descs[ppi_idx]); 1751 + return d == gic_data.domain; 1719 1752 } 1720 1753 1721 1754 static int gic_irq_get_fwspec_info(struct irq_fwspec *fwspec, struct irq_fwspec_info *info) ··· 1760 1809 .translate = gic_irq_domain_translate, 1761 1810 .alloc = gic_irq_domain_alloc, 1762 1811 .free = gic_irq_domain_free, 1763 - .select = gic_irq_domain_select, 1764 - .get_fwspec_info = gic_irq_get_fwspec_info, 1765 - }; 1766 - 1767 - static int partition_domain_translate(struct irq_domain *d, 1768 - struct irq_fwspec *fwspec, 1769 - unsigned long *hwirq, 1770 - unsigned int *type) 1771 - { 1772 - unsigned long ppi_intid; 1773 - struct device_node *np; 1774 - unsigned int ppi_idx; 1775 - int ret; 1776 - 1777 - if (!gic_data.ppi_descs) 1778 - return -ENOMEM; 1779 - 1780 - np = of_find_node_by_phandle(fwspec->param[3]); 1781 - if (WARN_ON(!np)) 1782 - return -EINVAL; 1783 - 1784 - ret = gic_irq_domain_translate(d, fwspec, &ppi_intid, type); 1785 - if (WARN_ON_ONCE(ret)) 1786 - return 0; 1787 - 1788 - ppi_idx = __gic_get_ppi_index(ppi_intid); 1789 - ret = partition_translate_id(gic_data.ppi_descs[ppi_idx], 1790 - of_fwnode_handle(np)); 1791 - if (ret < 0) 1792 - return ret; 1793 - 1794 - *hwirq = ret; 1795 - *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; 1796 - 1797 - return 0; 1798 - } 1799 - 1800 - static const struct irq_domain_ops partition_domain_ops = { 1801 - .translate = partition_domain_translate, 1802 1812 .select = gic_irq_domain_select, 1803 1813 .get_fwspec_info = gic_irq_get_fwspec_info, 1804 1814 }; ··· 2086 2174 if (!parts_node) 2087 2175 return; 2088 2176 2089 - gic_data.ppi_descs = kcalloc(gic_data.ppi_nr, sizeof(*gic_data.ppi_descs), GFP_KERNEL); 2090 - if (!gic_data.ppi_descs) 2091 - goto out_put_node; 2092 - 2093 2177 nr_parts = of_get_child_count(parts_node); 2094 - 2095 2178 if (!nr_parts) 2096 2179 goto out_put_node; 2097 2180 ··· 2141 2234 2142 2235 gic_data.parts = parts; 2143 2236 gic_data.nr_parts = nr_parts; 2144 - 2145 - for (i = 0; i < gic_data.ppi_nr; i++) { 2146 - unsigned int irq; 2147 - struct partition_desc *desc; 2148 - struct irq_fwspec ppi_fwspec = { 2149 - .fwnode = gic_data.fwnode, 2150 - .param_count = 3, 2151 - .param = { 2152 - [0] = GIC_IRQ_TYPE_PARTITION, 2153 - [1] = i, 2154 - [2] = IRQ_TYPE_NONE, 2155 - }, 2156 - }; 2157 - 2158 - irq = irq_create_fwspec_mapping(&ppi_fwspec); 2159 - if (WARN_ON(!irq)) 2160 - continue; 2161 - desc = partition_create_desc(gic_data.fwnode, parts, nr_parts, 2162 - irq, &partition_domain_ops); 2163 - if (WARN_ON(!desc)) 2164 - continue; 2165 - 2166 - gic_data.ppi_descs[i] = desc; 2167 - } 2168 2237 2169 2238 out_put_node: 2170 2239 of_node_put(parts_node);