qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4 6/6] target/riscv: select KVM AIA in riscv virt machine


From: Daniel Henrique Barboza
Subject: Re: [PATCH v4 6/6] target/riscv: select KVM AIA in riscv virt machine
Date: Fri, 30 Jun 2023 06:43:01 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.12.0



On 6/21/23 11:54, Yong-Xuan Wang wrote:
Select KVM AIA when the host kernel has in-kernel AIA chip support.
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
devices to KVM APLIC.
We also extend virt machine to specify the KVM AIA mode. The "kvm-aia"
parameter is passed along with machine name in QEMU command-line.
1) "kvm-aia=emul": IMSIC is emulated by hypervisor
2) "kvm-aia=hwaccel": use hardware guest IMSIC
3) "kvm-aia=auto": use the hardware guest IMSICs whenever available
                    otherwise we fallback to software emulation.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Jim Shu <jim.shu@sifive.com>
---

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

  hw/riscv/virt.c         | 92 ++++++++++++++++++++++++++++++++++-------
  include/hw/riscv/virt.h |  1 +
  2 files changed, 79 insertions(+), 14 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a1d29a741..efa176a184 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -35,6 +35,7 @@
  #include "hw/riscv/virt.h"
  #include "hw/riscv/boot.h"
  #include "hw/riscv/numa.h"
+#include "kvm_riscv.h"
  #include "hw/intc/riscv_aclint.h"
  #include "hw/intc/riscv_aplic.h"
  #include "hw/intc/riscv_imsic.h"
@@ -74,6 +75,12 @@
  #error "Can't accomodate all IMSIC groups in address space"
  #endif
+/* KVM AIA only supports APLIC.m. APLIC.w is always emulated by QEMU. */
+static bool virt_use_kvm_aia(RISCVVirtState *s)
+{
+    return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
+}
+
  static const MemMapEntry virt_memmap[] = {
      [VIRT_DEBUG] =        {        0x0,         0x100 },
      [VIRT_MROM] =         {     0x1000,        0xf000 },
@@ -642,7 +649,8 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
                                      uint32_t msi_s_phandle,
                                      uint32_t *phandle,
                                      uint32_t *intc_phandles,
-                                    uint32_t *aplic_phandles)
+                                    uint32_t *aplic_phandles,
+                                    int num_harts)
  {
      int cpu;
      char *aplic_name;
@@ -653,11 +661,11 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
aplic_m_phandle = (*phandle)++;
      aplic_s_phandle = (*phandle)++;
-    aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
+    aplic_cells = g_new0(uint32_t, num_harts * 2);
if (!kvm_enabled()) {
          /* M-level APLIC node */
-        for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
+        for (cpu = 0; cpu < num_harts; cpu++) {
              aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
              aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
          }
@@ -691,7 +699,7 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
      }
/* S-level APLIC node */
-    for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
+    for (cpu = 0; cpu < num_harts; cpu++) {
          aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
          aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
      }
@@ -798,17 +806,25 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
MemMapEntry *memmap,
          *msi_pcie_phandle = msi_s_phandle;
      }
- phandle_pos = ms->smp.cpus;
-    for (socket = (socket_count - 1); socket >= 0; socket--) {
-        phandle_pos -= s->soc[socket].num_harts;
+    /* KVM AIA only has one APLIC instance */
+    if (virt_use_kvm_aia(s)) {
+        create_fdt_socket_aplic(s, memmap, 0,
+            msi_m_phandle, msi_s_phandle, phandle,
+            &intc_phandles[0], xplic_phandles, ms->smp.cpus);
+    } else {
+        phandle_pos = ms->smp.cpus;
+        for (socket = (socket_count - 1); socket >= 0; socket--) {
+            phandle_pos -= s->soc[socket].num_harts;
- if (s->aia_type == VIRT_AIA_TYPE_NONE) {
-            create_fdt_socket_plic(s, memmap, socket, phandle,
-                &intc_phandles[phandle_pos], xplic_phandles);
-        } else {
-            create_fdt_socket_aplic(s, memmap, socket,
-                msi_m_phandle, msi_s_phandle, phandle,
-                &intc_phandles[phandle_pos], xplic_phandles);
+            if (s->aia_type == VIRT_AIA_TYPE_NONE) {
+                create_fdt_socket_plic(s, memmap, socket, phandle,
+                    &intc_phandles[phandle_pos], xplic_phandles);
+            } else {
+                create_fdt_socket_aplic(s, memmap, socket,
+                    msi_m_phandle, msi_s_phandle, phandle,
+                    &intc_phandles[phandle_pos], xplic_phandles,
+                    s->soc[socket].num_harts);
+            }
          }
      }
@@ -819,6 +835,9 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
              *irq_mmio_phandle = xplic_phandles[socket];
              *irq_virtio_phandle = xplic_phandles[socket];
              *irq_pcie_phandle = xplic_phandles[socket];
+
+            if (virt_use_kvm_aia(s))
+                break;
          }
          if (socket == 1) {
              *irq_virtio_phandle = xplic_phandles[socket];
@@ -1454,6 +1473,14 @@ static void virt_machine_init(MachineState *machine)
          }
      }
+ if (virt_use_kvm_aia(s)) {
+        kvm_riscv_aia_create(
+            machine, s->kvm_aia_mode, IMSIC_MMIO_GROUP_MIN_SHIFT,
+            VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
+            memmap[VIRT_APLIC_S].base, memmap[VIRT_IMSIC_S].base,
+            s->aia_guests);
+    }
+
      if (riscv_is_32bit(&s->soc[0])) {
  #if HOST_LONG_BITS == 64
          /* limit RAM size in a 32-bit system */
@@ -1610,6 +1637,31 @@ static void virt_set_aia(Object *obj, const char *val, 
Error **errp)
      }
  }
+#if defined(CONFIG_KVM)
+static char *virt_get_kvm_aia(Object *obj, Error **errp)
+{
+    RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
+
+    return kvm_aia_mode_str(s->kvm_aia_mode);
+}
+
+static void virt_set_kvm_aia(Object *obj, const char *val, Error **errp)
+{
+    RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
+
+    if (!strcmp(val, "emul")) {
+        s->kvm_aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
+    } else if (!strcmp(val, "hwaccel")) {
+        s->kvm_aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
+    } else if (!strcmp(val, "auto")) {
+        s->kvm_aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
+    } else {
+        error_setg(errp, "Invalid KVM AIA mode");
+        error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
+    }
+}
+#endif
+
  static bool virt_get_aclint(Object *obj, Error **errp)
  {
      RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
@@ -1717,6 +1769,18 @@ static void virt_machine_class_init(ObjectClass *oc, 
void *data)
      sprintf(str, "Set number of guest MMIO pages for AIA IMSIC. Valid value "
                   "should be between 0 and %d.", VIRT_IRQCHIP_MAX_GUESTS);
      object_class_property_set_description(oc, "aia-guests", str);
+
+#if defined(CONFIG_KVM)
+    object_class_property_add_str(oc, "kvm-aia", virt_get_kvm_aia,
+                                  virt_set_kvm_aia);
+    object_class_property_set_description(oc, "kvm-aia",
+                                          "Set KVM AIA mode. Valid values are "
+                                          "emul, hwaccel, and auto. Default "
+                                          "is auto.");
+    object_property_set_default_str(object_class_property_find(oc, "kvm-aia"),
+                                    "auto");
+
+#endif
      object_class_property_add(oc, "acpi", "OnOffAuto",
                                virt_get_acpi, virt_set_acpi,
                                NULL, NULL);
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index e5c474b26e..d0140feeff 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -56,6 +56,7 @@ struct RISCVVirtState {
      bool have_aclint;
      RISCVVirtAIAType aia_type;
      int aia_guests;
+    uint64_t kvm_aia_mode;
      char *oem_id;
      char *oem_table_id;
      OnOffAuto acpi;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]