:p
atchew
Login
Arm patch queue for 2.12 -- a miscellaneous collection of bug fixes. thanks -- PMM The following changes since commit fb4fe32d5b6290deabe752b51cc1cc2a9e8573db: Merge remote-tracking branch 'remotes/xtensa/tags/20180409-xtensa' into staging (2018-04-10 10:22:45 +0100) are available in the Git repository at: git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180410 for you to fetch changes up to bd49e6027cbc207c87633c7add3ebd7d3474cd35: fpu: Fix rounding mode for floatN_to_uintM_round_to_zero (2018-04-10 13:02:26 +0100) ---------------------------------------------------------------- target-arm queue: * fpu: Fix rounding mode for floatN_to_uintM_round_to_zero * tcg: Fix guest state corruption when running 64-bit Arm guests on a 32-bit host (especially when using icount) * linux-user/signal.c: Ensure AArch64 signal frame isn't too small * cpus.c: ensure running CPU recalculates icount deadlines on timer expiry * target/arm: Report unsupported MPU region sizes more clearly * hw/arm/fsl-imx: Fix introspection problem with fsl-imx6 and fsl-imx7 * hw/arm/allwinner-a10: Do not use nd_table in instance_init function * hw/sd/bcm2835_sdhost: Don't raise spurious interrupts * hw/sd/bcm2835_sdhost: Add tracepoints * target-arm: Check undefined opcodes for SWP in A32 decoder * hw/arm/integratorcp: Don't do things that could be fatal in the instance_init * hw/arm: Allow manually specified /psci node ---------------------------------------------------------------- Andrey Smirnov (1): hw/arm: Allow manually specified /psci node Onur Sahin (1): target-arm: Check undefined opcodes for SWP in A32 decoder Peter Maydell (5): hw/sd/bcm2835_sdhost: Add tracepoints hw/sd/bcm2835_sdhost: Don't raise spurious interrupts target/arm: Report unsupported MPU region sizes more clearly cpus.c: ensure running CPU recalculates icount deadlines on timer expiry linux-user/signal.c: Ensure AArch64 signal frame isn't too small Richard Henderson (2): tcg: Introduce tcg_set_insn_start_param fpu: Fix rounding mode for floatN_to_uintM_round_to_zero Thomas Huth (3): hw/arm/integratorcp: Don't do things that could be fatal in the instance_init hw/arm/allwinner-a10: Do not use nd_table in instance_init function hw/arm/fsl-imx: Fix introspection problem with fsl-imx6 and fsl-imx7 target/arm/translate.h | 2 +- tcg/tcg.h | 10 ++++++++++ cpus.c | 10 +++++++++- fpu/softfloat.c | 4 ++-- hw/arm/allwinner-a10.c | 12 +++++------ hw/arm/boot.c | 10 ++++++++++ hw/arm/fsl-imx6.c | 14 ++++++------- hw/arm/fsl-imx7.c | 13 ++++++------ hw/arm/integratorcp.c | 23 +++++++++++++-------- hw/sd/bcm2835_sdhost.c | 54 ++++++++++++++++++++++++++++++++------------------ linux-user/signal.c | 6 ++++++ target/arm/helper.c | 6 +++--- target/arm/translate.c | 9 +++++++-- hw/sd/trace-events | 6 ++++++ 14 files changed, 124 insertions(+), 55 deletions(-)
From: Andrey Smirnov <andrew.smirnov@gmail.com> Change the code to avoid exiting QEMU if user provided DTB contains manually specified /psci node and skip any /psci related fixups instead. Fixes: 4cbca7d9b4 ("hw/arm: Move virt's PSCI DT fixup code to arm/boot.c") Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Reported-by: Marc Zyngier <marc.zyngier@arm.com> Tested-by: Marc Zyngier <marc.zyngier@arm.com> Message-id: 20180402205654.14572-1-andrew.smirnov@gmail.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/boot.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt) ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0)); const char *psci_method; int64_t psci_conduit; + int rc; psci_conduit = object_property_get_int(OBJECT(armcpu), "psci-conduit", @@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt) g_assert_not_reached(); } + /* + * If /psci node is present in provided DTB, assume that no fixup + * is necessary and all PSCI configuration should be taken as-is + */ + rc = fdt_path_offset(fdt, "/psci"); + if (rc >= 0) { + return; + } + qemu_fdt_add_subnode(fdt, "/psci"); if (armcpu->psci_version == 2) { const char comp[] = "arm,psci-0.2\0arm,psci"; -- 2.16.2
From: Thomas Huth <thuth@redhat.com> An instance_init function must not fail - and might be called multiple times, e.g. during device introspection with the 'device-list-properties' QMP command. Since the integratorcm device ignores this rule, QEMU currently aborts in this case (though it really should not): echo "{'execute':'qmp_capabilities'}"\ "{'execute':'device-list-properties',"\ "'arguments':{'typename':'integrator_core'}}" \ | arm-softmmu/qemu-system-arm -M integratorcp,accel=qtest -qmp stdio {"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2}, "package": "build-all"}, "capabilities": []}} {"return": {}} RAMBlock "integrator.flash" already registered, abort! Aborted (core dumped) Move the problematic code to the realize() function instead to fix this problem. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Thomas Huth <thuth@redhat.com> Message-id: 1522906473-11252-1-git-send-email-thuth@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/integratorcp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps integratorcm_ops = { static void integratorcm_init(Object *obj) { IntegratorCMState *s = INTEGRATOR_CM(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); s->cm_osc = 0x01000048; /* ??? What should the high bits of this value be? */ @@ -XXX,XX +XXX,XX @@ static void integratorcm_init(Object *obj) s->cm_init = 0x00000112; s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, 1000); - memory_region_init_ram(&s->flash, obj, "integrator.flash", 0x100000, - &error_fatal); - memory_region_init_io(&s->iomem, obj, &integratorcm_ops, s, - "integratorcm", 0x00800000); - sysbus_init_mmio(dev, &s->iomem); - - integratorcm_do_remap(s); /* ??? Save/restore. */ } static void integratorcm_realize(DeviceState *d, Error **errp) { IntegratorCMState *s = INTEGRATOR_CM(d); + SysBusDevice *dev = SYS_BUS_DEVICE(d); + Error *local_err = NULL; + + memory_region_init_ram(&s->flash, OBJECT(d), "integrator.flash", 0x100000, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + memory_region_init_io(&s->iomem, OBJECT(d), &integratorcm_ops, s, + "integratorcm", 0x00800000); + sysbus_init_mmio(dev, &s->iomem); + + integratorcm_do_remap(s); if (s->memsz >= 256) { integrator_spd[31] = 64; -- 2.16.2
From: Onur Sahin <onursahin08@gmail.com> Make sure we are not treating architecturally Undefined instructions as a SWP, by verifying the opcodes as per section A8.8.229 of ARMv7-A specification. Bits [21:20] must be zero for this to be a SWP or SWPB. We also choose to UNDEF for the architecturally UNPREDICTABLE case of bits [11:8] not being zero. Signed-off-by: Onur Sahin <onursahin08@gmail.com> [PMM: tweaked commit message] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/translate.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) } } tcg_temp_free_i32(addr); - } else { + } else if ((insn & 0x00300f00) == 0) { + /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx + * - SWP, SWPB + */ + TCGv taddr; TCGMemOp opc = s->be_data; - /* SWP instruction */ rm = (insn) & 0xf; if (insn & (1 << 22)) { @@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) get_mem_index(s), opc); tcg_temp_free(taddr); store_reg(s, rd, tmp); + } else { + goto illegal_op; } } } else { -- 2.16.2
Add some tracepoints to the bcm2835_sdhost driver, to assist debugging. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 20180319161556.16446-2-peter.maydell@linaro.org --- hw/sd/bcm2835_sdhost.c | 10 ++++++++++ hw/sd/trace-events | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/bcm2835_sdhost.c +++ b/hw/sd/bcm2835_sdhost.c @@ -XXX,XX +XXX,XX @@ #include "qemu/log.h" #include "sysemu/blockdev.h" #include "hw/sd/bcm2835_sdhost.h" +#include "trace.h" #define TYPE_BCM2835_SDHOST_BUS "bcm2835-sdhost-bus" #define BCM2835_SDHOST_BUS(obj) \ @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_update_irq(BCM2835SDHostState *s) { uint32_t irq = s->status & (SDHSTS_BUSY_IRPT | SDHSTS_BLOCK_IRPT | SDHSTS_SDIO_IRPT); + trace_bcm2835_sdhost_update_irq(irq); qemu_set_irq(s->irq, !!irq); } @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) s->edm &= ~0xf; s->edm |= SDEDM_FSM_DATAMODE; + trace_bcm2835_sdhost_edm_change("datacnt 0", s->edm); if (s->config & SDHCFG_DATA_IRPT_EN) { s->status |= SDHSTS_SDIO_IRPT; @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) s->edm &= ~(0x1f << 4); s->edm |= ((s->fifo_len & 0x1f) << 4); + trace_bcm2835_sdhost_edm_change("fifo run", s->edm); } static uint64_t bcm2835_sdhost_read(void *opaque, hwaddr offset, @@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_sdhost_read(void *opaque, hwaddr offset, break; } + trace_bcm2835_sdhost_read(offset, res, size); + return res; } @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_write(void *opaque, hwaddr offset, { BCM2835SDHostState *s = (BCM2835SDHostState *)opaque; + trace_bcm2835_sdhost_write(offset, value, size); + switch (offset) { case SDCMD: s->cmd = value; @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_write(void *opaque, hwaddr offset, value &= ~0xf; } s->edm = value; + trace_bcm2835_sdhost_edm_change("guest register write", s->edm); break; case SDHCFG: s->config = value; @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_reset(DeviceState *dev) s->cmd = 0; s->cmdarg = 0; s->edm = 0x0000c60f; + trace_bcm2835_sdhost_edm_change("device reset", s->edm); s->config = 0; s->hbct = 0; s->hblc = 0; diff --git a/hw/sd/trace-events b/hw/sd/trace-events index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/trace-events +++ b/hw/sd/trace-events @@ -XXX,XX +XXX,XX @@ # See docs/devel/tracing.txt for syntax documentation. +# hw/sd/bcm2835_sdhost.c +bcm2835_sdhost_read(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +bcm2835_sdhost_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +bcm2835_sdhost_edm_change(const char *why, uint32_t edm) "(%s) EDM now 0x%x" +bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x\n" + # hw/sd/core.c sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg, uint8_t crc) "@%s CMD%02d arg 0x%08x crc 0x%02x" sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x" -- 2.16.2
The Linux bcm2835_sdhost driver doesn't work on QEMU, because our model raises spurious data interrupts. Our function bcm2835_sdhost_fifo_run() will flag an interrupt any time it is called with s->datacnt == 0, even if the host hasn't actually issued a data read or write command yet. This means that the driver gets a spurious data interrupt as soon as it enables IRQs and then does something else that causes us to call the fifo_run routine, like writing to SDHCFG, and before it does the write to SDCMD to issue the read. The driver's IRQ handler then spins forever complaining that there's no data and the SD controller isn't in a state where there's going to be any data: [ 41.040738] sdhost-bcm2835 3f202000.mmc: fsm 1, hsts 00000000 [ 41.042059] sdhost-bcm2835 3f202000.mmc: fsm 1, hsts 00000000 (continues forever). Move the interrupt flag setting to more plausible places: * for BUSY, raise this as soon as a BUSYWAIT command has executed * for DATA, raise this when the FIFO has any space free (for a write) or any data in it (for a read) * for BLOCK, raise this when the data count is 0 and we've actually done some reading or writing This is pure guesswork since the documentation for this hardware is not public, but it is sufficient to get the Linux bcm2835_sdhost driver to work. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 20180319161556.16446-3-peter.maydell@linaro.org --- hw/sd/bcm2835_sdhost.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/bcm2835_sdhost.c +++ b/hw/sd/bcm2835_sdhost.c @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s) } #undef RWORD } + /* We never really delay commands, so if this was a 'busywait' command + * then we've completed it now and can raise the interrupt. + */ + if ((s->cmd & SDCMD_BUSYWAIT) && (s->config & SDHCFG_BUSY_IRPT_EN)) { + s->status |= SDHSTS_BUSY_IRPT; + } return; error: @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) n++; if (n == 4) { bcm2835_sdhost_fifo_push(s, value); + s->status |= SDHSTS_DATA_FLAG; + if (s->config & SDHCFG_DATA_IRPT_EN) { + s->status |= SDHSTS_SDIO_IRPT; + } n = 0; value = 0; } } if (n != 0) { bcm2835_sdhost_fifo_push(s, value); + s->status |= SDHSTS_DATA_FLAG; } } else { /* write */ n = 0; while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) { if (n == 0) { value = bcm2835_sdhost_fifo_pop(s); + s->status |= SDHSTS_DATA_FLAG; + if (s->config & SDHCFG_DATA_IRPT_EN) { + s->status |= SDHSTS_SDIO_IRPT; + } n = 4; } n--; @@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) value >>= 8; } } + if (s->datacnt == 0) { + s->edm &= ~SDEDM_FSM_MASK; + s->edm |= SDEDM_FSM_DATAMODE; + trace_bcm2835_sdhost_edm_change("datacnt 0", s->edm); + + if ((s->cmd & SDCMD_WRITE_CMD) && + (s->config & SDHCFG_BLOCK_IRPT_EN)) { + s->status |= SDHSTS_BLOCK_IRPT; + } + } } - if (s->datacnt == 0) { - s->status |= SDHSTS_DATA_FLAG; - s->edm &= ~0xf; - s->edm |= SDEDM_FSM_DATAMODE; - trace_bcm2835_sdhost_edm_change("datacnt 0", s->edm); - - if (s->config & SDHCFG_DATA_IRPT_EN) { - s->status |= SDHSTS_SDIO_IRPT; - } - - if ((s->cmd & SDCMD_BUSYWAIT) && (s->config & SDHCFG_BUSY_IRPT_EN)) { - s->status |= SDHSTS_BUSY_IRPT; - } - - if ((s->cmd & SDCMD_WRITE_CMD) && (s->config & SDHCFG_BLOCK_IRPT_EN)) { - s->status |= SDHSTS_BLOCK_IRPT; - } - - bcm2835_sdhost_update_irq(s); - } + bcm2835_sdhost_update_irq(s); s->edm &= ~(0x1f << 4); s->edm |= ((s->fifo_len & 0x1f) << 4); -- 2.16.2
From: Thomas Huth <thuth@redhat.com> The instance_init function of a device can be called at any time, even if the device is not going to be used (i.e. not going to be realized). So a instance_init function must not do things that could cause QEMU to exit, like calling qemu_check_nic_model(&nd_table[0], ...) for example. But this is what the instance_init function of the allwinner-a10 device is currently doing - and this causes QEMU to quit unexpectedly when you run the 'device-list-properties' QMP command for example: $ echo "{'execute':'qmp_capabilities'}"\ "{'execute':'device-list-properties',"\ " 'arguments':{'typename':'allwinner-a10'}}" \ | arm-softmmu/qemu-system-arm -M mps2-an505,accel=qtest -qmp stdio {"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2}, "package": "build-all"}, "capabilities": []}} {"return": {}} Unsupported NIC model: lan9118 ... and QEMU quits after printing the last line (which should not happen just because of running 'device-list-properties' here). And with the cubieboard, this even causes QEMU to abort(): $ echo "{'execute':'qmp_capabilities'}"\ "{'execute':'device-list-properties',"\ " 'arguments':{'typename':'allwinner-a10'}}" \ | arm-softmmu/qemu-system-arm -M cubieboard,accel=qtest -qmp stdio {"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2}, "package": "build-all"}, "capabilities": []}} {"return": {}} Unexpected error in error_set_from_qdev_prop_error() at hw/core/qdev-properties.c:1095: Property 'allwinner-emac.netdev' can't take value 'hub0port0', it's in use Aborted (core dumped) To fix the problem we've got to move the offending code to the realize function instead. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-id: 1522862420-7484-1-git-send-email-thuth@redhat.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/allwinner-a10.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj) object_initialize(&s->emac, sizeof(s->emac), TYPE_AW_EMAC); qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default()); - /* FIXME use qdev NIC properties instead of nd_table[] */ - if (nd_table[0].used) { - qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC); - qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]); - } object_initialize(&s->sata, sizeof(s->sata), TYPE_ALLWINNER_AHCI); qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default()); @@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s->irq[67]); sysbus_connect_irq(sysbusdev, 5, s->irq[68]); + /* FIXME use qdev NIC properties instead of nd_table[] */ + if (nd_table[0].used) { + qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC); + qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]); + } object_property_set_bool(OBJECT(&s->emac), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); @@ -XXX,XX +XXX,XX @@ static void aw_a10_class_init(ObjectClass *oc, void *data) DeviceClass *dc = DEVICE_CLASS(oc); dc->realize = aw_a10_realize; - /* Reason: Uses serial_hds in realize and nd_table in instance_init */ + /* Reason: Uses serial_hds and nd_table in realize function */ dc->user_creatable = false; } -- 2.16.2
From: Thomas Huth <thuth@redhat.com> QEMU currently exits unexpectedly when trying to introspect the fsl-imx6 and fsl-imx7 devices on systems with many SMP CPUs: $ echo "{'execute':'qmp_capabilities'}"\ "{'execute':'device-list-properties',"\ " 'arguments':{'typename':'fsl,imx6'}}" \ | arm-softmmu/qemu-system-arm -M virt,accel=qtest -qmp stdio -smp 8 {"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2}, "package": "build-all"}, "capabilities": []}} {"return": {}} fsl,imx6: Only 4 CPUs are supported (8 requested) And: $ echo "{'execute':'qmp_capabilities'}"\ "{'execute':'device-list-properties',"\ " 'arguments':{'typename':'fsl,imx7'}}" \ | arm-softmmu/qemu-system-arm -M raspi2,accel=qtest -qmp stdio {"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2}, "package": "build-all"}, "capabilities": []}} {"return": {}} fsl,imx7: Only 2 CPUs are supported (4 requested) This happens because these devices are doing an exit() from their instance_init function - which should never be done since instance_init can be called at any time for device introspection! Fix it by moving the deadly check into the realize() function instead. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-id: 1522908551-14885-1-git-send-email-thuth@redhat.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/fsl-imx6.c | 14 +++++++------- hw/arm/fsl-imx7.c | 13 +++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj) char name[NAME_SIZE]; int i; - if (smp_cpus > FSL_IMX6_NUM_CPUS) { - error_report("%s: Only %d CPUs are supported (%d requested)", - TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus); - exit(1); - } - - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < MIN(smp_cpus, FSL_IMX6_NUM_CPUS); i++) { object_initialize(&s->cpu[i], sizeof(s->cpu[i]), "cortex-a9-" TYPE_ARM_CPU); snprintf(name, NAME_SIZE, "cpu%d", i); @@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) uint16_t i; Error *err = NULL; + if (smp_cpus > FSL_IMX6_NUM_CPUS) { + error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", + TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus); + return; + } + for (i = 0; i < smp_cpus; i++) { /* On uniprocessor, the CBAR is set to 0 */ diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/fsl-imx7.c +++ b/hw/arm/fsl-imx7.c @@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj) char name[NAME_SIZE]; int i; - if (smp_cpus > FSL_IMX7_NUM_CPUS) { - error_report("%s: Only %d CPUs are supported (%d requested)", - TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus); - exit(1); - } - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < MIN(smp_cpus, FSL_IMX7_NUM_CPUS); i++) { object_initialize(&s->cpu[i], sizeof(s->cpu[i]), ARM_CPU_TYPE_NAME("cortex-a7")); snprintf(name, NAME_SIZE, "cpu%d", i); @@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) qemu_irq irq; char name[NAME_SIZE]; + if (smp_cpus > FSL_IMX7_NUM_CPUS) { + error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", + TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus); + return; + } + for (i = 0; i < smp_cpus; i++) { o = OBJECT(&s->cpu[i]); -- 2.16.2
Currently our PMSAv7 and ARMv7M MPU implementation cannot handle MPU region sizes smaller than our TARGET_PAGE_SIZE. However we report that in a slightly confusing way: DRSR[3]: No support for MPU (sub)region alignment of 9 bits. Minimum is 10 The problem is not the alignment of the region, but its size; tweak the error message to say so: DRSR[3]: No support for MPU (sub)region size of 512 bytes. Minimum is 1024. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180405172554.27401-1-peter.maydell@linaro.org --- target/arm/helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, } if (rsize < TARGET_PAGE_BITS) { qemu_log_mask(LOG_UNIMP, - "DRSR[%d]: No support for MPU (sub)region " - "alignment of %" PRIu32 " bits. Minimum is %d\n", - n, rsize, TARGET_PAGE_BITS); + "DRSR[%d]: No support for MPU (sub)region size of" + " %" PRIu32 " bytes. Minimum is %d.\n", + n, (1 << rsize), TARGET_PAGE_SIZE); continue; } if (srdis) { -- 2.16.2
When we run in TCG icount mode, we calculate the number of instructions to execute using tcg_get_icount_limit(), which ensures that we stop execution at the next timer deadline. However there is a bug where currently we do not recalculate that limit if the guest reprograms a timer so that the next deadline moves closer, and so we will continue execution until the original limit and fire the timer later than we should. Fix this bug in qemu_timer_notify_cb(): if we are currently running a VCPU in icount mode, we simply need to kick it out of the main loop and back to tcg_cpu_exec(), where it will recalculate the icount limit. If we are not currently running a VCPU, then we retain the existing logic for waking up a halted CPU. Cc: qemu-stable@nongnu.org Fixes: https://bugs.launchpad.net/qemu/+bug/1754038 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20180406123838.21249-1-peter.maydell@linaro.org --- cpus.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index XXXXXXX..XXXXXXX 100644 --- a/cpus.c +++ b/cpus.c @@ -XXX,XX +XXX,XX @@ void qemu_timer_notify_cb(void *opaque, QEMUClockType type) return; } - if (!qemu_in_vcpu_thread() && first_cpu) { + if (qemu_in_vcpu_thread()) { + /* A CPU is currently running; kick it back out to the + * tcg_cpu_exec() loop so it will recalculate its + * icount deadline immediately. + */ + qemu_cpu_kick(current_cpu); + } else if (first_cpu) { /* qemu_cpu_kick is not enough to kick a halted CPU out of * qemu_tcg_wait_io_event. async_run_on_cpu, instead, * causes cpu_thread_is_idle to return false. This way, * handle_icount_deadline can run. + * If we have no CPUs at all for some reason, we don't + * need to do anything. */ async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL); } -- 2.16.2
The AArch64 signal frame design was extended for SVE in commit 8c5931de0ac77388096d79ceb, so that instead of having a fixed setup we now add various records to the frame, with some of them possibly overflowing into an extra space outside the original 4K reserved block in the target_sigcontext. However, we failed to ensure that we always at least allocate the 4K reserved block. This is ABI, and some userspace programs rely on it. In particular the dash shell would segfault if the frame wasn't as big enough. (Compare the kernel's sigframe_size() function in arch/arm64/kernel/signal.c.) Reported-by: Richard Henwood <richard.henwood@arm.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180409140714.26841-1-peter.maydell@linaro.org Fixes: https://bugs.launchpad.net/bugs/1761535 Fixes: 8c5931de0ac77388096d79ceb Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- linux-user/signal.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/linux-user/signal.c b/linux-user/signal.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka, fr_ofs = layout.total_size; layout.total_size += sizeof(struct target_rt_frame_record); + /* We must always provide at least the standard 4K reserved space, + * even if we don't use all of it (this is part of the ABI) + */ + layout.total_size = MAX(layout.total_size, + sizeof(struct target_rt_sigframe)); + frame_addr = get_sigframe(ka, env, layout.total_size); trace_user_setup_frame(env, frame_addr); if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { -- 2.16.2
From: Richard Henderson <richard.henderson@linaro.org> The parameters for tcg_gen_insn_start are target_ulong, which may be split into two TCGArg parameters for storage in the opcode on 32-bit hosts. Fixes the ARM target and its direct use of tcg_set_insn_param, which would set the wrong argument in the 64-on-32 case. Cc: qemu-stable@nongnu.org Reported-by: alarson@ddci.com Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180410003558.2470-1-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/translate.h | 2 +- tcg/tcg.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/target/arm/translate.h b/target/arm/translate.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -XXX,XX +XXX,XX @@ static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn) /* We check and clear insn_start_idx to catch multiple updates. */ assert(s->insn_start != NULL); - tcg_set_insn_param(s->insn_start, 2, syn); + tcg_set_insn_start_param(s->insn_start, 2, syn); s->insn_start = NULL; } diff --git a/tcg/tcg.h b/tcg/tcg.h index XXXXXXX..XXXXXXX 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -XXX,XX +XXX,XX @@ static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v) op->args[arg] = v; } +static inline void tcg_set_insn_start_param(TCGOp *op, int arg, target_ulong v) +{ +#if TARGET_LONG_BITS <= TCG_TARGET_REG_BITS + tcg_set_insn_param(op, arg, v); +#else + tcg_set_insn_param(op, arg * 2, v); + tcg_set_insn_param(op, arg * 2 + 1, v >> 32); +#endif +} + /* The last op that was emitted. */ static inline TCGOp *tcg_last_op(void) { -- 2.16.2
From: Richard Henderson <richard.henderson@linaro.org> We incorrectly passed in the current rounding mode instead of float_round_to_zero. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180410055912.934-1-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- fpu/softfloat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index XXXXXXX..XXXXXXX 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -XXX,XX +XXX,XX @@ uint ## isz ## _t float ## fsz ## _to_uint ## isz ## _round_to_zero \ (float ## fsz a, float_status *s) \ { \ FloatParts p = float ## fsz ## _unpack_canonical(a, s); \ - return round_to_uint_and_pack(p, s->float_rounding_mode, \ - UINT ## isz ## _MAX, s); \ + return round_to_uint_and_pack(p, float_round_to_zero, \ + UINT ## isz ## _MAX, s); \ } FLOAT_TO_UINT(16, 16) -- 2.16.2
v3->v4: Windows headers define an INT type which clashed with an enum value name in arm_gicv3_its.c... The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5: Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-3 for you to fetch changes up to 28e987a7e7edaa3ca7feeac65edca26145df8814: hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 21:01:08 +0100) ---------------------------------------------------------------- target-arm queue: * mark MPS2/MPS3 board-internal i2c buses as 'full' so that command line user-created devices are not plugged into them * Take an exception if PSTATE.IL is set * Support an emulated ITS in the virt board * Add support for kudo-bmc board * Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM * cadence_uart: Fix clock handling issues that prevented u-boot from running ---------------------------------------------------------------- Bin Meng (6): hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase hw/char: cadence_uart: Disable transmit when input clock is disabled hw/char: cadence_uart: Move clock/reset check to uart_can_receive() hw/char: cadence_uart: Convert to memop_with_attrs() ops hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}() hw/char: cadence_uart: Log a guest error when device is unclocked or in reset Chris Rauer (1): hw/arm: Add support for kudo-bmc board. Marc Zyngier (1): hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM Peter Maydell (5): target/arm: Take an exception if PSTATE.IL is set qdev: Support marking individual buses as 'full' hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full' hw/arm/mps2.c: Mark internal-only I2C buses as 'full' Richard Henderson (1): target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn Shashi Mallela (9): hw/intc: GICv3 ITS initial framework hw/intc: GICv3 ITS register definitions added hw/intc: GICv3 ITS command queue framework hw/intc: GICv3 ITS Command processing hw/intc: GICv3 ITS Feature enablement hw/intc: GICv3 redistributor ITS processing tests/data/acpi/virt: Add IORT files for ITS hw/arm/virt: add ITS support in virt GIC tests/data/acpi/virt: Update IORT files for ITS docs/system/arm/nuvoton.rst | 1 + hw/intc/gicv3_internal.h | 188 ++++- include/hw/arm/virt.h | 2 + include/hw/intc/arm_gicv3_common.h | 13 + include/hw/intc/arm_gicv3_its_common.h | 32 +- include/hw/qdev-core.h | 24 + target/arm/cpu.h | 1 + target/arm/kvm_arm.h | 4 +- target/arm/syndrome.h | 5 + target/arm/translate.h | 2 + hw/arm/mps2-tz.c | 92 ++- hw/arm/mps2.c | 12 +- hw/arm/npcm7xx_boards.c | 34 + hw/arm/virt.c | 29 +- hw/char/cadence_uart.c | 61 +- hw/intc/arm_gicv3.c | 14 + hw/intc/arm_gicv3_common.c | 13 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_dist.c | 5 +- hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 7 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/arm_gicv3_redist.c | 153 +++- hw/misc/zynq_slcr.c | 31 +- softmmu/qdev-monitor.c | 7 +- target/arm/helper-a64.c | 1 + target/arm/helper.c | 8 + target/arm/kvm.c | 7 +- target/arm/translate-a64.c | 255 +++--- target/arm/translate.c | 21 + hw/intc/meson.build | 1 + tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes 35 files changed, 2144 insertions(+), 210 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c create mode 100644 tests/data/acpi/virt/IORT create mode 100644 tests/data/acpi/virt/IORT.memhp create mode 100644 tests/data/acpi/virt/IORT.numamem create mode 100644 tests/data/acpi/virt/IORT.pxb