@@ -207,6 +207,11 @@ static bool require_its_list_vmovp(struct its_vm *vm, struct its_node *its)
207207 return (gic_rdists -> has_rvpeid || vm -> vlpi_count [its -> list_nr ]);
208208}
209209
210+ static bool rdists_support_shareable (void )
211+ {
212+ return !(gic_rdists -> flags & RDIST_FLAGS_FORCE_NON_SHAREABLE );
213+ }
214+
210215static u16 get_its_list (struct its_vm * vm )
211216{
212217 struct its_node * its ;
@@ -2710,10 +2715,12 @@ static u64 inherit_vpe_l1_table_from_its(void)
27102715 break ;
27112716 }
27122717 val |= FIELD_PREP (GICR_VPROPBASER_4_1_ADDR , addr >> 12 );
2713- val |= FIELD_PREP (GICR_VPROPBASER_SHAREABILITY_MASK ,
2714- FIELD_GET (GITS_BASER_SHAREABILITY_MASK , baser ));
2715- val |= FIELD_PREP (GICR_VPROPBASER_INNER_CACHEABILITY_MASK ,
2716- FIELD_GET (GITS_BASER_INNER_CACHEABILITY_MASK , baser ));
2718+ if (rdists_support_shareable ()) {
2719+ val |= FIELD_PREP (GICR_VPROPBASER_SHAREABILITY_MASK ,
2720+ FIELD_GET (GITS_BASER_SHAREABILITY_MASK , baser ));
2721+ val |= FIELD_PREP (GICR_VPROPBASER_INNER_CACHEABILITY_MASK ,
2722+ FIELD_GET (GITS_BASER_INNER_CACHEABILITY_MASK , baser ));
2723+ }
27172724 val |= FIELD_PREP (GICR_VPROPBASER_4_1_SIZE , GITS_BASER_NR_PAGES (baser ) - 1 );
27182725
27192726 return val ;
@@ -2936,8 +2943,10 @@ static int allocate_vpe_l1_table(void)
29362943 WARN_ON (!IS_ALIGNED (pa , psz ));
29372944
29382945 val |= FIELD_PREP (GICR_VPROPBASER_4_1_ADDR , pa >> 12 );
2939- val |= GICR_VPROPBASER_RaWb ;
2940- val |= GICR_VPROPBASER_InnerShareable ;
2946+ if (rdists_support_shareable ()) {
2947+ val |= GICR_VPROPBASER_RaWb ;
2948+ val |= GICR_VPROPBASER_InnerShareable ;
2949+ }
29412950 val |= GICR_VPROPBASER_4_1_Z ;
29422951 val |= GICR_VPROPBASER_4_1_VALID ;
29432952
@@ -3126,7 +3135,7 @@ static void its_cpu_init_lpis(void)
31263135 gicr_write_propbaser (val , rbase + GICR_PROPBASER );
31273136 tmp = gicr_read_propbaser (rbase + GICR_PROPBASER );
31283137
3129- if (gic_rdists -> flags & RDIST_FLAGS_FORCE_NON_SHAREABLE )
3138+ if (! rdists_support_shareable () )
31303139 tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK ;
31313140
31323141 if ((tmp ^ val ) & GICR_PROPBASER_SHAREABILITY_MASK ) {
@@ -3153,7 +3162,7 @@ static void its_cpu_init_lpis(void)
31533162 gicr_write_pendbaser (val , rbase + GICR_PENDBASER );
31543163 tmp = gicr_read_pendbaser (rbase + GICR_PENDBASER );
31553164
3156- if (gic_rdists -> flags & RDIST_FLAGS_FORCE_NON_SHAREABLE )
3165+ if (! rdists_support_shareable () )
31573166 tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK ;
31583167
31593168 if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK )) {
@@ -3817,8 +3826,9 @@ static int its_vpe_set_affinity(struct irq_data *d,
38173826 bool force )
38183827{
38193828 struct its_vpe * vpe = irq_data_get_irq_chip_data (d );
3820- int from , cpu = cpumask_first ( mask_val ) ;
3829+ struct cpumask common , * table_mask ;
38213830 unsigned long flags ;
3831+ int from , cpu ;
38223832
38233833 /*
38243834 * Changing affinity is mega expensive, so let's be as lazy as
@@ -3834,19 +3844,22 @@ static int its_vpe_set_affinity(struct irq_data *d,
38343844 * taken on any vLPI handling path that evaluates vpe->col_idx.
38353845 */
38363846 from = vpe_to_cpuid_lock (vpe , & flags );
3837- if (from == cpu )
3838- goto out ;
3839-
3840- vpe -> col_idx = cpu ;
3847+ table_mask = gic_data_rdist_cpu (from )-> vpe_table_mask ;
38413848
38423849 /*
3843- * GICv4.1 allows us to skip VMOVP if moving to a cpu whose RD
3844- * is sharing its VPE table with the current one .
3850+ * If we are offered another CPU in the same GICv4.1 ITS
3851+ * affinity, pick this one. Otherwise, any CPU will do .
38453852 */
3846- if (gic_data_rdist_cpu (cpu )-> vpe_table_mask &&
3847- cpumask_test_cpu (from , gic_data_rdist_cpu (cpu )-> vpe_table_mask ))
3853+ if (table_mask && cpumask_and (& common , mask_val , table_mask ))
3854+ cpu = cpumask_test_cpu (from , & common ) ? from : cpumask_first (& common );
3855+ else
3856+ cpu = cpumask_first (mask_val );
3857+
3858+ if (from == cpu )
38483859 goto out ;
38493860
3861+ vpe -> col_idx = cpu ;
3862+
38503863 its_send_vmovp (vpe );
38513864 its_vpe_db_proxy_move (vpe , from , cpu );
38523865
@@ -3880,14 +3893,18 @@ static void its_vpe_schedule(struct its_vpe *vpe)
38803893 val = virt_to_phys (page_address (vpe -> its_vm -> vprop_page )) &
38813894 GENMASK_ULL (51 , 12 );
38823895 val |= (LPI_NRBITS - 1 ) & GICR_VPROPBASER_IDBITS_MASK ;
3883- val |= GICR_VPROPBASER_RaWb ;
3884- val |= GICR_VPROPBASER_InnerShareable ;
3896+ if (rdists_support_shareable ()) {
3897+ val |= GICR_VPROPBASER_RaWb ;
3898+ val |= GICR_VPROPBASER_InnerShareable ;
3899+ }
38853900 gicr_write_vpropbaser (val , vlpi_base + GICR_VPROPBASER );
38863901
38873902 val = virt_to_phys (page_address (vpe -> vpt_page )) &
38883903 GENMASK_ULL (51 , 16 );
3889- val |= GICR_VPENDBASER_RaWaWb ;
3890- val |= GICR_VPENDBASER_InnerShareable ;
3904+ if (rdists_support_shareable ()) {
3905+ val |= GICR_VPENDBASER_RaWaWb ;
3906+ val |= GICR_VPENDBASER_InnerShareable ;
3907+ }
38913908 /*
38923909 * There is no good way of finding out if the pending table is
38933910 * empty as we can race against the doorbell interrupt very
@@ -5078,6 +5095,8 @@ static int __init its_probe_one(struct its_node *its)
50785095 u32 ctlr ;
50795096 int err ;
50805097
5098+ its_enable_quirks (its );
5099+
50815100 if (is_v4 (its )) {
50825101 if (!(its -> typer & GITS_TYPER_VMOVP )) {
50835102 err = its_compute_its_list_map (its );
@@ -5429,7 +5448,6 @@ static int __init its_of_probe(struct device_node *node)
54295448 if (!its )
54305449 return - ENOMEM ;
54315450
5432- its_enable_quirks (its );
54335451 err = its_probe_one (its );
54345452 if (err ) {
54355453 its_node_destroy (its );
0 commit comments