diff options
| -rw-r--r-- | MAINTAINERS | 5 | ||||
| -rw-r--r-- | dump/dump.c | 2 | ||||
| -rw-r--r-- | dump/win_dump.c | 4 | ||||
| -rw-r--r-- | hw/arm/collie.c | 33 | ||||
| -rw-r--r-- | hw/dma/xlnx-zdma.c | 56 | ||||
| -rw-r--r-- | hw/gpio/aspeed_gpio.c | 2 | ||||
| -rw-r--r-- | hw/ppc/e500.c | 4 | ||||
| -rw-r--r-- | hw/ppc/pnv.c | 32 | ||||
| -rw-r--r-- | hw/ppc/pnv_bmc.c | 45 | ||||
| -rw-r--r-- | hw/ppc/ppc440_uc.c | 3 | ||||
| -rw-r--r-- | hw/ppc/spapr_caps.c | 7 | ||||
| -rw-r--r-- | hw/ppc/spapr_events.c | 49 | ||||
| -rw-r--r-- | hw/ppc/spapr_pci.c | 1 | ||||
| -rw-r--r-- | hw/ppc/spapr_rtas.c | 10 | ||||
| -rw-r--r-- | hw/vfio/spapr.c | 6 | ||||
| -rw-r--r-- | include/hw/ppc/pnv.h | 2 | ||||
| -rw-r--r-- | pc-bios/README | 2 | ||||
| -rw-r--r-- | pc-bios/slof.bin | bin | 965008 -> 965112 bytes | |||
| -rw-r--r-- | qga/commands-posix.c | 3 | ||||
| m--------- | roms/SLOF | 0 | ||||
| -rw-r--r-- | scripts/coccinelle/error-use-after-free.cocci | 52 | ||||
| -rw-r--r-- | target/arm/gdbstub.c | 7 | ||||
| -rw-r--r-- | target/arm/helper.c | 13 | ||||
| -rw-r--r-- | target/ppc/kvm.c | 7 | ||||
| -rw-r--r-- | target/ppc/kvm_ppc.h | 6 |
25 files changed, 278 insertions, 73 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 7cb53ec138..9d156d73b3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2053,6 +2053,11 @@ F: include/qemu/error-report.h F: qapi/error.json F: util/error.c F: util/qemu-error.c +F: scripts/coccinelle/err-bad-newline.cocci +F: scripts/coccinelle/error-use-after-free.cocci +F: scripts/coccinelle/error_propagate_null.cocci +F: scripts/coccinelle/remove_local_err.cocci +F: scripts/coccinelle/use-error_fatal.cocci GDB stub M: Alex Bennée <alex.bennee@linaro.org> diff --git a/dump/dump.c b/dump/dump.c index 6fb6e1245a..22ed1d3b0d 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -364,7 +364,7 @@ static void write_elf_section(DumpState *s, int type, Error **errp) shdr = &shdr64; } - ret = fd_write_vmcore(&shdr, shdr_size, s); + ret = fd_write_vmcore(shdr, shdr_size, s); if (ret < 0) { error_setg_errno(errp, -ret, "dump: failed to write section header table"); diff --git a/dump/win_dump.c b/dump/win_dump.c index eda2a48974..652c7bad99 100644 --- a/dump/win_dump.c +++ b/dump/win_dump.c @@ -304,13 +304,11 @@ static void restore_context(WinDumpHeader64 *h, struct saved_context *saved_ctx) { int i; - Error *err = NULL; for (i = 0; i < h->NumberProcessors; i++) { if (cpu_memory_rw_debug(first_cpu, saved_ctx[i].addr, (uint8_t *)&saved_ctx[i].ctx, sizeof(WinContext), 1)) { - error_setg(&err, "win-dump: failed to restore CPU #%d context", i); - warn_report_err(err); + warn_report("win-dump: failed to restore CPU #%d context", i); } } } diff --git a/hw/arm/collie.c b/hw/arm/collie.c index 4992084a3f..4b35ef4bed 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -19,6 +19,16 @@ #include "exec/address-spaces.h" #include "cpu.h" +typedef struct { + MachineState parent; + + StrongARMState *sa1110; +} CollieMachineState; + +#define TYPE_COLLIE_MACHINE MACHINE_TYPE_NAME("collie") +#define COLLIE_MACHINE(obj) \ + OBJECT_CHECK(CollieMachineState, obj, TYPE_COLLIE_MACHINE) + static struct arm_boot_info collie_binfo = { .loader_start = SA_SDCS0, .ram_size = 0x20000000, @@ -26,9 +36,9 @@ static struct arm_boot_info collie_binfo = { static void collie_init(MachineState *machine) { - StrongARMState *s; DriveInfo *dinfo; MachineClass *mc = MACHINE_GET_CLASS(machine); + CollieMachineState *cms = COLLIE_MACHINE(machine); if (machine->ram_size != mc->default_ram_size) { char *sz = size_to_str(mc->default_ram_size); @@ -37,7 +47,7 @@ static void collie_init(MachineState *machine) exit(EXIT_FAILURE); } - s = sa1110_init(machine->cpu_type); + cms->sa1110 = sa1110_init(machine->cpu_type); memory_region_add_subregion(get_system_memory(), SA_SDCS0, machine->ram); @@ -54,11 +64,13 @@ static void collie_init(MachineState *machine) sysbus_create_simple("scoop", 0x40800000, NULL); collie_binfo.board_id = 0x208; - arm_load_kernel(s->cpu, machine, &collie_binfo); + arm_load_kernel(cms->sa1110->cpu, machine, &collie_binfo); } -static void collie_machine_init(MachineClass *mc) +static void collie_machine_class_init(ObjectClass *oc, void *data) { + MachineClass *mc = MACHINE_CLASS(oc); + mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)"; mc->init = collie_init; mc->ignore_memory_transaction_failures = true; @@ -67,4 +79,15 @@ static void collie_machine_init(MachineClass *mc) mc->default_ram_id = "strongarm.sdram"; } -DEFINE_MACHINE("collie", collie_machine_init) +static const TypeInfo collie_machine_typeinfo = { + .name = TYPE_COLLIE_MACHINE, + .parent = TYPE_MACHINE, + .class_init = collie_machine_class_init, + .instance_size = sizeof(CollieMachineState), +}; + +static void collie_machine_register_types(void) +{ + type_register_static(&collie_machine_typeinfo); +} +type_init(collie_machine_register_types); diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c index 2d9c0a0d5e..1c45367f3c 100644 --- a/hw/dma/xlnx-zdma.c +++ b/hw/dma/xlnx-zdma.c @@ -333,10 +333,28 @@ static void zdma_load_src_descriptor(XlnxZDMA *s) } } +static void zdma_update_descr_addr(XlnxZDMA *s, bool type, + unsigned int basereg) +{ + uint64_t addr, next; + + if (type == DTYPE_LINEAR) { + addr = zdma_get_regaddr64(s, basereg); + next = addr + sizeof(s->dsc_dst); + } else { + addr = zdma_get_regaddr64(s, basereg); + addr += sizeof(s->dsc_dst); + address_space_read(s->dma_as, addr, s->attr, (void *) &next, 8); + } + + zdma_put_regaddr64(s, basereg, next); +} + static void zdma_load_dst_descriptor(XlnxZDMA *s) { uint64_t dst_addr; unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE); + bool dst_type; if (ptype == PT_REG) { memcpy(&s->dsc_dst, &s->regs[R_ZDMA_CH_DST_DSCR_WORD0], @@ -349,24 +367,10 @@ static void zdma_load_dst_descriptor(XlnxZDMA *s) if (!zdma_load_descriptor(s, dst_addr, &s->dsc_dst)) { ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, AXI_RD_DST_DSCR, true); } -} - -static uint64_t zdma_update_descr_addr(XlnxZDMA *s, bool type, - unsigned int basereg) -{ - uint64_t addr, next; - if (type == DTYPE_LINEAR) { - next = zdma_get_regaddr64(s, basereg); - next += sizeof(s->dsc_dst); - zdma_put_regaddr64(s, basereg, next); - } else { - addr = zdma_get_regaddr64(s, basereg); - addr += sizeof(s->dsc_dst); - address_space_read(s->dma_as, addr, s->attr, &next, 8); - zdma_put_regaddr64(s, basereg, next); - } - return next; + /* Advance the descriptor pointer. */ + dst_type = FIELD_EX32(s->dsc_dst.words[3], ZDMA_CH_DST_DSCR_WORD3, TYPE); + zdma_update_descr_addr(s, dst_type, R_ZDMA_CH_DST_CUR_DSCR_LSB); } static void zdma_write_dst(XlnxZDMA *s, uint8_t *buf, uint32_t len) @@ -387,14 +391,7 @@ static void zdma_write_dst(XlnxZDMA *s, uint8_t *buf, uint32_t len) dst_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2, SIZE); if (dst_size == 0 && ptype == PT_MEM) { - uint64_t next; - bool dst_type = FIELD_EX32(s->dsc_dst.words[3], - ZDMA_CH_DST_DSCR_WORD3, - TYPE); - - next = zdma_update_descr_addr(s, dst_type, - R_ZDMA_CH_DST_CUR_DSCR_LSB); - zdma_load_descriptor(s, next, &s->dsc_dst); + zdma_load_dst_descriptor(s); dst_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2, SIZE); } @@ -511,16 +508,15 @@ static void zdma_process_descr(XlnxZDMA *s) zdma_src_done(s); } - /* Load next descriptor. */ if (ptype == PT_REG || src_cmd == CMD_STOP) { ARRAY_FIELD_DP32(s->regs, ZDMA_CH_CTRL2, EN, 0); zdma_set_state(s, DISABLED); - return; } if (src_cmd == CMD_HALT) { zdma_set_state(s, PAUSED); ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, DMA_PAUSE, 1); + ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, DMA_DONE, false); zdma_ch_imr_update_irq(s); return; } @@ -681,6 +677,12 @@ static RegisterAccessInfo zdma_regs_info[] = { },{ .name = "ZDMA_CH_DBG0", .addr = A_ZDMA_CH_DBG0, .rsvd = 0xfffffe00, .ro = 0x1ff, + + /* + * There's SW out there that will check the debug regs for free space. + * Claim that we always have 0x100 free. + */ + .reset = 0x100 },{ .name = "ZDMA_CH_DBG1", .addr = A_ZDMA_CH_DBG1, .rsvd = 0xfffffe00, .ro = 0x1ff, diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c index 41e11ea9b0..e52fcfd9a0 100644 --- a/hw/gpio/aspeed_gpio.c +++ b/hw/gpio/aspeed_gpio.c @@ -6,8 +6,6 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include <assert.h> - #include "qemu/osdep.h" #include "qemu/host-utils.h" #include "qemu/log.h" diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 854cd3ac46..0d1f41197c 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -1047,6 +1047,10 @@ void ppce500_init(MachineState *machine) } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name); + if (!filename) { + error_report("could not find firmware/kernel file '%s'", payload_name); + exit(1); + } payload_size = load_elf(filename, NULL, NULL, NULL, &bios_entry, &loadaddr, NULL, NULL, diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index b75ad06390..c9cb6fa357 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -571,10 +571,29 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque) static void pnv_reset(MachineState *machine) { + PnvMachineState *pnv = PNV_MACHINE(machine); + IPMIBmc *bmc; void *fdt; qemu_devices_reset(); + /* + * The machine should provide by default an internal BMC simulator. + * If not, try to use the BMC device that was provided on the command + * line. + */ + bmc = pnv_bmc_find(&error_fatal); + if (!pnv->bmc) { + if (!bmc) { + warn_report("machine has no BMC device. Use '-device " + "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' " + "to define one"); + } else { + pnv_bmc_set_pnor(bmc, pnv->pnor); + pnv->bmc = bmc; + } + } + fdt = pnv_dt_create(machine); /* Pack resulting tree */ @@ -833,9 +852,6 @@ static void pnv_init(MachineState *machine) } g_free(chip_typename); - /* Create the machine BMC simulator */ - pnv->bmc = pnv_bmc_create(pnv->pnor); - /* Instantiate ISA bus on chip 0 */ pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal); @@ -845,8 +861,14 @@ static void pnv_init(MachineState *machine) /* Create an RTC ISA device too */ mc146818_rtc_init(pnv->isa_bus, 2000, NULL); - /* Create the IPMI BT device for communication with the BMC */ - pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10); + /* + * Create the machine BMC simulator and the IPMI BT device for + * communication with the BMC + */ + if (defaults_enabled()) { + pnv->bmc = pnv_bmc_create(pnv->pnor); + pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10); + } /* * OpenPOWER systems use a IPMI SEL Event message to notify the diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c index 8863354c1c..4e018b8b70 100644 --- a/hw/ppc/pnv_bmc.c +++ b/hw/ppc/pnv_bmc.c @@ -213,6 +213,18 @@ static const IPMINetfn hiomap_netfn = { .cmd_handlers = hiomap_cmds }; + +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor) +{ + object_ref(OBJECT(pnor)); + object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor), + &error_abort); + + /* Install the HIOMAP protocol handlers to access the PNOR */ + ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM, + &hiomap_netfn); +} + /* * Instantiate the machine BMC. PowerNV uses the QEMU internal * simulator but it could also be external. @@ -232,3 +244,36 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor) return IPMI_BMC(obj); } + +typedef struct ForeachArgs { + const char *name; + Object *obj; +} ForeachArgs; + +static int bmc_find(Object *child, void *opaque) +{ + ForeachArgs *args = opaque; + + if (object_dynamic_cast(child, args->name)) { + if (args->obj) { + return 1; + } + args->obj = child; + } + return 0; +} + +IPMIBmc *pnv_bmc_find(Error **errp) +{ + ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL }; + int ret; + + ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args); + if (ret) { + error_setg(errp, "machine should have only one BMC device. " + "Use '-nodefaults'"); + return NULL; + } + + return args.obj ? IPMI_BMC(args.obj) : NULL; +} diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index d5ea962249..b30e093cbb 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -13,7 +13,6 @@ #include "qemu/error-report.h" #include "qapi/error.h" #include "qemu/log.h" -#include "qemu/main-loop.h" #include "qemu/module.h" #include "cpu.h" #include "hw/irq.h" @@ -1183,9 +1182,7 @@ static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val) case PEGPL_CFGMSK: s->cfg_mask = val; size = ~(val & 0xfffffffe) + 1; - qemu_mutex_lock_iothread(); pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size); - qemu_mutex_unlock_iothread(); break; case PEGPL_MSGBAH: s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff); diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 679ae7959f..eb54f94227 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -517,9 +517,10 @@ static void cap_fwnmi_apply(SpaprMachineState *spapr, uint8_t val, } if (kvm_enabled()) { - if (kvmppc_set_fwnmi() < 0) { - error_setg(errp, "Firmware Assisted Non-Maskable Interrupts(FWNMI) " - "not supported by KVM"); + if (!kvmppc_get_fwnmi()) { + error_setg(errp, +"Firmware Assisted Non-Maskable Interrupts(FWNMI) not supported by KVM."); + error_append_hint(errp, "Try appending -machine cap-fwnmi=off\n"); } } } diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index a4a540f43d..1069d0197b 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -833,11 +833,28 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered) /* get rtas addr from fdt */ rtas_addr = spapr_get_rtas_addr(); if (!rtas_addr) { - qemu_system_guest_panicked(NULL); + if (!recovered) { + error_report( +"FWNMI: Unable to deliver machine check to guest: rtas_addr not found."); + qemu_system_guest_panicked(NULL); + } else { + warn_report( +"FWNMI: Unable to deliver machine check to guest: rtas_addr not found. " +"Machine check recovered."); + } g_free(ext_elog); return; } + /* + * By taking the interlock, we assume that the MCE will be + * delivered to the guest. CAUTION: don't add anything that could + * prevent the MCE to be delivered after this line, otherwise the + * guest won't be able to release the interlock and ultimately + * hang/crash? + */ + spapr->fwnmi_machine_check_interlock = cpu->vcpu_id; + stq_be_phys(&address_space_memory, rtas_addr + RTAS_ERROR_LOG_OFFSET, env->gpr[3]); cpu_physical_memory_write(rtas_addr + RTAS_ERROR_LOG_OFFSET + @@ -860,17 +877,13 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) Error *local_err = NULL; if (spapr->fwnmi_machine_check_addr == -1) { - /* - * This implies that we have hit a machine check either when the - * guest has not registered FWNMI (i.e., "ibm,nmi-register" not - * called) or between system reset and "ibm,nmi-register". - * Fall back to the old machine check behavior in such cases. - */ + /* Non-FWNMI case, deliver it like an architected CPU interrupt. */ cs->exception_index = POWERPC_EXCP_MCHECK; ppc_cpu_do_interrupt(cs); return; } + /* Wait for FWNMI interlock. */ while (spapr->fwnmi_machine_check_interlock != -1) { /* * Check whether the same CPU got machine check error @@ -878,12 +891,25 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) * that CPU called "ibm,nmi-interlock") */ if (spapr->fwnmi_machine_check_interlock == cpu->vcpu_id) { - qemu_system_guest_panicked(NULL); + if (!recovered) { + error_report( +"FWNMI: Unable to deliver machine check to guest: nested machine check."); + qemu_system_guest_panicked(NULL); + } else { + warn_report( +"FWNMI: Unable to deliver machine check to guest: nested machine check. " +"Machine check recovered."); + } return; } qemu_cond_wait_iothread(&spapr->fwnmi_machine_check_interlock_cond); - /* Meanwhile if the system is reset, then just return */ if (spapr->fwnmi_machine_check_addr == -1) { + /* + * If the machine was reset while waiting for the interlock, + * abort the delivery. The machine check applies to a context + * that no longer exists, so it wouldn't make sense to deliver + * it now. + */ return; } } @@ -894,12 +920,13 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) * We don't want to abort so we let the migration to continue. * In a rare case, the machine check handler will run on the target. * Though this is not preferable, it is better than aborting - * the migration or killing the VM. + * the migration or killing the VM. It is okay to call + * migrate_del_blocker on a blocker that was not added (which the + * nmi-interlock handler would do when it's called after this). */ warn_report("Received a fwnmi while migration was in progress"); } - spapr->fwnmi_machine_check_interlock = cpu->vcpu_id; spapr_mce_dispatch_elog(cpu, recovered); } diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 709a52780d..55ca9dee1e 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1663,6 +1663,7 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler, if (pc->is_bridge) { error_setg(errp, "PCI: Hot unplug of PCI bridges not supported"); + return; } /* ensure any other present functions are pending unplug */ diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 9fb8c8632a..bcac0d00e7 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -437,6 +437,13 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu, return; } + if (kvm_enabled()) { + if (kvmppc_set_fwnmi() < 0) { + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); + return; + } + } + spapr->fwnmi_system_reset_addr = sreset_addr; spapr->fwnmi_machine_check_addr = mce_addr; @@ -455,6 +462,9 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu, } if (spapr->fwnmi_machine_check_addr == -1) { + qemu_log_mask(LOG_GUEST_ERROR, +"FWNMI: ibm,nmi-interlock RTAS called with FWNMI not registered.\n"); + /* NMI register not called */ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c index 33692fc86f..2900bd1941 100644 --- a/hw/vfio/spapr.c +++ b/hw/vfio/spapr.c @@ -147,7 +147,7 @@ int vfio_spapr_create_window(VFIOContainer *container, { int ret = 0; IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); - uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr); + uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr), pgmask; unsigned entries, bits_total, bits_per_level, max_levels; struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) }; long rampagesize = qemu_minrampagesize(); @@ -159,8 +159,8 @@ int vfio_spapr_create_window(VFIOContainer *container, if (pagesize > rampagesize) { pagesize = rampagesize; } - pagesize = 1ULL << (63 - clz64(container->pgsizes & - (pagesize | (pagesize - 1)))); + pgmask = container->pgsizes & (pagesize | (pagesize - 1)); + pagesize = pgmask ? (1ULL << (63 - clz64(pgmask))) : 0; if (!pagesize) { error_report("Host doesn't support page size 0x%"PRIx64 ", the supported mask is 0x%lx", diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index fb4d0c0234..d4b0b0e2ff 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -241,6 +241,8 @@ struct PnvMachineState { void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt); void pnv_bmc_powerdown(IPMIBmc *bmc); IPMIBmc *pnv_bmc_create(PnvPnor *pnor); +IPMIBmc *pnv_bmc_find(Error **errp); +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor); /* * POWER8 MMIO base addresses diff --git a/pc-bios/README b/pc-bios/README index f54c2743d0..a5a770f066 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -14,7 +14,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20200317. + built from git tag qemu-slof-20200327. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index 40499a1451..80bbf91a18 100644 --- a/pc-bios/slof.bin +++ b/pc-bios/slof.bin Binary files differdiff --git a/qga/commands-posix.c b/qga/commands-posix.c index 93474ff770..cc69b82704 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -1773,6 +1773,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) } error_free(local_err); + local_err = NULL; if (pmutils_supports_mode(mode, &local_err)) { mode_supported = true; @@ -1784,6 +1785,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) } error_free(local_err); + local_err = NULL; if (linux_sys_state_supports_mode(mode, &local_err)) { mode_supported = true; @@ -1791,6 +1793,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) } if (!mode_supported) { + error_free(local_err); error_setg(errp, "the requested suspend mode is not supported by the guest"); } else { diff --git a/roms/SLOF b/roms/SLOF -Subproject ab6984f5a6d054e1f634dda855b32e535711197 +Subproject 8e012d6fddb62be833d746cef3f03e6c8beecde diff --git a/scripts/coccinelle/error-use-after-free.cocci b/scripts/coccinelle/error-use-after-free.cocci new file mode 100644 index 0000000000..72ae9fdebf --- /dev/null +++ b/scripts/coccinelle/error-use-after-free.cocci @@ -0,0 +1,52 @@ +// Find and fix trivial use-after-free of Error objects +// +// Copyright (c) 2020 Virtuozzo International GmbH. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see +// <http://www.gnu.org/licenses/>. +// +// How to use: +// spatch --sp-file scripts/coccinelle/error-use-after-free.cocci \ +// --macro-file scripts/cocci-macro-file.h --in-place \ +// --no-show-diff ( FILES... | --use-gitgrep . ) + +@ exists@ +identifier fn, fn2; +expression err; +@@ + + fn(...) + { + <... +( + error_free(err); ++ err = NULL; +| + error_report_err(err); ++ err = NULL; +| + error_reportf_err(err, ...); ++ err = NULL; +| + warn_report_err(err); ++ err = NULL; +| + warn_reportf_err(err, ...); ++ err = NULL; +) + ... when != err = NULL + when != exit(...) + fn2(..., err, ...) + ...> + } diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index d9ef7d2187..8efc535f2a 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -192,7 +192,12 @@ static const struct TypeSize vec_lanes[] = { /* 16 bit */ { "uint16", 16, 'h', 'u' }, { "int16", 16, 'h', 's' }, - { "ieee_half", 16, 'h', 'f' }, + /* + * TODO: currently there is no reliable way of telling + * if the remote gdb actually understands ieee_half so + * we don't expose it in the target description for now. + * { "ieee_half", 16, 'h', 'f' }, + */ /* bytes */ { "uint8", 8, 'b', 'u' }, { "int8", 8, 'b', 's' }, diff --git a/target/arm/helper.c b/target/arm/helper.c index 163c91a1cc..7e9ea5d20f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -10025,9 +10025,11 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, prot_rw = user_rw; } else { if (user_rw && regime_is_pan(env, mmu_idx)) { - return 0; + /* PAN forbids data accesses but doesn't affect insn fetch */ + prot_rw = 0; + } else { + prot_rw = simple_ap_to_rw_prot_is_user(ap, false); } - prot_rw = simple_ap_to_rw_prot_is_user(ap, false); } if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) { @@ -10751,12 +10753,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, bool aarch64 = arm_el_is_aa64(env, el); bool guarded = false; - /* TODO: - * This code does not handle the different format TCR for VTCR_EL2. - * This code also does not support shareability levels. - * Attribute and permission bit handling should also be checked when adding - * support for those page table walks. - */ + /* TODO: This code does not support shareability levels. */ if (aarch64) { param = aa64_va_parameters(env, address, mmu_idx, access_type != MMU_INST_FETCH); diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 597f72be1b..03d0667e8f 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -88,6 +88,7 @@ static int cap_ppc_safe_indirect_branch; static int cap_ppc_count_cache_flush_assist; static int cap_ppc_nested_kvm_hv; static int cap_large_decr; +static int cap_fwnmi; static uint32_t debug_inst_opcode; @@ -136,6 +137,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) kvmppc_get_cpu_characteristics(s); cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); cap_large_decr = kvmppc_get_dec_bits(); + cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); /* * Note: setting it to false because there is not such capability * in KVM at this moment. @@ -2064,6 +2066,11 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) } } +bool kvmppc_get_fwnmi(void) +{ + return cap_fwnmi; +} + int kvmppc_set_fwnmi(void) { PowerPCCPU *cpu = POWERPC_CPU(first_cpu); diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 332fa0aa1c..fcaf745516 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -27,6 +27,7 @@ void kvmppc_enable_h_page_init(void); void kvmppc_set_papr(PowerPCCPU *cpu); int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr); void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy); +bool kvmppc_get_fwnmi(void); int kvmppc_set_fwnmi(void); int kvmppc_smt_threads(void); void kvmppc_error_append_smt_possible_hint(Error *const *errp); @@ -163,6 +164,11 @@ static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) { } +static inline bool kvmppc_get_fwnmi(void) +{ + return false; +} + static inline int kvmppc_set_fwnmi(void) { return -1; |