diff options
Diffstat (limited to 'hw/ppc/spapr.c')
| -rw-r--r-- | hw/ppc/spapr.c | 470 |
1 files changed, 186 insertions, 284 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b0a0f8c..99b843b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -77,7 +77,6 @@ #include "hw/virtio/virtio-scsi.h" #include "hw/virtio/vhost-scsi-common.h" -#include "exec/ram_addr.h" #include "system/confidential-guest-support.h" #include "hw/usb.h" #include "qemu/config-file.h" @@ -577,7 +576,7 @@ static int spapr_dt_dynamic_memory(SpaprMachineState *spapr, void *fdt, /* * Adds ibm,dynamic-reconfiguration-memory node. - * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation + * Refer to docs/specs/ppc-spapr-hotplug.rst for the documentation * of this device tree node. */ static int spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr, @@ -901,12 +900,80 @@ static int spapr_dt_rng(void *fdt) return ret ? -1 : 0; } +static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas) +{ + MachineState *ms = MACHINE(spapr); + MachineClass *mc = MACHINE_GET_CLASS(ms); + FadumpMemStruct *fdm = &spapr->registered_fdm; + uint16_t dump_status_flag; + + uint32_t max_possible_cpus = mc->possible_cpu_arch_ids(ms)->len; + uint64_t fadump_cpu_state_size = 0; + uint16_t fadump_versions[2] = { + FADUMP_VERSION /* min supported version */, + FADUMP_VERSION /* max supported version */ + }; + uint32_t fadump_rgn_sizes[2][3] = { + { + cpu_to_be32(FADUMP_CPU_STATE_DATA), + 0, 0 /* Calculated later */ + }, + { + cpu_to_be32(FADUMP_HPTE_REGION), + 0, 0 /* HPTE region not implemented */ + } + }; + + /* + * CPU State Data contains multiple fields such as header, num_cpus and + * register entries + * + * Calculate the maximum CPU State Data size, according to maximum + * possible CPUs the QEMU VM can have + * + * This calculation must match the 'cpu_state_len' calculation done in + * 'populate_cpu_state_data' in spapr_fadump.c + */ + fadump_cpu_state_size += sizeof(struct FadumpRegSaveAreaHeader); + fadump_cpu_state_size += 0xc; /* padding as in PAPR */ + fadump_cpu_state_size += sizeof(uint32_t); /* num_cpus */ + fadump_cpu_state_size += max_possible_cpus * /* reg entries */ + FADUMP_PER_CPU_REG_ENTRIES * + sizeof(struct FadumpRegEntry); + + /* Set maximum size for CPU state data region */ + assert(fadump_rgn_sizes[0][0] == cpu_to_be32(FADUMP_CPU_STATE_DATA)); + + /* Upper 32 bits of size, usually 0 */ + fadump_rgn_sizes[0][1] = cpu_to_be32(fadump_cpu_state_size >> 32); + + /* Lower 32 bits of size */ + fadump_rgn_sizes[0][2] = cpu_to_be32(fadump_cpu_state_size & 0xffffffff); + + /* Add device tree properties required from platform for fadump */ + _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-version", + fadump_versions, sizeof(fadump_versions)))); + _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-sizes", + fadump_rgn_sizes, sizeof(fadump_rgn_sizes)))); + + dump_status_flag = be16_to_cpu(fdm->header.dump_status_flag); + if (dump_status_flag & FADUMP_STATUS_DUMP_TRIGGERED) { + uint64_t fdm_size = + sizeof(struct FadumpSectionHeader) + + (be16_to_cpu(fdm->header.dump_num_sections) * + sizeof(struct FadumpSection)); + + _FDT((fdt_setprop(fdt, rtas, "ibm,kernel-dump", fdm, fdm_size))); + } +} + 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); + uint64_t max_device_addr = 0; uint32_t lrdr_capacity[] = { 0, 0, @@ -917,13 +984,15 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt) /* Do we have device memory? */ if (MACHINE(spapr)->device_memory) { - uint64_t max_device_addr = MACHINE(spapr)->device_memory->base + + 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); + } else if (ms->ram_size == ms->maxram_size) { + max_device_addr = ms->ram_size; } + 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 */ @@ -1013,6 +1082,8 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt) _FDT(fdt_setprop(fdt, rtas, "ibm,lrdr-capacity", lrdr_capacity, sizeof(lrdr_capacity))); + spapr_dt_rtas_fadump(spapr, fdt, rtas); + spapr_dt_rtas_tokens(fdt, rtas); } @@ -1070,7 +1141,6 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt, 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")); @@ -1141,9 +1211,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset) * 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)); - } + _FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0)); spapr_dt_ov5_platform_support(spapr, fdt, chosen); } @@ -1180,7 +1248,6 @@ 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; @@ -1211,16 +1278,10 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space) /* 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)); @@ -1258,9 +1319,8 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space) /* 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; - } + root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PHB; + if (mc->nvdimm_supported) { root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PMEM; } @@ -2059,13 +2119,6 @@ static const VMStateDescription vmstate_spapr_irq_map = { }, }; -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; @@ -2081,7 +2134,6 @@ 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), @@ -2518,7 +2570,7 @@ static void htab_save_cleanup(void *opaque) static SaveVMHandlers savevm_htab_handlers = { .save_setup = htab_save_setup, .save_live_iterate = htab_save_iterate, - .save_live_complete_precopy = htab_save_complete, + .save_complete = htab_save_complete, .save_cleanup = htab_save_cleanup, .load_state = htab_load, }; @@ -2603,7 +2655,6 @@ static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx) 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(); @@ -2639,15 +2690,6 @@ static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp) 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; } @@ -2756,7 +2798,6 @@ static PCIHostState *spapr_create_default_phb(void) 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); @@ -2769,15 +2810,6 @@ static hwaddr spapr_rma_size(SpaprMachineState *spapr, Error **errp) */ 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 @@ -2815,18 +2847,14 @@ static void spapr_machine_init(MachineState *machine) int i; MemoryRegion *sysmem = get_system_memory(); long load_limit, fw_size; - Error *resize_hpt_err = NULL; + Error *errp = 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); - } + fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE, &error_fatal); /* * if Secure VM (PEF) support is configured, then initialize it @@ -2843,7 +2871,7 @@ static void spapr_machine_init(MachineState *machine) /* Determine capabilities to run with */ spapr_caps_init(spapr); - kvmppc_check_papr_resize_hpt(&resize_hpt_err); + kvmppc_check_papr_resize_hpt(&errp); if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) { /* * If the user explicitly requested a mode we should either @@ -2851,10 +2879,10 @@ static void spapr_machine_init(MachineState *machine) * it's not set explicitly, we reset our mode to something * that works */ - if (resize_hpt_err) { + if (errp) { spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED; - error_free(resize_hpt_err); - resize_hpt_err = NULL; + error_free(errp); + errp = NULL; } else { spapr->resize_hpt = smc->resize_hpt_default; } @@ -2862,14 +2890,14 @@ static void spapr_machine_init(MachineState *machine) assert(spapr->resize_hpt != SPAPR_RESIZE_HPT_DEFAULT); - if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && resize_hpt_err) { + if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && errp) { /* * User requested HPT resize, but this host can't supply it. Bail out */ - error_report_err(resize_hpt_err); + error_report_err(errp); exit(1); } - error_free(resize_hpt_err); + error_free(errp); spapr->rma_size = spapr_rma_size(spapr, &error_fatal); @@ -3007,10 +3035,8 @@ static void spapr_machine_init(MachineState *machine) * 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); - } + for (i = 0; i < SPAPR_MAX_PHBS; i++) { + spapr_dr_connector_new(OBJECT(machine), TYPE_SPAPR_DRC_PHB, i); } /* Set up PCI */ @@ -3085,14 +3111,9 @@ static void spapr_machine_init(MachineState *machine) 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); - } + spapr->initrd_base, + load_limit - spapr->initrd_base, + &error_fatal); } } @@ -3345,9 +3366,7 @@ 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) { + if (spapr->irq == &spapr_irq_xics) { return g_strdup("xics"); } else if (spapr->irq == &spapr_irq_xive) { return g_strdup("xive"); @@ -3361,11 +3380,6 @@ 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; @@ -4091,20 +4105,65 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, return 0; } +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 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; @@ -4120,26 +4179,18 @@ static bool spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, * 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); + return spapr_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); @@ -4265,7 +4316,6 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, { 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)) { @@ -4280,10 +4330,6 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, } 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); @@ -4384,57 +4430,6 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine) 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); @@ -4468,21 +4463,14 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj, GString *buf) /* * 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 crowd, bool cam_ignore, uint8_t priority, - uint32_t logic_serv, XiveTCTXMatch *match) +static bool spapr_match_nvt(XiveFabric *xfb, uint8_t format, + uint8_t nvt_blk, uint32_t nvt_idx, + bool crowd, 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, crowd, cam_ignore, - priority, logic_serv, match); - if (count < 0) { - return count; - } /* * When we implement the save and restore of the thread interrupt @@ -4493,12 +4481,14 @@ static int spapr_match_nvt(XiveFabric *xfb, uint8_t format, * Until this is done, the sPAPR machine should find at least one * matching context always. */ - if (count == 0) { + if (!xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd, cam_ignore, + priority, logic_serv, match)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is not dispatched\n", nvt_blk, nvt_idx); + return false; } - return count; + return true; } int spapr_get_vcpu_id(PowerPCCPU *cpu) @@ -4595,7 +4585,7 @@ static void spapr_cpu_exec_exit(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) } } -static void spapr_machine_class_init(ObjectClass *oc, void *data) +static void spapr_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc); @@ -4644,14 +4634,12 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) 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; @@ -4698,10 +4686,6 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) 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; @@ -4717,7 +4701,7 @@ static const TypeInfo spapr_machine_info = { .instance_finalize = spapr_machine_finalizefn, .class_size = sizeof(SpaprMachineClass), .class_init = spapr_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { TYPE_NMI }, { TYPE_HOTPLUG_HANDLER }, @@ -4739,7 +4723,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) #define DEFINE_SPAPR_MACHINE_IMPL(latest, ...) \ static void MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__)( \ ObjectClass *oc, \ - void *data) \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ MACHINE_VER_SYM(class_options, spapr, __VA_ARGS__)(mc); \ @@ -4767,14 +4751,36 @@ static void spapr_machine_latest_class_options(MachineClass *mc) DEFINE_SPAPR_MACHINE_IMPL(false, major, minor) /* + * pseries-10.2 + */ +static void spapr_machine_10_2_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE_AS_LATEST(10, 2); + +/* + * pseries-10.1 + */ +static void spapr_machine_10_1_class_options(MachineClass *mc) +{ + spapr_machine_10_2_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len); +} + +DEFINE_SPAPR_MACHINE(10, 1); + +/* * pseries-10.0 */ static void spapr_machine_10_0_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_10_1_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_10_0, hw_compat_10_0_len); } -DEFINE_SPAPR_MACHINE_AS_LATEST(10, 0); +DEFINE_SPAPR_MACHINE(10, 0); /* * pseries-9.2 @@ -4957,110 +4963,6 @@ static void spapr_machine_5_0_class_options(MachineClass *mc) 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); |
