aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/ppc/kvm.c39
-rw-r--r--target/ppc/kvm_ppc.h12
-rw-r--r--target/ppc/translate_init.c14
3 files changed, 50 insertions, 15 deletions
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index f1d5410..b6bd0fa 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -74,6 +74,7 @@ static int cap_interrupt_level = false;
static int cap_segstate;
static int cap_booke_sregs;
static int cap_ppc_smt;
+static int cap_ppc_smt_possible;
static int cap_ppc_rma;
static int cap_spapr_tce;
static int cap_spapr_tce_64;
@@ -130,7 +131,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL);
cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
- cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
+ cap_ppc_smt_possible = kvm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE);
cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
@@ -144,6 +145,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
* only activated after this by kvmppc_set_papr() */
cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
+ cap_ppc_smt = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT);
cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
@@ -2134,6 +2136,41 @@ int kvmppc_smt_threads(void)
return cap_ppc_smt ? cap_ppc_smt : 1;
}
+int kvmppc_set_smt_threads(int smt)
+{
+ int ret;
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SMT, 0, smt, 0);
+ if (!ret) {
+ cap_ppc_smt = smt;
+ }
+ return ret;
+}
+
+void kvmppc_hint_smt_possible(Error **errp)
+{
+ int i;
+ GString *g;
+ char *s;
+
+ assert(kvm_enabled());
+ if (cap_ppc_smt_possible) {
+ g = g_string_new("Available VSMT modes:");
+ for (i = 63; i >= 0; i--) {
+ if ((1UL << i) & cap_ppc_smt_possible) {
+ g_string_append_printf(g, " %lu", (1UL << i));
+ }
+ }
+ s = g_string_free(g, false);
+ error_append_hint(errp, "%s.\n", s);
+ g_free(s);
+ } else {
+ error_append_hint(errp,
+ "This KVM seems to be too old to support VSMT.\n");
+ }
+}
+
+
#ifdef TARGET_PPC64
off_t kvmppc_alloc_rma(void **rma)
{
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 381afe6..e6711fc 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -29,6 +29,8 @@ void kvmppc_set_papr(PowerPCCPU *cpu);
int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
int kvmppc_smt_threads(void);
+void kvmppc_hint_smt_possible(Error **errp);
+int kvmppc_set_smt_threads(int smt);
int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
int kvmppc_set_tcr(PowerPCCPU *cpu);
@@ -148,6 +150,16 @@ static inline int kvmppc_smt_threads(void)
return 1;
}
+static inline void kvmppc_hint_smt_possible(Error **errp)
+{
+ return;
+}
+
+static inline int kvmppc_set_smt_threads(int smt)
+{
+ return 0;
+}
+
static inline int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
{
return 0;
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 08ef74f..703ea12 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -9907,20 +9907,6 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
int max_smt = kvmppc_smt_threads();
#endif
-#if !defined(CONFIG_USER_ONLY)
- if (smp_threads > max_smt) {
- error_setg(errp, "Cannot support more than %d threads on PPC with %s",
- max_smt, kvm_enabled() ? "KVM" : "TCG");
- return;
- }
- if (!is_power_of_2(smp_threads)) {
- error_setg(errp, "Cannot support %d threads on PPC with %s, "
- "threads count must be a power of 2.",
- smp_threads, kvm_enabled() ? "KVM" : "TCG");
- return;
- }
-#endif
-
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);