diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-03-26 09:57:07 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-03-26 09:57:07 +0000 |
commit | 527266f324def9f7f392fe3b0dd940cb8dc699d9 (patch) | |
tree | 26137e5661167d49913a911e1e8986e8de346a8b | |
parent | 199f8d94be106f20dfce23fa4e157fc8d55fd494 (diff) | |
parent | 3f905a5bba69691f1384a0464b5a7b8e516861c4 (diff) |
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>
-rw-r--r-- | hw/block/block.c | 48 | ||||
-rw-r--r-- | hw/block/pflash_cfi01.c | 15 | ||||
-rw-r--r-- | hw/block/pflash_cfi02.c | 13 | ||||
-rw-r--r-- | include/hw/block/block.h | 7 |
4 files changed, 59 insertions, 24 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; } } 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, |