aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index fee7d13a5587..63cd0f2b8707 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1836,6 +1836,78 @@ static int __init its_of_probe(struct device_node *node)
1836 1836
1837#define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K) 1837#define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K)
1838 1838
1839#if defined(CONFIG_ACPI_NUMA) && (ACPI_CA_VERSION >= 0x20170531)
1840struct its_srat_map {
1841 /* numa node id */
1842 u32 numa_node;
1843 /* GIC ITS ID */
1844 u32 its_id;
1845};
1846
1847static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata;
1848static int its_in_srat __initdata;
1849
1850static int __init acpi_get_its_numa_node(u32 its_id)
1851{
1852 int i;
1853
1854 for (i = 0; i < its_in_srat; i++) {
1855 if (its_id == its_srat_maps[i].its_id)
1856 return its_srat_maps[i].numa_node;
1857 }
1858 return NUMA_NO_NODE;
1859}
1860
1861static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
1862 const unsigned long end)
1863{
1864 int node;
1865 struct acpi_srat_gic_its_affinity *its_affinity;
1866
1867 its_affinity = (struct acpi_srat_gic_its_affinity *)header;
1868 if (!its_affinity)
1869 return -EINVAL;
1870
1871 if (its_affinity->header.length < sizeof(*its_affinity)) {
1872 pr_err("SRAT: Invalid header length %d in ITS affinity\n",
1873 its_affinity->header.length);
1874 return -EINVAL;
1875 }
1876
1877 if (its_in_srat >= MAX_NUMNODES) {
1878 pr_err("SRAT: ITS affinity exceeding max count[%d]\n",
1879 MAX_NUMNODES);
1880 return -EINVAL;
1881 }
1882
1883 node = acpi_map_pxm_to_node(its_affinity->proximity_domain);
1884
1885 if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
1886 pr_err("SRAT: Invalid NUMA node %d in ITS affinity\n", node);
1887 return 0;
1888 }
1889
1890 its_srat_maps[its_in_srat].numa_node = node;
1891 its_srat_maps[its_in_srat].its_id = its_affinity->its_id;
1892 its_in_srat++;
1893 pr_info("SRAT: PXM %d -> ITS %d -> Node %d\n",
1894 its_affinity->proximity_domain, its_affinity->its_id, node);
1895
1896 return 0;
1897}
1898
1899static void __init acpi_table_parse_srat_its(void)
1900{
1901 acpi_table_parse_entries(ACPI_SIG_SRAT,
1902 sizeof(struct acpi_table_srat),
1903 ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
1904 gic_acpi_parse_srat_its, 0);
1905}
1906#else
1907static void __init acpi_table_parse_srat_its(void) { }
1908static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; }
1909#endif
1910
1839static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header, 1911static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
1840 const unsigned long end) 1912 const unsigned long end)
1841{ 1913{
@@ -1864,7 +1936,8 @@ static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
1864 goto dom_err; 1936 goto dom_err;
1865 } 1937 }
1866 1938
1867 err = its_probe_one(&res, dom_handle, NUMA_NO_NODE); 1939 err = its_probe_one(&res, dom_handle,
1940 acpi_get_its_numa_node(its_entry->translation_id));
1868 if (!err) 1941 if (!err)
1869 return 0; 1942 return 0;
1870 1943
@@ -1876,6 +1949,7 @@ dom_err:
1876 1949
1877static void __init its_acpi_probe(void) 1950static void __init its_acpi_probe(void)
1878{ 1951{
1952 acpi_table_parse_srat_its();
1879 acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, 1953 acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
1880 gic_acpi_parse_madt_its, 0); 1954 gic_acpi_parse_madt_its, 0);
1881} 1955}