@@ -97,9 +97,14 @@ struct its_device;
97
97
* The ITS structure - contains most of the infrastructure, with the
98
98
* top-level MSI domain, the command queue, the collections, and the
99
99
* list of devices writing to it.
100
+ *
101
+ * dev_alloc_lock has to be taken for device allocations, while the
102
+ * spinlock must be taken to parse data structures such as the device
103
+ * list.
100
104
*/
101
105
struct its_node {
102
106
raw_spinlock_t lock ;
107
+ struct mutex dev_alloc_lock ;
103
108
struct list_head entry ;
104
109
void __iomem * base ;
105
110
phys_addr_t phys_base ;
@@ -156,6 +161,7 @@ struct its_device {
156
161
void * itt ;
157
162
u32 nr_ites ;
158
163
u32 device_id ;
164
+ bool shared ;
159
165
};
160
166
161
167
static struct {
@@ -1580,6 +1586,9 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids)
1580
1586
nr_irqs /= 2 ;
1581
1587
} while (nr_irqs > 0 );
1582
1588
1589
+ if (!nr_irqs )
1590
+ err = - ENOSPC ;
1591
+
1583
1592
if (err )
1584
1593
goto out ;
1585
1594
@@ -2059,6 +2068,29 @@ static int __init allocate_lpi_tables(void)
2059
2068
return 0 ;
2060
2069
}
2061
2070
2071
+ static u64 its_clear_vpend_valid (void __iomem * vlpi_base )
2072
+ {
2073
+ u32 count = 1000000 ; /* 1s! */
2074
+ bool clean ;
2075
+ u64 val ;
2076
+
2077
+ val = gits_read_vpendbaser (vlpi_base + GICR_VPENDBASER );
2078
+ val &= ~GICR_VPENDBASER_Valid ;
2079
+ gits_write_vpendbaser (val , vlpi_base + GICR_VPENDBASER );
2080
+
2081
+ do {
2082
+ val = gits_read_vpendbaser (vlpi_base + GICR_VPENDBASER );
2083
+ clean = !(val & GICR_VPENDBASER_Dirty );
2084
+ if (!clean ) {
2085
+ count -- ;
2086
+ cpu_relax ();
2087
+ udelay (1 );
2088
+ }
2089
+ } while (!clean && count );
2090
+
2091
+ return val ;
2092
+ }
2093
+
2062
2094
static void its_cpu_init_lpis (void )
2063
2095
{
2064
2096
void __iomem * rbase = gic_data_rdist_rd_base ();
@@ -2144,6 +2176,30 @@ static void its_cpu_init_lpis(void)
2144
2176
val |= GICR_CTLR_ENABLE_LPIS ;
2145
2177
writel_relaxed (val , rbase + GICR_CTLR );
2146
2178
2179
+ if (gic_rdists -> has_vlpis ) {
2180
+ void __iomem * vlpi_base = gic_data_rdist_vlpi_base ();
2181
+
2182
+ /*
2183
+ * It's possible for CPU to receive VLPIs before it is
2184
+ * sheduled as a vPE, especially for the first CPU, and the
2185
+ * VLPI with INTID larger than 2^(IDbits+1) will be considered
2186
+ * as out of range and dropped by GIC.
2187
+ * So we initialize IDbits to known value to avoid VLPI drop.
2188
+ */
2189
+ val = (LPI_NRBITS - 1 ) & GICR_VPROPBASER_IDBITS_MASK ;
2190
+ pr_debug ("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n" ,
2191
+ smp_processor_id (), val );
2192
+ gits_write_vpropbaser (val , vlpi_base + GICR_VPROPBASER );
2193
+
2194
+ /*
2195
+ * Also clear Valid bit of GICR_VPENDBASER, in case some
2196
+ * ancient programming gets left in and has possibility of
2197
+ * corrupting memory.
2198
+ */
2199
+ val = its_clear_vpend_valid (vlpi_base );
2200
+ WARN_ON (val & GICR_VPENDBASER_Dirty );
2201
+ }
2202
+
2147
2203
/* Make sure the GIC has seen the above */
2148
2204
dsb (sy );
2149
2205
out :
@@ -2422,6 +2478,7 @@ static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
2422
2478
struct its_device * its_dev ;
2423
2479
struct msi_domain_info * msi_info ;
2424
2480
u32 dev_id ;
2481
+ int err = 0 ;
2425
2482
2426
2483
/*
2427
2484
* We ignore "dev" entierely, and rely on the dev_id that has
@@ -2444,25 +2501,30 @@ static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
2444
2501
return - EINVAL ;
2445
2502
}
2446
2503
2504
+ mutex_lock (& its -> dev_alloc_lock );
2447
2505
its_dev = its_find_device (its , dev_id );
2448
2506
if (its_dev ) {
2449
2507
/*
2450
2508
* We already have seen this ID, probably through
2451
2509
* another alias (PCI bridge of some sort). No need to
2452
2510
* create the device.
2453
2511
*/
2512
+ its_dev -> shared = true;
2454
2513
pr_debug ("Reusing ITT for devID %x\n" , dev_id );
2455
2514
goto out ;
2456
2515
}
2457
2516
2458
2517
its_dev = its_create_device (its , dev_id , nvec , true);
2459
- if (!its_dev )
2460
- return - ENOMEM ;
2518
+ if (!its_dev ) {
2519
+ err = - ENOMEM ;
2520
+ goto out ;
2521
+ }
2461
2522
2462
2523
pr_debug ("ITT %d entries, %d bits\n" , nvec , ilog2 (nvec ));
2463
2524
out :
2525
+ mutex_unlock (& its -> dev_alloc_lock );
2464
2526
info -> scratchpad [0 ].ptr = its_dev ;
2465
- return 0 ;
2527
+ return err ;
2466
2528
}
2467
2529
2468
2530
static struct msi_domain_ops its_msi_domain_ops = {
@@ -2566,6 +2628,7 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
2566
2628
{
2567
2629
struct irq_data * d = irq_domain_get_irq_data (domain , virq );
2568
2630
struct its_device * its_dev = irq_data_get_irq_chip_data (d );
2631
+ struct its_node * its = its_dev -> its ;
2569
2632
int i ;
2570
2633
2571
2634
for (i = 0 ; i < nr_irqs ; i ++ ) {
@@ -2580,8 +2643,14 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
2580
2643
irq_domain_reset_irq_data (data );
2581
2644
}
2582
2645
2583
- /* If all interrupts have been freed, start mopping the floor */
2584
- if (bitmap_empty (its_dev -> event_map .lpi_map ,
2646
+ mutex_lock (& its -> dev_alloc_lock );
2647
+
2648
+ /*
2649
+ * If all interrupts have been freed, start mopping the
2650
+ * floor. This is conditionned on the device not being shared.
2651
+ */
2652
+ if (!its_dev -> shared &&
2653
+ bitmap_empty (its_dev -> event_map .lpi_map ,
2585
2654
its_dev -> event_map .nr_lpis )) {
2586
2655
its_lpi_free (its_dev -> event_map .lpi_map ,
2587
2656
its_dev -> event_map .lpi_base ,
@@ -2593,6 +2662,8 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
2593
2662
its_free_device (its_dev );
2594
2663
}
2595
2664
2665
+ mutex_unlock (& its -> dev_alloc_lock );
2666
+
2596
2667
irq_domain_free_irqs_parent (domain , virq , nr_irqs );
2597
2668
}
2598
2669
@@ -2755,26 +2826,11 @@ static void its_vpe_schedule(struct its_vpe *vpe)
2755
2826
static void its_vpe_deschedule (struct its_vpe * vpe )
2756
2827
{
2757
2828
void __iomem * vlpi_base = gic_data_rdist_vlpi_base ();
2758
- u32 count = 1000000 ; /* 1s! */
2759
- bool clean ;
2760
2829
u64 val ;
2761
2830
2762
- /* We're being scheduled out */
2763
- val = gits_read_vpendbaser (vlpi_base + GICR_VPENDBASER );
2764
- val &= ~GICR_VPENDBASER_Valid ;
2765
- gits_write_vpendbaser (val , vlpi_base + GICR_VPENDBASER );
2766
-
2767
- do {
2768
- val = gits_read_vpendbaser (vlpi_base + GICR_VPENDBASER );
2769
- clean = !(val & GICR_VPENDBASER_Dirty );
2770
- if (!clean ) {
2771
- count -- ;
2772
- cpu_relax ();
2773
- udelay (1 );
2774
- }
2775
- } while (!clean && count );
2831
+ val = its_clear_vpend_valid (vlpi_base );
2776
2832
2777
- if (unlikely (! clean && ! count )) {
2833
+ if (unlikely (val & GICR_VPENDBASER_Dirty )) {
2778
2834
pr_err_ratelimited ("ITS virtual pending table not cleaning\n" );
2779
2835
vpe -> idai = false;
2780
2836
vpe -> pending_last = true;
@@ -3517,6 +3573,7 @@ static int __init its_probe_one(struct resource *res,
3517
3573
}
3518
3574
3519
3575
raw_spin_lock_init (& its -> lock );
3576
+ mutex_init (& its -> dev_alloc_lock );
3520
3577
INIT_LIST_HEAD (& its -> entry );
3521
3578
INIT_LIST_HEAD (& its -> its_device_list );
3522
3579
typer = gic_read_typer (its_base + GITS_TYPER );
0 commit comments