pc-bios/s390-ccw: Define memory for IPLB and convert IPLB to pointers
Define a memory space for both IPL Parameter Block (IPLB) and IPL Information Report Block (IIRB) since IIRB is stored immediately following IPLB. Convert IPLB to pointer and it points to the start of the defined memory space. IIRB points to the end of IPLB. Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Farhan Ali <alifm@linux.ibm.com> Reviewed-by: Jared Rossi <jrossi@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260730214624.2328883-17-zycai@linux.ibm.com Signed-off-by: Eric Farman <farman@linux.ibm.com>
Zhuoying Cai committed
Jul 30, 2026 at 17:46 UTC
3c057b938673cf5d5dbd82d450d1e0c7a81587c5
5 files changed
+35
-24
include/hw/s390x/ipl/qipl.h
+6
@@ -210,4 +210,10 @@ struct IplInfoReportBlock {
210
};
211
typedef struct IplInfoReportBlock IplInfoReportBlock;
212
213
+struct IplBlocks {
214
+ IplParameterBlock iplb;
215
+ IplInfoReportBlock iirb;
216
+};
217
+typedef struct IplBlocks IplBlocks;
218
+
219
#endif
pc-bios/s390-ccw/iplb.h
+3
-2
@@ -20,8 +20,9 @@
20
#include <string.h>
21
22
extern QemuIplParameters qipl;
23
-extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
23
+extern IplParameterBlock *iplb;
24
extern bool have_iplb;
25
+extern IplBlocks ipl_blocks;
26
27
static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
28
{
@@ -61,7 +62,7 @@ static inline bool load_next_iplb(void)
62
63
qipl.index++;
64
next_iplb = (IplParameterBlock *) qipl.next_iplb;
64
- memcpy(&iplb, next_iplb, sizeof(IplParameterBlock));
65
+ memcpy(iplb, next_iplb, sizeof(IplParameterBlock));
66
67
qipl.chain_len--;
68
qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock);
pc-bios/s390-ccw/jump2ipl.c
+3
-3
@@ -43,11 +43,11 @@ int jump_to_IPL_code(uint64_t address)
43
* The IPLB for QEMU SCSI type devices must be rebuilt during re-ipl. The
44
* iplb.devno is set to the boot position of the target SCSI device.
45
*/
46
- if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
47
- iplb.devno = qipl.index;
46
+ if (iplb->pbt == S390_IPL_TYPE_QEMU_SCSI) {
47
+ iplb->devno = qipl.index;
48
}
49
50
- if (have_iplb && !set_iplb(&iplb)) {
50
+ if (have_iplb && !set_iplb(iplb)) {
51
panic("Failed to set IPLB");
52
}
53
pc-bios/s390-ccw/main.c
+19
-15
@@ -24,7 +24,9 @@
24
static SubChannelId blk_schid = { .one = 1 };
25
static char loadparm_str[LOADPARM_LEN + 1];
26
QemuIplParameters qipl;
27
-IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
27
+/* Ensure that IPLB and IIRB are page aligned and sequential in memory */
28
+IplBlocks ipl_blocks __attribute__((__aligned__(PAGE_SIZE)));
29
+IplParameterBlock *iplb;
30
bool have_iplb;
31
static uint16_t cutype;
32
LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
@@ -54,7 +56,7 @@ void write_iplb_location(void)
56
{
57
if (virtio_is_supported(virtio_get_device()) &&
58
virtio_get_device_type() != VIRTIO_ID_NET) {
57
- lowcore->ptr_iplb = ptr2u32(&iplb);
59
+ lowcore->ptr_iplb = ptr2u32(iplb);
60
}
61
}
62
@@ -216,14 +218,14 @@ static void boot_setup(void)
218
char lpmsg[] = "LOADPARM=[________]\n";
219
VDev *vdev = virtio_get_device();
220
219
- if (have_iplb && memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) {
220
- ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN);
221
+ if (have_iplb && memcmp(iplb->loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) {
222
+ ebcdic_to_ascii((char *) iplb->loadparm, loadparm_str, LOADPARM_LEN);
223
} else {
224
sclp_get_loadparm_ascii(loadparm_str);
225
}
226
227
if (have_iplb) {
226
- vdev->ipl_type = iplb.pbt;
228
+ vdev->ipl_type = iplb->pbt;
229
menu_setup(vdev);
230
} else {
231
vdev->ipl_type = QEMU_DEFAULT_IPL;
@@ -247,21 +249,21 @@ static bool find_boot_device(void)
249
switch (vdev->ipl_type) {
250
case S390_IPL_TYPE_CCW:
251
vdev->scsi_device_selected = false;
250
- debug_print_int("device no. ", iplb.ccw.devno);
251
- blk_schid.ssid = iplb.ccw.ssid & 0x3;
252
+ debug_print_int("device no. ", iplb->ccw.devno);
253
+ blk_schid.ssid = iplb->ccw.ssid & 0x3;
254
debug_print_int("ssid ", blk_schid.ssid);
253
- found = find_subch(iplb.ccw.devno);
255
+ found = find_subch(iplb->ccw.devno);
256
break;
257
case S390_IPL_TYPE_QEMU_SCSI:
258
vdev->scsi_device_selected = true;
257
- vdev->selected_scsi_device.channel = iplb.scsi.channel;
258
- vdev->selected_scsi_device.target = iplb.scsi.target;
259
- vdev->selected_scsi_device.lun = iplb.scsi.lun;
260
- blk_schid.ssid = iplb.scsi.ssid & 0x3;
261
- found = find_subch(iplb.scsi.devno);
259
+ vdev->selected_scsi_device.channel = iplb->scsi.channel;
260
+ vdev->selected_scsi_device.target = iplb->scsi.target;
261
+ vdev->selected_scsi_device.lun = iplb->scsi.lun;
262
+ blk_schid.ssid = iplb->scsi.ssid & 0x3;
263
+ found = find_subch(iplb->scsi.devno);
264
break;
265
case S390_IPL_TYPE_PCI:
264
- found = find_fid(iplb.pci.fid);
266
+ found = find_fid(iplb->pci.fid);
267
break;
268
default:
269
puts("Unsupported IPLB");
@@ -380,10 +382,12 @@ static void probe_boot_device(void)
382
383
void main(void)
384
{
385
+ iplb = &ipl_blocks.iplb;
386
+
387
copy_qipl();
388
sclp_setup();
389
css_setup();
386
- have_iplb = store_iplb(&iplb);
390
+ have_iplb = store_iplb(iplb);
391
if (!have_iplb) {
392
boot_setup();
393
probe_boot_device();
pc-bios/s390-ccw/netmain.c
+4
-4
@@ -531,11 +531,11 @@ static bool virtio_setup(void)
531
*/
532
enable_mss_facility();
533
534
- if (have_iplb || store_iplb(&iplb)) {
535
- IPL_assert(iplb.pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected");
536
- dev_no = iplb.ccw.devno;
534
+ if (have_iplb || store_iplb(iplb)) {
535
+ IPL_assert(iplb->pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected");
536
+ dev_no = iplb->ccw.devno;
537
debug_print_int("device no. ", dev_no);
538
- net_schid.ssid = iplb.ccw.ssid & 0x3;
538
+ net_schid.ssid = iplb->ccw.ssid & 0x3;
539
debug_print_int("ssid ", net_schid.ssid);
540
found = find_net_dev(&schib, dev_no);
541
} else {