A desperate attempt to get PowerNV KVM acceleration working. See if you can triumph where I have failed.
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c | |
index c9cb6fa3..c1f43310 100644 | |
--- a/hw/ppc/pnv.c | |
+++ b/hw/ppc/pnv.c | |
@@ -23,16 +23,17 @@ | |
#include "qapi/error.h" | |
#include "sysemu/sysemu.h" | |
#include "sysemu/numa.h" | |
#include "sysemu/reset.h" | |
#include "sysemu/runstate.h" | |
#include "sysemu/cpus.h" | |
#include "sysemu/device_tree.h" | |
#include "target/ppc/cpu.h" | |
+#include "target/ppc/kvm_ppc.h" | |
#include "qemu/log.h" | |
#include "hw/ppc/fdt.h" | |
#include "hw/ppc/ppc.h" | |
#include "hw/ppc/pnv.h" | |
#include "hw/ppc/pnv_core.h" | |
#include "hw/loader.h" | |
#include "exec/address-spaces.h" | |
#include "qapi/visitor.h" | |
@@ -786,20 +787,26 @@ static void pnv_init(MachineState *machine) | |
* default. | |
*/ | |
if (!pnv_match_cpu(mc->default_cpu_type, machine->cpu_type)) { | |
error_report("invalid CPU model '%s' for %s machine", | |
machine->cpu_type, mc->name); | |
exit(1); | |
} | |
- /* Create the processor chips */ | |
- i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX); | |
- chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"), | |
- i, machine->cpu_type); | |
+ /* Create the processor chips. */ | |
+ if (strcmp(machine->cpu_type, TYPE_HOST_POWERPC_CPU) != 0) { | |
+ i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX); | |
+ chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"), | |
+ i, machine->cpu_type); | |
+ } else { | |
+ /* hacky hack hack hack */ | |
+ chip_typename = g_strdup_printf("power9_v2.0-pnv-chip"); | |
+ i = 11; | |
+ } | |
if (!object_class_by_name(chip_typename)) { | |
error_report("invalid chip model '%.*s' for %s machine", | |
i, machine->cpu_type, mc->name); | |
exit(1); | |
} | |
pnv->num_chips = | |
machine->smp.max_cpus / (machine->smp.cores * machine->smp.threads); | |
@@ -1972,16 +1979,49 @@ static void pnv_machine_set_hb(Object *obj, bool value, Error **errp) | |
{ | |
PnvMachineState *pnv = PNV_MACHINE(obj); | |
if (value) { | |
pnv->fw_load_addr = 0x8000000; | |
} | |
} | |
+static char *pnv_machine_get_kvm_type(Object *obj, Error **errp) | |
+{ | |
+ PnvMachineState *pnv = PNV_MACHINE(obj); | |
+ | |
+ return g_strdup(pnv->kvm_type); | |
+} | |
+ | |
+static void pnv_machine_set_kvm_type(Object *obj, const char *value, Error **errp) | |
+{ | |
+ PnvMachineState *pnv = PNV_MACHINE(obj); | |
+ | |
+ g_free(pnv->kvm_type); | |
+ pnv->kvm_type = g_strdup(value); | |
+} | |
+ | |
+static int pnv_machine_kvm_type(MachineState *machine, const char *vm_type) | |
+{ | |
+ if (!vm_type) { | |
+ return 0; | |
+ } | |
+ | |
+ if (!strcmp(vm_type, "HV")) { | |
+ return 1; | |
+ } | |
+ | |
+ if (!strcmp(vm_type, "PR")) { | |
+ return 2; | |
+ } | |
+ | |
+ error_report("Unknown kvm-type specified '%s'", vm_type); | |
+ exit(1); | |
+} | |
+ | |
static void pnv_machine_class_init(ObjectClass *oc, void *data) | |
{ | |
MachineClass *mc = MACHINE_CLASS(oc); | |
InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc); | |
mc->desc = "IBM PowerNV (Non-Virtualized)"; | |
mc->init = pnv_init; | |
mc->reset = pnv_reset; | |
@@ -1991,24 +2031,31 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data) | |
mc->no_parallel = 1; | |
mc->default_boot_order = NULL; | |
/* | |
* RAM defaults to less than 2048 for 32-bit hosts, and large | |
* enough to fit the maximum initrd size at it's load address | |
*/ | |
mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE; | |
mc->default_ram_id = "pnv.ram"; | |
+ mc->kvm_type = pnv_machine_kvm_type; | |
ispc->print_info = pnv_pic_print_info; | |
object_class_property_add_bool(oc, "hb-mode", | |
pnv_machine_get_hb, pnv_machine_set_hb, | |
&error_abort); | |
object_class_property_set_description(oc, "hb-mode", | |
"Use a hostboot like boot loader", | |
NULL); | |
+ object_class_property_add_str(oc, "kvm-type", | |
+ pnv_machine_get_kvm_type, | |
+ pnv_machine_set_kvm_type, NULL); | |
+ object_class_property_set_description(oc, "kvm-type", | |
+ "Specifies the KVM virtualization mode (HV, PR)", | |
+ NULL); | |
} | |
#define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \ | |
{ \ | |
.name = type, \ | |
.class_init = class_initfn, \ | |
.parent = TYPE_PNV8_CHIP, \ | |
} | |
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h | |
index d4b0b0e2..37dbe672 100644 | |
--- a/include/hw/ppc/pnv.h | |
+++ b/include/hw/ppc/pnv.h | |
@@ -225,16 +225,18 @@ struct PnvMachineState { | |
uint32_t cpld_irqstate; | |
IPMIBmc *bmc; | |
Notifier powerdown_notifier; | |
PnvPnor *pnor; | |
hwaddr fw_load_addr; | |
+ | |
+ char *kvm_type; | |
}; | |
#define PNV_FDT_ADDR 0x01000000 | |
#define PNV_TIMEBASE_FREQ 512000000ULL | |
/* | |
* BMC helpers | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment