@@ -227,11 +227,27 @@ static struct its_vlpi_map *dev_event_to_vlpi_map(struct its_device *its_dev,
227
227
return & its_dev -> event_map .vlpi_maps [event ];
228
228
}
229
229
230
- static struct its_collection * irq_to_col (struct irq_data * d )
230
+ static struct its_vlpi_map * get_vlpi_map (struct irq_data * d )
231
+ {
232
+ if (irqd_is_forwarded_to_vcpu (d )) {
233
+ struct its_device * its_dev = irq_data_get_irq_chip_data (d );
234
+ u32 event = its_get_event_id (d );
235
+
236
+ return dev_event_to_vlpi_map (its_dev , event );
237
+ }
238
+
239
+ return NULL ;
240
+ }
241
+
242
+ static int irq_to_cpuid (struct irq_data * d )
231
243
{
232
244
struct its_device * its_dev = irq_data_get_irq_chip_data (d );
245
+ struct its_vlpi_map * map = get_vlpi_map (d );
246
+
247
+ if (map )
248
+ return map -> vpe -> col_idx ;
233
249
234
- return dev_event_to_col ( its_dev , its_get_event_id (d )) ;
250
+ return its_dev -> event_map . col_map [ its_get_event_id (d )] ;
235
251
}
236
252
237
253
static struct its_collection * valid_col (struct its_collection * col )
@@ -1269,18 +1285,6 @@ static void its_send_invdb(struct its_node *its, struct its_vpe *vpe)
1269
1285
/*
1270
1286
* irqchip functions - assumes MSI, mostly.
1271
1287
*/
1272
- static struct its_vlpi_map * get_vlpi_map (struct irq_data * d )
1273
- {
1274
- if (irqd_is_forwarded_to_vcpu (d )) {
1275
- struct its_device * its_dev = irq_data_get_irq_chip_data (d );
1276
- u32 event = its_get_event_id (d );
1277
-
1278
- return dev_event_to_vlpi_map (its_dev , event );
1279
- }
1280
-
1281
- return NULL ;
1282
- }
1283
-
1284
1288
static void lpi_write_config (struct irq_data * d , u8 clr , u8 set )
1285
1289
{
1286
1290
struct its_vlpi_map * map = get_vlpi_map (d );
@@ -1323,13 +1327,25 @@ static void wait_for_syncr(void __iomem *rdbase)
1323
1327
1324
1328
static void direct_lpi_inv (struct irq_data * d )
1325
1329
{
1326
- struct its_collection * col ;
1330
+ struct its_vlpi_map * map = get_vlpi_map ( d ) ;
1327
1331
void __iomem * rdbase ;
1332
+ u64 val ;
1333
+
1334
+ if (map ) {
1335
+ struct its_device * its_dev = irq_data_get_irq_chip_data (d );
1336
+
1337
+ WARN_ON (!is_v4_1 (its_dev -> its ));
1338
+
1339
+ val = GICR_INVLPIR_V ;
1340
+ val |= FIELD_PREP (GICR_INVLPIR_VPEID , map -> vpe -> vpe_id );
1341
+ val |= FIELD_PREP (GICR_INVLPIR_INTID , map -> vintid );
1342
+ } else {
1343
+ val = d -> hwirq ;
1344
+ }
1328
1345
1329
1346
/* Target the redistributor this LPI is currently routed to */
1330
- col = irq_to_col (d );
1331
- rdbase = per_cpu_ptr (gic_rdists -> rdist , col -> col_id )-> rd_base ;
1332
- gic_write_lpir (d -> hwirq , rdbase + GICR_INVLPIR );
1347
+ rdbase = per_cpu_ptr (gic_rdists -> rdist , irq_to_cpuid (d ))-> rd_base ;
1348
+ gic_write_lpir (val , rdbase + GICR_INVLPIR );
1333
1349
1334
1350
wait_for_syncr (rdbase );
1335
1351
}
@@ -1339,7 +1355,8 @@ static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
1339
1355
struct its_device * its_dev = irq_data_get_irq_chip_data (d );
1340
1356
1341
1357
lpi_write_config (d , clr , set );
1342
- if (gic_rdists -> has_direct_lpi && !irqd_is_forwarded_to_vcpu (d ))
1358
+ if (gic_rdists -> has_direct_lpi &&
1359
+ (is_v4_1 (its_dev -> its ) || !irqd_is_forwarded_to_vcpu (d )))
1343
1360
direct_lpi_inv (d );
1344
1361
else if (!irqd_is_forwarded_to_vcpu (d ))
1345
1362
its_send_inv (its_dev , its_get_event_id (d ));
0 commit comments