summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--gdbstub.c14
-rw-r--r--hw/block/block.c48
-rw-r--r--hw/block/pflash_cfi01.c15
-rw-r--r--hw/block/pflash_cfi02.c13
-rw-r--r--hw/block/xen-block.c4
-rw-r--r--include/hw/block/block.h7
-rw-r--r--qapi/qmp-dispatch.c2
-rw-r--r--qobject/json-lexer.c2
-rw-r--r--target/arm/cpu.c5
-rw-r--r--target/riscv/insn_trans/trans_rvc.inc.c2
-rw-r--r--util/error.c4
11 files changed, 81 insertions, 35 deletions
diff --git a/gdbstub.c b/gdbstub.c
index bc774ae992..d54abd17cc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1152,6 +1152,7 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
     uint32_t pid, tid;
     GDBProcess *process;
     CPUState *cpu;
+    GDBThreadIdKind kind;
 #ifdef CONFIG_USER_ONLY
     int max_cpus = 1; /* global variable max_cpus exists only in system mode */
 
@@ -1194,12 +1195,21 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
             goto out;
         }
 
-        if (*p++ != ':') {
+        if (*p == '\0' || *p == ';') {
+            /*
+             * No thread specifier, action is on "all threads". The
+             * specification is unclear regarding the process to act on. We
+             * choose all processes.
+             */
+            kind = GDB_ALL_PROCESSES;
+        } else if (*p++ == ':') {
+            kind = read_thread_id(p, &p, &pid, &tid);
+        } else {
             res = -ENOTSUP;
             goto out;
         }
 
-        switch (read_thread_id(p, &p, &pid, &tid)) {
+        switch (kind) {
         case GDB_READ_THREAD_ERR:
             res = -EINVAL;
             goto out;
diff --git a/hw/block/block.c b/hw/block/block.c
index cf0eb826f1..bf56c7612b 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -13,7 +13,53 @@
 #include "hw/block/block.h"
 #include "qapi/error.h"
 #include "qapi/qapi-types-block.h"
-#include "qemu/error-report.h"
+
+/*
+ * Read the entire contents of @blk into @buf.
+ * @blk's contents must be @size bytes, and @size must be at most
+ * BDRV_REQUEST_MAX_BYTES.
+ * On success, return true.
+ * On failure, store an error through @errp and return false.
+ * Note that the error messages do not identify the block backend.
+ * TODO Since callers don't either, this can result in confusing
+ * errors.
+ * This function not intended for actual block devices, which read on
+ * demand.  It's for things like memory devices that (ab)use a block
+ * backend to provide persistence.
+ */
+bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
+                                 Error **errp)
+{
+    int64_t blk_len;
+    int ret;
+
+    blk_len = blk_getlength(blk);
+    if (blk_len < 0) {
+        error_setg_errno(errp, -blk_len,
+                         "can't get size of block backend");
+        return false;
+    }
+    if (blk_len != size) {
+        error_setg(errp, "device requires %" HWADDR_PRIu " bytes, "
+                   "block backend provides %" PRIu64 " bytes",
+                   size, blk_len);
+        return false;
+    }
+
+    /*
+     * We could loop for @size > BDRV_REQUEST_MAX_BYTES, but if we
+     * ever get to the point we want to read *gigabytes* here, we
+     * should probably rework the device to be more like an actual
+     * block device and read only on demand.
+     */
+    assert(size <= BDRV_REQUEST_MAX_BYTES);
+    ret = blk_pread(blk, 0, buf, size);
+    if (ret < 0) {
+        error_setg_errno(errp, -ret, "can't read block backend");
+        return false;
+    }
+    return true;
+}
 
 void blkconf_blocksizes(BlockConf *conf)
 {
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 125f70b8e4..16dfae14b8 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -38,6 +38,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/hw.h"
+#include "hw/block/block.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
@@ -730,13 +731,6 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
     }
     device_len = sector_len_per_device * blocks_per_device;
 
-    /* XXX: to be fixed */
-#if 0
-    if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
-        total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
-        return NULL;
-#endif
-
     memory_region_init_rom_device(
         &pfl->mem, OBJECT(dev),
         &pflash_cfi01_ops,
@@ -763,12 +757,9 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
     }
 
     if (pfl->blk) {
-        /* read the initial flash content */
-        ret = blk_pread(pfl->blk, 0, pfl->storage, total_len);
-
-        if (ret < 0) {
+        if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, total_len,
+                                         errp)) {
             vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));
-            error_setg(errp, "failed to read the initial flash content");
             return;
         }
     }
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index c9db430611..f2c6201f81 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -37,6 +37,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/hw.h"
+#include "hw/block/block.h"
 #include "hw/block/flash.h"
 #include "qapi/error.h"
 #include "qemu/timer.h"
@@ -550,12 +551,6 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
     }
 
     chip_len = pfl->sector_len * pfl->nb_blocs;
-    /* XXX: to be fixed */
-#if 0
-    if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
-        total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
-        return NULL;
-#endif
 
     memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ?
                                   &pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
@@ -581,11 +576,9 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
     }
 
     if (pfl->blk) {
-        /* read the initial flash content */
-        ret = blk_pread(pfl->blk, 0, pfl->storage, chip_len);
-        if (ret < 0) {
+        if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, chip_len,
+                                         errp)) {
             vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
-            error_setg(errp, "failed to read the initial flash content");
             return;
         }
     }
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 70fc2455e8..9c722b9b95 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -771,7 +771,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
             QDict *cache_qdict = qdict_new();
 
             qdict_put_bool(cache_qdict, "direct", true);
-            qdict_put_obj(file_layer, "cache", QOBJECT(cache_qdict));
+            qdict_put(file_layer, "cache", cache_qdict);
 
             qdict_put_str(file_layer, "aio", "native");
         }
@@ -796,7 +796,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
     qdict_put_str(driver_layer, "driver", driver);
     g_free(driver);
 
-    qdict_put_obj(driver_layer, "file", QOBJECT(file_layer));
+    qdict_put(driver_layer, "file", file_layer);
 
     g_assert(!drive->node_name);
     drive->node_name = xen_block_blockdev_add(drive->id, driver_layer,
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index e9f9e2223f..d06f25aa0f 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -11,7 +11,7 @@
 #ifndef HW_BLOCK_H
 #define HW_BLOCK_H
 
-#include "qemu-common.h"
+#include "exec/hwaddr.h"
 #include "qapi/qapi-types-block-core.h"
 
 /* Configuration */
@@ -70,6 +70,11 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
     DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror,       \
                                   BLOCKDEV_ON_ERROR_AUTO)
 
+/* Backend access helpers */
+
+bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
+                                 Error **errp);
+
 /* Configuration helpers */
 
 bool blkconf_geometry(BlockConf *conf, int *trans,
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 5f812bb9f2..e2c366e09e 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -111,7 +111,7 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
     if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
         error_setg(errp, "The command %s does not support OOB",
                    command);
-        return false;
+        return NULL;
     }
 
     if (runstate_check(RUN_STATE_PRECONFIG) &&
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index a7df2093aa..632320d72d 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -266,7 +266,7 @@ static inline uint8_t next_state(JSONLexer *lexer, char ch, bool flush,
 {
     uint8_t next;
 
-    assert(lexer->state <= ARRAY_SIZE(json_lexer));
+    assert(lexer->state < ARRAY_SIZE(json_lexer));
     next = json_lexer[lexer->state][(uint8_t)ch];
     *char_consumed = !flush && !(next & LOOKAHEAD);
     return next & ~LOOKAHEAD;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 504a4771fb..4155782197 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2028,6 +2028,11 @@ static void arm_max_initfn(Object *obj)
             t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
             cpu->isar.id_isar6 = t;
 
+            t = cpu->isar.mvfr2;
+            t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
+            t = FIELD_DP32(t, MVFR2, FPMISC, 4);   /* FP MaxNum */
+            cpu->isar.mvfr2 = t;
+
             t = cpu->id_mmfr4;
             t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
             cpu->id_mmfr4 = t;
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c
index 5819f53f90..ebcd977b2f 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -337,7 +337,7 @@ static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a)
 {
 #ifdef TARGET_RISCV32
     /* C.FSWSP */
-    arg_fsw a_fsw = { .rs1 = a->rs2, .rs2 = 2, .imm = a->uimm_fswsp };
+    arg_fsw a_fsw = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm_fswsp };
     return trans_fsw(ctx, &a_fsw);
 #else
     /* C.SDSP */
diff --git a/util/error.c b/util/error.c
index b5ccbd8eac..934a78e1b1 100644
--- a/util/error.c
+++ b/util/error.c
@@ -103,10 +103,6 @@ void error_setg_errno_internal(Error **errp,
     va_list ap;
     int saved_errno = errno;
 
-    if (errp == NULL) {
-        return;
-    }
-
     va_start(ap, fmt);
     error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap,
                os_errno != 0 ? strerror(os_errno) : NULL);