/*
 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
 *
 * Copyright (c) 2004-2007 Fabrice Bellard
 * Copyright (c) 2007 Jocelyn Mayer
 * Copyright (c) 2010 David Gibson, IBM Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/datadir.h"
#include "qemu/memalign.h"
#include "qemu/guest-random.h"
#include "qapi/error.h"
#include "qapi/qapi-events-machine.h"
#include "qapi/qapi-events-qdev.h"
#include "qapi/visitor.h"
#include "sysemu/sysemu.h"
#include "sysemu/hostmem.h"
#include "sysemu/numa.h"
#include "sysemu/tcg.h"
#include "sysemu/qtest.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "qemu/log.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "net/net.h"
#include "sysemu/device_tree.h"
#include "sysemu/cpus.h"
#include "sysemu/hw_accel.h"
#include "kvm_ppc.h"
#include "migration/misc.h"
#include "migration/qemu-file-types.h"
#include "migration/global_state.h"
#include "migration/register.h"
#include "migration/blocker.h"
#include "mmu-hash64.h"
#include "mmu-book3s-v3.h"
#include "cpu-models.h"
#include "hw/core/cpu.h"

#include "hw/ppc/ppc.h"
#include "hw/loader.h"

#include "hw/ppc/fdt.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_nested.h"
#include "hw/ppc/spapr_vio.h"
#include "hw/ppc/vof.h"
#include "hw/qdev-properties.h"
#include "hw/pci-host/spapr.h"
#include "hw/pci/msi.h"

#include "hw/pci/pci.h"
#include "hw/scsi/scsi.h"
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/vhost-scsi-common.h"

#include "exec/ram_addr.h"
#include "exec/confidential-guest-support.h"
#include "hw/usb.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "trace.h"
#include "hw/nmi.h"
#include "hw/intc/intc.h"

#include "hw/ppc/spapr_cpu_core.h"
#include "hw/mem/memory-device.h"
#include "hw/ppc/spapr_tpm_proxy.h"
#include "hw/ppc/spapr_nvdimm.h"
#include "hw/ppc/spapr_numa.h"

#include <libfdt.h>

/* SLOF memory layout:
 *
 * SLOF raw image loaded at 0, copies its romfs right below the flat
 * device-tree, then position SLOF itself 31M below that
 *
 * So we set FW_OVERHEAD to 40MB which should account for all of that
 * and more
 *
 * We load our kernel at 4M, leaving space for SLOF initial image
 */
#define FDT_MAX_ADDR            0x80000000 /* FDT must stay below that */
#define FW_MAX_SIZE             0x400000
#define FW_FILE_NAME            "slof.bin"
#define FW_FILE_NAME_VOF        "vof.bin"
#define FW_OVERHEAD             0x2800000
#define KERNEL_LOAD_ADDR        FW_MAX_SIZE

#define MIN_RMA_SLOF            (128 * MiB)

#define PHANDLE_INTC            0x00001111

/* These two functions implement the VCPU id numbering: one to compute them
 * all and one to identify thread 0 of a VCORE. Any change to the first one
 * is likely to have an impact on the second one, so let's keep them close.
 */
static int spapr_vcpu_id(SpaprMachineState *spapr, int cpu_index)
{
    MachineState *ms = MACHINE(spapr);
    unsigned int smp_threads = ms->smp.threads;

    assert(spapr->vsmt);
    return
        (cpu_index / smp_threads) * spapr->vsmt + cpu_index % smp_threads;
}
static bool spapr_is_thread0_in_vcore(SpaprMachineState *spapr,
                                      PowerPCCPU *cpu)
{
    assert(spapr->vsmt);
    return spapr_get_vcpu_id(cpu) % spapr->vsmt == 0;
}

int spapr_max_server_number(SpaprMachineState *spapr)
{
    MachineState *ms = MACHINE(spapr);

    assert(spapr->vsmt);
    return DIV_ROUND_UP(ms->smp.max_cpus * spapr->vsmt, ms->smp.threads);
}

static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
                                  int smt_threads)
{
    int i, ret = 0;
    g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
    g_autofree uint32_t *gservers_prop = g_new(uint32_t, smt_threads * 2);
    int index = spapr_get_vcpu_id(cpu);

    if (cpu->compat_pvr) {
        ret = fdt_setprop_cell(fdt, offset, "cpu-version", cpu->compat_pvr);
        if (ret < 0) {
            return ret;
        }
    }

    /* Build interrupt servers and gservers properties */
    for (i = 0; i < smt_threads; i++) {
        servers_prop[i] = cpu_to_be32(index + i);
        /* Hack, direct the group queues back to cpu 0 */
        gservers_prop[i*2] = cpu_to_be32(index + i);
        gservers_prop[i*2 + 1] = 0;
    }
    ret = fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
                      servers_prop, sizeof(*servers_prop) * smt_threads);
    if (ret < 0) {
        return ret;
    }
    ret = fdt_setprop(fdt, offset, "ibm,ppc-interrupt-gserver#s",
                      gservers_prop, sizeof(*gservers_prop) * smt_threads * 2);

    return ret;
}

static void spapr_dt_pa_features(SpaprMachineState *spapr,
                                 PowerPCCPU *cpu,
                                 void *fdt, int offset)
{
    /*
     * SSO (SAO) ordering is supported on KVM and thread=single hosts,
     * but not MTTCG, so disable it. To advertise it, a cap would have
     * to be added, or support implemented for MTTCG.
     *
     * Copy/paste is not supported by TCG, so it is not advertised. KVM
     * can execute them but it has no accelerator drivers which are usable,
     * so there isn't much need for it anyway.
     */

    /* These should be kept in sync with pnv */
    uint8_t pa_features_206[] = { 6, 0,
        0xf6, 0x1f, 0xc7, 0x00, 0x00, 0xc0 };
    uint8_t pa_features_207[] = { 24, 0,
        0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0,
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
        0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
    uint8_t pa_features_300[] = { 66, 0,
        /* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
        /* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
        0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
        /* 6: DS207 */
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
        /* 16: Vector */
        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
        /* 18: Vec. Scalar, 20: Vec. XOR */
        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
        /* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
        /* 32: LE atomic, 34: EBB + ext EBB */
        0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
        /* 40: Radix MMU */
        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
        /* 42: PM, 44: PC RA, 46: SC vec'd */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
        /* 48: SIMD, 50: QP BFP, 52: String */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
        /* 54: DecFP, 56: DecI, 58: SHA */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
        /* 60: NM atomic, 62: RNG */
        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
    };
    /* 3.1 removes SAO, HTM support */
    uint8_t pa_features_31[] = { 74, 0,
        /* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
        /* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
        0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
        /* 6: DS207 */
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
        /* 16: Vector */
        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
        /* 18: Vec. Scalar, 20: Vec. XOR */
        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
        /* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
        /* 32: LE atomic, 34: EBB + ext EBB */
        0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
        /* 40: Radix MMU */
        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
        /* 42: PM, 44: PC RA, 46: SC vec'd */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
        /* 48: SIMD, 50: QP BFP, 52: String */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
        /* 54: DecFP, 56: DecI, 58: SHA */
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
        /* 60: NM atomic, 62: RNG */
        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
        /* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */
        0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */
        /* 72: [P]HASHST/[P]HASHCHK */
        0x80, 0x00,                         /* 72 - 73 */
    };
    uint8_t *pa_features = NULL;
    size_t pa_size;

    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06, 0, cpu->compat_pvr)) {
        pa_features = pa_features_206;
        pa_size = sizeof(pa_features_206);
    }
    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07, 0, cpu->compat_pvr)) {
        pa_features = pa_features_207;
        pa_size = sizeof(pa_features_207);
    }
    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, cpu->compat_pvr)) {
        pa_features = pa_features_300;
        pa_size = sizeof(pa_features_300);
    }
    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_10, 0, cpu->compat_pvr)) {
        pa_features = pa_features_31;
        pa_size = sizeof(pa_features_31);
    }
    if (!pa_features) {
        return;
    }

    if (ppc_hash64_has(cpu, PPC_HASH64_CI_LARGEPAGE)) {
        /*
         * Note: we keep CI large pages off by default because a 64K capable
         * guest provisioned with large pages might otherwise try to map a qemu
         * framebuffer (or other kind of memory mapped PCI BAR) using 64K pages
         * even if that qemu runs on a 4k host.
         * We dd this bit back here if we are confident this is not an issue
         */
        pa_features[3] |= 0x20;
    }
    if ((spapr_get_cap(spapr, SPAPR_CAP_HTM) != 0) && pa_size > 24) {
        pa_features[24] |= 0x80;    /* Transactional memory support */
    }
    if (spapr->cas_pre_isa3_guest && pa_size > 40) {
        /* Workaround for broken kernels that attempt (guest) radix
         * mode when they can't handle it, if they see the radix bit set
         * in pa-features. So hide it from them. */
        pa_features[40 + 2] &= ~0x80; /* Radix MMU */
    }

    _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
}

static void spapr_dt_pi_features(SpaprMachineState *spapr,
                                 PowerPCCPU *cpu,
                                 void *fdt, int offset)
{
    uint8_t pi_features[] = { 1, 0,
        0x00 };

    if (kvm_enabled() && ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00,
                                          0, cpu->compat_pvr)) {
        /*
         * POWER9 and later CPUs with KVM run in LPAR-per-thread mode where
         * all threads are essentially independent CPUs, and msgsndp does not
         * work (because it is physically-addressed) and therefore is
         * emulated by KVM, so disable it here to ensure XIVE will be used.
         * This is both KVM and CPU implementation-specific behaviour so a KVM
         * cap would be cleanest, but for now this works. If KVM ever permits
         * native msgsndp execution by guests, a cap could be added at that
         * time.
         */
        pi_features[2] |= 0x08; /* 4: No msgsndp */
    }

    _FDT((fdt_setprop(fdt, offset, "ibm,pi-features", pi_features,
                      sizeof(pi_features))));
}

static hwaddr spapr_node0_size(MachineState *machine)
{
    if (machine->numa_state->num_nodes) {
        int i;
        for (i = 0; i < machine->numa_state->num_nodes; ++i) {
            if (machine->numa_state->nodes[i].node_mem) {
                return MIN(pow2floor(machine->numa_state->nodes[i].node_mem),
                           machine->ram_size);
            }
        }
    }
    return machine->ram_size;
}

static void add_str(GString *s, const gchar *s1)
{
    g_string_append_len(s, s1, strlen(s1) + 1);
}

static int spapr_dt_memory_node(SpaprMachineState *spapr, void *fdt, int nodeid,
                                hwaddr start, hwaddr size)
{
    char mem_name[32];
    uint64_t mem_reg_property[2];
    int off;

    mem_reg_property[0] = cpu_to_be64(start);
    mem_reg_property[1] = cpu_to_be64(size);

    sprintf(mem_name, "memory@%" HWADDR_PRIx, start);
    off = fdt_add_subnode(fdt, 0, mem_name);
    _FDT(off);
    _FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
    _FDT((fdt_setprop(fdt, off, "reg", mem_reg_property,
                      sizeof(mem_reg_property))));
    spapr_numa_write_associativity_dt(spapr, fdt, off, nodeid);
    return off;
}

static uint32_t spapr_pc_dimm_node(MemoryDeviceInfoList *list, ram_addr_t addr)
{
    MemoryDeviceInfoList *info;

    for (info = list; info; info = info->next) {
        MemoryDeviceInfo *value = info->value;

        if (value && value->type == MEMORY_DEVICE_INFO_KIND_DIMM) {
            PCDIMMDeviceInfo *pcdimm_info = value->u.dimm.data;

            if (addr >= pcdimm_info->addr &&
                addr < (pcdimm_info->addr + pcdimm_info->size)) {
                return pcdimm_info->node;
            }
        }
    }

    return -1;
}

struct sPAPRDrconfCellV2 {
     uint32_t seq_lmbs;
     uint64_t base_addr;
     uint32_t drc_index;
     uint32_t aa_index;
     uint32_t flags;
} QEMU_PACKED;

typedef struct DrconfCellQueue {
    struct sPAPRDrconfCellV2 cell;
    QSIMPLEQ_ENTRY(DrconfCellQueue) entry;
} DrconfCellQueue;

static DrconfCellQueue *
spapr_get_drconf_cell(uint32_t seq_lmbs, uint64_t base_addr,
                      uint32_t drc_index, uint32_t aa_index,
                      uint32_t flags)
{
    DrconfCellQueue *elem;

    elem = g_malloc0(sizeof(*elem));
    elem->cell.seq_lmbs = cpu_to_be32(seq_lmbs);
    elem->cell.base_addr = cpu_to_be64(base_addr);
    elem->cell.drc_index = cpu_to_be32(drc_index);
    elem->cell.aa_index = cpu_to_be32(aa_index);
    elem->cell.flags = cpu_to_be32(flags);

    return elem;
}

static int spapr_dt_dynamic_memory_v2(SpaprMachineState *spapr, void *fdt,
                                      int offset, MemoryDeviceInfoList *dimms)
{
    MachineState *machine = MACHINE(spapr);
    uint8_t *int_buf, *cur_index;
    int ret;
    uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
    uint64_t addr, cur_addr, size;
    uint32_t nr_boot_lmbs = (machine->device_memory->base / lmb_size);
    uint64_t mem_end = machine->device_memory->base +
                       memory_region_size(&machine->device_memory->mr);
    uint32_t node, buf_len, nr_entries = 0;
    SpaprDrc *drc;
    DrconfCellQueue *elem, *next;
    MemoryDeviceInfoList *info;
    QSIMPLEQ_HEAD(, DrconfCellQueue) drconf_queue
        = QSIMPLEQ_HEAD_INITIALIZER(drconf_queue);

    /* Entry to cover RAM and the gap area */
    elem = spapr_get_drconf_cell(nr_boot_lmbs, 0, 0, -1,
                                 SPAPR_LMB_FLAGS_RESERVED |
                                 SPAPR_LMB_FLAGS_DRC_INVALID);
    QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry);
    nr_entries++;

    cur_addr = machine->device_memory->base;
    for (info = dimms; info; info = info->next) {
        PCDIMMDeviceInfo *di = info->value->u.dimm.data;

        addr = di->addr;
        size = di->size;
        node = di->node;

        /*
         * The NVDIMM area is hotpluggable after the NVDIMM is unplugged. The
         * area is marked hotpluggable in the next iteration for the bigger
         * chunk including the NVDIMM occupied area.
         */
        if (info->value->type == MEMORY_DEVICE_INFO_KIND_NVDIMM)
            continue;

        /* Entry for hot-pluggable area */
        if (cur_addr < addr) {
            drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, cur_addr / lmb_size);
            g_assert(drc);
            elem = spapr_get_drconf_cell((addr - cur_addr) / lmb_size,
                                         cur_addr, spapr_drc_index(drc), -1, 0);
            QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry);
            nr_entries++;
        }

        /* Entry for DIMM */
        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, addr / lmb_size);
        g_assert(drc);
        elem = spapr_get_drconf_cell(size / lmb_size, addr,
                                     spapr_drc_index(drc), node,
                                     (SPAPR_LMB_FLAGS_ASSIGNED |
                                      SPAPR_LMB_FLAGS_HOTREMOVABLE));
        QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry);
        nr_entries++;
        cur_addr = addr + size;
    }

    /* Entry for remaining hotpluggable area */
    if (cur_addr < mem_end) {
        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, cur_addr / lmb_size);
        g_assert(drc);
        elem = spapr_get_drconf_cell((mem_end - cur_addr) / lmb_size,
                                     cur_addr, spapr_drc_index(drc), -1, 0);
        QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry);
        nr_entries++;
    }

    buf_len = nr_entries * sizeof(struct sPAPRDrconfCellV2) + sizeof(uint32_t);
    int_buf = cur_index = g_malloc0(buf_len);
    *(uint32_t *)int_buf = cpu_to_be32(nr_entries);
    cur_index += sizeof(nr_entries);

    QSIMPLEQ_FOREACH_SAFE(elem, &drconf_queue, entry, next) {
        memcpy(cur_index, &elem->cell, sizeof(elem->cell));
        cur_index += sizeof(elem->cell);
        QSIMPLEQ_REMOVE(&drconf_queue, elem, DrconfCellQueue, entry);
        g_free(elem);
    }

    ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory-v2", int_buf, buf_len);
    g_free(int_buf);
    if (ret < 0) {
        return -1;
    }
    return 0;
}

static int spapr_dt_dynamic_memory(SpaprMachineState *spapr, void *fdt,
                                   int offset, MemoryDeviceInfoList *dimms)
{
    MachineState *machine = MACHINE(spapr);
    int i, ret;
    uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
    uint32_t device_lmb_start = machine->device_memory->base / lmb_size;
    uint32_t nr_lmbs = (machine->device_memory->base +
                       memory_region_size(&machine->device_memory->mr)) /
                       lmb_size;
    uint32_t *int_buf, *cur_index, buf_len;

    /*
     * Allocate enough buffer size to fit in ibm,dynamic-memory
     */
    buf_len = (nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE + 1) * sizeof(uint32_t);
    cur_index = int_buf = g_malloc0(buf_len);
    int_buf[0] = cpu_to_be32(nr_lmbs);
    cur_index++;
    for (i = 0; i < nr_lmbs; i++) {
        uint64_t addr = i * lmb_size;
        uint32_t *dynamic_memory = cur_index;

        if (i >= device_lmb_start) {
            SpaprDrc *drc;

            drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, i);
            g_assert(drc);

            dynamic_memory[0] = cpu_to_be32(addr >> 32);
            dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff);
            dynamic_memory[2] = cpu_to_be32(spapr_drc_index(drc));
            dynamic_memory[3] = cpu_to_be32(0); /* reserved */
            dynamic_memory[4] = cpu_to_be32(spapr_pc_dimm_node(dimms, addr));
            if (memory_region_present(get_system_memory(), addr)) {
                dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED);
            } else {
                dynamic_memory[5] = cpu_to_be32(0);
            }
        } else {
            /*
             * LMB information for RMA, boot time RAM and gap b/n RAM and
             * device memory region -- all these are marked as reserved
             * and as having no valid DRC.
             */
            dynamic_memory[0] = cpu_to_be32(addr >> 32);
            dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff);
            dynamic_memory[2] = cpu_to_be32(0);
            dynamic_memory[3] = cpu_to_be32(0); /* reserved */
            dynamic_memory[4] = cpu_to_be32(-1);
            dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_RESERVED |
                                            SPAPR_LMB_FLAGS_DRC_INVALID);
        }

        cur_index += SPAPR_DR_LMB_LIST_ENTRY_SIZE;
    }
    ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory", int_buf, buf_len);
    g_free(int_buf);
    if (ret < 0) {
        return -1;
    }
    return 0;
}

/*
 * Adds ibm,dynamic-reconfiguration-memory node.
 * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation
 * of this device tree node.
 */
static int spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr,
                                                   void *fdt)
{
    MachineState *machine = MACHINE(spapr);
    int ret, offset;
    uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
    uint32_t prop_lmb_size[] = {cpu_to_be32(lmb_size >> 32),
                                cpu_to_be32(lmb_size & 0xffffffff)};
    MemoryDeviceInfoList *dimms = NULL;

    /* Don't create the node if there is no device memory. */
    if (!machine->device_memory) {
        return 0;
    }

    offset = fdt_add_subnode(fdt, 0, "ibm,dynamic-reconfiguration-memory");

    ret = fdt_setprop(fdt, offset, "ibm,lmb-size", prop_lmb_size,
                    sizeof(prop_lmb_size));
    if (ret < 0) {
        return ret;
    }

    ret = fdt_setprop_cell(fdt, offset, "ibm,memory-flags-mask", 0xff);
    if (ret < 0) {
        return ret;
    }

    ret = fdt_setprop_cell(fdt, offset, "ibm,memory-preservation-time", 0x0);
    if (ret < 0) {
        return ret;
    }

    /* ibm,dynamic-memory or ibm,dynamic-memory-v2 */
    dimms = qmp_memory_device_list();
    if (spapr_ovec_test(spapr->ov5_cas, OV5_DRMEM_V2)) {
        ret = spapr_dt_dynamic_memory_v2(spapr, fdt, offset, dimms);
    } else {
        ret = spapr_dt_dynamic_memory(spapr, fdt, offset, dimms);
    }
    qapi_free_MemoryDeviceInfoList(dimms);

    if (ret < 0) {
        return ret;
    }

    ret = spapr_numa_write_assoc_lookup_arrays(spapr, fdt, offset);

    return ret;
}

static int spapr_dt_memory(SpaprMachineState *spapr, void *fdt)
{
    MachineState *machine = MACHINE(spapr);
    hwaddr mem_start, node_size;
    int i, nb_nodes = machine->numa_state->num_nodes;
    NodeInfo *nodes = machine->numa_state->nodes;

    for (i = 0, mem_start = 0; i < nb_nodes; ++i) {
        if (!nodes[i].node_mem) {
            continue;
        }
        if (mem_start >= machine->ram_size) {
            node_size = 0;
        } else {
            node_size = nodes[i].node_mem;
            if (node_size > machine->ram_size - mem_start) {
                node_size = machine->ram_size - mem_start;
            }
        }
        if (!mem_start) {
            /* spapr_machine_init() checks for rma_size <= node0_size
             * already */
            spapr_dt_memory_node(spapr, fdt, i, 0, spapr->rma_size);
            mem_start += spapr->rma_size;
            node_size -= spapr->rma_size;
        }
        for ( ; node_size; ) {
            hwaddr sizetmp = pow2floor(node_size);

            /* mem_start != 0 here */
            if (ctzl(mem_start) < ctzl(sizetmp)) {
                sizetmp = 1ULL << ctzl(mem_start);
            }

            spapr_dt_memory_node(spapr, fdt, i, mem_start, sizetmp);
            node_size -= sizetmp;
            mem_start += sizetmp;
        }
    }

    /* Generate ibm,dynamic-reconfiguration-memory node if required */
    if (spapr_ovec_test(spapr->ov5_cas, OV5_DRCONF_MEMORY)) {
        int ret;

        ret = spapr_dt_dynamic_reconfiguration_memory(spapr, fdt);
        if (ret) {
            return ret;
        }
    }

    return 0;
}

static void spapr_dt_cpu(CPUState *cs, void *fdt, int offset,
                         SpaprMachineState *spapr)
{
    MachineState *ms = MACHINE(spapr);
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
    int index = spapr_get_vcpu_id(cpu);
    uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
                       0xffffffff, 0xffffffff};
    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq()
        : SPAPR_TIMEBASE_FREQ;
    uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
    uint32_t page_sizes_prop[64];
    size_t page_sizes_prop_size;
    unsigned int smp_threads = ms->smp.threads;
    uint32_t vcpus_per_socket = smp_threads * ms->smp.cores;
    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
    int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
    SpaprDrc *drc;
    int drc_index;
    uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];
    int i;

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index);
    if (drc) {
        drc_index = spapr_drc_index(drc);
        _FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)));
    }

    _FDT((fdt_setprop_cell(fdt, offset, "reg", index)));
    _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));

    _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
                           env->dcache_line_size)));
    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
                           env->dcache_line_size)));
    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
                           env->icache_line_size)));
    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
                           env->icache_line_size)));

    if (pcc->l1_dcache_size) {
        _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
                               pcc->l1_dcache_size)));
    } else {
        warn_report("Unknown L1 dcache size for cpu");
    }
    if (pcc->l1_icache_size) {
        _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",
                               pcc->l1_icache_size)));
    } else {
        warn_report("Unknown L1 icache size for cpu");
    }

    _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
    _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
    _FDT((fdt_setprop_cell(fdt, offset, "slb-size", cpu->hash64_opts->slb_size)));
    _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", cpu->hash64_opts->slb_size)));
    _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
    _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));

    if (ppc_has_spr(cpu, SPR_PURR)) {
        _FDT((fdt_setprop_cell(fdt, offset, "ibm,purr", 1)));
    }
    if (ppc_has_spr(cpu, SPR_PURR)) {
        _FDT((fdt_setprop_cell(fdt, offset, "ibm,spurr", 1)));
    }

    if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG)) {
        _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
                          segs, sizeof(segs))));
    }

    /* Advertise VSX (vector extensions) if available
     *   1               == VMX / Altivec available
     *   2               == VSX available
     *
     * Only CPUs for which we create core types in spapr_cpu_core.c
     * are possible, and all of those have VMX */
    if (env->insns_flags & PPC_ALTIVEC) {
        if (spapr_get_cap(spapr, SPAPR_CAP_VSX) != 0) {
            _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
        } else {
            _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
        }
    }

    /* Advertise DFP (Decimal Floating Point) if available
     *   0 / no property == no DFP
     *   1               == DFP available */
    if (spapr_get_cap(spapr, SPAPR_CAP_DFP) != 0) {
        _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
    }

    page_sizes_prop_size = ppc_create_page_sizes_prop(cpu, page_sizes_prop,
                                                      sizeof(page_sizes_prop));
    if (page_sizes_prop_size) {
        _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
                          page_sizes_prop, page_sizes_prop_size)));
    }

    spapr_dt_pa_features(spapr, cpu, fdt, offset);

    spapr_dt_pi_features(spapr, cpu, fdt, offset);

    _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
                           cs->cpu_index / vcpus_per_socket)));

    _FDT((fdt_setprop(fdt, offset, "ibm,pft-size",
                      pft_size_prop, sizeof(pft_size_prop))));

    if (ms->numa_state->num_nodes > 1) {
        _FDT(spapr_numa_fixup_cpu_dt(spapr, fdt, offset, cpu));
    }

    _FDT(spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt));

    if (pcc->radix_page_info) {
        for (i = 0; i < pcc->radix_page_info->count; i++) {
            radix_AP_encodings[i] =
                cpu_to_be32(pcc->radix_page_info->entries[i]);
        }
        _FDT((fdt_setprop(fdt, offset, "ibm,processor-radix-AP-encodings",
                          radix_AP_encodings,
                          pcc->radix_page_info->count *
                          sizeof(radix_AP_encodings[0]))));
    }

    /*
     * We set this property to let the guest know that it can use the large
     * decrementer and its width in bits.
     */
    if (spapr_get_cap(spapr, SPAPR_CAP_LARGE_DECREMENTER) != SPAPR_CAP_OFF)
        _FDT((fdt_setprop_u32(fdt, offset, "ibm,dec-bits",
                              pcc->lrg_decr_bits)));
}

static void spapr_dt_one_cpu(void *fdt, SpaprMachineState *spapr, CPUState *cs,
                             int cpus_offset)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    int index = spapr_get_vcpu_id(cpu);
    DeviceClass *dc = DEVICE_GET_CLASS(cs);
    g_autofree char *nodename = NULL;
    int offset;

    if (!spapr_is_thread0_in_vcore(spapr, cpu)) {
        return;
    }

    nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
    offset = fdt_add_subnode(fdt, cpus_offset, nodename);
    _FDT(offset);
    spapr_dt_cpu(cs, fdt, offset, spapr);
}


static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)
{
    CPUState **rev;
    CPUState *cs;
    int n_cpus;
    int cpus_offset;
    int i;

    cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
    _FDT(cpus_offset);
    _FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0x1)));
    _FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0)));

    /*
     * We walk the CPUs in reverse order to ensure that CPU DT nodes
     * created by fdt_add_subnode() end up in the right order in FDT
     * for the guest kernel the enumerate the CPUs correctly.
     *
     * The CPU list cannot be traversed in reverse order, so we need
     * to do extra work.
     */
    n_cpus = 0;
    rev = NULL;
    CPU_FOREACH(cs) {
        rev = g_renew(CPUState *, rev, n_cpus + 1);
        rev[n_cpus++] = cs;
    }

    for (i = n_cpus - 1; i >= 0; i--) {
        spapr_dt_one_cpu(fdt, spapr, rev[i], cpus_offset);
    }

    g_free(rev);
}

static int spapr_dt_rng(void *fdt)
{
    int node;
    int ret;

    node = qemu_fdt_add_subnode(fdt, "/ibm,platform-facilities");
    if (node <= 0) {
        return -1;
    }
    ret = fdt_setprop_string(fdt, node, "device_type",
                             "ibm,platform-facilities");
    ret |= fdt_setprop_cell(fdt, node, "#address-cells", 0x1);
    ret |= fdt_setprop_cell(fdt, node, "#size-cells", 0x0);

    node = fdt_add_subnode(fdt, node, "ibm,random-v1");
    if (node <= 0) {
        return -1;
    }
    ret |= fdt_setprop_string(fdt, node, "compatible", "ibm,random");

    return ret ? -1 : 0;
}

static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
{
    MachineState *ms = MACHINE(spapr);
    int rtas;
    GString *hypertas = g_string_sized_new(256);
    GString *qemu_hypertas = g_string_sized_new(256);
    uint32_t lrdr_capacity[] = {
        0,
        0,
        cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE >> 32),
        cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE & 0xffffffff),
        cpu_to_be32(ms->smp.max_cpus / ms->smp.threads),
    };

    /* Do we have device memory? */
    if (MACHINE(spapr)->device_memory) {
        uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
            memory_region_size(&MACHINE(spapr)->device_memory->mr);

        lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
        lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
    }

    _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));

    /* hypertas */
    add_str(hypertas, "hcall-pft");
    add_str(hypertas, "hcall-term");
    add_str(hypertas, "hcall-dabr");
    add_str(hypertas, "hcall-interrupt");
    add_str(hypertas, "hcall-tce");
    add_str(hypertas, "hcall-vio");
    add_str(hypertas, "hcall-splpar");
    add_str(hypertas, "hcall-join");
    add_str(hypertas, "hcall-bulk");
    add_str(hypertas, "hcall-set-mode");
    add_str(hypertas, "hcall-sprg0");
    add_str(hypertas, "hcall-copy");
    add_str(hypertas, "hcall-debug");
    add_str(hypertas, "hcall-vphn");
    if (spapr_get_cap(spapr, SPAPR_CAP_RPT_INVALIDATE) == SPAPR_CAP_ON) {
        add_str(hypertas, "hcall-rpt-invalidate");
    }

    add_str(qemu_hypertas, "hcall-memop1");

    if (!kvm_enabled() || kvmppc_spapr_use_multitce()) {
        add_str(hypertas, "hcall-multi-tce");
    }

    if (spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) {
        add_str(hypertas, "hcall-hpt-resize");
    }

    add_str(hypertas, "hcall-watchdog");

    _FDT(fdt_setprop(fdt, rtas, "ibm,hypertas-functions",
                     hypertas->str, hypertas->len));
    g_string_free(hypertas, TRUE);
    _FDT(fdt_setprop(fdt, rtas, "qemu,hypertas-functions",
                     qemu_hypertas->str, qemu_hypertas->len));
    g_string_free(qemu_hypertas, TRUE);

    spapr_numa_write_rtas_dt(spapr, fdt, rtas);

    /*
     * FWNMI reserves RTAS_ERROR_LOG_MAX for the machine check error log,
     * and 16 bytes per CPU for system reset error log plus an extra 8 bytes.
     *
     * The system reset requirements are driven by existing Linux and PowerVM
     * implementation which (contrary to PAPR) saves r3 in the error log
     * structure like machine check, so Linux expects to find the saved r3
     * value at the address in r3 upon FWNMI-enabled sreset interrupt (and
     * does not look at the error value).
     *
     * System reset interrupts are not subject to interlock like machine
     * check, so this memory area could be corrupted if the sreset is
     * interrupted by a machine check (or vice versa) if it was shared. To
     * prevent this, system reset uses per-CPU areas for the sreset save
     * area. A system reset that interrupts a system reset handler could
     * still overwrite this area, but Linux doesn't try to recover in that
     * case anyway.
     *
     * The extra 8 bytes is required because Linux's FWNMI error log check
     * is off-by-one.
     *
     * RTAS_MIN_SIZE is required for the RTAS blob itself.
     */
    _FDT(fdt_setprop_cell(fdt, rtas, "rtas-size", RTAS_MIN_SIZE +
                          RTAS_ERROR_LOG_MAX +
                          ms->smp.max_cpus * sizeof(uint64_t) * 2 +
                          sizeof(uint64_t)));
    _FDT(fdt_setprop_cell(fdt, rtas, "rtas-error-log-max",
                          RTAS_ERROR_LOG_MAX));
    _FDT(fdt_setprop_cell(fdt, rtas, "rtas-event-scan-rate",
                          RTAS_EVENT_SCAN_RATE));

    g_assert(msi_nonbroken);
    _FDT(fdt_setprop(fdt, rtas, "ibm,change-msix-capable", NULL, 0));

    /*
     * According to PAPR, rtas ibm,os-term does not guarantee a return
     * back to the guest cpu.
     *
     * While an additional ibm,extended-os-term property indicates
     * that rtas call return will always occur. Set this property.
     */
    _FDT(fdt_setprop(fdt, rtas, "ibm,extended-os-term", NULL, 0));

    _FDT(fdt_setprop(fdt, rtas, "ibm,lrdr-capacity",
                     lrdr_capacity, sizeof(lrdr_capacity)));

    spapr_dt_rtas_tokens(fdt, rtas);
}

/*
 * Prepare ibm,arch-vec-5-platform-support, which indicates the MMU
 * and the XIVE features that the guest may request and thus the valid
 * values for bytes 23..26 of option vector 5:
 */
static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
                                          int chosen)
{
    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);

    char val[2 * 4] = {
        23, 0x00, /* XICS / XIVE mode */
        24, 0x00, /* Hash/Radix, filled in below. */
        25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
        26, 0x40, /* Radix options: GTSE == yes. */
    };

    if (spapr->irq->xics && spapr->irq->xive) {
        val[1] = SPAPR_OV5_XIVE_BOTH;
    } else if (spapr->irq->xive) {
        val[1] = SPAPR_OV5_XIVE_EXPLOIT;
    } else {
        assert(spapr->irq->xics);
        val[1] = SPAPR_OV5_XIVE_LEGACY;
    }

    if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
                          first_ppc_cpu->compat_pvr)) {
        /*
         * If we're in a pre POWER9 compat mode then the guest should
         * do hash and use the legacy interrupt mode
         */
        val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
        val[3] = 0x00; /* Hash */
        spapr_check_mmu_mode(false);
    } else if (kvm_enabled()) {
        if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
            val[3] = 0x80; /* OV5_MMU_BOTH */
        } else if (kvmppc_has_cap_mmu_radix()) {
            val[3] = 0x40; /* OV5_MMU_RADIX_300 */
        } else {
            val[3] = 0x00; /* Hash */
        }
    } else {
        /* V3 MMU supports both hash and radix in tcg (with dynamic switching) */
        val[3] = 0xC0;
    }
    _FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support",
                     val, sizeof(val)));
}

static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset)
{
    MachineState *machine = MACHINE(spapr);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
    int chosen;

    _FDT(chosen = fdt_add_subnode(fdt, 0, "chosen"));

    if (reset) {
        const char *boot_device = spapr->boot_device;
        g_autofree char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
        size_t cb = 0;
        g_autofree char *bootlist = get_boot_devices_list(&cb);

        if (machine->kernel_cmdline && machine->kernel_cmdline[0]) {
            _FDT(fdt_setprop_string(fdt, chosen, "bootargs",
                                    machine->kernel_cmdline));
        }

        if (spapr->initrd_size) {
            _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
                                  spapr->initrd_base));
            _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-end",
                                  spapr->initrd_base + spapr->initrd_size));
        }

        if (spapr->kernel_size) {
            uint64_t kprop[2] = { cpu_to_be64(spapr->kernel_addr),
                                  cpu_to_be64(spapr->kernel_size) };

            _FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel",
                         &kprop, sizeof(kprop)));
            if (spapr->kernel_le) {
                _FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel-le", NULL, 0));
            }
        }
        if (machine->boot_config.has_menu && machine->boot_config.menu) {
            _FDT((fdt_setprop_cell(fdt, chosen, "qemu,boot-menu", true)));
        }
        _FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-width", graphic_width));
        _FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-height", graphic_height));
        _FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-depth", graphic_depth));

        if (cb && bootlist) {
            int i;

            for (i = 0; i < cb; i++) {
                if (bootlist[i] == '\n') {
                    bootlist[i] = ' ';
                }
            }
            _FDT(fdt_setprop_string(fdt, chosen, "qemu,boot-list", bootlist));
        }

        if (boot_device && strlen(boot_device)) {
            _FDT(fdt_setprop_string(fdt, chosen, "qemu,boot-device", boot_device));
        }

        if (spapr->want_stdout_path && stdout_path) {
            /*
             * "linux,stdout-path" and "stdout" properties are
             * deprecated by linux kernel. New platforms should only
             * use the "stdout-path" property. Set the new property
             * and continue using older property to remain compatible
             * with the existing firmware.
             */
            _FDT(fdt_setprop_string(fdt, chosen, "linux,stdout-path", stdout_path));
            _FDT(fdt_setprop_string(fdt, chosen, "stdout-path", stdout_path));
        }

        /*
         * We can deal with BAR reallocation just fine, advertise it
         * to the guest
         */
        if (smc->linux_pci_probe) {
            _FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0));
        }

        spapr_dt_ov5_platform_support(spapr, fdt, chosen);
    }

    _FDT(fdt_setprop(fdt, chosen, "rng-seed", spapr->fdt_rng_seed, 32));

    _FDT(spapr_dt_ovec(fdt, chosen, spapr->ov5_cas, "ibm,architecture-vec-5"));
}

static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
{
    /* The /hypervisor node isn't in PAPR - this is a hack to allow PR
     * KVM to work under pHyp with some guest co-operation */
    int hypervisor;
    uint8_t hypercall[16];

    _FDT(hypervisor = fdt_add_subnode(fdt, 0, "hypervisor"));
    /* indicate KVM hypercall interface */
    _FDT(fdt_setprop_string(fdt, hypervisor, "compatible", "linux,kvm"));
    if (kvmppc_has_cap_fixup_hcalls()) {
        /*
         * Older KVM versions with older guest kernels were broken
         * with the magic page, don't allow the guest to map it.
         */
        if (!kvmppc_get_hypercall(cpu_env(first_cpu), hypercall,
                                  sizeof(hypercall))) {
            _FDT(fdt_setprop(fdt, hypervisor, "hcall-instructions",
                             hypercall, sizeof(hypercall)));
        }
    }
}

void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
{
    MachineState *machine = MACHINE(spapr);
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
    uint32_t root_drc_type_mask = 0;
    int ret;
    void *fdt;
    SpaprPhbState *phb;
    char *buf;

    fdt = g_malloc0(space);
    _FDT((fdt_create_empty_tree(fdt, space)));

    /* Root node */
    _FDT(fdt_setprop_string(fdt, 0, "device_type", "chrp"));
    _FDT(fdt_setprop_string(fdt, 0, "model", "IBM pSeries (emulated by qemu)"));
    _FDT(fdt_setprop_string(fdt, 0, "compatible", "qemu,pseries"));

    /* Guest UUID & Name*/
    buf = qemu_uuid_unparse_strdup(&qemu_uuid);
    _FDT(fdt_setprop_string(fdt, 0, "vm,uuid", buf));
    if (qemu_uuid_set) {
        _FDT(fdt_setprop_string(fdt, 0, "system-id", buf));
    }
    g_free(buf);

    if (qemu_get_vm_name()) {
        _FDT(fdt_setprop_string(fdt, 0, "ibm,partition-name",
                                qemu_get_vm_name()));
    }

    /* Host Model & Serial Number */
    if (spapr->host_model) {
        _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
    } else if (smc->broken_host_serial_model && kvmppc_get_host_model(&buf)) {
        _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
        g_free(buf);
    }

    if (spapr->host_serial) {
        _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
    } else if (smc->broken_host_serial_model && kvmppc_get_host_serial(&buf)) {
        _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
        g_free(buf);
    }

    _FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2));
    _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));

    /* /interrupt controller */
    spapr_irq_dt(spapr, spapr_max_server_number(spapr), fdt, PHANDLE_INTC);

    ret = spapr_dt_memory(spapr, fdt);
    if (ret < 0) {
        error_report("couldn't setup memory nodes in fdt");
        exit(1);
    }

    /* /vdevice */
    spapr_dt_vdevice(spapr->vio_bus, fdt);

    if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL)) {
        ret = spapr_dt_rng(fdt);
        if (ret < 0) {
            error_report("could not set up rng device in the fdt");
            exit(1);
        }
    }

    QLIST_FOREACH(phb, &spapr->phbs, list) {
        ret = spapr_dt_phb(spapr, phb, PHANDLE_INTC, fdt, NULL);
        if (ret < 0) {
            error_report("couldn't setup PCI devices in fdt");
            exit(1);
        }
    }

    spapr_dt_cpus(fdt, spapr);

    /* ibm,drc-indexes and friends */
    root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_LMB;
    if (smc->dr_phb_enabled) {
        root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PHB;
    }
    if (mc->nvdimm_supported) {
        root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PMEM;
    }
    if (root_drc_type_mask) {
        _FDT(spapr_dt_drc(fdt, 0, NULL, root_drc_type_mask));
    }

    if (mc->has_hotpluggable_cpus) {
        int offset = fdt_path_offset(fdt, "/cpus");
        ret = spapr_dt_drc(fdt, offset, NULL, SPAPR_DR_CONNECTOR_TYPE_CPU);
        if (ret < 0) {
            error_report("Couldn't set up CPU DR device tree properties");
            exit(1);
        }
    }

    /* /event-sources */
    spapr_dt_events(spapr, fdt);

    /* /rtas */
    spapr_dt_rtas(spapr, fdt);

    /* /chosen */
    spapr_dt_chosen(spapr, fdt, reset);

    /* /hypervisor */
    if (kvm_enabled()) {
        spapr_dt_hypervisor(spapr, fdt);
    }

    /* Build memory reserve map */
    if (reset) {
        if (spapr->kernel_size) {
            _FDT((fdt_add_mem_rsv(fdt, spapr->kernel_addr,
                                  spapr->kernel_size)));
        }
        if (spapr->initrd_size) {
            _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base,
                                  spapr->initrd_size)));
        }
    }

    /* NVDIMM devices */
    if (mc->nvdimm_supported) {
        spapr_dt_persistent_memory(spapr, fdt);
    }

    return fdt;
}

static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
{
    SpaprMachineState *spapr = opaque;

    return (addr & 0x0fffffff) + spapr->kernel_addr;
}

static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp,
                                    PowerPCCPU *cpu)
{
    CPUPPCState *env = &cpu->env;

    /* The TCG path should also be holding the BQL at this point */
    g_assert(bql_locked());

    g_assert(!vhyp_cpu_in_nested(cpu));

    if (FIELD_EX64(env->msr, MSR, PR)) {
        hcall_dprintf("Hypercall made with MSR[PR]=1\n");
        env->gpr[3] = H_PRIVILEGE;
    } else {
        env->gpr[3] = spapr_hypercall(cpu, env->gpr[3], &env->gpr[4]);
    }
}

struct LPCRSyncState {
    target_ulong value;
    target_ulong mask;
};

static void do_lpcr_sync(CPUState *cs, run_on_cpu_data arg)
{
    struct LPCRSyncState *s = arg.host_ptr;
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    target_ulong lpcr;

    cpu_synchronize_state(cs);
    lpcr = env->spr[SPR_LPCR];
    lpcr &= ~s->mask;
    lpcr |= s->value;
    ppc_store_lpcr(cpu, lpcr);
}

void spapr_set_all_lpcrs(target_ulong value, target_ulong mask)
{
    CPUState *cs;
    struct LPCRSyncState s = {
        .value = value,
        .mask = mask
    };
    CPU_FOREACH(cs) {
        run_on_cpu(cs, do_lpcr_sync, RUN_ON_CPU_HOST_PTR(&s));
    }
}

/* May be used when the machine is not running */
void spapr_init_all_lpcrs(target_ulong value, target_ulong mask)
{
    CPUState *cs;
    CPU_FOREACH(cs) {
        PowerPCCPU *cpu = POWERPC_CPU(cs);
        CPUPPCState *env = &cpu->env;
        target_ulong lpcr;

        lpcr = env->spr[SPR_LPCR];
        lpcr &= ~(LPCR_HR | LPCR_UPRT);
        ppc_store_lpcr(cpu, lpcr);
    }
}

static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
                           target_ulong lpid, ppc_v3_pate_t *entry)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    if (!spapr_cpu->in_nested) {
        assert(lpid == 0);

        /* Copy PATE1:GR into PATE0:HR */
        entry->dw0 = spapr->patb_entry & PATE0_HR;
        entry->dw1 = spapr->patb_entry;
        return true;
    } else {
        if (spapr_nested_api(spapr) == NESTED_API_KVM_HV) {
            return spapr_get_pate_nested_hv(spapr, cpu, lpid, entry);
        } else if (spapr_nested_api(spapr) == NESTED_API_PAPR) {
            return spapr_get_pate_nested_papr(spapr, cpu, lpid, entry);
        } else {
            g_assert_not_reached();
        }
    }
}

#define HPTE(_table, _i)   (void *)(((uint64_t *)(_table)) + ((_i) * 2))
#define HPTE_VALID(_hpte)  (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID)
#define HPTE_DIRTY(_hpte)  (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY)
#define CLEAN_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY))
#define DIRTY_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY))

/*
 * Get the fd to access the kernel htab, re-opening it if necessary
 */
static int get_htab_fd(SpaprMachineState *spapr)
{
    Error *local_err = NULL;

    if (spapr->htab_fd >= 0) {
        return spapr->htab_fd;
    }

    spapr->htab_fd = kvmppc_get_htab_fd(false, 0, &local_err);
    if (spapr->htab_fd < 0) {
        error_report_err(local_err);
    }

    return spapr->htab_fd;
}

void close_htab_fd(SpaprMachineState *spapr)
{
    if (spapr->htab_fd >= 0) {
        close(spapr->htab_fd);
    }
    spapr->htab_fd = -1;
}

static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);

    return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1;
}

static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);

    assert(kvm_enabled());

    if (!spapr->htab) {
        return 0;
    }

    return (target_ulong)(uintptr_t)spapr->htab | (spapr->htab_shift - 18);
}

static const ppc_hash_pte64_t *spapr_map_hptes(PPCVirtualHypervisor *vhyp,
                                                hwaddr ptex, int n)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
    hwaddr pte_offset = ptex * HASH_PTE_SIZE_64;

    if (!spapr->htab) {
        /*
         * HTAB is controlled by KVM. Fetch into temporary buffer
         */
        ppc_hash_pte64_t *hptes = g_malloc(n * HASH_PTE_SIZE_64);
        kvmppc_read_hptes(hptes, ptex, n);
        return hptes;
    }

    /*
     * HTAB is controlled by QEMU. Just point to the internally
     * accessible PTEG.
     */
    return (const ppc_hash_pte64_t *)(spapr->htab + pte_offset);
}

static void spapr_unmap_hptes(PPCVirtualHypervisor *vhyp,
                              const ppc_hash_pte64_t *hptes,
                              hwaddr ptex, int n)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);

    if (!spapr->htab) {
        g_free((void *)hptes);
    }

    /* Nothing to do for qemu managed HPT */
}

void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
                      uint64_t pte0, uint64_t pte1)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(cpu->vhyp);
    hwaddr offset = ptex * HASH_PTE_SIZE_64;

    if (!spapr->htab) {
        kvmppc_write_hpte(ptex, pte0, pte1);
    } else {
        if (pte0 & HPTE64_V_VALID) {
            stq_p(spapr->htab + offset + HPTE64_DW1, pte1);
            /*
             * When setting valid, we write PTE1 first. This ensures
             * proper synchronization with the reading code in
             * ppc_hash64_pteg_search()
             */
            smp_wmb();
            stq_p(spapr->htab + offset, pte0);
        } else {
            stq_p(spapr->htab + offset, pte0);
            /*
             * When clearing it we set PTE0 first. This ensures proper
             * synchronization with the reading code in
             * ppc_hash64_pteg_search()
             */
            smp_wmb();
            stq_p(spapr->htab + offset + HPTE64_DW1, pte1);
        }
    }
}

static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex,
                             uint64_t pte1)
{
    hwaddr offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_C;
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);

    if (!spapr->htab) {
        /* There should always be a hash table when this is called */
        error_report("spapr_hpte_set_c called with no hash table !");
        return;
    }

    /* The HW performs a non-atomic byte update */
    stb_p(spapr->htab + offset, (pte1 & 0xff) | 0x80);
}

static void spapr_hpte_set_r(PPCVirtualHypervisor *vhyp, hwaddr ptex,
                             uint64_t pte1)
{
    hwaddr offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_R;
    SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);

    if (!spapr->htab) {
        /* There should always be a hash table when this is called */
        error_report("spapr_hpte_set_r called with no hash table !");
        return;
    }

    /* The HW performs a non-atomic byte update */
    stb_p(spapr->htab + offset, ((pte1 >> 8) & 0xff) | 0x01);
}

int spapr_hpt_shift_for_ramsize(uint64_t ramsize)
{
    int shift;

    /* We aim for a hash table of size 1/128 the size of RAM (rounded
     * up).  The PAPR recommendation is actually 1/64 of RAM size, but
     * that's much more than is needed for Linux guests */
    shift = ctz64(pow2ceil(ramsize)) - 7;
    shift = MAX(shift, 18); /* Minimum architected size */
    shift = MIN(shift, 46); /* Maximum architected size */
    return shift;
}

void spapr_free_hpt(SpaprMachineState *spapr)
{
    qemu_vfree(spapr->htab);
    spapr->htab = NULL;
    spapr->htab_shift = 0;
    close_htab_fd(spapr);
}

int spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp)
{
    ERRP_GUARD();
    long rc;

    /* Clean up any HPT info from a previous boot */
    spapr_free_hpt(spapr);

    rc = kvmppc_reset_htab(shift);

    if (rc == -EOPNOTSUPP) {
        error_setg(errp, "HPT not supported in nested guests");
        return -EOPNOTSUPP;
    }

    if (rc < 0) {
        /* kernel-side HPT needed, but couldn't allocate one */
        error_setg_errno(errp, errno, "Failed to allocate KVM HPT of order %d",
                         shift);
        error_append_hint(errp, "Try smaller maxmem?\n");
        return -errno;
    } else if (rc > 0) {
        /* kernel-side HPT allocated */
        if (rc != shift) {
            error_setg(errp,
                       "Requested order %d HPT, but kernel allocated order %ld",
                       shift, rc);
            error_append_hint(errp, "Try smaller maxmem?\n");
            return -ENOSPC;
        }

        spapr->htab_shift = shift;
        spapr->htab = NULL;
    } else {
        /* kernel-side HPT not needed, allocate in userspace instead */
        size_t size = 1ULL << shift;
        int i;

        spapr->htab = qemu_memalign(size, size);
        memset(spapr->htab, 0, size);
        spapr->htab_shift = shift;

        for (i = 0; i < size / HASH_PTE_SIZE_64; i++) {
            DIRTY_HPTE(HPTE(spapr->htab, i));
        }
    }
    /* We're setting up a hash table, so that means we're not radix */
    spapr->patb_entry = 0;
    spapr_init_all_lpcrs(0, LPCR_HR | LPCR_UPRT);
    return 0;
}

void spapr_setup_hpt(SpaprMachineState *spapr)
{
    int hpt_shift;

    if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) {
        hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size);
    } else {
        uint64_t current_ram_size;

        current_ram_size = MACHINE(spapr)->ram_size + get_plugged_memory_size();
        hpt_shift = spapr_hpt_shift_for_ramsize(current_ram_size);
    }
    spapr_reallocate_hpt(spapr, hpt_shift, &error_fatal);

    if (kvm_enabled()) {
        hwaddr vrma_limit = kvmppc_vrma_limit(spapr->htab_shift);

        /* Check our RMA fits in the possible VRMA */
        if (vrma_limit < spapr->rma_size) {
            error_report("Unable to create %" HWADDR_PRIu
                         "MiB RMA (VRMA only allows %" HWADDR_PRIu "MiB",
                         spapr->rma_size / MiB, vrma_limit / MiB);
            exit(EXIT_FAILURE);
        }
    }
}

void spapr_check_mmu_mode(bool guest_radix)
{
    if (guest_radix) {
        if (kvm_enabled() && !kvmppc_has_cap_mmu_radix()) {
            error_report("Guest requested unavailable MMU mode (radix).");
            exit(EXIT_FAILURE);
        }
    } else {
        if (kvm_enabled() && kvmppc_has_cap_mmu_radix()
            && !kvmppc_has_cap_mmu_hash_v3()) {
            error_report("Guest requested unavailable MMU mode (hash).");
            exit(EXIT_FAILURE);
        }
    }
}

static void spapr_machine_reset(MachineState *machine, ResetType type)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(machine);
    PowerPCCPU *first_ppc_cpu;
    hwaddr fdt_addr;
    void *fdt;
    int rc;

    if (type != RESET_TYPE_SNAPSHOT_LOAD) {
        /*
         * Record-replay snapshot load must not consume random, this was
         * already replayed from initial machine reset.
         */
        qemu_guest_getrandom_nofail(spapr->fdt_rng_seed, 32);
    }

    if (machine->cgs) {
        confidential_guest_kvm_reset(machine->cgs, &error_fatal);
    }
    spapr_caps_apply(spapr);
    spapr_nested_reset(spapr);

    first_ppc_cpu = POWERPC_CPU(first_cpu);
    if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
        ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
                              spapr->max_compat_pvr)) {
        /*
         * If using KVM with radix mode available, VCPUs can be started
         * without a HPT because KVM will start them in radix mode.
         * Set the GR bit in PATE so that we know there is no HPT.
         */
        spapr->patb_entry = PATE1_GR;
        spapr_set_all_lpcrs(LPCR_HR | LPCR_UPRT, LPCR_HR | LPCR_UPRT);
    } else {
        spapr_setup_hpt(spapr);
    }

    qemu_devices_reset(type);

    spapr_ovec_cleanup(spapr->ov5_cas);
    spapr->ov5_cas = spapr_ovec_new();

    ppc_init_compat_all(spapr->max_compat_pvr, &error_fatal);

    /*
     * This is fixing some of the default configuration of the XIVE
     * devices. To be called after the reset of the machine devices.
     */
    spapr_irq_reset(spapr, &error_fatal);

    /*
     * There is no CAS under qtest. Simulate one to please the code that
     * depends on spapr->ov5_cas. This is especially needed to test device
     * unplug, so we do that before resetting the DRCs.
     */
    if (qtest_enabled()) {
        spapr_ovec_cleanup(spapr->ov5_cas);
        spapr->ov5_cas = spapr_ovec_clone(spapr->ov5);
    }

    spapr_nvdimm_finish_flushes();

    /* DRC reset may cause a device to be unplugged. This will cause troubles
     * if this device is used by another device (eg, a running vhost backend
     * will crash QEMU if the DIMM holding the vring goes away). To avoid such
     * situations, we reset DRCs after all devices have been reset.
     */
    spapr_drc_reset_all(spapr);

    spapr_clear_pending_events(spapr);

    /*
     * We place the device tree just below either the top of the RMA,
     * or just below 2GB, whichever is lower, so that it can be
     * processed with 32-bit real mode code if necessary
     */
    fdt_addr = MIN(spapr->rma_size, FDT_MAX_ADDR) - FDT_MAX_SIZE;

    fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE);
    if (spapr->vof) {
        spapr_vof_reset(spapr, fdt, &error_fatal);
        /*
         * Do not pack the FDT as the client may change properties.
         * VOF client does not expect the FDT so we do not load it to the VM.
         */
    } else {
        rc = fdt_pack(fdt);
        /* Should only fail if we've built a corrupted tree */
        assert(rc == 0);

        spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT,
                                  0, fdt_addr, 0);
        cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
    }
    qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));

    g_free(spapr->fdt_blob);
    spapr->fdt_size = fdt_totalsize(fdt);
    spapr->fdt_initial_size = spapr->fdt_size;
    spapr->fdt_blob = fdt;

    /* Set machine->fdt for 'dumpdtb' QMP/HMP command */
    machine->fdt = fdt;

    /* Set up the entry state */
    first_ppc_cpu->env.gpr[5] = 0;

    spapr->fwnmi_system_reset_addr = -1;
    spapr->fwnmi_machine_check_addr = -1;
    spapr->fwnmi_machine_check_interlock = -1;

    /* Signal all vCPUs waiting on this condition */
    qemu_cond_broadcast(&spapr->fwnmi_machine_check_interlock_cond);

    migrate_del_blocker(&spapr->fwnmi_migration_blocker);
}

static void spapr_create_nvram(SpaprMachineState *spapr)
{
    DeviceState *dev = qdev_new("spapr-nvram");
    DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);

    if (dinfo) {
        qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(dinfo),
                                &error_fatal);
    }

    qdev_realize_and_unref(dev, &spapr->vio_bus->bus, &error_fatal);

    spapr->nvram = (struct SpaprNvram *)dev;
}

static void spapr_rtc_create(SpaprMachineState *spapr)
{
    object_initialize_child_with_props(OBJECT(spapr), "rtc", &spapr->rtc,
                                       sizeof(spapr->rtc), TYPE_SPAPR_RTC,
                                       &error_fatal, NULL);
    qdev_realize(DEVICE(&spapr->rtc), NULL, &error_fatal);
    object_property_add_alias(OBJECT(spapr), "rtc-time", OBJECT(&spapr->rtc),
                              "date");
}

/* Returns whether we want to use VGA or not */
static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
{
    vga_interface_created = true;
    switch (vga_interface_type) {
    case VGA_NONE:
        return false;
    case VGA_DEVICE:
        return true;
    case VGA_STD:
    case VGA_VIRTIO:
    case VGA_CIRRUS:
        return pci_vga_init(pci_bus) != NULL;
    default:
        error_setg(errp,
                   "Unsupported VGA mode, only -vga std or -vga virtio is supported");
        return false;
    }
}

static int spapr_pre_load(void *opaque)
{
    int rc;

    rc = spapr_caps_pre_load(opaque);
    if (rc) {
        return rc;
    }

    return 0;
}

static int spapr_post_load(void *opaque, int version_id)
{
    SpaprMachineState *spapr = (SpaprMachineState *)opaque;
    int err = 0;

    err = spapr_caps_post_migration(spapr);
    if (err) {
        return err;
    }

    /*
     * In earlier versions, there was no separate qdev for the PAPR
     * RTC, so the RTC offset was stored directly in sPAPREnvironment.
     * So when migrating from those versions, poke the incoming offset
     * value into the RTC device
     */
    if (version_id < 3) {
        err = spapr_rtc_import_offset(&spapr->rtc, spapr->rtc_offset);
        if (err) {
            return err;
        }
    }

    if (kvm_enabled() && spapr->patb_entry) {
        PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
        bool radix = !!(spapr->patb_entry & PATE1_GR);
        bool gtse = !!(cpu->env.spr[SPR_LPCR] & LPCR_GTSE);

        /*
         * Update LPCR:HR and UPRT as they may not be set properly in
         * the stream
         */
        spapr_set_all_lpcrs(radix ? (LPCR_HR | LPCR_UPRT) : 0,
                            LPCR_HR | LPCR_UPRT);

        err = kvmppc_configure_v3_mmu(cpu, radix, gtse, spapr->patb_entry);
        if (err) {
            error_report("Process table config unsupported by the host");
            return -EINVAL;
        }
    }

    err = spapr_irq_post_load(spapr, version_id);
    if (err) {
        return err;
    }

    return err;
}

static int spapr_pre_save(void *opaque)
{
    int rc;

    rc = spapr_caps_pre_save(opaque);
    if (rc) {
        return rc;
    }

    return 0;
}

static bool version_before_3(void *opaque, int version_id)
{
    return version_id < 3;
}

static bool spapr_pending_events_needed(void *opaque)
{
    SpaprMachineState *spapr = (SpaprMachineState *)opaque;
    return !QTAILQ_EMPTY(&spapr->pending_events);
}

static const VMStateDescription vmstate_spapr_event_entry = {
    .name = "spapr_event_log_entry",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32(summary, SpaprEventLogEntry),
        VMSTATE_UINT32(extended_length, SpaprEventLogEntry),
        VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, SpaprEventLogEntry, 0,
                                     NULL, extended_length),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_spapr_pending_events = {
    .name = "spapr_pending_events",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_pending_events_needed,
    .fields = (const VMStateField[]) {
        VMSTATE_QTAILQ_V(pending_events, SpaprMachineState, 1,
                         vmstate_spapr_event_entry, SpaprEventLogEntry, next),
        VMSTATE_END_OF_LIST()
    },
};

static bool spapr_ov5_cas_needed(void *opaque)
{
    SpaprMachineState *spapr = opaque;
    SpaprOptionVector *ov5_mask = spapr_ovec_new();
    bool cas_needed;

    /* Prior to the introduction of SpaprOptionVector, we had two option
     * vectors we dealt with: OV5_FORM1_AFFINITY, and OV5_DRCONF_MEMORY.
     * Both of these options encode machine topology into the device-tree
     * in such a way that the now-booted OS should still be able to interact
     * appropriately with QEMU regardless of what options were actually
     * negotiatied on the source side.
     *
     * As such, we can avoid migrating the CAS-negotiated options if these
     * are the only options available on the current machine/platform.
     * Since these are the only options available for pseries-2.7 and
     * earlier, this allows us to maintain old->new/new->old migration
     * compatibility.
     *
     * For QEMU 2.8+, there are additional CAS-negotiatable options available
     * via default pseries-2.8 machines and explicit command-line parameters.
     * Some of these options, like OV5_HP_EVT, *do* require QEMU to be aware
     * of the actual CAS-negotiated values to continue working properly. For
     * example, availability of memory unplug depends on knowing whether
     * OV5_HP_EVT was negotiated via CAS.
     *
     * Thus, for any cases where the set of available CAS-negotiatable
     * options extends beyond OV5_FORM1_AFFINITY and OV5_DRCONF_MEMORY, we
     * include the CAS-negotiated options in the migration stream, unless
     * if they affect boot time behaviour only.
     */
    spapr_ovec_set(ov5_mask, OV5_FORM1_AFFINITY);
    spapr_ovec_set(ov5_mask, OV5_DRCONF_MEMORY);
    spapr_ovec_set(ov5_mask, OV5_DRMEM_V2);

    /* We need extra information if we have any bits outside the mask
     * defined above */
    cas_needed = !spapr_ovec_subset(spapr->ov5, ov5_mask);

    spapr_ovec_cleanup(ov5_mask);

    return cas_needed;
}

static const VMStateDescription vmstate_spapr_ov5_cas = {
    .name = "spapr_option_vector_ov5_cas",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_ov5_cas_needed,
    .fields = (const VMStateField[]) {
        VMSTATE_STRUCT_POINTER_V(ov5_cas, SpaprMachineState, 1,
                                 vmstate_spapr_ovec, SpaprOptionVector),
        VMSTATE_END_OF_LIST()
    },
};

static bool spapr_patb_entry_needed(void *opaque)
{
    SpaprMachineState *spapr = opaque;

    return !!spapr->patb_entry;
}

static const VMStateDescription vmstate_spapr_patb_entry = {
    .name = "spapr_patb_entry",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_patb_entry_needed,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT64(patb_entry, SpaprMachineState),
        VMSTATE_END_OF_LIST()
    },
};

static bool spapr_irq_map_needed(void *opaque)
{
    SpaprMachineState *spapr = opaque;

    return spapr->irq_map && !bitmap_empty(spapr->irq_map, spapr->irq_map_nr);
}

static const VMStateDescription vmstate_spapr_irq_map = {
    .name = "spapr_irq_map",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_irq_map_needed,
    .fields = (const VMStateField[]) {
        VMSTATE_BITMAP(irq_map, SpaprMachineState, 0, irq_map_nr),
        VMSTATE_END_OF_LIST()
    },
};

static bool spapr_dtb_needed(void *opaque)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);

    return smc->update_dt_enabled;
}

static int spapr_dtb_pre_load(void *opaque)
{
    SpaprMachineState *spapr = (SpaprMachineState *)opaque;

    g_free(spapr->fdt_blob);
    spapr->fdt_blob = NULL;
    spapr->fdt_size = 0;

    return 0;
}

static const VMStateDescription vmstate_spapr_dtb = {
    .name = "spapr_dtb",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_dtb_needed,
    .pre_load = spapr_dtb_pre_load,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32(fdt_initial_size, SpaprMachineState),
        VMSTATE_UINT32(fdt_size, SpaprMachineState),
        VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, SpaprMachineState, 0, NULL,
                                     fdt_size),
        VMSTATE_END_OF_LIST()
    },
};

static bool spapr_fwnmi_needed(void *opaque)
{
    SpaprMachineState *spapr = (SpaprMachineState *)opaque;

    return spapr->fwnmi_machine_check_addr != -1;
}

static int spapr_fwnmi_pre_save(void *opaque)
{
    SpaprMachineState *spapr = (SpaprMachineState *)opaque;

    /*
     * Check if machine check handling is in progress and print a
     * warning message.
     */
    if (spapr->fwnmi_machine_check_interlock != -1) {
        warn_report("A machine check is being handled during migration. The"
                "handler may run and log hardware error on the destination");
    }

    return 0;
}

static const VMStateDescription vmstate_spapr_fwnmi = {
    .name = "spapr_fwnmi",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_fwnmi_needed,
    .pre_save = spapr_fwnmi_pre_save,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT64(fwnmi_system_reset_addr, SpaprMachineState),
        VMSTATE_UINT64(fwnmi_machine_check_addr, SpaprMachineState),
        VMSTATE_INT32(fwnmi_machine_check_interlock, SpaprMachineState),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_spapr = {
    .name = "spapr",
    .version_id = 3,
    .minimum_version_id = 1,
    .pre_load = spapr_pre_load,
    .post_load = spapr_post_load,
    .pre_save = spapr_pre_save,
    .fields = (const VMStateField[]) {
        /* used to be @next_irq */
        VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),

        /* RTC offset */
        VMSTATE_UINT64_TEST(rtc_offset, SpaprMachineState, version_before_3),

        VMSTATE_PPC_TIMEBASE_V(tb, SpaprMachineState, 2),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * const []) {
        &vmstate_spapr_ov5_cas,
        &vmstate_spapr_patb_entry,
        &vmstate_spapr_pending_events,
        &vmstate_spapr_cap_htm,
        &vmstate_spapr_cap_vsx,
        &vmstate_spapr_cap_dfp,
        &vmstate_spapr_cap_cfpc,
        &vmstate_spapr_cap_sbbc,
        &vmstate_spapr_cap_ibs,
        &vmstate_spapr_cap_hpt_maxpagesize,
        &vmstate_spapr_irq_map,
        &vmstate_spapr_cap_nested_kvm_hv,
        &vmstate_spapr_dtb,
        &vmstate_spapr_cap_large_decr,
        &vmstate_spapr_cap_ccf_assist,
        &vmstate_spapr_cap_fwnmi,
        &vmstate_spapr_fwnmi,
        &vmstate_spapr_cap_rpt_invalidate,
        &vmstate_spapr_cap_ail_mode_3,
        &vmstate_spapr_cap_nested_papr,
        NULL
    }
};

static int htab_save_setup(QEMUFile *f, void *opaque, Error **errp)
{
    SpaprMachineState *spapr = opaque;

    /* "Iteration" header */
    if (!spapr->htab_shift) {
        qemu_put_be32(f, -1);
    } else {
        qemu_put_be32(f, spapr->htab_shift);
    }

    if (spapr->htab) {
        spapr->htab_save_index = 0;
        spapr->htab_first_pass = true;
    } else {
        if (spapr->htab_shift) {
            assert(kvm_enabled());
        }
    }


    return 0;
}

static void htab_save_chunk(QEMUFile *f, SpaprMachineState *spapr,
                            int chunkstart, int n_valid, int n_invalid)
{
    qemu_put_be32(f, chunkstart);
    qemu_put_be16(f, n_valid);
    qemu_put_be16(f, n_invalid);
    qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
                    HASH_PTE_SIZE_64 * n_valid);
}

static void htab_save_end_marker(QEMUFile *f)
{
    qemu_put_be32(f, 0);
    qemu_put_be16(f, 0);
    qemu_put_be16(f, 0);
}

static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr,
                                 int64_t max_ns)
{
    bool has_timeout = max_ns != -1;
    int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
    int index = spapr->htab_save_index;
    int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);

    assert(spapr->htab_first_pass);

    do {
        int chunkstart;

        /* Consume invalid HPTEs */
        while ((index < htabslots)
               && !HPTE_VALID(HPTE(spapr->htab, index))) {
            CLEAN_HPTE(HPTE(spapr->htab, index));
            index++;
        }

        /* Consume valid HPTEs */
        chunkstart = index;
        while ((index < htabslots) && (index - chunkstart < USHRT_MAX)
               && HPTE_VALID(HPTE(spapr->htab, index))) {
            CLEAN_HPTE(HPTE(spapr->htab, index));
            index++;
        }

        if (index > chunkstart) {
            int n_valid = index - chunkstart;

            htab_save_chunk(f, spapr, chunkstart, n_valid, 0);

            if (has_timeout &&
                (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
                break;
            }
        }
    } while ((index < htabslots) && !migration_rate_exceeded(f));

    if (index >= htabslots) {
        assert(index == htabslots);
        index = 0;
        spapr->htab_first_pass = false;
    }
    spapr->htab_save_index = index;
}

static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr,
                                int64_t max_ns)
{
    bool final = max_ns < 0;
    int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
    int examined = 0, sent = 0;
    int index = spapr->htab_save_index;
    int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);

    assert(!spapr->htab_first_pass);

    do {
        int chunkstart, invalidstart;

        /* Consume non-dirty HPTEs */
        while ((index < htabslots)
               && !HPTE_DIRTY(HPTE(spapr->htab, index))) {
            index++;
            examined++;
        }

        chunkstart = index;
        /* Consume valid dirty HPTEs */
        while ((index < htabslots) && (index - chunkstart < USHRT_MAX)
               && HPTE_DIRTY(HPTE(spapr->htab, index))
               && HPTE_VALID(HPTE(spapr->htab, index))) {
            CLEAN_HPTE(HPTE(spapr->htab, index));
            index++;
            examined++;
        }

        invalidstart = index;
        /* Consume invalid dirty HPTEs */
        while ((index < htabslots) && (index - invalidstart < USHRT_MAX)
               && HPTE_DIRTY(HPTE(spapr->htab, index))
               && !HPTE_VALID(HPTE(spapr->htab, index))) {
            CLEAN_HPTE(HPTE(spapr->htab, index));
            index++;
            examined++;
        }

        if (index > chunkstart) {
            int n_valid = invalidstart - chunkstart;
            int n_invalid = index - invalidstart;

            htab_save_chunk(f, spapr, chunkstart, n_valid, n_invalid);
            sent += index - chunkstart;

            if (!final && (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
                break;
            }
        }

        if (examined >= htabslots) {
            break;
        }

        if (index >= htabslots) {
            assert(index == htabslots);
            index = 0;
        }
    } while ((examined < htabslots) && (!migration_rate_exceeded(f) || final));

    if (index >= htabslots) {
        assert(index == htabslots);
        index = 0;
    }

    spapr->htab_save_index = index;

    return (examined >= htabslots) && (sent == 0) ? 1 : 0;
}

#define MAX_ITERATION_NS    5000000 /* 5 ms */
#define MAX_KVM_BUF_SIZE    2048

static int htab_save_iterate(QEMUFile *f, void *opaque)
{
    SpaprMachineState *spapr = opaque;
    int fd;
    int rc = 0;

    /* Iteration header */
    if (!spapr->htab_shift) {
        qemu_put_be32(f, -1);
        return 1;
    } else {
        qemu_put_be32(f, 0);
    }

    if (!spapr->htab) {
        assert(kvm_enabled());

        fd = get_htab_fd(spapr);
        if (fd < 0) {
            return fd;
        }

        rc = kvmppc_save_htab(f, fd, MAX_KVM_BUF_SIZE, MAX_ITERATION_NS);
        if (rc < 0) {
            return rc;
        }
    } else  if (spapr->htab_first_pass) {
        htab_save_first_pass(f, spapr, MAX_ITERATION_NS);
    } else {
        rc = htab_save_later_pass(f, spapr, MAX_ITERATION_NS);
    }

    htab_save_end_marker(f);

    return rc;
}

static int htab_save_complete(QEMUFile *f, void *opaque)
{
    SpaprMachineState *spapr = opaque;
    int fd;

    /* Iteration header */
    if (!spapr->htab_shift) {
        qemu_put_be32(f, -1);
        return 0;
    } else {
        qemu_put_be32(f, 0);
    }

    if (!spapr->htab) {
        int rc;

        assert(kvm_enabled());

        fd = get_htab_fd(spapr);
        if (fd < 0) {
            return fd;
        }

        rc = kvmppc_save_htab(f, fd, MAX_KVM_BUF_SIZE, -1);
        if (rc < 0) {
            return rc;
        }
    } else {
        if (spapr->htab_first_pass) {
            htab_save_first_pass(f, spapr, -1);
        }
        htab_save_later_pass(f, spapr, -1);
    }

    /* End marker */
    htab_save_end_marker(f);

    return 0;
}

static int htab_load(QEMUFile *f, void *opaque, int version_id)
{
    SpaprMachineState *spapr = opaque;
    uint32_t section_hdr;
    int fd = -1;
    Error *local_err = NULL;

    if (version_id < 1 || version_id > 1) {
        error_report("htab_load() bad version");
        return -EINVAL;
    }

    section_hdr = qemu_get_be32(f);

    if (section_hdr == -1) {
        spapr_free_hpt(spapr);
        return 0;
    }

    if (section_hdr) {
        int ret;

        /* First section gives the htab size */
        ret = spapr_reallocate_hpt(spapr, section_hdr, &local_err);
        if (ret < 0) {
            error_report_err(local_err);
            return ret;
        }
        return 0;
    }

    if (!spapr->htab) {
        assert(kvm_enabled());

        fd = kvmppc_get_htab_fd(true, 0, &local_err);
        if (fd < 0) {
            error_report_err(local_err);
            return fd;
        }
    }

    while (true) {
        uint32_t index;
        uint16_t n_valid, n_invalid;

        index = qemu_get_be32(f);
        n_valid = qemu_get_be16(f);
        n_invalid = qemu_get_be16(f);

        if ((index == 0) && (n_valid == 0) && (n_invalid == 0)) {
            /* End of Stream */
            break;
        }

        if ((index + n_valid + n_invalid) >
            (HTAB_SIZE(spapr) / HASH_PTE_SIZE_64)) {
            /* Bad index in stream */
            error_report(
                "htab_load() bad index %d (%hd+%hd entries) in htab stream (htab_shift=%d)",
                index, n_valid, n_invalid, spapr->htab_shift);
            return -EINVAL;
        }

        if (spapr->htab) {
            if (n_valid) {
                qemu_get_buffer(f, HPTE(spapr->htab, index),
                                HASH_PTE_SIZE_64 * n_valid);
            }
            if (n_invalid) {
                memset(HPTE(spapr->htab, index + n_valid), 0,
                       HASH_PTE_SIZE_64 * n_invalid);
            }
        } else {
            int rc;

            assert(fd >= 0);

            rc = kvmppc_load_htab_chunk(f, fd, index, n_valid, n_invalid,
                                        &local_err);
            if (rc < 0) {
                error_report_err(local_err);
                return rc;
            }
        }
    }

    if (!spapr->htab) {
        assert(fd >= 0);
        close(fd);
    }

    return 0;
}

static void htab_save_cleanup(void *opaque)
{
    SpaprMachineState *spapr = opaque;

    close_htab_fd(spapr);
}

static SaveVMHandlers savevm_htab_handlers = {
    .save_setup = htab_save_setup,
    .save_live_iterate = htab_save_iterate,
    .save_live_complete_precopy = htab_save_complete,
    .save_cleanup = htab_save_cleanup,
    .load_state = htab_load,
};

static void spapr_boot_set(void *opaque, const char *boot_device,
                           Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(opaque);

    g_free(spapr->boot_device);
    spapr->boot_device = g_strdup(boot_device);
}

static void spapr_create_lmb_dr_connectors(SpaprMachineState *spapr)
{
    MachineState *machine = MACHINE(spapr);
    uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
    uint32_t nr_lmbs = (machine->maxram_size - machine->ram_size)/lmb_size;
    int i;

    g_assert(!nr_lmbs || machine->device_memory);
    for (i = 0; i < nr_lmbs; i++) {
        uint64_t addr;

        addr = i * lmb_size + machine->device_memory->base;
        spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_LMB,
                               addr / lmb_size);
    }
}

/*
 * If RAM size, maxmem size and individual node mem sizes aren't aligned
 * to SPAPR_MEMORY_BLOCK_SIZE(256MB), then refuse to start the guest
 * since we can't support such unaligned sizes with DRCONF_MEMORY.
 */
static void spapr_validate_node_memory(MachineState *machine, Error **errp)
{
    int i;

    if (machine->ram_size % SPAPR_MEMORY_BLOCK_SIZE) {
        error_setg(errp, "Memory size 0x" RAM_ADDR_FMT
                   " is not aligned to %" PRIu64 " MiB",
                   machine->ram_size,
                   SPAPR_MEMORY_BLOCK_SIZE / MiB);
        return;
    }

    if (machine->maxram_size % SPAPR_MEMORY_BLOCK_SIZE) {
        error_setg(errp, "Maximum memory size 0x" RAM_ADDR_FMT
                   " is not aligned to %" PRIu64 " MiB",
                   machine->ram_size,
                   SPAPR_MEMORY_BLOCK_SIZE / MiB);
        return;
    }

    for (i = 0; i < machine->numa_state->num_nodes; i++) {
        if (machine->numa_state->nodes[i].node_mem % SPAPR_MEMORY_BLOCK_SIZE) {
            error_setg(errp,
                       "Node %d memory size 0x%" PRIx64
                       " is not aligned to %" PRIu64 " MiB",
                       i, machine->numa_state->nodes[i].node_mem,
                       SPAPR_MEMORY_BLOCK_SIZE / MiB);
            return;
        }
    }
}

/* find cpu slot in machine->possible_cpus by core_id */
static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)
{
    int index = id / ms->smp.threads;

    if (index >= ms->possible_cpus->len) {
        return NULL;
    }
    if (idx) {
        *idx = index;
    }
    return &ms->possible_cpus->cpus[index];
}

static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp)
{
    MachineState *ms = MACHINE(spapr);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    Error *local_err = NULL;
    bool vsmt_user = !!spapr->vsmt;
    int kvm_smt = kvmppc_smt_threads();
    int ret;
    unsigned int smp_threads = ms->smp.threads;

    if (tcg_enabled()) {
        if (smp_threads > 1 &&
            !ppc_type_check_compat(ms->cpu_type, CPU_POWERPC_LOGICAL_2_07, 0,
                                   spapr->max_compat_pvr)) {
            error_setg(errp, "TCG only supports SMT on POWER8 or newer CPUs");
            return;
        }

        if (smp_threads > 8) {
            error_setg(errp, "TCG cannot support more than 8 threads/core "
                       "on a pseries machine");
            return;
        }
    }
    if (!is_power_of_2(smp_threads)) {
        error_setg(errp, "Cannot support %d threads/core on a pseries "
                   "machine because it must be a power of 2", smp_threads);
        return;
    }

    /* Determine the VSMT mode to use: */
    if (vsmt_user) {
        if (spapr->vsmt < smp_threads) {
            error_setg(errp, "Cannot support VSMT mode %d"
                       " because it must be >= threads/core (%d)",
                       spapr->vsmt, smp_threads);
            return;
        }
        /* In this case, spapr->vsmt has been set by the command line */
    } else if (!smc->smp_threads_vsmt) {
        /*
         * Default VSMT value is tricky, because we need it to be as
         * consistent as possible (for migration), but this requires
         * changing it for at least some existing cases.  We pick 8 as
         * the value that we'd get with KVM on POWER8, the
         * overwhelmingly common case in production systems.
         */
        spapr->vsmt = MAX(8, smp_threads);
    } else {
        spapr->vsmt = smp_threads;
    }

    /* KVM: If necessary, set the SMT mode: */
    if (kvm_enabled() && (spapr->vsmt != kvm_smt)) {
        ret = kvmppc_set_smt_threads(spapr->vsmt);
        if (ret) {
            /* Looks like KVM isn't able to change VSMT mode */
            error_setg(&local_err,
                       "Failed to set KVM's VSMT mode to %d (errno %d)",
                       spapr->vsmt, ret);
            /* We can live with that if the default one is big enough
             * for the number of threads, and a submultiple of the one
             * we want.  In this case we'll waste some vcpu ids, but
             * behaviour will be correct */
            if ((kvm_smt >= smp_threads) && ((spapr->vsmt % kvm_smt) == 0)) {
                warn_report_err(local_err);
            } else {
                if (!vsmt_user) {
                    error_append_hint(&local_err,
                                      "On PPC, a VM with %d threads/core"
                                      " on a host with %d threads/core"
                                      " requires the use of VSMT mode %d.\n",
                                      smp_threads, kvm_smt, spapr->vsmt);
                }
                kvmppc_error_append_smt_possible_hint(&local_err);
                error_propagate(errp, local_err);
            }
        }
    }
    /* else TCG: nothing to do currently */
}

static void spapr_init_cpus(SpaprMachineState *spapr)
{
    MachineState *machine = MACHINE(spapr);
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    const char *type = spapr_get_cpu_core_type(machine->cpu_type);
    const CPUArchIdList *possible_cpus;
    unsigned int smp_cpus = machine->smp.cpus;
    unsigned int smp_threads = machine->smp.threads;
    unsigned int max_cpus = machine->smp.max_cpus;
    int boot_cores_nr = smp_cpus / smp_threads;
    int i;

    possible_cpus = mc->possible_cpu_arch_ids(machine);
    if (mc->has_hotpluggable_cpus) {
        if (smp_cpus % smp_threads) {
            error_report("smp_cpus (%u) must be multiple of threads (%u)",
                         smp_cpus, smp_threads);
            exit(1);
        }
        if (max_cpus % smp_threads) {
            error_report("max_cpus (%u) must be multiple of threads (%u)",
                         max_cpus, smp_threads);
            exit(1);
        }
    } else {
        if (max_cpus != smp_cpus) {
            error_report("This machine version does not support CPU hotplug");
            exit(1);
        }
        boot_cores_nr = possible_cpus->len;
    }

    for (i = 0; i < possible_cpus->len; i++) {
        int core_id = i * smp_threads;

        if (mc->has_hotpluggable_cpus) {
            spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU,
                                   spapr_vcpu_id(spapr, core_id));
        }

        if (i < boot_cores_nr) {
            Object *core  = object_new(type);
            int nr_threads = smp_threads;

            /* Handle the partially filled core for older machine types */
            if ((i + 1) * smp_threads >= smp_cpus) {
                nr_threads = smp_cpus - i * smp_threads;
            }

            object_property_set_int(core, "nr-threads", nr_threads,
                                    &error_fatal);
            object_property_set_int(core, CPU_CORE_PROP_CORE_ID, core_id,
                                    &error_fatal);
            qdev_realize(DEVICE(core), NULL, &error_fatal);

            object_unref(core);
        }
    }
}

static PCIHostState *spapr_create_default_phb(void)
{
    DeviceState *dev;

    dev = qdev_new(TYPE_SPAPR_PCI_HOST_BRIDGE);
    qdev_prop_set_uint32(dev, "index", 0);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    return PCI_HOST_BRIDGE(dev);
}

static hwaddr spapr_rma_size(SpaprMachineState *spapr, Error **errp)
{
    MachineState *machine = MACHINE(spapr);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    hwaddr rma_size = machine->ram_size;
    hwaddr node0_size = spapr_node0_size(machine);

    /* RMA has to fit in the first NUMA node */
    rma_size = MIN(rma_size, node0_size);

    /*
     * VRMA access is via a special 1TiB SLB mapping, so the RMA can
     * never exceed that
     */
    rma_size = MIN(rma_size, 1 * TiB);

    /*
     * Clamp the RMA size based on machine type.  This is for
     * migration compatibility with older qemu versions, which limited
     * the RMA size for complicated and mostly bad reasons.
     */
    if (smc->rma_limit) {
        rma_size = MIN(rma_size, smc->rma_limit);
    }

    if (rma_size < MIN_RMA_SLOF) {
        error_setg(errp,
                   "pSeries SLOF firmware requires >= %" HWADDR_PRIx
                   "ldMiB guest RMA (Real Mode Area memory)",
                   MIN_RMA_SLOF / MiB);
        return 0;
    }

    return rma_size;
}

static void spapr_create_nvdimm_dr_connectors(SpaprMachineState *spapr)
{
    MachineState *machine = MACHINE(spapr);
    int i;

    for (i = 0; i < machine->ram_slots; i++) {
        spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_PMEM, i);
    }
}

/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(machine);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    const char *bios_default = spapr->vof ? FW_FILE_NAME_VOF : FW_FILE_NAME;
    const char *bios_name = machine->firmware ?: bios_default;
    g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    const char *kernel_filename = machine->kernel_filename;
    const char *initrd_filename = machine->initrd_filename;
    PCIHostState *phb;
    bool has_vga;
    int i;
    MemoryRegion *sysmem = get_system_memory();
    long load_limit, fw_size;
    Error *resize_hpt_err = NULL;
    NICInfo *nd;

    if (!filename) {
        error_report("Could not find LPAR firmware '%s'", bios_name);
        exit(1);
    }
    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
    if (fw_size <= 0) {
        error_report("Could not load LPAR firmware '%s'", filename);
        exit(1);
    }

    /*
     * if Secure VM (PEF) support is configured, then initialize it
     */
    if (machine->cgs) {
        confidential_guest_kvm_init(machine->cgs, &error_fatal);
    }

    msi_nonbroken = true;

    QLIST_INIT(&spapr->phbs);
    QTAILQ_INIT(&spapr->pending_dimm_unplugs);

    /* Determine capabilities to run with */
    spapr_caps_init(spapr);

    kvmppc_check_papr_resize_hpt(&resize_hpt_err);
    if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) {
        /*
         * If the user explicitly requested a mode we should either
         * supply it, or fail completely (which we do below).  But if
         * it's not set explicitly, we reset our mode to something
         * that works
         */
        if (resize_hpt_err) {
            spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED;
            error_free(resize_hpt_err);
            resize_hpt_err = NULL;
        } else {
            spapr->resize_hpt = smc->resize_hpt_default;
        }
    }

    assert(spapr->resize_hpt != SPAPR_RESIZE_HPT_DEFAULT);

    if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && resize_hpt_err) {
        /*
         * User requested HPT resize, but this host can't supply it.  Bail out
         */
        error_report_err(resize_hpt_err);
        exit(1);
    }
    error_free(resize_hpt_err);

    spapr->rma_size = spapr_rma_size(spapr, &error_fatal);

    /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
    load_limit = MIN(spapr->rma_size, FDT_MAX_ADDR) - FW_OVERHEAD;

    /*
     * VSMT must be set in order to be able to compute VCPU ids, ie to
     * call spapr_max_server_number() or spapr_vcpu_id().
     */
    spapr_set_vsmt_mode(spapr, &error_fatal);

    /* Set up Interrupt Controller before we create the VCPUs */
    spapr_irq_init(spapr, &error_fatal);

    /* Set up containers for ibm,client-architecture-support negotiated options
     */
    spapr->ov5 = spapr_ovec_new();
    spapr->ov5_cas = spapr_ovec_new();

    spapr_ovec_set(spapr->ov5, OV5_DRCONF_MEMORY);
    spapr_validate_node_memory(machine, &error_fatal);

    spapr_ovec_set(spapr->ov5, OV5_FORM1_AFFINITY);

    /* Do not advertise FORM2 NUMA support for pseries-6.1 and older */
    if (!smc->pre_6_2_numa_affinity) {
        spapr_ovec_set(spapr->ov5, OV5_FORM2_AFFINITY);
    }

    /* advertise support for dedicated HP event source to guests */
    if (spapr->use_hotplug_event_source) {
        spapr_ovec_set(spapr->ov5, OV5_HP_EVT);
    }

    /* advertise support for HPT resizing */
    if (spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) {
        spapr_ovec_set(spapr->ov5, OV5_HPT_RESIZE);
    }

    /* advertise support for ibm,dyamic-memory-v2 */
    spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);

    /* advertise XIVE on POWER9 machines */
    if (spapr->irq->xive) {
        spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
    }

    /* init CPUs */
    spapr_init_cpus(spapr);

    /* Init numa_assoc_array */
    spapr_numa_associativity_init(spapr, machine);

    if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) &&
        ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
                              spapr->max_compat_pvr)) {
        spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_300);
        /* KVM and TCG always allow GTSE with radix... */
        spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_GTSE);
    }
    /* ... but not with hash (currently). */

    if (kvm_enabled()) {
        /* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */
        kvmppc_enable_logical_ci_hcalls();
        kvmppc_enable_set_mode_hcall();

        /* H_CLEAR_MOD/_REF are mandatory in PAPR, but off by default */
        kvmppc_enable_clear_ref_mod_hcalls();

        /* Enable H_PAGE_INIT */
        kvmppc_enable_h_page_init();
    }

    /* map RAM */
    memory_region_add_subregion(sysmem, 0, machine->ram);

    /* initialize hotplug memory address space */
    if (machine->ram_size < machine->maxram_size) {
        ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size;
        hwaddr device_mem_base;

        /*
         * Limit the number of hotpluggable memory slots to half the number
         * slots that KVM supports, leaving the other half for PCI and other
         * devices. However ensure that number of slots doesn't drop below 32.
         */
        int max_memslots = kvm_enabled() ? kvm_get_max_memslots() / 2 :
                           SPAPR_MAX_RAM_SLOTS;

        if (max_memslots < SPAPR_MAX_RAM_SLOTS) {
            max_memslots = SPAPR_MAX_RAM_SLOTS;
        }
        if (machine->ram_slots > max_memslots) {
            error_report("Specified number of memory slots %"
                         PRIu64" exceeds max supported %d",
                         machine->ram_slots, max_memslots);
            exit(1);
        }

        device_mem_base = ROUND_UP(machine->ram_size, SPAPR_DEVICE_MEM_ALIGN);
        machine_memory_devices_init(machine, device_mem_base, device_mem_size);
    }

    spapr_create_lmb_dr_connectors(spapr);

    if (mc->nvdimm_supported) {
        spapr_create_nvdimm_dr_connectors(spapr);
    }

    /* Set up RTAS event infrastructure */
    spapr_events_init(spapr);

    /* Set up the RTC RTAS interfaces */
    spapr_rtc_create(spapr);

    /* Set up VIO bus */
    spapr->vio_bus = spapr_vio_bus_init();

    for (i = 0; serial_hd(i); i++) {
        spapr_vty_create(spapr->vio_bus, serial_hd(i));
    }

    /* We always have at least the nvram device on VIO */
    spapr_create_nvram(spapr);

    /*
     * Setup hotplug / dynamic-reconfiguration connectors. top-level
     * connectors (described in root DT node's "ibm,drc-types" property)
     * are pre-initialized here. additional child connectors (such as
     * connectors for a PHBs PCI slots) are added as needed during their
     * parent's realization.
     */
    if (smc->dr_phb_enabled) {
        for (i = 0; i < SPAPR_MAX_PHBS; i++) {
            spapr_dr_connector_new(OBJECT(machine), TYPE_SPAPR_DRC_PHB, i);
        }
    }

    /* Set up PCI */
    spapr_pci_rtas_init();

    phb = spapr_create_default_phb();

    while ((nd = qemu_find_nic_info("spapr-vlan", true, "ibmveth"))) {
        spapr_vlan_create(spapr->vio_bus, nd);
    }

    pci_init_nic_devices(phb->bus, NULL);

    for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {
        spapr_vscsi_create(spapr->vio_bus);
    }

    /* Graphics */
    has_vga = spapr_vga_init(phb->bus, &error_fatal);
    if (has_vga) {
        spapr->want_stdout_path = !machine->enable_graphics;
        machine->usb |= defaults_enabled() && !machine->usb_disabled;
    } else {
        spapr->want_stdout_path = true;
    }

    if (machine->usb) {
        pci_create_simple(phb->bus, -1, "nec-usb-xhci");

        if (has_vga) {
            USBBus *usb_bus;

            usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS,
                                                              &error_abort));
            usb_create_simple(usb_bus, "usb-kbd");
            usb_create_simple(usb_bus, "usb-mouse");
        }
    }

    if (kernel_filename) {
        uint64_t loaded_addr = 0;

        spapr->kernel_size = load_elf(kernel_filename, NULL,
                                      translate_kernel_address, spapr,
                                      NULL, &loaded_addr, NULL, NULL, 1,
                                      PPC_ELF_MACHINE, 0, 0);
        if (spapr->kernel_size == ELF_LOAD_WRONG_ENDIAN) {
            spapr->kernel_size = load_elf(kernel_filename, NULL,
                                          translate_kernel_address, spapr,
                                          NULL, &loaded_addr, NULL, NULL, 0,
                                          PPC_ELF_MACHINE, 0, 0);
            spapr->kernel_le = spapr->kernel_size > 0;
        }
        if (spapr->kernel_size < 0) {
            error_report("error loading %s: %s", kernel_filename,
                         load_elf_strerror(spapr->kernel_size));
            exit(1);
        }

        if (spapr->kernel_addr != loaded_addr) {
            warn_report("spapr: kernel_addr changed from 0x%"PRIx64
                        " to 0x%"PRIx64,
                        spapr->kernel_addr, loaded_addr);
            spapr->kernel_addr = loaded_addr;
        }

        /* load initrd */
        if (initrd_filename) {
            /* Try to locate the initrd in the gap between the kernel
             * and the firmware. Add a bit of space just in case
             */
            spapr->initrd_base = (spapr->kernel_addr + spapr->kernel_size
                                  + 0x1ffff) & ~0xffff;
            spapr->initrd_size = load_image_targphys(initrd_filename,
                                                     spapr->initrd_base,
                                                     load_limit
                                                     - spapr->initrd_base);
            if (spapr->initrd_size < 0) {
                error_report("could not load initial ram disk '%s'",
                             initrd_filename);
                exit(1);
            }
        }
    }

    /* FIXME: Should register things through the MachineState's qdev
     * interface, this is a legacy from the sPAPREnvironment structure
     * which predated MachineState but had a similar function */
    vmstate_register(NULL, 0, &vmstate_spapr, spapr);
    register_savevm_live("spapr/htab", VMSTATE_INSTANCE_ID_ANY, 1,
                         &savevm_htab_handlers, spapr);

    qbus_set_hotplug_handler(sysbus_get_default(), OBJECT(machine));

    qemu_register_boot_set(spapr_boot_set, spapr);

    /*
     * Nothing needs to be done to resume a suspended guest because
     * suspending does not change the machine state, so no need for
     * a ->wakeup method.
     */
    qemu_register_wakeup_support();

    if (kvm_enabled()) {
        /* to stop and start vmclock */
        qemu_add_vm_change_state_handler(cpu_ppc_clock_vm_state_change,
                                         &spapr->tb);

        kvmppc_spapr_enable_inkernel_multitce();
    }

    qemu_cond_init(&spapr->fwnmi_machine_check_interlock_cond);
    if (spapr->vof) {
        spapr->vof->fw_size = fw_size; /* for claim() on itself */
        spapr_register_hypercall(KVMPPC_H_VOF_CLIENT, spapr_h_vof_client);
    }

    spapr_watchdog_init(spapr);
}

#define DEFAULT_KVM_TYPE "auto"
static int spapr_kvm_type(MachineState *machine, const char *vm_type)
{
    /*
     * The use of g_ascii_strcasecmp() for 'hv' and 'pr' is to
     * accommodate the 'HV' and 'PV' formats that exists in the
     * wild. The 'auto' mode is being introduced already as
     * lower-case, thus we don't need to bother checking for
     * "AUTO".
     */
    if (!vm_type || !strcmp(vm_type, DEFAULT_KVM_TYPE)) {
        return 0;
    }

    if (!g_ascii_strcasecmp(vm_type, "hv")) {
        return 1;
    }

    if (!g_ascii_strcasecmp(vm_type, "pr")) {
        return 2;
    }

    error_report("Unknown kvm-type specified '%s'", vm_type);
    return -1;
}

/*
 * Implementation of an interface to adjust firmware path
 * for the bootindex property handling.
 */
static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
                                   DeviceState *dev)
{
#define CAST(type, obj, name) \
    ((type *)object_dynamic_cast(OBJECT(obj), (name)))
    SCSIDevice *d = CAST(SCSIDevice,  dev, TYPE_SCSI_DEVICE);
    SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
    VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
    PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);

    if (d && bus) {
        void *spapr = CAST(void, bus->parent, "spapr-vscsi");
        VirtIOSCSI *virtio = CAST(VirtIOSCSI, bus->parent, TYPE_VIRTIO_SCSI);
        USBDevice *usb = CAST(USBDevice, bus->parent, TYPE_USB_DEVICE);

        if (spapr) {
            /*
             * Replace "channel@0/disk@0,0" with "disk@8000000000000000":
             * In the top 16 bits of the 64-bit LUN, we use SRP luns of the form
             * 0x8000 | (target << 8) | (bus << 5) | lun
             * (see the "Logical unit addressing format" table in SAM5)
             */
            unsigned id = 0x8000 | (d->id << 8) | (d->channel << 5) | d->lun;
            return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
                                   (uint64_t)id << 48);
        } else if (virtio) {
            /*
             * We use SRP luns of the form 01000000 | (target << 8) | lun
             * in the top 32 bits of the 64-bit LUN
             * Note: the quote above is from SLOF and it is wrong,
             * the actual binding is:
             * swap 0100 or 10 << or 20 << ( target lun-id -- srplun )
             */
            unsigned id = 0x1000000 | (d->id << 16) | d->lun;
            if (d->lun >= 256) {
                /* Use the LUN "flat space addressing method" */
                id |= 0x4000;
            }
            return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
                                   (uint64_t)id << 32);
        } else if (usb) {
            /*
             * We use SRP luns of the form 01000000 | (usb-port << 16) | lun
             * in the top 32 bits of the 64-bit LUN
             */
            unsigned usb_port = atoi(usb->port->path);
            unsigned id = 0x1000000 | (usb_port << 16) | d->lun;
            return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
                                   (uint64_t)id << 32);
        }
    }

    /*
     * SLOF probes the USB devices, and if it recognizes that the device is a
     * storage device, it changes its name to "storage" instead of "usb-host",
     * and additionally adds a child node for the SCSI LUN, so the correct
     * boot path in SLOF is something like .../storage@1/disk@xxx" instead.
     */
    if (strcmp("usb-host", qdev_fw_name(dev)) == 0) {
        USBDevice *usbdev = CAST(USBDevice, dev, TYPE_USB_DEVICE);
        if (usb_device_is_scsi_storage(usbdev)) {
            return g_strdup_printf("storage@%s/disk", usbdev->port->path);
        }
    }

    if (phb) {
        /* Replace "pci" with "pci@800000020000000" */
        return g_strdup_printf("pci@%"PRIX64, phb->buid);
    }

    if (vsc) {
        /* Same logic as virtio above */
        unsigned id = 0x1000000 | (vsc->target << 16) | vsc->lun;
        return g_strdup_printf("disk@%"PRIX64, (uint64_t)id << 32);
    }

    if (g_str_equal("pci-bridge", qdev_fw_name(dev))) {
        /* SLOF uses "pci" instead of "pci-bridge" for PCI bridges */
        PCIDevice *pdev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
        return g_strdup_printf("pci@%x", PCI_SLOT(pdev->devfn));
    }

    if (pcidev) {
        return spapr_pci_fw_dev_name(pcidev);
    }

    return NULL;
}

static char *spapr_get_kvm_type(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    return g_strdup(spapr->kvm_type);
}

static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    g_free(spapr->kvm_type);
    spapr->kvm_type = g_strdup(value);
}

static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    return spapr->use_hotplug_event_source;
}

static void spapr_set_modern_hotplug_events(Object *obj, bool value,
                                            Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    spapr->use_hotplug_event_source = value;
}

static bool spapr_get_msix_emulation(Object *obj, Error **errp)
{
    return true;
}

static char *spapr_get_resize_hpt(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    switch (spapr->resize_hpt) {
    case SPAPR_RESIZE_HPT_DEFAULT:
        return g_strdup("default");
    case SPAPR_RESIZE_HPT_DISABLED:
        return g_strdup("disabled");
    case SPAPR_RESIZE_HPT_ENABLED:
        return g_strdup("enabled");
    case SPAPR_RESIZE_HPT_REQUIRED:
        return g_strdup("required");
    }
    g_assert_not_reached();
}

static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    if (strcmp(value, "default") == 0) {
        spapr->resize_hpt = SPAPR_RESIZE_HPT_DEFAULT;
    } else if (strcmp(value, "disabled") == 0) {
        spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED;
    } else if (strcmp(value, "enabled") == 0) {
        spapr->resize_hpt = SPAPR_RESIZE_HPT_ENABLED;
    } else if (strcmp(value, "required") == 0) {
        spapr->resize_hpt = SPAPR_RESIZE_HPT_REQUIRED;
    } else {
        error_setg(errp, "Bad value for \"resize-hpt\" property");
    }
}

static bool spapr_get_vof(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    return spapr->vof != NULL;
}

static void spapr_set_vof(Object *obj, bool value, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    if (spapr->vof) {
        vof_cleanup(spapr->vof);
        g_free(spapr->vof);
        spapr->vof = NULL;
    }
    if (!value) {
        return;
    }
    spapr->vof = g_malloc0(sizeof(*spapr->vof));
}

static char *spapr_get_ic_mode(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    if (spapr->irq == &spapr_irq_xics_legacy) {
        return g_strdup("legacy");
    } else if (spapr->irq == &spapr_irq_xics) {
        return g_strdup("xics");
    } else if (spapr->irq == &spapr_irq_xive) {
        return g_strdup("xive");
    } else if (spapr->irq == &spapr_irq_dual) {
        return g_strdup("dual");
    }
    g_assert_not_reached();
}

static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
        error_setg(errp, "This machine only uses the legacy XICS backend, don't pass ic-mode");
        return;
    }

    /* The legacy IRQ backend can not be set */
    if (strcmp(value, "xics") == 0) {
        spapr->irq = &spapr_irq_xics;
    } else if (strcmp(value, "xive") == 0) {
        spapr->irq = &spapr_irq_xive;
    } else if (strcmp(value, "dual") == 0) {
        spapr->irq = &spapr_irq_dual;
    } else {
        error_setg(errp, "Bad value for \"ic-mode\" property");
    }
}

static char *spapr_get_host_model(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    return g_strdup(spapr->host_model);
}

static void spapr_set_host_model(Object *obj, const char *value, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    g_free(spapr->host_model);
    spapr->host_model = g_strdup(value);
}

static char *spapr_get_host_serial(Object *obj, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    return g_strdup(spapr->host_serial);
}

static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    g_free(spapr->host_serial);
    spapr->host_serial = g_strdup(value);
}

static void spapr_instance_init(Object *obj)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    MachineState *ms = MACHINE(spapr);
    MachineClass *mc = MACHINE_GET_CLASS(ms);

    /*
     * NVDIMM support went live in 5.1 without considering that, in
     * other archs, the user needs to enable NVDIMM support with the
     * 'nvdimm' machine option and the default behavior is NVDIMM
     * support disabled. It is too late to roll back to the standard
     * behavior without breaking 5.1 guests.
     */
    if (mc->nvdimm_supported) {
        ms->nvdimms_state->is_enabled = true;
    }

    spapr->htab_fd = -1;
    spapr->use_hotplug_event_source = true;
    spapr->kvm_type = g_strdup(DEFAULT_KVM_TYPE);
    object_property_add_str(obj, "kvm-type",
                            spapr_get_kvm_type, spapr_set_kvm_type);
    object_property_set_description(obj, "kvm-type",
                                    "Specifies the KVM virtualization mode (auto,"
                                    " hv, pr). Defaults to 'auto'. This mode will use"
                                    " any available KVM module loaded in the host,"
                                    " where kvm_hv takes precedence if both kvm_hv and"
                                    " kvm_pr are loaded.");
    object_property_add_bool(obj, "modern-hotplug-events",
                            spapr_get_modern_hotplug_events,
                            spapr_set_modern_hotplug_events);
    object_property_set_description(obj, "modern-hotplug-events",
                                    "Use dedicated hotplug event mechanism in"
                                    " place of standard EPOW events when possible"
                                    " (required for memory hot-unplug support)");
    ppc_compat_add_property(obj, "max-cpu-compat", &spapr->max_compat_pvr,
                            "Maximum permitted CPU compatibility mode");

    object_property_add_str(obj, "resize-hpt",
                            spapr_get_resize_hpt, spapr_set_resize_hpt);
    object_property_set_description(obj, "resize-hpt",
                                    "Resizing of the Hash Page Table (enabled, disabled, required)");
    object_property_add_uint32_ptr(obj, "vsmt",
                                   &spapr->vsmt, OBJ_PROP_FLAG_READWRITE);
    object_property_set_description(obj, "vsmt",
                                    "Virtual SMT: KVM behaves as if this were"
                                    " the host's SMT mode");

    object_property_add_bool(obj, "vfio-no-msix-emulation",
                             spapr_get_msix_emulation, NULL);

    object_property_add_uint64_ptr(obj, "kernel-addr",
                                   &spapr->kernel_addr, OBJ_PROP_FLAG_READWRITE);
    object_property_set_description(obj, "kernel-addr",
                                    stringify(KERNEL_LOAD_ADDR)
                                    " for -kernel is the default");
    spapr->kernel_addr = KERNEL_LOAD_ADDR;

    object_property_add_bool(obj, "x-vof", spapr_get_vof, spapr_set_vof);
    object_property_set_description(obj, "x-vof",
                                    "Enable Virtual Open Firmware (experimental)");

    /* The machine class defines the default interrupt controller mode */
    spapr->irq = smc->irq;
    object_property_add_str(obj, "ic-mode", spapr_get_ic_mode,
                            spapr_set_ic_mode);
    object_property_set_description(obj, "ic-mode",
                 "Specifies the interrupt controller mode (xics, xive, dual)");

    object_property_add_str(obj, "host-model",
        spapr_get_host_model, spapr_set_host_model);
    object_property_set_description(obj, "host-model",
        "Host model to advertise in guest device tree");
    object_property_add_str(obj, "host-serial",
        spapr_get_host_serial, spapr_set_host_serial);
    object_property_set_description(obj, "host-serial",
        "Host serial number to advertise in guest device tree");
}

static void spapr_machine_finalizefn(Object *obj)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    g_free(spapr->kvm_type);
}

void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    CPUPPCState *env = cpu_env(cs);

    cpu_synchronize_state(cs);
    /* If FWNMI is inactive, addr will be -1, which will deliver to 0x100 */
    if (spapr->fwnmi_system_reset_addr != -1) {
        uint64_t rtas_addr, addr;

        /* get rtas addr from fdt */
        rtas_addr = spapr_get_rtas_addr();
        if (!rtas_addr) {
            qemu_system_guest_panicked(NULL);
            return;
        }

        addr = rtas_addr + RTAS_ERROR_LOG_MAX + cs->cpu_index * sizeof(uint64_t)*2;
        stq_be_phys(&address_space_memory, addr, env->gpr[3]);
        stq_be_phys(&address_space_memory, addr + sizeof(uint64_t), 0);
        env->gpr[3] = addr;
    }
    ppc_cpu_do_system_reset(cs);
    if (spapr->fwnmi_system_reset_addr != -1) {
        env->nip = spapr->fwnmi_system_reset_addr;
    }
}

static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
{
    CPUState *cs;

    CPU_FOREACH(cs) {
        async_run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
    }
}

int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
                          void *fdt, int *fdt_start_offset, Error **errp)
{
    uint64_t addr;
    uint32_t node;

    addr = spapr_drc_index(drc) * SPAPR_MEMORY_BLOCK_SIZE;
    node = object_property_get_uint(OBJECT(drc->dev), PC_DIMM_NODE_PROP,
                                    &error_abort);
    *fdt_start_offset = spapr_dt_memory_node(spapr, fdt, node, addr,
                                             SPAPR_MEMORY_BLOCK_SIZE);
    return 0;
}

static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
                           bool dedicated_hp_event_source)
{
    SpaprDrc *drc;
    uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;
    int i;
    uint64_t addr = addr_start;
    bool hotplugged = spapr_drc_hotplugged(dev);

    for (i = 0; i < nr_lmbs; i++) {
        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
                              addr / SPAPR_MEMORY_BLOCK_SIZE);
        g_assert(drc);

        /*
         * memory_device_get_free_addr() provided a range of free addresses
         * that doesn't overlap with any existing mapping at pre-plug. The
         * corresponding LMB DRCs are thus assumed to be all attachable.
         */
        spapr_drc_attach(drc, dev);
        if (!hotplugged) {
            spapr_drc_reset(drc);
        }
        addr += SPAPR_MEMORY_BLOCK_SIZE;
    }
    /* send hotplug notification to the
     * guest only in case of hotplugged memory
     */
    if (hotplugged) {
        if (dedicated_hp_event_source) {
            drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
                                  addr_start / SPAPR_MEMORY_BLOCK_SIZE);
            g_assert(drc);
            spapr_hotplug_req_add_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
                                                   nr_lmbs,
                                                   spapr_drc_index(drc));
        } else {
            spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB,
                                           nr_lmbs);
        }
    }
}

static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev);
    PCDIMMDevice *dimm = PC_DIMM(dev);
    uint64_t size, addr;
    int64_t slot;
    bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);

    size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort);

    pc_dimm_plug(dimm, MACHINE(ms));

    if (!is_nvdimm) {
        addr = object_property_get_uint(OBJECT(dimm),
                                        PC_DIMM_ADDR_PROP, &error_abort);
        spapr_add_lmbs(dev, addr, size,
                       spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT));
    } else {
        slot = object_property_get_int(OBJECT(dimm),
                                       PC_DIMM_SLOT_PROP, &error_abort);
        /* We should have valid slot number at this point */
        g_assert(slot >= 0);
        spapr_add_nvdimm(dev, slot);
    }
}

static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
                                  Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
    bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
    PCDIMMDevice *dimm = PC_DIMM(dev);
    Error *local_err = NULL;
    uint64_t size;
    Object *memdev;
    hwaddr pagesize;

    size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    if (is_nvdimm) {
        if (!spapr_nvdimm_validate(hotplug_dev, NVDIMM(dev), size, errp)) {
            return;
        }
    } else if (size % SPAPR_MEMORY_BLOCK_SIZE) {
        error_setg(errp, "Hotplugged memory size must be a multiple of "
                   "%" PRIu64 " MB", SPAPR_MEMORY_BLOCK_SIZE / MiB);
        return;
    }

    memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP,
                                      &error_abort);
    pagesize = host_memory_backend_pagesize(MEMORY_BACKEND(memdev));
    if (!spapr_check_pagesize(spapr, pagesize, errp)) {
        return;
    }

    pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), errp);
}

struct SpaprDimmState {
    PCDIMMDevice *dimm;
    uint32_t nr_lmbs;
    QTAILQ_ENTRY(SpaprDimmState) next;
};

static SpaprDimmState *spapr_pending_dimm_unplugs_find(SpaprMachineState *s,
                                                       PCDIMMDevice *dimm)
{
    SpaprDimmState *dimm_state = NULL;

    QTAILQ_FOREACH(dimm_state, &s->pending_dimm_unplugs, next) {
        if (dimm_state->dimm == dimm) {
            break;
        }
    }
    return dimm_state;
}

static SpaprDimmState *spapr_pending_dimm_unplugs_add(SpaprMachineState *spapr,
                                                      uint32_t nr_lmbs,
                                                      PCDIMMDevice *dimm)
{
    SpaprDimmState *ds = NULL;

    /*
     * If this request is for a DIMM whose removal had failed earlier
     * (due to guest's refusal to remove the LMBs), we would have this
     * dimm already in the pending_dimm_unplugs list. In that
     * case don't add again.
     */
    ds = spapr_pending_dimm_unplugs_find(spapr, dimm);
    if (!ds) {
        ds = g_new0(SpaprDimmState, 1);
        ds->nr_lmbs = nr_lmbs;
        ds->dimm = dimm;
        QTAILQ_INSERT_HEAD(&spapr->pending_dimm_unplugs, ds, next);
    }
    return ds;
}

static void spapr_pending_dimm_unplugs_remove(SpaprMachineState *spapr,
                                              SpaprDimmState *dimm_state)
{
    QTAILQ_REMOVE(&spapr->pending_dimm_unplugs, dimm_state, next);
    g_free(dimm_state);
}

static SpaprDimmState *spapr_recover_pending_dimm_state(SpaprMachineState *ms,
                                                        PCDIMMDevice *dimm)
{
    SpaprDrc *drc;
    uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm),
                                                  &error_abort);
    uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
    uint32_t avail_lmbs = 0;
    uint64_t addr_start, addr;
    int i;

    addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
                                          &error_abort);

    addr = addr_start;
    for (i = 0; i < nr_lmbs; i++) {
        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
                              addr / SPAPR_MEMORY_BLOCK_SIZE);
        g_assert(drc);
        if (drc->dev) {
            avail_lmbs++;
        }
        addr += SPAPR_MEMORY_BLOCK_SIZE;
    }

    return spapr_pending_dimm_unplugs_add(ms, avail_lmbs, dimm);
}

void spapr_memory_unplug_rollback(SpaprMachineState *spapr, DeviceState *dev)
{
    SpaprDimmState *ds;
    PCDIMMDevice *dimm;
    SpaprDrc *drc;
    uint32_t nr_lmbs;
    uint64_t size, addr_start, addr;
    int i;

    if (!dev) {
        return;
    }

    dimm = PC_DIMM(dev);
    ds = spapr_pending_dimm_unplugs_find(spapr, dimm);

    /*
     * 'ds == NULL' would mean that the DIMM doesn't have a pending
     * unplug state, but one of its DRC is marked as unplug_requested.
     * This is bad and weird enough to g_assert() out.
     */
    g_assert(ds);

    spapr_pending_dimm_unplugs_remove(spapr, ds);

    size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort);
    nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;

    addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
                                          &error_abort);

    addr = addr_start;
    for (i = 0; i < nr_lmbs; i++) {
        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
                              addr / SPAPR_MEMORY_BLOCK_SIZE);
        g_assert(drc);

        drc->unplug_requested = false;
        addr += SPAPR_MEMORY_BLOCK_SIZE;
    }

    /*
     * Tell QAPI that something happened and the memory
     * hotunplug wasn't successful.
     */
    qapi_event_send_device_unplug_guest_error(dev->id,
                                              dev->canonical_path);
}

/* Callback to be called during DRC release. */
void spapr_lmb_release(DeviceState *dev)
{
    HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
    SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_ctrl);
    SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));

    /* This information will get lost if a migration occurs
     * during the unplug process. In this case recover it. */
    if (ds == NULL) {
        ds = spapr_recover_pending_dimm_state(spapr, PC_DIMM(dev));
        g_assert(ds);
        /* The DRC being examined by the caller at least must be counted */
        g_assert(ds->nr_lmbs);
    }

    if (--ds->nr_lmbs) {
        return;
    }

    /*
     * Now that all the LMBs have been removed by the guest, call the
     * unplug handler chain. This can never fail.
     */
    hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
    object_unparent(OBJECT(dev));
}

static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
    SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));

    /* We really shouldn't get this far without anything to unplug */
    g_assert(ds);

    pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
    qdev_unrealize(dev);
    spapr_pending_dimm_unplugs_remove(spapr, ds);
}

static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
                                        DeviceState *dev, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
    PCDIMMDevice *dimm = PC_DIMM(dev);
    uint32_t nr_lmbs;
    uint64_t size, addr_start, addr;
    int i;
    SpaprDrc *drc;

    if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
        error_setg(errp, "nvdimm device hot unplug is not supported yet.");
        return;
    }

    size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort);
    nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;

    addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
                                          &error_abort);

    /*
     * An existing pending dimm state for this DIMM means that there is an
     * unplug operation in progress, waiting for the spapr_lmb_release
     * callback to complete the job (BQL can't cover that far). In this case,
     * bail out to avoid detaching DRCs that were already released.
     */
    if (spapr_pending_dimm_unplugs_find(spapr, dimm)) {
        error_setg(errp, "Memory unplug already in progress for device %s",
                   dev->id);
        return;
    }

    spapr_pending_dimm_unplugs_add(spapr, nr_lmbs, dimm);

    addr = addr_start;
    for (i = 0; i < nr_lmbs; i++) {
        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
                              addr / SPAPR_MEMORY_BLOCK_SIZE);
        g_assert(drc);

        spapr_drc_unplug_request(drc);
        addr += SPAPR_MEMORY_BLOCK_SIZE;
    }

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
                          addr_start / SPAPR_MEMORY_BLOCK_SIZE);
    spapr_hotplug_req_remove_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
                                              nr_lmbs, spapr_drc_index(drc));
}

/* Callback to be called during DRC release. */
void spapr_core_release(DeviceState *dev)
{
    HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);

    /* Call the unplug handler chain. This can never fail. */
    hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
    object_unparent(OBJECT(dev));
}

static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    MachineState *ms = MACHINE(hotplug_dev);
    CPUCore *cc = CPU_CORE(dev);
    CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL);

    assert(core_slot);
    core_slot->cpu = NULL;
    qdev_unrealize(dev);
}

static
void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
                               Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
    int index;
    SpaprDrc *drc;
    CPUCore *cc = CPU_CORE(dev);

    if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) {
        error_setg(errp, "Unable to find CPU core with core-id: %d",
                   cc->core_id);
        return;
    }
    if (index == 0) {
        error_setg(errp, "Boot CPU core may not be unplugged");
        return;
    }

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU,
                          spapr_vcpu_id(spapr, cc->core_id));
    g_assert(drc);

    if (!spapr_drc_unplug_requested(drc)) {
        spapr_drc_unplug_request(drc);
    }

    /*
     * spapr_hotplug_req_remove_by_index is left unguarded, out of the
     * "!spapr_drc_unplug_requested" check, to allow for multiple IRQ
     * pulses removing the same CPU. Otherwise, in an failed hotunplug
     * attempt (e.g. the kernel will refuse to remove the last online
     * CPU), we will never attempt it again because unplug_requested
     * will still be 'true' in that case.
     */
    spapr_hotplug_req_remove_by_index(drc);
}

int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
                           void *fdt, int *fdt_start_offset, Error **errp)
{
    SpaprCpuCore *core = SPAPR_CPU_CORE(drc->dev);
    CPUState *cs = CPU(core->threads[0]);
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    DeviceClass *dc = DEVICE_GET_CLASS(cs);
    int id = spapr_get_vcpu_id(cpu);
    g_autofree char *nodename = NULL;
    int offset;

    nodename = g_strdup_printf("%s@%x", dc->fw_name, id);
    offset = fdt_add_subnode(fdt, 0, nodename);

    spapr_dt_cpu(cs, fdt, offset, spapr);

    /*
     * spapr_dt_cpu() does not fill the 'name' property in the
     * CPU node. The function is called during boot process, before
     * and after CAS, and overwriting the 'name' property written
     * by SLOF is not allowed.
     *
     * Write it manually after spapr_dt_cpu(). This makes the hotplug
     * CPUs more compatible with the coldplugged ones, which have
     * the 'name' property. Linux Kernel also relies on this
     * property to identify CPU nodes.
     */
    _FDT((fdt_setprop_string(fdt, offset, "name", nodename)));

    *fdt_start_offset = offset;
    return 0;
}

static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
    MachineClass *mc = MACHINE_GET_CLASS(spapr);
    SpaprCpuCore *core = SPAPR_CPU_CORE(OBJECT(dev));
    CPUCore *cc = CPU_CORE(dev);
    SpaprDrc *drc;
    CPUArchId *core_slot;
    int index;
    bool hotplugged = spapr_drc_hotplugged(dev);
    int i;

    core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index);
    g_assert(core_slot); /* Already checked in spapr_core_pre_plug() */

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU,
                          spapr_vcpu_id(spapr, cc->core_id));

    g_assert(drc || !mc->has_hotpluggable_cpus);

    if (drc) {
        /*
         * spapr_core_pre_plug() already buys us this is a brand new
         * core being plugged into a free slot. Nothing should already
         * be attached to the corresponding DRC.
         */
        spapr_drc_attach(drc, dev);

        if (hotplugged) {
            /*
             * Send hotplug notification interrupt to the guest only
             * in case of hotplugged CPUs.
             */
            spapr_hotplug_req_add_by_index(drc);
        } else {
            spapr_drc_reset(drc);
        }
    }

    core_slot->cpu = CPU(dev);

    /*
     * Set compatibility mode to match the boot CPU, which was either set
     * by the machine reset code or by CAS. This really shouldn't fail at
     * this point.
     */
    if (hotplugged) {
        for (i = 0; i < cc->nr_threads; i++) {
            ppc_set_compat(core->threads[i], POWERPC_CPU(first_cpu)->compat_pvr,
                           &error_abort);
        }
    }

}

static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
                                Error **errp)
{
    MachineState *machine = MACHINE(OBJECT(hotplug_dev));
    MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
    CPUCore *cc = CPU_CORE(dev);
    const char *base_core_type = spapr_get_cpu_core_type(machine->cpu_type);
    const char *type = object_get_typename(OBJECT(dev));
    CPUArchId *core_slot;
    int index;
    unsigned int smp_threads = machine->smp.threads;

    if (dev->hotplugged && !mc->has_hotpluggable_cpus) {
        error_setg(errp, "CPU hotplug not supported for this machine");
        return;
    }

    if (strcmp(base_core_type, type)) {
        error_setg(errp, "CPU core type should be %s", base_core_type);
        return;
    }

    if (cc->core_id % smp_threads) {
        error_setg(errp, "invalid core id %d", cc->core_id);
        return;
    }

    /*
     * In general we should have homogeneous threads-per-core, but old
     * (pre hotplug support) machine types allow the last core to have
     * reduced threads as a compatibility hack for when we allowed
     * total vcpus not a multiple of threads-per-core.
     */
    if (mc->has_hotpluggable_cpus && (cc->nr_threads != smp_threads)) {
        error_setg(errp, "invalid nr-threads %d, must be %d", cc->nr_threads,
                   smp_threads);
        return;
    }

    core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index);
    if (!core_slot) {
        error_setg(errp, "core id %d out of range", cc->core_id);
        return;
    }

    if (core_slot->cpu) {
        error_setg(errp, "core %d already populated", cc->core_id);
        return;
    }

    numa_cpu_pre_plug(core_slot, dev, errp);
}

int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
                          void *fdt, int *fdt_start_offset, Error **errp)
{
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(drc->dev);
    int intc_phandle;

    intc_phandle = spapr_irq_get_phandle(spapr, spapr->fdt_blob, errp);
    if (intc_phandle <= 0) {
        return -1;
    }

    if (spapr_dt_phb(spapr, sphb, intc_phandle, fdt, fdt_start_offset)) {
        error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
        return -1;
    }

    /* generally SLOF creates these, for hotplug it's up to QEMU */
    _FDT(fdt_setprop_string(fdt, *fdt_start_offset, "name", "pci"));

    return 0;
}

static bool spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
                               Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    const unsigned windows_supported = spapr_phb_windows_supported(sphb);
    SpaprDrc *drc;

    if (dev->hotplugged && !smc->dr_phb_enabled) {
        error_setg(errp, "PHB hotplug not supported for this machine");
        return false;
    }

    if (sphb->index == (uint32_t)-1) {
        error_setg(errp, "\"index\" for PAPR PHB is mandatory");
        return false;
    }

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
    if (drc && drc->dev) {
        error_setg(errp, "PHB %d already attached", sphb->index);
        return false;
    }

    /*
     * This will check that sphb->index doesn't exceed the maximum number of
     * PHBs for the current machine type.
     */
    return
        smc->phb_placement(spapr, sphb->index,
                           &sphb->buid, &sphb->io_win_addr,
                           &sphb->mem_win_addr, &sphb->mem64_win_addr,
                           windows_supported, sphb->dma_liobn,
                           errp);
}

static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
    SpaprDrc *drc;
    bool hotplugged = spapr_drc_hotplugged(dev);

    if (!smc->dr_phb_enabled) {
        return;
    }

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
    /* hotplug hooks should check it's enabled before getting this far */
    assert(drc);

    /* spapr_phb_pre_plug() already checked the DRC is attachable */
    spapr_drc_attach(drc, dev);

    if (hotplugged) {
        spapr_hotplug_req_add_by_index(drc);
    } else {
        spapr_drc_reset(drc);
    }
}

void spapr_phb_release(DeviceState *dev)
{
    HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);

    hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
    object_unparent(OBJECT(dev));
}

static void spapr_phb_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    qdev_unrealize(dev);
}

static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev,
                                     DeviceState *dev, Error **errp)
{
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
    SpaprDrc *drc;

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
    assert(drc);

    if (!spapr_drc_unplug_requested(drc)) {
        spapr_drc_unplug_request(drc);
        spapr_hotplug_req_remove_by_index(drc);
    } else {
        error_setg(errp,
                   "PCI Host Bridge unplug already in progress for device %s",
                   dev->id);
    }
}

static
bool spapr_tpm_proxy_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
                              Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));

    if (spapr->tpm_proxy != NULL) {
        error_setg(errp, "Only one TPM proxy can be specified for this machine");
        return false;
    }

    return true;
}

static void spapr_tpm_proxy_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
    SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(dev);

    /* Already checked in spapr_tpm_proxy_pre_plug() */
    g_assert(spapr->tpm_proxy == NULL);

    spapr->tpm_proxy = tpm_proxy;
}

static void spapr_tpm_proxy_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));

    qdev_unrealize(dev);
    object_unparent(OBJECT(dev));
    spapr->tpm_proxy = NULL;
}

static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
                                      DeviceState *dev, Error **errp)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        spapr_memory_plug(hotplug_dev, dev);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
        spapr_core_plug(hotplug_dev, dev);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
        spapr_phb_plug(hotplug_dev, dev);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
        spapr_tpm_proxy_plug(hotplug_dev, dev);
    }
}

static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev,
                                        DeviceState *dev, Error **errp)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        spapr_memory_unplug(hotplug_dev, dev);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
        spapr_core_unplug(hotplug_dev, dev);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
        spapr_phb_unplug(hotplug_dev, dev);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
        spapr_tpm_proxy_unplug(hotplug_dev, dev);
    }
}

bool spapr_memory_hot_unplug_supported(SpaprMachineState *spapr)
{
    return spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT) ||
        /*
         * CAS will process all pending unplug requests.
         *
         * HACK: a guest could theoretically have cleared all bits in OV5,
         * but none of the guests we care for do.
         */
        spapr_ovec_empty(spapr->ov5_cas);
}

static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
                                                DeviceState *dev, Error **errp)
{
    SpaprMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
    MachineClass *mc = MACHINE_GET_CLASS(sms);
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        if (spapr_memory_hot_unplug_supported(sms)) {
            spapr_memory_unplug_request(hotplug_dev, dev, errp);
        } else {
            error_setg(errp, "Memory hot unplug not supported for this guest");
        }
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
        if (!mc->has_hotpluggable_cpus) {
            error_setg(errp, "CPU hot unplug not supported on this machine");
            return;
        }
        spapr_core_unplug_request(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
        if (!smc->dr_phb_enabled) {
            error_setg(errp, "PHB hot unplug not supported on this machine");
            return;
        }
        spapr_phb_unplug_request(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
        spapr_tpm_proxy_unplug(hotplug_dev, dev);
    }
}

static void spapr_machine_device_pre_plug(HotplugHandler *hotplug_dev,
                                          DeviceState *dev, Error **errp)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
        spapr_memory_pre_plug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
        spapr_core_pre_plug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
        spapr_phb_pre_plug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
        spapr_tpm_proxy_pre_plug(hotplug_dev, dev, errp);
    }
}

static HotplugHandler *spapr_get_hotplug_handler(MachineState *machine,
                                                 DeviceState *dev)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
        object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE) ||
        object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE) ||
        object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
        return HOTPLUG_HANDLER(machine);
    }
    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
        PCIDevice *pcidev = PCI_DEVICE(dev);
        PCIBus *root = pci_device_root_bus(pcidev);
        SpaprPhbState *phb =
            (SpaprPhbState *)object_dynamic_cast(OBJECT(BUS(root)->parent),
                                                 TYPE_SPAPR_PCI_HOST_BRIDGE);

        if (phb) {
            return HOTPLUG_HANDLER(phb);
        }
    }
    return NULL;
}

static CpuInstanceProperties
spapr_cpu_index_to_props(MachineState *machine, unsigned cpu_index)
{
    CPUArchId *core_slot;
    MachineClass *mc = MACHINE_GET_CLASS(machine);

    /* make sure possible_cpu are initialized */
    mc->possible_cpu_arch_ids(machine);
    /* get CPU core slot containing thread that matches cpu_index */
    core_slot = spapr_find_cpu_slot(machine, cpu_index, NULL);
    assert(core_slot);
    return core_slot->props;
}

static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx)
{
    return idx / ms->smp.cores % ms->numa_state->num_nodes;
}

static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
{
    int i;
    unsigned int smp_threads = machine->smp.threads;
    unsigned int smp_cpus = machine->smp.cpus;
    const char *core_type;
    int spapr_max_cores = machine->smp.max_cpus / smp_threads;
    MachineClass *mc = MACHINE_GET_CLASS(machine);

    if (!mc->has_hotpluggable_cpus) {
        spapr_max_cores = QEMU_ALIGN_UP(smp_cpus, smp_threads) / smp_threads;
    }
    if (machine->possible_cpus) {
        assert(machine->possible_cpus->len == spapr_max_cores);
        return machine->possible_cpus;
    }

    core_type = spapr_get_cpu_core_type(machine->cpu_type);
    if (!core_type) {
        error_report("Unable to find sPAPR CPU Core definition");
        exit(1);
    }

    machine->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
                             sizeof(CPUArchId) * spapr_max_cores);
    machine->possible_cpus->len = spapr_max_cores;
    for (i = 0; i < machine->possible_cpus->len; i++) {
        int core_id = i * smp_threads;

        machine->possible_cpus->cpus[i].type = core_type;
        machine->possible_cpus->cpus[i].vcpus_count = smp_threads;
        machine->possible_cpus->cpus[i].arch_id = core_id;
        machine->possible_cpus->cpus[i].props.has_core_id = true;
        machine->possible_cpus->cpus[i].props.core_id = core_id;
    }
    return machine->possible_cpus;
}

static bool spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
                                uint64_t *buid, hwaddr *pio,
                                hwaddr *mmio32, hwaddr *mmio64,
                                unsigned n_dma, uint32_t *liobns, Error **errp)
{
    /*
     * New-style PHB window placement.
     *
     * Goals: Gives large (1TiB), naturally aligned 64-bit MMIO window
     * for each PHB, in addition to 2GiB 32-bit MMIO and 64kiB PIO
     * windows.
     *
     * Some guest kernels can't work with MMIO windows above 1<<46
     * (64TiB), so we place up to 31 PHBs in the area 32TiB..64TiB
     *
     * 32TiB..(33TiB+1984kiB) contains the 64kiB PIO windows for each
     * PHB stacked together.  (32TiB+2GiB)..(32TiB+64GiB) contains the
     * 2GiB 32-bit MMIO windows for each PHB.  Then 33..64TiB has the
     * 1TiB 64-bit MMIO windows for each PHB.
     */
    const uint64_t base_buid = 0x800000020000000ULL;
    int i;

    /* Sanity check natural alignments */
    QEMU_BUILD_BUG_ON((SPAPR_PCI_BASE % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
    QEMU_BUILD_BUG_ON((SPAPR_PCI_LIMIT % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
    QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM64_WIN_SIZE % SPAPR_PCI_MEM32_WIN_SIZE) != 0);
    QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM32_WIN_SIZE % SPAPR_PCI_IO_WIN_SIZE) != 0);
    /* Sanity check bounds */
    QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_IO_WIN_SIZE) >
                      SPAPR_PCI_MEM32_WIN_SIZE);
    QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_MEM32_WIN_SIZE) >
                      SPAPR_PCI_MEM64_WIN_SIZE);

    if (index >= SPAPR_MAX_PHBS) {
        error_setg(errp, "\"index\" for PAPR PHB is too large (max %llu)",
                   SPAPR_MAX_PHBS - 1);
        return false;
    }

    *buid = base_buid + index;
    for (i = 0; i < n_dma; ++i) {
        liobns[i] = SPAPR_PCI_LIOBN(index, i);
    }

    *pio = SPAPR_PCI_BASE + index * SPAPR_PCI_IO_WIN_SIZE;
    *mmio32 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM32_WIN_SIZE;
    *mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
    return true;
}

static ICSState *spapr_ics_get(XICSFabric *dev, int irq)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(dev);

    return ics_valid_irq(spapr->ics, irq) ? spapr->ics : NULL;
}

static void spapr_ics_resend(XICSFabric *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(dev);

    ics_resend(spapr->ics);
}

static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
{
    PowerPCCPU *cpu = spapr_find_cpu(vcpu_id);

    return cpu ? spapr_cpu_state(cpu)->icp : NULL;
}

static void spapr_pic_print_info(InterruptStatsProvider *obj, GString *buf)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(obj);

    spapr_irq_print_info(spapr, buf);
    g_string_append_printf(buf, "irqchip: %s\n",
                           kvm_irqchip_in_kernel() ? "in-kernel" : "emulated");
}

/*
 * This is a XIVE only operation
 */
static int spapr_match_nvt(XiveFabric *xfb, uint8_t format,
                           uint8_t nvt_blk, uint32_t nvt_idx,
                           bool cam_ignore, uint8_t priority,
                           uint32_t logic_serv, XiveTCTXMatch *match)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(xfb);
    XivePresenter *xptr = XIVE_PRESENTER(spapr->active_intc);
    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
    int count;

    count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
                           priority, logic_serv, match);
    if (count < 0) {
        return count;
    }

    /*
     * When we implement the save and restore of the thread interrupt
     * contexts in the enter/exit CPU handlers of the machine and the
     * escalations in QEMU, we should be able to handle non dispatched
     * vCPUs.
     *
     * Until this is done, the sPAPR machine should find at least one
     * matching context always.
     */
    if (count == 0) {
        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is not dispatched\n",
                      nvt_blk, nvt_idx);
    }

    return count;
}

int spapr_get_vcpu_id(PowerPCCPU *cpu)
{
    return cpu->vcpu_id;
}

bool spapr_set_vcpu_id(PowerPCCPU *cpu, int cpu_index, Error **errp)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    MachineState *ms = MACHINE(spapr);
    int vcpu_id;

    vcpu_id = spapr_vcpu_id(spapr, cpu_index);

    if (kvm_enabled() && !kvm_vcpu_id_is_valid(vcpu_id)) {
        error_setg(errp, "Can't create CPU with id %d in KVM", vcpu_id);
        error_append_hint(errp, "Adjust the number of cpus to %d "
                          "or try to raise the number of threads per core\n",
                          vcpu_id * ms->smp.threads / spapr->vsmt);
        return false;
    }

    cpu->vcpu_id = vcpu_id;
    return true;
}

PowerPCCPU *spapr_find_cpu(int vcpu_id)
{
    CPUState *cs;

    CPU_FOREACH(cs) {
        PowerPCCPU *cpu = POWERPC_CPU(cs);

        if (spapr_get_vcpu_id(cpu) == vcpu_id) {
            return cpu;
        }
    }

    return NULL;
}

static bool spapr_cpu_in_nested(PowerPCCPU *cpu)
{
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    return spapr_cpu->in_nested;
}

static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    /* These are only called by TCG, KVM maintains dispatch state */

    spapr_cpu->prod = false;
    if (spapr_cpu->vpa_addr) {
        CPUState *cs = CPU(cpu);
        uint32_t dispatch;

        dispatch = ldl_be_phys(cs->as,
                               spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER);
        dispatch++;
        if ((dispatch & 1) != 0) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "VPA: incorrect dispatch counter value for "
                          "dispatched partition %u, correcting.\n", dispatch);
            dispatch++;
        }
        stl_be_phys(cs->as,
                    spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER, dispatch);
    }
}

static void spapr_cpu_exec_exit(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    if (spapr_cpu->vpa_addr) {
        CPUState *cs = CPU(cpu);
        uint32_t dispatch;

        dispatch = ldl_be_phys(cs->as,
                               spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER);
        dispatch++;
        if ((dispatch & 1) != 1) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "VPA: incorrect dispatch counter value for "
                          "preempted partition %u, correcting.\n", dispatch);
            dispatch++;
        }
        stl_be_phys(cs->as,
                    spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER, dispatch);
    }
}

static void spapr_machine_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
    FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
    PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
    XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
    VofMachineIfClass *vmc = VOF_MACHINE_CLASS(oc);

    mc->desc = "pSeries Logical Partition (PAPR compliant)";
    mc->ignore_boot_device_suffixes = true;

    /*
     * We set up the default / latest behaviour here.  The class_init
     * functions for the specific versioned machine types can override
     * these details for backwards compatibility
     */
    mc->init = spapr_machine_init;
    mc->reset = spapr_machine_reset;
    mc->block_default_type = IF_SCSI;

    /*
     * While KVM determines max cpus in kvm_init() using kvm_max_vcpus(),
     * In TCG the limit is restricted by the range of CPU IPIs available.
     */
    mc->max_cpus = SPAPR_IRQ_NR_IPIS;

    mc->no_parallel = 1;
    mc->default_boot_order = "";
    mc->default_ram_size = 512 * MiB;
    mc->default_ram_id = "ppc_spapr.ram";
    mc->default_display = "std";
    mc->kvm_type = spapr_kvm_type;
    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SPAPR_PCI_HOST_BRIDGE);
    mc->pci_allow_0_address = true;
    assert(!mc->get_hotplug_handler);
    mc->get_hotplug_handler = spapr_get_hotplug_handler;
    hc->pre_plug = spapr_machine_device_pre_plug;
    hc->plug = spapr_machine_device_plug;
    mc->cpu_index_to_instance_props = spapr_cpu_index_to_props;
    mc->get_default_cpu_node_id = spapr_get_default_cpu_node_id;
    mc->possible_cpu_arch_ids = spapr_possible_cpu_arch_ids;
    hc->unplug_request = spapr_machine_device_unplug_request;
    hc->unplug = spapr_machine_device_unplug;

    smc->update_dt_enabled = true;
    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
    mc->has_hotpluggable_cpus = true;
    mc->nvdimm_supported = true;
    smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
    fwc->get_dev_path = spapr_get_fw_dev_path;
    nc->nmi_monitor_handler = spapr_nmi;
    smc->phb_placement = spapr_phb_placement;
    vhc->cpu_in_nested = spapr_cpu_in_nested;
    vhc->deliver_hv_excp = spapr_exit_nested;
    vhc->hypercall = emulate_spapr_hypercall;
    vhc->hpt_mask = spapr_hpt_mask;
    vhc->map_hptes = spapr_map_hptes;
    vhc->unmap_hptes = spapr_unmap_hptes;
    vhc->hpte_set_c = spapr_hpte_set_c;
    vhc->hpte_set_r = spapr_hpte_set_r;
    vhc->get_pate = spapr_get_pate;
    vhc->encode_hpt_for_kvm_pr = spapr_encode_hpt_for_kvm_pr;
    vhc->cpu_exec_enter = spapr_cpu_exec_enter;
    vhc->cpu_exec_exit = spapr_cpu_exec_exit;
    xic->ics_get = spapr_ics_get;
    xic->ics_resend = spapr_ics_resend;
    xic->icp_get = spapr_icp_get;
    ispc->print_info = spapr_pic_print_info;
    /* Force NUMA node memory size to be a multiple of
     * SPAPR_MEMORY_BLOCK_SIZE (256M) since that's the granularity
     * in which LMBs are represented and hot-added
     */
    mc->numa_mem_align_shift = 28;
    mc->auto_enable_numa = true;

    smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
    smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
    smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
    smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND;
    smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND;
    smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_WORKAROUND;
    smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
    smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
    smc->default_caps.caps[SPAPR_CAP_NESTED_PAPR] = SPAPR_CAP_OFF;
    smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
    smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
    smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;
    smc->default_caps.caps[SPAPR_CAP_RPT_INVALIDATE] = SPAPR_CAP_OFF;

    /*
     * This cap specifies whether the AIL 3 mode for
     * H_SET_RESOURCE is supported. The default is modified
     * by default_caps_with_cpu().
     */
    smc->default_caps.caps[SPAPR_CAP_AIL_MODE_3] = SPAPR_CAP_ON;
    spapr_caps_add_properties(smc);
    smc->irq = &spapr_irq_dual;
    smc->dr_phb_enabled = true;
    smc->linux_pci_probe = true;
    smc->smp_threads_vsmt = true;
    smc->nr_xirqs = SPAPR_NR_XIRQS;
    xfc->match_nvt = spapr_match_nvt;
    vmc->client_architecture_support = spapr_vof_client_architecture_support;
    vmc->quiesce = spapr_vof_quiesce;
    vmc->setprop = spapr_vof_setprop;
}

static const TypeInfo spapr_machine_info = {
    .name          = TYPE_SPAPR_MACHINE,
    .parent        = TYPE_MACHINE,
    .abstract      = true,
    .instance_size = sizeof(SpaprMachineState),
    .instance_init = spapr_instance_init,
    .instance_finalize = spapr_machine_finalizefn,
    .class_size    = sizeof(SpaprMachineClass),
    .class_init    = spapr_machine_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_FW_PATH_PROVIDER },
        { TYPE_NMI },
        { TYPE_HOTPLUG_HANDLER },
        { TYPE_PPC_VIRTUAL_HYPERVISOR },
        { TYPE_XICS_FABRIC },
        { TYPE_INTERRUPT_STATS_PROVIDER },
        { TYPE_XIVE_FABRIC },
        { TYPE_VOF_MACHINE_IF },
        { }
    },
};

static void spapr_machine_latest_class_options(MachineClass *mc)
{
    mc->alias = "pseries";
    mc->is_default = true;
}

#define DEFINE_SPAPR_MACHINE_IMPL(latest, ...)                       \
    static void MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__)(     \
        ObjectClass *oc,                                             \
        void *data)                                                  \
    {                                                                \
        MachineClass *mc = MACHINE_CLASS(oc);                        \
        MACHINE_VER_SYM(class_options, spapr, __VA_ARGS__)(mc);      \
        MACHINE_VER_DEPRECATION(__VA_ARGS__);                        \
        if (latest) {                                                \
            spapr_machine_latest_class_options(mc);                  \
        }                                                            \
    }                                                                \
    static const TypeInfo MACHINE_VER_SYM(info, spapr, __VA_ARGS__) = \
    {                                                                \
        .name = MACHINE_VER_TYPE_NAME("pseries", __VA_ARGS__),       \
        .parent = TYPE_SPAPR_MACHINE,                                \
        .class_init = MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__), \
    };                                                               \
    static void MACHINE_VER_SYM(register, spapr, __VA_ARGS__)(void)  \
    {                                                                \
        MACHINE_VER_DELETION(__VA_ARGS__);                           \
        type_register(&MACHINE_VER_SYM(info, spapr, __VA_ARGS__));   \
    }                                                                \
    type_init(MACHINE_VER_SYM(register, spapr, __VA_ARGS__))

#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor) \
    DEFINE_SPAPR_MACHINE_IMPL(true, major, minor)
#define DEFINE_SPAPR_MACHINE(major, minor) \
    DEFINE_SPAPR_MACHINE_IMPL(false, major, minor)

/*
 * pseries-9.2
 */
static void spapr_machine_9_2_class_options(MachineClass *mc)
{
    /* Defaults for the latest behaviour inherited from the base class */
}

DEFINE_SPAPR_MACHINE_AS_LATEST(9, 2);

/*
 * pseries-9.1
 */
static void spapr_machine_9_1_class_options(MachineClass *mc)
{
    spapr_machine_9_2_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_9_1, hw_compat_9_1_len);
}

DEFINE_SPAPR_MACHINE(9, 1);

/*
 * pseries-9.0
 */
static void spapr_machine_9_0_class_options(MachineClass *mc)
{
    spapr_machine_9_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_9_0, hw_compat_9_0_len);
}

DEFINE_SPAPR_MACHINE(9, 0);

/*
 * pseries-8.2
 */
static void spapr_machine_8_2_class_options(MachineClass *mc)
{
    spapr_machine_9_0_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
}

DEFINE_SPAPR_MACHINE(8, 2);

/*
 * pseries-8.1
 */
static void spapr_machine_8_1_class_options(MachineClass *mc)
{
    spapr_machine_8_2_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
}

DEFINE_SPAPR_MACHINE(8, 1);

/*
 * pseries-8.0
 */
static void spapr_machine_8_0_class_options(MachineClass *mc)
{
    spapr_machine_8_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
}

DEFINE_SPAPR_MACHINE(8, 0);

/*
 * pseries-7.2
 */
static void spapr_machine_7_2_class_options(MachineClass *mc)
{
    spapr_machine_8_0_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_7_2, hw_compat_7_2_len);
}

DEFINE_SPAPR_MACHINE(7, 2);

/*
 * pseries-7.1
 */
static void spapr_machine_7_1_class_options(MachineClass *mc)
{
    spapr_machine_7_2_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len);
}

DEFINE_SPAPR_MACHINE(7, 1);

/*
 * pseries-7.0
 */
static void spapr_machine_7_0_class_options(MachineClass *mc)
{
    spapr_machine_7_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_7_0, hw_compat_7_0_len);
}

DEFINE_SPAPR_MACHINE(7, 0);

/*
 * pseries-6.2
 */
static void spapr_machine_6_2_class_options(MachineClass *mc)
{
    spapr_machine_7_0_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_6_2, hw_compat_6_2_len);
}

DEFINE_SPAPR_MACHINE(6, 2);

/*
 * pseries-6.1
 */
static void spapr_machine_6_1_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    spapr_machine_6_2_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
    smc->pre_6_2_numa_affinity = true;
    mc->smp_props.prefer_sockets = true;
}

DEFINE_SPAPR_MACHINE(6, 1);

/*
 * pseries-6.0
 */
static void spapr_machine_6_0_class_options(MachineClass *mc)
{
    spapr_machine_6_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
}

DEFINE_SPAPR_MACHINE(6, 0);

/*
 * pseries-5.2
 */
static void spapr_machine_5_2_class_options(MachineClass *mc)
{
    spapr_machine_6_0_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
}

DEFINE_SPAPR_MACHINE(5, 2);

/*
 * pseries-5.1
 */
static void spapr_machine_5_1_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    spapr_machine_5_2_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
    smc->pre_5_2_numa_associativity = true;
}

DEFINE_SPAPR_MACHINE(5, 1);

/*
 * pseries-5.0
 */
static void spapr_machine_5_0_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
    static GlobalProperty compat[] = {
        { TYPE_SPAPR_PCI_HOST_BRIDGE, "pre-5.1-associativity", "on" },
    };

    spapr_machine_5_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
    compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
    mc->numa_mem_supported = true;
    smc->pre_5_1_assoc_refpoints = true;
}

DEFINE_SPAPR_MACHINE(5, 0);

/*
 * pseries-4.2
 */
static void spapr_machine_4_2_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    spapr_machine_5_0_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
    smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
    smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_OFF;
    smc->rma_limit = 16 * GiB;
    mc->nvdimm_supported = false;
}

DEFINE_SPAPR_MACHINE(4, 2);

/*
 * pseries-4.1
 */
static void spapr_machine_4_1_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
    static GlobalProperty compat[] = {
        /* Only allow 4kiB and 64kiB IOMMU pagesizes */
        { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" },
    };

    spapr_machine_4_2_class_options(mc);
    smc->linux_pci_probe = false;
    smc->smp_threads_vsmt = false;
    compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
    compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}

DEFINE_SPAPR_MACHINE(4, 1);

/*
 * pseries-4.0
 */
static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
                              uint64_t *buid, hwaddr *pio,
                              hwaddr *mmio32, hwaddr *mmio64,
                              unsigned n_dma, uint32_t *liobns, Error **errp)
{
    if (!spapr_phb_placement(spapr, index, buid, pio, mmio32, mmio64, n_dma,
                             liobns, errp)) {
        return false;
    }
    return true;
}
static void spapr_machine_4_0_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    spapr_machine_4_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
    smc->phb_placement = phb_placement_4_0;
    smc->irq = &spapr_irq_xics;
    smc->pre_4_1_migration = true;
}

DEFINE_SPAPR_MACHINE(4, 0);

/*
 * pseries-3.1
 */
static void spapr_machine_3_1_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    spapr_machine_4_0_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);

    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
    smc->update_dt_enabled = false;
    smc->dr_phb_enabled = false;
    smc->broken_host_serial_model = true;
    smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
    smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
    smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
    smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
}

DEFINE_SPAPR_MACHINE(3, 1);

/*
 * pseries-3.0
 */

static void spapr_machine_3_0_class_options(MachineClass *mc)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);

    spapr_machine_3_1_class_options(mc);
    compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);

    smc->legacy_irq_allocation = true;
    smc->nr_xirqs = 0x400;
    smc->irq = &spapr_irq_xics_legacy;
}

DEFINE_SPAPR_MACHINE(3, 0);

static void spapr_machine_register_types(void)
{
    type_register_static(&spapr_machine_info);
}

type_init(spapr_machine_register_types)
