Skip to content

Commit 8424312

Browse files
Zenghui YuMarc Zyngier
authored andcommitted
irqchip/gic-v3-its: Use the exact ITSList for VMOVP
On a system without Single VMOVP support (say GITS_TYPER.VMOVP == 0), we will map vPEs only on ITSs that will actually control interrupts for the given VM. And when moving a vPE, the VMOVP command will be issued only for those ITSs. But when issuing VMOVPs we seemed fail to present the exact ITSList to ITSs who are actually included in the synchronization operation. The its_list_map we're currently using includes all ITSs in the system, even though some of them don't have the corresponding vPE mapping at all. Introduce get_its_list() to get the per-VM its_list_map, to indicate which ITSs have vPE mappings for the given VM, and use this map as the expected ITSList when building VMOVP. This is hopefully a performance gain not to do some synchronization with those unsuspecting ITSs. And initialize the whole command descriptor to zero at beginning, since the seq_num and its_list should be RES0 when GITS_TYPER.VMOVP == 1. Signed-off-by: Zenghui Yu <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent bb0fed1 commit 8424312

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,22 @@ static DEFINE_IDA(its_vpeid_ida);
175175
#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
176176
#define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
177177

178+
static u16 get_its_list(struct its_vm *vm)
179+
{
180+
struct its_node *its;
181+
unsigned long its_list = 0;
182+
183+
list_for_each_entry(its, &its_nodes, entry) {
184+
if (!its->is_v4)
185+
continue;
186+
187+
if (vm->vlpi_count[its->list_nr])
188+
__set_bit(its->list_nr, &its_list);
189+
}
190+
191+
return (u16)its_list;
192+
}
193+
178194
static struct its_collection *dev_event_to_col(struct its_device *its_dev,
179195
u32 event)
180196
{
@@ -976,17 +992,15 @@ static void its_send_vmapp(struct its_node *its,
976992

977993
static void its_send_vmovp(struct its_vpe *vpe)
978994
{
979-
struct its_cmd_desc desc;
995+
struct its_cmd_desc desc = {};
980996
struct its_node *its;
981997
unsigned long flags;
982998
int col_id = vpe->col_idx;
983999

9841000
desc.its_vmovp_cmd.vpe = vpe;
985-
desc.its_vmovp_cmd.its_list = (u16)its_list_map;
9861001

9871002
if (!its_list_map) {
9881003
its = list_first_entry(&its_nodes, struct its_node, entry);
989-
desc.its_vmovp_cmd.seq_num = 0;
9901004
desc.its_vmovp_cmd.col = &its->collections[col_id];
9911005
its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
9921006
return;
@@ -1003,6 +1017,7 @@ static void its_send_vmovp(struct its_vpe *vpe)
10031017
raw_spin_lock_irqsave(&vmovp_lock, flags);
10041018

10051019
desc.its_vmovp_cmd.seq_num = vmovp_seq_num++;
1020+
desc.its_vmovp_cmd.its_list = get_its_list(vpe->its_vm);
10061021

10071022
/* Emit VMOVPs */
10081023
list_for_each_entry(its, &its_nodes, entry) {

0 commit comments

Comments
 (0)