[PATCH] hw/sd/sdcard: Fix size check for backing block image, part II

Jan Kiszka posted 1 patch 2 weeks, 5 days ago
Failed in applying to current master (apply log)
hw/sd/sd.c | 48 ++++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 18 deletions(-)
[PATCH] hw/sd/sdcard: Fix size check for backing block image, part II
Posted by Jan Kiszka 2 weeks, 5 days ago
From: Jan Kiszka <jan.kiszka@siemens.com>

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 <jan.kiszka@siemens.com>
---

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