v2 -> v3: * pick up Ack (thanks Andrew) * minor cosmetic change to rand generator * add sie_is_pv function * extend sie_is_diag_icpt to support pv, replace pv_icptdata_check_diag Add a test case that tests the interpretation of STFLE performed by a nested guest using a snippet. Also add some functionality to lib/, namely: * pseudo random number generation (arch independent) * exit (optionally with return code) from snippet (s390x) * add function for checking diag intercepts, replacing pv_icptdata_check_diag (s390x) v1 -> v2: * implement SHA-256 based PRNG * pick up R-b (thanks Claudio) * change snippet exit API and implementation (thanks Claudio) * add stfle-sie to unittests.cfg Nina Schoetterl-Glausch (7): lib: Add pseudo random functions s390x: lib: Remove double include s390x: Add sie_is_pv s390x: Add function for checking diagnose intercepts s390x: Add library functions for exiting from snippet s390x: Use library functions for snippet exit s390x: Add test for STFLE interpretive execution (format-0) Makefile | 1 + s390x/Makefile | 3 + lib/s390x/asm/arch_def.h | 13 ++ lib/s390x/asm/facility.h | 10 +- lib/rand.h | 21 +++ lib/s390x/pv_icptdata.h | 42 ------ lib/s390x/sie.h | 18 +++ lib/s390x/snippet-guest.h | 26 ++++ lib/s390x/{snippet.h => snippet-host.h} | 10 +- lib/rand.c | 177 ++++++++++++++++++++++++ lib/s390x/sie.c | 58 +++++++- lib/s390x/snippet-host.c | 42 ++++++ lib/s390x/uv.c | 2 +- s390x/mvpg-sie.c | 2 +- s390x/pv-diags.c | 10 +- s390x/pv-icptcode.c | 13 +- s390x/pv-ipl.c | 9 +- s390x/sie-dat.c | 13 +- s390x/snippets/c/sie-dat.c | 19 +-- s390x/snippets/c/stfle.c | 26 ++++ s390x/spec_ex-sie.c | 2 +- s390x/stfle-sie.c | 134 ++++++++++++++++++ s390x/uv-host.c | 2 +- s390x/unittests.cfg | 3 + 24 files changed, 558 insertions(+), 98 deletions(-) create mode 100644 lib/rand.h delete mode 100644 lib/s390x/pv_icptdata.h create mode 100644 lib/s390x/snippet-guest.h rename lib/s390x/{snippet.h => snippet-host.h} (92%) create mode 100644 lib/rand.c create mode 100644 lib/s390x/snippet-host.c create mode 100644 s390x/snippets/c/stfle.c create mode 100644 s390x/stfle-sie.c Range-diff against v2: 1: 6c869961 ! 1: baecabf2 lib: Add pseudo random functions @@ Commit message for i in range(8): yield int.from_bytes(state[i*4:(i+1)*4], byteorder="big") + Acked-by: Andrew Jones <andrew.jones@xxxxxxxxx> Signed-off-by: Nina Schoetterl-Glausch <nsg@xxxxxxxxxxxxx> @@ lib/rand.c (new) + return rot(x, 17) ^ rot(x, 19) ^ (x >> 10); +} + -+enum alphabet { a, b, c, d, e, f, g, h, }; ++enum alphabet { A, B, C, D, E, F, G, H, }; + +static void sha256_chunk(const uint32_t (*chunk)[16], uint32_t (*hash)[8]) +{ @@ lib/rand.c (new) + for (int i = 0; i < 64; i++) { + uint32_t t1, t2; + -+ t1 = w_hash[h] + -+ upper_sig1(w_hash[e]) + -+ ch(w_hash[e], w_hash[f], w_hash[g]) + ++ t1 = w_hash[H] + ++ upper_sig1(w_hash[E]) + ++ ch(w_hash[E], w_hash[F], w_hash[G]) + + K[i] + + w[i]; + -+ t2 = upper_sig0(w_hash[a]) + maj(w_hash[a], w_hash[b], w_hash[c]); ++ t2 = upper_sig0(w_hash[A]) + maj(w_hash[A], w_hash[B], w_hash[C]); + -+ w_hash[h] = w_hash[g]; -+ w_hash[g] = w_hash[f]; -+ w_hash[f] = w_hash[e]; -+ w_hash[e] = w_hash[d] + t1; -+ w_hash[d] = w_hash[c]; -+ w_hash[c] = w_hash[b]; -+ w_hash[b] = w_hash[a]; -+ w_hash[a] = t1 + t2; ++ w_hash[H] = w_hash[G]; ++ w_hash[G] = w_hash[F]; ++ w_hash[F] = w_hash[E]; ++ w_hash[E] = w_hash[D] + t1; ++ w_hash[D] = w_hash[C]; ++ w_hash[C] = w_hash[B]; ++ w_hash[B] = w_hash[A]; ++ w_hash[A] = t1 + t2; + } + + for (int i = 0; i < 8; i++) 2: 77319d3e = 2: b30314eb s390x: lib: Remove double include -: -------- > 3: f2af539b s390x: Add sie_is_pv -: -------- > 4: c4331d19 s390x: Add function for checking diagnose intercepts 3: e2c2cad8 ! 5: a3f92777 s390x: Add library functions for exiting from snippet @@ lib/s390x/asm/arch_def.h: static inline uint32_t get_prefix(void) + #endif - ## lib/s390x/sie.h ## -@@ lib/s390x/sie.h: void sie_expect_validity(struct vm *vm); - uint16_t sie_get_validity(struct vm *vm); - void sie_check_validity(struct vm *vm, uint16_t vir_exp); - void sie_handle_validity(struct vm *vm); -+bool sie_is_diag_icpt(struct vm *vm, unsigned int diag); - void sie_guest_sca_create(struct vm *vm); - void sie_guest_create(struct vm *vm, uint64_t guest_mem, uint64_t guest_mem_len); - void sie_guest_destroy(struct vm *vm); - ## lib/s390x/snippet-guest.h (new) ## @@ +/* SPDX-License-Identifier: GPL-2.0-only */ @@ lib/s390x/snippet-guest.h (new) + mb(); /* allow host to modify guest memory */ +} + -+#endif ++#endif /* _S390X_SNIPPET_GUEST_H_ */ ## lib/s390x/snippet.h => lib/s390x/snippet-host.h ## @@ @@ lib/s390x/snippet-host.h: static inline void snippet_setup_guest(struct vm *vm, +void snippet_check_force_exit_value(struct vm *vm, uint64_t exit_exp); #endif - ## lib/s390x/sie.c ## -@@ lib/s390x/sie.c: void sie_check_validity(struct vm *vm, uint16_t vir_exp) - report(vir_exp == vir, "VALIDITY: %x", vir); - } - -+bool sie_is_diag_icpt(struct vm *vm, unsigned int diag) -+{ -+ union { -+ struct { -+ uint64_t : 16; -+ uint64_t ipa : 16; -+ uint64_t ipb : 32; -+ }; -+ struct { -+ uint64_t : 16; -+ uint64_t opcode : 8; -+ uint64_t r_1 : 4; -+ uint64_t r_2 : 4; -+ uint64_t r_base : 4; -+ uint64_t displace : 12; -+ uint64_t zero : 16; -+ }; -+ } instr = { .ipa = vm->sblk->ipa, .ipb = vm->sblk->ipb }; -+ uint64_t code; -+ -+ assert(diag == 0x44 || diag == 0x9c); -+ -+ if (vm->sblk->icptcode != ICPT_INST) -+ return false; -+ if (instr.opcode != 0x83 || instr.zero) -+ return false; -+ code = instr.r_base ? vm->save_area.guest.grs[instr.r_base] : 0; -+ code = (code + instr.displace) & 0xffff; -+ return code == diag; -+} -+ - void sie_handle_validity(struct vm *vm) - { - if (vm->sblk->icptcode != ICPT_VALIDITY) - ## lib/s390x/snippet-host.c (new) ## @@ +/* SPDX-License-Identifier: GPL-2.0-only */ @@ s390x/pv-diags.c #include <libcflat.h> -#include <snippet.h> +#include <snippet-host.h> - #include <pv_icptdata.h> #include <sie.h> #include <sclp.h> + #include <asm/facility.h> ## s390x/pv-icptcode.c ## @@ @@ s390x/pv-icptcode.c #include <sclp.h> -#include <snippet.h> +#include <snippet-host.h> - #include <pv_icptdata.h> #include <asm/facility.h> #include <asm/barrier.h> + #include <asm/sigp.h> ## s390x/pv-ipl.c ## @@ @@ s390x/pv-ipl.c #include <sclp.h> -#include <snippet.h> +#include <snippet-host.h> - #include <pv_icptdata.h> #include <asm/facility.h> #include <asm/uv.h> + ## s390x/sie-dat.c ## @@ 4: 67fbf0bb ! 6: a1db588b s390x: Use library functions for snippet exit @@ s390x/sie-dat.c: static void test_sie_dat(void) ## s390x/snippets/c/sie-dat.c ## @@ - */ #include <libcflat.h> #include <asm-generic/page.h> + #include <asm/mem.h> +#include <snippet-guest.h> #include "sie-dat.h" 5: 157079f2 ! 7: 0b89b3c6 s390x: Add test for STFLE interpretive execution (format-0) @@ s390x/stfle-sie.c (new) +} ## s390x/unittests.cfg ## -@@ s390x/unittests.cfg: extra_params = """-cpu max,ctop=on -smp cpus=1,drawers=2,books=2,sockets=2,cores +@@ s390x/unittests.cfg: file = sie-dat.elf - [sie-dat] - file = sie-dat.elf + [pv-attest] + file = pv-attest.elf + +[stfle-sie] +file = stfle-sie.elf base-commit: 28ac3b10d6f982b1d9c2fe629f23d23ec5024b4f -- 2.44.0