aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <dbarboza@ventanamicro.com>2023-12-18 17:43:20 -0300
committerAlistair Francis <alistair.francis@wdc.com>2024-01-10 18:47:47 +1000
commit0d71f0a34938a6ac11953ae3dbec40113d2838a1 (patch)
tree0fb6fa370e92e3598a75b6e2a4e98842c6517ead
parent1583ca8aa61e1648d1f340c9a6ae3cd7ba3a82ae (diff)
downloadqemu-0d71f0a34938a6ac11953ae3dbec40113d2838a1.zip
qemu-0d71f0a34938a6ac11953ae3dbec40113d2838a1.tar.gz
qemu-0d71f0a34938a6ac11953ae3dbec40113d2838a1.tar.bz2
target/riscv/kvm: do PR_RISCV_V_SET_CONTROL during realize()
Linux RISC-V vector documentation (Document/arch/riscv/vector.rst) mandates a prctl() in order to allow an userspace thread to use the Vector extension from the host. This is something to be done in realize() time, after init(), when we already decided whether we're using RVV or not. We don't have a realize() callback for KVM yet, so add kvm_cpu_realize() and enable RVV for the thread via PR_RISCV_V_SET_CONTROL. Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20231218204321.75757-4-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-rw-r--r--target/riscv/kvm/kvm-cpu.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 841756a..d7d6fb1 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -18,6 +18,7 @@
#include "qemu/osdep.h"
#include <sys/ioctl.h>
+#include <sys/prctl.h>
#include <linux/kvm.h>
@@ -47,6 +48,9 @@
#include "sysemu/runstate.h"
#include "hw/riscv/numa.h"
+#define PR_RISCV_V_SET_CONTROL 69
+#define PR_RISCV_V_VSTATE_CTRL_ON 2
+
void riscv_kvm_aplic_request(void *opaque, int irq, int level)
{
kvm_set_irq(kvm_state, irq, !!level);
@@ -1496,11 +1500,36 @@ static void kvm_cpu_instance_init(CPUState *cs)
}
}
+/*
+ * We'll get here via the following path:
+ *
+ * riscv_cpu_realize()
+ * -> cpu_exec_realizefn()
+ * -> kvm_cpu_realize() (via accel_cpu_common_realize())
+ */
+static bool kvm_cpu_realize(CPUState *cs, Error **errp)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ int ret;
+
+ if (riscv_has_ext(&cpu->env, RVV)) {
+ ret = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
+ if (ret) {
+ error_setg(errp, "Error in prctl PR_RISCV_V_SET_CONTROL, code: %s",
+ strerrorname_np(errno));
+ return false;
+ }
+ }
+
+ return true;
+}
+
static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)
{
AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
acc->cpu_instance_init = kvm_cpu_instance_init;
+ acc->cpu_target_realize = kvm_cpu_realize;
}
static const TypeInfo kvm_cpu_accel_type_info = {