Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.