On Mon, 2025-07-21 at 17:26 -0400, Collin Walling wrote: > On 7/11/25 17:10, Zhuoying Cai wrote: > > DIAGNOSE 320 is introduced to support certificate store facility, > > which includes operations such as query certificate storage > > information and provide certificates in the certificate store. > > > > Currently, only subcode 0 is supported with this patch, which is > > used to query a bitmap of which subcodes are supported. > > Change to: "used to query the Installed Subcodes Mask (ISM)." > > Based on my feedback below, make sure to include a statement that this > subcode is only supported when the Certificate Store facility is enabled. > > > > > Signed-off-by: Zhuoying Cai <zy...@linux.ibm.com> > > --- > > include/hw/s390x/ipl/diag320.h | 17 ++++++++++++++ > > target/s390x/diag.c | 41 ++++++++++++++++++++++++++++++++++ > > target/s390x/kvm/kvm.c | 14 ++++++++++++ > > target/s390x/s390x-internal.h | 2 ++ > > target/s390x/tcg/misc_helper.c | 7 ++++++ > > 5 files changed, 81 insertions(+) > > create mode 100644 include/hw/s390x/ipl/diag320.h > > > > diff --git a/include/hw/s390x/ipl/diag320.h b/include/hw/s390x/ipl/diag320.h > > new file mode 100644 > > index 0000000000..713570545d > > --- /dev/null > > +++ b/include/hw/s390x/ipl/diag320.h > > @@ -0,0 +1,17 @@ > > +/* > > + * S/390 DIAGNOSE 320 definitions and structures > > + * > > + * Copyright 2025 IBM Corp. > > + * Author(s): Zhuoying Cai <zy...@linux.ibm.com> > > + * > > + * SPDX-License-Identifier: GPL-2.0-or-later > > + */ > > + > > +#ifndef S390X_DIAG320_H > > +#define S390X_DIAG320_H > > + > > +#define DIAG_320_SUBC_QUERY_ISM 0 > > + > > +#define DIAG_320_RC_OK 0x0001 > > + > > +#endif > > diff --git a/target/s390x/diag.c b/target/s390x/diag.c > > index cff9fbc4b0..d33c5daf38 100644 > > --- a/target/s390x/diag.c > > +++ b/target/s390x/diag.c > > @@ -18,6 +18,7 @@ > > #include "hw/watchdog/wdt_diag288.h" > > #include "system/cpus.h" > > #include "hw/s390x/ipl.h" > > +#include "hw/s390x/ipl/diag320.h" > > #include "hw/s390x/s390-virtio-ccw.h" > > #include "system/kvm.h" > > #include "kvm/kvm_s390x.h" > > @@ -191,3 +192,43 @@ out: > > break; > > } > > } > > + > > +void handle_diag_320(CPUS390XState *env, uint64_t r1, uint64_t r3, > > uintptr_t ra) > > +{ > > + S390CPU *cpu = env_archcpu(env); > > + uint64_t subcode = env->regs[r3]; > > + uint64_t addr = env->regs[r1]; > > + int rc; > > Even though "rc" likely means "response code" in the context of DIAG, it > screams "return code" in a void function, which looks a little odd. I'd > remove this variable and simply set `env->regs[r1 + 1] = DIAG_320_RC_*` > instead, similar to how DIAG 308 handles this. > > > + > > + if (env->psw.mask & PSW_MASK_PSTATE) { > > + s390_program_interrupt(env, PGM_PRIVILEGED, ra); > > + return; > > + } > > + > > + if (!s390_has_feat(S390_FEAT_DIAG_320)) { > > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > > + return; > > + } > > + > > + if (r1 & 1) { > > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > > + return; > > + } > > + > > + switch (subcode) { > > In patch 4, you introduce the feature bit for DIAG 320. It is > documented that subcodes 0-3 are only supported if this feature bit is > on. Please add a check for this feature. Subcode 0 (and later 1 and 2) > should not be handled if this feature bit is not present. > > > + case DIAG_320_SUBC_QUERY_ISM: > > + uint64_t ism = 0; > > Technically, this subcode is suppose to write to an 8-word installed > subcodes block (ISB). Though I can't imagine that we'll grow beyond > even the first word for quite some time. I guess it's up to the caller > to provide a proper ISB anyway. > > I'd suggest the following: > > change from `uint64_t` to `uint32_t ism_word0` > > Add a comment: > > /* > * The Installed Subcode Block (ISB) can be up 8 words in size, > * but the current set of subcodes can fit within a single word > * for now. > */ > > > + > > + if (s390_cpu_virt_mem_write(cpu, addr, r1, &ism, sizeof(ism))) { > > + s390_cpu_virt_mem_handle_exc(cpu, ra); > > + return; > > + } > > + > > + rc = DIAG_320_RC_OK; > > env->regs[r1 + 1] = DIAG_320_RC_OK; > > > + break; > > + default: > > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > > + return; > > As specified in the documentation, "response code 0x0102 indicates that > the subcode is reserved or not supported on this model". There is no > program specification when an incorrect subcode has been provided.
Yes to this, but subcode is limited to one byte so we still need to do a spec exception if r3 is greater than 255 (you can do it before the switch, like is done to r1). > > > + } > > + env->regs[r1 + 1] = rc; > > Remove this line. > > > +} > > diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c > > index 8f655a4b7f..d5b3694600 100644 > > --- a/target/s390x/kvm/kvm.c > > +++ b/target/s390x/kvm/kvm.c > > @@ -98,6 +98,7 @@ > > #define DIAG_TIMEREVENT 0x288 > > #define DIAG_IPL 0x308 > > #define DIAG_SET_CONTROL_PROGRAM_CODES 0x318 > > +#define DIAG_CERT_STORE 0x320 > > #define DIAG_KVM_HYPERCALL 0x500 > > #define DIAG_KVM_BREAKPOINT 0x501 > > > > @@ -1560,6 +1561,16 @@ static void handle_diag_318(S390CPU *cpu, struct > > kvm_run *run) > > } > > } > > > > +static void kvm_handle_diag_320(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_320(&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) > > @@ -1590,6 +1601,9 @@ static int handle_diag(S390CPU *cpu, struct kvm_run > > *run, uint32_t ipb) > > case DIAG_KVM_BREAKPOINT: > > r = handle_sw_breakpoint(cpu, run); > > break; > > + case DIAG_CERT_STORE: > > + kvm_handle_diag_320(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 a4ba6227ab..86a652f833 100644 > > --- a/target/s390x/s390x-internal.h > > +++ b/target/s390x/s390x-internal.h > > @@ -400,6 +400,8 @@ int mmu_translate_real(CPUS390XState *env, target_ulong > > raddr, int rw, > > int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3); > > 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); > > > > > > /* translate.c */ > > diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c > > index f7101be574..412c34ed93 100644 > > --- a/target/s390x/tcg/misc_helper.c > > +++ b/target/s390x/tcg/misc_helper.c > > @@ -142,6 +142,13 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, > > uint32_t r3, uint32_t num) > > /* time bomb (watchdog) */ > > r = handle_diag_288(env, r1, r3); > > break; > > + case 0x320: > > + /* cert store */ > > + bql_lock(); > > + handle_diag_320(env, r1, r3, GETPC()); > > + bql_unlock(); > > + r = 0; > > + break; > > default: > > r = -1; > > break; >