From 03b3542ac93cb196bf6a6d85e92fa68a894f5256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 6 Apr 2021 10:48:42 +0200 Subject: hw/ppc/mac_newworld: Restrict RAM to 2 GiB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Mac99 and newer machines, the Uninorth PCI host bridge maps the PCI hole region at 2GiB, so the RAM area beside 2GiB is not accessible by the CPU. Restrict the memory to 2GiB to avoid problems such the one reported in the buglink. Buglink: https://bugs.launchpad.net/qemu/+bug/1922391 Reported-by: Håvard Eidnes Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210406084842.2859664-1-f4bug@amsat.org> Reviewed-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'hw/ppc') diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 2175962846..d88b38e925 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -157,6 +157,10 @@ static void ppc_core99_init(MachineState *machine) } /* allocate RAM */ + if (machine->ram_size > 2 * GiB) { + error_report("RAM size more than 2 GiB is not supported"); + exit(1); + } memory_region_add_subregion(get_system_memory(), 0, machine->ram); /* allocate and load firmware ROM */ -- cgit v1.2.3 From bd4160bc6adc2fd5484a9c1cee6df65e6f2f4508 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 15 Mar 2021 12:46:12 -0600 Subject: hw/ppc/pnv_core: Update hflags after setting msr Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-15-richard.henderson@linaro.org> Signed-off-by: David Gibson --- hw/ppc/pnv_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'hw/ppc') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index bd2bf2e044..8c2a15a0fb 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -29,6 +29,7 @@ #include "hw/ppc/pnv_xscom.h" #include "hw/ppc/xics.h" #include "hw/qdev-properties.h" +#include "helper_regs.h" static const char *pnv_core_cpu_typename(PnvCore *pc) { @@ -55,8 +56,8 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu) env->gpr[3] = PNV_FDT_ADDR; env->nip = 0x10; env->msr |= MSR_HVB; /* Hypervisor mode */ - env->spr[SPR_HRMOR] = pc->hrmor; + hreg_compute_hflags(env); pcc->intc_reset(pc->chip, cpu); } -- cgit v1.2.3 From e81f17a3f616a4f2c803aafed60500ac45df9b3d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 15 Mar 2021 12:46:13 -0600 Subject: hw/ppc/spapr_rtas: Update hflags after setting msr Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-16-richard.henderson@linaro.org> Signed-off-by: David Gibson --- hw/ppc/spapr_rtas.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 8a79f9c628..6ec3e71757 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -51,6 +51,7 @@ #include "target/ppc/mmu-hash64.h" #include "target/ppc/mmu-book3s-v3.h" #include "migration/blocker.h" +#include "helper_regs.h" static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState *spapr, uint32_t token, uint32_t nargs, @@ -163,6 +164,7 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, cpu_synchronize_state(CPU(newcpu)); env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); + hreg_compute_hflags(env); /* Enable Power-saving mode Exit Cause exceptions for the new CPU */ lpcr = env->spr[SPR_LPCR]; -- cgit v1.2.3 From ba7e5ac18e7b3232ec93e0d3324bba167b965d70 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 25 Mar 2021 14:50:39 +0100 Subject: hw/ppc: Add emulation of Genesi/bPlan Pegasos II MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new machine called pegasos2 emulating the Genesi/bPlan Pegasos II, a PowerPC board based on the Marvell MV64361 system controller and the VIA VT8231 integrated south bridge/superio chips. It can run Linux, AmigaOS and a wide range of MorphOS versions. Currently a firmware ROM image is needed to boot and only MorphOS has a video driver to produce graphics output. Linux could work too but distros that supported this machine don't include usual video drivers so those only run with serial console for now. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <30cbfb9cbe6f46a1e15a69a75fac45ac39340122.1616680239.git.balaton@eik.bme.hu> Signed-off-by: David Gibson --- hw/ppc/Kconfig | 9 ++++ hw/ppc/meson.build | 2 + hw/ppc/pegasos2.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 hw/ppc/pegasos2.c (limited to 'hw/ppc') diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index d11dc30509..e51e0e5e5a 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -68,6 +68,15 @@ config SAM460EX select USB_OHCI select FDT_PPC +config PEGASOS2 + bool + select MV64361 + select VT82C686 + select IDE_VIA + select SMBUS_EEPROM +# This should come with VT82C686 + select ACPI_X86 + config PREP bool imply PCI_DEVICES diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 218631c883..86d6f379d1 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -78,5 +78,7 @@ ppc_ss.add(when: 'CONFIG_E500', if_true: files( )) # PowerPC 440 Xilinx ML507 reference board. ppc_ss.add(when: 'CONFIG_VIRTEX', if_true: files('virtex_ml507.c')) +# Pegasos2 +ppc_ss.add(when: 'CONFIG_PEGASOS2', if_true: files('pegasos2.c')) hw_arch += {'ppc': ppc_ss} diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c new file mode 100644 index 0000000000..0bfd0928aa --- /dev/null +++ b/hw/ppc/pegasos2.c @@ -0,0 +1,144 @@ +/* + * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator + * + * Copyright (c) 2018-2020 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/ppc/ppc.h" +#include "hw/sysbus.h" +#include "hw/pci/pci_host.h" +#include "hw/irq.h" +#include "hw/pci-host/mv64361.h" +#include "hw/isa/vt82c686.h" +#include "hw/ide/pci.h" +#include "hw/i2c/smbus_eeprom.h" +#include "hw/qdev-properties.h" +#include "sysemu/reset.h" +#include "hw/boards.h" +#include "hw/loader.h" +#include "hw/fw-path-provider.h" +#include "elf.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "sysemu/kvm.h" +#include "kvm_ppc.h" +#include "exec/address-spaces.h" +#include "trace.h" +#include "qemu/datadir.h" +#include "sysemu/device_tree.h" + +#define PROM_FILENAME "pegasos2.rom" +#define PROM_ADDR 0xfff00000 +#define PROM_SIZE 0x80000 + +#define BUS_FREQ_HZ 133333333 + +static void pegasos2_cpu_reset(void *opaque) +{ + PowerPCCPU *cpu = opaque; + + cpu_reset(CPU(cpu)); + cpu->env.spr[SPR_HID1] = 7ULL << 28; +} + +static void pegasos2_init(MachineState *machine) +{ + PowerPCCPU *cpu = NULL; + MemoryRegion *rom = g_new(MemoryRegion, 1); + DeviceState *mv; + PCIBus *pci_bus; + PCIDevice *dev; + I2CBus *i2c_bus; + const char *fwname = machine->firmware ?: PROM_FILENAME; + char *filename; + int sz; + uint8_t *spd_data; + + /* init CPU */ + cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); + if (PPC_INPUT(&cpu->env) != PPC_FLAGS_INPUT_6xx) { + error_report("Incompatible CPU, only 6xx bus supported"); + exit(1); + } + + /* Set time-base frequency */ + cpu_ppc_tb_init(&cpu->env, BUS_FREQ_HZ / 4); + qemu_register_reset(pegasos2_cpu_reset, cpu); + + /* RAM */ + memory_region_add_subregion(get_system_memory(), 0, machine->ram); + + /* allocate and load firmware */ + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, fwname); + if (!filename) { + error_report("Could not find firmware '%s'", fwname); + exit(1); + } + memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fatal); + memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom); + sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, + PPC_ELF_MACHINE, 0, 0); + if (sz <= 0) { + sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE); + } + if (sz <= 0 || sz > PROM_SIZE) { + error_report("Could not load firmware '%s'", filename); + exit(1); + } + g_free(filename); + + /* Marvell Discovery II system controller */ + mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1, + ((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT])); + pci_bus = mv64361_get_pci_bus(mv, 1); + + /* VIA VT8231 South Bridge (multifunction PCI device) */ + /* VT8231 function 0: PCI-to-ISA Bridge */ + dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, + TYPE_VT8231_ISA); + qdev_connect_gpio_out(DEVICE(dev), 0, + qdev_get_gpio_in_named(mv, "gpp", 31)); + + /* VT8231 function 1: IDE Controller */ + dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide"); + pci_ide_create_devs(dev); + + /* VT8231 function 2-3: USB Ports */ + pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci"); + pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci"); + + /* VT8231 function 4: Power Management Controller */ + dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM); + i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); + spd_data = spd_data_generate(DDR, machine->ram_size); + smbus_eeprom_init_one(i2c_bus, 0x57, spd_data); + + /* VT8231 function 5-6: AC97 Audio & Modem */ + pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97); + pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97); + + /* other PC hardware */ + pci_vga_init(pci_bus); +} + +static void pegasos2_machine(MachineClass *mc) +{ + mc->desc = "Genesi/bPlan Pegasos II"; + mc->init = pegasos2_init; + mc->block_default_type = IF_IDE; + mc->default_boot_order = "cd"; + mc->default_display = "std"; + mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9"); + mc->default_ram_id = "pegasos2.ram"; + mc->default_ram_size = 512 * MiB; +} + +DEFINE_MACHINE("pegasos2", pegasos2_machine) -- cgit v1.2.3 From 4b98e72d973f8612d3f65fd1dbcdd232a62bd6d6 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 31 Mar 2021 13:51:23 +1100 Subject: spapr: Rename RTAS_MAX_ADDR to FDT_MAX_ADDR SLOF instantiates RTAS since 744a928ccee9 ("spapr: Stop providing RTAS blob") so the max address applies to the FDT only. This renames the macro and fixes up the comment. This should not cause any behavioral change. Signed-off-by: Alexey Kardashevskiy Message-Id: <20210331025123.29310-1-aik@ozlabs.ru> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 529ff056dd..fd53615df0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -100,7 +100,7 @@ * * We load our kernel at 4M, leaving space for SLOF initial image */ -#define RTAS_MAX_ADDR 0x80000000 /* RTAS must stay below that */ +#define FDT_MAX_ADDR 0x80000000 /* FDT must stay below that */ #define FW_MAX_SIZE 0x400000 #define FW_FILE_NAME "slof.bin" #define FW_OVERHEAD 0x2800000 @@ -1617,11 +1617,11 @@ static void spapr_machine_reset(MachineState *machine) spapr_clear_pending_events(spapr); /* - * We place the device tree and RTAS just below either the top of the RMA, + * 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, RTAS_MAX_ADDR) - FDT_MAX_SIZE; + fdt_addr = MIN(spapr->rma_size, FDT_MAX_ADDR) - FDT_MAX_SIZE; fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE); @@ -2694,7 +2694,7 @@ static void spapr_machine_init(MachineState *machine) 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, RTAS_MAX_ADDR) - FW_OVERHEAD; + 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 -- cgit v1.2.3 From 53d7d7e2b164f97ae36bca3cb3b3cf1ba2abe4c0 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Fri, 2 Apr 2021 15:51:28 +0530 Subject: ppc/spapr: Add support for implement support for H_SCM_HEALTH Add support for H_SCM_HEALTH hcall described at [1] for spapr nvdimms. This enables guest to detect the 'unarmed' status of a specific spapr nvdimm identified by its DRC and if its unarmed, mark the region backed by the nvdimm as read-only. The patch adds h_scm_health() to handle the H_SCM_HEALTH hcall which returns two 64-bit bitmaps (health bitmap, health bitmap mask) derived from 'struct nvdimm->unarmed' member. Linux kernel side changes to enable handling of 'unarmed' nvdimms for ppc64 are proposed at [2]. References: [1] "Hypercall Op-codes (hcalls)" https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/powerpc/papr_hcalls.rst#n220 [2] "powerpc/papr_scm: Mark nvdimm as unarmed if needed during probe" https://lore.kernel.org/linux-nvdimm/20210329113103.476760-1-vaibhav@linux.ibm.com/ Signed-off-by: Vaibhav Jain Message-Id: <20210402102128.213943-1-vaibhav@linux.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_nvdimm.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c index b46c36917c..252204e25f 100644 --- a/hw/ppc/spapr_nvdimm.c +++ b/hw/ppc/spapr_nvdimm.c @@ -31,6 +31,10 @@ #include "qemu/range.h" #include "hw/ppc/spapr_numa.h" +/* DIMM health bitmap bitmap indicators. Taken from kernel's papr_scm.c */ +/* SCM device is unable to persist memory contents */ +#define PAPR_PMEM_UNARMED PPC_BIT(0) + bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm, uint64_t size, Error **errp) { @@ -467,6 +471,37 @@ static target_ulong h_scm_unbind_all(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_SUCCESS; } +static target_ulong h_scm_health(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + + NVDIMMDevice *nvdimm; + uint64_t hbitmap = 0; + uint32_t drc_index = args[0]; + SpaprDrc *drc = spapr_drc_by_index(drc_index); + const uint64_t hbitmap_mask = PAPR_PMEM_UNARMED; + + + /* Ensure that the drc is valid & is valid PMEM dimm and is plugged in */ + if (!drc || !drc->dev || + spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) { + return H_PARAMETER; + } + + nvdimm = NVDIMM(drc->dev); + + /* Update if the nvdimm is unarmed and send its status via health bitmaps */ + if (object_property_get_bool(OBJECT(nvdimm), NVDIMM_UNARMED_PROP, NULL)) { + hbitmap |= PAPR_PMEM_UNARMED; + } + + /* Update the out args with health bitmap/mask */ + args[0] = hbitmap; + args[1] = hbitmap_mask; + + return H_SUCCESS; +} + static void spapr_scm_register_types(void) { /* qemu/scm specific hcalls */ @@ -475,6 +510,7 @@ static void spapr_scm_register_types(void) spapr_register_hypercall(H_SCM_BIND_MEM, h_scm_bind_mem); spapr_register_hypercall(H_SCM_UNBIND_MEM, h_scm_unbind_mem); spapr_register_hypercall(H_SCM_UNBIND_ALL, h_scm_unbind_all); + spapr_register_hypercall(H_SCM_HEALTH, h_scm_health); } type_init(spapr_scm_register_types) -- cgit v1.2.3 From 5642e4513e60b46473422902d7cc34e894e8793d Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Thu, 8 Apr 2021 17:40:48 -0300 Subject: spapr.c: do not use MachineClass::max_cpus to limit CPUs Up to this patch, 'max_cpus' value is hardcoded to 1024 (commit 6244bb7e5811). In theory this patch would simply bump it to 2048, since it's the default NR_CPUS kernel setting for ppc64 servers nowadays, but the whole mechanic of MachineClass:max_cpus is flawed for the pSeries machine. The two supported accelerators, KVM and TCG, can live without it. TCG guests don't have a theoretical limit. The user must be free to emulate as many CPUs as the hardware is capable of. And even if there were a limit, max_cpus is not the proper way to report it since it's a common value checked by SMP code in machine_smp_parse() for KVM as well. For KVM guests, the proper way to limit KVM CPUs is by host configuration via NR_CPUS, not a QEMU hardcoded value. There is no technical reason for a pSeries QEMU guest to forcefully stay below NR_CPUS. This hardcoded value also disregard hosts that might have a lower NR_CPUS limit, say 512. In this case, machine.c:machine_smp_parse() will allow a 1024 value to pass, but then kvm_init() will complain about it because it will exceed NR_CPUS: Number of SMP cpus requested (1024) exceeds the maximum cpus supported by KVM (512) A better 'max_cpus' value would consider host settings, but MachineClass::max_cpus is defined well before machine_init() and kvm_init(). We can't check for KVM limits because it's too soon, so we end up making a guess. This patch makes MachineClass:max_cpus settings innocuous by setting it to INT32_MAX. machine.c:machine_smp_parse() will not fail the verification based on max_cpus, letting kvm_init() do the checking with actual host settings. And TCG guests get to do whatever the hardware is capable of emulating. Signed-off-by: Daniel Henrique Barboza Message-Id: <20210408204049.221802-2-danielhb413@gmail.com> Signed-off-by: David Gibson --- hw/ppc/spapr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fd53615df0..b37ceb8ee8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4487,7 +4487,16 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->init = spapr_machine_init; mc->reset = spapr_machine_reset; mc->block_default_type = IF_SCSI; - mc->max_cpus = 1024; + + /* + * Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values + * should be limited by the host capability instead of hardcoded. + * max_cpus for KVM guests will be checked in kvm_init(), and TCG + * guests are welcome to have as many CPUs as the host are capable + * of emulate. + */ + mc->max_cpus = INT32_MAX; + mc->no_parallel = 1; mc->default_boot_order = ""; mc->default_ram_size = 512 * MiB; -- cgit v1.2.3 From 87758fed7a7a7c00c1bd0c965ae8b94e04ea9359 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 20 Apr 2021 13:51:00 -0300 Subject: spapr_drc.c: handle hotunplug errors in drc_unisolate_logical() At this moment, PAPR does not provide a way to report errors during a device removal operation. This led the pSeries machine to implement extra mechanisms to try to fallback and recover from an error that might have happened during the hotunplug in the guest side. This started to change a bit with commit fe1831eff8a4 ("spapr_drc.c: use DRC reconfiguration to cleanup DIMM unplug state"), where one way to fallback from a memory removal error was introduced. Around the same time, in [1], the idea of using RTAS set-indicator for this role was first introduced. The RTAS set-indicator call, when attempting to UNISOLATE a DRC that is already UNISOLATED or CONFIGURED, returns RTAS_OK and does nothing else for both QEMU and phyp. This gives us an opportunity to use this behavior to signal the hypervisor layer when a device removal errir happens, allowing QEMU/phyp to do a proper error handling. Using set-indicator to report HP errors isn't strange to PAPR, as per R1-13.5.3.4-4. of table 13.7 of current PAPR [2]: "For all DR options: If this is a DR operation that involves the user insert- ing a DR entity, then if the firmware can determine that the inserted entity would cause a system disturbance, then the set-indicator RTAS call must not unisolate the entity and must return an error status which is unique to the particular error." A change was proposed to the pSeries Linux kernel to call set-indicator to move a DRC to 'unisolate' in the case of a hotunplug error in the guest side [3]. Setting a DRC that is already unisolated or configured to 'unisolate' is a no-op (returns RTAS_OK) for QEMU and also for phyp. Being a benign change for hypervisors that doesn't care about handling such errors, we expect the kernel to accept this change at some point. This patch prepares the pSeries machine for this new kernel feature by changing drc_unisolate_logical() to handle guest side hotunplug errors. For CPUs it's a simple matter of setting drc->unplug_requested to 'false', while for LMBs the process is similar to the rollback that is done in rtas_ibm_configure_connector(). [1] https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg06395.html [2] https://openpowerfoundation.org/wp-content/uploads/2020/07/LoPAR-20200611.pdf [3] https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20210416210216.380291-3-danielhb413@gmail.com/ Reviewed-by: David Gibson Signed-off-by: Daniel Henrique Barboza Message-Id: <20210420165100.108368-2-danielhb413@gmail.com> Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 9e16505fa1..6918e0c9d1 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -151,9 +151,32 @@ static uint32_t drc_isolate_logical(SpaprDrc *drc) static uint32_t drc_unisolate_logical(SpaprDrc *drc) { + SpaprMachineState *spapr = NULL; + switch (drc->state) { case SPAPR_DRC_STATE_LOGICAL_UNISOLATE: case SPAPR_DRC_STATE_LOGICAL_CONFIGURED: + /* + * Unisolating a logical DRC that was marked for unplug + * means that the kernel is refusing the removal. + */ + if (drc->unplug_requested && drc->dev) { + if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) { + spapr = SPAPR_MACHINE(qdev_get_machine()); + + spapr_memory_unplug_rollback(spapr, drc->dev); + } + + drc->unplug_requested = false; + error_report("Device hotunplug rejected by the guest " + "for device %s", drc->dev->id); + + /* + * TODO: send a QAPI DEVICE_UNPLUG_ERROR event when + * it is implemented. + */ + } + return RTAS_OUT_SUCCESS; /* Nothing to do */ case SPAPR_DRC_STATE_LOGICAL_AVAILABLE: break; /* see below */ -- cgit v1.2.3 From 8b7e6b07a46809a75b857d30ae47e697e0f9b724 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 1 May 2021 17:24:34 +1000 Subject: target/ppc: rework AIL logic in interrupt delivery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AIL logic is becoming unmanageable spread all over powerpc_excp(), and it is slated to get even worse with POWER10 support. Move it all to a new helper function. Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Signed-off-by: Nicholas Piggin Message-Id: <20210501072436.145444-2-npiggin@gmail.com> [dwg: Corrected tab indenting] Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 7b5cd3553c..2fbe04a689 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1395,7 +1395,8 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, return H_P4; } - if (mflags == AIL_RESERVED) { + if (mflags == 1) { + /* AIL=1 is reserved */ return H_UNSUPPORTED_FLAG; } -- cgit v1.2.3 From 526cdce771fa27c37b68fd235ff9f1caa0bdd563 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 1 May 2021 17:24:35 +1000 Subject: target/ppc: Add POWER10 exception model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POWER10 adds a new bit that modifies interrupt behaviour, LPCR[HAIL], and it removes support for the LPCR[AIL]=0b10 mode. Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Signed-off-by: Nicholas Piggin Message-Id: <20210501072436.145444-3-npiggin@gmail.com> [dwg: Corrected tab indenting] Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 2fbe04a689..7275d0bba1 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1396,7 +1396,12 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, } if (mflags == 1) { - /* AIL=1 is reserved */ + /* AIL=1 is reserved in POWER8/POWER9/POWER10 */ + return H_UNSUPPORTED_FLAG; + } + + if (mflags == 2 && (pcc->insns_flags2 & PPC2_ISA310)) { + /* AIL=2 is reserved in POWER10 (ISA v3.1) */ return H_UNSUPPORTED_FLAG; } -- cgit v1.2.3 From 3e1c8ba98844254cbf2e8134697c3f20faf461d4 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 3 May 2021 16:18:48 +0100 Subject: hw/ppc/spapr_vio: Reset TCE table object with device_cold_reset() The spapr_vio_quiesce_one() function resets the TCE table object (TYPE_SPAPR_TCE_TABLE) via device_legacy_reset(). We know that objects of that type do not have a qbus of their own, so the new device_cold_reset() function (which resets both the device and its child buses) is equivalent here to device_legacy_reset() and we can just switch to the new API. Signed-off-by: Peter Maydell Message-Id: <20210503151849.8766-3-peter.maydell@linaro.org> Signed-off-by: David Gibson --- hw/ppc/spapr_vio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/ppc') diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index ef06e0362c..b59452bcd6 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -310,7 +310,7 @@ int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq) static void spapr_vio_quiesce_one(SpaprVioDevice *dev) { if (dev->tcet) { - device_legacy_reset(DEVICE(dev->tcet)); + device_cold_reset(DEVICE(dev->tcet)); } free_crq(dev); } -- cgit v1.2.3 From 4bb32cd7b1e42c46d274b727c8be8e45b4df3814 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 3 May 2021 16:18:49 +0100 Subject: hw/ppc/pnv_psi: Use device_cold_reset() instead of device_legacy_reset() The pnv_psi.c code uses device_legacy_reset() for two purposes: * to reset itself from its qemu_register_reset() handler * to reset a XiveSource object it has Neither it nor the XiveSource have any qbuses, so the new device_cold_reset() function (which resets both the device and its child buses) is equivalent here to device_legacy_reset() and we can just switch to the new API. Signed-off-by: Peter Maydell Message-Id: <20210503151849.8766-4-peter.maydell@linaro.org> Signed-off-by: David Gibson --- hw/ppc/pnv_psi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/ppc') diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index 3e868c8c8d..292b373f93 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -466,7 +466,7 @@ static void pnv_psi_reset(DeviceState *dev) static void pnv_psi_reset_handler(void *dev) { - device_legacy_reset(DEVICE(dev)); + device_cold_reset(DEVICE(dev)); } static void pnv_psi_realize(DeviceState *dev, Error **errp) @@ -710,7 +710,7 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr, break; case PSIHB9_INTERRUPT_CONTROL: if (val & PSIHB9_IRQ_RESET) { - device_legacy_reset(DEVICE(&psi9->source)); + device_cold_reset(DEVICE(&psi9->source)); } psi->regs[reg] = val; break; -- cgit v1.2.3