[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 10/62] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
From: |
David Gibson |
Subject: |
[Qemu-devel] [PULL 10/62] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST |
Date: |
Tue, 12 Mar 2019 19:54:10 +1100 |
From: Suraj Jitindar Singh <address@hidden>
Introduce a new spapr_cap SPAPR_CAP_CCF_ASSIST to be used to indicate
the requirement for a hw-assisted version of the count cache flush
workaround.
The count cache flush workaround is a software workaround which can be
used to flush the count cache on context switch. Some revisions of
hardware may have a hardware accelerated flush, in which case the
software flush can be shortened. This cap is used to set the
availability of such hardware acceleration for the count cache flush
routine.
The availability of such hardware acceleration is indicated by the
H_CPU_CHAR_BCCTR_FLUSH_ASSIST flag being set in the characteristics
returned from the KVM_PPC_GET_CPU_CHAR ioctl.
Signed-off-by: Suraj Jitindar Singh <address@hidden>
Message-Id: <address@hidden>
[dwg: Small style fixes]
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr.c | 2 ++
hw/ppc/spapr_caps.c | 25 +++++++++++++++++++++++++
hw/ppc/spapr_hcall.c | 5 +++++
include/hw/ppc/spapr.h | 5 ++++-
target/ppc/kvm.c | 16 ++++++++++++++++
target/ppc/kvm_ppc.h | 6 ++++++
6 files changed, 58 insertions(+), 1 deletion(-)
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);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index a7f3b1bfdd..ff1bd60615 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -76,8 +76,10 @@ typedef enum {
#define SPAPR_CAP_NESTED_KVM_HV 0x07
/* Large Decrementer */
#define SPAPR_CAP_LARGE_DECREMENTER 0x08
+/* Count Cache Flush Assist HW Instruction */
+#define SPAPR_CAP_CCF_ASSIST 0x09
/* Num Caps */
-#define SPAPR_CAP_NUM (SPAPR_CAP_LARGE_DECREMENTER + 1)
+#define SPAPR_CAP_NUM (SPAPR_CAP_CCF_ASSIST + 1)
/*
* Capability Values
@@ -838,6 +840,7 @@ extern const VMStateDescription vmstate_spapr_cap_sbbc;
extern const VMStateDescription vmstate_spapr_cap_ibs;
extern const VMStateDescription vmstate_spapr_cap_nested_kvm_hv;
extern const VMStateDescription vmstate_spapr_cap_large_decr;
+extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
{
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4d46314276..1da28039a8 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -90,6 +90,7 @@ static int cap_ppc_pvr_compat;
static int cap_ppc_safe_cache;
static int cap_ppc_safe_bounds_check;
static int cap_ppc_safe_indirect_branch;
+static int cap_ppc_count_cache_flush_assist;
static int cap_ppc_nested_kvm_hv;
static int cap_large_decr;
@@ -2407,6 +2408,14 @@ static int parse_cap_ppc_safe_indirect_branch(struct
kvm_ppc_cpu_char c)
return 0;
}
+static int parse_cap_ppc_count_cache_flush_assist(struct kvm_ppc_cpu_char c)
+{
+ if (c.character & c.character_mask & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) {
+ return 1;
+ }
+ return 0;
+}
+
static void kvmppc_get_cpu_characteristics(KVMState *s)
{
struct kvm_ppc_cpu_char c;
@@ -2429,6 +2438,8 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c);
cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c);
cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c);
+ cap_ppc_count_cache_flush_assist =
+ parse_cap_ppc_count_cache_flush_assist(c);
}
int kvmppc_get_cap_safe_cache(void)
@@ -2446,6 +2457,11 @@ int kvmppc_get_cap_safe_indirect_branch(void)
return cap_ppc_safe_indirect_branch;
}
+int kvmppc_get_cap_count_cache_flush_assist(void)
+{
+ return cap_ppc_count_cache_flush_assist;
+}
+
bool kvmppc_has_cap_nested_kvm_hv(void)
{
return !!cap_ppc_nested_kvm_hv;
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index a79835bd14..2937b36cae 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -62,6 +62,7 @@ bool kvmppc_has_cap_mmu_hash_v3(void);
int kvmppc_get_cap_safe_cache(void);
int kvmppc_get_cap_safe_bounds_check(void);
int kvmppc_get_cap_safe_indirect_branch(void);
+int kvmppc_get_cap_count_cache_flush_assist(void);
bool kvmppc_has_cap_nested_kvm_hv(void);
int kvmppc_set_cap_nested_kvm_hv(int enable);
int kvmppc_get_cap_large_decr(void);
@@ -324,6 +325,11 @@ static inline int kvmppc_get_cap_safe_indirect_branch(void)
return 0;
}
+static inline int kvmppc_get_cap_count_cache_flush_assist(void)
+{
+ return 0;
+}
+
static inline bool kvmppc_has_cap_nested_kvm_hv(void)
{
return false;
--
2.20.1
- [Qemu-devel] [PULL 00/62] ppc-for-4.0 queue 20190312, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 04/62] Revert "spapr: support memory unplug for qtest", David Gibson, 2019/03/12
- [Qemu-devel] [PULL 01/62] vfio/spapr: Fix indirect levels calculation, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 03/62] spapr: Simulate CAS for qtest, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 02/62] vfio/spapr: Rename local systempagesize variable, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 05/62] target/ppc/spapr: Add SPAPR_CAP_LARGE_DECREMENTER, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 07/62] target/ppc: Implement large decrementer support for KVM, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 14/62] target/ppc: Move handling of hardware breakpoints to a separate function, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 09/62] target/ppc/spapr: Add workaround option to SPAPR_CAP_IBS, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 10/62] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST,
David Gibson <=
- [Qemu-devel] [PULL 17/62] target/ppc/spapr: Clear partition table entry when allocating hash table, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 08/62] target/ppc/spapr: Enable the large decrementer for pseries-4.0, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 13/62] target/ppc: Move exception vector offset computation into a function, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 06/62] target/ppc: Implement large decrementer support for TCG, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 27/62] ppc/pnv: introduce a new dt_populate() operation to the chip model, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 25/62] ppc/pnv: change the CPU machine_data presenter type to Object *, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 11/62] target/ppc/tcg: make spapr_caps apply cap-[cfpc/sbbc/ibs] non-fatal for tcg, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 20/62] PPC: E500: Add FSL I2C controller and integrate RTC with it, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 23/62] ppc/xive: export the TIMA memory accessors, David Gibson, 2019/03/12
- [Qemu-devel] [PULL 19/62] target/ppc/spapr: Enable H_PAGE_INIT in-kernel handling, David Gibson, 2019/03/12