Add boot-certs to s390-ccw-virtio machine type option
Introduce a new `boot-certs` machine type option for the s390-ccw-virtio machine. This allows users to specify one or more certificate file paths or directories to be used during secure boot. Each entry is specified using the syntax: boot-certs.<index>.path=/path/to/cert.pem Multiple paths can be specify using array properties: boot-certs.0.path=/path/to/cert.pem, boot-certs.1.path=/path/to/cert-dir, boot-certs.2.path=/path/to/another-dir... Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com> Acked-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260730214624.2328883-2-zycai@linux.ibm.com Signed-off-by: Eric Farman <farman@linux.ibm.com>
Zhuoying Cai committed
Jul 30, 2026 at 17:45 UTC
21efab616eb1409848b25ad308cd6a5d502ec108
7 files changed
+94
-1
docs/system/s390x/secure-ipl.rst
new
+20
@@ -0,0 +1,20 @@
1
+.. SPDX-License-Identifier: GPL-2.0-or-later
2
+
3
+Secure IPL Command Line Options
4
+-------------------------------
5
+
6
+The s390-ccw-virtio machine type supports secure IPL. These parameters allow
7
+users to provide certificates and enable secure IPL directly via the command
8
+line.
9
+
10
+Providing Certificates
11
+^^^^^^^^^^^^^^^^^^^^^^
12
+
13
+The certificate store can be populated by supplying a list of X.509 certificate
14
+file paths or directories containing certificate files on the command-line:
15
+
16
+Note: certificate files must have a .pem extension.
17
+
18
+.. code-block:: shell
19
+
20
+ qemu-system-s390x -machine s390-ccw-virtio,boot-certs.0.path=/.../qemu/certs,boot-certs.1.path=/another/path/cert.pem ...
docs/system/target-s390x.rst
+1
@@ -35,3 +35,4 @@ Architectural features
35
s390x/bootdevices
36
s390x/protvirt
37
s390x/cpu-topology
38
+ s390x/secure-ipl
hw/s390x/s390-virtio-ccw.c
+41
@@ -44,6 +44,7 @@
44
#include "target/s390x/kvm/pv.h"
45
#include "migration/blocker.h"
46
#include "qapi/visitor.h"
47
+#include "qapi/qapi-visit-machine-s390x.h"
48
#include "hw/s390x/cpu-topology.h"
49
#include "kvm/kvm_s390x.h"
50
#include "hw/virtio/virtio-md-pci.h"
@@ -786,6 +787,36 @@ static void machine_set_loadparm(Object *obj, Visitor *v,
787
g_free(val);
788
}
789
790
+static void machine_get_boot_certs(Object *obj, Visitor *v,
791
+ const char *name, void *opaque,
792
+ Error **errp)
793
+{
794
+ S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
795
+ BootCertificatesList **certs = &ms->boot_certs;
796
+
797
+ visit_type_BootCertificatesList(v, name, certs, errp);
798
+}
799
+
800
+static void machine_set_boot_certs(Object *obj, Visitor *v, const char *name,
801
+ void *opaque, Error **errp)
802
+{
803
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_GET_CLASS(obj);
804
+ S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
805
+ BootCertificatesList *cert_list = NULL;
806
+
807
+ if (!s390mc->use_certs) {
808
+ error_setg(errp, "boot-certs is not supported by this machine version");
809
+ return;
810
+ }
811
+
812
+ visit_type_BootCertificatesList(v, name, &cert_list, errp);
813
+ if (!cert_list) {
814
+ return;
815
+ }
816
+
817
+ ms->boot_certs = cert_list;
818
+}
819
+
820
/*
821
* S390x-specific global compatibility properties.
822
*
@@ -811,6 +842,7 @@ static void ccw_machine_class_init(ObjectClass *oc, const void *data)
842
843
s390mc->max_threads = 1;
844
s390mc->use_cpi = true;
845
+ s390mc->use_certs = true;
846
mc->reset = s390_machine_reset;
847
mc->block_default_type = IF_VIRTIO;
848
mc->no_cdrom = 1;
@@ -854,6 +886,11 @@ static void ccw_machine_class_init(ObjectClass *oc, const void *data)
886
"Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted"
887
" to upper case) to pass to machine loader, boot manager,"
888
" and guest kernel");
889
+
890
+ object_class_property_add(oc, "boot-certs", "BootCertificatesList",
891
+ machine_get_boot_certs, machine_set_boot_certs, NULL, NULL);
892
+ object_class_property_set_description(oc, "boot-certs",
893
+ "provide paths to a directory and/or a certificate file for secure boot");
894
}
895
896
static inline void s390_machine_initfn(Object *obj)
@@ -939,6 +976,10 @@ static void ccw_machine_11_1_instance_options(MachineState *machine)
976
977
static void ccw_machine_11_1_class_options(MachineClass *mc)
978
{
979
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
980
+
981
+ s390mc->use_certs = false;
982
+
983
ccw_machine_11_2_class_options(mc);
984
compat_props_add(mc->compat_props, hw_compat_11_1, hw_compat_11_1_len);
985
}
include/hw/s390x/s390-virtio-ccw.h
+3
@@ -14,6 +14,7 @@
14
#include "hw/core/boards.h"
15
#include "qom/object.h"
16
#include "hw/s390x/sclp.h"
17
+#include "qapi/qapi-types-machine-s390x.h"
18
19
#define TYPE_S390_CCW_MACHINE "s390-ccw-machine"
20
@@ -31,6 +32,7 @@ struct S390CcwMachineState {
32
uint8_t loadparm[8];
33
uint64_t memory_limit;
34
uint64_t max_pagesize;
35
+ BootCertificatesList *boot_certs;
36
37
SCLPDevice *sclp;
38
};
@@ -55,6 +57,7 @@ struct S390CcwMachineClass {
57
/*< public >*/
58
int max_threads;
59
bool use_cpi;
60
+ bool use_certs;
61
};
62
63
#endif
qapi/machine-s390x.json
+23
@@ -140,3 +140,26 @@
140
{ 'event': 'SCLP_CPI_INFO_AVAILABLE',
141
'features': [ 'unstable' ]
142
}
143
+
144
+##
145
+# @BootCertificates:
146
+#
147
+# Boot certificates for secure IPL.
148
+#
149
+# @path: path to an X.509 certificate file or a directory containing
150
+# certificate files.
151
+#
152
+# Since: 11.2
153
+##
154
+{ 'struct': 'BootCertificates',
155
+ 'data': {'path': 'str'} }
156
+
157
+##
158
+# @DummyBootCertificates:
159
+#
160
+# Not used by QMP; hack to let us use BootCertificatesList internally.
161
+#
162
+# Since: 11.2
163
+##
164
+{ 'struct': 'DummyBootCertificates',
165
+ 'data': {'unused-boot-certs': ['BootCertificates'] } }
qapi/pragma.json
+1
@@ -49,6 +49,7 @@
49
'DisplayProtocol',
50
'DriveBackupWrapper',
51
'DummyBlockCoreForceArrays',
52
+ 'DummyBootCertificates',
53
'DummyForceArrays',
54
'DummyVirtioForceArrays',
55
'HotKeyMod',
qemu-options.hx
+5
-1
@@ -46,7 +46,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
46
" memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)\n"
47
" cxl-fmw.0.targets.0=firsttarget,cxl-fmw.0.targets.1=secondtarget,cxl-fmw.0.size=size[,cxl-fmw.0.interleave-granularity=granularity]\n"
48
" sgx-epc.0.memdev=memid,sgx-epc.0.node=numaid\n"
49
- " smp-cache.0.cache=cachename,smp-cache.0.topology=topologylevel\n",
49
+ " smp-cache.0.cache=cachename,smp-cache.0.topology=topologylevel\n"
50
+ " boot-certs.0.path=/path/directory,boot-certs.1.path=/path/file provides paths to a directory and/or a certificate file\n",
51
QEMU_ARCH_ALL)
52
SRST
53
``-machine [type=]name[,prop=value[,...]]``
@@ -214,6 +215,9 @@ SRST
215
::
216
217
-machine smp-cache.0.cache=l1d,smp-cache.0.topology=core,smp-cache.1.cache=l1i,smp-cache.1.topology=core
218
+
219
+ ``boot-certs.0.path=/path/directory,boot-certs.1.path=/path/file``
220
+ Provide paths to a directory and/or a certificate file on the host [s390x only].
221
ERST
222
223
DEF("M", HAS_ARG, QEMU_OPTION_M,