summaryrefslogtreecommitdiff
path: root/hw/block
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-03-26 09:57:07 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-03-26 09:57:07 +0000
commit527266f324def9f7f392fe3b0dd940cb8dc699d9 (patch)
tree26137e5661167d49913a911e1e8986e8de346a8b /hw/block
parent199f8d94be106f20dfce23fa4e157fc8d55fd494 (diff)
parent3f905a5bba69691f1384a0464b5a7b8e516861c4 (diff)
downloadqemu-527266f324def9f7f392fe3b0dd940cb8dc699d9.zip
Merge remote-tracking branch 'remotes/armbru/tags/pull-pflash-2019-03-26' into staging
Pflash and firmware configuration patches for 2019-03-26 # gpg: Signature made Tue 26 Mar 2019 07:21:13 GMT # gpg: using RSA key 3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-pflash-2019-03-26: pflash: Bury disabled code to limit device sizes pflash: Require backend size to match device, improve errors Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/block')
-rw-r--r--hw/block/block.c48
-rw-r--r--hw/block/pflash_cfi01.c15
-rw-r--r--hw/block/pflash_cfi02.c13
3 files changed, 53 insertions, 23 deletions
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;
}
}