Fix secondary vCPUs(id > 0) stall after migration. Signed-off-by: BillXiang <xiangwench...@lanxincomputing.com> --- target/riscv/cpu.h | 3 +++ target/riscv/kvm/kvm-cpu.c | 34 ++++++++++++++++++++++++++-------- target/riscv/kvm/kvm_riscv.h | 3 ++- target/riscv/machine.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 4a862da615..4290229c56 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -20,6 +20,7 @@ #ifndef RISCV_CPU_H #define RISCV_CPU_H +#include <linux/kvm.h> #include "hw/core/cpu.h" #include "hw/registerfields.h" #include "hw/qdev-properties.h" @@ -546,6 +547,8 @@ struct ArchCPU { RISCVCPUConfig cfg; RISCVSATPModes satp_modes; + struct kvm_mp_state mp_state; + QEMUTimer *pmu_timer; /* A bitmask of Available programmable counters */ uint32_t pmu_avail_ctrs; diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index 5c19062c19..f0a97293f9 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -1348,17 +1348,16 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) return ret; } + RISCVCPU *cpu = RISCV_CPU(cs); + ret = kvm_riscv_sync_mpstate_to_qemu(cpu); + return ret; } -int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state) +int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu) { if (cap_has_mp_state) { - struct kvm_mp_state mp_state = { - .mp_state = state - }; - - int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MP_STATE, &mp_state); + int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MP_STATE, &cpu->mp_state); if (ret) { fprintf(stderr, "%s: failed to sync MP_STATE %d/%s\n", __func__, ret, strerror(-ret)); @@ -1369,6 +1368,17 @@ int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state) return 0; } +int kvm_riscv_sync_mpstate_to_qemu(RISCVCPU *cpu) +{ + if (cap_has_mp_state) { + int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MP_STATE, &cpu->mp_state); + if (ret) { + return ret; + } + } + return 0; +} + int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) { int ret = 0; @@ -1396,13 +1406,21 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) if (KVM_PUT_RESET_STATE == level) { RISCVCPU *cpu = RISCV_CPU(cs); if (cs->cpu_index == 0) { - ret = kvm_riscv_sync_mpstate_to_kvm(cpu, KVM_MP_STATE_RUNNABLE); + cpu->mp_state.mp_state = KVM_MP_STATE_RUNNABLE; + ret = kvm_riscv_sync_mpstate_to_kvm(cpu); } else { - ret = kvm_riscv_sync_mpstate_to_kvm(cpu, KVM_MP_STATE_STOPPED); + cpu->mp_state.mp_state = KVM_MP_STATE_STOPPED; + ret = kvm_riscv_sync_mpstate_to_kvm(cpu); } if (ret) { return ret; } + } else if (KVM_PUT_FULL_STATE == level) { + RISCVCPU *cpu = RISCV_CPU(cs); + ret = kvm_riscv_sync_mpstate_to_kvm(cpu); + if (ret) { + return ret; + } } return ret; diff --git a/target/riscv/kvm/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h index b2bcd1041f..770f58bf0a 100644 --- a/target/riscv/kvm/kvm_riscv.h +++ b/target/riscv/kvm/kvm_riscv.h @@ -28,7 +28,8 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, uint64_t aplic_base, uint64_t imsic_base, uint64_t guest_num); void riscv_kvm_aplic_request(void *opaque, int irq, int level); -int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state); +int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu); +int kvm_riscv_sync_mpstate_to_qemu(RISCVCPU *cpu); void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp); uint64_t kvm_riscv_get_timebase_frequency(RISCVCPU *cpu); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 1600ec44f0..178ae6a3a0 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -251,6 +251,28 @@ static const VMStateDescription vmstate_debug = { } }; +static int get_mp_state(QEMUFile *f, void *opaque, size_t size, + const VMStateField *field) +{ + RISCVCPU *cpu = opaque; + cpu->mp_state.mp_state = qemu_get_be32(f); + return 0; +} + +static int put_mp_state(QEMUFile *f, void *opaque, size_t size, + const VMStateField *field, JSONWriter *vmdesc) +{ + RISCVCPU *cpu = opaque; + qemu_put_be32(f, cpu->mp_state.mp_state); + return 0; +} + +static const VMStateInfo vmstate_mp_state = { + .name = "mp_state", + .get = get_mp_state, + .put = put_mp_state, +}; + static int riscv_cpu_post_load(void *opaque, int version_id) { RISCVCPU *cpu = opaque; @@ -457,6 +479,14 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINTTL(env.sscratch, RISCVCPU), VMSTATE_UINTTL(env.mscratch, RISCVCPU), VMSTATE_UINT64(env.stimecmp, RISCVCPU), + { + .name = "mp_state", + .version_id = 0, + .size = sizeof(bool), + .info = &vmstate_mp_state, + .flags = VMS_SINGLE, + .offset = 0, + }, VMSTATE_END_OF_LIST() }, -- 2.46.2.windows.1