@samitouri / QOSamiQemu / commits / c76ae1a31d

s390x: Guest support for Secure-IPL Code Loading Attributes Facility (SCLAF)

The secure-IPL-code-loading-attributes facility (SCLAF) provides additional security during secure IPL. Availability of SCLAF is determined by byte 136 bit 3 of the SCLP Read SCP Info. This feature is available starting with the gen16 CPU model. Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com> Reviewed-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260730214624.2328883-26-zycai@linux.ibm.com Signed-off-by: Eric Farman <farman@linux.ibm.com>

Zhuoying Cai committed Jul 30, 2026 at 17:46 UTC c76ae1a31d8d5afa0dcd3fbee6c09d8144dc0729
6 files changed +27
docs/specs/s390x-secure-ipl.rst
+18
@@ -122,3 +122,21 @@ The guest kernel uses the contents in the IIRB for:
122 * Boot logging: reports which components were loaded and verified.
123 * kexec operations: builds the next kernel’s IPL report from the existing one.
124 * Keying: installs IPL certificates into the platform trusted keyring.
125 +
126 +Secure Code Loading Attributes Facility
127 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
128 +
129 +The Secure Code Loading Attributes Facility (SCLAF) enhances system security
130 +during the IPL by enforcing additional verification rules.
131 +
132 +When SCLAF is available, its behavior depends on the IPL mode. It introduces
133 +verification of both signed and unsigned components to help ensure that only
134 +authorized code is loaded during the IPL process. Any errors detected by SCLAF
135 +are reported in the IIRB.
136 +
137 +Unsigned components are restricted to load addresses at or above absolute
138 +storage address ``0x2000``.
139 +
140 +Signed components must include a Secure Code Loading Attribute Block (SCLAB),
141 +which is appended at the very end of the component. The SCLAB defines security
142 +attributes for handling the signed code.
target/s390x/cpu_features.c
+2
@@ -120,6 +120,7 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
120 * - All SIE facilities because SIE is not available
121 * - DIAG318
122 * - Secure IPL Facility
123 + * - Secure IPL Code Loading Attributes Facility
124 *
125 * As VMs can move in and out of protected mode the CPU model
126 * doesn't protect us from that problem because it is only
@@ -152,6 +153,7 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
153 break;
154 case S390_FEAT_TYPE_SCLP_FAC_IPL:
155 clear_be_bit(s390_feat_def(S390_FEAT_SIPL)->bit, data);
156 + clear_be_bit(s390_feat_def(S390_FEAT_SCLAF)->bit, data);
157 break;
158 case S390_FEAT_TYPE_SCLP_FAC139:
159 clear_be_bit(s390_feat_def(S390_FEAT_SIE_ASTFLEIE2)->bit, data);
target/s390x/cpu_features_def.h.inc
+1
@@ -142,6 +142,7 @@ DEF_FEAT(CERT_STORE, "cstore", SCLP_FAC134, 5, "Certificate Store functions")
142
143 /* Features exposed via SCLP SCCB Facilities byte 136 - 137 (bit numbers relative to byte-136) */
144 DEF_FEAT(SIPL, "sipl", SCLP_FAC_IPL, 1, "Secure-IPL facility")
145 +DEF_FEAT(SCLAF, "sclaf", SCLP_FAC_IPL, 3, "Secure-IPL-code-loading-attributes facility")
146
147 /* Features exposed via SCLP SCCB Facilities byte 139 (bit numbers relative to byte-139) */
148 DEF_FEAT(SIE_ASTFLEIE2, "astfleie2", SCLP_FAC139, 1, "SIE: ASTFLE interpretation execution facility 2")
target/s390x/cpu_models.c
+3
@@ -264,6 +264,7 @@ bool s390_has_feat(S390Feat feat)
264 case S390_FEAT_SIE_PFMFI:
265 case S390_FEAT_SIE_IBS:
266 case S390_FEAT_SIPL:
267 + case S390_FEAT_SCLAF:
268 case S390_FEAT_CONFIGURATION_TOPOLOGY:
269 case S390_FEAT_SIE_ASTFLEIE2:
270 return false;
@@ -510,6 +511,8 @@ static void check_consistency(const S390CPUModel *model)
511 { S390_FEAT_DIAG_318, S390_FEAT_EXTENDED_LENGTH_SCCB },
512 { S390_FEAT_CERT_STORE, S390_FEAT_EXTENDED_LENGTH_SCCB },
513 { S390_FEAT_SIPL, S390_FEAT_EXTENDED_LENGTH_SCCB },
514 + { S390_FEAT_SCLAF, S390_FEAT_EXTENDED_LENGTH_SCCB },
515 + { S390_FEAT_SCLAF, S390_FEAT_SIPL },
516 { S390_FEAT_NNPA, S390_FEAT_VECTOR },
517 { S390_FEAT_RDP, S390_FEAT_LOCAL_TLB_CLEARING },
518 { S390_FEAT_UV_FEAT_AP, S390_FEAT_AP },
target/s390x/gen-features.c
+2
@@ -723,6 +723,7 @@ static uint16_t full_GEN16_GA1[] = {
723 S390_FEAT_SIE_ASTFLEIE2,
724 S390_FEAT_CERT_STORE,
725 S390_FEAT_SIPL,
726 + S390_FEAT_SCLAF,
727 };
728
729 static uint16_t full_GEN17_GA1[] = {
@@ -925,6 +926,7 @@ static uint16_t qemu_MAX[] = {
926 S390_FEAT_EXTENDED_LENGTH_SCCB,
927 S390_FEAT_CERT_STORE,
928 S390_FEAT_SIPL,
929 + S390_FEAT_SCLAF,
930 };
931
932 /****** END FEATURE DEFS ******/
target/s390x/kvm/kvm.c
+1
@@ -2504,6 +2504,7 @@ bool kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
2504
2505 /* Some Secure IPL facilities are emulated by QEMU */
2506 set_bit(S390_FEAT_SIPL, model->features);
2507 + set_bit(S390_FEAT_SCLAF, model->features);
2508
2509 /* Test for Ultravisor features that influence secure guest behavior */
2510 query_uv_feat_guest(model->features);