@@ -380,6 +380,15 @@ struct its_cmd_desc {
380
380
struct {
381
381
struct its_vpe * vpe ;
382
382
} its_invdb_cmd ;
383
+
384
+ struct {
385
+ struct its_vpe * vpe ;
386
+ u8 sgi ;
387
+ u8 priority ;
388
+ bool enable ;
389
+ bool group ;
390
+ bool clear ;
391
+ } its_vsgi_cmd ;
383
392
};
384
393
};
385
394
@@ -528,6 +537,31 @@ static void its_encode_db(struct its_cmd_block *cmd, bool db)
528
537
its_mask_encode (& cmd -> raw_cmd [2 ], db , 63 , 63 );
529
538
}
530
539
540
+ static void its_encode_sgi_intid (struct its_cmd_block * cmd , u8 sgi )
541
+ {
542
+ its_mask_encode (& cmd -> raw_cmd [0 ], sgi , 35 , 32 );
543
+ }
544
+
545
+ static void its_encode_sgi_priority (struct its_cmd_block * cmd , u8 prio )
546
+ {
547
+ its_mask_encode (& cmd -> raw_cmd [0 ], prio >> 4 , 23 , 20 );
548
+ }
549
+
550
+ static void its_encode_sgi_group (struct its_cmd_block * cmd , bool grp )
551
+ {
552
+ its_mask_encode (& cmd -> raw_cmd [0 ], grp , 10 , 10 );
553
+ }
554
+
555
+ static void its_encode_sgi_clear (struct its_cmd_block * cmd , bool clr )
556
+ {
557
+ its_mask_encode (& cmd -> raw_cmd [0 ], clr , 9 , 9 );
558
+ }
559
+
560
+ static void its_encode_sgi_enable (struct its_cmd_block * cmd , bool en )
561
+ {
562
+ its_mask_encode (& cmd -> raw_cmd [0 ], en , 8 , 8 );
563
+ }
564
+
531
565
static inline void its_fixup_cmd (struct its_cmd_block * cmd )
532
566
{
533
567
/* Let's fixup BE commands */
@@ -893,6 +927,26 @@ static struct its_vpe *its_build_invdb_cmd(struct its_node *its,
893
927
return valid_vpe (its , desc -> its_invdb_cmd .vpe );
894
928
}
895
929
930
+ static struct its_vpe * its_build_vsgi_cmd (struct its_node * its ,
931
+ struct its_cmd_block * cmd ,
932
+ struct its_cmd_desc * desc )
933
+ {
934
+ if (WARN_ON (!is_v4_1 (its )))
935
+ return NULL ;
936
+
937
+ its_encode_cmd (cmd , GITS_CMD_VSGI );
938
+ its_encode_vpeid (cmd , desc -> its_vsgi_cmd .vpe -> vpe_id );
939
+ its_encode_sgi_intid (cmd , desc -> its_vsgi_cmd .sgi );
940
+ its_encode_sgi_priority (cmd , desc -> its_vsgi_cmd .priority );
941
+ its_encode_sgi_group (cmd , desc -> its_vsgi_cmd .group );
942
+ its_encode_sgi_clear (cmd , desc -> its_vsgi_cmd .clear );
943
+ its_encode_sgi_enable (cmd , desc -> its_vsgi_cmd .enable );
944
+
945
+ its_fixup_cmd (cmd );
946
+
947
+ return valid_vpe (its , desc -> its_vsgi_cmd .vpe );
948
+ }
949
+
896
950
static u64 its_cmd_ptr_to_offset (struct its_node * its ,
897
951
struct its_cmd_block * ptr )
898
952
{
@@ -3870,6 +3924,26 @@ static struct irq_chip its_vpe_4_1_irq_chip = {
3870
3924
.irq_set_vcpu_affinity = its_vpe_4_1_set_vcpu_affinity ,
3871
3925
};
3872
3926
3927
+ static void its_configure_sgi (struct irq_data * d , bool clear )
3928
+ {
3929
+ struct its_vpe * vpe = irq_data_get_irq_chip_data (d );
3930
+ struct its_cmd_desc desc ;
3931
+
3932
+ desc .its_vsgi_cmd .vpe = vpe ;
3933
+ desc .its_vsgi_cmd .sgi = d -> hwirq ;
3934
+ desc .its_vsgi_cmd .priority = vpe -> sgi_config [d -> hwirq ].priority ;
3935
+ desc .its_vsgi_cmd .enable = vpe -> sgi_config [d -> hwirq ].enabled ;
3936
+ desc .its_vsgi_cmd .group = vpe -> sgi_config [d -> hwirq ].group ;
3937
+ desc .its_vsgi_cmd .clear = clear ;
3938
+
3939
+ /*
3940
+ * GICv4.1 allows us to send VSGI commands to any ITS as long as the
3941
+ * destination VPE is mapped there. Since we map them eagerly at
3942
+ * activation time, we're pretty sure the first GICv4.1 ITS will do.
3943
+ */
3944
+ its_send_single_vcommand (find_4_1_its (), its_build_vsgi_cmd , & desc );
3945
+ }
3946
+
3873
3947
static int its_sgi_set_affinity (struct irq_data * d ,
3874
3948
const struct cpumask * mask_val ,
3875
3949
bool force )
@@ -3920,13 +3994,29 @@ static void its_sgi_irq_domain_free(struct irq_domain *domain,
3920
3994
static int its_sgi_irq_domain_activate (struct irq_domain * domain ,
3921
3995
struct irq_data * d , bool reserve )
3922
3996
{
3997
+ /* Write out the initial SGI configuration */
3998
+ its_configure_sgi (d , false);
3923
3999
return 0 ;
3924
4000
}
3925
4001
3926
4002
static void its_sgi_irq_domain_deactivate (struct irq_domain * domain ,
3927
4003
struct irq_data * d )
3928
4004
{
3929
- /* Nothing to do */
4005
+ struct its_vpe * vpe = irq_data_get_irq_chip_data (d );
4006
+
4007
+ /*
4008
+ * The VSGI command is awkward:
4009
+ *
4010
+ * - To change the configuration, CLEAR must be set to false,
4011
+ * leaving the pending bit unchanged.
4012
+ * - To clear the pending bit, CLEAR must be set to true, leaving
4013
+ * the configuration unchanged.
4014
+ *
4015
+ * You just can't do both at once, hence the two commands below.
4016
+ */
4017
+ vpe -> sgi_config [d -> hwirq ].enabled = false;
4018
+ its_configure_sgi (d , false);
4019
+ its_configure_sgi (d , true);
3930
4020
}
3931
4021
3932
4022
static const struct irq_domain_ops its_sgi_domain_ops = {
0 commit comments