]> git.proxmox.com Git - mirror_qemu.git/commitdiff
ppc: First cut implementation of -cpu host
authorDavid Gibson <david@gibson.dropbear.id.au>
Wed, 12 Oct 2011 22:40:32 +0000 (22:40 +0000)
committerAlexander Graf <agraf@suse.de>
Sun, 30 Oct 2011 16:11:54 +0000 (17:11 +0100)
For convenience with kvm, x86 allows the user to specify -cpu host on the
qemu command line, which means make the guest cpu the same as the host
cpu.  This patch implements the same option for ppc targets.

For now, this just read the host PVR (Processor Version Register) and
selects one of our existing CPU specs based on it.  This means that the
option will not work if the host cpu is not supported by TCG, even if that
wouldn't matter for use under kvm.

In future, we can extend this in future to override parts of the cpu spec
based on information obtained from the host (via /proc/cpuinfo, the host
device tree, or explicit KVM calls).  That will let us handle cases where
the real kvm-virtualized CPU doesn't behave exactly like the TCG-emulated
CPU.  With appropriate annotation of the CPU specs we'll also then be able
to use host cpus under kvm even when there isn't a matching full TCG model.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
target-ppc/cpu.h
target-ppc/kvm.c
target-ppc/kvm_ppc.h
target-ppc/translate_init.c

index 3f77e308a6e842967b380c2f21f774db5555e350..8e5c85c28efd5ca6af6234b20b275c72b3363525 100644 (file)
@@ -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);
 
index 96139acb23b935857ec8ab0fe1cfb60f2a795cca..313c7b2af29a39669543c16a2f3c82dbb143069f 100644 (file)
@@ -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;
index 955729a1cfe50de511e84773334bbfcb9dca6ecc..b0d6fb667eca4c34e75061250c3dfd345770b562 100644 (file)
@@ -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
index 73b49cfd6e55b120e94434c9468382abea7cbc0a..62f0a6b86768563d7802d871ba178b6889fa7971 100644 (file)
@@ -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') {