From f9741d9d3d178299096f5802be2ce10ca67cece3 Mon Sep 17 00:00:00 2001 From: Andrew Lukoshko Date: Wed, 12 Aug 2026 11:59:44 +0000 Subject: [PATCH] Backport upstream s390-tools fixes for 2.40.0 --- s390utils-2.40.0-rhel.patch | 1283 +++++++++++++++++++++++++++++++++++ s390utils.spec | 12 +- 2 files changed, 1293 insertions(+), 2 deletions(-) diff --git a/s390utils-2.40.0-rhel.patch b/s390utils-2.40.0-rhel.patch index e69de29..b81009a 100644 --- a/s390utils-2.40.0-rhel.patch +++ b/s390utils-2.40.0-rhel.patch @@ -0,0 +1,1283 @@ +From 11f2ccb9570569a57ac0ef0148efcd9b35d7a6b6 Mon Sep 17 00:00:00 2001 +From: Aswin Karuvally +Date: Sun, 1 Feb 2026 18:39:38 +0530 +Subject: [PATCH] hsci: Automatically set appropriate MTU for HSCI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +At present, the hsci tool creates HiperSockets Converged Interface +(HSCI) with MTU of 1500 bytes regardless of the values of MTU for the +external and HiperSockets interface from which it is formed. This can +degrade performance or worse, affect network connectivity through the +converged interface. + +Update the tool to automatically set MTU of HSCI as the lower of the +MTU values of external and HiperSockets interface. + +Reviewed-by: Alexandra Winter +Signed-off-by: Aswin Karuvally +Signed-off-by: Jan Höppner +--- + hsci/hsci | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/hsci/hsci b/hsci/hsci +index 5540e82fc..8f884c9ac 100755 +--- a/hsci/hsci ++++ b/hsci/hsci +@@ -365,6 +365,13 @@ function add_hsci { + fi + fi + ++ #### Set MTU for the veth pair ++ ndev_mtu="$(cat /sys/class/net/${ndev}/mtu)" ++ hsdev_mtu="$(cat /sys/class/net/${hsdev}/mtu)" ++ hsci_mtu=$(( ndev_mtu < hsdev_mtu ? ndev_mtu : hsdev_mtu )) ++ ip link set dev $hscibp mtu $hsci_mtu ++ ip link set dev $hsci mtu $hsci_mtu ++ + #### Set veth pair to UP + ip link set dev $hscibp up >/dev/null 2>&1 + if [ $? -ne 0 ]; then +From 376ddfbd22f3ca6bed4fb80f2a5eb1ee9c89e3d9 Mon Sep 17 00:00:00 2001 +From: Mete Durlu +Date: Tue, 17 Feb 2026 09:02:34 +0100 +Subject: [PATCH] hyptop/opts: Replace sort_field option with sort +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Hyptop's "--sort_field" command line option has always been documented +as "--sort", while the code _only_ explicitly has "--sort_field". +Specifying the shorter "--sort" happened to work due to an unnoticed +getopt() behavior. + +From getopt(3) man page: +""" + Long option names may be abbreviated if the abbreviation is unique + or is an exact match for some defined option. +""" + +With the addition of "--sort-field" as another unique identifier via +commit c5695e43c4cd ("hyptop/opts: Replace long option formats for +consistency") "--sort" is no longer unique. getopt() won't be able to +use that as an abbreviation, since there is ambiguity between +"--sort_field" and new "--sort-field" as they are defined as separate +options. + +Replace "--sort-field" and "--sort_field" with plain "--sort" to adhere +to the documented hyptop command line argument specification and resolve +the broken behavior. + +Fixes: c5695e43c4cd ("hyptop/opts: Replace long option formats for consistency") +Reported-by: Gorkem Kilinc +Reviewed-by: Jan Höppner +Signed-off-by: Mete Durlu +Signed-off-by: Jan Höppner +--- + hyptop/opts.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/hyptop/opts.c b/hyptop/opts.c +index ca1820691..a88296839 100644 +--- a/hyptop/opts.c ++++ b/hyptop/opts.c +@@ -58,9 +58,8 @@ static char HELP_TEXT[] = + * Options with underscore to keep compatibility + */ + #define OPT_BATCH_MODE 257 /* --batch_mode */ +-#define OPT_SORT_FIELD 258 /* --sort | --sort_field */ +-#define OPT_CPU_TYPES 259 /* --cpu_types */ +-#define OPT_SMT_FACTOR 260 /* --smt_factor */ ++#define OPT_CPU_TYPES 258 /* --cpu_types */ ++#define OPT_SMT_FACTOR 259 /* --smt_factor */ + + /* + * Initialize default settings +@@ -224,7 +223,7 @@ static void l_fields_set(char *str) + } + + /* +- * Set the "--sort_field" option ++ * Set the "--sort" option + */ + static void l_sort_field_set(char *str) + { +@@ -371,8 +370,7 @@ void opts_parse(int argc, char *argv[]) + { "sys", required_argument, NULL, 's'}, + { "iterations", required_argument, NULL, 'n'}, + { "fields", required_argument, NULL, 'f'}, +- { "sort-field", required_argument, NULL, 'S'}, +- { "sort_field", required_argument, NULL, OPT_SORT_FIELD}, ++ { "sort", required_argument, NULL, 'S'}, + { "cpu-types", required_argument, NULL, 't'}, + { "cpu_types", required_argument, NULL, OPT_CPU_TYPES}, + { "format", required_argument, NULL, OPT_FORMAT }, +@@ -420,7 +418,6 @@ void opts_parse(int argc, char *argv[]) + case 'f': + l_fields_set(optarg); + break; +- case OPT_SORT_FIELD: + case 'S': + l_sort_field_set(optarg); + break; +From 7c75df9e9634548a2513aa1e6dc7f6c100a4f37a Mon Sep 17 00:00:00 2001 +From: Mete Durlu +Date: Tue, 17 Feb 2026 09:54:08 +0100 +Subject: [PATCH] hyptop/opts: Fix long command line option abbreviations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Hyptop should be able to accept abbreviations of the long command line +options as getopt() is able to match them. Ex; + +$ hyptop --batch-mode + +$ hyptop --batch + +$ hyptop --bat + +From getopt(3) man page: +""" + Long option names may be abbreviated if the abbreviation is unique + or is an exact match for some defined option. +""" + +After the introduction of commit c5695e43c4cd ("hyptop/opts: Replace long +option formats for consistency") long command line options for hyptop +received additional definitions to support dash separated option formats. +Unfortunately these definitions were defined as new and unique options +and caused an ambiguity for getopt() when abbreviations matched both +definitions. Ex; + +$ hyptop --batch +hyptop: option '--batch' is ambiguous; +possibilities: '--batch-mode' '--batch_mode' + +Map both long option formats to the same short option to fix the +issue and restore the functionality. + +Fixes: c5695e43c4cd ("hyptop/opts: Replace long option formats for consistency") +Reported-by: Gorkem Kilinc +Reviewed-by: Jan Höppner +Signed-off-by: Mete Durlu +Signed-off-by: Jan Höppner +--- + hyptop/opts.c | 16 +++------------- + 1 file changed, 3 insertions(+), 13 deletions(-) + +diff --git a/hyptop/opts.c b/hyptop/opts.c +index a8829683..1a98cd99 100644 +--- a/hyptop/opts.c ++++ b/hyptop/opts.c +@@ -54,13 +54,6 @@ static char HELP_TEXT[] = + #define OPT_FORMAT 256 /* --format */ + #define OPT_FORMAT_ALL 261 /* --all*/ + +-/* +- * Options with underscore to keep compatibility +- */ +-#define OPT_BATCH_MODE 257 /* --batch_mode */ +-#define OPT_CPU_TYPES 258 /* --cpu_types */ +-#define OPT_SMT_FACTOR 259 /* --smt_factor */ +- + /* + * Initialize default settings + */ +@@ -361,18 +354,18 @@ void opts_parse(int argc, char *argv[]) + { "version", no_argument, NULL, 'v'}, + { "help", no_argument, NULL, 'h'}, + { "batch-mode", no_argument, NULL, 'b'}, +- { "batch_mode", no_argument, NULL, OPT_BATCH_MODE}, ++ { "batch_mode", no_argument, NULL, 'b'}, + { "all", no_argument, NULL, OPT_FORMAT_ALL }, + { "delay", required_argument, NULL, 'd'}, + { "smt-factor", required_argument, NULL, 'm'}, +- { "smt_factor", required_argument, NULL, OPT_SMT_FACTOR}, ++ { "smt_factor", required_argument, NULL, 'm'}, + { "window", required_argument, NULL, 'w'}, + { "sys", required_argument, NULL, 's'}, + { "iterations", required_argument, NULL, 'n'}, + { "fields", required_argument, NULL, 'f'}, + { "sort", required_argument, NULL, 'S'}, + { "cpu-types", required_argument, NULL, 't'}, +- { "cpu_types", required_argument, NULL, OPT_CPU_TYPES}, ++ { "cpu_types", required_argument, NULL, 't'}, + { "format", required_argument, NULL, OPT_FORMAT }, + { NULL, 0, NULL, 0 } + }; +@@ -391,14 +384,12 @@ void opts_parse(int argc, char *argv[]) + case 'h': + l_usage(); + hyptop_exit(0); +- case OPT_BATCH_MODE: + case 'b': + l_batch_mode_set(); + break; + case 'd': + l_delay_set(optarg); + break; +- case OPT_SMT_FACTOR: + case 'm': + l_factor_set(optarg); + break; +@@ -411,7 +402,6 @@ void opts_parse(int argc, char *argv[]) + case 'n': + l_iterations_set(optarg); + break; +- case OPT_CPU_TYPES: + case 't': + l_cpu_types_set(optarg); + break; +From 50f909db8f53011b00c5819e593504264d23bb82 Mon Sep 17 00:00:00 2001 +From: Vasily Gorbik +Date: Thu, 12 Mar 2026 18:36:00 +0100 +Subject: [PATCH] zipl/boot: Fix stage3 secure boot trailer placement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The stage3 linker script places .sb.trailer so that it must end at +COMMAND_LINE_EXTRA. The current script derives the start address from +SIZEOF(.sb.trailer) before the section is emitted: + + . = COMMAND_LINE_EXTRA - SIZEOF(.sb.trailer); + +With binutils older than 2.39 before commit 648f6099d4dc ("-z relro +relaxation and ld script SIZEOF") this can result in .sb.trailer being +placed at COMMAND_LINE_EXTRA instead, moving the trailer into the +following area and breaking the expected layout. + +The trailer has a fixed size, so use an explicit constant for the +placement calculation and keep the ASSERT to verify the final section +size. This makes the placement deterministic again. + +Fixes: a1126352ecfa ("zipl/boot: Improve linker scripts") +Reviewed-by: Marc Hartmayer +Signed-off-by: Vasily Gorbik +Signed-off-by: Jan Höppner +--- + zipl/boot/stage3.lds.S | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/zipl/boot/stage3.lds.S b/zipl/boot/stage3.lds.S +index 35ed32d29..cbfaaf0fc 100644 +--- a/zipl/boot/stage3.lds.S ++++ b/zipl/boot/stage3.lds.S +@@ -48,15 +48,16 @@ SECTIONS + .rodata : {*(.rodata .rodata.*) } + .data : { *(.data .data.*) } + ++#define SB_TRAILER_SIZE 32 + /* Trailer needed for Secure Boot */ +- . = COMMAND_LINE_EXTRA - SIZEOF(.sb.trailer); ++ . = COMMAND_LINE_EXTRA - SB_TRAILER_SIZE; + .sb.trailer : { + QUAD(0x0000c00000000000) + QUAD(STAGE3_ENTRY + PSW_LOAD) + QUAD(STAGE3_ENTRY) + QUAD(0x000000207a49504c) + } +- ASSERT(SIZEOF(.sb.trailer) == 32, "Invalid .sb.trailer size") ++ ASSERT(SIZEOF(.sb.trailer) == SB_TRAILER_SIZE, "Invalid .sb.trailer size") + + . = COMMAND_LINE_EXTRA; + .cmdline_extra : { +From fcfee1aa84d3d3afef6a30b3657b2a2ea99edfce Mon Sep 17 00:00:00 2001 +From: Eduard Shishkin +Date: Mon, 16 Mar 2026 17:31:33 +0100 +Subject: [PATCH] zipl/src: Fix a bug in building replicated program tables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When installing IPL on mirrored targets, zipl builds multiple program +tables (one such table per each mirror). If the option "--add-files" +was specified, then zipl uses the in-bootmap files, that was written +at the prevoius iteration (for the mirror ID #0) to build program +tables for mirrors with ID #1 (and larger). The in-bootmap files +already don't contain trailers. Despite this, the building process +cuts off the tail of trailer size, which results in corrupted boot +data. + +This bug may result in crashing the kernel when booting from mirrors +with ID #1 (and larger) and manifests only if the boot components are +signed and the option "--add-files" is specified for the installation +session. + +Don't count the trailer, when building program tables using in-bootmap +files written at the previous iteration. + +Fixes: 431e4542ca9c ("zipl/src: Reuse data of file components in bootmap") +Signed-off-by: Eduard Shishkin +Reviewed-by: Jan Höppner +Signed-off-by: Jan Höppner +--- + zipl/src/bootmap.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 7d75b608..14a30c34 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -441,12 +441,14 @@ static int add_component_file(struct install_set *bis, const char *filename, + + if (add_files && comp_reg->offset > 0) { + /* +- * The file has been already written to the bootmap. ++ * The file has been already written to the bootmap, ++ * and that in-bootmap file doesn't contain a trailer. + * Use the respective region in the bootmap file to + * add the component + */ + filename = bis->filename; + add_files = 0; ++ trailer = 0; + } else { + comp_reg = NULL; + } +From 984e008127985172bdfe90262d5dc705cc5149a1 Mon Sep 17 00:00:00 2001 +From: Eduard Shishkin +Date: Mon, 23 Mar 2026 16:31:50 +0100 +Subject: [PATCH] zipl/src: Indicate in a verbose output if a component is + signed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Regardless of secure boot support, indicate in the verbose zipl(8) +output if a component is signed. + +Signed-off-by: Eduard Shishkin +Reviewed-by: Jan Höppner +Signed-off-by: Jan Höppner +--- + zipl/src/bootmap.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 14a30c34..6a72d28c 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -704,9 +704,6 @@ static int add_ipl_program(struct install_set *bis, bool add_envblk, + /* initiate values for ramdisk */ + stats.st_size = 0; + if (ipl->common.ramdisk != NULL) { +- /* Add ramdisk */ +- if (verbose && bis->mirrors[mirror_id].print_details) +- printf(" initial ramdisk...: %s\n", ipl->common.ramdisk); + /* Get ramdisk file size */ + if (stat(ipl->common.ramdisk, &stats)) { + error_reason(strerror(errno)); +@@ -834,10 +831,10 @@ static int add_ipl_program(struct install_set *bis, bool add_envblk, + offset += sizeof(struct component_entry); + + /* Add kernel image */ +- if (verbose && bis->mirrors[mirror_id].print_details) +- printf(" kernel image......: %s\n", ipl->common.image); +- + signature_size = extract_signature(ipl->common.image, &signature, &sig_head); ++ if (verbose && bis->mirrors[mirror_id].print_details) ++ printf(" kernel image......: %s%s\n", ++ ipl->common.image, signature_size ? " (signed)" : ""); + if (signature_size && + (is_secure == SECURE_BOOT_ENABLED || + (is_secure == SECURE_BOOT_AUTO && secure_boot_supported))) { +@@ -906,6 +903,10 @@ static int add_ipl_program(struct install_set *bis, bool add_envblk, + if (ipl->common.ramdisk != NULL) { + signature_size = extract_signature(ipl->common.ramdisk, &signature, + &sig_head); ++ if (verbose && bis->mirrors[mirror_id].print_details) ++ printf(" initial ramdisk...: %s%s\n", ++ ipl->common.ramdisk, ++ signature_size ? " (signed)" : ""); + if (signature_size && + (is_secure == SECURE_BOOT_ENABLED || + (is_secure == SECURE_BOOT_AUTO && +From 9882aabe4434594cd055b95ad8427338207a8763 Mon Sep 17 00:00:00 2001 +From: Eduard Shishkin +Date: Mon, 8 Jun 2026 17:12:05 +0200 +Subject: [PATCH] zipl/src: Update format of zipl helpers output +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change the format of zipl helpers output to support hybrid mirrors +(i.e. composed of disks of different types and geometry). +The new format imposes an additional requirement that any key-value +pair "targetbase=X:Y" titles a new section with a set of target +parmeters for the base disk identified by that pair. + +Without this change, zipl reports "Inconsistent script output". +To reproduce the problem, build a mixed mirrored setup with first +SCSI disk and second DASD disk, and prepare it for IPL. + +Fixes: 731f00202c53 ("zipl/src: Enable heterogeneous mirrors support") +Reviewed-by: Stefan Haberland +Signed-off-by: Eduard Shishkin +Signed-off-by: Jan Höppner +--- + zipl/include/job.h | 2 +- + zipl/src/disk.c | 81 ++++++++++++++++++---------------------------- + 2 files changed, 32 insertions(+), 51 deletions(-) + +diff --git a/zipl/include/job.h b/zipl/include/job.h +index 0acea592..3e93a323 100644 +--- a/zipl/include/job.h ++++ b/zipl/include/job.h +@@ -167,7 +167,7 @@ struct job_data { + static inline struct target *target_at(struct job_target_data *data, + int index) + { +- return index >= MAX_TARGETS ? NULL : &data->targets[index]; ++ return index < 0 || index >= MAX_TARGETS ? NULL : &data->targets[index]; + } + + static inline char *get_targetbase(struct job_target_data *data, int index) +diff --git a/zipl/src/disk.c b/zipl/src/disk.c +index 86ec6bc7..673224fb 100644 +--- a/zipl/src/disk.c ++++ b/zipl/src/disk.c +@@ -176,6 +176,15 @@ static int determine_virtblk_type(struct device_info *dev_info, + return rc; + } + ++#define GET_TARGET_OR_GOTO_ERR() \ ++ do { \ ++ if (target_id < 0) \ ++ goto err_inc; \ ++ t = target_at(td, target_id); \ ++ if (!t) \ ++ goto err_exc; \ ++ } while (0) ++ + /** + * Process a script output represented by FH and consisting + * of pairs 'key=value' (each such pair is on a separate line). +@@ -189,57 +198,46 @@ static int determine_virtblk_type(struct device_info *dev_info, + */ + static int set_target_parameters(FILE *fh, struct job_target_data *td) + { +- int idx[LAST_TARGET_PARAM] = {0}; ++ int target_id = -1; + struct target *t; + char buffer[80]; + char value[40]; +- char *error; + int i; + + /* reset array of target parameters */ + memset(td->targets, 0, sizeof(td->targets)); +- /** +- * Process a stream of 'key=value' pairs and distribute +- * them into groups. +- * The i-th occurrence of some "key" in the stream means +- * that the respective pair belongs to the group #i ++ /* ++ * Process a stream of key-value pairs and complete the array of ++ * target parameters. ++ * Each key-value pair "targetbase=foo" title a group of parameters ++ * for a new target. + */ +- error = "Exceeded the maximum number of base disks"; + while (fgets(buffer, 80, fh)) { + if (sscanf(buffer, "targetbase=%s", value) == 1) { +- t = target_at(td, idx[TARGET_BASE]++); +- if (!t) +- goto error; ++ target_id++; /* new title */ ++ GET_TARGET_OR_GOTO_ERR(); + t->targetbase = misc_strdup(value); + goto found; + } + if (sscanf(buffer, "targettype=%s", value) == 1) { +- t = target_at(td, idx[TARGET_TYPE]++); +- if (!t) +- goto error; ++ GET_TARGET_OR_GOTO_ERR(); + type_from_target(value, &t->targettype); + goto found; + } + if (sscanf(buffer, "targetgeometry=%s", value) == 1) { +- t = target_at(td, idx[TARGET_GEOMETRY]++); +- if (!t) +- goto error; ++ GET_TARGET_OR_GOTO_ERR(); + t->targetcylinders = atoi(strtok(value, ",")); + t->targetheads = atoi(strtok(NULL, ",")); + t->targetsectors = atoi(strtok(NULL, ",")); + goto found; + } + if (sscanf(buffer, "targetblocksize=%s", value) == 1) { +- t = target_at(td, idx[TARGET_BLOCKSIZE]++); +- if (!t) +- goto error; ++ GET_TARGET_OR_GOTO_ERR(); + t->targetblocksize = atoi(value); + goto found; + } + if (sscanf(buffer, "targetoffset=%s", value) == 1) { +- t = target_at(td, idx[TARGET_OFFSET]++); +- if (!t) +- goto error; ++ GET_TARGET_OR_GOTO_ERR(); + t->targetoffset = atol(value); + goto found; + } +@@ -247,43 +245,26 @@ static int set_target_parameters(FILE *fh, struct job_target_data *td) + found: + t->check_params++; + } ++ td->nr_targets = target_id + 1; + /* Check for consistency */ +- error = "Inconsistent script output"; +- /* +- * First, calculate total number of groups +- */ +- td->nr_targets = 0; +- for (i = 0; i < MAX_TARGETS; i++) { +- t = target_at(td, i); +- if (t->check_params == 0) +- break; +- td->nr_targets++; +- } + if (!td->nr_targets) +- /* No keywords found in the stream */ +- goto error; +- /* +- * Each group has to include targetbase, targettype, +- * targetblocksize and targetoffset. +- */ +- if (td->nr_targets != idx[TARGET_BASE] || +- td->nr_targets != idx[TARGET_TYPE] || +- td->nr_targets != idx[TARGET_BLOCKSIZE] || +- td->nr_targets != idx[TARGET_OFFSET]) +- goto error; ++ /* Missed a title pair "targetbase=foo" in the stream */ ++ goto err_inc; + /* +- * In addition, any group of "ECKD" type has to include +- * targetgeometry ++ * Any group of "ECKD" type has to include targetgeometry + */ + for (i = 0; i < td->nr_targets; i++) { + t = target_at(td, i); + assert(t->check_params >= 4); + if (disk_type_is_eckd(t->targettype) && t->check_params != 5) +- goto error; ++ goto err_inc; + } + return 0; +-error: +- error_reason("%s", error); ++err_inc: ++ error_reason("%s", "Inconsistent script output"); ++ return -1; ++err_exc: ++ error_reason("%s", "Exceeded the maximum number of base disks"); + return -1; + } + +From f2902a1990783159a8358ead99b4dd19009183a1 Mon Sep 17 00:00:00 2001 +From: Eduard Shishkin +Date: Wed, 10 Jun 2026 18:05:55 +0200 +Subject: [PATCH] zipl/src: Fix alignment of componets location in bootmap file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Calculate the alignment value as maximum of physical block sizes of +disks participating in the mirrored setup. Earlier the alignment was +calculated as a physical block size of the first disk of a mirrored +setup. + +Without this change, the assertion in disk_get_blocklist_from_file() +'assert(reg->offset % info->phy_block_size == 0)' is triggered in case +when blocksize of base disk #J > blocksize of base disk #I && (J>I). +To reproduce the problem, build a mixed mirrored setup with first SCSI +disk, second DASD disk and prepare it for IPL. + +Fixes: 731f00202c53 ("zipl/src: Enable heterogeneous mirrors support") +Reviewed-by: Stefan Haberland +Signed-off-by: Eduard Shishkin +Signed-off-by: Jan Höppner +--- + zipl/include/disk.h | 9 ++++---- + zipl/include/install.h | 4 ++-- + zipl/src/bootmap.c | 21 ++++++++++------- + zipl/src/disk.c | 27 +++++++++++++++++----- + zipl/src/install.c | 52 +++++++++++++++++++++++------------------- + 5 files changed, 69 insertions(+), 44 deletions(-) + +diff --git a/zipl/include/disk.h b/zipl/include/disk.h +index cce69f73a..ff64fda75 100644 +--- a/zipl/include/disk.h ++++ b/zipl/include/disk.h +@@ -93,6 +93,7 @@ struct device_info { + * as retrieved from "/proc/devices", or evaluated + */ + int fs_block_size; ++ int align; /* alignment of component location in bootmap */ + struct disk_info base[MAX_TARGETS]; /* array of physical disks for + * bootstrap blocks recording + */ +@@ -133,13 +134,13 @@ int disk_write_block_aligned(struct misc_fd *mfd, const void *data, + blocknum_t disk_write_block_buffer(struct misc_fd *fd, int fd_is_basedisk, + const void* buffer, size_t bytecount, + disk_blockptr_t** blocklist, +- int fs_block_size, struct disk_info *info); ++ int fs_block_size, int align, ++ struct disk_info *info); + blocknum_t disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, + const void *buffer, size_t bytecount, + disk_blockptr_t **blocklist, +- int fs_block_size, +- struct disk_info *info, int align, +- off_t *offset); ++ int fs_block_size, int align, ++ struct disk_info *info, off_t *offset); + void disk_print_devt(dev_t d); + void disk_print_devname(dev_t d); + void prepare_footnote_ptr(int source, char *ptr); +diff --git a/zipl/include/install.h b/zipl/include/install.h +index 71dc33d97..cc1f39b7f 100644 +--- a/zipl/include/install.h ++++ b/zipl/include/install.h +@@ -160,13 +160,13 @@ int install_mvdump(char* const device[], struct job_target_data* target, + + int install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, +- blocknum_t stage2_count, int fs_block_size, ++ blocknum_t stage2_count, int fs_block_size, int align, + struct disk_info *info); + int install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + blocknum_t *stage1b_count, + disk_blockptr_t *stage2_list, + blocknum_t stage2_count, int fs_block_size, +- struct disk_info *info); ++ int align, struct disk_info *info); + int rewind_tape(int fd); + + #endif /* INSTALL_H */ +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 6a72d28cb..9b5d2a12f 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -383,8 +383,8 @@ static int add_component_file_range(struct install_set *bis, + 0 /* not a base disk */, + buffer, size, list, + bis->info->fs_block_size, ++ bis->info->align, + info, +- info->phy_block_size, + /* + * save component offset + */ +@@ -478,7 +478,7 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer, + + align = fs_block_aligned_by_id(comp_id) ? + bis->info->fs_block_size : +- info->phy_block_size; ++ bis->info->align; + + if (bis->skip_prepare_device && + bis->mirrors[mirror_id].skip_prepare_blocklist) +@@ -486,8 +486,8 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer, + goto write_segment_table; + /* Write buffer */ + *count = disk_write_block_buffer_align(&bis->mfd, 0, buffer, size, list, +- bis->info->fs_block_size, +- info, align, &offset); ++ bis->info->fs_block_size, align, ++ info, &offset); + if (*count == 0) { + error_text("Could not write to bootmap file"); + return -1; +@@ -1265,7 +1265,7 @@ write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block, + + static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, + struct job_data *job, +- int fs_block_size, ++ int fs_block_size, int align, + struct disk_info *info, + disk_blockptr_t **stage1b_list, + blocknum_t *stage1b_count, +@@ -1289,6 +1289,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, + stage2_size, + &stage2_list, + fs_block_size, ++ align, + info); + free(stage2_data); + if (stage2_count == 0) { +@@ -1297,7 +1298,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, + } + if (install_fba_stage1b(mfd, stage1b_list, stage1b_count, + stage2_list, stage2_count, +- fs_block_size, info)) ++ fs_block_size, align, info)) + return -1; + free(stage2_list); + break; +@@ -1317,7 +1318,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, + + static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, + struct job_data *job, +- int fs_block_size, ++ int fs_block_size, int align, + struct disk_info *info, + disk_blockptr_t *program_table, + disk_blockptr_t **stage1b_list, +@@ -1341,6 +1342,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, + stage2b_size, + &stage2b_list, + fs_block_size, ++ align, + info); + free(stage2b_data); + if (stage2b_count == 0) { +@@ -1349,7 +1351,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, + } + if (install_eckd_stage1b(mfd, stage1b_list, stage1b_count, + stage2b_list, stage2b_count, +- fs_block_size, info)) ++ fs_block_size, align, info)) + return -1; + free(stage2b_list); + break; +@@ -1367,6 +1369,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, + stage2b_size, + stage1b_list, + fs_block_size, ++ align, + info); + free(stage2b_data); + if (stage2b_count == 0) { +@@ -1395,6 +1398,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, + case disk_type_fba: + rc = install_stages_dasd_fba(&bis->mfd, bis->filename, job, + bis->info->fs_block_size, ++ bis->info->align, + info, + &pt->stage1b_list, + &pt->stage1b_count, +@@ -1404,6 +1408,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, + case disk_type_eckd_cdl: + rc = install_stages_eckd_dasd(&bis->mfd, bis->filename, job, + bis->info->fs_block_size, ++ bis->info->align, + info, + &pt->table, + &pt->stage1b_list, +diff --git a/zipl/src/disk.c b/zipl/src/disk.c +index 673224fb9..b2f2561da 100644 +--- a/zipl/src/disk.c ++++ b/zipl/src/disk.c +@@ -575,7 +575,21 @@ static int disk_set_info_complete(struct job_target_data *td, + return 0; + } + +-static int device_set_info_complete(struct device_info *dev_info) ++static void device_get_alignment(struct device_info *dev_info, ++ struct job_target_data *td) ++{ ++ struct disk_info *base; ++ int i; ++ ++ for (i = 0; i < td->nr_targets; i++) { ++ base = &dev_info->base[i]; ++ if (dev_info->align < base->phy_block_size) ++ dev_info->align = base->phy_block_size; ++ } ++} ++ ++static int device_set_info_complete(struct device_info *dev_info, ++ struct job_target_data *td) + { + struct util_proc_part_entry part_entry; + +@@ -588,6 +602,7 @@ static int device_set_info_complete(struct device_info *dev_info) + } + /* Initialize file system block size with invalid value */ + dev_info->fs_block_size = -1; ++ device_get_alignment(dev_info, td); + return 0; + } + +@@ -689,7 +704,7 @@ int device_get_info(const char *device, struct job_target_data *td, + if (disk_set_info_complete(td, &data->base[i], &stats, fd)) + goto error; + } +- if (device_set_info_complete(data)) ++ if (device_set_info_complete(data, td)) + goto error; + free(script_file); + close(fd); +@@ -1017,7 +1032,7 @@ blocknum_t + disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, + const void *buffer, size_t bytecount, + disk_blockptr_t **blocklist, int fs_block_size, +- struct disk_info *info, int align, off_t *offset) ++ int align, struct disk_info *info, off_t *offset) + { + blocknum_t count; + blocknum_t i; +@@ -1058,12 +1073,12 @@ blocknum_t + disk_write_block_buffer(struct misc_fd *mfd, int fd_is_basedisk, + const void *buffer, size_t bytecount, + disk_blockptr_t **blocklist, int fs_block_size, +- struct disk_info *info) ++ int align, struct disk_info *info) + { + return disk_write_block_buffer_align(mfd, fd_is_basedisk, buffer, + bytecount, blocklist, +- fs_block_size, info, +- info->phy_block_size, NULL); ++ fs_block_size, align, info, ++ NULL); + } + + /* Print device node. */ +diff --git a/zipl/src/install.c b/zipl/src/install.c +index 176a00437..1baf153fa 100644 +--- a/zipl/src/install.c ++++ b/zipl/src/install.c +@@ -172,7 +172,7 @@ install_fba_ccw(int fd, disk_blockptr_t *program_table, + int + install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, +- blocknum_t stage2_count, int fs_block_size, ++ blocknum_t stage2_count, int fs_block_size, int align, + struct disk_info *info) + { + struct boot_eckd_stage1b *stage1b; +@@ -189,7 +189,7 @@ install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + goto out_free_stage1b; + *stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size, + stage1b_list, fs_block_size, +- info); ++ align, info); + if (*stage1b_count == 0) + goto out_free_stage1b; + rc = 0; +@@ -855,7 +855,7 @@ static void eckd_dump_store_param(struct eckd_dump_param *param, + + static int + install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size, +- struct disk_info *info, ++ int align, struct disk_info *info, + const struct stage2dump_parm_tail *stage2dump_parms) + { + disk_blockptr_t *stage2_list, *stage1b_list; +@@ -879,13 +879,13 @@ install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size, + if (misc_seek(mfd->fd, info->geo.start * info->phy_block_size)) + goto out_free_stage2; + stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, +- &stage2_list, +- fs_block_size, info); ++ &stage2_list, fs_block_size, ++ align, info); + if (stage2_count == 0) + goto out_free_stage2_list; + if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count, + stage2_list, stage2_count, fs_block_size, +- info)) ++ align, info)) + goto out_free_stage2_list; + /* Install stage 0 - afterwards we are at stage 1 position*/ + boot_init_eckd_ldl_stage0(&stage0); +@@ -913,8 +913,8 @@ install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size, + } + + static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, +- struct disk_info *info, void *stage2, +- size_t stage2_size, int mvdump, ++ int align, struct disk_info *info, ++ void *stage2, size_t stage2_size, int mvdump, + int force) + { + blocknum_t count, stage2_count, stage1b_count; +@@ -939,13 +939,13 @@ static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, + goto out; + stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, + &stage2_list, fs_block_size, +- info); ++ align, info); + if (stage2_count == 0) + goto out; + /* Install stage 1b behind stage 2*/ + if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count, + stage2_list, stage2_count, fs_block_size, +- info)) ++ align, info)) + goto out_free_stage2_list; + /* Install stage 0 */ + boot_init_eckd_cdl_stage0(&stage0_cdl); +@@ -973,7 +973,7 @@ static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, + + static int + install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, +- struct disk_info *info, ++ int align, struct disk_info *info, + const struct stage2dump_parm_tail *stage2dump_parms) + { + size_t stage2_size; +@@ -982,7 +982,7 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, + + if (boot_get_eckd_dump_stage2(&stage2, &stage2_size, stage2dump_parms)) + return -1; +- rc = install_dump_eckd_cdl(mfd, fs_block_size, ++ rc = install_dump_eckd_cdl(mfd, fs_block_size, align, + info, stage2, stage2_size, 0, 0); + free(stage2); + return rc; +@@ -990,7 +990,7 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, + + static int + install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, +- struct disk_info *info, ++ int align, struct disk_info *info, + const struct stage2dump_parm_tail *stage2dump_parms, + const struct mvdump_parm_table *mv_parm_table) + { +@@ -1002,7 +1002,7 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, + if (boot_get_eckd_mvdump_stage2(&stage2, &stage2_size, stage2dump_parms, + mv_parm_table)) + return -1; +- rc = install_dump_eckd_cdl(mfd, fs_block_size, info, stage2, ++ rc = install_dump_eckd_cdl(mfd, fs_block_size, align, info, stage2, + stage2_size, 1, + stage2dump_parms->mvdump_force); + free(stage2); +@@ -1012,7 +1012,7 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, + int + install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, +- blocknum_t stage2_count, int fs_block_size, ++ blocknum_t stage2_count, int fs_block_size, int align, + struct disk_info *info) + { + struct boot_fba_stage1b *stage1b; +@@ -1029,7 +1029,7 @@ install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + goto out_free_stage1b; + *stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size, + stage1b_list, fs_block_size, +- info); ++ align, info); + if (*stage1b_count == 0) + goto out_free_stage1b; + rc = 0; +@@ -1041,7 +1041,7 @@ install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, + + static int + install_svdump_fba(struct misc_fd *mfd, int fs_block_size, +- struct disk_info *info, ++ int align, struct disk_info *info, + const struct stage2dump_parm_tail *stage2dump_parms) + { + blocknum_t stage1b_count, stage2_count, blk; +@@ -1067,7 +1067,7 @@ install_svdump_fba(struct misc_fd *mfd, int fs_block_size, + goto out_free_stage2; + stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, + &stage2_list, fs_block_size, +- info); ++ align, info); + if (stage2_count == 0) + goto out_free_stage2; + /* Install stage 1b in front of stage 2 */ +@@ -1075,7 +1075,8 @@ install_svdump_fba(struct misc_fd *mfd, int fs_block_size, + if (misc_seek(mfd->fd, blk * info->phy_block_size)) + goto out_free_stage2_list; + if (install_fba_stage1b(mfd, &stage1b_list, &stage1b_count, +- stage2_list, stage2_count, fs_block_size, info)) ++ stage2_list, stage2_count, fs_block_size, ++ align, info)) + goto out_free_stage2_list; + /* Install stage 0/1 fill in dump partition parameter */ + if (boot_init_fba_stage0(&stage0, stage1b_list, stage1b_count)) +@@ -1219,14 +1220,17 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, + if (info->type == disk_type_eckd_ldl) + rc = install_svdump_eckd_ldl(&mfd, + dev_info->fs_block_size, +- info, &stage2dump_parms); ++ dev_info->align, info, ++ &stage2dump_parms); + else if (info->type == disk_type_eckd_cdl) + rc = install_svdump_eckd_cdl(&mfd, + dev_info->fs_block_size, +- info, &stage2dump_parms); ++ dev_info->align, info, ++ &stage2dump_parms); + else + rc = install_svdump_fba(&mfd, dev_info->fs_block_size, +- info, &stage2dump_parms); ++ dev_info->align, info, ++ &stage2dump_parms); + break; + case disk_type_scsi: + error_reason("%s: Unsupported disk type '%s' (try --dumptofs)", +@@ -1382,8 +1386,8 @@ install_mvdump(char* const device[], struct job_target_data* target, int count, + printf("Installing dump record on target partition " + "'%s'\n", device[i]); + rc = install_mvdump_eckd_cdl(&mfd, dev_info[i]->fs_block_size, +- info[i], &stage2dump_parms, +- &mvdump_parms); ++ dev_info[i]->align, info[i], ++ &stage2dump_parms, &mvdump_parms); + misc_free_temp_dev(tempdev); + + if (fsync(mfd.fd)) +From 4f622325efa2e433254ea01d3eabf472dcc6f757 Mon Sep 17 00:00:00 2001 +From: Eduard Shishkin +Date: Thu, 11 Jun 2026 12:21:09 +0200 +Subject: [PATCH] zipl/src: Fix add_component_file_range() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix add_component_file_range() to process components of all types +(not only of COMPONENT_TYPE_LOAD), similar to how it is going in +add_component_buffer(). + +Earlier components of COMPONENT_TYPE_SIGNATURE were processed only +by add_component_buffer(). Starting from 60bc1e3, signatures for +mirrors (i.e. base disks of #1 and larger ID) are processed also by +the function add_component_file_range(), which works incorrectly for +such type of components. + +Fixes: 60bc1e38d058 ("zipl/src: Reuse data of buffer components in bootmap") +Reviewed-by: Stefan Haberland +Signed-off-by: Eduard Shishkin +Signed-off-by: Jan Höppner +--- + zipl/src/bootmap.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 9b5d2a12..0d6df2d2 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -413,8 +413,13 @@ static int add_component_file_range(struct install_set *bis, + *count -= DIV_ROUND_UP(trailer, info->phy_block_size); + } + /* Fill in component location */ +- location->addr = load_address; +- location->size = *count * info->phy_block_size; ++ if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) { ++ location->addr = load_address; ++ location->size = *count * info->phy_block_size; ++ } else { ++ location->addr = 0; ++ location->size = 0; ++ } + /* Try to compact list */ + *count = disk_compact_blocklist(*list, *count, info); + write_segment_table: +From ee8897f9db5b93bc16799d0b534cc13c36719785 Mon Sep 17 00:00:00 2001 +From: Eduard Shishkin +Date: Thu, 11 Jun 2026 15:43:20 +0200 +Subject: [PATCH] zipl/src: Add ->set_location() private method of program + component +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add/use ->set_location() private method of struct component_footer +instead of checking component types every time when operating with +program components. + +Reviewed-by: Stefan Haberland +Signed-off-by: Eduard Shishkin +Signed-off-by: Jan Höppner +--- + zipl/include/install.h | 9 +++++++ + zipl/src/bootmap.c | 21 +++++----------- + zipl/src/zipl.c | 54 ++++++++++++++++++++++++++++++++---------- + 3 files changed, 57 insertions(+), 27 deletions(-) + +diff --git a/zipl/include/install.h b/zipl/include/install.h +index cc1f39b7..874068ef 100644 +--- a/zipl/include/install.h ++++ b/zipl/include/install.h +@@ -58,6 +58,9 @@ struct component_footer { + * in the bootmap file. Otherwise, to + * phy_block_size boundary. + */ ++ void (*set_location)(struct component_loc *location, ++ address_t load_address, blocknum_t count, ++ int block_size); + }; + + struct program_component { +@@ -109,6 +112,12 @@ static inline enum scsi_layout get_scsi_layout(unsigned char *bootblock) + return scsi_layout_unknown; + } + ++static inline struct component_footer * ++component_footer_by_id(enum program_component_id id) ++{ ++ return &component_footers[id]; ++} ++ + static inline component_type component_type_by_id(enum program_component_id id) + { + return component_footers[id].type; +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 0d6df2d2..78ff73aa 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -353,6 +353,7 @@ static int add_component_file_range(struct install_set *bis, + { + struct program_component *pc = get_component(bis, mirror_id, + comp_id, menu_idx); ++ struct component_footer *cf = component_footer_by_id(comp_id); + struct disk_info *info = &bis->info->base[mirror_id]; + struct component_loc *location = &pc->loc; + disk_blockptr_t **list = &pc->list; +@@ -413,13 +414,7 @@ static int add_component_file_range(struct install_set *bis, + *count -= DIV_ROUND_UP(trailer, info->phy_block_size); + } + /* Fill in component location */ +- if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) { +- location->addr = load_address; +- location->size = *count * info->phy_block_size; +- } else { +- location->addr = 0; +- location->size = 0; +- } ++ cf->set_location(location, load_address, *count, info->phy_block_size); + /* Try to compact list */ + *count = disk_compact_blocklist(*list, *count, info); + write_segment_table: +@@ -472,6 +467,7 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer, + comp_id, menu_idx); + struct file_range *comp_reg = get_component_range(bis, comp_id, + menu_idx); ++ struct component_footer *cf = component_footer_by_id(comp_id); + struct disk_info *info = &bis->info->base[mirror_id]; + struct component_loc *location = &pc->loc; + disk_blockptr_t **list = &pc->list; +@@ -506,14 +502,9 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer, + comp_reg->offset = offset; + comp_reg->len = size; + } +- if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) { +- /* Fill in component location */ +- location->addr = data.load_address; +- location->size = *count * info->phy_block_size; +- } else { +- location->addr = 0; +- location->size = 0; +- } ++ /* Fill in component location */ ++ cf->set_location(location, data.load_address, *count, ++ info->phy_block_size); + /* Try to compact list */ + *count = disk_compact_blocklist(*list, *count, info); + write_segment_table: +diff --git a/zipl/src/zipl.c b/zipl/src/zipl.c +index 21f6eb0a..faf5b118 100644 +--- a/zipl/src/zipl.c ++++ b/zipl/src/zipl.c +@@ -257,57 +257,87 @@ main(int argc, char* argv[]) + return abs(rc); + } + ++static void set_location_common(struct component_loc *location, ++ address_t load_address, ++ blocknum_t count, ++ int block_size) ++{ ++ location->addr = load_address; ++ location->size = count * block_size; ++} ++ ++static void set_location_noop(struct component_loc *location, ++ __attribute__((unused)) address_t load_address, ++ __attribute__((unused)) blocknum_t count, ++ __attribute__((unused)) int block_size) ++{ ++ location->addr = 0; ++ location->size = 0; ++} ++ + /** + * Program Component Footers + */ + struct component_footer component_footers[NR_PROGRAM_COMPONENTS] = { + [COMPONENT_ID_HEAP_AREA] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "heap area" ++ .desc = "heap area", ++ .set_location = set_location_common + }, + [COMPONENT_ID_STACK_AREA] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "stack area" ++ .desc = "stack area", ++ .set_location = set_location_common + }, + [COMPONENT_ID_LOADER_SIGNATURE] = { + .type = COMPONENT_TYPE_SIGNATURE, +- .desc = "loader signature" ++ .desc = "loader signature", ++ .set_location = set_location_noop + }, + [COMPONENT_ID_LOADER] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "internal loader" ++ .desc = "internal loader", ++ .set_location = set_location_common + }, + [COMPONENT_ID_PARAMETERS] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "parameters" ++ .desc = "parameters", ++ .set_location = set_location_common + }, + [COMPONENT_ID_IMAGE_SIGNATURE] = { + .type = COMPONENT_TYPE_SIGNATURE, +- .desc = "image signature" ++ .desc = "image signature", ++ .set_location = set_location_noop, + }, + [COMPONENT_ID_KERNEL_IMAGE] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "kernel image" ++ .desc = "kernel image", ++ .set_location = set_location_common + }, + [COMPONENT_ID_PARMLINE] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "parmline" ++ .desc = "parmline", ++ .set_location = set_location_common + }, + [COMPONENT_ID_RAMDISK_SIGNATURE] = { + .type = COMPONENT_TYPE_SIGNATURE, +- .desc = "ramdisk signature" ++ .desc = "ramdisk signature", ++ .set_location = set_location_noop + }, + [COMPONENT_ID_RAMDISK] = { + .type = COMPONENT_TYPE_LOAD, +- .desc = "initial ramdisk" ++ .desc = "initial ramdisk", ++ .set_location = set_location_common + }, + [COMPONENT_ID_ENVBLK] = { + .type = COMPONENT_TYPE_LOAD, + .desc = "environment blk", +- .fs_block_aligned = 1 ++ .fs_block_aligned = 1, ++ .set_location = set_location_common + }, + [COMPONENT_ID_SEGMENT_FILE] = { + .type = COMPONENT_TYPE_EXECUTE, +- .desc = "segment file" ++ .desc = "segment file", ++ .set_location = set_location_noop + } + }; diff --git a/s390utils.spec b/s390utils.spec index 99094b4..75ec1f5 100644 --- a/s390utils.spec +++ b/s390utils.spec @@ -14,7 +14,7 @@ Name: s390utils Summary: Utilities and daemons for IBM z Systems Version: 2.40.0 -Release: 1%{?dist} +Release: 1%{?dist}.2 Epoch: 2 # MIT covers nearly all the files, except init files License: MIT AND LGPL-2.1-or-later @@ -47,7 +47,7 @@ Patch0: s390-tools-zipl-invert-script-options.patch Patch1: s390-tools-zipl-blscfg-rpm-nvr-sort.patch # upstream fixes/updates -#Patch100: s390utils-%%{version}-rhel.patch +Patch100: s390utils-%{version}-rhel.patch # https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval ExcludeArch: %{ix86} @@ -1107,6 +1107,14 @@ User-space development files for the s390/s390x architecture. %changelog +* Wed Aug 12 2026 Andrew Lukoshko - 2:2.40.0-1.2 +- Backport 10 upstream s390-tools fixes: + hsci: automatically set appropriate MTU for HSCI + hyptop/opts: replace sort_field option and fix long option abbreviations + zipl/boot: fix stage3 secure boot trailer placement + zipl/src: fixes for replicated program tables, component location + alignment, verbose output and add_component_file_range() + * Mon Jan 12 2026 Dan Horák - 2:2.40.0-1 - rebased to 2.40.0 (RHEL-100438) - zipl/boot: Fix unused loadparm when SCLP line-mode console is absent (RHEL-71829)