]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/6.6.26/risc-v-kvm-fix-aplic-setipnum_le-be-write-emulation.patch
Linux 6.6.26
[thirdparty/kernel/stable-queue.git] / releases / 6.6.26 / risc-v-kvm-fix-aplic-setipnum_le-be-write-emulation.patch
1 From d8dd9f113e16bef3b29c9dcceb584a6f144f55e4 Mon Sep 17 00:00:00 2001
2 From: Anup Patel <apatel@ventanamicro.com>
3 Date: Thu, 21 Mar 2024 14:20:40 +0530
4 Subject: RISC-V: KVM: Fix APLIC setipnum_le/be write emulation
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Anup Patel <apatel@ventanamicro.com>
10
11 commit d8dd9f113e16bef3b29c9dcceb584a6f144f55e4 upstream.
12
13 The writes to setipnum_le/be register for APLIC in MSI-mode have special
14 consideration for level-triggered interrupts as-per the section "4.9.2
15 Special consideration for level-sensitive interrupt sources" of the RISC-V
16 AIA specification.
17
18 Particularly, the below text from the RISC-V AIA specification defines
19 the behaviour of writes to setipnum_le/be register for level-triggered
20 interrupts:
21
22 "A second option is for the interrupt service routine to write the
23 APLIC’s source identity number for the interrupt to the domain’s
24 setipnum register just before exiting. This will cause the interrupt’s
25 pending bit to be set to one again if the source is still asserting
26 an interrupt, but not if the source is not asserting an interrupt."
27
28 Fix setipnum_le/be write emulation for in-kernel APLIC by implementing
29 the above behaviour in aplic_write_pending() function.
30
31 Cc: stable@vger.kernel.org
32 Fixes: 74967aa208e2 ("RISC-V: KVM: Add in-kernel emulation of AIA APLIC")
33 Signed-off-by: Anup Patel <apatel@ventanamicro.com>
34 Signed-off-by: Anup Patel <anup@brainfault.org>
35 Link: https://lore.kernel.org/r/20240321085041.1955293-2-apatel@ventanamicro.com
36 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
37 ---
38 arch/riscv/kvm/aia_aplic.c | 16 +++++++++++++---
39 1 file changed, 13 insertions(+), 3 deletions(-)
40
41 diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c
42 index 39e72aa016a4..5e842b92dc46 100644
43 --- a/arch/riscv/kvm/aia_aplic.c
44 +++ b/arch/riscv/kvm/aia_aplic.c
45 @@ -137,11 +137,21 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
46 raw_spin_lock_irqsave(&irqd->lock, flags);
47
48 sm = irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK;
49 - if (!pending &&
50 - ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
51 - (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)))
52 + if (sm == APLIC_SOURCECFG_SM_INACTIVE)
53 goto skip_write_pending;
54
55 + if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH ||
56 + sm == APLIC_SOURCECFG_SM_LEVEL_LOW) {
57 + if (!pending)
58 + goto skip_write_pending;
59 + if ((irqd->state & APLIC_IRQ_STATE_INPUT) &&
60 + sm == APLIC_SOURCECFG_SM_LEVEL_LOW)
61 + goto skip_write_pending;
62 + if (!(irqd->state & APLIC_IRQ_STATE_INPUT) &&
63 + sm == APLIC_SOURCECFG_SM_LEVEL_HIGH)
64 + goto skip_write_pending;
65 + }
66 +
67 if (pending)
68 irqd->state |= APLIC_IRQ_STATE_PENDING;
69 else
70 --
71 2.44.0
72