
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> virt inclusion category: feature bugzilla: https://gitee.com/openeuler/qemu/issues/IBSJV9 ------------------------------------------------------------------------ At present CPU state ID register values are not updated to list. Only the list values are later synced to KVM. Hence update the list with ID register values. Whether use the KVM to set up reg here is worth considering. Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- target/arm/helper.c | 54 +++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 0370a739e3..4c73005a2e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -116,6 +116,25 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri) return true; } + +static bool is_id_register(const ARMCPRegInfo *ri) +{ + /* + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2), + * where 1<=crm<8, 0<=op2<8. + */ + if (ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && + ri->crm > 0 && ri->crm < 8) { + return true; + } else if (ri->opc0 == 3 && ri->opc1 == 3 && ri->crn == 0 && + ri->crm == 0 && ri->opc2 == 1) { + /* CTR_EL0 */ + return true; + } + + return false; +} + bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync) { /* Write the coprocessor state from cpu->env to the (index,value) list. */ @@ -132,30 +151,33 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync) ok = false; continue; } - if (ri->type & ARM_CP_NO_RAW) { + if (ri->type & ARM_CP_NO_RAW && !(kvm_sync && is_id_register(ri))) { continue; } newval = read_raw_cp_reg(&cpu->env, ri); if (kvm_sync) { - /* - * Only sync if the previous list->cpustate sync succeeded. - * Rather than tracking the success/failure state for every - * item in the list, we just recheck "does the raw write we must - * have made in write_list_to_cpustate() read back OK" here. - */ - uint64_t oldval = cpu->cpreg_values[i]; + /* Check we need to attempt a KVM sync when ri is id register. */ + if (!is_id_register(ri)) { + /* + * Only sync if the previous list->cpustate sync succeeded. + * Rather than tracking the success/failure state for every + * item in the list, we just recheck "does the raw write we must + * have made in write_list_to_cpustate() read back OK" here. + */ + uint64_t oldval = cpu->cpreg_values[i]; - if (oldval == newval) { - continue; - } + if (oldval == newval) { + continue; + } - write_raw_cp_reg(&cpu->env, ri, oldval); - if (read_raw_cp_reg(&cpu->env, ri) != oldval) { - continue; - } + write_raw_cp_reg(&cpu->env, ri, oldval); + if (read_raw_cp_reg(&cpu->env, ri) != oldval) { + continue; + } - write_raw_cp_reg(&cpu->env, ri, newval); + write_raw_cp_reg(&cpu->env, ri, newval); + } } cpu->cpreg_values[i] = newval; } -- 2.33.0