qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Crosthwaite <crosthwaitepeter@gmail.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, saipava@xilinx.com, stefanha@redhat.com,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>
Subject: [Qemu-devel] [RFC] Block device size rounding
Date: Fri,  9 Oct 2015 20:01:55 -0700	[thread overview]
Message-ID: <1444446115-3796-1-git-send-email-crosthwaite.peter@gmail.com> (raw)

I have in interesting problem with SD cards, where if you pass a block
device that is not multiple-of-512k size the last bit gets chopped off.
The problem is the card can only report a 512kX size to the guest, so
a significant rounding is needed one way or the other. The current
round-down policy causes crashing boots because parts of my guest
file-system are missing.

The below patch works around it, by changing to round-up and simply
ignoring reads and writes past the end of the block device file.

What is the correct action here though? If the file is writeable should
we just allow the device to extend its size? Is that possible already?
Just zero-pad read-only?

The same could be applied to pflash, where the device init barfs if the
backing file is too small (the devices are inited of a constant size,
not based on the block device size).

Requiring the user to pad files in a device dependent way is a little
user-unfriendly.

Regards,
Peter
---
 hw/sd/sd.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 3e2a451..539bb72 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -248,13 +248,18 @@ static const uint8_t sd_csd_rw_mask[16] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
 };
 
-static void sd_set_csd(SDState *sd, uint64_t size)
+static uint64_t sd_set_csd(SDState *sd, uint64_t size)
 {
-    uint32_t csize = (size >> (CMULT_SHIFT + HWBLOCK_SHIFT)) - 1;
-    uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
-    uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
+    uint64_t actual_size;
 
     if (size <= 0x40000000) {	/* Standard Capacity SD */
+        uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
+        uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
+        uint32_t csize;
+
+        actual_size = ROUND_UP(size, 1 << (CMULT_SHIFT + HWBLOCK_SHIFT));
+        csize = (actual_size >> (CMULT_SHIFT + HWBLOCK_SHIFT)) - 1;
+
         sd->csd[0] = 0x00;	/* CSD structure */
         sd->csd[1] = 0x26;	/* Data read access-time-1 */
         sd->csd[2] = 0x00;	/* Data read access-time-2 */
@@ -281,7 +286,8 @@ static void sd_set_csd(SDState *sd, uint64_t size)
         sd->csd[14] = 0x00;	/* File format group */
         sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
     } else {			/* SDHC */
-        size /= 512 * 1024;
+        actual_size = ROUND_UP(size, 512 * 1024);
+        size = actual_size / (512 * 1024);
         size -= 1;
         sd->csd[0] = 0x40;
         sd->csd[1] = 0x0e;
@@ -301,6 +307,7 @@ static void sd_set_csd(SDState *sd, uint64_t size)
         sd->csd[15] = 0x00;
         sd->ocr |= 1 << 30;     /* High Capacity SD Memory Card */
     }
+    return actual_size;
 }
 
 static void sd_set_rca(SDState *sd)
@@ -408,7 +415,7 @@ static void sd_reset(SDState *sd)
     sd_set_ocr(sd);
     sd_set_scr(sd);
     sd_set_cid(sd);
-    sd_set_csd(sd, size);
+    size = sd_set_csd(sd, size);
     sd_set_cardstatus(sd);
     sd_set_sdstatus(sd);
 
-- 
1.9.1

             reply	other threads:[~2015-10-10  3:02 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-10  3:01 Peter Crosthwaite [this message]
2015-10-12 15:56 ` [Qemu-devel] [RFC] Block device size rounding John Snow
2015-10-12 16:26   ` Eric Blake
2015-10-12 18:09     ` Peter Crosthwaite
2015-10-12 18:26       ` John Snow
2015-10-13  7:16         ` Markus Armbruster
2015-10-13  9:14         ` Kevin Wolf
2015-10-13 15:30           ` Peter Crosthwaite
2015-10-13 15:51             ` John Snow
2015-10-14  8:36               ` Kevin Wolf
2015-10-16 17:04                 ` John Snow
2015-10-16 18:10                   ` Peter Crosthwaite

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1444446115-3796-1-git-send-email-crosthwaite.peter@gmail.com \
    --to=crosthwaitepeter@gmail.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=saipava@xilinx.com \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).