diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/core/cpu-common.c | 9 | ||||
| -rw-r--r-- | hw/ppc/pef.c | 6 | ||||
| -rw-r--r-- | hw/ppc/spapr.c | 8 | ||||
| -rw-r--r-- | hw/ppc/spapr_nvdimm.c | 16 | ||||
| -rw-r--r-- | hw/ppc/spapr_pci_vfio.c | 40 | ||||
| -rw-r--r-- | hw/ppc/spapr_rtas.c | 15 |
6 files changed, 65 insertions, 29 deletions
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 9530e266ec..e2f5a64604 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -109,15 +109,6 @@ void cpu_dump_state(CPUState *cpu, FILE *f, int flags) } } -void cpu_dump_statistics(CPUState *cpu, int flags) -{ - CPUClass *cc = CPU_GET_CLASS(cpu); - - if (cc->dump_statistics) { - cc->dump_statistics(cpu, flags); - } -} - void cpu_reset(CPUState *cpu) { device_cold_reset(DEVICE(cpu)); diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c index 573be3ed79..cc44d5e339 100644 --- a/hw/ppc/pef.c +++ b/hw/ppc/pef.c @@ -41,7 +41,7 @@ struct PefGuest { ConfidentialGuestSupport parent_obj; }; -static int kvmppc_svm_init(Error **errp) +static int kvmppc_svm_init(ConfidentialGuestSupport *cgs, Error **errp) { #ifdef CONFIG_KVM static Error *pef_mig_blocker; @@ -65,6 +65,8 @@ static int kvmppc_svm_init(Error **errp) /* NB: This can fail if --only-migratable is used */ migrate_add_blocker(pef_mig_blocker, &error_fatal); + cgs->ready = true; + return 0; #else g_assert_not_reached(); @@ -102,7 +104,7 @@ int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) return -1; } - return kvmppc_svm_init(errp); + return kvmppc_svm_init(cgs, errp); } int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c23bcc4490..4dd90b75cc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1005,7 +1005,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset) _FDT(chosen = fdt_add_subnode(fdt, 0, "chosen")); if (reset) { - const char *boot_device = machine->boot_order; + const char *boot_device = spapr->boot_device; char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus); size_t cb = 0; char *bootlist = get_boot_devices_list(&cb); @@ -2376,8 +2376,10 @@ static SaveVMHandlers savevm_htab_handlers = { static void spapr_boot_set(void *opaque, const char *boot_device, Error **errp) { - MachineState *machine = MACHINE(opaque); - machine->boot_order = g_strdup(boot_device); + 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) diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c index 252204e25f..91de1052f2 100644 --- a/hw/ppc/spapr_nvdimm.c +++ b/hw/ppc/spapr_nvdimm.c @@ -35,6 +35,18 @@ /* SCM device is unable to persist memory contents */ #define PAPR_PMEM_UNARMED PPC_BIT(0) +/* + * The nvdimm size should be aligned to SCM block size. + * The SCM block size should be aligned to SPAPR_MEMORY_BLOCK_SIZE + * in order to have SCM regions not to overlap with dimm memory regions. + * The SCM devices can have variable block sizes. For now, fixing the + * block size to the minimum value. + */ +#define SPAPR_MINIMUM_SCM_BLOCK_SIZE SPAPR_MEMORY_BLOCK_SIZE + +/* Have an explicit check for alignment */ +QEMU_BUILD_BUG_ON(SPAPR_MINIMUM_SCM_BLOCK_SIZE % SPAPR_MEMORY_BLOCK_SIZE); + bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm, uint64_t size, Error **errp) { @@ -163,11 +175,11 @@ int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt) { - int offset = fdt_subnode_offset(fdt, 0, "persistent-memory"); + int offset = fdt_subnode_offset(fdt, 0, "ibm,persistent-memory"); GSList *iter, *nvdimms = nvdimm_get_device_list(); if (offset < 0) { - offset = fdt_add_subnode(fdt, 0, "persistent-memory"); + offset = fdt_add_subnode(fdt, 0, "ibm,persistent-memory"); _FDT(offset); _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1))); _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0))); diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index 7817cf72ee..f3b37df8ea 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -46,6 +46,16 @@ void spapr_phb_vfio_reset(DeviceState *qdev) spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev)); } +static void spapr_eeh_pci_find_device(PCIBus *bus, PCIDevice *pdev, + void *opaque) +{ + bool *found = opaque; + + if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { + *found = true; + } +} + int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, unsigned int addr, int option) { @@ -58,17 +68,33 @@ int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, break; case RTAS_EEH_ENABLE: { PCIHostState *phb; - PCIDevice *pdev; + bool found = false; /* - * The EEH functionality is enabled on basis of PCI device, - * instead of PE. We need check the validity of the PCI - * device address. + * The EEH functionality is enabled per sphb level instead of + * per PCI device. We have already identified this specific sphb + * based on buid passed as argument to ibm,set-eeh-option rtas + * call. Now we just need to check the validity of the PCI + * pass-through devices (vfio-pci) under this sphb bus. + * We have already validated that all the devices under this sphb + * are from same iommu group (within same PE) before comming here. + * + * Prior to linux commit 98ba956f6a389 ("powerpc/pseries/eeh: + * Rework device EEH PE determination") kernel would call + * eeh-set-option for each device in the PE using the device's + * config_address as the argument rather than the PE address. + * Hence if we check validity of supplied config_addr whether + * it matches to this PHB will cause issues with older kernel + * versions v5.9 and older. If we return an error from + * eeh-set-option when the argument isn't a valid PE address + * then older kernels (v5.9 and older) will interpret that as + * EEH not being supported. */ phb = PCI_HOST_BRIDGE(sphb); - pdev = pci_find_device(phb->bus, - (addr >> 16) & 0xFF, (addr >> 8) & 0xFF); - if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { + pci_for_each_device(phb->bus, (addr >> 16) & 0xFF, + spapr_eeh_pci_find_device, &found); + + if (!found) { return RTAS_OUT_PARAM_ERROR; } diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 03355b4c0a..b476382ae6 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -132,8 +132,8 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, target_ulong id, start, r3; PowerPCCPU *newcpu; CPUPPCState *env; - PowerPCCPUClass *pcc; target_ulong lpcr; + target_ulong caller_lpcr; if (nargs != 3 || nret != 1) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); @@ -152,7 +152,6 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, } env = &newcpu->env; - pcc = POWERPC_CPU_GET_CLASS(newcpu); if (!CPU(newcpu)->halted) { rtas_st(rets, 0, RTAS_OUT_HW_ERROR); @@ -164,11 +163,15 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); hreg_compute_hflags(env); - /* Enable Power-saving mode Exit Cause exceptions for the new CPU */ + caller_lpcr = callcpu->env.spr[SPR_LPCR]; lpcr = env->spr[SPR_LPCR]; - if (!pcc->interrupts_big_endian(callcpu)) { - lpcr |= LPCR_ILE; - } + + /* Set ILE the same way */ + lpcr = (lpcr & ~LPCR_ILE) | (caller_lpcr & LPCR_ILE); + + /* Set AIL the same way */ + lpcr = (lpcr & ~LPCR_AIL) | (caller_lpcr & LPCR_AIL); + if (env->mmu_model == POWERPC_MMU_3_00) { /* * New cpus are expected to start in the same radix/hash mode |