From: Jan Kiszka <[email protected]> There was another mistake in the size check which 8c81d38ea5ae now revealed: alignment rules depend on the size of the image. Up to and include 2GB, the power-of-2 rule applies. For larger images, multiples of 512 sectors must be used. Fix the check accordingly.
Signed-off-by: Jan Kiszka <[email protected]> --- Not fully tested yet, but as staging is broken right now, I wanted to provide this already for early feedback. hw/sd/sd.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 2d34781fe4..0f33784bd0 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -2759,6 +2759,26 @@ static void sd_instance_finalize(Object *obj) timer_free(sd->ocr_power_timer); } +static void blk_size_error(int64_t blk_size, int64_t blk_size_aligned, + const char *rule, Error **errp) +{ + char *blk_size_str; + + blk_size_str = size_to_str(blk_size); + error_setg(errp, "Invalid SD card size: %s", blk_size_str); + g_free(blk_size_str); + + blk_size_str = size_to_str(blk_size_aligned); + error_append_hint(errp, + "SD card size has to be %s, e.g. %s.\n" + "You can resize disk images with" + " 'qemu-img resize <imagefile> <new-size>'\n" + "(note that this will lose data if you make the" + " image smaller than it currently is).\n", + rule, blk_size_str); + g_free(blk_size_str); +} + static void sd_realize(DeviceState *dev, Error **errp) { SDState *sd = SDMMC_COMMON(dev); @@ -2782,24 +2802,16 @@ static void sd_realize(DeviceState *dev, Error **errp) } blk_size = blk_getlength(sd->blk) - sd->boot_part_size * 2; - if (blk_size > 0 && !is_power_of_2(blk_size)) { - int64_t blk_size_aligned = pow2ceil(blk_size); - char *blk_size_str; - - blk_size_str = size_to_str(blk_size); - error_setg(errp, "Invalid SD card size: %s", blk_size_str); - g_free(blk_size_str); - - blk_size_str = size_to_str(blk_size_aligned); - error_append_hint(errp, - "SD card size has to be a power of 2, e.g. %s.\n" - "You can resize disk images with" - " 'qemu-img resize <imagefile> <new-size>'\n" - "(note that this will lose data if you make the" - " image smaller than it currently is).\n", - blk_size_str); - g_free(blk_size_str); - + if (blk_size > 0 && blk_size <= SDSC_MAX_CAPACITY && + !is_power_of_2(blk_size)) { + blk_size_error(blk_size, pow2ceil(blk_size), "a power of 2", errp); + return; + } else if (blk_size > SDSC_MAX_CAPACITY && + blk_size % (1 << HWBLOCK_SHIFT) != 0) { + int64_t blk_size_aligned = + ((blk_size >> HWBLOCK_SHIFT) + 1) << HWBLOCK_SHIFT; + blk_size_error(blk_size, blk_size_aligned, "multiples of 512", + errp); return; } -- 2.43.0
