> -----Original Message----- > From: Anup Patel [mailto:anup@xxxxxxxxxxxxxx] > Sent: Friday, December 3, 2021 5:38 PM > To: Jiangyifei <jiangyifei@xxxxxxxxxx> > Cc: QEMU Developers <qemu-devel@xxxxxxxxxx>; open list:RISC-V > <qemu-riscv@xxxxxxxxxx>; kvm-riscv@xxxxxxxxxxxxxxxxxxx; KVM General > <kvm@xxxxxxxxxxxxxxx>; libvir-list@xxxxxxxxxx; Anup Patel > <anup.patel@xxxxxxx>; Palmer Dabbelt <palmer@xxxxxxxxxxx>; Alistair > Francis <Alistair.Francis@xxxxxxx>; Bin Meng <bin.meng@xxxxxxxxxxxxx>; > Fanliang (EulerOS) <fanliang@xxxxxxxxxx>; Wubin (H) > <wu.wubin@xxxxxxxxxx>; Wanghaibin (D) <wanghaibin.wang@xxxxxxxxxx>; > wanbo (G) <wanbo13@xxxxxxxxxx>; limingwang (A) > <limingwang@xxxxxxxxxx> > 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@xxxxxxxxxx> 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@xxxxxxxxxx> > > Signed-off-by: Mingwang Li <limingwang@xxxxxxxxxx> > > --- > > 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), ®); > > + if (ret) { > > + abort(); > > + } > > + env->kvm_timer_time = reg; > > + > > + ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, compare), ®); > > + if (ret) { > > + abort(); > > + } > > + env->kvm_timer_compare = reg; > > + > > + ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, state), ®); > > + if (ret) { > > + abort(); > > + } > > + env->kvm_timer_state = reg; > > + > > + env->kvm_timer_dirty = true; > > +} > > + > > +static void kvm_riscv_put_regs_timer(CPUState *cs) { > > + int ret; > > + uint64_t reg; > > + CPURISCVState *env = &RISCV_CPU(cs)->env; > > + > > + if (!env->kvm_timer_dirty) { > > + return; > > + } > > + > > + reg = env->kvm_timer_time; > > + ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, time), ®); > > + if (ret) { > > + abort(); > > + } > > + > > + reg = env->kvm_timer_compare; > > + ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, compare), ®); > > + if (ret) { > > + abort(); > > + } > > + > > + /* > > + * To set register of RISCV_TIMER_REG(state) will occur a error from > KVM > > + * on env->kvm_timer_state == 0, It's better to adapt in KVM, but it > > + * doesn't matter that adaping in QEMU now. > > + * TODO If KVM changes, adapt here. > > + */ > > + if (env->kvm_timer_state) { > > + reg = env->kvm_timer_state; > > + ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, state), ®); > > + if (ret) { > > + abort(); > > + } > > + } > > + > > + env->kvm_timer_dirty = false; > > +} > > > > const KVMCapabilityInfo kvm_arch_required_capabilities[] = { > > KVM_CAP_LAST_INFO > > -- > > 2.19.1 > > > > > > -- > > kvm-riscv mailing list > > kvm-riscv@xxxxxxxxxxxxxxxxxxx > > http://lists.infradead.org/mailman/listinfo/kvm-riscv