X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/f6d4dca807d853516fc307519f3260a432818bdc..bd94bc06479ad3be5e2d5db70fde9e8098b77d21:/hw/ppc/spapr.c diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b6a571b6f1..4fd16b43f0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -29,6 +29,7 @@ #include "qapi/visitor.h" #include "sysemu/sysemu.h" #include "sysemu/numa.h" +#include "sysemu/qtest.h" #include "hw/hw.h" #include "qemu/log.h" #include "hw/fw-path-provider.h" @@ -102,13 +103,13 @@ * 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) +static int spapr_vcpu_id(SpaprMachineState *spapr, int cpu_index) { assert(spapr->vsmt); return (cpu_index / smp_threads) * spapr->vsmt + cpu_index % smp_threads; } -static bool spapr_is_thread0_in_vcore(sPAPRMachineState *spapr, +static bool spapr_is_thread0_in_vcore(SpaprMachineState *spapr, PowerPCCPU *cpu) { assert(spapr->vsmt); @@ -149,7 +150,7 @@ static void pre_2_10_vmstate_unregister_dummy_icp(int i) (void *)(uintptr_t) i); } -int spapr_max_server_number(sPAPRMachineState *spapr) +int spapr_max_server_number(SpaprMachineState *spapr) { assert(spapr->vsmt); return DIV_ROUND_UP(max_cpus * spapr->vsmt, smp_threads); @@ -204,7 +205,7 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu) } /* Populate the "ibm,pa-features" property */ -static void spapr_populate_pa_features(sPAPRMachineState *spapr, +static void spapr_populate_pa_features(SpaprMachineState *spapr, PowerPCCPU *cpu, void *fdt, int offset, bool legacy_guest) @@ -283,7 +284,7 @@ static void spapr_populate_pa_features(sPAPRMachineState *spapr, _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size))); } -static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr) +static int spapr_fixup_cpu_dt(void *fdt, SpaprMachineState *spapr) { int ret = 0, offset, cpus_offset; CPUState *cs; @@ -386,7 +387,7 @@ static int spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start, return off; } -static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) +static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); hwaddr mem_start, node_size; @@ -438,7 +439,7 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) } static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, - sPAPRMachineState *spapr) + SpaprMachineState *spapr) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; @@ -454,7 +455,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, uint32_t vcpus_per_socket = smp_threads * 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)); - sPAPRDRConnector *drc; + SpaprDrc *drc; int drc_index; uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ]; int i; @@ -499,7 +500,10 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0))); if (env->spr_cb[SPR_PURR].oea_read) { - _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0))); + _FDT((fdt_setprop_cell(fdt, offset, "ibm,purr", 1))); + } + if (env->spr_cb[SPR_SPURR].oea_read) { + _FDT((fdt_setprop_cell(fdt, offset, "ibm,spurr", 1))); } if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG)) { @@ -557,9 +561,17 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, 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_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) +static void spapr_populate_cpus_dt_node(void *fdt, SpaprMachineState *spapr) { CPUState **rev; CPUState *cs; @@ -683,7 +695,7 @@ spapr_get_drconf_cell(uint32_t seq_lmbs, uint64_t base_addr, } /* ibm,dynamic-memory-v2 */ -static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt, +static int spapr_populate_drmem_v2(SpaprMachineState *spapr, void *fdt, int offset, MemoryDeviceInfoList *dimms) { MachineState *machine = MACHINE(spapr); @@ -695,7 +707,7 @@ static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt, uint64_t mem_end = machine->device_memory->base + memory_region_size(&machine->device_memory->mr); uint32_t node, buf_len, nr_entries = 0; - sPAPRDRConnector *drc; + SpaprDrc *drc; DrconfCellQueue *elem, *next; MemoryDeviceInfoList *info; QSIMPLEQ_HEAD(, DrconfCellQueue) drconf_queue @@ -768,7 +780,7 @@ static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt, } /* ibm,dynamic-memory */ -static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt, +static int spapr_populate_drmem_v1(SpaprMachineState *spapr, void *fdt, int offset, MemoryDeviceInfoList *dimms) { MachineState *machine = MACHINE(spapr); @@ -792,7 +804,7 @@ static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt, uint32_t *dynamic_memory = cur_index; if (i >= device_lmb_start) { - sPAPRDRConnector *drc; + SpaprDrc *drc; drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, i); g_assert(drc); @@ -837,7 +849,7 @@ static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt, * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation * of this device tree node. */ -static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) +static int spapr_populate_drconf_memory(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); int ret, i, offset; @@ -908,10 +920,10 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) return ret; } -static int spapr_dt_cas_updates(sPAPRMachineState *spapr, void *fdt, - sPAPROptionVector *ov5_updates) +static int spapr_dt_cas_updates(SpaprMachineState *spapr, void *fdt, + SpaprOptionVector *ov5_updates) { - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); int ret = 0, offset; /* Generate ibm,dynamic-reconfiguration-memory node if required */ @@ -957,12 +969,12 @@ static bool spapr_hotplugged_dev_before_cas(void) return false; } -int spapr_h_cas_compose_response(sPAPRMachineState *spapr, +int spapr_h_cas_compose_response(SpaprMachineState *spapr, target_ulong addr, target_ulong size, - sPAPROptionVector *ov5_updates) + SpaprOptionVector *ov5_updates) { void *fdt, *fdt_skel; - sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 }; + SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 }; if (spapr_hotplugged_dev_before_cas()) { return 1; @@ -1011,7 +1023,7 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr, return 0; } -static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) +static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt) { int rtas; GString *hypertas = g_string_sized_new(256); @@ -1025,12 +1037,13 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) 0, cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE), cpu_to_be32(max_cpus / smp_threads), }; + uint32_t maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0); uint32_t maxdomains[] = { cpu_to_be32(4), - cpu_to_be32(0), - cpu_to_be32(0), - cpu_to_be32(0), - cpu_to_be32(nb_numa_nodes ? nb_numa_nodes : 1), + maxdomain, + maxdomain, + maxdomain, + cpu_to_be32(spapr->gpu_numa_id), }; _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas")); @@ -1100,7 +1113,7 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) * 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, +static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt, int chosen) { PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); @@ -1136,7 +1149,7 @@ static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *fdt, val, sizeof(val))); } -static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt) +static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); int chosen; @@ -1202,7 +1215,7 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt) g_free(bootlist); } -static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt) +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 */ @@ -1225,14 +1238,14 @@ static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt) } } -static void *spapr_build_fdt(sPAPRMachineState *spapr) +static void *spapr_build_fdt(SpaprMachineState *spapr) { MachineState *machine = MACHINE(spapr); MachineClass *mc = MACHINE_GET_CLASS(machine); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); int ret; void *fdt; - sPAPRPHBState *phb; + SpaprPhbState *phb; char *buf; fdt = g_malloc0(FDT_MAX_SIZE); @@ -1243,38 +1256,8 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr) _FDT(fdt_setprop_string(fdt, 0, "model", "IBM pSeries (emulated by qemu)")); _FDT(fdt_setprop_string(fdt, 0, "compatible", "qemu,pseries")); - /* - * Add info to guest to indentify which host is it being run on - * and what is the uuid of the guest - */ - if (spapr->host_model && !g_str_equal(spapr->host_model, "none")) { - if (g_str_equal(spapr->host_model, "passthrough")) { - /* -M host-model=passthrough */ - if (kvmppc_get_host_model(&buf)) { - _FDT(fdt_setprop_string(fdt, 0, "host-model", buf)); - g_free(buf); - } - } else { - /* -M host-model= */ - _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model)); - } - } - - if (spapr->host_serial && !g_str_equal(spapr->host_serial, "none")) { - if (g_str_equal(spapr->host_serial, "passthrough")) { - /* -M host-serial=passthrough */ - if (kvmppc_get_host_serial(&buf)) { - _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf)); - g_free(buf); - } - } else { - /* -M host-serial= */ - _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial)); - } - } - + /* 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)); @@ -1286,6 +1269,21 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr) 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)); @@ -1430,7 +1428,7 @@ void spapr_set_all_lpcrs(target_ulong value, target_ulong mask) static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry) { - sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp); + SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); /* Copy PATE1:GR into PATE0:HR */ entry->dw0 = spapr->patb_entry & PATE0_HR; @@ -1446,7 +1444,7 @@ static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry) /* * Get the fd to access the kernel htab, re-opening it if necessary */ -static int get_htab_fd(sPAPRMachineState *spapr) +static int get_htab_fd(SpaprMachineState *spapr) { Error *local_err = NULL; @@ -1462,7 +1460,7 @@ static int get_htab_fd(sPAPRMachineState *spapr) return spapr->htab_fd; } -void close_htab_fd(sPAPRMachineState *spapr) +void close_htab_fd(SpaprMachineState *spapr) { if (spapr->htab_fd >= 0) { close(spapr->htab_fd); @@ -1472,14 +1470,14 @@ void close_htab_fd(sPAPRMachineState *spapr) static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(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); + SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); assert(kvm_enabled()); @@ -1493,7 +1491,7 @@ static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp) static const ppc_hash_pte64_t *spapr_map_hptes(PPCVirtualHypervisor *vhyp, hwaddr ptex, int n) { - sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp); + SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); hwaddr pte_offset = ptex * HASH_PTE_SIZE_64; if (!spapr->htab) { @@ -1516,7 +1514,7 @@ static void spapr_unmap_hptes(PPCVirtualHypervisor *vhyp, const ppc_hash_pte64_t *hptes, hwaddr ptex, int n) { - sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp); + SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); if (!spapr->htab) { g_free((void *)hptes); @@ -1525,10 +1523,10 @@ static void spapr_unmap_hptes(PPCVirtualHypervisor *vhyp, /* Nothing to do for qemu managed HPT */ } -static void spapr_store_hpte(PPCVirtualHypervisor *vhyp, hwaddr ptex, - uint64_t pte0, uint64_t pte1) +void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex, + uint64_t pte0, uint64_t pte1) { - sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp); + SpaprMachineState *spapr = SPAPR_MACHINE(cpu->vhyp); hwaddr offset = ptex * HASH_PTE_SIZE_64; if (!spapr->htab) { @@ -1556,6 +1554,38 @@ static void spapr_store_hpte(PPCVirtualHypervisor *vhyp, hwaddr ptex, } } +static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex, + uint64_t pte1) +{ + hwaddr offset = ptex * HASH_PTE_SIZE_64 + 15; + 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 + 14; + 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; @@ -1569,7 +1599,7 @@ int spapr_hpt_shift_for_ramsize(uint64_t ramsize) return shift; } -void spapr_free_hpt(sPAPRMachineState *spapr) +void spapr_free_hpt(SpaprMachineState *spapr) { g_free(spapr->htab); spapr->htab = NULL; @@ -1577,7 +1607,7 @@ void spapr_free_hpt(sPAPRMachineState *spapr) close_htab_fd(spapr); } -void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift, +void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp) { long rc; @@ -1623,10 +1653,11 @@ void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift, } } /* We're setting up a hash table, so that means we're not radix */ + spapr->patb_entry = 0; spapr_set_all_lpcrs(0, LPCR_HR | LPCR_UPRT); } -void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr) +void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr) { int hpt_shift; @@ -1650,8 +1681,8 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr) static int spapr_reset_drcs(Object *child, void *opaque) { - sPAPRDRConnector *drc = - (sPAPRDRConnector *) object_dynamic_cast(child, + SpaprDrc *drc = + (SpaprDrc *) object_dynamic_cast(child, TYPE_SPAPR_DR_CONNECTOR); if (drc) { @@ -1664,7 +1695,7 @@ static int spapr_reset_drcs(Object *child, void *opaque) static void spapr_machine_reset(void) { MachineState *machine = MACHINE(qdev_get_machine()); - sPAPRMachineState *spapr = SPAPR_MACHINE(machine); + SpaprMachineState *spapr = SPAPR_MACHINE(machine); PowerPCCPU *first_ppc_cpu; uint32_t rtas_limit; hwaddr rtas_addr, fdt_addr; @@ -1703,6 +1734,16 @@ static void spapr_machine_reset(void) spapr_irq_msi_reset(spapr); } + /* + * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node. + * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is + * called from vPHB reset handler so we initialize the counter here. + * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM + * must be equally distant from any other node. + * The final value of spapr->gpu_numa_id is going to be written to + * max-associativity-domains in spapr_build_fdt(). + */ + spapr->gpu_numa_id = MAX(1, nb_numa_nodes); qemu_devices_reset(); /* @@ -1711,6 +1752,16 @@ static void spapr_machine_reset(void) */ 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); + } + /* 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 @@ -1759,7 +1810,7 @@ static void spapr_machine_reset(void) spapr->cas_reboot = false; } -static void spapr_create_nvram(sPAPRMachineState *spapr) +static void spapr_create_nvram(SpaprMachineState *spapr) { DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram"); DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); @@ -1771,10 +1822,10 @@ static void spapr_create_nvram(sPAPRMachineState *spapr) qdev_init_nofail(dev); - spapr->nvram = (struct sPAPRNVRAM *)dev; + spapr->nvram = (struct SpaprNvram *)dev; } -static void spapr_rtc_create(sPAPRMachineState *spapr) +static void spapr_rtc_create(SpaprMachineState *spapr) { object_initialize_child(OBJECT(spapr), "rtc", &spapr->rtc, sizeof(spapr->rtc), TYPE_SPAPR_RTC, @@ -1818,7 +1869,7 @@ static int spapr_pre_load(void *opaque) static int spapr_post_load(void *opaque, int version_id) { - sPAPRMachineState *spapr = (sPAPRMachineState *)opaque; + SpaprMachineState *spapr = (SpaprMachineState *)opaque; int err = 0; err = spapr_caps_post_migration(spapr); @@ -1885,7 +1936,7 @@ static bool version_before_3(void *opaque, int version_id) static bool spapr_pending_events_needed(void *opaque) { - sPAPRMachineState *spapr = (sPAPRMachineState *)opaque; + SpaprMachineState *spapr = (SpaprMachineState *)opaque; return !QTAILQ_EMPTY(&spapr->pending_events); } @@ -1894,9 +1945,9 @@ static const VMStateDescription vmstate_spapr_event_entry = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_UINT32(summary, sPAPREventLogEntry), - VMSTATE_UINT32(extended_length, sPAPREventLogEntry), - VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, sPAPREventLogEntry, 0, + VMSTATE_UINT32(summary, SpaprEventLogEntry), + VMSTATE_UINT32(extended_length, SpaprEventLogEntry), + VMSTATE_VBUFFER_ALLOC_UINT32(extended_log, SpaprEventLogEntry, 0, NULL, extended_length), VMSTATE_END_OF_LIST() }, @@ -1908,21 +1959,21 @@ static const VMStateDescription vmstate_spapr_pending_events = { .minimum_version_id = 1, .needed = spapr_pending_events_needed, .fields = (VMStateField[]) { - VMSTATE_QTAILQ_V(pending_events, sPAPRMachineState, 1, - vmstate_spapr_event_entry, sPAPREventLogEntry, next), + 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(); - sPAPROptionVector *ov5_legacy = spapr_ovec_new(); - sPAPROptionVector *ov5_removed = spapr_ovec_new(); + SpaprMachineState *spapr = opaque; + SpaprOptionVector *ov5_mask = spapr_ovec_new(); + SpaprOptionVector *ov5_legacy = spapr_ovec_new(); + SpaprOptionVector *ov5_removed = spapr_ovec_new(); bool cas_needed; - /* Prior to the introduction of sPAPROptionVector, we had two option + /* 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 @@ -1972,15 +2023,15 @@ static const VMStateDescription vmstate_spapr_ov5_cas = { .minimum_version_id = 1, .needed = spapr_ov5_cas_needed, .fields = (VMStateField[]) { - VMSTATE_STRUCT_POINTER_V(ov5_cas, sPAPRMachineState, 1, - vmstate_spapr_ovec, sPAPROptionVector), + 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; + SpaprMachineState *spapr = opaque; return !!spapr->patb_entry; } @@ -1991,14 +2042,14 @@ static const VMStateDescription vmstate_spapr_patb_entry = { .minimum_version_id = 1, .needed = spapr_patb_entry_needed, .fields = (VMStateField[]) { - VMSTATE_UINT64(patb_entry, sPAPRMachineState), + VMSTATE_UINT64(patb_entry, SpaprMachineState), VMSTATE_END_OF_LIST() }, }; static bool spapr_irq_map_needed(void *opaque) { - sPAPRMachineState *spapr = opaque; + SpaprMachineState *spapr = opaque; return spapr->irq_map && !bitmap_empty(spapr->irq_map, spapr->irq_map_nr); } @@ -2009,21 +2060,21 @@ static const VMStateDescription vmstate_spapr_irq_map = { .minimum_version_id = 1, .needed = spapr_irq_map_needed, .fields = (VMStateField[]) { - VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, irq_map_nr), + 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); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque); return smc->update_dt_enabled; } static int spapr_dtb_pre_load(void *opaque) { - sPAPRMachineState *spapr = (sPAPRMachineState *)opaque; + SpaprMachineState *spapr = (SpaprMachineState *)opaque; g_free(spapr->fdt_blob); spapr->fdt_blob = NULL; @@ -2039,9 +2090,9 @@ static const VMStateDescription vmstate_spapr_dtb = { .needed = spapr_dtb_needed, .pre_load = spapr_dtb_pre_load, .fields = (VMStateField[]) { - VMSTATE_UINT32(fdt_initial_size, sPAPRMachineState), - VMSTATE_UINT32(fdt_size, sPAPRMachineState), - VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, sPAPRMachineState, 0, NULL, + 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() }, @@ -2059,9 +2110,9 @@ static const VMStateDescription vmstate_spapr = { VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4), /* RTC offset */ - VMSTATE_UINT64_TEST(rtc_offset, sPAPRMachineState, version_before_3), + VMSTATE_UINT64_TEST(rtc_offset, SpaprMachineState, version_before_3), - VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2), + VMSTATE_PPC_TIMEBASE_V(tb, SpaprMachineState, 2), VMSTATE_END_OF_LIST() }, .subsections = (const VMStateDescription*[]) { @@ -2074,16 +2125,19 @@ static const VMStateDescription vmstate_spapr = { &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, NULL } }; static int htab_save_setup(QEMUFile *f, void *opaque) { - sPAPRMachineState *spapr = opaque; + SpaprMachineState *spapr = opaque; /* "Iteration" header */ if (!spapr->htab_shift) { @@ -2105,7 +2159,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque) return 0; } -static void htab_save_chunk(QEMUFile *f, sPAPRMachineState *spapr, +static void htab_save_chunk(QEMUFile *f, SpaprMachineState *spapr, int chunkstart, int n_valid, int n_invalid) { qemu_put_be32(f, chunkstart); @@ -2122,7 +2176,7 @@ static void htab_save_end_marker(QEMUFile *f) qemu_put_be16(f, 0); } -static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr, +static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr, int64_t max_ns) { bool has_timeout = max_ns != -1; @@ -2170,7 +2224,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr, spapr->htab_save_index = index; } -static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr, +static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, int64_t max_ns) { bool final = max_ns < 0; @@ -2248,7 +2302,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr, static int htab_save_iterate(QEMUFile *f, void *opaque) { - sPAPRMachineState *spapr = opaque; + SpaprMachineState *spapr = opaque; int fd; int rc = 0; @@ -2285,7 +2339,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) static int htab_save_complete(QEMUFile *f, void *opaque) { - sPAPRMachineState *spapr = opaque; + SpaprMachineState *spapr = opaque; int fd; /* Iteration header */ @@ -2325,7 +2379,7 @@ static int htab_save_complete(QEMUFile *f, void *opaque) static int htab_load(QEMUFile *f, void *opaque, int version_id) { - sPAPRMachineState *spapr = opaque; + SpaprMachineState *spapr = opaque; uint32_t section_hdr; int fd = -1; Error *local_err = NULL; @@ -2415,7 +2469,7 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) static void htab_save_cleanup(void *opaque) { - sPAPRMachineState *spapr = opaque; + SpaprMachineState *spapr = opaque; close_htab_fd(spapr); } @@ -2435,7 +2489,7 @@ static void spapr_boot_set(void *opaque, const char *boot_device, machine->boot_order = g_strdup(boot_device); } -static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr) +static void spapr_create_lmb_dr_connectors(SpaprMachineState *spapr) { MachineState *machine = MACHINE(spapr); uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; @@ -2502,7 +2556,7 @@ static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx) return &ms->possible_cpus->cpus[index]; } -static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp) +static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp) { Error *local_err = NULL; bool vsmt_user = !!spapr->vsmt; @@ -2574,11 +2628,11 @@ out: error_propagate(errp, local_err); } -static void spapr_init_cpus(sPAPRMachineState *spapr) +static void spapr_init_cpus(SpaprMachineState *spapr) { MachineState *machine = MACHINE(spapr); MachineClass *mc = MACHINE_GET_CLASS(machine); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); const char *type = spapr_get_cpu_core_type(machine->cpu_type); const CPUArchIdList *possible_cpus; int boot_cores_nr = smp_cpus / smp_threads; @@ -2657,8 +2711,8 @@ static PCIHostState *spapr_create_default_phb(void) /* pSeries LPAR / sPAPR hardware init */ static void spapr_machine_init(MachineState *machine) { - sPAPRMachineState *spapr = SPAPR_MACHINE(machine); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); + SpaprMachineState *spapr = SPAPR_MACHINE(machine); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); const char *kernel_filename = machine->kernel_filename; const char *initrd_filename = machine->initrd_filename; PCIHostState *phb; @@ -2773,13 +2827,7 @@ static void spapr_machine_init(MachineState *machine) /* advertise XIVE on POWER9 machines */ if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) { - if (ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, - 0, spapr->max_compat_pvr)) { - spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); - } else if (spapr->irq->ov5 & SPAPR_OV5_XIVE_EXPLOIT) { - error_report("XIVE-only machines require a POWER9 CPU"); - exit(1); - } + spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); } /* init CPUs */ @@ -2800,6 +2848,9 @@ static void spapr_machine_init(MachineState *machine) /* 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(); } /* allocate RAM */ @@ -3023,7 +3074,7 @@ static void spapr_machine_init(MachineState *machine) } } -static int spapr_kvm_type(const char *vm_type) +static int spapr_kvm_type(MachineState *machine, const char *vm_type) { if (!vm_type) { return 0; @@ -3051,7 +3102,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus, #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); + SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE); VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON); if (d) { @@ -3131,14 +3182,14 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus, static char *spapr_get_kvm_type(Object *obj, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + 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); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); g_free(spapr->kvm_type); spapr->kvm_type = g_strdup(value); @@ -3146,7 +3197,7 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp) static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); return spapr->use_hotplug_event_source; } @@ -3154,7 +3205,7 @@ static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp) static void spapr_set_modern_hotplug_events(Object *obj, bool value, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); spapr->use_hotplug_event_source = value; } @@ -3166,7 +3217,7 @@ static bool spapr_get_msix_emulation(Object *obj, Error **errp) static char *spapr_get_resize_hpt(Object *obj, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); switch (spapr->resize_hpt) { case SPAPR_RESIZE_HPT_DEFAULT: @@ -3183,7 +3234,7 @@ static char *spapr_get_resize_hpt(Object *obj, Error **errp) static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); if (strcmp(value, "default") == 0) { spapr->resize_hpt = SPAPR_RESIZE_HPT_DEFAULT; @@ -3212,7 +3263,7 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name, static char *spapr_get_ic_mode(Object *obj, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); if (spapr->irq == &spapr_irq_xics_legacy) { return g_strdup("legacy"); @@ -3228,7 +3279,7 @@ static char *spapr_get_ic_mode(Object *obj, Error **errp) static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + 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"); @@ -3249,14 +3300,14 @@ static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp) static char *spapr_get_host_model(Object *obj, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + 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); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); g_free(spapr->host_model); spapr->host_model = g_strdup(value); @@ -3264,14 +3315,14 @@ static void spapr_set_host_model(Object *obj, const char *value, Error **errp) static char *spapr_get_host_serial(Object *obj, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + 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); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); g_free(spapr->host_serial); spapr->host_serial = g_strdup(value); @@ -3279,8 +3330,8 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp) static void spapr_instance_init(Object *obj) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); spapr->htab_fd = -1; spapr->use_hotplug_event_source = true; @@ -3327,17 +3378,17 @@ static void spapr_instance_init(Object *obj) spapr_get_host_model, spapr_set_host_model, &error_abort); object_property_set_description(obj, "host-model", - "Set host's model-id to use - none|passthrough|string", &error_abort); + "Host model to advertise in guest device tree", &error_abort); object_property_add_str(obj, "host-serial", spapr_get_host_serial, spapr_set_host_serial, &error_abort); object_property_set_description(obj, "host-serial", - "Set host's system-id to use - none|passthrough|string", &error_abort); + "Host serial number to advertise in guest device tree", &error_abort); } static void spapr_machine_finalizefn(Object *obj) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); g_free(spapr->kvm_type); } @@ -3357,7 +3408,7 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) } } -int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr, +int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, void *fdt, int *fdt_start_offset, Error **errp) { uint64_t addr; @@ -3374,7 +3425,7 @@ int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr, static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, bool dedicated_hp_event_source, Error **errp) { - sPAPRDRConnector *drc; + SpaprDrc *drc; uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE; int i; uint64_t addr = addr_start; @@ -3423,7 +3474,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { Error *local_err = NULL; - sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev); + SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); uint64_t size, addr; @@ -3457,8 +3508,8 @@ out: static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev); - sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev); + const SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev); + SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); Error *local_err = NULL; uint64_t size; @@ -3494,16 +3545,16 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp); } -struct sPAPRDIMMState { +struct SpaprDimmState { PCDIMMDevice *dimm; uint32_t nr_lmbs; - QTAILQ_ENTRY(sPAPRDIMMState) next; + QTAILQ_ENTRY(SpaprDimmState) next; }; -static sPAPRDIMMState *spapr_pending_dimm_unplugs_find(sPAPRMachineState *s, +static SpaprDimmState *spapr_pending_dimm_unplugs_find(SpaprMachineState *s, PCDIMMDevice *dimm) { - sPAPRDIMMState *dimm_state = NULL; + SpaprDimmState *dimm_state = NULL; QTAILQ_FOREACH(dimm_state, &s->pending_dimm_unplugs, next) { if (dimm_state->dimm == dimm) { @@ -3513,11 +3564,11 @@ static sPAPRDIMMState *spapr_pending_dimm_unplugs_find(sPAPRMachineState *s, return dimm_state; } -static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr, +static SpaprDimmState *spapr_pending_dimm_unplugs_add(SpaprMachineState *spapr, uint32_t nr_lmbs, PCDIMMDevice *dimm) { - sPAPRDIMMState *ds = NULL; + SpaprDimmState *ds = NULL; /* * If this request is for a DIMM whose removal had failed earlier @@ -3527,7 +3578,7 @@ static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr, */ ds = spapr_pending_dimm_unplugs_find(spapr, dimm); if (!ds) { - ds = g_malloc0(sizeof(sPAPRDIMMState)); + ds = g_malloc0(sizeof(SpaprDimmState)); ds->nr_lmbs = nr_lmbs; ds->dimm = dimm; QTAILQ_INSERT_HEAD(&spapr->pending_dimm_unplugs, ds, next); @@ -3535,17 +3586,17 @@ static sPAPRDIMMState *spapr_pending_dimm_unplugs_add(sPAPRMachineState *spapr, return ds; } -static void spapr_pending_dimm_unplugs_remove(sPAPRMachineState *spapr, - sPAPRDIMMState *dimm_state) +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, +static SpaprDimmState *spapr_recover_pending_dimm_state(SpaprMachineState *ms, PCDIMMDevice *dimm) { - sPAPRDRConnector *drc; + SpaprDrc *drc; uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort); uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; @@ -3574,8 +3625,8 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms, 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)); + 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. */ @@ -3595,28 +3646,29 @@ void spapr_lmb_release(DeviceState *dev) * 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)); + SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev); + SpaprDimmState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev)); pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev)); - object_unparent(OBJECT(dev)); + object_property_set_bool(OBJECT(dev), false, "realized", NULL); 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); + SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev); Error *local_err = NULL; PCDIMMDevice *dimm = PC_DIMM(dev); uint32_t nr_lmbs; uint64_t size, addr_start, addr; int i; - sPAPRDRConnector *drc; + SpaprDrc *drc; size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort); nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; @@ -3667,17 +3719,18 @@ void spapr_core_release(DeviceState *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); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms); CPUCore *cc = CPU_CORE(dev); CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL); if (smc->pre_2_10_has_unused_icps) { - sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); + SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); int i; for (i = 0; i < cc->nr_threads; i++) { @@ -3689,16 +3742,16 @@ static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev) assert(core_slot); core_slot->cpu = NULL; - object_unparent(OBJECT(dev)); + object_property_set_bool(OBJECT(dev), false, "realized", NULL); } static void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); int index; - sPAPRDRConnector *drc; + SpaprDrc *drc; CPUCore *cc = CPU_CORE(dev); if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) { @@ -3720,10 +3773,10 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, spapr_hotplug_req_remove_by_index(drc); } -int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr, +int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, void *fdt, int *fdt_start_offset, Error **errp) { - sPAPRCPUCore *core = SPAPR_CPU_CORE(drc->dev); + SpaprCpuCore *core = SPAPR_CPU_CORE(drc->dev); CPUState *cs = CPU(core->threads[0]); PowerPCCPU *cpu = POWERPC_CPU(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs); @@ -3744,13 +3797,13 @@ int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr, static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); MachineClass *mc = MACHINE_GET_CLASS(spapr); - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); - sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev)); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprCpuCore *core = SPAPR_CPU_CORE(OBJECT(dev)); CPUCore *cc = CPU_CORE(dev); CPUState *cs; - sPAPRDRConnector *drc; + SpaprDrc *drc; Error *local_err = NULL; CPUArchId *core_slot; int index; @@ -3853,10 +3906,10 @@ out: error_propagate(errp, local_err); } -int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr, +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); + SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(drc->dev); int intc_phandle; intc_phandle = spapr_irq_get_phandle(spapr, spapr->fdt_blob, errp); @@ -3879,9 +3932,9 @@ int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr, static void 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); + 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); if (dev->hotplugged && !smc->dr_phb_enabled) { @@ -3901,16 +3954,18 @@ static void spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, 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); + windows_supported, sphb->dma_liobn, + &sphb->nv2_gpa_win_addr, &sphb->nv2_atsd_win_addr, + errp); } static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); - sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev); - sPAPRDRConnector *drc; + 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); Error *local_err = NULL; @@ -3940,18 +3995,19 @@ 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) { - object_unparent(OBJECT(dev)); + object_property_set_bool(OBJECT(dev), false, "realized", NULL); } static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(dev); - sPAPRDRConnector *drc; + SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev); + SpaprDrc *drc; drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index); assert(drc); @@ -3989,9 +4045,9 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - sPAPRMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev)); + SpaprMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev)); MachineClass *mc = MACHINE_GET_CLASS(sms); - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { if (spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) { @@ -4098,10 +4154,11 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine) return machine->possible_cpus; } -static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index, +static void 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) + unsigned n_dma, uint32_t *liobns, + hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp) { /* * New-style PHB window placement. @@ -4146,18 +4203,21 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index, *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; + + *nv2gpa = SPAPR_PCI_NV2RAM64_WIN_BASE + index * SPAPR_PCI_NV2RAM64_WIN_SIZE; + *nv2atsd = SPAPR_PCI_NV2ATSD_WIN_BASE + index * SPAPR_PCI_NV2ATSD_WIN_SIZE; } static ICSState *spapr_ics_get(XICSFabric *dev, int irq) { - sPAPRMachineState *spapr = SPAPR_MACHINE(dev); + 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); + SpaprMachineState *spapr = SPAPR_MACHINE(dev); ics_resend(spapr->ics); } @@ -4172,7 +4232,7 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id) static void spapr_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { - sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + SpaprMachineState *spapr = SPAPR_MACHINE(obj); spapr->irq->print_info(spapr, mon); } @@ -4184,7 +4244,7 @@ int spapr_get_vcpu_id(PowerPCCPU *cpu) void spapr_set_vcpu_id(PowerPCCPU *cpu, int cpu_index, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); int vcpu_id; vcpu_id = spapr_vcpu_id(spapr, cpu_index); @@ -4218,7 +4278,7 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id) static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - sPAPRMachineClass *smc = SPAPR_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); @@ -4267,7 +4327,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) vhc->hpt_mask = spapr_hpt_mask; vhc->map_hptes = spapr_map_hptes; vhc->unmap_hptes = spapr_unmap_hptes; - vhc->store_hpte = spapr_store_hpte; + 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; xic->ics_get = spapr_ics_get; @@ -4283,13 +4344,15 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) 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_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_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_LARGE_DECREMENTER] = SPAPR_CAP_ON; + smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF; spapr_caps_add_properties(smc, &error_abort); - smc->irq = &spapr_irq_xics; + smc->irq = &spapr_irq_dual; smc->dr_phb_enabled = true; } @@ -4297,10 +4360,10 @@ static const TypeInfo spapr_machine_info = { .name = TYPE_SPAPR_MACHINE, .parent = TYPE_MACHINE, .abstract = true, - .instance_size = sizeof(sPAPRMachineState), + .instance_size = sizeof(SpaprMachineState), .instance_init = spapr_instance_init, .instance_finalize = spapr_machine_finalizefn, - .class_size = sizeof(sPAPRMachineClass), + .class_size = sizeof(SpaprMachineClass), .class_init = spapr_machine_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, @@ -4335,34 +4398,61 @@ static const TypeInfo spapr_machine_info = { } \ type_init(spapr_machine_register_##suffix) +/* + * pseries-4.1 + */ +static void spapr_machine_4_1_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(4_1, "4.1", true); + /* * pseries-4.0 */ +static void phb_placement_4_0(SpaprMachineState *spapr, uint32_t index, + uint64_t *buid, hwaddr *pio, + hwaddr *mmio32, hwaddr *mmio64, + unsigned n_dma, uint32_t *liobns, + hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp) +{ + spapr_phb_placement(spapr, index, buid, pio, mmio32, mmio64, n_dma, liobns, + nv2gpa, nv2atsd, errp); + *nv2gpa = 0; + *nv2atsd = 0; +} + static void spapr_machine_4_0_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + 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; } -DEFINE_SPAPR_MACHINE(4_0, "4.0", true); +DEFINE_SPAPR_MACHINE(4_0, "4.0", false); /* * pseries-3.1 */ static void spapr_machine_3_1_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); - static GlobalProperty compat[] = { - { TYPE_SPAPR_MACHINE, "host-model", "passthrough" }, - { TYPE_SPAPR_MACHINE, "host-serial", "passthrough" }, - }; + 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); - compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); 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, "3.1", false); @@ -4373,7 +4463,7 @@ DEFINE_SPAPR_MACHINE(3_1, "3.1", false); static void spapr_machine_3_0_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(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); @@ -4389,7 +4479,7 @@ DEFINE_SPAPR_MACHINE(3_0, "3.0", false); */ static void spapr_machine_2_12_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); static GlobalProperty compat[] = { { TYPE_POWERPC_CPU, "pre-3.0-migration", "on" }, { TYPE_SPAPR_CPU_CORE, "pre-3.0-migration", "on" }, @@ -4411,7 +4501,7 @@ DEFINE_SPAPR_MACHINE(2_12, "2.12", false); static void spapr_machine_2_12_sxxm_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); spapr_machine_2_12_class_options(mc); smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; @@ -4427,7 +4517,7 @@ DEFINE_SPAPR_MACHINE(2_12_sxxm, "2.12-sxxm", false); static void spapr_machine_2_11_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); spapr_machine_2_12_class_options(mc); smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON; @@ -4454,7 +4544,7 @@ DEFINE_SPAPR_MACHINE(2_10, "2.10", false); static void spapr_machine_2_9_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); static GlobalProperty compat[] = { { TYPE_POWERPC_CPU, "pre-2.10-migration", "on" }, }; @@ -4491,10 +4581,11 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false); * pseries-2.7 */ -static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index, +static void phb_placement_2_7(SpaprMachineState *spapr, uint32_t index, uint64_t *buid, hwaddr *pio, hwaddr *mmio32, hwaddr *mmio64, - unsigned n_dma, uint32_t *liobns, Error **errp) + unsigned n_dma, uint32_t *liobns, + hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp) { /* Legacy PHB placement for pseries-2.7 and earlier machine types */ const uint64_t base_buid = 0x800000020000000ULL; @@ -4538,11 +4629,14 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index, * fallback behaviour of automatically splitting a large "32-bit" * window into contiguous 32-bit and 64-bit windows */ + + *nv2gpa = 0; + *nv2atsd = 0; } static void spapr_machine_2_7_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); static GlobalProperty compat[] = { { TYPE_SPAPR_PCI_HOST_BRIDGE, "mem_win_size", "0xf80000000", }, { TYPE_SPAPR_PCI_HOST_BRIDGE, "mem64_win_size", "0", }, @@ -4584,7 +4678,7 @@ DEFINE_SPAPR_MACHINE(2_6, "2.6", false); static void spapr_machine_2_5_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); static GlobalProperty compat[] = { { "spapr-vlan", "use-rx-buffer-pools", "off" }, }; @@ -4603,7 +4697,7 @@ DEFINE_SPAPR_MACHINE(2_5, "2.5", false); static void spapr_machine_2_4_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); spapr_machine_2_5_class_options(mc); smc->dr_lmb_enabled = false;