From: Manish Jaggi <manish.ja...@cavium.com> When KVM_SET_ONE_REG returns KVM_EINVARIANT call KVM_GET_ONE_REG to query and then replace the particular guest invariant register value with destination hosts register.
Signed-off-by: Manish Jaggi <manish.ja...@cavium.com> diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 65f867d..8cf4dc9 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -19,6 +19,7 @@ #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "kvm_arm.h" +#include "standard-headers/asm-arm/kvm_para.h" #include "cpu.h" #include "trace.h" #include "internals.h" @@ -37,6 +38,8 @@ static bool cap_has_mp_state; static ARMHostCPUFeatures arm_host_cpu_features; +extern bool enable_hostinvariant; + int kvm_arm_vcpu_init(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); @@ -451,8 +454,16 @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level) default: abort(); } - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); - if (ret) { + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); + if (enable_hostinvariant && ret == -KVM_EINVARIANT) { + /* Update Guest invariant to match with migrated host regs*/ + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); + if (ret) + ok = false; + else + cpu->cpreg_values[i] = r.addr; + } + else if (ret) { /* We might fail for "unknown register" and also for * "you tried to set a register which is constant with * a different value from what it actually contains". -- 1.8.3.1