summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr.c15
-rw-r--r--hw/ppc/spapr_caps.c29
-rw-r--r--include/hw/ppc/spapr.h3
3 files changed, 41 insertions, 6 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a6cf1234d8..73310bd3ee 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -253,7 +253,9 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
}
/* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
+static void spapr_populate_pa_features(sPAPRMachineState *spapr,
+ PowerPCCPU *cpu,
+ void *fdt, int offset,
bool legacy_guest)
{
CPUPPCState *env = &cpu->env;
@@ -318,7 +320,7 @@ static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
*/
pa_features[3] |= 0x20;
}
- if (kvmppc_has_cap_htm() && pa_size > 24) {
+ if (spapr_has_cap(spapr, SPAPR_CAP_HTM) && pa_size > 24) {
pa_features[24] |= 0x80; /* Transactional memory support */
}
if (legacy_guest && pa_size > 40) {
@@ -384,8 +386,8 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
return ret;
}
- spapr_populate_pa_features(cpu, fdt, offset,
- spapr->cas_legacy_guest_workaround);
+ spapr_populate_pa_features(spapr, cpu, fdt, offset,
+ spapr->cas_legacy_guest_workaround);
}
return ret;
}
@@ -579,7 +581,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
page_sizes_prop, page_sizes_prop_size)));
}
- spapr_populate_pa_features(cpu, fdt, offset, false);
+ spapr_populate_pa_features(spapr, cpu, fdt, offset, false);
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
cs->cpu_index / vcpus_per_socket)));
@@ -3903,7 +3905,10 @@ static void spapr_machine_2_11_instance_options(MachineState *machine)
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
spapr_machine_2_12_class_options(mc);
+ smc->default_caps = spapr_caps(SPAPR_CAP_HTM);
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
}
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 968ba7b857..3b35b91a5b 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -24,6 +24,10 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
+#include "sysemu/hw_accel.h"
+#include "target/ppc/cpu.h"
+#include "cpu-models.h"
+#include "kvm_ppc.h"
#include "hw/ppc/spapr.h"
@@ -40,18 +44,41 @@ typedef struct sPAPRCapabilityInfo {
void (*disallow)(sPAPRMachineState *spapr, Error **errp);
} sPAPRCapabilityInfo;
+static void cap_htm_allow(sPAPRMachineState *spapr, Error **errp)
+{
+ if (tcg_enabled()) {
+ error_setg(errp,
+ "No Transactional Memory support in TCG, try cap-htm=off");
+ } else if (kvm_enabled() && !kvmppc_has_cap_htm()) {
+ error_setg(errp,
+"KVM implementation does not support Transactional Memory, try cap-htm=off"
+ );
+ }
+}
+
static sPAPRCapabilityInfo capability_table[] = {
+ {
+ .name = "htm",
+ .description = "Allow Hardware Transactional Memory (HTM)",
+ .flag = SPAPR_CAP_HTM,
+ .allow = cap_htm_allow,
+ /* TODO: add cap_htm_disallow */
+ },
};
static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
CPUState *cs)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
sPAPRCapabilities caps;
caps = smc->default_caps;
- /* TODO: clamp according to cpu model */
+ if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07,
+ 0, spapr->max_compat_pvr)) {
+ caps.mask &= ~SPAPR_CAP_HTM;
+ }
return caps;
}
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 5569caf1d4..dc64f4ebcb 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -54,6 +54,9 @@ typedef enum {
* Capabilities
*/
+/* Hardware Transactional Memory */
+#define SPAPR_CAP_HTM 0x0000000000000001ULL
+
typedef struct sPAPRCapabilities sPAPRCapabilities;
struct sPAPRCapabilities {
uint64_t mask;