diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/ppc/spapr.c | 2 | ||||
| -rw-r--r-- | hw/ppc/spapr_caps.c | 25 | ||||
| -rw-r--r-- | hw/ppc/spapr_hcall.c | 5 |
3 files changed, 32 insertions, 0 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 8e24d7dc50..37fd7a1411 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2097,6 +2097,7 @@ static const VMStateDescription vmstate_spapr = { &vmstate_spapr_cap_nested_kvm_hv, &vmstate_spapr_dtb, &vmstate_spapr_cap_large_decr, + &vmstate_spapr_cap_ccf_assist, NULL } }; @@ -4312,6 +4313,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */ smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF; smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON; + smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF; spapr_caps_add_properties(smc, &error_abort); smc->irq = &spapr_irq_xics; smc->dr_phb_enabled = true; diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index ca35b5153d..c5d381f183 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -441,6 +441,21 @@ static void cap_large_decr_cpu_apply(sPAPRMachineState *spapr, ppc_store_lpcr(cpu, lpcr); } +static void cap_ccf_assist_apply(sPAPRMachineState *spapr, uint8_t val, + Error **errp) +{ + uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist(); + + if (tcg_enabled() && val) { + /* TODO - for now only allow broken for TCG */ + error_setg(errp, +"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off"); + } else if (kvm_enabled() && (val > kvm_val)) { + error_setg(errp, +"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off"); + } +} + sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { [SPAPR_CAP_HTM] = { .name = "htm", @@ -530,6 +545,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { .apply = cap_large_decr_apply, .cpu_apply = cap_large_decr_cpu_apply, }, + [SPAPR_CAP_CCF_ASSIST] = { + .name = "ccf-assist", + .description = "Count Cache Flush Assist via HW Instruction", + .index = SPAPR_CAP_CCF_ASSIST, + .get = spapr_cap_get_bool, + .set = spapr_cap_set_bool, + .type = "bool", + .apply = cap_ccf_assist_apply, + }, }; static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr, @@ -664,6 +688,7 @@ SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC); SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS); SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV); SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER); +SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST); void spapr_caps_init(sPAPRMachineState *spapr) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 4aa8036fc0..15bdd30a12 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1693,6 +1693,8 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu, uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC); uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC); uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS); + uint8_t count_cache_flush_assist = spapr_get_cap(spapr, + SPAPR_CAP_CCF_ASSIST); switch (safe_cache) { case SPAPR_CAP_WORKAROUND: @@ -1733,6 +1735,9 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu, break; case SPAPR_CAP_WORKAROUND: behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE; + if (count_cache_flush_assist) { + characteristics |= H_CPU_CHAR_BCCTR_FLUSH_ASSIST; + } break; default: /* broken */ assert(safe_indirect_branch == SPAPR_CAP_BROKEN); |