kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/12] Add riscv kvm accel support
@ 2021-11-20  7:46 Yifei Jiang
  2021-11-20  7:46 ` [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h Yifei Jiang
                   ` (12 more replies)
  0 siblings, 13 replies; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang

This series adds both riscv32 and riscv64 kvm support, and implements
migration based on riscv.

Because of RISC-V KVM has been merged into the Linux master, so this
series are changed from RFC to patch v1.

Several steps to use this:
1. Build emulation
$ ./configure --target-list=riscv64-softmmu
$ make -j$(nproc)

2. Build kernel

3. Build QEMU VM
Cross built in riscv toolchain.
$ PKG_CONFIG_LIBDIR=<toolchain pkgconfig path>
$ export PKG_CONFIG_SYSROOT_DIR=<toolchain sysroot path>
$ ./configure --target-list=riscv64-softmmu --enable-kvm \
--cross-prefix=riscv64-linux-gnu- --disable-libiscsi --disable-glusterfs \
--disable-libusb --disable-usb-redir --audio-drv-list= --disable-opengl \
--disable-libxml2
$ make -j$(nproc)

4. Start emulation
$ ./qemu-system-riscv64 -M virt -m 4096M -cpu rv64,x-h=true -nographic \
        -name guest=riscv-hyp,debug-threads=on \
        -smp 4 \
        -bios ./fw_jump.bin \
        -kernel ./Image \
        -drive file=./hyp.img,format=raw,id=hd0 \
        -device virtio-blk-device,drive=hd0 \
        -append "root=/dev/vda rw console=ttyS0 earlycon=sbi"

5. Start kvm-acceled QEMU VM in emulation
$ ./qemu-system-riscv64 -M virt,accel=kvm -m 1024M -cpu host -nographic \
        -name guest=riscv-guset \
        -smp 2 \
        -bios none \
        -kernel ./Image \
        -drive file=./guest.img,format=raw,id=hd0 \
        -device virtio-blk-device,drive=hd0 \
        -append "root=/dev/vda rw console=ttyS0 earlycon=sbi"

Changes since RFC v6
- Rebase on recent commit 8627edfb3f1fca24a96a0954148885c3241c10f8
- Sync-up headers with Linux-5.16-rc1

Changes since RFC v5
- Rebase on QEMU v6.1.0-rc1 and kvm-riscv linux v19.
- Move kvm interrupt setting to riscv_cpu_update_mip().
- Replace __u64 with uint64_t.

Changes since RFC v4
- Rebase on QEMU v6.0.0-rc2 and kvm-riscv linux v17.
- Remove time scaling support as software solution is incomplete.
  Because it will cause unacceptable performance degradation. and
  We will post a better solution.
- Revise according to Alistair's review comments.
  - Remove compile time XLEN checks in kvm_riscv_reg_id
  - Surround TYPE_RISCV_CPU_HOST definition by CONFIG_KVM and share
    it between RV32 and RV64.
  - Add kvm-stub.c for reduce unnecessary compilation checks.
  - Add riscv_setup_direct_kernel() to direct boot kernel for KVM.

Changes since RFC v3
- Rebase on QEMU v5.2.0-rc2 and kvm-riscv linux v15.
- Add time scaling support(New patches 13, 14 and 15).
- Fix the bug that guest vm can't reboot.

Changes since RFC v2
- Fix checkpatch error at target/riscv/sbi_ecall_interface.h.
- Add riscv migration support.

Changes since RFC v1
- Add separate SBI ecall interface header.
- Add riscv32 kvm accel support.

Yifei Jiang (12):
  update-linux-headers: Add asm-riscv/kvm.h
  target/riscv: Add target/riscv/kvm.c to place the public kvm interface
  target/riscv: Implement function kvm_arch_init_vcpu
  target/riscv: Implement kvm_arch_get_registers
  target/riscv: Implement kvm_arch_put_registers
  target/riscv: Support start kernel directly by KVM
  target/riscv: Support setting external interrupt by KVM
  target/riscv: Handle KVM_EXIT_RISCV_SBI exit
  target/riscv: Add host cpu type
  target/riscv: Add kvm_riscv_get/put_regs_timer
  target/riscv: Implement virtual time adjusting with vm state changing
  target/riscv: Support virtual time context synchronization

 hw/riscv/boot.c                    |  11 +
 hw/riscv/virt.c                    |   7 +
 include/hw/riscv/boot.h            |   1 +
 linux-headers/asm-riscv/kvm.h      | 128 ++++++
 linux-headers/linux/kvm.h          |   8 +
 meson.build                        |   2 +
 target/riscv/cpu.c                 |  57 +++
 target/riscv/cpu.h                 |  10 +
 target/riscv/cpu_helper.c          |  27 --
 target/riscv/kvm-stub.c            |  30 ++
 target/riscv/kvm.c                 | 610 +++++++++++++++++++++++++++++
 target/riscv/kvm_riscv.h           |  25 ++
 target/riscv/machine.c             |  14 +
 target/riscv/meson.build           |   1 +
 target/riscv/sbi_ecall_interface.h |  72 ++++
 15 files changed, 976 insertions(+), 27 deletions(-)
 create mode 100644 linux-headers/asm-riscv/kvm.h
 create mode 100644 target/riscv/kvm-stub.c
 create mode 100644 target/riscv/kvm.c
 create mode 100644 target/riscv/kvm_riscv.h
 create mode 100644 target/riscv/sbi_ecall_interface.h

-- 
2.19.1


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-11-23  6:13   ` Alistair Francis
  2021-12-03  5:07   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface Yifei Jiang
                   ` (11 subsequent siblings)
  12 siblings, 2 replies; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li

Add asm-riscv/kvm.h for RISC-V KVM, and update linux/kvm.h

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
 linux-headers/asm-riscv/kvm.h | 128 ++++++++++++++++++++++++++++++++++
 linux-headers/linux/kvm.h     |   8 +++
 2 files changed, 136 insertions(+)
 create mode 100644 linux-headers/asm-riscv/kvm.h

diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h
new file mode 100644
index 0000000000..f808ad1ce5
--- /dev/null
+++ b/linux-headers/asm-riscv/kvm.h
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ *     Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __LINUX_KVM_RISCV_H
+#define __LINUX_KVM_RISCV_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/ptrace.h>
+
+#define __KVM_HAVE_READONLY_MEM
+
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
+
+#define KVM_INTERRUPT_SET	-1U
+#define KVM_INTERRUPT_UNSET	-2U
+
+/* for KVM_GET_REGS and KVM_SET_REGS */
+struct kvm_regs {
+};
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+};
+
+/* KVM Debug exit structure */
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
+/* definition of registers in kvm_run */
+struct kvm_sync_regs {
+};
+
+/* for KVM_GET_SREGS and KVM_SET_SREGS */
+struct kvm_sregs {
+};
+
+/* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+struct kvm_riscv_config {
+	unsigned long isa;
+};
+
+/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+struct kvm_riscv_core {
+	struct user_regs_struct regs;
+	unsigned long mode;
+};
+
+/* Possible privilege modes for kvm_riscv_core */
+#define KVM_RISCV_MODE_S	1
+#define KVM_RISCV_MODE_U	0
+
+/* CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+struct kvm_riscv_csr {
+	unsigned long sstatus;
+	unsigned long sie;
+	unsigned long stvec;
+	unsigned long sscratch;
+	unsigned long sepc;
+	unsigned long scause;
+	unsigned long stval;
+	unsigned long sip;
+	unsigned long satp;
+	unsigned long scounteren;
+};
+
+/* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+struct kvm_riscv_timer {
+	__u64 frequency;
+	__u64 time;
+	__u64 compare;
+	__u64 state;
+};
+
+/* Possible states for kvm_riscv_timer */
+#define KVM_RISCV_TIMER_STATE_OFF	0
+#define KVM_RISCV_TIMER_STATE_ON	1
+
+#define KVM_REG_SIZE(id)		\
+	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_RISCV_TYPE_MASK		0x00000000FF000000
+#define KVM_REG_RISCV_TYPE_SHIFT	24
+
+/* Config registers are mapped as type 1 */
+#define KVM_REG_RISCV_CONFIG		(0x01 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CONFIG_REG(name)	\
+	(offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
+
+/* Core registers are mapped as type 2 */
+#define KVM_REG_RISCV_CORE		(0x02 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CORE_REG(name)	\
+		(offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
+
+/* Control and status registers are mapped as type 3 */
+#define KVM_REG_RISCV_CSR		(0x03 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CSR_REG(name)	\
+		(offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
+
+/* Timer registers are mapped as type 4 */
+#define KVM_REG_RISCV_TIMER		(0x04 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_TIMER_REG(name)	\
+		(offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
+
+/* F extension registers are mapped as type 5 */
+#define KVM_REG_RISCV_FP_F		(0x05 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_FP_F_REG(name)	\
+		(offsetof(struct __riscv_f_ext_state, name) / sizeof(__u32))
+
+/* D extension registers are mapped as type 6 */
+#define KVM_REG_RISCV_FP_D		(0x06 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_FP_D_REG(name)	\
+		(offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
+
+#endif
+
+#endif /* __LINUX_KVM_RISCV_H */
diff --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] 35+ messages in thread

* [PATCH v1 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
  2021-11-20  7:46 ` [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  5:08   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu Yifei Jiang
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 96de1a6ef9..ae35e76ea4 100644
--- a/meson.build
+++ b/meson.build
@@ -77,6 +77,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 ['riscv']
+  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] 35+ messages in thread

* [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
  2021-11-20  7:46 ` [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h Yifei Jiang
  2021-11-20  7:46 ` [PATCH v1 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-11-20 22:19   ` Richard Henderson
  2021-11-20  7:46 ` [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers Yifei Jiang
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 687dd4b621..9f9692fb9e 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -38,6 +38,23 @@
 #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;
+
+    switch (riscv_cpu_mxl(env)) {
+    case MXL_RV32:
+        id |= KVM_REG_SIZE_U32;
+        break;
+    case MXL_RV64:
+        id |= KVM_REG_SIZE_U64;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    return id;
+}
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_LAST_INFO
 };
@@ -79,7 +96,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_mxl |= isa;
+
+    return ret;
 }
 
 int kvm_arch_msi_data_to_gsi(uint32_t data)
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (2 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  6:20   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers Yifei Jiang
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 9f9692fb9e..b49c24be0a 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -55,13 +55,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), &reg);
+    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, &reg);
+        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), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->mstatus = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sie), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->mie = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stvec), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->stvec = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sscratch), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->sscratch = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sepc), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->sepc = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, scause), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->scause = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stval), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->stval = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sip), &reg);
+    if (ret) {
+        return ret;
+    }
+    env->mip = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, satp), &reg);
+    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), &reg);
+            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), &reg);
+            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] 35+ messages in thread

* [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (3 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  6:22   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM Yifei Jiang
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 b49c24be0a..5fe5ca4434 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -90,6 +90,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), &reg);
+    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, &reg);
+        if (ret) {
+            return ret;
+        }
+    }
+
+    return ret;
+}
+
 static int kvm_riscv_get_regs_csr(CPUState *cs)
 {
     int ret = 0;
@@ -153,6 +178,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), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->mie;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sie), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->stvec;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stvec), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->sscratch;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sscratch), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->sepc;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sepc), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->scause;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, scause), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->stval;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stval), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->mip;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sip), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    reg = env->satp;
+    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, satp), &reg);
+    if (ret) {
+        return ret;
+    }
+
+    return ret;
+}
+
 static int kvm_riscv_get_regs_fp(CPUState *cs)
 {
     int ret = 0;
@@ -186,6 +274,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), &reg);
+            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), &reg);
+            if (ret) {
+                return ret;
+            }
+        }
+        return ret;
+    }
+
+    return ret;
+}
+
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_LAST_INFO
 };
@@ -214,7 +336,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] 35+ messages in thread

* [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (4 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  6:31   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 07/12] target/riscv: Support setting external interrupt " Yifei Jiang
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 519fa455a1..00df6d7810 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -317,3 +317,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 3af074148e..e3452b25e8 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -941,6 +941,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 baff11dd8a..5834c234aa 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -58,5 +58,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 f812998123..1c944872a3 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 */
 
@@ -380,6 +382,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 0760c0af93..2807eb1bcb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -255,6 +255,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 5fe5ca4434..7f3ffcc2b4 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)
 {
@@ -444,6 +445,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] 35+ messages in thread

* [PATCH v1 07/12] target/riscv: Support setting external interrupt by KVM
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (5 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  9:15   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 1c944872a3..a464845c99 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"
@@ -131,6 +132,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 9eeed38c7e..5e36c35b15 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -286,33 +286,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 7f3ffcc2b4..8da2648d1a 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -458,6 +458,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] 35+ messages in thread

* [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (6 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 07/12] target/riscv: Support setting external interrupt " Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-11-20 12:24   ` Philippe Mathieu-Daudé
  2021-11-20  7:46 ` [PATCH v1 09/12] target/riscv: Add host cpu type Yifei Jiang
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li

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 8da2648d1a..6d419ba02e 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)
 {
@@ -440,9 +442,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] 35+ messages in thread

* [PATCH v1 09/12] target/riscv: Add host cpu type
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (7 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  9:26   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer Yifei Jiang
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li, 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 a464845c99..6512182c62 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -247,6 +247,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, MXL_RV32, 0);
+#elif defined(TARGET_RISCV64)
+    set_misa(env, MXL_RV64, 0);
+#endif
+}
+#endif
+
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
@@ -844,6 +856,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 2807eb1bcb..e7dba35acb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -45,6 +45,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] 35+ messages in thread

* [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (8 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 09/12] target/riscv: Add host cpu type Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-12-03  9:38   ` Anup Patel
  2021-11-20  7:46 ` [PATCH v1 11/12] target/riscv: Implement virtual time adjusting with vm state changing Yifei Jiang
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li

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 e7dba35acb..dea49e53f0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -259,6 +259,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 6d419ba02e..e5725770f2 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -64,6 +64,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)
@@ -310,6 +313,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), &reg);
+    if (ret) {
+        abort();
+    }
+    env->kvm_timer_time = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, compare), &reg);
+    if (ret) {
+        abort();
+    }
+    env->kvm_timer_compare = reg;
+
+    ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, state), &reg);
+    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), &reg);
+    if (ret) {
+        abort();
+    }
+
+    reg = env->kvm_timer_compare;
+    ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, compare), &reg);
+    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), &reg);
+        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] 35+ messages in thread

* [PATCH v1 11/12] target/riscv: Implement virtual time adjusting with vm state changing
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (9 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-11-20  7:46 ` [PATCH v1 12/12] target/riscv: Support virtual time context synchronization Yifei Jiang
  2021-12-03  8:41 ` [PATCH v1 00/12] Add riscv kvm accel support Michal Prívozník
  12 siblings, 0 replies; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li

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 e5725770f2..b2e14d579e 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)
 {
@@ -452,6 +453,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)
 {
 }
@@ -464,6 +476,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] 35+ messages in thread

* [PATCH v1 12/12] target/riscv: Support virtual time context synchronization
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (10 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 11/12] target/riscv: Implement virtual time adjusting with vm state changing Yifei Jiang
@ 2021-11-20  7:46 ` Yifei Jiang
  2021-11-20 22:34   ` Richard Henderson
  2021-12-03  8:41 ` [PATCH v1 00/12] Add riscv kvm accel support Michal Prívozník
  12 siblings, 1 reply; 35+ messages in thread
From: Yifei Jiang @ 2021-11-20  7:46 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: kvm-riscv, kvm, libvir-list, anup.patel, palmer,
	Alistair.Francis, bin.meng, fanliang, wu.wubin, wanghaibin.wang,
	wanbo13, Yifei Jiang, Mingwang Li

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 ad8248ebfd..153215549b 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -164,10 +164,20 @@ static const VMStateDescription vmstate_pointermasking = {
     }
 };
 
+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 = 3,
     .minimum_version_id = 3,
+    .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
         VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
@@ -211,6 +221,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] 35+ messages in thread

* Re: [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
  2021-11-20  7:46 ` [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
@ 2021-11-20 12:24   ` Philippe Mathieu-Daudé
  2021-12-10 10:02     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-11-20 12:24 UTC (permalink / raw)
  To: Yifei Jiang, qemu-devel, qemu-riscv
  Cc: bin.meng, Mingwang Li, kvm, libvir-list, anup.patel, wanbo13,
	Alistair.Francis, kvm-riscv, wanghaibin.wang, palmer, fanliang,
	wu.wubin, Alex Bennée

Hi,

On 11/20/21 08:46, Yifei Jiang 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 8da2648d1a..6d419ba02e 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)
>  {
> @@ -440,9 +442,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;

Shouldn't this code use the Semihosting Console API from
"semihosting/console.h" instead?

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu
  2021-11-20  7:46 ` [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu Yifei Jiang
@ 2021-11-20 22:19   ` Richard Henderson
  2021-12-10  9:55     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Henderson @ 2021-11-20 22:19 UTC (permalink / raw)
  To: Yifei Jiang, qemu-devel, qemu-riscv
  Cc: bin.meng, Mingwang Li, kvm, libvir-list, anup.patel, wanbo13,
	Alistair Francis, kvm-riscv, wanghaibin.wang, palmer, fanliang,
	wu.wubin

On 11/20/21 8:46 AM, Yifei Jiang wrote:
> +    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_mxl |= isa;

This doesn't look right.
I'm sure you meant

     env->misa_ext = isa;


r~

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 12/12] target/riscv: Support virtual time context synchronization
  2021-11-20  7:46 ` [PATCH v1 12/12] target/riscv: Support virtual time context synchronization Yifei Jiang
@ 2021-11-20 22:34   ` Richard Henderson
  2021-12-10 10:03     ` Jiangyifei
  2021-12-10 10:11     ` Paolo Bonzini
  0 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2021-11-20 22:34 UTC (permalink / raw)
  To: Yifei Jiang, qemu-devel, qemu-riscv
  Cc: bin.meng, Mingwang Li, kvm, libvir-list, anup.patel, wanbo13,
	Alistair.Francis, kvm-riscv, wanghaibin.wang, palmer, fanliang,
	wu.wubin

On 11/20/21 8:46 AM, Yifei Jiang wrote:
>   const VMStateDescription vmstate_riscv_cpu = {
>       .name = "cpu",
>       .version_id = 3,
>       .minimum_version_id = 3,
> +    .post_load = cpu_post_load,
>       .fields = (VMStateField[]) {
>           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> @@ -211,6 +221,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()
>       },

Can't alter VMStateDescription.fields without bumping version.

If this is really kvm-only state, consider placing it into a subsection.  But I worry 
about kvm-only state because ideally we'd be able to migrate between tcg and kvm (if only 
for debugging).


r~

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h
  2021-11-20  7:46 ` [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h Yifei Jiang
@ 2021-11-23  6:13   ` Alistair Francis
  2021-12-03  5:07   ` Anup Patel
  1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2021-11-23  6:13 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, Bin Meng,
	Mingwang Li, open list:Overall, libvir-list, Anup Patel, wanbo13,
	Alistair Francis, kvm-riscv, wanghaibin.wang, Palmer Dabbelt,
	fanliang, Wubin (H)

On Sat, Nov 20, 2021 at 5:51 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> Add asm-riscv/kvm.h for RISC-V KVM, and update linux/kvm.h
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Mingwang Li <limingwang@huawei.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  linux-headers/asm-riscv/kvm.h | 128 ++++++++++++++++++++++++++++++++++
>  linux-headers/linux/kvm.h     |   8 +++
>  2 files changed, 136 insertions(+)
>  create mode 100644 linux-headers/asm-riscv/kvm.h
>
> diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h
> new file mode 100644
> index 0000000000..f808ad1ce5
> --- /dev/null
> +++ b/linux-headers/asm-riscv/kvm.h
> @@ -0,0 +1,128 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *     Anup Patel <anup.patel@wdc.com>
> + */
> +
> +#ifndef __LINUX_KVM_RISCV_H
> +#define __LINUX_KVM_RISCV_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <linux/types.h>
> +#include <asm/ptrace.h>
> +
> +#define __KVM_HAVE_READONLY_MEM
> +
> +#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
> +
> +#define KVM_INTERRUPT_SET      -1U
> +#define KVM_INTERRUPT_UNSET    -2U
> +
> +/* for KVM_GET_REGS and KVM_SET_REGS */
> +struct kvm_regs {
> +};
> +
> +/* for KVM_GET_FPU and KVM_SET_FPU */
> +struct kvm_fpu {
> +};
> +
> +/* KVM Debug exit structure */
> +struct kvm_debug_exit_arch {
> +};
> +
> +/* for KVM_SET_GUEST_DEBUG */
> +struct kvm_guest_debug_arch {
> +};
> +
> +/* definition of registers in kvm_run */
> +struct kvm_sync_regs {
> +};
> +
> +/* for KVM_GET_SREGS and KVM_SET_SREGS */
> +struct kvm_sregs {
> +};
> +
> +/* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_config {
> +       unsigned long isa;
> +};
> +
> +/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_core {
> +       struct user_regs_struct regs;
> +       unsigned long mode;
> +};
> +
> +/* Possible privilege modes for kvm_riscv_core */
> +#define KVM_RISCV_MODE_S       1
> +#define KVM_RISCV_MODE_U       0
> +
> +/* CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_csr {
> +       unsigned long sstatus;
> +       unsigned long sie;
> +       unsigned long stvec;
> +       unsigned long sscratch;
> +       unsigned long sepc;
> +       unsigned long scause;
> +       unsigned long stval;
> +       unsigned long sip;
> +       unsigned long satp;
> +       unsigned long scounteren;
> +};
> +
> +/* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_timer {
> +       __u64 frequency;
> +       __u64 time;
> +       __u64 compare;
> +       __u64 state;
> +};
> +
> +/* Possible states for kvm_riscv_timer */
> +#define KVM_RISCV_TIMER_STATE_OFF      0
> +#define KVM_RISCV_TIMER_STATE_ON       1
> +
> +#define KVM_REG_SIZE(id)               \
> +       (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
> +
> +/* If you need to interpret the index values, here is the key: */
> +#define KVM_REG_RISCV_TYPE_MASK                0x00000000FF000000
> +#define KVM_REG_RISCV_TYPE_SHIFT       24
> +
> +/* Config registers are mapped as type 1 */
> +#define KVM_REG_RISCV_CONFIG           (0x01 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_CONFIG_REG(name) \
> +       (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
> +
> +/* Core registers are mapped as type 2 */
> +#define KVM_REG_RISCV_CORE             (0x02 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_CORE_REG(name)   \
> +               (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
> +
> +/* Control and status registers are mapped as type 3 */
> +#define KVM_REG_RISCV_CSR              (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_CSR_REG(name)    \
> +               (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
> +
> +/* Timer registers are mapped as type 4 */
> +#define KVM_REG_RISCV_TIMER            (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_TIMER_REG(name)  \
> +               (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
> +
> +/* F extension registers are mapped as type 5 */
> +#define KVM_REG_RISCV_FP_F             (0x05 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_FP_F_REG(name)   \
> +               (offsetof(struct __riscv_f_ext_state, name) / sizeof(__u32))
> +
> +/* D extension registers are mapped as type 6 */
> +#define KVM_REG_RISCV_FP_D             (0x06 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_FP_D_REG(name)   \
> +               (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
> +
> +#endif
> +
> +#endif /* __LINUX_KVM_RISCV_H */
> diff --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	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h
  2021-11-20  7:46 ` [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h Yifei Jiang
  2021-11-23  6:13   ` Alistair Francis
@ 2021-12-03  5:07   ` Anup Patel
  1 sibling, 0 replies; 35+ messages in thread
From: Anup Patel @ 2021-12-03  5:07 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> Add asm-riscv/kvm.h for RISC-V KVM, and update linux/kvm.h
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Mingwang Li <limingwang@huawei.com>

Looks good to me.

Reviewed-by: Anup Patel <anup.patel@wdc.com>

Regards,
Anup

> ---
>  linux-headers/asm-riscv/kvm.h | 128 ++++++++++++++++++++++++++++++++++
>  linux-headers/linux/kvm.h     |   8 +++
>  2 files changed, 136 insertions(+)
>  create mode 100644 linux-headers/asm-riscv/kvm.h
>
> diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h
> new file mode 100644
> index 0000000000..f808ad1ce5
> --- /dev/null
> +++ b/linux-headers/asm-riscv/kvm.h
> @@ -0,0 +1,128 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *     Anup Patel <anup.patel@wdc.com>
> + */
> +
> +#ifndef __LINUX_KVM_RISCV_H
> +#define __LINUX_KVM_RISCV_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <linux/types.h>
> +#include <asm/ptrace.h>
> +
> +#define __KVM_HAVE_READONLY_MEM
> +
> +#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
> +
> +#define KVM_INTERRUPT_SET      -1U
> +#define KVM_INTERRUPT_UNSET    -2U
> +
> +/* for KVM_GET_REGS and KVM_SET_REGS */
> +struct kvm_regs {
> +};
> +
> +/* for KVM_GET_FPU and KVM_SET_FPU */
> +struct kvm_fpu {
> +};
> +
> +/* KVM Debug exit structure */
> +struct kvm_debug_exit_arch {
> +};
> +
> +/* for KVM_SET_GUEST_DEBUG */
> +struct kvm_guest_debug_arch {
> +};
> +
> +/* definition of registers in kvm_run */
> +struct kvm_sync_regs {
> +};
> +
> +/* for KVM_GET_SREGS and KVM_SET_SREGS */
> +struct kvm_sregs {
> +};
> +
> +/* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_config {
> +       unsigned long isa;
> +};
> +
> +/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_core {
> +       struct user_regs_struct regs;
> +       unsigned long mode;
> +};
> +
> +/* Possible privilege modes for kvm_riscv_core */
> +#define KVM_RISCV_MODE_S       1
> +#define KVM_RISCV_MODE_U       0
> +
> +/* CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_csr {
> +       unsigned long sstatus;
> +       unsigned long sie;
> +       unsigned long stvec;
> +       unsigned long sscratch;
> +       unsigned long sepc;
> +       unsigned long scause;
> +       unsigned long stval;
> +       unsigned long sip;
> +       unsigned long satp;
> +       unsigned long scounteren;
> +};
> +
> +/* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
> +struct kvm_riscv_timer {
> +       __u64 frequency;
> +       __u64 time;
> +       __u64 compare;
> +       __u64 state;
> +};
> +
> +/* Possible states for kvm_riscv_timer */
> +#define KVM_RISCV_TIMER_STATE_OFF      0
> +#define KVM_RISCV_TIMER_STATE_ON       1
> +
> +#define KVM_REG_SIZE(id)               \
> +       (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
> +
> +/* If you need to interpret the index values, here is the key: */
> +#define KVM_REG_RISCV_TYPE_MASK                0x00000000FF000000
> +#define KVM_REG_RISCV_TYPE_SHIFT       24
> +
> +/* Config registers are mapped as type 1 */
> +#define KVM_REG_RISCV_CONFIG           (0x01 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_CONFIG_REG(name) \
> +       (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
> +
> +/* Core registers are mapped as type 2 */
> +#define KVM_REG_RISCV_CORE             (0x02 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_CORE_REG(name)   \
> +               (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
> +
> +/* Control and status registers are mapped as type 3 */
> +#define KVM_REG_RISCV_CSR              (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_CSR_REG(name)    \
> +               (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
> +
> +/* Timer registers are mapped as type 4 */
> +#define KVM_REG_RISCV_TIMER            (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_TIMER_REG(name)  \
> +               (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
> +
> +/* F extension registers are mapped as type 5 */
> +#define KVM_REG_RISCV_FP_F             (0x05 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_FP_F_REG(name)   \
> +               (offsetof(struct __riscv_f_ext_state, name) / sizeof(__u32))
> +
> +/* D extension registers are mapped as type 6 */
> +#define KVM_REG_RISCV_FP_D             (0x06 << KVM_REG_RISCV_TYPE_SHIFT)
> +#define KVM_REG_RISCV_FP_D_REG(name)   \
> +               (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
> +
> +#endif
> +
> +#endif /* __LINUX_KVM_RISCV_H */
> diff --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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface
  2021-11-20  7:46 ` [PATCH v1 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface Yifei Jiang
@ 2021-12-03  5:08   ` Anup Patel
  0 siblings, 0 replies; 35+ messages in thread
From: Anup Patel @ 2021-12-03  5:08 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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>

Looks good to me.

Reviewed-by: Anup Patel <anup.patel@wdc.com>

Regards,
Anup

> ---
>  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 96de1a6ef9..ae35e76ea4 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -77,6 +77,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 ['riscv']
> +  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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers
  2021-11-20  7:46 ` [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers Yifei Jiang
@ 2021-12-03  6:20   ` Anup Patel
  2021-12-10  9:57     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Anup Patel @ 2021-12-03  6:20 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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 9f9692fb9e..b49c24be0a 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -55,13 +55,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), &reg);
> +    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, &reg);
> +        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), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->mstatus = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sie), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->mie = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stvec), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->stvec = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sscratch), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->sscratch = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sepc), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->sepc = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, scause), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->scause = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stval), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->stval = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sip), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->mip = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, satp), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +    env->satp = reg;

There is a common pattern in above kvm_get_one_reg() calls so I suggest
creating a macro for repeating code patterns. This can help us to have one
line for each CSR and in future it is easy to add more CSRs.

Regards,
Anup

> +
> +    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), &reg);
> +            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), &reg);
> +            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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers
  2021-11-20  7:46 ` [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers Yifei Jiang
@ 2021-12-03  6:22   ` Anup Patel
  2021-12-10  9:58     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Anup Patel @ 2021-12-03  6:22 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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 b49c24be0a..5fe5ca4434 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -90,6 +90,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), &reg);
> +    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, &reg);
> +        if (ret) {
> +            return ret;
> +        }
> +    }
> +
> +    return ret;
> +}
> +
>  static int kvm_riscv_get_regs_csr(CPUState *cs)
>  {
>      int ret = 0;
> @@ -153,6 +178,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), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->mie;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sie), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->stvec;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stvec), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->sscratch;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sscratch), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->sepc;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sepc), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->scause;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, scause), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->stval;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stval), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->mip;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sip), &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg = env->satp;
> +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, satp), &reg);
> +    if (ret) {
> +        return ret;
> +    }

Same as the previous patch, there is a common pattern in above
kvm_set_one_reg() calls. Please use a macro to simplify.

Regards,
Anup

> +
> +    return ret;
> +}
> +
>  static int kvm_riscv_get_regs_fp(CPUState *cs)
>  {
>      int ret = 0;
> @@ -186,6 +274,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), &reg);
> +            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), &reg);
> +            if (ret) {
> +                return ret;
> +            }
> +        }
> +        return ret;
> +    }
> +
> +    return ret;
> +}
> +
> +
>  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>      KVM_CAP_LAST_INFO
>  };
> @@ -214,7 +336,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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM
  2021-11-20  7:46 ` [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM Yifei Jiang
@ 2021-12-03  6:31   ` Anup Patel
  2021-12-10 10:00     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Anup Patel @ 2021-12-03  6:31 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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 519fa455a1..00df6d7810 100644
> --- a/hw/riscv/boot.c
> +++ b/hw/riscv/boot.c
> @@ -317,3 +317,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 3af074148e..e3452b25e8 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -941,6 +941,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);

This should be under "if (kvm_enabled()) {".

Also, update virt machine such that the "-bios" parameter is ignored
and treated like "-bios none" when KVM is enabled.

Further, virt machine should not create an ACLINT (or SiFive CLINT)
instance when KVM is enabled. Event the PLIC should be created
without M-mode PLIC contexts when KVM is enabled.

Regards,
Anup

> +
>      /* 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 baff11dd8a..5834c234aa 100644
> --- a/include/hw/riscv/boot.h
> +++ b/include/hw/riscv/boot.h
> @@ -58,5 +58,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 f812998123..1c944872a3 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 */
>
> @@ -380,6 +382,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 0760c0af93..2807eb1bcb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -255,6 +255,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 5fe5ca4434..7f3ffcc2b4 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)
>  {
> @@ -444,6 +445,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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 00/12] Add riscv kvm accel support
  2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
                   ` (11 preceding siblings ...)
  2021-11-20  7:46 ` [PATCH v1 12/12] target/riscv: Support virtual time context synchronization Yifei Jiang
@ 2021-12-03  8:41 ` Michal Prívozník
  12 siblings, 0 replies; 35+ messages in thread
From: Michal Prívozník @ 2021-12-03  8:41 UTC (permalink / raw)
  To: Yifei Jiang, qemu-devel, qemu-riscv
  Cc: bin.meng, kvm, libvir-list, anup.patel, wanbo13,
	Alistair.Francis, kvm-riscv, wanghaibin.wang, palmer, fanliang,
	wu.wubin

On 11/20/21 08:46, Yifei Jiang wrote:
> This series adds both riscv32 and riscv64 kvm support, and implements
> migration based on riscv.

What libvirt does when detecting KVM support is issuing query-kvm
monitor command and checking if both 'present' and 'enabled' bools are
true. If this is what these patches end up with we should get KVM
acceleration in Libvirt for free.

Michal


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 07/12] target/riscv: Support setting external interrupt by KVM
  2021-11-20  7:46 ` [PATCH v1 07/12] target/riscv: Support setting external interrupt " Yifei Jiang
@ 2021-12-03  9:15   ` Anup Patel
  2021-12-10 10:01     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Anup Patel @ 2021-12-03  9:15 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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 1c944872a3..a464845c99 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"
> @@ -131,6 +132,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
> +

We should not change riscv_cpu_update_mip() for injecting KVM interrupts
because this function touches the user-space state of MIP csr but for KVM
the SIP csr state is always in kernel-space.

Further, the KVM kernel-space ensures synchronization so we don't need
to do qemu_mutex_lock/unlock_iothread() for KVM interrupts.

I would suggest to extend riscv_cpu_set_irq() for KVM interrupts. When
KVM is enabled, the riscv_cpu_set_irq() should throw warning/abort for
any interrupt other than S-mode external interrupts.

Regards,
Anup

>  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 9eeed38c7e..5e36c35b15 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -286,33 +286,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 7f3ffcc2b4..8da2648d1a 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -458,6 +458,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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 09/12] target/riscv: Add host cpu type
  2021-11-20  7:46 ` [PATCH v1 09/12] target/riscv: Add host cpu type Yifei Jiang
@ 2021-12-03  9:26   ` Anup Patel
  0 siblings, 0 replies; 35+ messages in thread
From: Anup Patel @ 2021-12-03  9:26 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> '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>

Looks good to me.

Reviewed-by: Anup Patel <anup.patel@wdc.com>

Regards,
Anup

> ---
>  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 a464845c99..6512182c62 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -247,6 +247,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, MXL_RV32, 0);
> +#elif defined(TARGET_RISCV64)
> +    set_misa(env, MXL_RV64, 0);
> +#endif
> +}
> +#endif
> +
>  static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
>  {
>      ObjectClass *oc;
> @@ -844,6 +856,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 2807eb1bcb..e7dba35acb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -45,6 +45,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
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer
  2021-11-20  7:46 ` [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer Yifei Jiang
@ 2021-12-03  9:38   ` Anup Patel
  2021-12-10 10:03     ` Jiangyifei
  0 siblings, 1 reply; 35+ messages in thread
From: Anup Patel @ 2021-12-03  9:38 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, fanliang, Wubin (H),
	wanghaibin.wang, wanbo13, Mingwang Li

On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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 e7dba35acb..dea49e53f0 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -259,6 +259,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;

We should also include kvm_timer_frequency here.

Currently, it is read-only but in-future KVM RISC-V will allow
setting timer_frequency using SBI para-virt time scaling extension.

Regards,
Anup

>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
> index 6d419ba02e..e5725770f2 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -64,6 +64,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)
> @@ -310,6 +313,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), &reg);
> +    if (ret) {
> +        abort();
> +    }
> +    env->kvm_timer_time = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, compare), &reg);
> +    if (ret) {
> +        abort();
> +    }
> +    env->kvm_timer_compare = reg;
> +
> +    ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, state), &reg);
> +    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), &reg);
> +    if (ret) {
> +        abort();
> +    }
> +
> +    reg = env->kvm_timer_compare;
> +    ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, compare), &reg);
> +    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), &reg);
> +        if (ret) {
> +            abort();
> +        }
> +    }
> +
> +    env->kvm_timer_dirty = false;
> +}
>
>  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>      KVM_CAP_LAST_INFO
> --
> 2.19.1
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu
  2021-11-20 22:19   ` Richard Henderson
@ 2021-12-10  9:55     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10  9:55 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: bin.meng, limingwang (A), kvm, libvir-list, anup.patel, wanbo (G),
	Alistair Francis, kvm-riscv, Wanghaibin (D),
	palmer, Fanliang (EulerOS), Wubin (H)


> -----Original Message-----
> From: Richard Henderson [mailto:richard.henderson@linaro.org]
> Sent: Sunday, November 21, 2021 6:19 AM
> To: Jiangyifei <jiangyifei@huawei.com>; qemu-devel@nongnu.org;
> qemu-riscv@nongnu.org
> Cc: bin.meng@windriver.com; limingwang (A) <limingwang@huawei.com>;
> kvm@vger.kernel.org; libvir-list@redhat.com; anup.patel@wdc.com; wanbo (G)
> <wanbo13@huawei.com>; Alistair Francis <alistair.francis@wdc.com>;
> kvm-riscv@lists.infradead.org; Wanghaibin (D)
> <wanghaibin.wang@huawei.com>; palmer@dabbelt.com; Fanliang (EulerOS)
> <fanliang@huawei.com>; Wubin (H) <wu.wubin@huawei.com>
> Subject: Re: [PATCH v1 03/12] target/riscv: Implement function
> kvm_arch_init_vcpu
> 
> On 11/20/21 8:46 AM, Yifei Jiang wrote:
> > +    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_mxl |= isa;
> 
> This doesn't look right.
> I'm sure you meant
> 
>      env->misa_ext = isa;
> 
> 
> r~

Thanks, it will be modified in the next series.

Yifei

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers
  2021-12-03  6:20   ` Anup Patel
@ 2021-12-10  9:57     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10  9:57 UTC (permalink / raw)
  To: Anup Patel
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, Fanliang (EulerOS), Wubin (H), Wanghaibin (D),
	wanbo (G), limingwang (A)


> -----Original Message-----
> From: kvm-riscv [mailto:kvm-riscv-bounces@lists.infradead.org] On Behalf Of
> Anup Patel
> Sent: Friday, December 3, 2021 2:20 PM
> To: Jiangyifei <jiangyifei@huawei.com>
> Cc: QEMU Developers <qemu-devel@nongnu.org>; open list:RISC-V
> <qemu-riscv@nongnu.org>; kvm-riscv@lists.infradead.org; KVM General
> <kvm@vger.kernel.org>; libvir-list@redhat.com; Anup Patel
> <anup.patel@wdc.com>; Palmer Dabbelt <palmer@dabbelt.com>; Alistair
> Francis <Alistair.Francis@wdc.com>; Bin Meng <bin.meng@windriver.com>;
> Fanliang (EulerOS) <fanliang@huawei.com>; Wubin (H)
> <wu.wubin@huawei.com>; Wanghaibin (D) <wanghaibin.wang@huawei.com>;
> wanbo (G) <wanbo13@huawei.com>; limingwang (A)
> <limingwang@huawei.com>
> Subject: Re: [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers
> 
> On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
> >
> > 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
> > 9f9692fb9e..b49c24be0a 100644
> > --- a/target/riscv/kvm.c
> > +++ b/target/riscv/kvm.c
> > @@ -55,13 +55,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), &reg);
> > +    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, &reg);
> > +        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), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->mstatus = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sie), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->mie = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stvec), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->stvec = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sscratch), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->sscratch = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sepc), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->sepc = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, scause), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->scause = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, stval), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->stval = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, sip), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->mip = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, satp), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    env->satp = reg;
> 
> There is a common pattern in above kvm_get_one_reg() calls so I suggest
> creating a macro for repeating code patterns. This can help us to have one line
> for each CSR and in future it is easy to add more CSRs.
> 
> Regards,
> Anup
> 

Thanks, it will be modified in the next series.

Yifei

> > +
> > +    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), &reg);
> > +            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), &reg);
> > +            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
> >
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv
> 
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers
  2021-12-03  6:22   ` Anup Patel
@ 2021-12-10  9:58     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10  9:58 UTC (permalink / raw)
  To: Anup Patel
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, Fanliang (EulerOS), Wubin (H), Wanghaibin (D),
	wanbo (G), limingwang (A)


> -----Original Message-----
> From: Anup Patel [mailto:anup@brainfault.org]
> Sent: Friday, December 3, 2021 2:22 PM
> To: Jiangyifei <jiangyifei@huawei.com>
> Cc: QEMU Developers <qemu-devel@nongnu.org>; open list:RISC-V
> <qemu-riscv@nongnu.org>; kvm-riscv@lists.infradead.org; KVM General
> <kvm@vger.kernel.org>; libvir-list@redhat.com; Anup Patel
> <anup.patel@wdc.com>; Palmer Dabbelt <palmer@dabbelt.com>; Alistair
> Francis <Alistair.Francis@wdc.com>; Bin Meng <bin.meng@windriver.com>;
> Fanliang (EulerOS) <fanliang@huawei.com>; Wubin (H)
> <wu.wubin@huawei.com>; Wanghaibin (D) <wanghaibin.wang@huawei.com>;
> wanbo (G) <wanbo13@huawei.com>; limingwang (A)
> <limingwang@huawei.com>
> Subject: Re: [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers
> 
> On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
> >
> > 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
> > b49c24be0a..5fe5ca4434 100644
> > --- a/target/riscv/kvm.c
> > +++ b/target/riscv/kvm.c
> > @@ -90,6 +90,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), &reg);
> > +    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, &reg);
> > +        if (ret) {
> > +            return ret;
> > +        }
> > +    }
> > +
> > +    return ret;
> > +}
> > +
> >  static int kvm_riscv_get_regs_csr(CPUState *cs)  {
> >      int ret = 0;
> > @@ -153,6 +178,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), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->mie;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sie), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->stvec;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stvec), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->sscratch;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sscratch), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->sepc;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sepc), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->scause;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, scause), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->stval;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, stval), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->mip;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, sip), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +
> > +    reg = env->satp;
> > +    ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, satp), &reg);
> > +    if (ret) {
> > +        return ret;
> > +    }
> 
> Same as the previous patch, there is a common pattern in above
> kvm_set_one_reg() calls. Please use a macro to simplify.
> 
> Regards,
> Anup
> 

Thanks, it will be modified in the next series.

Yifei

> > +
> > +    return ret;
> > +}
> > +
> >  static int kvm_riscv_get_regs_fp(CPUState *cs)  {
> >      int ret = 0;
> > @@ -186,6 +274,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), &reg);
> > +            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), &reg);
> > +            if (ret) {
> > +                return ret;
> > +            }
> > +        }
> > +        return ret;
> > +    }
> > +
> > +    return ret;
> > +}
> > +
> > +
> >  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
> >      KVM_CAP_LAST_INFO
> >  };
> > @@ -214,7 +336,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
> >
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM
  2021-12-03  6:31   ` Anup Patel
@ 2021-12-10 10:00     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10 10:00 UTC (permalink / raw)
  To: Anup Patel
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, Fanliang (EulerOS), Wubin (H), Wanghaibin (D),
	wanbo (G), limingwang (A)


> -----Original Message-----
> From: kvm-riscv [mailto:kvm-riscv-bounces@lists.infradead.org] On Behalf Of
> Anup Patel
> Sent: Friday, December 3, 2021 2:31 PM
> To: Jiangyifei <jiangyifei@huawei.com>
> Cc: QEMU Developers <qemu-devel@nongnu.org>; open list:RISC-V
> <qemu-riscv@nongnu.org>; kvm-riscv@lists.infradead.org; KVM General
> <kvm@vger.kernel.org>; libvir-list@redhat.com; Anup Patel
> <anup.patel@wdc.com>; Palmer Dabbelt <palmer@dabbelt.com>; Alistair
> Francis <Alistair.Francis@wdc.com>; Bin Meng <bin.meng@windriver.com>;
> Fanliang (EulerOS) <fanliang@huawei.com>; Wubin (H)
> <wu.wubin@huawei.com>; Wanghaibin (D) <wanghaibin.wang@huawei.com>;
> wanbo (G) <wanbo13@huawei.com>; limingwang (A)
> <limingwang@huawei.com>
> Subject: Re: [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM
> 
> On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
> >
> > 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
> > 519fa455a1..00df6d7810 100644
> > --- a/hw/riscv/boot.c
> > +++ b/hw/riscv/boot.c
> > @@ -317,3 +317,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
> > 3af074148e..e3452b25e8 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -941,6 +941,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);
> 
> This should be under "if (kvm_enabled()) {".
> 
> Also, update virt machine such that the "-bios" parameter is ignored and
> treated like "-bios none" when KVM is enabled.
> 

Thanks, it will be modified in the next series.

> Further, virt machine should not create an ACLINT (or SiFive CLINT) instance
> when KVM is enabled. Event the PLIC should be created without M-mode PLIC
> contexts when KVM is enabled.
> 
> Regards,
> Anup
> 

Yes, you are right. But in order to reuse the PLIC, it is not planned to modify the PLIC at this time.

Yifei

> > +
> >      /* 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
> > baff11dd8a..5834c234aa 100644
> > --- a/include/hw/riscv/boot.h
> > +++ b/include/hw/riscv/boot.h
> > @@ -58,5 +58,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
> > f812998123..1c944872a3 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 */
> >
> > @@ -380,6 +382,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
> > 0760c0af93..2807eb1bcb 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -255,6 +255,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
> > 5fe5ca4434..7f3ffcc2b4 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)  { @@ -444,6 +445,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
> >
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv
> 
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 07/12] target/riscv: Support setting external interrupt by KVM
  2021-12-03  9:15   ` Anup Patel
@ 2021-12-10 10:01     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10 10:01 UTC (permalink / raw)
  To: Anup Patel
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, Fanliang (EulerOS), Wubin (H), Wanghaibin (D),
	wanbo (G), limingwang (A)


> -----Original Message-----
> From: kvm-riscv [mailto:kvm-riscv-bounces@lists.infradead.org] On Behalf Of
> Anup Patel
> Sent: Friday, December 3, 2021 5:15 PM
> To: Jiangyifei <jiangyifei@huawei.com>
> Cc: QEMU Developers <qemu-devel@nongnu.org>; open list:RISC-V
> <qemu-riscv@nongnu.org>; kvm-riscv@lists.infradead.org; KVM General
> <kvm@vger.kernel.org>; libvir-list@redhat.com; Anup Patel
> <anup.patel@wdc.com>; Palmer Dabbelt <palmer@dabbelt.com>; Alistair
> Francis <Alistair.Francis@wdc.com>; Bin Meng <bin.meng@windriver.com>;
> Fanliang (EulerOS) <fanliang@huawei.com>; Wubin (H)
> <wu.wubin@huawei.com>; Wanghaibin (D) <wanghaibin.wang@huawei.com>;
> wanbo (G) <wanbo13@huawei.com>; limingwang (A)
> <limingwang@huawei.com>
> Subject: Re: [PATCH v1 07/12] target/riscv: Support setting external interrupt
> by KVM
> 
> On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
> >
> > 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
> > 1c944872a3..a464845c99 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"
> > @@ -131,6 +132,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
> > +
> 
> We should not change riscv_cpu_update_mip() for injecting KVM interrupts
> because this function touches the user-space state of MIP csr but for KVM the
> SIP csr state is always in kernel-space.
> 
> Further, the KVM kernel-space ensures synchronization so we don't need to do
> qemu_mutex_lock/unlock_iothread() for KVM interrupts.
> 
> I would suggest to extend riscv_cpu_set_irq() for KVM interrupts. When KVM is
> enabled, the riscv_cpu_set_irq() should throw warning/abort for any interrupt
> other than S-mode external interrupts.
> 
> Regards,
> Anup
> 

Thanks, it will be modified in the next series.

Yifei

> >  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 9eeed38c7e..5e36c35b15 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -286,33 +286,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
> > 7f3ffcc2b4..8da2648d1a 100644
> > --- a/target/riscv/kvm.c
> > +++ b/target/riscv/kvm.c
> > @@ -458,6 +458,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
> >
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv
> 
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
  2021-11-20 12:24   ` Philippe Mathieu-Daudé
@ 2021-12-10 10:02     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10 10:02 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel, qemu-riscv
  Cc: bin.meng, limingwang (A), kvm, libvir-list, anup.patel, wanbo (G),
	Alistair.Francis, kvm-riscv, Wanghaibin (D),
	palmer, Fanliang (EulerOS), Wubin (H),
	Alex Bennée


> -----Original Message-----
> From: Philippe Mathieu-Daudé [mailto:philippe.mathieu.daude@gmail.com]
> On Behalf Of Philippe Mathieu-Daudé
> Sent: Saturday, November 20, 2021 8:25 PM
> To: Jiangyifei <jiangyifei@huawei.com>; qemu-devel@nongnu.org;
> qemu-riscv@nongnu.org
> Cc: bin.meng@windriver.com; limingwang (A) <limingwang@huawei.com>;
> kvm@vger.kernel.org; libvir-list@redhat.com; anup.patel@wdc.com; wanbo (G)
> <wanbo13@huawei.com>; Alistair.Francis@wdc.com;
> kvm-riscv@lists.infradead.org; Wanghaibin (D)
> <wanghaibin.wang@huawei.com>; palmer@dabbelt.com; Fanliang (EulerOS)
> <fanliang@huawei.com>; Wubin (H) <wu.wubin@huawei.com>; Alex Bennée
> <alex.bennee@linaro.org>
> Subject: Re: [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit
> 
> Hi,
> 
> On 11/20/21 08:46, Yifei Jiang 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
> > 8da2648d1a..6d419ba02e 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)  { @@ -440,9 +442,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;
> 
> Shouldn't this code use the Semihosting Console API from
> "semihosting/console.h" instead?

Thanks, I will use this API in the next series.

Yifei

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer
  2021-12-03  9:38   ` Anup Patel
@ 2021-12-10 10:03     ` Jiangyifei
  0 siblings, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10 10:03 UTC (permalink / raw)
  To: Anup Patel
  Cc: QEMU Developers, open list:RISC-V, kvm-riscv, KVM General,
	libvir-list, Anup Patel, Palmer Dabbelt, Alistair Francis,
	Bin Meng, Fanliang (EulerOS), Wubin (H), Wanghaibin (D),
	wanbo (G), limingwang (A)


> -----Original Message-----
> From: Anup Patel [mailto:anup@brainfault.org]
> Sent: Friday, December 3, 2021 5:38 PM
> To: Jiangyifei <jiangyifei@huawei.com>
> Cc: QEMU Developers <qemu-devel@nongnu.org>; open list:RISC-V
> <qemu-riscv@nongnu.org>; kvm-riscv@lists.infradead.org; KVM General
> <kvm@vger.kernel.org>; libvir-list@redhat.com; Anup Patel
> <anup.patel@wdc.com>; Palmer Dabbelt <palmer@dabbelt.com>; Alistair
> Francis <Alistair.Francis@wdc.com>; Bin Meng <bin.meng@windriver.com>;
> Fanliang (EulerOS) <fanliang@huawei.com>; Wubin (H)
> <wu.wubin@huawei.com>; Wanghaibin (D) <wanghaibin.wang@huawei.com>;
> wanbo (G) <wanbo13@huawei.com>; limingwang (A)
> <limingwang@huawei.com>
> Subject: Re: [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer
> 
> On Sat, Nov 20, 2021 at 1:17 PM Yifei Jiang <jiangyifei@huawei.com> wrote:
> >
> > 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
> > e7dba35acb..dea49e53f0 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -259,6 +259,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;
> 
> We should also include kvm_timer_frequency here.
> 
> Currently, it is read-only but in-future KVM RISC-V will allow setting
> timer_frequency using SBI para-virt time scaling extension.
> 
> Regards,
> Anup
> 

Ok, added.

> >  };
> >
> >  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass, diff --git
> > a/target/riscv/kvm.c b/target/riscv/kvm.c index 6d419ba02e..e5725770f2
> > 100644
> > --- a/target/riscv/kvm.c
> > +++ b/target/riscv/kvm.c
> > @@ -64,6 +64,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) @@ -310,6 +313,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), &reg);
> > +    if (ret) {
> > +        abort();
> > +    }
> > +    env->kvm_timer_time = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, compare), &reg);
> > +    if (ret) {
> > +        abort();
> > +    }
> > +    env->kvm_timer_compare = reg;
> > +
> > +    ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, state), &reg);
> > +    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), &reg);
> > +    if (ret) {
> > +        abort();
> > +    }
> > +
> > +    reg = env->kvm_timer_compare;
> > +    ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, compare), &reg);
> > +    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), &reg);
> > +        if (ret) {
> > +            abort();
> > +        }
> > +    }
> > +
> > +    env->kvm_timer_dirty = false;
> > +}
> >
> >  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
> >      KVM_CAP_LAST_INFO
> > --
> > 2.19.1
> >
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v1 12/12] target/riscv: Support virtual time context synchronization
  2021-11-20 22:34   ` Richard Henderson
@ 2021-12-10 10:03     ` Jiangyifei
  2021-12-10 10:11     ` Paolo Bonzini
  1 sibling, 0 replies; 35+ messages in thread
From: Jiangyifei @ 2021-12-10 10:03 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: bin.meng, limingwang (A), kvm, libvir-list, anup.patel, wanbo (G),
	Alistair.Francis, kvm-riscv, Wanghaibin (D),
	palmer, Fanliang (EulerOS), Wubin (H)


> -----Original Message-----
> From: Richard Henderson [mailto:richard.henderson@linaro.org]
> Sent: Sunday, November 21, 2021 6:35 AM
> To: Jiangyifei <jiangyifei@huawei.com>; qemu-devel@nongnu.org;
> qemu-riscv@nongnu.org
> Cc: bin.meng@windriver.com; limingwang (A) <limingwang@huawei.com>;
> kvm@vger.kernel.org; libvir-list@redhat.com; anup.patel@wdc.com; wanbo (G)
> <wanbo13@huawei.com>; Alistair.Francis@wdc.com;
> kvm-riscv@lists.infradead.org; Wanghaibin (D)
> <wanghaibin.wang@huawei.com>; palmer@dabbelt.com; Fanliang (EulerOS)
> <fanliang@huawei.com>; Wubin (H) <wu.wubin@huawei.com>
> Subject: Re: [PATCH v1 12/12] target/riscv: Support virtual time context
> synchronization
> 
> On 11/20/21 8:46 AM, Yifei Jiang wrote:
> >   const VMStateDescription vmstate_riscv_cpu = {
> >       .name = "cpu",
> >       .version_id = 3,
> >       .minimum_version_id = 3,
> > +    .post_load = cpu_post_load,
> >       .fields = (VMStateField[]) {
> >           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
> >           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32), @@ -211,6
> > +221,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()
> >       },
> 
> Can't alter VMStateDescription.fields without bumping version.
> 
> If this is really kvm-only state, consider placing it into a subsection.  But I
> worry about kvm-only state because ideally we'd be able to migrate between
> tcg and kvm (if only for debugging).
> 
> 
> r~

Thanks, I will update the version in the next series and place it into a subsection.

Yifei

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v1 12/12] target/riscv: Support virtual time context synchronization
  2021-11-20 22:34   ` Richard Henderson
  2021-12-10 10:03     ` Jiangyifei
@ 2021-12-10 10:11     ` Paolo Bonzini
  1 sibling, 0 replies; 35+ messages in thread
From: Paolo Bonzini @ 2021-12-10 10:11 UTC (permalink / raw)
  To: Richard Henderson, Yifei Jiang, qemu-devel, qemu-riscv
  Cc: bin.meng, Mingwang Li, kvm, libvir-list, anup.patel, wanbo13,
	Alistair.Francis, kvm-riscv, wanghaibin.wang, fanliang, palmer,
	wu.wubin

On 11/20/21 23:34, Richard Henderson wrote:
> On 11/20/21 8:46 AM, Yifei Jiang wrote:
>>   const VMStateDescription vmstate_riscv_cpu = {
>>       .name = "cpu",
>>       .version_id = 3,
>>       .minimum_version_id = 3,
>> +    .post_load = cpu_post_load,
>>       .fields = (VMStateField[]) {
>>           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>>           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
>> @@ -211,6 +221,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()
>>       },
> 
> Can't alter VMStateDescription.fields without bumping version.
> 
> If this is really kvm-only state, consider placing it into a 
> subsection.  But I worry about kvm-only state because ideally we'd be 
> able to migrate between tcg and kvm (if only for debugging).

Where is this state stored for TCG?

Paolo

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2021-12-10 10:11 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-20  7:46 [PATCH v1 00/12] Add riscv kvm accel support Yifei Jiang
2021-11-20  7:46 ` [PATCH v1 01/12] update-linux-headers: Add asm-riscv/kvm.h Yifei Jiang
2021-11-23  6:13   ` Alistair Francis
2021-12-03  5:07   ` Anup Patel
2021-11-20  7:46 ` [PATCH v1 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface Yifei Jiang
2021-12-03  5:08   ` Anup Patel
2021-11-20  7:46 ` [PATCH v1 03/12] target/riscv: Implement function kvm_arch_init_vcpu Yifei Jiang
2021-11-20 22:19   ` Richard Henderson
2021-12-10  9:55     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 04/12] target/riscv: Implement kvm_arch_get_registers Yifei Jiang
2021-12-03  6:20   ` Anup Patel
2021-12-10  9:57     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 05/12] target/riscv: Implement kvm_arch_put_registers Yifei Jiang
2021-12-03  6:22   ` Anup Patel
2021-12-10  9:58     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 06/12] target/riscv: Support start kernel directly by KVM Yifei Jiang
2021-12-03  6:31   ` Anup Patel
2021-12-10 10:00     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 07/12] target/riscv: Support setting external interrupt " Yifei Jiang
2021-12-03  9:15   ` Anup Patel
2021-12-10 10:01     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 08/12] target/riscv: Handle KVM_EXIT_RISCV_SBI exit Yifei Jiang
2021-11-20 12:24   ` Philippe Mathieu-Daudé
2021-12-10 10:02     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 09/12] target/riscv: Add host cpu type Yifei Jiang
2021-12-03  9:26   ` Anup Patel
2021-11-20  7:46 ` [PATCH v1 10/12] target/riscv: Add kvm_riscv_get/put_regs_timer Yifei Jiang
2021-12-03  9:38   ` Anup Patel
2021-12-10 10:03     ` Jiangyifei
2021-11-20  7:46 ` [PATCH v1 11/12] target/riscv: Implement virtual time adjusting with vm state changing Yifei Jiang
2021-11-20  7:46 ` [PATCH v1 12/12] target/riscv: Support virtual time context synchronization Yifei Jiang
2021-11-20 22:34   ` Richard Henderson
2021-12-10 10:03     ` Jiangyifei
2021-12-10 10:11     ` Paolo Bonzini
2021-12-03  8:41 ` [PATCH v1 00/12] Add riscv kvm accel support Michal Prívozník

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).