|
Pablo Greco |
e6a3ae |
From d63d52e74a9af9d7d45f5734c4a6e127c3ecc0b4 Mon Sep 17 00:00:00 2001
|
|
Pablo Greco |
e6a3ae |
From: Sam Bobroff <sbobroff@redhat.com>
|
|
Pablo Greco |
e6a3ae |
Date: Thu, 29 Aug 2019 05:53:36 +0100
|
|
Pablo Greco |
e6a3ae |
Subject: [PATCH 03/10] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
RH-Author: Sam Bobroff <sbobroff@redhat.com>
|
|
Pablo Greco |
e6a3ae |
Message-id: <80714b6e8fc19054881e9c1eaf1b8a332f8e104f.1567057498.git.sbobroff@redhat.com>
|
|
Pablo Greco |
e6a3ae |
Patchwork-id: 90189
|
|
Pablo Greco |
e6a3ae |
O-Subject: [RHEL8.1 qemu-kvm BZ1744415 PATCH 2/2] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
|
|
Pablo Greco |
e6a3ae |
Bugzilla: 1744415
|
|
Pablo Greco |
e6a3ae |
RH-Acked-by: David Gibson <dgibson@redhat.com>
|
|
Pablo Greco |
e6a3ae |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
Pablo Greco |
e6a3ae |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
Introduce a new spapr_cap SPAPR_CAP_CCF_ASSIST to be used to indicate
|
|
Pablo Greco |
e6a3ae |
the requirement for a hw-assisted version of the count cache flush
|
|
Pablo Greco |
e6a3ae |
workaround.
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
The count cache flush workaround is a software workaround which can be
|
|
Pablo Greco |
e6a3ae |
used to flush the count cache on context switch. Some revisions of
|
|
Pablo Greco |
e6a3ae |
hardware may have a hardware accelerated flush, in which case the
|
|
Pablo Greco |
e6a3ae |
software flush can be shortened. This cap is used to set the
|
|
Pablo Greco |
e6a3ae |
availability of such hardware acceleration for the count cache flush
|
|
Pablo Greco |
e6a3ae |
routine.
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
The availability of such hardware acceleration is indicated by the
|
|
Pablo Greco |
e6a3ae |
H_CPU_CHAR_BCCTR_FLUSH_ASSIST flag being set in the characteristics
|
|
Pablo Greco |
e6a3ae |
returned from the KVM_PPC_GET_CPU_CHAR ioctl.
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
|
|
Pablo Greco |
e6a3ae |
Message-Id: <20190301031912.28809-2-sjitindarsingh@gmail.com>
|
|
Pablo Greco |
e6a3ae |
[dwg: Small style fixes]
|
|
Pablo Greco |
e6a3ae |
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
|
Pablo Greco |
e6a3ae |
(cherry picked from commit 8ff43ee404d3e295839d1fd4e9e6571ca7a62a66)
|
|
Pablo Greco |
e6a3ae |
[SB: Minor fixup for context change.]
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1744415
|
|
Pablo Greco |
e6a3ae |
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23229146
|
|
Pablo Greco |
e6a3ae |
Signed-off-by: Sam Bobroff <sbobroff@redhat.com>
|
|
Pablo Greco |
e6a3ae |
Testing: QEMU -M cap-ibs=workaround,cap-ccf-assist=on, check guest dmesg
|
|
Pablo Greco |
e6a3ae |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
Pablo Greco |
e6a3ae |
---
|
|
Pablo Greco |
e6a3ae |
hw/ppc/spapr.c | 2 ++
|
|
Pablo Greco |
e6a3ae |
hw/ppc/spapr_caps.c | 25 +++++++++++++++++++++++++
|
|
Pablo Greco |
e6a3ae |
hw/ppc/spapr_hcall.c | 5 +++++
|
|
Pablo Greco |
e6a3ae |
include/hw/ppc/spapr.h | 5 ++++-
|
|
Pablo Greco |
e6a3ae |
target/ppc/kvm.c | 16 ++++++++++++++++
|
|
Pablo Greco |
e6a3ae |
target/ppc/kvm_ppc.h | 6 ++++++
|
|
Pablo Greco |
e6a3ae |
6 files changed, 58 insertions(+), 1 deletion(-)
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
|
|
Pablo Greco |
e6a3ae |
index c72aad1..1a2f0d9 100644
|
|
Pablo Greco |
e6a3ae |
--- a/hw/ppc/spapr.c
|
|
Pablo Greco |
e6a3ae |
+++ b/hw/ppc/spapr.c
|
|
Pablo Greco |
e6a3ae |
@@ -1828,6 +1828,7 @@ static const VMStateDescription vmstate_spapr = {
|
|
Pablo Greco |
e6a3ae |
&vmstate_spapr_cap_sbbc,
|
|
Pablo Greco |
e6a3ae |
&vmstate_spapr_cap_ibs,
|
|
Pablo Greco |
e6a3ae |
&vmstate_spapr_cap_nested_kvm_hv,
|
|
Pablo Greco |
e6a3ae |
+ &vmstate_spapr_cap_ccf_assist,
|
|
Pablo Greco |
e6a3ae |
NULL
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
};
|
|
Pablo Greco |
e6a3ae |
@@ -3939,6 +3940,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
|
Pablo Greco |
e6a3ae |
smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
|
|
Pablo Greco |
e6a3ae |
smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
|
|
Pablo Greco |
e6a3ae |
smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
|
|
Pablo Greco |
e6a3ae |
+ smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
|
|
Pablo Greco |
e6a3ae |
spapr_caps_add_properties(smc, &error_abort);
|
|
Pablo Greco |
e6a3ae |
smc->has_power9_support = true;
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
|
|
Pablo Greco |
e6a3ae |
index dfc8cce..5353255 100644
|
|
Pablo Greco |
e6a3ae |
--- a/hw/ppc/spapr_caps.c
|
|
Pablo Greco |
e6a3ae |
+++ b/hw/ppc/spapr_caps.c
|
|
Pablo Greco |
e6a3ae |
@@ -285,6 +285,21 @@ static void cap_nested_kvm_hv_apply(sPAPRMachineState *spapr,
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
+static void cap_ccf_assist_apply(sPAPRMachineState *spapr, uint8_t val,
|
|
Pablo Greco |
e6a3ae |
+ Error **errp)
|
|
Pablo Greco |
e6a3ae |
+{
|
|
Pablo Greco |
e6a3ae |
+ uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist();
|
|
Pablo Greco |
e6a3ae |
+
|
|
Pablo Greco |
e6a3ae |
+ if (tcg_enabled() && val) {
|
|
Pablo Greco |
e6a3ae |
+ /* TODO - for now only allow broken for TCG */
|
|
Pablo Greco |
e6a3ae |
+ error_setg(errp,
|
|
Pablo Greco |
e6a3ae |
+"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off");
|
|
Pablo Greco |
e6a3ae |
+ } else if (kvm_enabled() && (val > kvm_val)) {
|
|
Pablo Greco |
e6a3ae |
+ error_setg(errp,
|
|
Pablo Greco |
e6a3ae |
+"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off");
|
|
Pablo Greco |
e6a3ae |
+ }
|
|
Pablo Greco |
e6a3ae |
+}
|
|
Pablo Greco |
e6a3ae |
+
|
|
Pablo Greco |
e6a3ae |
sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
|
Pablo Greco |
e6a3ae |
[SPAPR_CAP_HTM] = {
|
|
Pablo Greco |
e6a3ae |
.name = "htm",
|
|
Pablo Greco |
e6a3ae |
@@ -354,6 +369,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
|
Pablo Greco |
e6a3ae |
.type = "bool",
|
|
Pablo Greco |
e6a3ae |
.apply = cap_nested_kvm_hv_apply,
|
|
Pablo Greco |
e6a3ae |
},
|
|
Pablo Greco |
e6a3ae |
+ [SPAPR_CAP_CCF_ASSIST] = {
|
|
Pablo Greco |
e6a3ae |
+ .name = "ccf-assist",
|
|
Pablo Greco |
e6a3ae |
+ .description = "Count Cache Flush Assist via HW Instruction",
|
|
Pablo Greco |
e6a3ae |
+ .index = SPAPR_CAP_CCF_ASSIST,
|
|
Pablo Greco |
e6a3ae |
+ .get = spapr_cap_get_bool,
|
|
Pablo Greco |
e6a3ae |
+ .set = spapr_cap_set_bool,
|
|
Pablo Greco |
e6a3ae |
+ .type = "bool",
|
|
Pablo Greco |
e6a3ae |
+ .apply = cap_ccf_assist_apply,
|
|
Pablo Greco |
e6a3ae |
+ },
|
|
Pablo Greco |
e6a3ae |
};
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
|
|
Pablo Greco |
e6a3ae |
@@ -470,6 +494,7 @@ SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC);
|
|
Pablo Greco |
e6a3ae |
SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
|
|
Pablo Greco |
e6a3ae |
SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
|
|
Pablo Greco |
e6a3ae |
SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
|
|
Pablo Greco |
e6a3ae |
+SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
void spapr_caps_reset(sPAPRMachineState *spapr)
|
|
Pablo Greco |
e6a3ae |
{
|
|
Pablo Greco |
e6a3ae |
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
|
|
Pablo Greco |
e6a3ae |
index 01c4215..141d1f4 100644
|
|
Pablo Greco |
e6a3ae |
--- a/hw/ppc/spapr_hcall.c
|
|
Pablo Greco |
e6a3ae |
+++ b/hw/ppc/spapr_hcall.c
|
|
Pablo Greco |
e6a3ae |
@@ -1675,6 +1675,8 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
|
|
Pablo Greco |
e6a3ae |
uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
|
|
Pablo Greco |
e6a3ae |
uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
|
|
Pablo Greco |
e6a3ae |
uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
|
|
Pablo Greco |
e6a3ae |
+ uint8_t count_cache_flush_assist = spapr_get_cap(spapr,
|
|
Pablo Greco |
e6a3ae |
+ SPAPR_CAP_CCF_ASSIST);
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
switch (safe_cache) {
|
|
Pablo Greco |
e6a3ae |
case SPAPR_CAP_WORKAROUND:
|
|
Pablo Greco |
e6a3ae |
@@ -1715,6 +1717,9 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
|
|
Pablo Greco |
e6a3ae |
break;
|
|
Pablo Greco |
e6a3ae |
case SPAPR_CAP_WORKAROUND:
|
|
Pablo Greco |
e6a3ae |
behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
|
|
Pablo Greco |
e6a3ae |
+ if (count_cache_flush_assist) {
|
|
Pablo Greco |
e6a3ae |
+ characteristics |= H_CPU_CHAR_BCCTR_FLUSH_ASSIST;
|
|
Pablo Greco |
e6a3ae |
+ }
|
|
Pablo Greco |
e6a3ae |
break;
|
|
Pablo Greco |
e6a3ae |
default: /* broken */
|
|
Pablo Greco |
e6a3ae |
assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
|
|
Pablo Greco |
e6a3ae |
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
|
|
Pablo Greco |
e6a3ae |
index 8bb95bb..4aff3b6 100644
|
|
Pablo Greco |
e6a3ae |
--- a/include/hw/ppc/spapr.h
|
|
Pablo Greco |
e6a3ae |
+++ b/include/hw/ppc/spapr.h
|
|
Pablo Greco |
e6a3ae |
@@ -68,8 +68,10 @@ typedef enum {
|
|
Pablo Greco |
e6a3ae |
#define SPAPR_CAP_IBS 0x05
|
|
Pablo Greco |
e6a3ae |
/* Nested KVM-HV */
|
|
Pablo Greco |
e6a3ae |
#define SPAPR_CAP_NESTED_KVM_HV 0x06
|
|
Pablo Greco |
e6a3ae |
+/* Count Cache Flush Assist HW Instruction */
|
|
Pablo Greco |
e6a3ae |
+#define SPAPR_CAP_CCF_ASSIST 0x07
|
|
Pablo Greco |
e6a3ae |
/* Num Caps */
|
|
Pablo Greco |
e6a3ae |
-#define SPAPR_CAP_NUM (SPAPR_CAP_NESTED_KVM_HV + 1)
|
|
Pablo Greco |
e6a3ae |
+#define SPAPR_CAP_NUM (SPAPR_CAP_CCF_ASSIST + 1)
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
/*
|
|
Pablo Greco |
e6a3ae |
* Capability Values
|
|
Pablo Greco |
e6a3ae |
@@ -807,6 +809,7 @@ extern const VMStateDescription vmstate_spapr_cap_cfpc;
|
|
Pablo Greco |
e6a3ae |
extern const VMStateDescription vmstate_spapr_cap_sbbc;
|
|
Pablo Greco |
e6a3ae |
extern const VMStateDescription vmstate_spapr_cap_ibs;
|
|
Pablo Greco |
e6a3ae |
extern const VMStateDescription vmstate_spapr_cap_nested_kvm_hv;
|
|
Pablo Greco |
e6a3ae |
+extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
|
|
Pablo Greco |
e6a3ae |
{
|
|
Pablo Greco |
e6a3ae |
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
|
|
Pablo Greco |
e6a3ae |
index 0e94cfc..8f90ee5 100644
|
|
Pablo Greco |
e6a3ae |
--- a/target/ppc/kvm.c
|
|
Pablo Greco |
e6a3ae |
+++ b/target/ppc/kvm.c
|
|
Pablo Greco |
e6a3ae |
@@ -92,6 +92,7 @@ static int cap_ppc_pvr_compat;
|
|
Pablo Greco |
e6a3ae |
static int cap_ppc_safe_cache;
|
|
Pablo Greco |
e6a3ae |
static int cap_ppc_safe_bounds_check;
|
|
Pablo Greco |
e6a3ae |
static int cap_ppc_safe_indirect_branch;
|
|
Pablo Greco |
e6a3ae |
+static int cap_ppc_count_cache_flush_assist;
|
|
Pablo Greco |
e6a3ae |
static int cap_ppc_nested_kvm_hv;
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
static uint32_t debug_inst_opcode;
|
|
Pablo Greco |
e6a3ae |
@@ -2526,6 +2527,14 @@ static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
|
|
Pablo Greco |
e6a3ae |
return 0;
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
+static int parse_cap_ppc_count_cache_flush_assist(struct kvm_ppc_cpu_char c)
|
|
Pablo Greco |
e6a3ae |
+{
|
|
Pablo Greco |
e6a3ae |
+ if (c.character & c.character_mask & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) {
|
|
Pablo Greco |
e6a3ae |
+ return 1;
|
|
Pablo Greco |
e6a3ae |
+ }
|
|
Pablo Greco |
e6a3ae |
+ return 0;
|
|
Pablo Greco |
e6a3ae |
+}
|
|
Pablo Greco |
e6a3ae |
+
|
|
Pablo Greco |
e6a3ae |
static void kvmppc_get_cpu_characteristics(KVMState *s)
|
|
Pablo Greco |
e6a3ae |
{
|
|
Pablo Greco |
e6a3ae |
struct kvm_ppc_cpu_char c;
|
|
Pablo Greco |
e6a3ae |
@@ -2548,6 +2557,8 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
|
|
Pablo Greco |
e6a3ae |
cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c);
|
|
Pablo Greco |
e6a3ae |
cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c);
|
|
Pablo Greco |
e6a3ae |
cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c);
|
|
Pablo Greco |
e6a3ae |
+ cap_ppc_count_cache_flush_assist =
|
|
Pablo Greco |
e6a3ae |
+ parse_cap_ppc_count_cache_flush_assist(c);
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
int kvmppc_get_cap_safe_cache(void)
|
|
Pablo Greco |
e6a3ae |
@@ -2565,6 +2576,11 @@ int kvmppc_get_cap_safe_indirect_branch(void)
|
|
Pablo Greco |
e6a3ae |
return cap_ppc_safe_indirect_branch;
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
+int kvmppc_get_cap_count_cache_flush_assist(void)
|
|
Pablo Greco |
e6a3ae |
+{
|
|
Pablo Greco |
e6a3ae |
+ return cap_ppc_count_cache_flush_assist;
|
|
Pablo Greco |
e6a3ae |
+}
|
|
Pablo Greco |
e6a3ae |
+
|
|
Pablo Greco |
e6a3ae |
bool kvmppc_has_cap_nested_kvm_hv(void)
|
|
Pablo Greco |
e6a3ae |
{
|
|
Pablo Greco |
e6a3ae |
return !!cap_ppc_nested_kvm_hv;
|
|
Pablo Greco |
e6a3ae |
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
|
|
Pablo Greco |
e6a3ae |
index dc86eff..e440c75 100644
|
|
Pablo Greco |
e6a3ae |
--- a/target/ppc/kvm_ppc.h
|
|
Pablo Greco |
e6a3ae |
+++ b/target/ppc/kvm_ppc.h
|
|
Pablo Greco |
e6a3ae |
@@ -63,6 +63,7 @@ bool kvmppc_has_cap_mmu_hash_v3(void);
|
|
Pablo Greco |
e6a3ae |
int kvmppc_get_cap_safe_cache(void);
|
|
Pablo Greco |
e6a3ae |
int kvmppc_get_cap_safe_bounds_check(void);
|
|
Pablo Greco |
e6a3ae |
int kvmppc_get_cap_safe_indirect_branch(void);
|
|
Pablo Greco |
e6a3ae |
+int kvmppc_get_cap_count_cache_flush_assist(void);
|
|
Pablo Greco |
e6a3ae |
bool kvmppc_has_cap_nested_kvm_hv(void);
|
|
Pablo Greco |
e6a3ae |
int kvmppc_set_cap_nested_kvm_hv(int enable);
|
|
Pablo Greco |
e6a3ae |
int kvmppc_enable_hwrng(void);
|
|
Pablo Greco |
e6a3ae |
@@ -316,6 +317,11 @@ static inline int kvmppc_get_cap_safe_indirect_branch(void)
|
|
Pablo Greco |
e6a3ae |
return 0;
|
|
Pablo Greco |
e6a3ae |
}
|
|
Pablo Greco |
e6a3ae |
|
|
Pablo Greco |
e6a3ae |
+static inline int kvmppc_get_cap_count_cache_flush_assist(void)
|
|
Pablo Greco |
e6a3ae |
+{
|
|
Pablo Greco |
e6a3ae |
+ return 0;
|
|
Pablo Greco |
e6a3ae |
+}
|
|
Pablo Greco |
e6a3ae |
+
|
|
Pablo Greco |
e6a3ae |
static inline bool kvmppc_has_cap_nested_kvm_hv(void)
|
|
Pablo Greco |
e6a3ae |
{
|
|
Pablo Greco |
e6a3ae |
return false;
|
|
Pablo Greco |
e6a3ae |
--
|
|
Pablo Greco |
e6a3ae |
1.8.3.1
|
|
Pablo Greco |
e6a3ae |
|