Change zipl_load_segment() to accept explicit blockno and address parameters instead of ComponentEntry pointer and return segment length.
Modify this function to allow the caller to specify a memory address where segment data should be loaded into. seg_len variable is necessary to store the calculated segment length and is used during signature verification. Return the length on success, or a negative return code on failure. Remove static qualifier and add function declaration to bootmap.h to make it accessible to other modules. Signed-off-by: Zhuoying Cai <[email protected]> Reviewed-by: Thomas Huth <[email protected]> Reviewed-by: Collin Walling <[email protected]> Reviewed-by: Jared Rossi <[email protected]> --- pc-bios/s390-ccw/bootmap.c | 14 ++++++-------- pc-bios/s390-ccw/bootmap.h | 13 +++++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 03841672be..d0ac97795d 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -613,19 +613,15 @@ static int ipl_eckd(void) * IPL a SCSI disk */ -static int zipl_load_segment(ComponentEntry *entry) +int zipl_load_segment(block_number_t blockno, uint64_t address) { const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr)); ScsiBlockPtr *bprs = (void *)sec; const int bprs_size = sizeof(sec); - block_number_t blockno; - uint64_t address; int i; char err_msg[] = "zIPL failed to read BPRS at 0xZZZZZZZZZZZZZZZZ"; char *blk_no = &err_msg[30]; /* where to print blockno in (those ZZs) */ - - blockno = entry->data.blockno; - address = entry->compdat.load_addr; + int seg_len = 0; debug_print_int("loading segment at block", blockno); debug_print_int("addr", address); @@ -668,10 +664,12 @@ static int zipl_load_segment(ComponentEntry *entry) puts("zIPL load segment failed"); return -EIO; } + + seg_len += bprs->size * (bprs[i].blockct + 1); } } while (blockno); - return 0; + return seg_len; } static int zipl_run_normal(ComponentEntry **entry_ptr, const uint8_t *tmp_sec) @@ -687,7 +685,7 @@ static int zipl_run_normal(ComponentEntry **entry_ptr, const uint8_t *tmp_sec) continue; } - if (zipl_load_segment(entry)) { + if (zipl_load_segment(entry->data.blockno, entry->compdat.load_addr) < 0) { return -1; } diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 95943441d3..40580600b5 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -113,6 +113,19 @@ typedef struct ScsiMbr { ScsiBlockPtr pt; /* block pointer to program table */ } __attribute__ ((packed)) ScsiMbr; +/** + * zipl_load_segment + * @blockno: block number of the first BPRS describing the segment. + * @address: guest physical address at which to load the segment. + * + * Walks the BPRS chain starting at @blockno, loading each data block + * into guest memory at @address. + * + * Returns: length of the segment on success, + * negative value on error. + */ +int zipl_load_segment(block_number_t blockno, uint64_t address); + #define ZIPL_MAGIC "zIPL" #define ZIPL_MAGIC_EBCDIC "\xa9\xc9\xd7\xd3" #define IPL1_MAGIC "\xc9\xd7\xd3\xf1" /* == "IPL1" in EBCDIC */ -- 2.54.0
