Add ZiplBootMode enumeration to support multiple IPL boot configurations.
Boot modes differentiate between normal boot and secure IPL operations,
enabled based on boot certificates specified via the boot-certs option.
Normal Mode: IPL when no certificates are provided. No signature
verification is performed.
This prepares for future secure IPL modes requiring signature
verification.
Signed-off-by: Zhuoying Cai <[email protected]>
Reviewed-by: Collin Walling <[email protected]>
---
docs/system/s390x/secure-ipl.rst | 21 +++++++++++++++++++++
pc-bios/s390-ccw/bootmap.c | 16 +++++++++++++++-
pc-bios/s390-ccw/main.c | 6 ++++++
pc-bios/s390-ccw/s390-ccw.h | 6 ++++++
4 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/docs/system/s390x/secure-ipl.rst b/docs/system/s390x/secure-ipl.rst
index 88df52ce2f..9d7d33f5ed 100644
--- a/docs/system/s390x/secure-ipl.rst
+++ b/docs/system/s390x/secure-ipl.rst
@@ -18,3 +18,24 @@ Note: certificate files must have a .pem extension.
.. code-block:: shell
qemu-system-s390x -machine s390-ccw-virtio,boot-certs.0.path=/.../qemu/certs,boot-certs.1.path=/another/path/cert.pem ...
+
+
+IPL Modes
+---------
+
+Multiple IPL modes are available to differentiate between the various IPL
+configurations. These modes are mutually exclusive and enabled based on the
+``boot-certs`` option on the QEMU command line.
+
+Normal Mode
+^^^^^^^^^^^
+
+The absence of certificates will attempt to IPL a guest without secure IPL
+operations. No checks are performed, and no warnings/errors are reported.
+This is the default mode.
+
+Configuration:
+
+.. code-block:: shell
+
+ qemu-system-s390x -machine s390-ccw-virtio ...
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index b19981feb1..667a69f80d 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -733,7 +733,14 @@ static int zipl_run(ScsiBlockPtr *pte)
/* Load image(s) into RAM */
entry = (ComponentEntry *)(&header[1]);
- rc = zipl_run_normal(&entry, tmp_sec);
+ switch (boot_mode) {
+ case ZIPL_BOOT_MODE_NORMAL:
+ rc = zipl_run_normal(&entry, tmp_sec);
+ break;
+ default:
+ panic("Unknown boot mode");
+ }
+
if (rc) {
return rc;
}
@@ -1105,12 +1112,16 @@ void zipl_load(void)
VDev *vdev = virtio_get_device();
if (vdev->is_cdrom) {
+ IPL_assert((boot_mode == ZIPL_BOOT_MODE_NORMAL),
+ "Secure boot from ISO image is not supported!");
ipl_iso_el_torito();
puts("Failed to IPL this ISO image!");
return;
}
if (virtio_get_device_type() == VIRTIO_ID_NET) {
+ IPL_assert((boot_mode == ZIPL_BOOT_MODE_NORMAL),
+ "Virtio net boot device does not support secure boot!");
netmain();
puts("Failed to IPL from this network!");
return;
@@ -1121,6 +1132,9 @@ void zipl_load(void)
return;
}
+ IPL_assert((boot_mode == ZIPL_BOOT_MODE_NORMAL),
+ "Secure boot with the ECKD scheme is not supported!");
+
switch (virtio_get_device_type()) {
case VIRTIO_ID_BLOCK:
zipl_load_vblk();
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index b8f836c682..cd3d0776b0 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -30,6 +30,7 @@ IplParameterBlock *iplb;
bool have_iplb;
static uint16_t cutype;
LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
+ZiplBootMode boot_mode;
#define LOADPARM_PROMPT "PROMPT "
#define LOADPARM_EMPTY " "
@@ -303,6 +304,9 @@ static void ipl_ccw_device(void)
switch (cutype) {
case CU_TYPE_DASD_3990:
case CU_TYPE_DASD_2107:
+ IPL_assert((boot_mode == ZIPL_BOOT_MODE_NORMAL),
+ "Passthrough (vfio) CCW device does not support secure
boot!");
+
dasd_ipl(blk_schid, cutype);
break;
case CU_TYPE_VIRTIO:
@@ -390,6 +394,8 @@ void main(void)
probe_boot_device();
}
+ boot_mode = ZIPL_BOOT_MODE_NORMAL;
+
while (have_iplb) {
boot_setup();
if (have_iplb && find_boot_device()) {
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 1e1f71775e..5420443ad2 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -69,6 +69,12 @@ int sclp_read(char *str, size_t count);
/* bootmap.c */
void zipl_load(void);
+typedef enum ZiplBootMode {
+ ZIPL_BOOT_MODE_NORMAL = 0,
+} ZiplBootMode;
+
+extern ZiplBootMode boot_mode;
+
/* jump2ipl.c */
void write_reset_psw(uint64_t psw);
int jump_to_IPL_code(uint64_t address);