* [PATCH RFC v6 01/12] linux-header: Update linux/kvm.h
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface Yifei Jiang
` (10 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang
Update linux-headers/linux/kvm.h from
https://github.com/avpatel/linux/tree/riscv_kvm_v19.
Only use this header file, so here do not update all linux headers by
update-linux-headers.sh until above KVM series is accepted.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
| 8 ++++++++
1 file changed, 8 insertions(+)
--git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index bcaf66cc4d..5e290c3c3e 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -269,6 +269,7 @@ struct kvm_xen_exit {
#define KVM_EXIT_AP_RESET_HOLD 32
#define KVM_EXIT_X86_BUS_LOCK 33
#define KVM_EXIT_XEN 34
+#define KVM_EXIT_RISCV_SBI 35
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -469,6 +470,13 @@ struct kvm_run {
} msr;
/* KVM_EXIT_XEN */
struct kvm_xen_exit xen;
+ /* KVM_EXIT_RISCV_SBI */
+ struct {
+ unsigned long extension_id;
+ unsigned long function_id;
+ unsigned long args[6];
+ unsigned long ret[2];
+ } riscv_sbi;
/* Fix the size of the union. */
char padding[256];
};
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 01/12] linux-header: Update linux/kvm.h Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 03/12] target/riscv: Implement function kvm_arch_init_vcpu Yifei Jiang
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
Add target/riscv/kvm.c to place kvm_arch_* function needed by
kvm/kvm-all.c. Meanwhile, add kvm support in meson.build file.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
meson.build | 2 +
target/riscv/kvm.c | 133 +++++++++++++++++++++++++++++++++++++++
target/riscv/meson.build | 1 +
3 files changed, 136 insertions(+)
create mode 100644 target/riscv/kvm.c
diff --git a/meson.build b/meson.build
index f2e148eaf9..8ad009ceb6 100644
--- a/meson.build
+++ b/meson.build
@@ -72,6 +72,8 @@ elif cpu in ['ppc', 'ppc64']
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
elif cpu in ['mips', 'mips64']
kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
+elif cpu in ['riscv32', 'riscv64']
+ kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
else
kvm_targets = []
endif
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
new file mode 100644
index 0000000000..687dd4b621
--- /dev/null
+++ b/target/riscv/kvm.c
@@ -0,0 +1,133 @@
+/*
+ * RISC-V implementation of KVM hooks
+ *
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+
+#include <linux/kvm.h>
+
+#include "qemu-common.h"
+#include "qemu/timer.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "sysemu/kvm_int.h"
+#include "cpu.h"
+#include "trace.h"
+#include "hw/pci/pci.h"
+#include "exec/memattrs.h"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "hw/irq.h"
+#include "qemu/log.h"
+#include "hw/loader.h"
+
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+ KVM_CAP_LAST_INFO
+};
+
+int kvm_arch_get_registers(CPUState *cs)
+{
+ return 0;
+}
+
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+ return 0;
+}
+
+int kvm_arch_release_virq_post(int virq)
+{
+ return 0;
+}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data, PCIDevice *dev)
+{
+ return 0;
+}
+
+int kvm_arch_destroy_vcpu(CPUState *cs)
+{
+ return 0;
+}
+
+unsigned long kvm_arch_vcpu_id(CPUState *cpu)
+{
+ return cpu->cpu_index;
+}
+
+void kvm_arch_init_irq_routing(KVMState *s)
+{
+}
+
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+ return 0;
+}
+
+int kvm_arch_msi_data_to_gsi(uint32_t data)
+{
+ abort();
+}
+
+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
+ int vector, PCIDevice *dev)
+{
+ return 0;
+}
+
+int kvm_arch_init(MachineState *ms, KVMState *s)
+{
+ return 0;
+}
+
+int kvm_arch_irqchip_create(KVMState *s)
+{
+ return 0;
+}
+
+int kvm_arch_process_async_events(CPUState *cs)
+{
+ return 0;
+}
+
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
+{
+}
+
+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
+{
+ return MEMTXATTRS_UNSPECIFIED;
+}
+
+bool kvm_arch_stop_on_emulation_error(CPUState *cs)
+{
+ return true;
+}
+
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
+{
+ return 0;
+}
+
+bool kvm_arch_cpu_check_are_resettable(void)
+{
+ return true;
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..2faf08a941 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -19,6 +19,7 @@ riscv_ss.add(files(
'bitmanip_helper.c',
'translate.c',
))
+riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
riscv_softmmu_ss = ss.source_set()
riscv_softmmu_ss.add(files(
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 03/12] target/riscv: Implement function kvm_arch_init_vcpu
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 01/12] linux-header: Update linux/kvm.h Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 04/12] target/riscv: Implement kvm_arch_get_registers Yifei Jiang
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
Get isa info from kvm while kvm init.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/kvm.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 687dd4b621..dd3bbd7ceb 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -38,6 +38,18 @@
#include "qemu/log.h"
#include "hw/loader.h"
+static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx)
+{
+ uint64_t id = KVM_REG_RISCV | type | idx;
+
+ if (riscv_cpu_is_32bit(env)) {
+ id |= KVM_REG_SIZE_U32;
+ } else {
+ id |= KVM_REG_SIZE_U64;
+ }
+ return id;
+}
+
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
@@ -79,7 +91,20 @@ void kvm_arch_init_irq_routing(KVMState *s)
int kvm_arch_init_vcpu(CPUState *cs)
{
- return 0;
+ int ret = 0;
+ target_ulong isa;
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+ uint64_t id;
+
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, KVM_REG_RISCV_CONFIG_REG(isa));
+ ret = kvm_get_one_reg(cs, id, &isa);
+ if (ret) {
+ return ret;
+ }
+ env->misa |= isa;
+
+ return ret;
}
int kvm_arch_msi_data_to_gsi(uint32_t data)
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 04/12] target/riscv: Implement kvm_arch_get_registers
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (2 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 03/12] target/riscv: Implement function kvm_arch_init_vcpu Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 05/12] target/riscv: Implement kvm_arch_put_registers Yifei Jiang
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
Get GPR CSR and FP registers from kvm by KVM_GET_ONE_REG ioctl.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/kvm.c | 150 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 149 insertions(+), 1 deletion(-)
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index dd3bbd7ceb..128a9922e8 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -50,13 +50,161 @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx
return id;
}
+#define RISCV_CORE_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
+ KVM_REG_RISCV_CORE_REG(name))
+
+#define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
+ KVM_REG_RISCV_CSR_REG(name))
+
+#define RISCV_FP_F_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx)
+
+#define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx)
+
+static int kvm_riscv_get_regs_core(CPUState *cs)
+{
+ int ret = 0;
+ int i;
+ target_ulong reg;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ ret = kvm_get_one_reg(cs, RISCV_CORE_REG(env, regs.pc), ®);
+ if (ret) {
+ return ret;
+ }
+ env->pc = reg;
+
+ for (i = 1; i < 32; i++) {
+ uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
+ ret = kvm_get_one_reg(cs, id, ®);
+ if (ret) {
+ return ret;
+ }
+ env->gpr[i] = reg;
+ }
+
+ return ret;
+}
+
+static int kvm_riscv_get_regs_csr(CPUState *cs)
+{
+ int ret = 0;
+ target_ulong reg;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sstatus), ®);
+ if (ret) {
+ return ret;
+ }
+ env->mstatus = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sie), ®);
+ if (ret) {
+ return ret;
+ }
+ env->mie = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stvec), ®);
+ if (ret) {
+ return ret;
+ }
+ env->stvec = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sscratch), ®);
+ if (ret) {
+ return ret;
+ }
+ env->sscratch = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sepc), ®);
+ if (ret) {
+ return ret;
+ }
+ env->sepc = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, scause), ®);
+ if (ret) {
+ return ret;
+ }
+ env->scause = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stval), ®);
+ if (ret) {
+ return ret;
+ }
+ env->stval = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sip), ®);
+ if (ret) {
+ return ret;
+ }
+ env->mip = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, satp), ®);
+ if (ret) {
+ return ret;
+ }
+ env->satp = reg;
+
+ return ret;
+}
+
+static int kvm_riscv_get_regs_fp(CPUState *cs)
+{
+ int ret = 0;
+ int i;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ if (riscv_has_ext(env, RVD)) {
+ uint64_t reg;
+ for (i = 0; i < 32; i++) {
+ ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), ®);
+ if (ret) {
+ return ret;
+ }
+ env->fpr[i] = reg;
+ }
+ return ret;
+ }
+
+ if (riscv_has_ext(env, RVF)) {
+ uint32_t reg;
+ for (i = 0; i < 32; i++) {
+ ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), ®);
+ if (ret) {
+ return ret;
+ }
+ env->fpr[i] = reg;
+ }
+ return ret;
+ }
+
+ return ret;
+}
+
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
int kvm_arch_get_registers(CPUState *cs)
{
- return 0;
+ int ret = 0;
+
+ ret = kvm_riscv_get_regs_core(cs);
+ if (ret) {
+ return ret;
+ }
+
+ ret = kvm_riscv_get_regs_csr(cs);
+ if (ret) {
+ return ret;
+ }
+
+ ret = kvm_riscv_get_regs_fp(cs);
+ if (ret) {
+ return ret;
+ }
+
+ return ret;
}
int kvm_arch_put_registers(CPUState *cs, int level)
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 05/12] target/riscv: Implement kvm_arch_put_registers
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (3 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 04/12] target/riscv: Implement kvm_arch_get_registers Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 06/12] target/riscv: Support start kernel directly by KVM Yifei Jiang
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
Put GPR CSR and FP registers to kvm by KVM_SET_ONE_REG ioctl
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/kvm.c | 141 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 140 insertions(+), 1 deletion(-)
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 128a9922e8..55b117aff1 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -85,6 +85,31 @@ static int kvm_riscv_get_regs_core(CPUState *cs)
return ret;
}
+static int kvm_riscv_put_regs_core(CPUState *cs)
+{
+ int ret = 0;
+ int i;
+ target_ulong reg;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ reg = env->pc;
+ ret = kvm_set_one_reg(cs, RISCV_CORE_REG(env, regs.pc), ®);
+ if (ret) {
+ return ret;
+ }
+
+ for (i = 1; i < 32; i++) {
+ uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
+ reg = env->gpr[i];
+ ret = kvm_set_one_reg(cs, id, ®);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
static int kvm_riscv_get_regs_csr(CPUState *cs)
{
int ret = 0;
@@ -148,6 +173,69 @@ static int kvm_riscv_get_regs_csr(CPUState *cs)
return ret;
}
+static int kvm_riscv_put_regs_csr(CPUState *cs)
+{
+ int ret = 0;
+ target_ulong reg;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ reg = env->mstatus;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sstatus), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->mie;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sie), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->stvec;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stvec), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->sscratch;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sscratch), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->sepc;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sepc), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->scause;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, scause), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->stval;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stval), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->mip;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sip), ®);
+ if (ret) {
+ return ret;
+ }
+
+ reg = env->satp;
+ ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, satp), ®);
+ if (ret) {
+ return ret;
+ }
+
+ return ret;
+}
+
static int kvm_riscv_get_regs_fp(CPUState *cs)
{
int ret = 0;
@@ -181,6 +269,40 @@ static int kvm_riscv_get_regs_fp(CPUState *cs)
return ret;
}
+static int kvm_riscv_put_regs_fp(CPUState *cs)
+{
+ int ret = 0;
+ int i;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ if (riscv_has_ext(env, RVD)) {
+ uint64_t reg;
+ for (i = 0; i < 32; i++) {
+ reg = env->fpr[i];
+ ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(env, i), ®);
+ if (ret) {
+ return ret;
+ }
+ }
+ return ret;
+ }
+
+ if (riscv_has_ext(env, RVF)) {
+ uint32_t reg;
+ for (i = 0; i < 32; i++) {
+ reg = env->fpr[i];
+ ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(env, i), ®);
+ if (ret) {
+ return ret;
+ }
+ }
+ return ret;
+ }
+
+ return ret;
+}
+
+
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
@@ -209,7 +331,24 @@ int kvm_arch_get_registers(CPUState *cs)
int kvm_arch_put_registers(CPUState *cs, int level)
{
- return 0;
+ int ret = 0;
+
+ ret = kvm_riscv_put_regs_core(cs);
+ if (ret) {
+ return ret;
+ }
+
+ ret = kvm_riscv_put_regs_csr(cs);
+ if (ret) {
+ return ret;
+ }
+
+ ret = kvm_riscv_put_regs_fp(cs);
+ if (ret) {
+ return ret;
+ }
+
+ return ret;
}
int kvm_arch_release_virq_post(int virq)
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 06/12] target/riscv: Support start kernel directly by KVM
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (4 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 05/12] target/riscv: Implement kvm_arch_put_registers Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 07/12] target/riscv: Support setting external interrupt " Yifei Jiang
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
Get kernel and fdt start address in virt.c, and pass them to KVM
when cpu reset. In addition, add kvm_riscv.h to place riscv specific
interface.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/boot.c | 11 +++++++++++
hw/riscv/virt.c | 7 +++++++
include/hw/riscv/boot.h | 1 +
target/riscv/cpu.c | 8 ++++++++
target/riscv/cpu.h | 3 +++
target/riscv/kvm-stub.c | 25 +++++++++++++++++++++++++
target/riscv/kvm.c | 14 ++++++++++++++
target/riscv/kvm_riscv.h | 24 ++++++++++++++++++++++++
target/riscv/meson.build | 2 +-
9 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/kvm-stub.c
create mode 100644 target/riscv/kvm_riscv.h
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 993bf89064..920132d078 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -292,3 +292,14 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
return;
}
+
+void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr)
+{
+ CPUState *cs;
+
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
+ RISCVCPU *riscv_cpu = RISCV_CPU(cs);
+ riscv_cpu->env.kernel_addr = kernel_addr;
+ riscv_cpu->env.fdt_addr = fdt_addr;
+ }
+}
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a3cd2599a..cdc27d6498 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -736,6 +736,13 @@ static void virt_machine_init(MachineState *machine)
virt_memmap[VIRT_MROM].size, kernel_entry,
fdt_load_addr, machine->fdt);
+ /*
+ * Only direct boot kernel is currently supported for KVM VM,
+ * So here setup kernel start address and fdt address.
+ * TODO:Support firmware loading and integrate to TCG start
+ */
+ riscv_setup_direct_kernel(kernel_entry, fdt_load_addr);
+
/* SiFive Test MMIO device */
sifive_test_create(memmap[VIRT_TEST].base);
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 0e89400b09..bcad5b11b1 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -56,5 +56,6 @@ void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
hwaddr rom_size,
uint32_t reset_vec_size,
uint64_t kernel_entry);
+void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr);
#endif /* RISCV_BOOT_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 991a6bb760..764fd39928 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -29,6 +29,8 @@
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "fpu/softfloat-helpers.h"
+#include "sysemu/kvm.h"
+#include "kvm_riscv.h"
/* RISC-V CPU definitions */
@@ -374,6 +376,12 @@ static void riscv_cpu_reset(DeviceState *dev)
cs->exception_index = RISCV_EXCP_NONE;
env->load_res = -1;
set_default_nan_mode(1, &env->fp_status);
+
+#ifndef CONFIG_USER_ONLY
+ if (kvm_enabled()) {
+ kvm_riscv_reset_vcpu(cpu);
+ }
+#endif
}
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bf1c899c00..3d3bdc2816 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -243,6 +243,9 @@ struct CPURISCVState {
/* Fields from here on are preserved across CPU reset. */
QEMUTimer *timer; /* Internal timer */
+
+ hwaddr kernel_addr;
+ hwaddr fdt_addr;
};
OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
diff --git a/target/riscv/kvm-stub.c b/target/riscv/kvm-stub.c
new file mode 100644
index 0000000000..39b96fe3f4
--- /dev/null
+++ b/target/riscv/kvm-stub.c
@@ -0,0 +1,25 @@
+/*
+ * QEMU KVM RISC-V specific function stubs
+ *
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "kvm_riscv.h"
+
+void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
+{
+ abort();
+}
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 55b117aff1..ee76371116 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -37,6 +37,7 @@
#include "hw/irq.h"
#include "qemu/log.h"
#include "hw/loader.h"
+#include "kvm_riscv.h"
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx)
{
@@ -439,6 +440,19 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
return 0;
}
+void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
+{
+ CPURISCVState *env = &cpu->env;
+
+ if (!kvm_enabled()) {
+ return;
+ }
+ env->pc = cpu->env.kernel_addr;
+ env->gpr[10] = kvm_arch_vcpu_id(CPU(cpu)); /* a0 */
+ env->gpr[11] = cpu->env.fdt_addr; /* a1 */
+ env->satp = 0;
+}
+
bool kvm_arch_cpu_check_are_resettable(void)
{
return true;
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
new file mode 100644
index 0000000000..f38c82bf59
--- /dev/null
+++ b/target/riscv/kvm_riscv.h
@@ -0,0 +1,24 @@
+/*
+ * QEMU KVM support -- RISC-V specific functions.
+ *
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_KVM_RISCV_H
+#define QEMU_KVM_RISCV_H
+
+void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
+
+#endif
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 2faf08a941..fe41cc5805 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -19,7 +19,7 @@ riscv_ss.add(files(
'bitmanip_helper.c',
'translate.c',
))
-riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
+riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
riscv_softmmu_ss = ss.source_set()
riscv_softmmu_ss.add(files(
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 07/12] target/riscv: Support setting external interrupt by KVM
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (5 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 06/12] target/riscv: Support start kernel directly by KVM Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
Extend riscv_cpu_update_mip() to support setting external interrupt
by KVM. It will call kvm_riscv_set_irq() to change the IRQ state in
the KVM module When kvm is enabled and the MIP_SEIP bit is set in "mask"
In addition, bacause target/riscv/cpu_helper.c is used to TCG, so move
riscv_cpu_update_mip() to target/riscv/cpu.c from target/riscv/cpu_helper.c
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 34 ++++++++++++++++++++++++++++++++++
target/riscv/cpu_helper.c | 27 ---------------------------
target/riscv/kvm-stub.c | 5 +++++
target/riscv/kvm.c | 20 ++++++++++++++++++++
target/riscv/kvm_riscv.h | 1 +
5 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 764fd39928..2251784f7b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -21,6 +21,7 @@
#include "qemu/qemu-print.h"
#include "qemu/ctype.h"
#include "qemu/log.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "internals.h"
#include "exec/exec-all.h"
@@ -144,6 +145,39 @@ static void set_feature(CPURISCVState *env, int feature)
env->features |= (1ULL << feature);
}
+#ifndef CONFIG_USER_ONLY
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
+{
+ CPURISCVState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+ uint32_t old = env->mip;
+ bool locked = false;
+
+ if (!qemu_mutex_iothread_locked()) {
+ locked = true;
+ qemu_mutex_lock_iothread();
+ }
+
+ env->mip = (env->mip & ~mask) | (value & mask);
+
+ if (kvm_enabled() && (mask & MIP_SEIP)) {
+ kvm_riscv_set_irq(RISCV_CPU(cpu), IRQ_S_EXT, value & MIP_SEIP);
+ }
+
+ if (env->mip) {
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+ }
+
+ if (locked) {
+ qemu_mutex_unlock_iothread();
+ }
+
+ return old;
+}
+#endif
+
static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
{
#ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 968cb8046f..0b88bda07a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -224,33 +224,6 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
}
}
-uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
-{
- CPURISCVState *env = &cpu->env;
- CPUState *cs = CPU(cpu);
- uint32_t old = env->mip;
- bool locked = false;
-
- if (!qemu_mutex_iothread_locked()) {
- locked = true;
- qemu_mutex_lock_iothread();
- }
-
- env->mip = (env->mip & ~mask) | (value & mask);
-
- if (env->mip) {
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
- }
-
- if (locked) {
- qemu_mutex_unlock_iothread();
- }
-
- return old;
-}
-
void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
uint32_t arg)
{
diff --git a/target/riscv/kvm-stub.c b/target/riscv/kvm-stub.c
index 39b96fe3f4..4e8fc31a21 100644
--- a/target/riscv/kvm-stub.c
+++ b/target/riscv/kvm-stub.c
@@ -23,3 +23,8 @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
{
abort();
}
+
+void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
+{
+ abort();
+}
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index ee76371116..bc9cb5d8f9 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -453,6 +453,26 @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
env->satp = 0;
}
+void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
+{
+ int ret;
+ unsigned virq = level ? KVM_INTERRUPT_SET : KVM_INTERRUPT_UNSET;
+
+ if (irq != IRQ_S_EXT) {
+ return;
+ }
+
+ if (!kvm_enabled()) {
+ return;
+ }
+
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq);
+ if (ret < 0) {
+ perror("Set irq failed");
+ abort();
+ }
+}
+
bool kvm_arch_cpu_check_are_resettable(void)
{
return true;
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
index f38c82bf59..ed281bdce0 100644
--- a/target/riscv/kvm_riscv.h
+++ b/target/riscv/kvm_riscv.h
@@ -20,5 +20,6 @@
#define QEMU_KVM_RISCV_H
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
+void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
#endif
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (6 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 07/12] target/riscv: Support setting external interrupt " Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-19 6:13 ` Alistair Francis
2021-08-17 3:24 ` [PATCH RFC v6 09/12] target/riscv: Add host cpu type Yifei Jiang
` (3 subsequent siblings)
11 siblings, 1 reply; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang
Use char-fe to handle console sbi call, which implement early
console io while apply 'earlycon=sbi' into kernel parameters.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/riscv/kvm.c | 42 ++++++++++++++++-
target/riscv/sbi_ecall_interface.h | 72 ++++++++++++++++++++++++++++++
2 files changed, 113 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/sbi_ecall_interface.h
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index bc9cb5d8f9..a68f31c2f3 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -38,6 +38,8 @@
#include "qemu/log.h"
#include "hw/loader.h"
#include "kvm_riscv.h"
+#include "sbi_ecall_interface.h"
+#include "chardev/char-fe.h"
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx)
{
@@ -435,9 +437,47 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
return true;
}
+static int kvm_riscv_handle_sbi(struct kvm_run *run)
+{
+ int ret = 0;
+ unsigned char ch;
+ switch (run->riscv_sbi.extension_id) {
+ case SBI_EXT_0_1_CONSOLE_PUTCHAR:
+ ch = run->riscv_sbi.args[0];
+ qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
+ break;
+ case SBI_EXT_0_1_CONSOLE_GETCHAR:
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
+ if (ret == sizeof(ch)) {
+ run->riscv_sbi.args[0] = ch;
+ } else {
+ run->riscv_sbi.args[0] = -1;
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: un-handled SBI EXIT, specific reasons is %lu\n",
+ __func__, run->riscv_sbi.extension_id);
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
- return 0;
+ int ret = 0;
+ switch (run->exit_reason) {
+ case KVM_EXIT_RISCV_SBI:
+ ret = kvm_riscv_handle_sbi(run);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
+ __func__, run->exit_reason);
+ ret = -1;
+ break;
+ }
+ return ret;
}
void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
new file mode 100644
index 0000000000..fb1a3fa8f2
--- /dev/null
+++ b/target/riscv/sbi_ecall_interface.h
@@ -0,0 +1,72 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_ECALL_INTERFACE_H__
+#define __SBI_ECALL_INTERFACE_H__
+
+/* clang-format off */
+
+/* SBI Extension IDs */
+#define SBI_EXT_0_1_SET_TIMER 0x0
+#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
+#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
+#define SBI_EXT_0_1_CLEAR_IPI 0x3
+#define SBI_EXT_0_1_SEND_IPI 0x4
+#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7
+#define SBI_EXT_0_1_SHUTDOWN 0x8
+#define SBI_EXT_BASE 0x10
+#define SBI_EXT_TIME 0x54494D45
+#define SBI_EXT_IPI 0x735049
+#define SBI_EXT_RFENCE 0x52464E43
+#define SBI_EXT_HSM 0x48534D
+
+/* SBI function IDs for BASE extension*/
+#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
+#define SBI_EXT_BASE_GET_IMP_ID 0x1
+#define SBI_EXT_BASE_GET_IMP_VERSION 0x2
+#define SBI_EXT_BASE_PROBE_EXT 0x3
+#define SBI_EXT_BASE_GET_MVENDORID 0x4
+#define SBI_EXT_BASE_GET_MARCHID 0x5
+#define SBI_EXT_BASE_GET_MIMPID 0x6
+
+/* SBI function IDs for TIME extension*/
+#define SBI_EXT_TIME_SET_TIMER 0x0
+
+/* SBI function IDs for IPI extension*/
+#define SBI_EXT_IPI_SEND_IPI 0x0
+
+/* SBI function IDs for RFENCE extension*/
+#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x3
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x4
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
+
+/* SBI function IDs for HSM extension */
+#define SBI_EXT_HSM_HART_START 0x0
+#define SBI_EXT_HSM_HART_STOP 0x1
+#define SBI_EXT_HSM_HART_GET_STATUS 0x2
+
+#define SBI_HSM_HART_STATUS_STARTED 0x0
+#define SBI_HSM_HART_STATUS_STOPPED 0x1
+#define SBI_HSM_HART_STATUS_START_PENDING 0x2
+#define SBI_HSM_HART_STATUS_STOP_PENDING 0x3
+
+#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
+#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
+#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
+#define SBI_EXT_VENDOR_START 0x09000000
+#define SBI_EXT_VENDOR_END 0x09FFFFFF
+/* clang-format on */
+
+#endif
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
2021-08-17 3:24 ` [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
@ 2021-08-19 6:13 ` Alistair Francis
2021-08-20 9:23 ` Jiangyifei
0 siblings, 1 reply; 15+ messages in thread
From: Alistair Francis @ 2021-08-19 6:13 UTC (permalink / raw)
To: Yifei Jiang
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, Bin Meng,
limingwang (A),
open list:Overall, libvir-list, Anup Patel, Alistair Francis,
kvm-riscv, wanghaibin.wang, Palmer Dabbelt, fanliang, Wubin (H)
On Tue, Aug 17, 2021 at 1:25 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> Use char-fe to handle console sbi call, which implement early
> console io while apply 'earlycon=sbi' into kernel parameters.
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Mingwang Li <limingwang@huawei.com>
> ---
> target/riscv/kvm.c | 42 ++++++++++++++++-
> target/riscv/sbi_ecall_interface.h | 72 ++++++++++++++++++++++++++++++
> 2 files changed, 113 insertions(+), 1 deletion(-)
> create mode 100644 target/riscv/sbi_ecall_interface.h
>
> diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
> index bc9cb5d8f9..a68f31c2f3 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -38,6 +38,8 @@
> #include "qemu/log.h"
> #include "hw/loader.h"
> #include "kvm_riscv.h"
> +#include "sbi_ecall_interface.h"
> +#include "chardev/char-fe.h"
>
> static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx)
> {
> @@ -435,9 +437,47 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
> return true;
> }
>
> +static int kvm_riscv_handle_sbi(struct kvm_run *run)
> +{
> + int ret = 0;
> + unsigned char ch;
> + switch (run->riscv_sbi.extension_id) {
> + case SBI_EXT_0_1_CONSOLE_PUTCHAR:
> + ch = run->riscv_sbi.args[0];
> + qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
> + break;
> + case SBI_EXT_0_1_CONSOLE_GETCHAR:
> + ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
> + if (ret == sizeof(ch)) {
> + run->riscv_sbi.args[0] = ch;
> + } else {
> + run->riscv_sbi.args[0] = -1;
> + }
> + break;
These have been deprecated (see
https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc#4-legacy-extensions-eids-0x00---0x0f),
is it even worth supporting them?
> + default:
> + qemu_log_mask(LOG_UNIMP,
> + "%s: un-handled SBI EXIT, specific reasons is %lu\n",
> + __func__, run->riscv_sbi.extension_id);
> + ret = -1;
> + break;
> + }
> + return ret;
> +}
> +
> int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
> {
> - return 0;
> + int ret = 0;
> + switch (run->exit_reason) {
> + case KVM_EXIT_RISCV_SBI:
> + ret = kvm_riscv_handle_sbi(run);
> + break;
> + default:
> + qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
> + __func__, run->exit_reason);
> + ret = -1;
> + break;
> + }
> + return ret;
> }
>
> void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
> diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
> new file mode 100644
> index 0000000000..fb1a3fa8f2
> --- /dev/null
> +++ b/target/riscv/sbi_ecall_interface.h
> @@ -0,0 +1,72 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + * Anup Patel <anup.patel@wdc.com>
> + */
> +
> +#ifndef __SBI_ECALL_INTERFACE_H__
> +#define __SBI_ECALL_INTERFACE_H__
> +
> +/* clang-format off */
> +
> +/* SBI Extension IDs */
> +#define SBI_EXT_0_1_SET_TIMER 0x0
> +#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
> +#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
> +#define SBI_EXT_0_1_CLEAR_IPI 0x3
> +#define SBI_EXT_0_1_SEND_IPI 0x4
> +#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5
> +#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6
> +#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7
> +#define SBI_EXT_0_1_SHUTDOWN 0x8
> +#define SBI_EXT_BASE 0x10
> +#define SBI_EXT_TIME 0x54494D45
> +#define SBI_EXT_IPI 0x735049
> +#define SBI_EXT_RFENCE 0x52464E43
> +#define SBI_EXT_HSM 0x48534D
> +
> +/* SBI function IDs for BASE extension*/
> +#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
> +#define SBI_EXT_BASE_GET_IMP_ID 0x1
> +#define SBI_EXT_BASE_GET_IMP_VERSION 0x2
> +#define SBI_EXT_BASE_PROBE_EXT 0x3
> +#define SBI_EXT_BASE_GET_MVENDORID 0x4
> +#define SBI_EXT_BASE_GET_MARCHID 0x5
> +#define SBI_EXT_BASE_GET_MIMPID 0x6
> +
> +/* SBI function IDs for TIME extension*/
> +#define SBI_EXT_TIME_SET_TIMER 0x0
> +
> +/* SBI function IDs for IPI extension*/
> +#define SBI_EXT_IPI_SEND_IPI 0x0
> +
> +/* SBI function IDs for RFENCE extension*/
> +#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0
> +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1
> +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2
> +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x3
> +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x4
> +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
> +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
> +
> +/* SBI function IDs for HSM extension */
> +#define SBI_EXT_HSM_HART_START 0x0
> +#define SBI_EXT_HSM_HART_STOP 0x1
> +#define SBI_EXT_HSM_HART_GET_STATUS 0x2
> +
> +#define SBI_HSM_HART_STATUS_STARTED 0x0
> +#define SBI_HSM_HART_STATUS_STOPPED 0x1
> +#define SBI_HSM_HART_STATUS_START_PENDING 0x2
> +#define SBI_HSM_HART_STATUS_STOP_PENDING 0x3
> +
> +#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
> +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
> +#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
> +#define SBI_EXT_VENDOR_START 0x09000000
> +#define SBI_EXT_VENDOR_END 0x09FFFFFF
> +/* clang-format on */
> +
> +#endif
> --
> 2.19.1
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* RE: [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
2021-08-19 6:13 ` Alistair Francis
@ 2021-08-20 9:23 ` Jiangyifei
0 siblings, 0 replies; 15+ messages in thread
From: Jiangyifei @ 2021-08-20 9:23 UTC (permalink / raw)
To: Alistair Francis
Cc: Anup Patel, open list:RISC-V, open list:Overall, limingwang (A),
libvir-list, Bin Meng, qemu-devel@nongnu.org Developers,
Alistair Francis, kvm-riscv, Wanghaibin (D), Fanliang (EulerOS),
Palmer Dabbelt, Wubin (H)
> -----Original Message-----
> From: Qemu-riscv
> [mailto:qemu-riscv-bounces+jiangyifei=huawei.com@nongnu.org] On Behalf Of
> Alistair Francis
> Sent: Thursday, August 19, 2021 2:14 PM
> To: Jiangyifei <jiangyifei@huawei.com>
> Cc: Anup Patel <anup.patel@wdc.com>; open list:RISC-V
> <qemu-riscv@nongnu.org>; open list:Overall <kvm@vger.kernel.org>;
> limingwang (A) <limingwang@huawei.com>; libvir-list@redhat.com; Bin Meng
> <bin.meng@windriver.com>; qemu-devel@nongnu.org Developers
> <qemu-devel@nongnu.org>; Alistair Francis <Alistair.Francis@wdc.com>;
> kvm-riscv@lists.infradead.org; Wanghaibin (D)
> <wanghaibin.wang@huawei.com>; Fanliang (EulerOS) <fanliang@huawei.com>;
> Palmer Dabbelt <palmer@dabbelt.com>; Wubin (H) <wu.wubin@huawei.com>
> Subject: Re: [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI
> exit
>
> On Tue, Aug 17, 2021 at 1:25 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
> >
> > Use char-fe to handle console sbi call, which implement early console
> > io while apply 'earlycon=sbi' into kernel parameters.
> >
> > Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> > Signed-off-by: Mingwang Li <limingwang@huawei.com>
> > ---
> > target/riscv/kvm.c | 42 ++++++++++++++++-
> > target/riscv/sbi_ecall_interface.h | 72
> > ++++++++++++++++++++++++++++++
> > 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644
> > target/riscv/sbi_ecall_interface.h
> >
> > diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c index
> > bc9cb5d8f9..a68f31c2f3 100644
> > --- a/target/riscv/kvm.c
> > +++ b/target/riscv/kvm.c
> > @@ -38,6 +38,8 @@
> > #include "qemu/log.h"
> > #include "hw/loader.h"
> > #include "kvm_riscv.h"
> > +#include "sbi_ecall_interface.h"
> > +#include "chardev/char-fe.h"
> >
> > static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
> > uint64_t idx) { @@ -435,9 +437,47 @@ bool
> > kvm_arch_stop_on_emulation_error(CPUState *cs)
> > return true;
> > }
> >
> > +static int kvm_riscv_handle_sbi(struct kvm_run *run) {
> > + int ret = 0;
> > + unsigned char ch;
> > + switch (run->riscv_sbi.extension_id) {
> > + case SBI_EXT_0_1_CONSOLE_PUTCHAR:
> > + ch = run->riscv_sbi.args[0];
> > + qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
> > + break;
> > + case SBI_EXT_0_1_CONSOLE_GETCHAR:
> > + ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
> > + if (ret == sizeof(ch)) {
> > + run->riscv_sbi.args[0] = ch;
> > + } else {
> > + run->riscv_sbi.args[0] = -1;
> > + }
> > + break;
>
> These have been deprecated (see
> https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc#4-legacy-ext
> ensions-eids-0x00---0x0f),
> is it even worth supporting them?
>
Yes. The legacy console SBI functions (sbi_console_getchar() and sbi_console_putchar())
are expected to be deprecated.
However, the linux kernel still uses these sbi call interfaces, so they are retained here.
If the linux kernel doesn't use these interfaces, we will remove them.
Yifei
> > + default:
> > + qemu_log_mask(LOG_UNIMP,
> > + "%s: un-handled SBI EXIT, specific reasons
> is %lu\n",
> > + __func__, run->riscv_sbi.extension_id);
> > + ret = -1;
> > + break;
> > + }
> > + return ret;
> > +}
> > +
> > int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) {
> > - return 0;
> > + int ret = 0;
> > + switch (run->exit_reason) {
> > + case KVM_EXIT_RISCV_SBI:
> > + ret = kvm_riscv_handle_sbi(run);
> > + break;
> > + default:
> > + qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
> > + __func__, run->exit_reason);
> > + ret = -1;
> > + break;
> > + }
> > + return ret;
> > }
> >
> > void kvm_riscv_reset_vcpu(RISCVCPU *cpu) diff --git
> > a/target/riscv/sbi_ecall_interface.h
> > b/target/riscv/sbi_ecall_interface.h
> > new file mode 100644
> > index 0000000000..fb1a3fa8f2
> > --- /dev/null
> > +++ b/target/riscv/sbi_ecall_interface.h
> > @@ -0,0 +1,72 @@
> > +/*
> > + * SPDX-License-Identifier: BSD-2-Clause
> > + *
> > + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > + *
> > + * Authors:
> > + * Anup Patel <anup.patel@wdc.com>
> > + */
> > +
> > +#ifndef __SBI_ECALL_INTERFACE_H__
> > +#define __SBI_ECALL_INTERFACE_H__
> > +
> > +/* clang-format off */
> > +
> > +/* SBI Extension IDs */
> > +#define SBI_EXT_0_1_SET_TIMER 0x0
> > +#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
> > +#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
> > +#define SBI_EXT_0_1_CLEAR_IPI 0x3
> > +#define SBI_EXT_0_1_SEND_IPI 0x4
> > +#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5
> > +#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6
> > +#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7
> > +#define SBI_EXT_0_1_SHUTDOWN 0x8
> > +#define SBI_EXT_BASE 0x10
> > +#define SBI_EXT_TIME 0x54494D45
> > +#define SBI_EXT_IPI 0x735049
> > +#define SBI_EXT_RFENCE 0x52464E43
> > +#define SBI_EXT_HSM 0x48534D
> > +
> > +/* SBI function IDs for BASE extension*/
> > +#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
> > +#define SBI_EXT_BASE_GET_IMP_ID 0x1
> > +#define SBI_EXT_BASE_GET_IMP_VERSION 0x2
> > +#define SBI_EXT_BASE_PROBE_EXT 0x3
> > +#define SBI_EXT_BASE_GET_MVENDORID 0x4
> > +#define SBI_EXT_BASE_GET_MARCHID 0x5
> > +#define SBI_EXT_BASE_GET_MIMPID 0x6
> > +
> > +/* SBI function IDs for TIME extension*/
> > +#define SBI_EXT_TIME_SET_TIMER 0x0
> > +
> > +/* SBI function IDs for IPI extension*/
> > +#define SBI_EXT_IPI_SEND_IPI 0x0
> > +
> > +/* SBI function IDs for RFENCE extension*/
> > +#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0
> > +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1
> > +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2
> > +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x3
> > +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x4
> > +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
> > +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
> > +
> > +/* SBI function IDs for HSM extension */
> > +#define SBI_EXT_HSM_HART_START 0x0
> > +#define SBI_EXT_HSM_HART_STOP 0x1
> > +#define SBI_EXT_HSM_HART_GET_STATUS 0x2
> > +
> > +#define SBI_HSM_HART_STATUS_STARTED 0x0
> > +#define SBI_HSM_HART_STATUS_STOPPED 0x1
> > +#define SBI_HSM_HART_STATUS_START_PENDING 0x2
> > +#define SBI_HSM_HART_STATUS_STOP_PENDING 0x3
> > +
> > +#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
> > +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
> > +#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
> > +#define SBI_EXT_VENDOR_START 0x09000000
> > +#define SBI_EXT_VENDOR_END 0x09FFFFFF
> > +/* clang-format on */
> > +
> > +#endif
> > --
> > 2.19.1
> >
> >
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH RFC v6 09/12] target/riscv: Add host cpu type
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (7 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer Yifei Jiang
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang, Alistair Francis
'host' type cpu is set isa to RV32 or RV64 simply, more isa info
will obtain from KVM in kvm_arch_init_vcpu()
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 15 +++++++++++++++
target/riscv/cpu.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2251784f7b..976e71c4c7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -260,6 +260,18 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
}
#endif
+#if defined(CONFIG_KVM)
+static void riscv_host_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+#if defined(TARGET_RISCV32)
+ set_misa(env, RV32);
+#elif defined(TARGET_RISCV64)
+ set_misa(env, RV64);
+#endif
+}
+#endif
+
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
{
ObjectClass *oc;
@@ -792,6 +804,9 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.class_init = riscv_cpu_class_init,
},
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
+#if defined(CONFIG_KVM)
+ DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
+#endif
#if defined(TARGET_RISCV32)
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3d3bdc2816..720cb688bb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -44,6 +44,7 @@
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
+#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
#if defined(TARGET_RISCV32)
# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE32
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (8 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 09/12] target/riscv: Add host cpu type Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 11/12] target/riscv: Implement virtual time adjusting with vm state changing Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 12/12] target/riscv: Support virtual time context synchronization Yifei Jiang
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang
Add kvm_riscv_get/put_regs_timer to synchronize virtual time context
from KVM.
To set register of RISCV_TIMER_REG(state) will occur a error from KVM
on kvm_timer_state == 0. It's better to adapt in KVM, but it doesn't matter
that adaping in QEMU.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/riscv/cpu.h | 6 ++++
target/riscv/kvm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 720cb688bb..42ed9b1232 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -247,6 +247,12 @@ struct CPURISCVState {
hwaddr kernel_addr;
hwaddr fdt_addr;
+
+ /* kvm timer */
+ bool kvm_timer_dirty;
+ uint64_t kvm_timer_time;
+ uint64_t kvm_timer_compare;
+ uint64_t kvm_timer_state;
};
OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index a68f31c2f3..d1ab4b1247 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -59,6 +59,9 @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx
#define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
KVM_REG_RISCV_CSR_REG(name))
+#define RISCV_TIMER_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, \
+ KVM_REG_RISCV_TIMER_REG(name))
+
#define RISCV_FP_F_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx)
#define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx)
@@ -305,6 +308,75 @@ static int kvm_riscv_put_regs_fp(CPUState *cs)
return ret;
}
+static void kvm_riscv_get_regs_timer(CPUState *cs)
+{
+ int ret;
+ uint64_t reg;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ if (env->kvm_timer_dirty) {
+ return;
+ }
+
+ ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, time), ®);
+ if (ret) {
+ abort();
+ }
+ env->kvm_timer_time = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, compare), ®);
+ if (ret) {
+ abort();
+ }
+ env->kvm_timer_compare = reg;
+
+ ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, state), ®);
+ if (ret) {
+ abort();
+ }
+ env->kvm_timer_state = reg;
+
+ env->kvm_timer_dirty = true;
+}
+
+static void kvm_riscv_put_regs_timer(CPUState *cs)
+{
+ int ret;
+ uint64_t reg;
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+
+ if (!env->kvm_timer_dirty) {
+ return;
+ }
+
+ reg = env->kvm_timer_time;
+ ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, time), ®);
+ if (ret) {
+ abort();
+ }
+
+ reg = env->kvm_timer_compare;
+ ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, compare), ®);
+ if (ret) {
+ abort();
+ }
+
+ /*
+ * To set register of RISCV_TIMER_REG(state) will occur a error from KVM
+ * on env->kvm_timer_state == 0, It's better to adapt in KVM, but it
+ * doesn't matter that adaping in QEMU now.
+ * TODO If KVM changes, adapt here.
+ */
+ if (env->kvm_timer_state) {
+ reg = env->kvm_timer_state;
+ ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, state), ®);
+ if (ret) {
+ abort();
+ }
+ }
+
+ env->kvm_timer_dirty = false;
+}
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 11/12] target/riscv: Implement virtual time adjusting with vm state changing
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (9 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
2021-08-17 3:24 ` [PATCH RFC v6 12/12] target/riscv: Support virtual time context synchronization Yifei Jiang
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang
We hope that virtual time adjusts with vm state changing. When a vm
is stopped, guest virtual time should stop counting and kvm_timer
should be stopped. When the vm is resumed, guest virtual time should
continue to count and kvm_timer should be restored.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/riscv/kvm.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index d1ab4b1247..60c61ba924 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -40,6 +40,7 @@
#include "kvm_riscv.h"
#include "sbi_ecall_interface.h"
#include "chardev/char-fe.h"
+#include "sysemu/runstate.h"
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, uint64_t idx)
{
@@ -447,6 +448,17 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
return cpu->cpu_index;
}
+static void kvm_riscv_vm_state_change(void *opaque, bool running, RunState state)
+{
+ CPUState *cs = opaque;
+
+ if (running) {
+ kvm_riscv_put_regs_timer(cs);
+ } else {
+ kvm_riscv_get_regs_timer(cs);
+ }
+}
+
void kvm_arch_init_irq_routing(KVMState *s)
{
}
@@ -459,6 +471,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
CPURISCVState *env = &cpu->env;
uint64_t id;
+ qemu_add_vm_change_state_handler(kvm_riscv_vm_state_change, cs);
+
id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, KVM_REG_RISCV_CONFIG_REG(isa));
ret = kvm_get_one_reg(cs, id, &isa);
if (ret) {
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH RFC v6 12/12] target/riscv: Support virtual time context synchronization
2021-08-17 3:24 [PATCH RFC v6 00/12] Add riscv kvm accel support Yifei Jiang
` (10 preceding siblings ...)
2021-08-17 3:24 ` [PATCH RFC v6 11/12] target/riscv: Implement virtual time adjusting with vm state changing Yifei Jiang
@ 2021-08-17 3:24 ` Yifei Jiang
11 siblings, 0 replies; 15+ messages in thread
From: Yifei Jiang @ 2021-08-17 3:24 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
Alistair.Francis, bin.meng, wu.wubin, fanliang, wanghaibin.wang,
limingwang, Yifei Jiang
Add virtual time context description to vmstate_riscv_cpu. After cpu being
loaded, virtual time context is updated to KVM.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/riscv/machine.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 16a08302da..36edac86f6 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -138,10 +138,20 @@ static const VMStateDescription vmstate_hyper = {
}
};
+static int cpu_post_load(void *opaque, int version_id)
+{
+ RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
+
+ env->kvm_timer_dirty = true;
+ return 0;
+}
+
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
.version_id = 2,
.minimum_version_id = 2,
+ .post_load = cpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
@@ -183,6 +193,10 @@ const VMStateDescription vmstate_riscv_cpu = {
VMSTATE_UINT64(env.mtohost, RISCVCPU),
VMSTATE_UINT64(env.timecmp, RISCVCPU),
+ VMSTATE_UINT64(env.kvm_timer_time, RISCVCPU),
+ VMSTATE_UINT64(env.kvm_timer_compare, RISCVCPU),
+ VMSTATE_UINT64(env.kvm_timer_state, RISCVCPU),
+
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
--
2.19.1
^ permalink raw reply related [flat|nested] 15+ messages in thread