@@ -213,6 +213,16 @@ struct its_cmd_desc {
213
213
struct its_collection * col ;
214
214
} its_invall_cmd ;
215
215
216
+ struct {
217
+ struct its_vpe * vpe ;
218
+ } its_vinvall_cmd ;
219
+
220
+ struct {
221
+ struct its_vpe * vpe ;
222
+ struct its_collection * col ;
223
+ bool valid ;
224
+ } its_vmapp_cmd ;
225
+
216
226
struct {
217
227
struct its_vpe * vpe ;
218
228
struct its_device * dev ;
@@ -318,6 +328,16 @@ static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
318
328
its_mask_encode (& cmd -> raw_cmd [2 ], db_valid , 0 , 0 );
319
329
}
320
330
331
+ static void its_encode_vpt_addr (struct its_cmd_block * cmd , u64 vpt_pa )
332
+ {
333
+ its_mask_encode (& cmd -> raw_cmd [3 ], vpt_pa >> 16 , 50 , 16 );
334
+ }
335
+
336
+ static void its_encode_vpt_size (struct its_cmd_block * cmd , u8 vpt_size )
337
+ {
338
+ its_mask_encode (& cmd -> raw_cmd [3 ], vpt_size , 4 , 0 );
339
+ }
340
+
321
341
static inline void its_fixup_cmd (struct its_cmd_block * cmd )
322
342
{
323
343
/* Let's fixup BE commands */
@@ -476,6 +496,36 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
476
496
return NULL ;
477
497
}
478
498
499
+ static struct its_vpe * its_build_vinvall_cmd (struct its_cmd_block * cmd ,
500
+ struct its_cmd_desc * desc )
501
+ {
502
+ its_encode_cmd (cmd , GITS_CMD_VINVALL );
503
+ its_encode_vpeid (cmd , desc -> its_vinvall_cmd .vpe -> vpe_id );
504
+
505
+ its_fixup_cmd (cmd );
506
+
507
+ return desc -> its_vinvall_cmd .vpe ;
508
+ }
509
+
510
+ static struct its_vpe * its_build_vmapp_cmd (struct its_cmd_block * cmd ,
511
+ struct its_cmd_desc * desc )
512
+ {
513
+ unsigned long vpt_addr ;
514
+
515
+ vpt_addr = virt_to_phys (page_address (desc -> its_vmapp_cmd .vpe -> vpt_page ));
516
+
517
+ its_encode_cmd (cmd , GITS_CMD_VMAPP );
518
+ its_encode_vpeid (cmd , desc -> its_vmapp_cmd .vpe -> vpe_id );
519
+ its_encode_valid (cmd , desc -> its_vmapp_cmd .valid );
520
+ its_encode_target (cmd , desc -> its_vmapp_cmd .col -> target_address );
521
+ its_encode_vpt_addr (cmd , vpt_addr );
522
+ its_encode_vpt_size (cmd , LPI_NRBITS - 1 );
523
+
524
+ its_fixup_cmd (cmd );
525
+
526
+ return desc -> its_vmapp_cmd .vpe ;
527
+ }
528
+
479
529
static struct its_vpe * its_build_vmapti_cmd (struct its_cmd_block * cmd ,
480
530
struct its_cmd_desc * desc )
481
531
{
@@ -803,6 +853,37 @@ static void its_send_vmovi(struct its_device *dev, u32 id)
803
853
its_send_single_vcommand (dev -> its , its_build_vmovi_cmd , & desc );
804
854
}
805
855
856
+ static void its_send_vmapp (struct its_vpe * vpe , bool valid )
857
+ {
858
+ struct its_cmd_desc desc ;
859
+ struct its_node * its ;
860
+
861
+ desc .its_vmapp_cmd .vpe = vpe ;
862
+ desc .its_vmapp_cmd .valid = valid ;
863
+
864
+ list_for_each_entry (its , & its_nodes , entry ) {
865
+ if (!its -> is_v4 )
866
+ continue ;
867
+
868
+ desc .its_vmapp_cmd .col = & its -> collections [vpe -> col_idx ];
869
+ its_send_single_vcommand (its , its_build_vmapp_cmd , & desc );
870
+ }
871
+ }
872
+
873
+ static void its_send_vinvall (struct its_vpe * vpe )
874
+ {
875
+ struct its_cmd_desc desc ;
876
+ struct its_node * its ;
877
+
878
+ desc .its_vinvall_cmd .vpe = vpe ;
879
+
880
+ list_for_each_entry (its , & its_nodes , entry ) {
881
+ if (!its -> is_v4 )
882
+ continue ;
883
+ its_send_single_vcommand (its , its_build_vinvall_cmd , & desc );
884
+ }
885
+ }
886
+
806
887
/*
807
888
* irqchip functions - assumes MSI, mostly.
808
889
*/
@@ -2203,9 +2284,30 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
2203
2284
return err ;
2204
2285
}
2205
2286
2287
+ static void its_vpe_irq_domain_activate (struct irq_domain * domain ,
2288
+ struct irq_data * d )
2289
+ {
2290
+ struct its_vpe * vpe = irq_data_get_irq_chip_data (d );
2291
+
2292
+ /* Map the VPE to the first possible CPU */
2293
+ vpe -> col_idx = cpumask_first (cpu_online_mask );
2294
+ its_send_vmapp (vpe , true);
2295
+ its_send_vinvall (vpe );
2296
+ }
2297
+
2298
+ static void its_vpe_irq_domain_deactivate (struct irq_domain * domain ,
2299
+ struct irq_data * d )
2300
+ {
2301
+ struct its_vpe * vpe = irq_data_get_irq_chip_data (d );
2302
+
2303
+ its_send_vmapp (vpe , false);
2304
+ }
2305
+
2206
2306
static const struct irq_domain_ops its_vpe_domain_ops = {
2207
2307
.alloc = its_vpe_irq_domain_alloc ,
2208
2308
.free = its_vpe_irq_domain_free ,
2309
+ .activate = its_vpe_irq_domain_activate ,
2310
+ .deactivate = its_vpe_irq_domain_deactivate ,
2209
2311
};
2210
2312
2211
2313
static int its_force_quiescent (void __iomem * base )
0 commit comments