* [Qemu-devel] [QEMU-PPC] [PATCH 1/2] target/ppc/spapr: Add workaround option to SPAPR_CAP_IBS
@ 2019-03-01 3:19 Suraj Jitindar Singh
2019-03-01 3:19 ` [Qemu-devel] [QEMU-PPC] [PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST Suraj Jitindar Singh
0 siblings, 1 reply; 4+ messages in thread
From: Suraj Jitindar Singh @ 2019-03-01 3:19 UTC (permalink / raw)
To: qemu-ppc; +Cc: david, qemu-devel, mpe, Suraj Jitindar Singh
The spapr_cap SPAPR_CAP_IBS is used to indicate the level of capability
for mitigations for indirect branch speculation. Currently the available
values are broken (default), fixed-ibs (fixed by serialising indirect
branches) and fixed-ccd (fixed by diabling the count cache).
Introduce a new value for this capability denoted workaround, meaning that
software can work around the issue by flushing the count cache on
context switch. This option is available if the hypervisor sets the
H_CPU_BEHAV_FLUSH_COUNT_CACHE flag in the cpu behaviours returned from
the KVM_PPC_GET_CPU_CHAR ioctl.
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
hw/ppc/spapr_caps.c | 21 ++++++++++-----------
hw/ppc/spapr_hcall.c | 5 +++++
include/hw/ppc/spapr.h | 7 +++++++
target/ppc/kvm.c | 8 +++++++-
4 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 920224d0c2..74a48a423a 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -276,11 +276,13 @@ static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
}
sPAPRCapPossible cap_ibs_possible = {
- .num = 4,
+ .num = 5,
/* Note workaround only maintained for compatibility */
- .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd"},
- .help = "broken - no protection, fixed-ibs - indirect branch serialisation,"
- " fixed-ccd - cache count disabled",
+ .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd", "fixed-na"},
+ .help = "broken - no protection, workaround - count cache flush"
+ ", fixed-ibs - indirect branch serialisation,"
+ " fixed-ccd - cache count disabled,"
+ " fixed-na - fixed in hardware (no longer applicable)",
};
static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
@@ -288,15 +290,11 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
{
uint8_t kvm_val = kvmppc_get_cap_safe_indirect_branch();
- if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */
- error_setg(errp,
-"Requested safe indirect branch capability level \"workaround\" not valid, try cap-ibs=%s",
- cap_ibs_possible.vals[kvm_val]);
- } else if (tcg_enabled() && val) {
+ if (tcg_enabled() && val) {
/* TODO - for now only allow broken for TCG */
error_setg(errp,
"Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
- } else if (kvm_enabled() && val && (val != kvm_val)) {
+ } else if (kvm_enabled() && (val > kvm_val)) {
error_setg(errp,
"Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s",
cap_ibs_possible.vals[kvm_val]);
@@ -489,7 +487,8 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
[SPAPR_CAP_IBS] = {
.name = "ibs",
.description =
- "Indirect Branch Speculation (broken, fixed-ibs, fixed-ccd)",
+ "Indirect Branch Speculation (broken, workaround, fixed-ibs,"
+ "fixed-ccd, fixed-na)",
.index = SPAPR_CAP_IBS,
.get = spapr_cap_get_string,
.set = spapr_cap_set_string,
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 476bad6271..4aa8036fc0 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1723,12 +1723,17 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
}
switch (safe_indirect_branch) {
+ case SPAPR_CAP_FIXED_NA:
+ break;
case SPAPR_CAP_FIXED_CCD:
characteristics |= H_CPU_CHAR_CACHE_COUNT_DIS;
break;
case SPAPR_CAP_FIXED_IBS:
characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
break;
+ case SPAPR_CAP_WORKAROUND:
+ behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
+ break;
default: /* broken */
assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
break;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 3cd47fb6e8..80d33ea284 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -85,12 +85,17 @@ typedef enum {
/* Bool Caps */
#define SPAPR_CAP_OFF 0x00
#define SPAPR_CAP_ON 0x01
+
/* Custom Caps */
+
+/* Generic */
#define SPAPR_CAP_BROKEN 0x00
#define SPAPR_CAP_WORKAROUND 0x01
#define SPAPR_CAP_FIXED 0x02
+/* SPAPR_CAP_IBS (cap-ibs) */
#define SPAPR_CAP_FIXED_IBS 0x02
#define SPAPR_CAP_FIXED_CCD 0x03
+#define SPAPR_CAP_FIXED_NA 0x10 /* Lets leave a bit of a gap... */
typedef struct sPAPRCapabilities sPAPRCapabilities;
struct sPAPRCapabilities {
@@ -340,9 +345,11 @@ struct sPAPRMachineState {
#define H_CPU_CHAR_HON_BRANCH_HINTS PPC_BIT(5)
#define H_CPU_CHAR_THR_RECONF_TRIG PPC_BIT(6)
#define H_CPU_CHAR_CACHE_COUNT_DIS PPC_BIT(7)
+#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST PPC_BIT(9)
#define H_CPU_BEHAV_FAVOUR_SECURITY PPC_BIT(0)
#define H_CPU_BEHAV_L1D_FLUSH_PR PPC_BIT(1)
#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR PPC_BIT(2)
+#define H_CPU_BEHAV_FLUSH_COUNT_CACHE PPC_BIT(5)
/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 3f650c8fc4..7a7a5adee3 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2391,7 +2391,13 @@ static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c)
static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
{
- if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
+ if ((~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) &&
+ (~c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) &&
+ (~c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED)) {
+ return SPAPR_CAP_FIXED_NA;
+ } else if (c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) {
+ return SPAPR_CAP_WORKAROUND;
+ } else if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
return SPAPR_CAP_FIXED_CCD;
} else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
return SPAPR_CAP_FIXED_IBS;
--
2.13.6
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [QEMU-PPC] [PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
2019-03-01 3:19 [Qemu-devel] [QEMU-PPC] [PATCH 1/2] target/ppc/spapr: Add workaround option to SPAPR_CAP_IBS Suraj Jitindar Singh
@ 2019-03-01 3:19 ` Suraj Jitindar Singh
2019-03-01 4:26 ` Suraj Jitindar Singh
0 siblings, 1 reply; 4+ messages in thread
From: Suraj Jitindar Singh @ 2019-03-01 3:19 UTC (permalink / raw)
To: qemu-ppc; +Cc: david, qemu-devel, mpe, Suraj Jitindar Singh
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 <sjitindarsingh@gmail.com>
---
hw/ppc/spapr.c | 2 ++
hw/ppc/spapr_caps.c | 25 +++++++++++++++++++++++++
hw/ppc/spapr_hcall.c | 3 +++
include/hw/ppc/spapr.h | 5 ++++-
target/ppc/kvm.c | 14 ++++++++++++++
target/ppc/kvm_ppc.h | 6 ++++++
6 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1df324379f..708e18dcdf 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2086,6 +2086,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
}
};
@@ -4319,6 +4320,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 74a48a423a..f03f2f64e7 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -436,6 +436,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",
@@ -525,6 +540,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,
@@ -659,6 +683,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..8bfdddc964 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1693,6 +1693,7 @@ 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 +1734,8 @@ 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 80d33ea284..493a44700d 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
@@ -853,6 +855,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 7a7a5adee3..e0f0de0ce0 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;
@@ -2406,6 +2407,13 @@ 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;
@@ -2428,6 +2436,7 @@ 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)
@@ -2445,6 +2454,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.13.6
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [QEMU-PPC] [PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
2019-03-01 3:19 ` [Qemu-devel] [QEMU-PPC] [PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST Suraj Jitindar Singh
@ 2019-03-01 4:26 ` Suraj Jitindar Singh
2019-03-04 0:52 ` David Gibson
0 siblings, 1 reply; 4+ messages in thread
From: Suraj Jitindar Singh @ 2019-03-01 4:26 UTC (permalink / raw)
To: qemu-ppc; +Cc: david, qemu-devel, mpe
On Fri, 2019-03-01 at 14:19 +1100, Suraj Jitindar Singh wrote:
> 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 <sjitindarsingh@gmail.com>
> ---
> hw/ppc/spapr.c | 2 ++
> hw/ppc/spapr_caps.c | 25 +++++++++++++++++++++++++
> hw/ppc/spapr_hcall.c | 3 +++
> include/hw/ppc/spapr.h | 5 ++++-
> target/ppc/kvm.c | 14 ++++++++++++++
> target/ppc/kvm_ppc.h | 6 ++++++
> 6 files changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 1df324379f..708e18dcdf 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2086,6 +2086,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
> }
> };
> @@ -4319,6 +4320,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 74a48a423a..f03f2f64e7 100644
> --- a/hw/ppc/spapr_caps.c
> +++ b/hw/ppc/spapr_caps.c
> @@ -436,6 +436,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");
> + }
Actually, this should probably be non-fatal if the count cache flush
routine isn't enabled
> +}
> +
> sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
> [SPAPR_CAP_HTM] = {
> .name = "htm",
> @@ -525,6 +540,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,
> @@ -659,6 +683,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..8bfdddc964 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1693,6 +1693,7 @@ 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 +1734,8 @@ 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 80d33ea284..493a44700d 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
> @@ -853,6 +855,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 7a7a5adee3..e0f0de0ce0 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;
>
> @@ -2406,6 +2407,13 @@ 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;
> @@ -2428,6 +2436,7 @@ 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)
> @@ -2445,6 +2454,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;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [QEMU-PPC] [PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
2019-03-01 4:26 ` Suraj Jitindar Singh
@ 2019-03-04 0:52 ` David Gibson
0 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2019-03-04 0:52 UTC (permalink / raw)
To: Suraj Jitindar Singh; +Cc: qemu-ppc, qemu-devel, mpe
[-- Attachment #1: Type: text/plain, Size: 3685 bytes --]
On Fri, Mar 01, 2019 at 03:26:45PM +1100, Suraj Jitindar Singh wrote:
> On Fri, 2019-03-01 at 14:19 +1100, Suraj Jitindar Singh wrote:
> > 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 <sjitindarsingh@gmail.com>
> > ---
> > hw/ppc/spapr.c | 2 ++
> > hw/ppc/spapr_caps.c | 25 +++++++++++++++++++++++++
> > hw/ppc/spapr_hcall.c | 3 +++
> > include/hw/ppc/spapr.h | 5 ++++-
> > target/ppc/kvm.c | 14 ++++++++++++++
> > target/ppc/kvm_ppc.h | 6 ++++++
> > 6 files changed, 54 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 1df324379f..708e18dcdf 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -2086,6 +2086,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
> > }
> > };
> > @@ -4319,6 +4320,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 74a48a423a..f03f2f64e7 100644
> > --- a/hw/ppc/spapr_caps.c
> > +++ b/hw/ppc/spapr_caps.c
> > @@ -436,6 +436,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");
> > + }
>
> Actually, this should probably be non-fatal if the count cache flush
> routine isn't enabled
Since the new cap values aren't enabled by default, I've applied
anyway. You can make this error non-fatal in a followup.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-03-04 1:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-03-01 3:19 [Qemu-devel] [QEMU-PPC] [PATCH 1/2] target/ppc/spapr: Add workaround option to SPAPR_CAP_IBS Suraj Jitindar Singh
2019-03-01 3:19 ` [Qemu-devel] [QEMU-PPC] [PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST Suraj Jitindar Singh
2019-03-01 4:26 ` Suraj Jitindar Singh
2019-03-04 0:52 ` David Gibson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).