Message ID | 20250408155527.123341-9-zycai@linux.ibm.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Secure IPL Support for SCSI Scheme of virtio-blk/virtio-scsi Devices | expand |
On 08/04/2025 17.55, Zhuoying Cai wrote: > From: Collin Walling <walling@linux.ibm.com> > > In order to support secure IPL (aka secure boot) for the s390-ccw BIOS, > a new s390 DIAGNOSE instruction is introduced to leverage QEMU for > handling operations such as signature verification and certificate > retrieval. > > Currently, only subcode 0 is supported with this patch, which is used to > query a bitmap of which subcodes are supported. > > Signed-off-by: Collin Walling <walling@linux.ibm.com> > --- > hw/s390x/ipl.h | 1 + > include/hw/s390x/ipl/diag508.h | 17 +++++++++++++++++ > target/s390x/diag.c | 26 ++++++++++++++++++++++++++ > target/s390x/kvm/kvm.c | 14 ++++++++++++++ > target/s390x/s390x-internal.h | 2 ++ > 5 files changed, 60 insertions(+) > create mode 100644 include/hw/s390x/ipl/diag508.h > > diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h > index 822535ad76..e9ef8ddccd 100644 > --- a/hw/s390x/ipl.h > +++ b/hw/s390x/ipl.h > @@ -18,6 +18,7 @@ > #include "exec/address-spaces.h" > #include "hw/qdev-core.h" > #include "hw/s390x/ipl/diag320.h" > +#include "hw/s390x/ipl/diag508.h" > #include "hw/s390x/ipl/qipl.h" > #include "qom/object.h" > > diff --git a/include/hw/s390x/ipl/diag508.h b/include/hw/s390x/ipl/diag508.h > new file mode 100644 > index 0000000000..83c4439cb2 > --- /dev/null > +++ b/include/hw/s390x/ipl/diag508.h > @@ -0,0 +1,17 @@ > +/* > + * S/390 DIAGNOSE 508 definitions and structures > + * > + * Copyright 2025 IBM Corp. > + * Author(s): Collin Walling <walling@linux.ibm.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or (at > + * your option) any later version. See the COPYING file in the top-level > + * directory. > + */ > + > +#ifndef S390X_DIAG508_H > +#define S390X_DIAG508_H > + > +#define DIAG_508_SUBC_QUERY_SUBC 0x0000 > + > +#endif > diff --git a/target/s390x/diag.c b/target/s390x/diag.c > index 82e4dc9e1e..ad7f4b5025 100644 > --- a/target/s390x/diag.c > +++ b/target/s390x/diag.c > @@ -488,3 +488,29 @@ void handle_diag_320(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) > } > env->regs[r1 + 1] = rc; > } > + > +void handle_diag_508(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) > +{ > + uint64_t subcode = env->regs[r3]; > + int rc; Do we need to check some feature bit here? e.g. check s390_has_feat(S390_FEAT_DIAG_320) here, too? > + if (env->psw.mask & PSW_MASK_PSTATE) { > + s390_program_interrupt(env, PGM_PRIVILEGED, ra); > + return; > + } > + > + if ((subcode & ~0x0ffffULL) || (r1 & 1)) { > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > + return; > + } > + > + switch (subcode) { > + case DIAG_508_SUBC_QUERY_SUBC: > + rc = 0; > + break; > + default: > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > + return; > + } > + env->regs[r1 + 1] = rc; > +} Thomas
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index 822535ad76..e9ef8ddccd 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -18,6 +18,7 @@ #include "exec/address-spaces.h" #include "hw/qdev-core.h" #include "hw/s390x/ipl/diag320.h" +#include "hw/s390x/ipl/diag508.h" #include "hw/s390x/ipl/qipl.h" #include "qom/object.h" diff --git a/include/hw/s390x/ipl/diag508.h b/include/hw/s390x/ipl/diag508.h new file mode 100644 index 0000000000..83c4439cb2 --- /dev/null +++ b/include/hw/s390x/ipl/diag508.h @@ -0,0 +1,17 @@ +/* + * S/390 DIAGNOSE 508 definitions and structures + * + * Copyright 2025 IBM Corp. + * Author(s): Collin Walling <walling@linux.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#ifndef S390X_DIAG508_H +#define S390X_DIAG508_H + +#define DIAG_508_SUBC_QUERY_SUBC 0x0000 + +#endif diff --git a/target/s390x/diag.c b/target/s390x/diag.c index 82e4dc9e1e..ad7f4b5025 100644 --- a/target/s390x/diag.c +++ b/target/s390x/diag.c @@ -488,3 +488,29 @@ void handle_diag_320(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) } env->regs[r1 + 1] = rc; } + +void handle_diag_508(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) +{ + uint64_t subcode = env->regs[r3]; + int rc; + + if (env->psw.mask & PSW_MASK_PSTATE) { + s390_program_interrupt(env, PGM_PRIVILEGED, ra); + return; + } + + if ((subcode & ~0x0ffffULL) || (r1 & 1)) { + s390_program_interrupt(env, PGM_SPECIFICATION, ra); + return; + } + + switch (subcode) { + case DIAG_508_SUBC_QUERY_SUBC: + rc = 0; + break; + default: + s390_program_interrupt(env, PGM_SPECIFICATION, ra); + return; + } + env->regs[r1 + 1] = rc; +} diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index b013751478..a5c5150c04 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -101,6 +101,7 @@ #define DIAG_CERT_STORE 0x320 #define DIAG_KVM_HYPERCALL 0x500 #define DIAG_KVM_BREAKPOINT 0x501 +#define DIAG_SECURE_IPL 0x508 #define ICPT_INSTRUCTION 0x04 #define ICPT_PROGRAM 0x08 @@ -1572,6 +1573,16 @@ static void kvm_handle_diag_320(S390CPU *cpu, struct kvm_run *run) handle_diag_320(&cpu->env, r1, r3, RA_IGNORED); } +static void kvm_handle_diag_508(S390CPU *cpu, struct kvm_run *run) +{ + uint64_t r1, r3; + + r1 = (run->s390_sieic.ipa & 0x00f0) >> 4; + r3 = run->s390_sieic.ipa & 0x000f; + + handle_diag_508(&cpu->env, r1, r3, RA_IGNORED); +} + #define DIAG_KVM_CODE_MASK 0x000000000000ffff static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb) @@ -1605,6 +1616,9 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb) case DIAG_CERT_STORE: kvm_handle_diag_320(cpu, run); break; + case DIAG_SECURE_IPL: + kvm_handle_diag_508(cpu, run); + break; default: trace_kvm_insn_diag(func_code); kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION); diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h index 86a652f833..df0973266a 100644 --- a/target/s390x/s390x-internal.h +++ b/target/s390x/s390x-internal.h @@ -402,6 +402,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra); void handle_diag_320(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra); +void handle_diag_508(CPUS390XState *env, uint64_t r1, uint64_t r3, + uintptr_t ra); /* translate.c */