Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Date | Tue, 09 Apr 2024 09:16:34 -0000 | From | "tip-bot2 for Nianyao Tang" <> | Subject | [tip: irq/urgent] irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1 |
| |
The following commit has been merged into the irq/urgent branch of tip:
Commit-ID: 80e9963fb3b5509dfcabe9652d56bf4b35542055 Gitweb: https://git.kernel.org/tip/80e9963fb3b5509dfcabe9652d56bf4b35542055 Author: Nianyao Tang <tangnianyao@huawei.com> AuthorDate: Sat, 06 Apr 2024 02:27:37 Committer: Thomas Gleixner <tglx@linutronix.de> CommitterDate: Tue, 09 Apr 2024 11:11:18 +02:00
irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1
As per the GICv4.1 spec (Arm IHI 0069H, 5.3.19):
"A VMAPP with {V, Alloc}=={0, x} is self-synchronizing, This means the ITS command queue does not show the command as consumed until all of its effects are completed."
Furthermore, VSYNC is allowed to deliver an SError when referencing a non existent VPE.
By these definitions, a VMAPP followed by a VSYNC is a bug, as the later references a VPE that has been unmapped by the former.
Fix it by eliding the VSYNC in this scenario.
Fixes: 64edfaa9a234 ("irqchip/gic-v4.1: Implement the v4.1 flavour of VMAPP") Signed-off-by: Nianyao Tang <tangnianyao@huawei.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Zenghui Yu <yuzenghui@huawei.com> Link: https://lore.kernel.org/r/20240406022737.3898763-1-tangnianyao@huawei.com --- drivers/irqchip/irq-gic-v3-its.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index fca888b..2a537cb 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -786,6 +786,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, struct its_cmd_block *cmd, struct its_cmd_desc *desc) { + struct its_vpe *vpe = valid_vpe(its, desc->its_vmapp_cmd.vpe); unsigned long vpt_addr, vconf_addr; u64 target; bool alloc; @@ -798,6 +799,11 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, if (is_v4_1(its)) { alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); its_encode_alloc(cmd, alloc); + /* + * Unmapping a VPE is self-synchronizing on GICv4.1, + * no need to issue a VSYNC. + */ + vpe = NULL; } goto out; @@ -832,7 +838,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, out: its_fixup_cmd(cmd); - return valid_vpe(its, desc->its_vmapp_cmd.vpe); + return vpe; } static struct its_vpe *its_build_vmapti_cmd(struct its_node *its,
| ![\](/images/icornerr.gif) |