summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--target-ppc/cpu.h1
-rw-r--r--target-ppc/kvm.c19
-rw-r--r--target-ppc/kvm_ppc.h6
-rw-r--r--target-ppc/translate_init.c8
4 files changed, 33 insertions, 1 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 3f77e308a6..8e5c85c28e 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1107,6 +1107,7 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
 void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 
+const ppc_def_t *ppc_find_by_pvr(uint32_t pvr);
 const ppc_def_t *cpu_ppc_find_by_name (const char *name);
 int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
 
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 96139acb23..313c7b2af2 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -879,6 +879,25 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size)
     return 0;
 }
 
+static inline uint32_t mfpvr(void)
+{
+    uint32_t pvr;
+
+    asm ("mfpvr %0"
+         : "=r"(pvr));
+    return pvr;
+}
+
+const ppc_def_t *kvmppc_host_cpu_def(void)
+{
+    uint32_t host_pvr = mfpvr();
+    const ppc_def_t *base_spec;
+
+    base_spec = ppc_find_by_pvr(host_pvr);
+
+    return base_spec;
+}
+
 bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
     return true;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 955729a1cf..b0d6fb667e 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -26,6 +26,7 @@ int kvmppc_smt_threads(void);
 off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
 void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
 int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
+const ppc_def_t *kvmppc_host_cpu_def(void);
 
 #else
 
@@ -85,6 +86,11 @@ static inline int kvmppc_remove_spapr_tce(void *table, int pfd,
     return -1;
 }
 
+static inline const ppc_def_t *kvmppc_host_cpu_def(void)
+{
+    return NULL;
+}
+
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 73b49cfd6e..62f0a6b867 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -24,6 +24,8 @@
 
 #include "dis-asm.h"
 #include "gdbstub.h"
+#include <kvm.h>
+#include "kvm_ppc.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -10041,7 +10043,7 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
     return 0;
 }
 
-static const ppc_def_t *ppc_find_by_pvr (uint32_t pvr)
+const ppc_def_t *ppc_find_by_pvr(uint32_t pvr)
 {
     int i;
 
@@ -10063,6 +10065,10 @@ const ppc_def_t *cpu_ppc_find_by_name (const char *name)
     const char *p;
     int i, max, len;
 
+    if (kvm_enabled() && (strcasecmp(name, "host") == 0)) {
+        return kvmppc_host_cpu_def();
+    }
+
     /* Check if the given name is a PVR */
     len = strlen(name);
     if (len == 10 && name[0] == '0' && name[1] == 'x') {