Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20200407-pull-request' into staging
fixes for 5.0:
- audio: windows (dsound) fixes.
- vga: ati blitter sanity check fixes.
# gpg: Signature made Tue 07 Apr 2020 10:21:44 BST
# gpg: using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138
* remotes/kraxel/tags/fixes-20200407-pull-request:
ati-vga: Fix checks in ati_2d_blt() to avoid crash
dsoundaudio: dsound_get_buffer_in should honor *size
dsoundaudio: fix "Could not lock capture buffer" warning
dsoundaudio: fix never-ending playback loop
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/MAINTAINERS b/MAINTAINERS
index 7cb53ec..9d156d7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2053,6 +2053,11 @@
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 6fb6e12..22ed1d3b 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -364,7 +364,7 @@
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 eda2a48..652c7ba 100644
--- a/dump/win_dump.c
+++ b/dump/win_dump.c
@@ -304,13 +304,11 @@
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 4992084..4b35ef4 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 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 @@
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 @@
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 @@
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 2d9c0a0..1c45367 100644
--- a/hw/dma/xlnx-zdma.c
+++ b/hw/dma/xlnx-zdma.c
@@ -333,10 +333,28 @@
}
}
+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 @@
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 @@
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 @@
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 @@
},{ .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 41e11ea..e52fcfd 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 854cd3a..0d1f411 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1047,6 +1047,10 @@
}
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 b75ad06..c9cb6fa 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -571,10 +571,29 @@
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 @@
}
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 @@
/* 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 8863354..4e018b8 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -213,6 +213,18 @@
.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 @@
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 d5ea962..b30e093 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 @@
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 679ae79..eb54f94 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -517,9 +517,10 @@
}
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 a4a540f..1069d01 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -833,11 +833,28 @@
/* 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 @@
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 @@
* 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 @@
* 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 709a527..55ca9de 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1663,6 +1663,7 @@
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 9fb8c86..bcac0d0 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -437,6 +437,13 @@
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 @@
}
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 33692fc..2900bd1 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -147,7 +147,7 @@
{
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 @@
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 fb4d0c0..d4b0b0e 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -241,6 +241,8 @@
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 f54c274..a5a770f 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 40499a1..80bbf91 100644
--- a/pc-bios/slof.bin
+++ b/pc-bios/slof.bin
Binary files differ
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 93474ff..cc69b82 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1773,6 +1773,7 @@
}
error_free(local_err);
+ local_err = NULL;
if (pmutils_supports_mode(mode, &local_err)) {
mode_supported = true;
@@ -1784,6 +1785,7 @@
}
error_free(local_err);
+ local_err = NULL;
if (linux_sys_state_supports_mode(mode, &local_err)) {
mode_supported = true;
@@ -1791,6 +1793,7 @@
}
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
index ab6984f..8e012d6 160000
--- a/roms/SLOF
+++ b/roms/SLOF
@@ -1 +1 @@
-Subproject commit ab6984f5a6d054e1f634dda855b32e5357111974
+Subproject commit 8e012d6fddb62be833d746cef3f03e6c8beecde0
diff --git a/scripts/coccinelle/error-use-after-free.cocci b/scripts/coccinelle/error-use-after-free.cocci
new file mode 100644
index 0000000..72ae9fd
--- /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 d9ef7d2..8efc535 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -192,7 +192,12 @@
/* 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 163c91a..7e9ea5d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10025,9 +10025,11 @@
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 @@
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 597f72b..03d0667 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -88,6 +88,7 @@
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 @@
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 @@
}
}
+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 332fa0a..fcaf745 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -27,6 +27,7 @@
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 bool kvmppc_get_fwnmi(void)
+{
+ return false;
+}
+
static inline int kvmppc_set_fwnmi(void)
{
return -1;