aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnup Patel <apatel@ventanamicro.com>2023-11-30 09:46:33 +0530
committerWill Deacon <will@kernel.org>2024-02-09 15:47:19 +0000
commitf6cc06d6b53540b0c8d9eada04fb6c5bd90e56fd (patch)
tree2bb21bdbeef1f88045b0493bf5e7f9a6ddc72d20
parent4ddaa4249e0c59a9ef6e09c1e32b042dd01e4c08 (diff)
downloadkvmtool-f6cc06d6b53540b0c8d9eada04fb6c5bd90e56fd.tar.gz
riscv: Fix guest poweroff when using PLIC emulation
Recently due to commit 74af1456dfa0, the virtio device emulation in KVMTOOL now calls irq__update_msix_route() upon guest poweroff which results in KVMTOOL crash when Guest uses PLIC emulation in user space. This is because irq__update_msix_route() expects the irq_routing table to be available but the KVMTOOL PLIC emulation does not populate any irq_routing entries. Fixes: 74af1456dfa0 ("virtio: Cancel and join threads when exiting devices devices") Signed-off-by: Anup Patel <apatel@ventanamicro.com> Link: https://lore.kernel.org/r/20231130041633.78725-1-apatel@ventanamicro.com Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--riscv/plic.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/riscv/plic.c b/riscv/plic.c
index ab7c574c..6bd13ac2 100644
--- a/riscv/plic.c
+++ b/riscv/plic.c
@@ -95,6 +95,8 @@
#define REG_SIZE 0x1000000
+#define IRQCHIP_PLIC_NR 0
+
struct plic_state;
struct plic_context {
@@ -500,6 +502,33 @@ static void plic__generate_fdt_node(void *fdt, struct kvm *kvm)
free(irq_cells);
}
+static int plic__irq_routing_init(struct kvm *kvm)
+{
+ int r;
+
+ /*
+ * This describes the default routing that the kernel uses without
+ * any routing explicitly set up via KVM_SET_GSI_ROUTING. So we
+ * don't need to commit these setting right now. The first actual
+ * user (MSI routing) will engage these mappings then.
+ */
+ for (next_gsi = 0; next_gsi < MAX_DEVICES; next_gsi++) {
+ r = irq__allocate_routing_entry();
+ if (r)
+ return r;
+
+ irq_routing->entries[irq_routing->nr++] =
+ (struct kvm_irq_routing_entry) {
+ .gsi = next_gsi,
+ .type = KVM_IRQ_ROUTING_IRQCHIP,
+ .u.irqchip.irqchip = IRQCHIP_PLIC_NR,
+ .u.irqchip.pin = next_gsi,
+ };
+ }
+
+ return 0;
+}
+
static int plic__init(struct kvm *kvm)
{
u32 i;
@@ -535,6 +564,9 @@ static int plic__init(struct kvm *kvm)
if (ret)
return ret;
+ /* Setup default IRQ routing */
+ plic__irq_routing_init(kvm);
+
plic.ready = true;
return 0;