From a69dc537cc1a6d3c3cb35d30197ed45914a150c3 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 21 Aug 2018 13:27:48 +0200 Subject: ppc: Remove deprecated ppcemb target There is no known available OS for ppc around anymore that uses page sizes below 4k, so it does not make much sense that we keep wasting our time on building and testing the ppcemb-softmmu target. It has been deprecated since two releases, and nobody complained, so let's remove this now. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- configure | 13 +++---------- cpus.c | 1 - default-configs/ppcemb-softmmu.mak | 23 ----------------------- hw/ppc/ppc405_boards.c | 14 -------------- hw/ppc/ppc440_bamboo.c | 7 ------- hw/ppc/sam460ex.c | 7 ------- hw/ppc/virtex_ml507.c | 7 ------- include/exec/poison.h | 1 - qapi/common.json | 2 +- qemu-deprecated.texi | 6 ------ target/ppc/cpu-qom.h | 2 -- target/ppc/cpu.h | 16 ---------------- target/ppc/kvm.c | 4 +--- target/ppc/mmu_helper.c | 6 +++--- target/ppc/translate_init.inc.c | 35 +---------------------------------- tests/machine-none-test.c | 1 - 16 files changed, 9 insertions(+), 136 deletions(-) delete mode 100644 default-configs/ppcemb-softmmu.mak diff --git a/configure b/configure index 58862d2..7fd989a 100755 --- a/configure +++ b/configure @@ -195,8 +195,7 @@ supported_kvm_target() { i386:i386 | i386:x86_64 | i386:x32 | \ x86_64:i386 | x86_64:x86_64 | x86_64:x32 | \ mips:mips | mipsel:mips | \ - ppc:ppc | ppcemb:ppc | ppc64:ppc | \ - ppc:ppc64 | ppcemb:ppc64 | ppc64:ppc64 | \ + ppc:ppc | ppc64:ppc | ppc:ppc64 | ppc64:ppc64 | \ s390x:s390x) return 0 ;; @@ -6951,7 +6950,7 @@ if test "$linux" = "yes" ; then i386|x86_64|x32) linux_arch=x86 ;; - ppcemb|ppc|ppc64) + ppc|ppc64) linux_arch=powerpc ;; s390x) @@ -6981,7 +6980,7 @@ target_name=$(echo $target | cut -d '-' -f 1) target_bigendian="no" case "$target_name" in - armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) + armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -7109,12 +7108,6 @@ case "$target_name" in gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml" target_compiler=$cross_cc_powerpc ;; - ppcemb) - TARGET_BASE_ARCH=ppc - TARGET_ABI_DIR=ppc - gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml" - target_compiler=$cross_cc_ppcemb - ;; ppc64) TARGET_BASE_ARCH=ppc TARGET_ABI_DIR=ppc diff --git a/cpus.c b/cpus.c index 8ee6e5d..f66cb67 100644 --- a/cpus.c +++ b/cpus.c @@ -2251,7 +2251,6 @@ static CpuInfoArch sysemu_target_to_cpuinfo_arch(SysEmuTarget target) return CPU_INFO_ARCH_X86; case SYS_EMU_TARGET_PPC: - case SYS_EMU_TARGET_PPCEMB: case SYS_EMU_TARGET_PPC64: return CPU_INFO_ARCH_PPC; diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak deleted file mode 100644 index ac44f15..0000000 --- a/default-configs/ppcemb-softmmu.mak +++ /dev/null @@ -1,23 +0,0 @@ -# Default configuration for ppcemb-softmmu - -include pci.mak -include sound.mak -include usb.mak -CONFIG_PPC4XX=y -CONFIG_M48T59=y -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_I8257=y -CONFIG_OPENPIC=y -CONFIG_PFLASH_CFI01=y -CONFIG_PFLASH_CFI02=y -CONFIG_PTIMER=y -CONFIG_I8259=y -CONFIG_XILINX=y -CONFIG_XILINX_ETHLITE=y -CONFIG_USB_EHCI_SYSBUS=y -CONFIG_SM501=y -CONFIG_DDC=y -CONFIG_IDE_SII3112=y -CONFIG_I2C=y -CONFIG_BITBANG_I2C=y diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index f5a9c24..3be3fe4 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -162,13 +162,6 @@ static void ref405ep_init(MachineState *machine) DriveInfo *dinfo; MemoryRegion *sysmem = get_system_memory(); -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* XXX: fix this */ memory_region_allocate_system_memory(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000); @@ -463,13 +456,6 @@ static void taihu_405ep_init(MachineState *machine) int fl_idx, fl_sectors; DriveInfo *dinfo; -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* RAM is soldered to the board so the size cannot be changed */ ram_size = 0x08000000; memory_region_allocate_system_memory(ram, NULL, "taihu_405ep.ram", diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 3d4c43b..f5720f9 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -195,13 +195,6 @@ static void bamboo_init(MachineState *machine) exit(1); } -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - qemu_register_reset(main_cpu_reset, cpu); ppc_booke_timers_init(cpu, 400000000, 0); ppc_dcr_init(env, NULL, NULL); diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 9c77183..250fb86 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -419,13 +419,6 @@ static void sam460ex_init(MachineState *machine) exit(1); } -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - qemu_register_reset(main_cpu_reset, cpu); boot_info = g_malloc0(sizeof(*boot_info)); env->load_info = boot_info; diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 7891464..ee9b4b4 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -211,13 +211,6 @@ static void virtex_init(MachineState *machine) int kernel_size; int i; -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* init CPUs */ cpu = ppc440_init_xilinx(&ram_size, 1, machine->cpu_type, 400000000); env = &cpu->env; diff --git a/include/exec/poison.h b/include/exec/poison.h index 41cd2eb..97d3b56 100644 --- a/include/exec/poison.h +++ b/include/exec/poison.h @@ -24,7 +24,6 @@ #pragma GCC poison TARGET_NIOS2 #pragma GCC poison TARGET_OPENRISC #pragma GCC poison TARGET_PPC -#pragma GCC poison TARGET_PPCEMB #pragma GCC poison TARGET_PPC64 #pragma GCC poison TARGET_ABI32 #pragma GCC poison TARGET_S390X diff --git a/qapi/common.json b/qapi/common.json index c367adc..50ac121 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -146,6 +146,6 @@ 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', - 'ppc64', 'ppcemb', 'riscv32', 'riscv64', 's390x', 'sh4', + 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32', 'x86_64', 'xtensa', 'xtensaeb' ] } diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index 1b9c007..a0db7a5 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -162,12 +162,6 @@ replaced by the ``target'' output member. The ``ivshmem'' device type is replaced by either the ``ivshmem-plain'' or ``ivshmem-doorbell`` device types. -@subsection Page size support < 4k for embedded PowerPC CPUs (since 2.12.0) - -qemu-system-ppcemb will be removed. qemu-system-ppc (or qemu-system-ppc64) -should be used instead. That means that embedded 4xx PowerPC CPUs will not -support page sizes < 4096 any longer. - @section System emulator machines @subsection pc-0.10 and pc-0.11 (since 3.0) diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 433a71e..4ea6769 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -24,8 +24,6 @@ #ifdef TARGET_PPC64 #define TYPE_POWERPC_CPU "powerpc64-cpu" -#elif defined(TARGET_PPCEMB) -#define TYPE_POWERPC_CPU "embedded-powerpc-cpu" #else #define TYPE_POWERPC_CPU "powerpc-cpu" #endif diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ec14934..b5b8f6f 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -52,23 +52,7 @@ #else /* defined (TARGET_PPC64) */ /* PowerPC 32 definitions */ #define TARGET_LONG_BITS 32 - -#if defined(TARGET_PPCEMB) -/* Specific definitions for PowerPC embedded */ -/* BookE have 36 bits physical address space */ -#if defined(CONFIG_USER_ONLY) -/* It looks like a lot of Linux programs assume page size - * is 4kB long. This is evil, but we have to deal with it... - */ -#define TARGET_PAGE_BITS 12 -#else /* defined(CONFIG_USER_ONLY) */ -/* Pages can be 1 kB small */ -#define TARGET_PAGE_BITS 10 -#endif /* defined(CONFIG_USER_ONLY) */ -#else /* defined(TARGET_PPCEMB) */ -/* "standard" PowerPC 32 definitions */ #define TARGET_PAGE_BITS 12 -#endif /* defined(TARGET_PPCEMB) */ #define TARGET_PHYS_ADDR_SPACE_BITS 36 #define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 9211ee2..ef63842 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1315,9 +1315,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) return 0; } -#if defined(TARGET_PPCEMB) -#define PPC_INPUT_INT PPC40x_INPUT_INT -#elif defined(TARGET_PPC64) +#if defined(TARGET_PPC64) #define PPC_INPUT_INT PPC970_INPUT_INT #else #define PPC_INPUT_INT PPC6xx_INPUT_INT diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index e6739e6..04f8317 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -2363,12 +2363,12 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT) & PPC4XX_TLBHI_SIZE_MASK); /* We cannot handle TLB size < TARGET_PAGE_SIZE. - * If this ever occurs, one should use the ppcemb target instead - * of the ppc or ppc64 one + * If this ever occurs, we should implement TARGET_PAGE_BITS_VARY */ if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) { cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u " - "are not supported (%d)\n", + "are not supported (%d)\n" + "Please implement TARGET_PAGE_BITS_VARY\n", tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7)); } tlb->EPN = val & ~(tlb->size - 1); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index d920d3e..263e63c 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9647,17 +9647,6 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu) return 0; } -static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc) -{ -#ifdef TARGET_PPCEMB - return pcc->mmu_model == POWERPC_MMU_BOOKE || - pcc->mmu_model == POWERPC_MMU_SOFT_4xx || - pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z; -#else - return true; -#endif -} - static void ppc_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -9681,8 +9670,6 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) } } - assert(ppc_cpu_is_valid(pcc)); - create_ppc_opcodes(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); @@ -9933,10 +9920,6 @@ static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) return -1; } - if (!ppc_cpu_is_valid(pcc)) { - return -1; - } - return pcc->pvr == pvr ? 0 : -1; } @@ -9967,10 +9950,6 @@ static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b) return -1; } - if (!ppc_cpu_is_valid(pcc)) { - return -1; - } - if (pcc->pvr_match(pcc, pvr)) { return 0; } @@ -10036,11 +10015,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) g_free(typename); g_free(cpu_model); - if (oc && ppc_cpu_is_valid(POWERPC_CPU_CLASS(oc))) { - return oc; - } - - return NULL; + return oc; } static void ppc_cpu_parse_featurestr(const char *type, char *features, @@ -10146,9 +10121,6 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data) char *name; int i; - if (!ppc_cpu_is_valid(pcc)) { - return; - } if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) { return; } @@ -10206,11 +10178,6 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) const char *typename; CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - if (!ppc_cpu_is_valid(pcc)) { - return; - } typename = object_class_get_name(oc); info = g_malloc0(sizeof(*info)); diff --git a/tests/machine-none-test.c b/tests/machine-none-test.c index 7e72466..2b3b750 100644 --- a/tests/machine-none-test.c +++ b/tests/machine-none-test.c @@ -44,7 +44,6 @@ static struct arch2cpu cpus_map[] = { { "or1k", "or1200" }, { "ppc", "604" }, { "ppc64", "power8e_v2.1" }, - { "ppcemb", "440epb" }, { "s390x", "qemu" }, { "sh4", "sh7750r" }, { "sh4eb", "sh7751r" }, -- cgit v1.1 From eceba3477e7fa9b2c0a711a60edbdb7bfa8e4dcd Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 24 Aug 2018 16:31:01 -0400 Subject: spapr: fix leak of rev array Introduced in 04d595b300 ("spapr: do not use CPU_FOREACH_REVERSE", 2018-08-23) Fixes: CID1395181 Reported-by: Peter Maydell Signed-off-by: Emilio G. Cota Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4edb6c7..505d4c8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -607,6 +607,7 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) spapr_populate_cpu_dt(cs, fdt, offset, spapr); } + g_free(rev); } static uint32_t spapr_pc_dimm_node(MemoryDeviceInfoList *list, ram_addr_t addr) -- cgit v1.1 From bc9b1f10f29dd7e717e6b5a050cbe5fbe8537200 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 24 Aug 2018 17:30:04 +0200 Subject: spapr_pci: fix potential NULL pointer dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 2c88b098e76fd added a call to SPAPR_MACHINE_GET_CLASS(spapr) in spapr_phb_realize() before we check spapr isn't NULL. This causes QEMU to crash when starting a non-pseries machine with a sPAPR PHB. This could be fixed by setting the smc variable after the null check, but it seems more explicit to use a ternary operator to skip the call to SPAPR_MACHINE_GET_CLASS() if spapr is NULL, since spapr_phb_realize() will return immediately in this case. This was reported by Coverity (CID 1395170 and 1395183). Fixes: 2c88b098e76fde0c7fcc0476dd3f80ce58409505 Signed-off-by: Greg Kurz Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5cd676e..6bcb4f4 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1559,7 +1559,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) sPAPRMachineState *spapr = (sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(), TYPE_SPAPR_MACHINE); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + sPAPRMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL; SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); -- cgit v1.1 From 9b164a466767ccc3bd9ac2c6f16e4f0bb39e258a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:05 +0100 Subject: macio: move MACIOIDEState type declarations to macio.h Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ide/macio.c | 1 + hw/ppc/mac.h | 26 -------------------------- include/hw/misc/macio/macio.h | 26 ++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index d3a85cb..f23961e 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -26,6 +26,7 @@ #include "hw/hw.h" #include "hw/ppc/mac.h" #include "hw/ppc/mac_dbdma.h" +#include "hw/misc/macio/macio.h" #include "sysemu/block-backend.h" #include "sysemu/dma.h" diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 41fd289..a741300 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -86,32 +86,6 @@ typedef struct Core99MachineState { uint8_t via_config; } Core99MachineState; -/* MacIO */ -#define TYPE_MACIO_IDE "macio-ide" -#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) - -typedef struct MACIOIDEState { - /*< private >*/ - SysBusDevice parent_obj; - /*< public >*/ - uint32_t channel; - qemu_irq real_ide_irq; - qemu_irq real_dma_irq; - qemu_irq ide_irq; - qemu_irq dma_irq; - - MemoryRegion mem; - IDEBus bus; - IDEDMA dma; - void *dbdma; - bool dma_active; - uint32_t timing_reg; - uint32_t irq_reg; -} MACIOIDEState; - -void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); -void macio_ide_register_dma(MACIOIDEState *ide); - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index cfaa145..0c3964e 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -34,6 +34,32 @@ #include "hw/ppc/mac_dbdma.h" #include "hw/ppc/openpic.h" +/* MacIO IDE */ +#define TYPE_MACIO_IDE "macio-ide" +#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) + +typedef struct MACIOIDEState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + uint32_t channel; + qemu_irq real_ide_irq; + qemu_irq real_dma_irq; + qemu_irq ide_irq; + qemu_irq dma_irq; + + MemoryRegion mem; + IDEBus bus; + IDEDMA dma; + void *dbdma; + bool dma_active; + uint32_t timing_reg; + uint32_t irq_reg; +} MACIOIDEState; + +void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); +void macio_ide_register_dma(MACIOIDEState *ide); + #define TYPE_MACIO "macio" #define MACIO(obj) OBJECT_CHECK(MacIOState, (obj), TYPE_MACIO) -- cgit v1.1 From bf31c56f096ae11367c6ba19a47387d008791996 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:06 +0100 Subject: macio: add macio bus to help with fw path generation As the in-built IDE controller is attached to the macio bus then we should also model this the same in QEMU to aid fw path generation. Note that all existing macio devices are moved onto the new macio bus so that the qdev tree accurately reflects the real hardware. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/macio.c | 37 ++++++++++++++++++++++++++++--------- include/hw/misc/macio/macio.h | 10 ++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 52aa377..229bfdd 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -90,6 +90,15 @@ static void macio_bar_setup(MacIOState *s) macio_escc_legacy_setup(s); } +static void macio_init_child_obj(MacIOState *s, const char *childname, + void *child, size_t childsize, + const char *childtype) +{ + object_initialize_child(OBJECT(s), childname, child, childsize, childtype, + &error_abort, NULL); + qdev_set_parent_bus(DEVICE(child), BUS(&s->macio_bus)); +} + static void macio_common_realize(PCIDevice *d, Error **errp) { MacIOState *s = MACIO(d); @@ -211,7 +220,7 @@ static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size, { gchar *name = g_strdup_printf("ide[%i]", index); - sysbus_init_child_obj(OBJECT(s), name, ide, ide_size, TYPE_MACIO_IDE); + macio_init_child_obj(s, name, ide, ide_size, TYPE_MACIO_IDE); memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000), &ide->mem); g_free(name); @@ -229,7 +238,7 @@ static void macio_oldworld_init(Object *obj) qdev_prop_allow_set_link_before_realize, 0, NULL); - sysbus_init_child_obj(obj, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA); + macio_init_child_obj(s, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA); object_initialize(&os->nvram, sizeof(os->nvram), TYPE_MACIO_NVRAM); dev = DEVICE(&os->nvram); @@ -340,7 +349,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) object_property_set_link(OBJECT(&s->pmu), OBJECT(sysbus_dev), "gpio", &error_abort); qdev_prop_set_bit(DEVICE(&s->pmu), "has-adb", ns->has_adb); - qdev_set_parent_bus(DEVICE(&s->pmu), sysbus_get_default()); + qdev_set_parent_bus(DEVICE(&s->pmu), BUS(&s->macio_bus)); object_property_add_child(OBJECT(s), "pmu", OBJECT(&s->pmu), NULL); object_property_set_bool(OBJECT(&s->pmu), true, "realized", &err); @@ -356,7 +365,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) } else { /* CUDA */ object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA); - qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); + qdev_set_parent_bus(DEVICE(&s->cuda), BUS(&s->macio_bus)); object_property_add_child(OBJECT(s), "cuda", OBJECT(&s->cuda), NULL); qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency", s->frequency); @@ -385,8 +394,8 @@ static void macio_newworld_init(Object *obj) qdev_prop_allow_set_link_before_realize, 0, NULL); - sysbus_init_child_obj(obj, "gpio", &ns->gpio, sizeof(ns->gpio), - TYPE_MACIO_GPIO); + macio_init_child_obj(s, "gpio", &ns->gpio, sizeof(ns->gpio), + TYPE_MACIO_GPIO); for (i = 0; i < 2; i++) { macio_init_ide(s, &ns->ide[i], sizeof(ns->ide[i]), i); @@ -399,10 +408,13 @@ static void macio_instance_init(Object *obj) memory_region_init(&s->bar, obj, "macio", 0x80000); - sysbus_init_child_obj(obj, "dbdma", &s->dbdma, sizeof(s->dbdma), - TYPE_MAC_DBDMA); + qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS, + DEVICE(obj), "macio.0"); - sysbus_init_child_obj(obj, "escc", &s->escc, sizeof(s->escc), TYPE_ESCC); + macio_init_child_obj(s, "dbdma", &s->dbdma, sizeof(s->dbdma), + TYPE_MAC_DBDMA); + + macio_init_child_obj(s, "escc", &s->escc, sizeof(s->escc), TYPE_ESCC); } static const VMStateDescription vmstate_macio_oldworld = { @@ -470,6 +482,12 @@ static void macio_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } +static const TypeInfo macio_bus_info = { + .name = TYPE_MACIO_BUS, + .parent = TYPE_BUS, + .instance_size = sizeof(MacIOBusState), +}; + static const TypeInfo macio_oldworld_type_info = { .name = TYPE_OLDWORLD_MACIO, .parent = TYPE_MACIO, @@ -501,6 +519,7 @@ static const TypeInfo macio_type_info = { static void macio_register_types(void) { + type_register_static(&macio_bus_info); type_register_static(&macio_type_info); type_register_static(&macio_oldworld_type_info); type_register_static(&macio_newworld_type_info); diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index 0c3964e..3189973 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -34,6 +34,15 @@ #include "hw/ppc/mac_dbdma.h" #include "hw/ppc/openpic.h" +/* MacIO virtual bus */ +#define TYPE_MACIO_BUS "macio-bus" +#define MACIO_BUS(obj) OBJECT_CHECK(MacIOBusState, (obj), TYPE_MACIO_BUS) + +typedef struct MacIOBusState { + /*< private >*/ + BusState parent_obj; +} MacIOBusState; + /* MacIO IDE */ #define TYPE_MACIO_IDE "macio-ide" #define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) @@ -68,6 +77,7 @@ typedef struct MacIOState { PCIDevice parent; /*< public >*/ + MacIOBusState macio_bus; MemoryRegion bar; CUDAState cuda; PMUState pmu; -- cgit v1.1 From 5c8e3d17eda655ee7644a41cc0df646c7280ab2f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:07 +0100 Subject: macio: add addr property to macio IDE object This contains the offset of the IDE controller within the macio address space and is required to allow the address to be included within the fw path. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ide/macio.c | 1 + hw/misc/macio/macio.c | 5 +++-- include/hw/misc/macio/macio.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index f23961e..bab8c45 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -461,6 +461,7 @@ static void macio_ide_initfn(Object *obj) static Property macio_ide_properties[] = { DEFINE_PROP_UINT32("channel", MACIOIDEState, channel, 0), + DEFINE_PROP_UINT32("addr", MACIOIDEState, addr, -1), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 229bfdd..94da85c 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -219,10 +219,11 @@ static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size, int index) { gchar *name = g_strdup_printf("ide[%i]", index); + uint32_t addr = 0x1f000 + ((index + 1) * 0x1000); macio_init_child_obj(s, name, ide, ide_size, TYPE_MACIO_IDE); - memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000), - &ide->mem); + qdev_prop_set_uint32(DEVICE(ide), "addr", addr); + memory_region_add_subregion(&s->bar, addr, &ide->mem); g_free(name); } diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index 3189973..970058b 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -51,6 +51,7 @@ typedef struct MACIOIDEState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ + uint32_t addr; uint32_t channel; qemu_irq real_ide_irq; qemu_irq real_dma_irq; -- cgit v1.1 From ac43eb2e1397e897660384fef24f633fcdb3255d Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:08 +0100 Subject: grackle: set device fw_name and address for correct fw path generation Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/grackle.c | 17 +++++++++++++++++ hw/ppc/mac_oldworld.c | 1 + 2 files changed, 18 insertions(+) diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 4810a4d..5a151e9 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -37,6 +37,7 @@ typedef struct GrackleState { PCIHostState parent_obj; + uint32_t ofw_addr; HeathrowState *pic; qemu_irq irqs[4]; MemoryRegion pci_mmio; @@ -146,12 +147,28 @@ static const TypeInfo grackle_pci_info = { }, }; +static char *grackle_ofw_unit_address(const SysBusDevice *dev) +{ + GrackleState *s = GRACKLE_PCI_HOST_BRIDGE(dev); + + return g_strdup_printf("%x", s->ofw_addr); +} + +static Property grackle_properties[] = { + DEFINE_PROP_UINT32("ofw-addr", GrackleState, ofw_addr, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void grackle_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = grackle_realize; + dc->props = grackle_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = grackle_ofw_unit_address; } static const TypeInfo grackle_host_info = { diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 80b5525..c7b73e2 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -254,6 +254,7 @@ static void ppc_heathrow_init(MachineState *machine) /* Grackle PCI host bridge */ dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(dev, "ofw-addr", 0x80000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); -- cgit v1.1 From bbcc635fcdf3050b08ec67726e2f5e9d206e876d Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:09 +0100 Subject: mac_oldworld: implement custom FWPathProvider This enables the correct generation of bootdevice fw paths for in-built IDE and virtio-pci-blk devices suitable for OpenBIOS. Note we also set the MachineClass ignore_boot_device_suffixes property to true since an additional disk node should not be added except for virtio devices. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ppc/mac_oldworld.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index c7b73e2..9891c32 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -42,6 +42,7 @@ #include "hw/misc/macio/macio.h" #include "hw/ide.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" @@ -373,6 +374,54 @@ static void ppc_heathrow_init(MachineState *machine) qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + MACIOIDEState *macio_ide; + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-oldworld")) { + pci = PCI_DEVICE(dev); + return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn)); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) { + macio_ide = MACIO_IDE(dev); + return g_strdup_printf("ata-3@%x", macio_ide->addr); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup("cdrom"); + } + + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static int heathrow_kvm_type(const char *arg) { /* Always force PR KVM */ @@ -382,6 +431,7 @@ static int heathrow_kvm_type(const char *arg) static void heathrow_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Heathrow based PowerMAC"; mc->init = ppc_heathrow_init; @@ -395,12 +445,18 @@ static void heathrow_class_init(ObjectClass *oc, void *data) mc->kvm_type = heathrow_kvm_type; mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("750_v3.1"); mc->default_display = "std"; + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = heathrow_fw_dev_path; } static const TypeInfo ppc_heathrow_machine_info = { .name = MACHINE_TYPE_NAME("g3beige"), .parent = TYPE_MACHINE, - .class_init = heathrow_class_init + .class_init = heathrow_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void ppc_heathrow_register_types(void) -- cgit v1.1 From 03756c840e6e50f37c66a8c388f31cd59c5fdeb4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:10 +0100 Subject: uninorth: add ofw-addr property to allow correct fw path generation Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 16 ++++++++++++++++ hw/ppc/mac_newworld.c | 1 + include/hw/pci-host/uninorth.h | 1 + 3 files changed, 18 insertions(+) diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index a843aa7..1378c5c 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -118,6 +118,13 @@ static void pci_unin_init_irqs(UNINHostState *s) } } +static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev) +{ + UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); + + return g_strdup_printf("%x", s->ofw_addr); +} + static void pci_unin_main_realize(DeviceState *dev, Error **errp) { UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); @@ -455,12 +462,21 @@ static const TypeInfo unin_internal_pci_host_info = { }, }; +static Property pci_unin_main_pci_host_props[] = { + DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void pci_unin_main_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = pci_unin_main_realize; + dc->props = pci_unin_main_pci_host_props; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address; } static const TypeInfo pci_unin_main_info = { diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index a6b95f0..325013f 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -344,6 +344,7 @@ static void ppc_core99_init(MachineState *machine) /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); diff --git a/include/hw/pci-host/uninorth.h b/include/hw/pci-host/uninorth.h index 2a1cf9f..0603245 100644 --- a/include/hw/pci-host/uninorth.h +++ b/include/hw/pci-host/uninorth.h @@ -49,6 +49,7 @@ typedef struct UNINHostState { PCIHostState parent_obj; + uint32_t ofw_addr; OpenPICState *pic; qemu_irq irqs[4]; MemoryRegion pci_mmio; -- cgit v1.1 From 5d19be6c705ab827313dd76ec09fc6e1d6771bc8 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 29 Aug 2018 17:59:11 +0100 Subject: mac_newworld: implement custom FWPathProvider This enables the correct generation of bootdevice fw paths for in-built IDE and virtio-pci-blk devices suitable for OpenBIOS. Note we also set the MachineClass ignore_boot_device_suffixes property to true since an additional disk node should not be added except for virtio devices. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 325013f..a630cb8 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -64,6 +64,7 @@ #include "hw/ppc/openpic.h" #include "hw/ide.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" @@ -521,6 +522,54 @@ static void ppc_core99_init(MachineState *machine) qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + MACIOIDEState *macio_ide; + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-newworld")) { + pci = PCI_DEVICE(dev); + return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn)); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) { + macio_ide = MACIO_IDE(dev); + return g_strdup_printf("ata-3@%x", macio_ide->addr); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup("cdrom"); + } + + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static int core99_kvm_type(const char *arg) { /* Always force PR KVM */ @@ -530,6 +579,7 @@ static int core99_kvm_type(const char *arg) static void core99_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Mac99 based PowerMAC"; mc->init = ppc_core99_init; @@ -543,6 +593,8 @@ static void core99_machine_class_init(ObjectClass *oc, void *data) #else mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9"); #endif + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = core99_fw_dev_path; } static char *core99_get_via_config(Object *obj, Error **errp) @@ -599,7 +651,11 @@ static const TypeInfo core99_machine_info = { .parent = TYPE_MACHINE, .class_init = core99_machine_class_init, .instance_init = core99_instance_init, - .instance_size = sizeof(Core99MachineState) + .instance_size = sizeof(Core99MachineState), + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void mac_machine_register_types(void) -- cgit v1.1 From ecda255ebab14adc35731fe67f8cfa70624010e2 Mon Sep 17 00:00:00 2001 From: Sam Bobroff Date: Thu, 30 Aug 2018 15:54:40 +1000 Subject: spapr: Correct reference count on spapr-cpu-core spapr_init_cpus() currently creates spapr-cpu-core objects via object_new() and setting their realized property to true. This leaves their reference count at two, because object_new() adds an initial reference and the realization attaches them to a default parent object which also increments the reference count. This causes a problem if one of these cores is hot unplugged: no delete event is generated for it because it's reference count doesn't reach zero when it is detached from it's parent. Correct this by adding a call to object_unref() in spapr_init_cpus(). Signed-off-by: Sam Bobroff Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 505d4c8..4a9dd4d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2480,6 +2480,8 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID, &error_fatal); object_property_set_bool(core, true, "realized", &error_fatal); + + object_unref(core); } } } -- cgit v1.1 From b12a4efb76e81644e290d962d2eb6dbb0a5f214f Mon Sep 17 00:00:00 2001 From: Jose Ricardo Ziviani Date: Sun, 2 Sep 2018 11:19:04 -0300 Subject: Fix a deadlock case in the CPU hotplug flow We need to set cs->halted to 1 before calling ppc_set_compat. The reason is that ppc_set_compat kicks up the new thread created to manage the hotplugged KVM virtual CPU and the code drives directly to KVM_RUN ioctl. When cs->halted is 1, the code: int kvm_cpu_exec(CPUState *cpu) ... if (kvm_arch_process_async_events(cpu)) { atomic_set(&cpu->exit_request, 0); return EXCP_HLT; } ... returns before it reaches KVM_RUN, giving time to the main thread to finish its job. Otherwise we can fall in a deadlock because the KVM thread will issue the KVM_RUN ioctl while the main thread is setting up KVM registers. Depending on how these jobs are scheduled we'll end up freezing QEMU. The following output shows kvm_vcpu_ioctl sleeping because it cannot get the mutex and never will. PS: kvm_vcpu_ioctl was triggered kvm_set_one_reg - compat_pvr. STATE: TASK_UNINTERRUPTIBLE|TASK_WAKEKILL PID: 61564 TASK: c000003e981e0780 CPU: 48 COMMAND: "qemu-system-ppc" #0 [c000003e982679a0] __schedule at c000000000b10a44 #1 [c000003e98267a60] schedule at c000000000b113a8 #2 [c000003e98267a90] schedule_preempt_disabled at c000000000b11910 #3 [c000003e98267ab0] __mutex_lock at c000000000b132ec #4 [c000003e98267bc0] kvm_vcpu_ioctl at c00800000ea03140 [kvm] #5 [c000003e98267d20] do_vfs_ioctl at c000000000407d30 #6 [c000003e98267dc0] ksys_ioctl at c000000000408674 #7 [c000003e98267e10] sys_ioctl at c0000000004086f8 #8 [c000003e98267e30] system_call at c00000000000b488 crash> struct -x kvm.vcpus 0xc000003da0000000 vcpus = {0xc000003db4880000, 0xc000003d52b80000, 0xc0000039e9c80000, 0xc000003d0e200000, 0xc000003d58280000, 0x0, 0x0, ...} crash> struct -x kvm_vcpu.mutex.owner 0xc000003d58280000 mutex.owner = { counter = 0xc000003a23a5c881 <- flag 1: waiters }, crash> bt 0xc000003a23a5c880 PID: 61579 TASK: c000003a23a5c880 CPU: 9 COMMAND: "CPU 4/KVM" (active) crash> struct -x kvm_vcpu.mutex.wait_list 0xc000003d58280000 mutex.wait_list = { next = 0xc000003e98267b10, prev = 0xc000003e98267b10 }, crash> struct -x mutex_waiter.task 0xc000003e98267b10 task = 0xc000003e981e0780 The following command-line was used to reproduce the problem (note: gdb and trace can change the results). $ qemu-ppc/build/ppc64-softmmu/qemu-system-ppc64 -cpu host \ -enable-kvm -m 4096 \ -smp 4,maxcpus=8,sockets=1,cores=2,threads=4 \ -display none -nographic \ -drive file=disk1.qcow2,format=qcow2 ... (qemu) device_add host-spapr-cpu-core,core-id=4 [no interaction is possible after it, only SIGKILL to take the terminal back] Signed-off-by: Jose Ricardo Ziviani Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_cpu_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 876f0b3..a73b244 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -34,16 +34,16 @@ static void spapr_cpu_reset(void *opaque) cpu_reset(cs); - /* Set compatibility mode to match the boot CPU, which was either set - * by the machine reset code or by CAS. This should never fail. - */ - ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); - /* All CPUs start halted. CPU0 is unhalted from the machine level * reset code and the rest are explicitly started up by the guest * using an RTAS call */ cs->halted = 1; + /* Set compatibility mode to match the boot CPU, which was either set + * by the machine reset code or by CAS. This should never fail. + */ + ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); + env->spr[SPR_HIOR] = 0; lpcr = env->spr[SPR_LPCR]; -- cgit v1.1 From a84f71793aab5d06b5798e78e1cee82cc3e4b3e2 Mon Sep 17 00:00:00 2001 From: Nikunj A Dadhania Date: Tue, 4 Sep 2018 14:54:18 +0530 Subject: target/ppc/kvm: set vcpu as online/offline Set the newly added register(KVM_REG_PPC_ONLINE) to indicate if the vcpu is online(1) or offline(0) KVM will use this information to set the RWMR register, which controls the PURR and SPURR accumulation. CC: paulus@samba.org Signed-off-by: Nikunj A Dadhania Signed-off-by: David Gibson --- hw/ppc/spapr_cpu_core.c | 1 + hw/ppc/spapr_rtas.c | 2 ++ target/ppc/kvm.c | 9 +++++++++ target/ppc/kvm_ppc.h | 7 +++++++ 4 files changed, 19 insertions(+) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index a73b244..2398ce6 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -90,6 +90,7 @@ void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r env->nip = nip; env->gpr[3] = r3; + kvmppc_set_reg_ppc_online(cpu, 1); CPU(cpu)->halted = 0; /* Enable Power-saving mode Exit Cause exceptions */ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] | pcc->lpcr_pm); diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 4ac96bc..d6a0952 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -33,6 +33,7 @@ #include "sysemu/device_tree.h" #include "sysemu/cpus.h" #include "sysemu/hw_accel.h" +#include "kvm_ppc.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" @@ -207,6 +208,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr, * guest */ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); cs->halted = 1; + kvmppc_set_reg_ppc_online(cpu, 0); qemu_cpu_kick(cs); } diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index ef63842..30aeafa 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2783,3 +2783,12 @@ bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu) return !kvmppc_is_pr(cs->kvm_state); } + +void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online) +{ + CPUState *cs = CPU(cpu); + + if (kvm_enabled()) { + kvm_set_one_reg(cs, KVM_REG_PPC_ONLINE, &online); + } +} diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 657582b..f696c6e 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -72,6 +72,7 @@ bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu); bool kvmppc_hpt_needs_host_contiguous_pages(void); void kvm_check_mmu(PowerPCCPU *cpu, Error **errp); +void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online); #else @@ -187,6 +188,12 @@ static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, return 0; } +static inline void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, + unsigned int online) +{ + return; +} + #ifndef CONFIG_USER_ONLY static inline bool kvmppc_spapr_use_multitce(void) { -- cgit v1.1 From be0c46d464c7c6b601adcd21fe9d2dd054a6a2cf Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Thu, 6 Sep 2018 12:27:29 +0530 Subject: target-ppc: Extend HWCAP2 bits for ISA 3.0 This adds the HWCAP2 bit to detect if a linux user process is running on an ISA 3.0 compliant cpu like POWER9. This can be verified using a simple test program that prints the value in the auxiliary vector for AT_HWCAP2 as shown below. Before: $ qemu-ppc64le -cpu power8 test 0x8c000000 $ qemu-ppc64le -cpu power9 test 0x8c000000 After: $ qemu-ppc64le -cpu power8 test 0x8c000000 $ qemu-ppc64le -cpu power9 test 0x8c800000 Signed-off-by: Sandipan Das Reviewed-by: Laurent Vivier Signed-off-by: David Gibson --- linux-user/elfload.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8638612..e97c4cd 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -710,6 +710,7 @@ enum { QEMU_PPC_FEATURE2_HAS_EBB = 0x10000000, /* Event Base Branching */ QEMU_PPC_FEATURE2_HAS_ISEL = 0x08000000, /* Integer Select */ QEMU_PPC_FEATURE2_HAS_TAR = 0x04000000, /* Target Address Register */ + QEMU_PPC_FEATURE2_ARCH_3_00 = 0x00800000, /* ISA 3.00 */ }; #define ELF_HWCAP get_elf_hwcap() @@ -764,6 +765,7 @@ static uint32_t get_elf_hwcap2(void) GET_FEATURE2(PPC2_BCTAR_ISA207, QEMU_PPC_FEATURE2_HAS_TAR); GET_FEATURE2((PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07); + GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00); #undef GET_FEATURE #undef GET_FEATURE2 -- cgit v1.1