@@ -4856,6 +4856,38 @@ static struct syscore_ops its_syscore_ops = {
48564856 .resume = its_restore_enable ,
48574857};
48584858
4859+ static void __init __iomem * its_map_one (struct resource * res , int * err )
4860+ {
4861+ void __iomem * its_base ;
4862+ u32 val ;
4863+
4864+ its_base = ioremap (res -> start , SZ_64K );
4865+ if (!its_base ) {
4866+ pr_warn ("ITS@%pa: Unable to map ITS registers\n" , & res -> start );
4867+ * err = - ENOMEM ;
4868+ return NULL ;
4869+ }
4870+
4871+ val = readl_relaxed (its_base + GITS_PIDR2 ) & GIC_PIDR2_ARCH_MASK ;
4872+ if (val != 0x30 && val != 0x40 ) {
4873+ pr_warn ("ITS@%pa: No ITS detected, giving up\n" , & res -> start );
4874+ * err = - ENODEV ;
4875+ goto out_unmap ;
4876+ }
4877+
4878+ * err = its_force_quiescent (its_base );
4879+ if (* err ) {
4880+ pr_warn ("ITS@%pa: Failed to quiesce, giving up\n" , & res -> start );
4881+ goto out_unmap ;
4882+ }
4883+
4884+ return its_base ;
4885+
4886+ out_unmap :
4887+ iounmap (its_base );
4888+ return NULL ;
4889+ }
4890+
48594891static int its_init_domain (struct fwnode_handle * handle , struct its_node * its )
48604892{
48614893 struct irq_domain * inner_domain ;
@@ -4963,29 +4995,14 @@ static int __init its_probe_one(struct resource *res,
49634995{
49644996 struct its_node * its ;
49654997 void __iomem * its_base ;
4966- u32 val , ctlr ;
49674998 u64 baser , tmp , typer ;
49684999 struct page * page ;
5000+ u32 ctlr ;
49695001 int err ;
49705002
4971- its_base = ioremap (res -> start , SZ_64K );
4972- if (!its_base ) {
4973- pr_warn ("ITS@%pa: Unable to map ITS registers\n" , & res -> start );
4974- return - ENOMEM ;
4975- }
4976-
4977- val = readl_relaxed (its_base + GITS_PIDR2 ) & GIC_PIDR2_ARCH_MASK ;
4978- if (val != 0x30 && val != 0x40 ) {
4979- pr_warn ("ITS@%pa: No ITS detected, giving up\n" , & res -> start );
4980- err = - ENODEV ;
4981- goto out_unmap ;
4982- }
4983-
4984- err = its_force_quiescent (its_base );
4985- if (err ) {
4986- pr_warn ("ITS@%pa: Failed to quiesce, giving up\n" , & res -> start );
4987- goto out_unmap ;
4988- }
5003+ its_base = its_map_one (res , & err );
5004+ if (!its_base )
5005+ return err ;
49895006
49905007 pr_info ("ITS %pR\n" , res );
49915008
@@ -5241,13 +5258,31 @@ static int its_cpu_memreserve_lpi(unsigned int cpu)
52415258
52425259out :
52435260 /* Last CPU being brought up gets to issue the cleanup */
5244- if (cpumask_equal (& cpus_booted_once_mask , cpu_possible_mask ))
5261+ if (!IS_ENABLED (CONFIG_SMP ) ||
5262+ cpumask_equal (& cpus_booted_once_mask , cpu_possible_mask ))
52455263 schedule_work (& rdist_memreserve_cpuhp_cleanup_work );
52465264
52475265 gic_data_rdist ()-> flags |= RD_LOCAL_MEMRESERVE_DONE ;
52485266 return ret ;
52495267}
52505268
5269+ /* Mark all the BASER registers as invalid before they get reprogrammed */
5270+ static int __init its_reset_one (struct resource * res )
5271+ {
5272+ void __iomem * its_base ;
5273+ int err , i ;
5274+
5275+ its_base = its_map_one (res , & err );
5276+ if (!its_base )
5277+ return err ;
5278+
5279+ for (i = 0 ; i < GITS_BASER_NR_REGS ; i ++ )
5280+ gits_write_baser (0 , its_base + GITS_BASER + (i << 3 ));
5281+
5282+ iounmap (its_base );
5283+ return 0 ;
5284+ }
5285+
52515286static const struct of_device_id its_device_id [] = {
52525287 { .compatible = "arm,gic-v3-its" , },
52535288 {},
@@ -5258,6 +5293,26 @@ static int __init its_of_probe(struct device_node *node)
52585293 struct device_node * np ;
52595294 struct resource res ;
52605295
5296+ /*
5297+ * Make sure *all* the ITS are reset before we probe any, as
5298+ * they may be sharing memory. If any of the ITS fails to
5299+ * reset, don't even try to go any further, as this could
5300+ * result in something even worse.
5301+ */
5302+ for (np = of_find_matching_node (node , its_device_id ); np ;
5303+ np = of_find_matching_node (np , its_device_id )) {
5304+ int err ;
5305+
5306+ if (!of_device_is_available (np ) ||
5307+ !of_property_read_bool (np , "msi-controller" ) ||
5308+ of_address_to_resource (np , 0 , & res ))
5309+ continue ;
5310+
5311+ err = its_reset_one (& res );
5312+ if (err )
5313+ return err ;
5314+ }
5315+
52615316 for (np = of_find_matching_node (node , its_device_id ); np ;
52625317 np = of_find_matching_node (np , its_device_id )) {
52635318 if (!of_device_is_available (np ))
@@ -5420,11 +5475,35 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
54205475 return err ;
54215476}
54225477
5478+ static int __init its_acpi_reset (union acpi_subtable_headers * header ,
5479+ const unsigned long end )
5480+ {
5481+ struct acpi_madt_generic_translator * its_entry ;
5482+ struct resource res ;
5483+
5484+ its_entry = (struct acpi_madt_generic_translator * )header ;
5485+ res = (struct resource ) {
5486+ .start = its_entry -> base_address ,
5487+ .end = its_entry -> base_address + ACPI_GICV3_ITS_MEM_SIZE - 1 ,
5488+ .flags = IORESOURCE_MEM ,
5489+ };
5490+
5491+ return its_reset_one (& res );
5492+ }
5493+
54235494static void __init its_acpi_probe (void )
54245495{
54255496 acpi_table_parse_srat_its ();
5426- acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR ,
5427- gic_acpi_parse_madt_its , 0 );
5497+ /*
5498+ * Make sure *all* the ITS are reset before we probe any, as
5499+ * they may be sharing memory. If any of the ITS fails to
5500+ * reset, don't even try to go any further, as this could
5501+ * result in something even worse.
5502+ */
5503+ if (acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR ,
5504+ its_acpi_reset , 0 ) > 0 )
5505+ acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR ,
5506+ gic_acpi_parse_madt_its , 0 );
54285507 acpi_its_srat_maps_free ();
54295508}
54305509#else
0 commit comments