diff options
-rw-r--r-- | hw/ppc/e500plat.c | 7 | ||||
-rw-r--r-- | target-ppc/kvm.c | 7 | ||||
-rw-r--r-- | target-ppc/kvm_ppc.h | 6 |
3 files changed, 20 insertions, 0 deletions
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c index 7292ce1290..c85299588c 100644 --- a/hw/ppc/e500plat.c +++ b/hw/ppc/e500plat.c @@ -16,6 +16,7 @@ #include "sysemu/device_tree.h" #include "hw/pci/pci.h" #include "hw/ppc/openpic.h" +#include "kvm_ppc.h" static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt) { @@ -48,6 +49,12 @@ static void e500plat_init(QEMUMachineInitArgs *args) .mpic_version = OPENPIC_MODEL_FSL_MPIC_42, }; + /* Older KVM versions don't support EPR which breaks guests when we announce + MPIC variants that support EPR. Revert to an older one for those */ + if (kvm_enabled() && !kvmppc_has_cap_epr()) { + params.mpic_version = OPENPIC_MODEL_FSL_MPIC_20; + } + ppce500_init(¶ms); } diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 5e9dddbb54..f2658bba50 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -63,6 +63,7 @@ static int cap_ppc_rma; static int cap_spapr_tce; static int cap_hior; static int cap_one_reg; +static int cap_epr; /* XXX We have a race condition where we actually have a level triggered * interrupt, but the infrastructure can't expose that yet, so the guest @@ -95,6 +96,7 @@ int kvm_arch_init(KVMState *s) cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE); cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG); cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR); + cap_epr = kvm_check_extension(s, KVM_CAP_PPC_EPR); if (!cap_interrupt_level) { fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the " @@ -1530,6 +1532,11 @@ int kvmppc_fixup_cpu(PowerPCCPU *cpu) return 0; } +bool kvmppc_has_cap_epr(void) +{ + return cap_epr; +} + static int kvm_ppc_register_host_cpu_type(void) { TypeInfo type_info = { diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 6bcc5cc36c..600d63234a 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -33,6 +33,7 @@ int kvmppc_reset_htab(int shift_hint); uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift); #endif /* !CONFIG_USER_ONLY */ int kvmppc_fixup_cpu(PowerPCCPU *cpu); +bool kvmppc_has_cap_epr(void); #else @@ -129,6 +130,11 @@ static inline int kvmppc_fixup_cpu(PowerPCCPU *cpu) { return -1; } + +static inline bool kvmppc_has_cap_epr(void) +{ + return false; +} #endif #ifndef CONFIG_KVM |