@@ -79,6 +79,7 @@
#define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift))
+#define PPC_DEVTREE_STR "PowerPC,"
sPAPREnvironment *spapr;
int spapr_allocate_irq(int hint, bool lsi)
@@ -295,9 +296,12 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
_FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
_FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
- modelname = g_strdup(cpu_model);
+ /* device tree nodes must look like this :
+ * PowerPC,CPU_ALIAS@0
+ */
+ modelname = g_strdup_printf(PPC_DEVTREE_STR "%s", cpu_model);
- for (i = 0; i < strlen(modelname); i++) {
+ for (i = strlen(PPC_DEVTREE_STR); i < strlen(modelname); i++) {
modelname[i] = toupper(modelname[i]);
}
@@ -735,7 +739,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
hwaddr rma_alloc_size;
- uint32_t initrd_base = 0;
+ uint32_t initrd_base = 0, pvr = 0;
long kernel_size = 0, initrd_size = 0;
long load_limit, rtas_limit, fw_size;
char *filename;
@@ -959,6 +963,14 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
spapr->entry_point = 0x100;
+#ifdef CONFIG_KVM
+ /* Ensure that cpu_model is correctly reflected for a KVM guest */
+ if (kvm_enabled() && !strcmp(cpu_model, "host")) {
+ asm ("mfpvr %0"
+ : "=r"(pvr));
+ cpu_model = ppc_cpu_alias_by_pvr(pvr);
+ }
+#endif
/* Prepare the device tree */
spapr->fdt_skel = spapr_create_fdt_skel(cpu_model,
initrd_base, initrd_size,
@@ -99,6 +99,7 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
#define ENV_OFFSET offsetof(PowerPCCPU, env)
PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
+const char *ppc_cpu_alias_by_pvr(uint32_t pvr);
void ppc_cpu_do_interrupt(CPUState *cpu);
void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
@@ -7913,6 +7913,34 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
return pcc;
}
+const char *ppc_cpu_alias_by_pvr(uint32_t pvr)
+{
+ int i;
+ const char *cpu_alias;
+ char *offset, *model;
+
+ cpu_alias = object_class_get_name(OBJECT_CLASS
+ (ppc_cpu_class_by_pvr(pvr)));
+
+ /* Replace the full class name in cpu_alias with the CPU alias
+ * Eg, POWER7_V2.3-POWERPC64-CPU can simply be called
+ * POWER7
+ */
+
+ offset = strstr(cpu_alias, "-" TYPE_POWERPC_CPU);
+ if (offset) {
+ model = g_strndup(cpu_alias, offset - cpu_alias);
+ for (i = 0; ppc_cpu_aliases[i].model != NULL; i++) {
+ if (strcmp(ppc_cpu_aliases[i].model, model) == 0) {
+ g_free(model);
+ return ppc_cpu_aliases[i].alias;
+ }
+ }
+ g_free(model);
+ }
+ return NULL;
+}
+
static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
{
ObjectClass *oc = (ObjectClass *)a;