summaryrefslogtreecommitdiff
path: root/pc-bios/s390-ccw/bootmap.c
diff options
context:
space:
mode:
authorEugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>2014-08-29 11:01:39 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-09-01 09:23:02 +0200
commitf04db28b86654d1c7ff805b40eff27bba6b0f686 (patch)
tree752e37099f4a5149fc53a9df51cfdfa48e0833a7 /pc-bios/s390-ccw/bootmap.c
parentb0885f7599739ed1d7002774f9be2ba1f8212cc7 (diff)
downloadqemu-f04db28b86654d1c7ff805b40eff27bba6b0f686.tar.gz
pc-bios/s390-ccw Really big EAV ECKD DASD handling
For EAV ECKD DASD, the cylinder count will have the magic value 0xfffeU. Therefore, use the block number to test for valid eckd addresses instead. Signed-off-by: Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'pc-bios/s390-ccw/bootmap.c')
-rw-r--r--pc-bios/s390-ccw/bootmap.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index e4352b16cd..d4c579c245 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -93,11 +93,23 @@ static inline void verify_boot_info(BootInfo *bip)
"Bad block size in zIPL section of the 1st record.");
}
-static bool eckd_valid_address(BootMapPointer *p)
+static block_number_t eckd_block_num(BootMapPointer *p)
{
+ const uint64_t sectors = virtio_get_sectors();
+ const uint64_t heads = virtio_get_heads();
const uint64_t cylinder = p->eckd.cylinder
+ ((p->eckd.head & 0xfff0) << 12);
const uint64_t head = p->eckd.head & 0x000f;
+ const block_number_t block = sectors * heads * cylinder
+ + sectors * head
+ + p->eckd.sector
+ - 1; /* block nr starts with zero */
+ return block;
+}
+
+static bool eckd_valid_address(BootMapPointer *p)
+{
+ const uint64_t head = p->eckd.head & 0x000f;
if (head >= virtio_get_heads()
|| p->eckd.sector > virtio_get_sectors()
@@ -105,27 +117,14 @@ static bool eckd_valid_address(BootMapPointer *p)
return false;
}
- if (!virtio_guessed_disk_nature() && cylinder >= virtio_get_cylinders()) {
+ if (!virtio_guessed_disk_nature() &&
+ eckd_block_num(p) >= virtio_get_blocks()) {
return false;
}
return true;
}
-static block_number_t eckd_block_num(BootMapPointer *p)
-{
- const uint64_t sectors = virtio_get_sectors();
- const uint64_t heads = virtio_get_heads();
- const uint64_t cylinder = p->eckd.cylinder
- + ((p->eckd.head & 0xfff0) << 12);
- const uint64_t head = p->eckd.head & 0x000f;
- const block_number_t block = sectors * heads * cylinder
- + sectors * head
- + p->eckd.sector
- - 1; /* block nr starts with zero */
- return block;
-}
-
static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
{
block_number_t block_nr;