* [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation
@ 2024-10-16 18:03 Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 1/6] s390x: lib: Remove double include Nina Schoetterl-Glausch
` (5 more replies)
0 siblings, 6 replies; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Nico Böhr, Nicholas Piggin, Thomas Huth, Janosch Frank,
Claudio Imbrenda
Cc: Nina Schoetterl-Glausch, David Hildenbrand, linux-s390, kvm
v3 -> v4:
* pick up R-b's (thanks Claudio, Janosch, Nick)
* move diag intercept functions into sie-icpt.[hc]
expose some more functionality to avoid interpreting the diag text
with bit operations
* move snippet exit functions into snippet-exit.h,
guest part in s390x/snippet/lib
* add barrier before snippet exit
* simplify test (host and guest), add skip message
Add a test case that tests the interpretation of STFLE performed by a
nested guest using a snippet.
Also add some functionality to s390x lib, namely:
* exit (optionally with return code) from snippet
* add function for checking diag intercepts, replacing pv_icptdata_check_diag
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
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 (6):
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)
s390x/Makefile | 7 +-
lib/s390x/asm/arch_def.h | 13 +++
lib/s390x/asm/facility.h | 10 ++-
lib/s390x/pv_icptdata.h | 42 ---------
lib/s390x/sie-icpt.h | 39 +++++++++
lib/s390x/sie.h | 6 ++
lib/s390x/snippet-exit.h | 47 ++++++++++
lib/s390x/sie-icpt.c | 60 +++++++++++++
lib/s390x/sie.c | 5 +-
s390x/snippets/lib/snippet-exit.h | 28 ++++++
s390x/pv-diags.c | 9 +-
s390x/pv-icptcode.c | 12 +--
s390x/pv-ipl.c | 8 +-
s390x/sie-dat.c | 12 +--
s390x/snippets/c/sie-dat.c | 19 +---
s390x/snippets/c/stfle.c | 29 +++++++
s390x/stfle-sie.c | 138 ++++++++++++++++++++++++++++++
s390x/unittests.cfg | 3 +
18 files changed, 399 insertions(+), 88 deletions(-)
delete mode 100644 lib/s390x/pv_icptdata.h
create mode 100644 lib/s390x/sie-icpt.h
create mode 100644 lib/s390x/snippet-exit.h
create mode 100644 lib/s390x/sie-icpt.c
create mode 100644 s390x/snippets/lib/snippet-exit.h
create mode 100644 s390x/snippets/c/stfle.c
create mode 100644 s390x/stfle-sie.c
Range-diff against v3:
1: baecabf2 < -: -------- lib: Add pseudo random functions
2: b30314eb ! 1: 74832900 s390x: lib: Remove double include
@@ Commit message
libcflat.h was included twice.
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+ Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
## lib/s390x/sie.c ##
3: f2af539b ! 2: 973607d1 s390x: Add sie_is_pv
@@ Commit message
Add a function to check if a guest VM is currently running protected.
+ Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+ Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
+ Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
## lib/s390x/sie.h ##
4: c4331d19 ! 3: 56f16e10 s390x: Add function for checking diagnose intercepts
@@ Commit message
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
+ ## s390x/Makefile ##
+@@ s390x/Makefile: cflatobjs += lib/s390x/css_lib.o
+ cflatobjs += lib/s390x/malloc_io.o
+ cflatobjs += lib/s390x/uv.o
+ cflatobjs += lib/s390x/sie.o
++cflatobjs += lib/s390x/sie-icpt.o
+ cflatobjs += lib/s390x/fault.o
+
+ OBJDIRS += lib/s390x
+
## lib/s390x/pv_icptdata.h (deleted) ##
@@
-/* SPDX-License-Identifier: GPL-2.0-only */
@@ lib/s390x/pv_icptdata.h (deleted)
-}
-#endif
- ## lib/s390x/sie.h ##
-@@ lib/s390x/sie.h: static inline bool sie_is_pv(struct vm *vm)
- return vm->sblk->sdf == 2;
- }
-
+ ## lib/s390x/sie-icpt.h (new) ##
+@@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Functionality for SIE interception handling.
++ *
++ * Copyright IBM Corp. 2024
++ */
++
++#ifndef _S390X_SIE_ICPT_H_
++#define _S390X_SIE_ICPT_H_
++
++#include <libcflat.h>
++#include <sie.h>
++
++struct diag_itext {
++ 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;
++ uint64_t : 16;
++};
++
++struct diag_itext sblk_ip_as_diag(struct kvm_s390_sie_block *sblk);
++
+/**
+ * sie_is_diag_icpt() - Check if intercept is due to diagnose instruction
+ * @vm: the guest
+ * @diag: the expected diagnose code
+ *
+ * Check that the intercept is due to diagnose @diag and valid.
-+ * For protected virtualisation, check that the intercept data meets additional
++ * For protected virtualization, check that the intercept data meets additional
+ * constraints.
+ *
+ * Returns: true if intercept is due to a valid and has matching diagnose code
+ */
+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);
++
++#endif /* _S390X_SIE_ICPT_H_ */
- ## 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)
+ ## lib/s390x/sie-icpt.c (new) ##
+@@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Functionality for SIE interception handling.
++ *
++ * Copyright IBM Corp. 2024
++ */
++
++#include <sie-icpt.h>
++
++struct diag_itext sblk_ip_as_diag(struct kvm_s390_sie_block *sblk)
+{
+ union {
+ struct {
-+ uint64_t : 16;
+ uint64_t ipa : 16;
+ uint64_t ipb : 32;
++ uint64_t : 16;
+ };
-+ 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 };
++ struct diag_itext diag;
++ } instr = { .ipa = sblk->ipa, .ipb = sblk->ipb };
++
++ return instr.diag;
++}
++
++bool sie_is_diag_icpt(struct vm *vm, unsigned int diag)
++{
++ struct diag_itext instr = sblk_ip_as_diag(vm->sblk);
+ uint8_t icptcode;
+ uint64_t code;
+
@@ lib/s390x/sie.c: void sie_check_validity(struct vm *vm, uint16_t vir_exp)
+ break;
+ default:
+ /* If a new diag is introduced add it to the cases above! */
-+ assert_msg(false, "unknown diag");
++ assert_msg(false, "unknown diag 0x%x", diag);
+ }
+
+ if (sie_is_pv(vm)) {
@@ lib/s390x/sie.c: void sie_check_validity(struct vm *vm, uint16_t vir_exp)
+ code = (code + instr.displace) & 0xffff;
+ return code == diag;
+}
-+
- void sie_handle_validity(struct vm *vm)
- {
- if (vm->sblk->icptcode != ICPT_VALIDITY)
## s390x/pv-diags.c ##
@@
@@ s390x/pv-diags.c
#include <libcflat.h>
#include <snippet.h>
-#include <pv_icptdata.h>
++#include <sie-icpt.h>
#include <sie.h>
#include <sclp.h>
#include <asm/facility.h>
@@ s390x/pv-icptcode.c
#include <sclp.h>
#include <snippet.h>
-#include <pv_icptdata.h>
++#include <sie-icpt.h>
#include <asm/facility.h>
#include <asm/barrier.h>
#include <asm/sigp.h>
@@ s390x/pv-ipl.c
#include <sclp.h>
#include <snippet.h>
-#include <pv_icptdata.h>
++#include <sie-icpt.h>
#include <asm/facility.h>
#include <asm/uv.h>
5: a3f92777 ! 4: 8cafb8da s390x: Add library functions for exiting from snippet
@@ Commit message
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
## s390x/Makefile ##
-@@ s390x/Makefile: cflatobjs += lib/s390x/css_lib.o
- cflatobjs += lib/s390x/malloc_io.o
- cflatobjs += lib/s390x/uv.o
- cflatobjs += lib/s390x/sie.o
-+cflatobjs += lib/s390x/snippet-host.o
- cflatobjs += lib/s390x/fault.o
+@@ s390x/Makefile: test_cases: $(tests)
+ test_cases_binary: $(tests_binary)
+ test_cases_pv: $(tests_pv_binary)
+
+-INCLUDE_PATHS = $(SRCDIR)/lib $(SRCDIR)/lib/s390x $(SRCDIR)/s390x
++SNIPPET_INCLUDE :=
++INCLUDE_PATHS = $(SNIPPET_INCLUDE) $(SRCDIR)/lib $(SRCDIR)/lib/s390x $(SRCDIR)/s390x
+ # Include generated header files (e.g. in case of out-of-source builds)
+ INCLUDE_PATHS += lib
+ CPPFLAGS = $(addprefix -I,$(INCLUDE_PATHS))
+@@ s390x/Makefile: endif
+ $(SNIPPET_DIR)/asm/%.o: $(SNIPPET_DIR)/asm/%.S $(asm-offsets)
+ $(CC) $(CFLAGS) -c -nostdlib -o $@ $<
+
++$(SNIPPET_DIR)/c/%.o: SNIPPET_INCLUDE := $(SNIPPET_DIR)/lib
+ $(SNIPPET_DIR)/c/%.o: $(SNIPPET_DIR)/c/%.c $(asm-offsets)
+ $(CC) $(CFLAGS) -c -nostdlib -o $@ $<
- OBJDIRS += lib/s390x
## lib/s390x/asm/arch_def.h ##
@@ lib/s390x/asm/arch_def.h: static inline uint32_t get_prefix(void)
@@ lib/s390x/asm/arch_def.h: static inline uint32_t get_prefix(void)
+
#endif
- ## lib/s390x/snippet-guest.h (new) ##
+ ## lib/s390x/snippet-exit.h (new) ##
@@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
-+ * Snippet functionality for the guest.
++ * Functionality handling snippet exits
+ *
-+ * Copyright IBM Corp. 2023
++ * Copyright IBM Corp. 2024
+ */
+
-+#ifndef _S390X_SNIPPET_GUEST_H_
-+#define _S390X_SNIPPET_GUEST_H_
-+
-+#include <asm/arch_def.h>
-+#include <asm/barrier.h>
-+
-+static inline void force_exit(void)
-+{
-+ diag44();
-+ mb(); /* allow host to modify guest memory */
-+}
-+
-+static inline void force_exit_value(uint64_t val)
-+{
-+ diag9c(val);
-+ mb(); /* allow host to modify guest memory */
-+}
-+
-+#endif /* _S390X_SNIPPET_GUEST_H_ */
-
- ## lib/s390x/snippet.h => lib/s390x/snippet-host.h ##
-@@
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
-- * Snippet definitions
-+ * Snippet functionality for the host.
- *
- * Copyright IBM Corp. 2021
- * Author: Janosch Frank <frankja@linux.ibm.com>
- */
-
--#ifndef _S390X_SNIPPET_H_
--#define _S390X_SNIPPET_H_
-+#ifndef _S390X_SNIPPET_HOST_H_
-+#define _S390X_SNIPPET_HOST_H_
-
- #include <sie.h>
- #include <uv.h>
-@@ lib/s390x/snippet-host.h: static inline void snippet_setup_guest(struct vm *vm, bool is_pv)
- }
- }
-
-+bool snippet_is_force_exit(struct vm *vm);
-+bool snippet_is_force_exit_value(struct vm *vm);
-+uint64_t snippet_get_force_exit_value(struct vm *vm);
-+void snippet_check_force_exit_value(struct vm *vm, uint64_t exit_exp);
- #endif
-
- ## lib/s390x/snippet-host.c (new) ##
-@@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Snippet functionality for the host.
-+ *
-+ * Copyright IBM Corp. 2023
-+ */
++#ifndef _S390X_SNIPPET_EXIT_H_
++#define _S390X_SNIPPET_EXIT_H_
+
+#include <libcflat.h>
-+#include <snippet-host.h>
+#include <sie.h>
++#include <sie-icpt.h>
+
-+bool snippet_is_force_exit(struct vm *vm)
++static inline bool snippet_is_force_exit(struct vm *vm)
+{
+ return sie_is_diag_icpt(vm, 0x44);
+}
+
-+bool snippet_is_force_exit_value(struct vm *vm)
++static inline bool snippet_is_force_exit_value(struct vm *vm)
+{
+ return sie_is_diag_icpt(vm, 0x9c);
+}
+
-+uint64_t snippet_get_force_exit_value(struct vm *vm)
++static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
+{
+ struct kvm_s390_sie_block *sblk = vm->sblk;
+
+ assert(snippet_is_force_exit_value(vm));
+
-+ return vm->save_area.guest.grs[(sblk->ipa & 0xf0) >> 4];
++ return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
+}
+
-+void snippet_check_force_exit_value(struct vm *vm, uint64_t value_exp)
++static inline void snippet_check_force_exit_value(struct vm *vm, uint64_t value_exp)
+{
+ uint64_t value;
+
@@ lib/s390x/snippet-host.c (new)
+ report_fail("guest forced exit with value");
+ }
+}
-
- ## lib/s390x/uv.c ##
-@@
- #include <asm/uv.h>
- #include <uv.h>
- #include <sie.h>
--#include <snippet.h>
-+#include <snippet-host.h>
-
- static struct uv_cb_qui uvcb_qui = {
- .header.cmd = UVC_CMD_QUI,
-
- ## s390x/mvpg-sie.c ##
-@@
- #include <alloc_page.h>
- #include <sclp.h>
- #include <sie.h>
--#include <snippet.h>
-+#include <snippet-host.h>
-
- static struct vm vm;
-
-
- ## s390x/pv-diags.c ##
-@@
- * Janosch Frank <frankja@linux.ibm.com>
- */
- #include <libcflat.h>
--#include <snippet.h>
-+#include <snippet-host.h>
- #include <sie.h>
- #include <sclp.h>
- #include <asm/facility.h>
-
- ## s390x/pv-icptcode.c ##
-@@
- #include <sie.h>
- #include <smp.h>
- #include <sclp.h>
--#include <snippet.h>
-+#include <snippet-host.h>
- #include <asm/facility.h>
- #include <asm/barrier.h>
- #include <asm/sigp.h>
-
- ## s390x/pv-ipl.c ##
-@@
- #include <libcflat.h>
- #include <sie.h>
- #include <sclp.h>
--#include <snippet.h>
-+#include <snippet-host.h>
- #include <asm/facility.h>
- #include <asm/uv.h>
-
-
- ## s390x/sie-dat.c ##
-@@
- #include <alloc_page.h>
- #include <sclp.h>
- #include <sie.h>
--#include <snippet.h>
-+#include <snippet-host.h>
- #include "snippets/c/sie-dat.h"
-
- static struct vm vm;
-
- ## s390x/spec_ex-sie.c ##
-@@
- #include <asm/arch_def.h>
- #include <alloc_page.h>
- #include <sie.h>
--#include <snippet.h>
-+#include <snippet-host.h>
- #include <hardware.h>
-
- static struct vm vm;
-
- ## s390x/uv-host.c ##
-@@
- #include <sclp.h>
- #include <smp.h>
- #include <uv.h>
--#include <snippet.h>
-+#include <snippet-host.h>
- #include <mmu.h>
- #include <asm/page.h>
- #include <asm/pgtable.h>
++
++#endif /* _S390X_SNIPPET_EXIT_H_ */
+
+ ## s390x/snippets/lib/snippet-exit.h (new) ##
+@@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Functionality for exiting the snippet.
++ *
++ * Copyright IBM Corp. 2023
++ */
++
++#ifndef _S390X_SNIPPET_LIB_EXIT_H_
++#define _S390X_SNIPPET_LIB_EXIT_H_
++
++#include <asm/arch_def.h>
++#include <asm/barrier.h>
++
++static inline void force_exit(void)
++{
++ mb(); /* host may read any memory written by the guest before */
++ diag44();
++ mb(); /* allow host to modify guest memory */
++}
++
++static inline void force_exit_value(uint64_t val)
++{
++ mb(); /* host may read any memory written by the guest before */
++ diag9c(val);
++ mb(); /* allow host to modify guest memory */
++}
++
++#endif /* _S390X_SNIPPET_LIB_EXIT_H_ */
6: a1db588b ! 5: cd79e654 s390x: Use library functions for snippet exit
@@ Commit message
Replace the existing code for exiting from snippets with the newly
introduced library functionality.
+ Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+ Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
## s390x/sie-dat.c ##
+@@
+ #include <sclp.h>
+ #include <sie.h>
+ #include <snippet.h>
++#include <snippet-exit.h>
+ #include "snippets/c/sie-dat.h"
+
+ static struct vm vm;
@@ s390x/sie-dat.c: static void test_sie_dat(void)
uint64_t test_page_gpa, test_page_hpa;
uint8_t *test_page_hva, expected_val;
@@ s390x/snippets/c/sie-dat.c
#include <libcflat.h>
#include <asm-generic/page.h>
#include <asm/mem.h>
-+#include <snippet-guest.h>
++#include <snippet-exit.h>
#include "sie-dat.h"
static uint8_t test_pages[GUEST_TEST_PAGE_COUNT * PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
7: 0b89b3c6 ! 6: 1e9893b6 s390x: Add test for STFLE interpretive execution (format-0)
@@ s390x/snippets/c/stfle.c (new)
+ * Snippet used by the STLFE interpretive execution facilities test.
+ */
+#include <libcflat.h>
-+#include <snippet-guest.h>
++#include <snippet-exit.h>
+
+int main(void)
+{
+ const unsigned int max_fac_len = 8;
++ uint64_t len_arg = max_fac_len - 1;
+ uint64_t res[max_fac_len + 1];
++ uint64_t fac[max_fac_len];
+
-+ res[0] = max_fac_len - 1;
-+ asm volatile ( "lg 0,%[len]\n"
++ asm volatile ( "lgr 0,%[len]\n"
+ " stfle %[fac]\n"
-+ " stg 0,%[len]\n"
-+ : [fac] "=QS"(*(uint64_t(*)[max_fac_len])&res[1]),
-+ [len] "+RT"(res[0])
++ " lgr %[len],0\n"
++ : [fac] "=Q"(fac),
++ [len] "+d"(len_arg)
+ :
+ : "%r0", "cc"
+ );
++ res[0] = len_arg;
++ memcpy(&res[1], fac, sizeof(fac));
+ force_exit_value((uint64_t)&res);
+ return 0;
+}
@@ s390x/stfle-sie.c (new)
+#include <stdlib.h>
+#include <asm/facility.h>
+#include <asm/time.h>
-+#include <snippet-host.h>
++#include <snippet.h>
++#include <snippet-exit.h>
+#include <alloc_page.h>
+#include <sclp.h>
+#include <rand.h>
@@ s390x/stfle-sie.c (new)
+
+struct guest_stfle_res {
+ uint16_t len;
-+ uint64_t reg;
+ unsigned char *mem;
+};
+
@@ s390x/stfle-sie.c (new)
+{
+ struct guest_stfle_res res;
+ uint64_t guest_stfle_addr;
++ uint64_t reg;
+
+ sie(&vm);
+ assert(snippet_is_force_exit_value(&vm));
+ guest_stfle_addr = snippet_get_force_exit_value(&vm);
+ res.mem = &vm.guest_mem[guest_stfle_addr];
-+ memcpy(&res.reg, res.mem, sizeof(res.reg));
-+ res.len = (res.reg & 0xff) + 1;
-+ res.mem += sizeof(res.reg);
++ memcpy(®, res.mem, sizeof(reg));
++ res.len = (reg & 0xff) + 1;
++ res.mem += sizeof(reg);
+ return res;
+}
+
@@ s390x/stfle-sie.c (new)
+int main(int argc, char **argv)
+{
+ struct args args = parse_args(argc, argv);
++ bool run_format_0 = test_facility(7);
+
+ if (!sclp_facilities.has_sief2) {
+ report_skip("SIEF2 facility unavailable");
+ goto out;
+ }
++ if (!run_format_0)
++ report_skip("STFLE facility not available");
+
+ report_info("PRNG seed: 0x%lx", args.seed);
+ prng_s = prng_init(args.seed);
+ setup_guest();
-+ if (test_facility(7))
++ if (run_format_0)
+ test_stfle_format_0();
+out:
+ return report_summary();
base-commit: f246b16099478a916eab37b9bd1eb07c743a67d5
--
2.44.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [kvm-unit-tests PATCH v4 1/6] s390x: lib: Remove double include
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
@ 2024-10-16 18:03 ` Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 2/6] s390x: Add sie_is_pv Nina Schoetterl-Glausch
` (4 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Claudio Imbrenda, Janosch Frank, Nico Böhr
Cc: Nina Schoetterl-Glausch, Thomas Huth, Nicholas Piggin,
David Hildenbrand, kvm, linux-s390
libcflat.h was included twice.
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
lib/s390x/sie.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index 28fbf146..40936bd2 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -14,7 +14,6 @@
#include <sie.h>
#include <asm/page.h>
#include <asm/interrupt.h>
-#include <libcflat.h>
#include <alloc_page.h>
#include <vmalloc.h>
#include <sclp.h>
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [kvm-unit-tests PATCH v4 2/6] s390x: Add sie_is_pv
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 1/6] s390x: lib: Remove double include Nina Schoetterl-Glausch
@ 2024-10-16 18:03 ` Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 3/6] s390x: Add function for checking diagnose intercepts Nina Schoetterl-Glausch
` (3 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Nico Böhr, Janosch Frank, Claudio Imbrenda
Cc: Nina Schoetterl-Glausch, Nicholas Piggin, David Hildenbrand,
linux-s390, kvm, Thomas Huth
Add a function to check if a guest VM is currently running protected.
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
lib/s390x/sie.h | 6 ++++++
lib/s390x/sie.c | 4 ++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/lib/s390x/sie.h b/lib/s390x/sie.h
index c1724cf2..53cd767f 100644
--- a/lib/s390x/sie.h
+++ b/lib/s390x/sie.h
@@ -281,6 +281,12 @@ 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);
+
+static inline bool sie_is_pv(struct vm *vm)
+{
+ return vm->sblk->sdf == 2;
+}
+
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);
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index 40936bd2..0fa915cf 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -59,7 +59,7 @@ void sie(struct vm *vm)
/* When a pgm int code is set, we'll never enter SIE below. */
assert(!read_pgm_int_code());
- if (vm->sblk->sdf == 2)
+ if (sie_is_pv(vm))
memcpy(vm->sblk->pv_grregs, vm->save_area.guest.grs,
sizeof(vm->save_area.guest.grs));
@@ -98,7 +98,7 @@ void sie(struct vm *vm)
/* restore the old CR 13 */
lctlg(13, old_cr13);
- if (vm->sblk->sdf == 2)
+ if (sie_is_pv(vm))
memcpy(vm->save_area.guest.grs, vm->sblk->pv_grregs,
sizeof(vm->save_area.guest.grs));
}
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [kvm-unit-tests PATCH v4 3/6] s390x: Add function for checking diagnose intercepts
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 1/6] s390x: lib: Remove double include Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 2/6] s390x: Add sie_is_pv Nina Schoetterl-Glausch
@ 2024-10-16 18:03 ` Nina Schoetterl-Glausch
2024-10-18 7:50 ` Janosch Frank
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet Nina Schoetterl-Glausch
` (2 subsequent siblings)
5 siblings, 1 reply; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Nico Böhr, Janosch Frank, Claudio Imbrenda
Cc: Nina Schoetterl-Glausch, David Hildenbrand, Thomas Huth,
linux-s390, kvm, Nicholas Piggin
sie_is_diag_icpt() checks if the intercept is due to an expected
diagnose call and is valid.
It subsumes pv_icptdata_check_diag.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
s390x/Makefile | 1 +
lib/s390x/pv_icptdata.h | 42 -----------------------------
lib/s390x/sie-icpt.h | 39 +++++++++++++++++++++++++++
lib/s390x/sie-icpt.c | 60 +++++++++++++++++++++++++++++++++++++++++
s390x/pv-diags.c | 9 +++----
s390x/pv-icptcode.c | 12 ++++-----
s390x/pv-ipl.c | 8 +++---
7 files changed, 114 insertions(+), 57 deletions(-)
delete mode 100644 lib/s390x/pv_icptdata.h
create mode 100644 lib/s390x/sie-icpt.h
create mode 100644 lib/s390x/sie-icpt.c
diff --git a/s390x/Makefile b/s390x/Makefile
index 23342bd6..0ad8d021 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -111,6 +111,7 @@ cflatobjs += lib/s390x/css_lib.o
cflatobjs += lib/s390x/malloc_io.o
cflatobjs += lib/s390x/uv.o
cflatobjs += lib/s390x/sie.o
+cflatobjs += lib/s390x/sie-icpt.o
cflatobjs += lib/s390x/fault.o
OBJDIRS += lib/s390x
diff --git a/lib/s390x/pv_icptdata.h b/lib/s390x/pv_icptdata.h
deleted file mode 100644
index 4746117e..00000000
--- a/lib/s390x/pv_icptdata.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Commonly used checks for PV SIE intercept data
- *
- * Copyright IBM Corp. 2023
- * Author: Janosch Frank <frankja@linux.ibm.com>
- */
-
-#ifndef _S390X_PV_ICPTDATA_H_
-#define _S390X_PV_ICPTDATA_H_
-
-#include <sie.h>
-
-/*
- * Checks the diagnose instruction intercept data for consistency with
- * the constants defined by the PV SIE architecture
- *
- * Supports: 0x44, 0x9c, 0x288, 0x308, 0x500
- */
-static bool pv_icptdata_check_diag(struct vm *vm, int diag)
-{
- int icptcode;
-
- switch (diag) {
- case 0x44:
- case 0x9c:
- case 0x288:
- case 0x308:
- icptcode = ICPT_PV_NOTIFY;
- break;
- case 0x500:
- icptcode = ICPT_PV_INSTR;
- break;
- default:
- /* If a new diag is introduced add it to the cases above! */
- assert(0);
- }
-
- return vm->sblk->icptcode == icptcode && vm->sblk->ipa == 0x8302 &&
- vm->sblk->ipb == 0x50000000 && vm->save_area.guest.grs[5] == diag;
-}
-#endif
diff --git a/lib/s390x/sie-icpt.h b/lib/s390x/sie-icpt.h
new file mode 100644
index 00000000..604a7221
--- /dev/null
+++ b/lib/s390x/sie-icpt.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functionality for SIE interception handling.
+ *
+ * Copyright IBM Corp. 2024
+ */
+
+#ifndef _S390X_SIE_ICPT_H_
+#define _S390X_SIE_ICPT_H_
+
+#include <libcflat.h>
+#include <sie.h>
+
+struct diag_itext {
+ 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;
+ uint64_t : 16;
+};
+
+struct diag_itext sblk_ip_as_diag(struct kvm_s390_sie_block *sblk);
+
+/**
+ * sie_is_diag_icpt() - Check if intercept is due to diagnose instruction
+ * @vm: the guest
+ * @diag: the expected diagnose code
+ *
+ * Check that the intercept is due to diagnose @diag and valid.
+ * For protected virtualization, check that the intercept data meets additional
+ * constraints.
+ *
+ * Returns: true if intercept is due to a valid and has matching diagnose code
+ */
+bool sie_is_diag_icpt(struct vm *vm, unsigned int diag);
+
+#endif /* _S390X_SIE_ICPT_H_ */
diff --git a/lib/s390x/sie-icpt.c b/lib/s390x/sie-icpt.c
new file mode 100644
index 00000000..17064424
--- /dev/null
+++ b/lib/s390x/sie-icpt.c
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functionality for SIE interception handling.
+ *
+ * Copyright IBM Corp. 2024
+ */
+
+#include <sie-icpt.h>
+
+struct diag_itext sblk_ip_as_diag(struct kvm_s390_sie_block *sblk)
+{
+ union {
+ struct {
+ uint64_t ipa : 16;
+ uint64_t ipb : 32;
+ uint64_t : 16;
+ };
+ struct diag_itext diag;
+ } instr = { .ipa = sblk->ipa, .ipb = sblk->ipb };
+
+ return instr.diag;
+}
+
+bool sie_is_diag_icpt(struct vm *vm, unsigned int diag)
+{
+ struct diag_itext instr = sblk_ip_as_diag(vm->sblk);
+ uint8_t icptcode;
+ uint64_t code;
+
+ switch (diag) {
+ case 0x44:
+ case 0x9c:
+ case 0x288:
+ case 0x308:
+ icptcode = ICPT_PV_NOTIFY;
+ break;
+ case 0x500:
+ icptcode = ICPT_PV_INSTR;
+ break;
+ default:
+ /* If a new diag is introduced add it to the cases above! */
+ assert_msg(false, "unknown diag 0x%x", diag);
+ }
+
+ if (sie_is_pv(vm)) {
+ if (instr.r_1 != 0 || instr.r_2 != 2 || instr.r_base != 5)
+ return false;
+ if (instr.displace)
+ return false;
+ } else {
+ icptcode = ICPT_INST;
+ }
+ if (vm->sblk->icptcode != icptcode)
+ 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;
+}
diff --git a/s390x/pv-diags.c b/s390x/pv-diags.c
index 3193ad99..09b83d59 100644
--- a/s390x/pv-diags.c
+++ b/s390x/pv-diags.c
@@ -9,7 +9,7 @@
*/
#include <libcflat.h>
#include <snippet.h>
-#include <pv_icptdata.h>
+#include <sie-icpt.h>
#include <sie.h>
#include <sclp.h>
#include <asm/facility.h>
@@ -32,8 +32,7 @@ static void test_diag_500(void)
size_gbin, size_hdr, SNIPPET_UNPACK_OFF);
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x500),
- "intercept values");
+ report(sie_is_diag_icpt(&vm, 0x500), "intercept values");
report(vm.save_area.guest.grs[1] == 1 &&
vm.save_area.guest.grs[2] == 2 &&
vm.save_area.guest.grs[3] == 3 &&
@@ -45,7 +44,7 @@ static void test_diag_500(void)
*/
vm.sblk->iictl = IICTL_CODE_OPERAND;
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x9c) &&
+ report(sie_is_diag_icpt(&vm, 0x9c) &&
vm.save_area.guest.grs[0] == PGM_INT_CODE_OPERAND,
"operand exception");
@@ -57,7 +56,7 @@ static void test_diag_500(void)
vm.sblk->iictl = IICTL_CODE_SPECIFICATION;
/* Inject PGM, next exit should be 9c */
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x9c) &&
+ report(sie_is_diag_icpt(&vm, 0x9c) &&
vm.save_area.guest.grs[0] == PGM_INT_CODE_SPECIFICATION,
"specification exception");
diff --git a/s390x/pv-icptcode.c b/s390x/pv-icptcode.c
index d7c47d6f..5293306b 100644
--- a/s390x/pv-icptcode.c
+++ b/s390x/pv-icptcode.c
@@ -13,7 +13,7 @@
#include <smp.h>
#include <sclp.h>
#include <snippet.h>
-#include <pv_icptdata.h>
+#include <sie-icpt.h>
#include <asm/facility.h>
#include <asm/barrier.h>
#include <asm/sigp.h>
@@ -47,7 +47,7 @@ static void test_validity_timing(void)
size_gbin, size_hdr, SNIPPET_UNPACK_OFF);
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x44), "spt done");
+ report(sie_is_diag_icpt(&vm, 0x44), "spt done");
stck(&time_exit);
tmp = vm.sblk->cputm;
mb();
@@ -258,7 +258,7 @@ static void test_validity_asce(void)
/* Try if we can still do an entry with the correct asce */
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x44), "re-entry with valid CR1");
+ report(sie_is_diag_icpt(&vm, 0x44), "re-entry with valid CR1");
uv_destroy_guest(&vm);
free_pages(pgd_new);
report_prefix_pop();
@@ -294,7 +294,7 @@ static void run_icpt_122_tests_prefix(unsigned long prefix)
sie(&vm);
/* Guest indicates that it has been setup via the diag 0x44 */
- assert(pv_icptdata_check_diag(&vm, 0x44));
+ assert(sie_is_diag_icpt(&vm, 0x44));
/* If the pages have not been shared these writes will cause exceptions */
ptr = (uint32_t *)prefix;
WRITE_ONCE(ptr, 0);
@@ -328,7 +328,7 @@ static void test_icpt_112(void)
/* Setup of the guest's state for 0x0 prefix */
sie(&vm);
- assert(pv_icptdata_check_diag(&vm, 0x44));
+ assert(sie_is_diag_icpt(&vm, 0x44));
/* Test on standard 0x0 prefix */
run_icpt_122_tests_prefix(0);
@@ -348,7 +348,7 @@ static void test_icpt_112(void)
/* Try a re-entry after everything has been imported again */
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x9c) &&
+ report(sie_is_diag_icpt(&vm, 0x9c) &&
vm.save_area.guest.grs[0] == 42,
"re-entry successful");
report_prefix_pop();
diff --git a/s390x/pv-ipl.c b/s390x/pv-ipl.c
index cc46e7f7..61a1e0c0 100644
--- a/s390x/pv-ipl.c
+++ b/s390x/pv-ipl.c
@@ -11,7 +11,7 @@
#include <sie.h>
#include <sclp.h>
#include <snippet.h>
-#include <pv_icptdata.h>
+#include <sie-icpt.h>
#include <asm/facility.h>
#include <asm/uv.h>
@@ -35,7 +35,7 @@ static void test_diag_308(int subcode)
/* First exit is a diag 0x500 */
sie(&vm);
- assert(pv_icptdata_check_diag(&vm, 0x500));
+ assert(sie_is_diag_icpt(&vm, 0x500));
/*
* The snippet asked us for the subcode and we answer by
@@ -46,7 +46,7 @@ static void test_diag_308(int subcode)
/* Continue after diag 0x500, next icpt should be the 0x308 */
sie(&vm);
- assert(pv_icptdata_check_diag(&vm, 0x308));
+ assert(sie_is_diag_icpt(&vm, 0x308));
assert(vm.save_area.guest.grs[2] == subcode);
/*
@@ -118,7 +118,7 @@ static void test_diag_308(int subcode)
* see a diagnose 0x9c PV instruction notification.
*/
sie(&vm);
- report(pv_icptdata_check_diag(&vm, 0x9c) &&
+ report(sie_is_diag_icpt(&vm, 0x9c) &&
vm.save_area.guest.grs[0] == 42,
"continue after load");
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
` (2 preceding siblings ...)
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 3/6] s390x: Add function for checking diagnose intercepts Nina Schoetterl-Glausch
@ 2024-10-16 18:03 ` Nina Schoetterl-Glausch
2024-10-18 8:02 ` Janosch Frank
2024-12-10 10:20 ` Nico Boehr
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 5/6] s390x: Use library functions for snippet exit Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 6/6] s390x: Add test for STFLE interpretive execution (format-0) Nina Schoetterl-Glausch
5 siblings, 2 replies; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Claudio Imbrenda, Thomas Huth, Nico Böhr, Janosch Frank
Cc: Nina Schoetterl-Glausch, David Hildenbrand, kvm, Nicholas Piggin,
linux-s390
It is useful to be able to force an exit to the host from the snippet,
as well as do so while returning a value.
Add this functionality, also add helper functions for the host to check
for an exit and get or check the value.
Use diag 0x44 and 0x9c for this.
Add a guest specific snippet header file and rename snippet.h to reflect
that it is host specific.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
s390x/Makefile | 4 ++-
lib/s390x/asm/arch_def.h | 13 +++++++++
lib/s390x/snippet-exit.h | 47 +++++++++++++++++++++++++++++++
s390x/snippets/lib/snippet-exit.h | 28 ++++++++++++++++++
4 files changed, 91 insertions(+), 1 deletion(-)
create mode 100644 lib/s390x/snippet-exit.h
create mode 100644 s390x/snippets/lib/snippet-exit.h
diff --git a/s390x/Makefile b/s390x/Makefile
index 0ad8d021..1caf221d 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -70,7 +70,8 @@ test_cases: $(tests)
test_cases_binary: $(tests_binary)
test_cases_pv: $(tests_pv_binary)
-INCLUDE_PATHS = $(SRCDIR)/lib $(SRCDIR)/lib/s390x $(SRCDIR)/s390x
+SNIPPET_INCLUDE :=
+INCLUDE_PATHS = $(SNIPPET_INCLUDE) $(SRCDIR)/lib $(SRCDIR)/lib/s390x $(SRCDIR)/s390x
# Include generated header files (e.g. in case of out-of-source builds)
INCLUDE_PATHS += lib
CPPFLAGS = $(addprefix -I,$(INCLUDE_PATHS))
@@ -151,6 +152,7 @@ endif
$(SNIPPET_DIR)/asm/%.o: $(SNIPPET_DIR)/asm/%.S $(asm-offsets)
$(CC) $(CFLAGS) -c -nostdlib -o $@ $<
+$(SNIPPET_DIR)/c/%.o: SNIPPET_INCLUDE := $(SNIPPET_DIR)/lib
$(SNIPPET_DIR)/c/%.o: $(SNIPPET_DIR)/c/%.c $(asm-offsets)
$(CC) $(CFLAGS) -c -nostdlib -o $@ $<
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index 745a3387..db04deca 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -504,4 +504,17 @@ static inline uint32_t get_prefix(void)
return current_prefix;
}
+static inline void diag44(void)
+{
+ asm volatile("diag 0,0,0x44\n");
+}
+
+static inline void diag9c(uint64_t val)
+{
+ asm volatile("diag %[val],0,0x9c\n"
+ :
+ : [val] "d"(val)
+ );
+}
+
#endif
diff --git a/lib/s390x/snippet-exit.h b/lib/s390x/snippet-exit.h
new file mode 100644
index 00000000..f62f0068
--- /dev/null
+++ b/lib/s390x/snippet-exit.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functionality handling snippet exits
+ *
+ * Copyright IBM Corp. 2024
+ */
+
+#ifndef _S390X_SNIPPET_EXIT_H_
+#define _S390X_SNIPPET_EXIT_H_
+
+#include <libcflat.h>
+#include <sie.h>
+#include <sie-icpt.h>
+
+static inline bool snippet_is_force_exit(struct vm *vm)
+{
+ return sie_is_diag_icpt(vm, 0x44);
+}
+
+static inline bool snippet_is_force_exit_value(struct vm *vm)
+{
+ return sie_is_diag_icpt(vm, 0x9c);
+}
+
+static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
+{
+ struct kvm_s390_sie_block *sblk = vm->sblk;
+
+ assert(snippet_is_force_exit_value(vm));
+
+ return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
+}
+
+static inline void snippet_check_force_exit_value(struct vm *vm, uint64_t value_exp)
+{
+ uint64_t value;
+
+ if (snippet_is_force_exit_value(vm)) {
+ value = snippet_get_force_exit_value(vm);
+ report(value == value_exp, "guest forced exit with value (0x%lx == 0x%lx)",
+ value, value_exp);
+ } else {
+ report_fail("guest forced exit with value");
+ }
+}
+
+#endif /* _S390X_SNIPPET_EXIT_H_ */
diff --git a/s390x/snippets/lib/snippet-exit.h b/s390x/snippets/lib/snippet-exit.h
new file mode 100644
index 00000000..0b483366
--- /dev/null
+++ b/s390x/snippets/lib/snippet-exit.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functionality for exiting the snippet.
+ *
+ * Copyright IBM Corp. 2023
+ */
+
+#ifndef _S390X_SNIPPET_LIB_EXIT_H_
+#define _S390X_SNIPPET_LIB_EXIT_H_
+
+#include <asm/arch_def.h>
+#include <asm/barrier.h>
+
+static inline void force_exit(void)
+{
+ mb(); /* host may read any memory written by the guest before */
+ diag44();
+ mb(); /* allow host to modify guest memory */
+}
+
+static inline void force_exit_value(uint64_t val)
+{
+ mb(); /* host may read any memory written by the guest before */
+ diag9c(val);
+ mb(); /* allow host to modify guest memory */
+}
+
+#endif /* _S390X_SNIPPET_LIB_EXIT_H_ */
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [kvm-unit-tests PATCH v4 5/6] s390x: Use library functions for snippet exit
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
` (3 preceding siblings ...)
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet Nina Schoetterl-Glausch
@ 2024-10-16 18:03 ` Nina Schoetterl-Glausch
2024-10-18 8:03 ` Janosch Frank
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 6/6] s390x: Add test for STFLE interpretive execution (format-0) Nina Schoetterl-Glausch
5 siblings, 1 reply; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Nico Böhr, Janosch Frank, Claudio Imbrenda, Thomas Huth,
Nicholas Piggin
Cc: Nina Schoetterl-Glausch, kvm, linux-s390, David Hildenbrand
Replace the existing code for exiting from snippets with the newly
introduced library functionality.
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
s390x/sie-dat.c | 12 ++++--------
s390x/snippets/c/sie-dat.c | 19 +------------------
2 files changed, 5 insertions(+), 26 deletions(-)
diff --git a/s390x/sie-dat.c b/s390x/sie-dat.c
index f0257770..44bf29fe 100644
--- a/s390x/sie-dat.c
+++ b/s390x/sie-dat.c
@@ -17,6 +17,7 @@
#include <sclp.h>
#include <sie.h>
#include <snippet.h>
+#include <snippet-exit.h>
#include "snippets/c/sie-dat.h"
static struct vm vm;
@@ -27,23 +28,18 @@ static void test_sie_dat(void)
uint64_t test_page_gpa, test_page_hpa;
uint8_t *test_page_hva, expected_val;
bool contents_match;
- uint8_t r1;
/* guest will tell us the guest physical address of the test buffer */
sie(&vm);
- assert(vm.sblk->icptcode == ICPT_INST &&
- (vm.sblk->ipa & 0xff00) == 0x8300 && vm.sblk->ipb == 0x9c0000);
-
- r1 = (vm.sblk->ipa & 0xf0) >> 4;
- test_page_gpa = vm.save_area.guest.grs[r1];
+ assert(snippet_is_force_exit_value(&vm));
+ test_page_gpa = snippet_get_force_exit_value(&vm);
test_page_hpa = virt_to_pte_phys(guest_root, (void*)test_page_gpa);
test_page_hva = __va(test_page_hpa);
report_info("test buffer gpa=0x%lx hva=%p", test_page_gpa, test_page_hva);
/* guest will now write to the test buffer and we verify the contents */
sie(&vm);
- assert(vm.sblk->icptcode == ICPT_INST &&
- vm.sblk->ipa == 0x8300 && vm.sblk->ipb == 0x440000);
+ assert(snippet_is_force_exit(&vm));
contents_match = true;
for (unsigned int i = 0; i < GUEST_TEST_PAGE_COUNT; i++) {
diff --git a/s390x/snippets/c/sie-dat.c b/s390x/snippets/c/sie-dat.c
index 9d89801d..ba1604de 100644
--- a/s390x/snippets/c/sie-dat.c
+++ b/s390x/snippets/c/sie-dat.c
@@ -10,28 +10,11 @@
#include <libcflat.h>
#include <asm-generic/page.h>
#include <asm/mem.h>
+#include <snippet-exit.h>
#include "sie-dat.h"
static uint8_t test_pages[GUEST_TEST_PAGE_COUNT * PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
-static inline void force_exit(void)
-{
- asm volatile("diag 0,0,0x44\n"
- :
- :
- : "memory"
- );
-}
-
-static inline void force_exit_value(uint64_t val)
-{
- asm volatile("diag %[val],0,0x9c\n"
- :
- : [val] "d"(val)
- : "memory"
- );
-}
-
int main(void)
{
uint8_t *invalid_ptr;
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [kvm-unit-tests PATCH v4 6/6] s390x: Add test for STFLE interpretive execution (format-0)
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
` (4 preceding siblings ...)
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 5/6] s390x: Use library functions for snippet exit Nina Schoetterl-Glausch
@ 2024-10-16 18:03 ` Nina Schoetterl-Glausch
5 siblings, 0 replies; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-10-16 18:03 UTC (permalink / raw)
To: Janosch Frank, Nico Böhr, Claudio Imbrenda
Cc: Nina Schoetterl-Glausch, Thomas Huth, kvm, David Hildenbrand,
linux-s390, Nicholas Piggin
The STFLE instruction indicates installed facilities.
SIE can interpretively execute STFLE.
Use a snippet guest executing STFLE to get the result of
interpretive execution and check the result.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
s390x/Makefile | 2 +
lib/s390x/asm/facility.h | 10 ++-
s390x/snippets/c/stfle.c | 29 ++++++++
s390x/stfle-sie.c | 138 +++++++++++++++++++++++++++++++++++++++
s390x/unittests.cfg | 3 +
5 files changed, 181 insertions(+), 1 deletion(-)
create mode 100644 s390x/snippets/c/stfle.c
create mode 100644 s390x/stfle-sie.c
diff --git a/s390x/Makefile b/s390x/Makefile
index 1caf221d..a5ef3a8e 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -44,6 +44,7 @@ tests += $(TEST_DIR)/exittime.elf
tests += $(TEST_DIR)/ex.elf
tests += $(TEST_DIR)/topology.elf
tests += $(TEST_DIR)/sie-dat.elf
+tests += $(TEST_DIR)/stfle-sie.elf
pv-tests += $(TEST_DIR)/pv-diags.elf
pv-tests += $(TEST_DIR)/pv-icptcode.elf
@@ -130,6 +131,7 @@ snippet_lib = $(snippet_asmlib) lib/auxinfo.o
$(TEST_DIR)/mvpg-sie.elf: snippets = $(SNIPPET_DIR)/c/mvpg-snippet.gbin
$(TEST_DIR)/sie-dat.elf: snippets = $(SNIPPET_DIR)/c/sie-dat.gbin
$(TEST_DIR)/spec_ex-sie.elf: snippets = $(SNIPPET_DIR)/c/spec_ex.gbin
+$(TEST_DIR)/stfle-sie.elf: snippets = $(SNIPPET_DIR)/c/stfle.gbin
$(TEST_DIR)/pv-diags.elf: pv-snippets += $(SNIPPET_DIR)/asm/pv-diag-yield.gbin
$(TEST_DIR)/pv-diags.elf: pv-snippets += $(SNIPPET_DIR)/asm/pv-diag-288.gbin
diff --git a/lib/s390x/asm/facility.h b/lib/s390x/asm/facility.h
index a66fe56a..2bad05c5 100644
--- a/lib/s390x/asm/facility.h
+++ b/lib/s390x/asm/facility.h
@@ -27,12 +27,20 @@ static inline void stfl(void)
asm volatile(" stfl 0(0)\n" : : : "memory");
}
-static inline void stfle(uint64_t *fac, unsigned int nb_doublewords)
+static inline unsigned int stfle(uint64_t *fac, unsigned int nb_doublewords)
{
register unsigned long r0 asm("0") = nb_doublewords - 1;
asm volatile(" .insn s,0xb2b00000,0(%1)\n"
: "+d" (r0) : "a" (fac) : "memory", "cc");
+ return r0 + 1;
+}
+
+static inline unsigned long stfle_size(void)
+{
+ uint64_t dummy;
+
+ return stfle(&dummy, 1);
}
static inline void setup_facilities(void)
diff --git a/s390x/snippets/c/stfle.c b/s390x/snippets/c/stfle.c
new file mode 100644
index 00000000..42d3d7fe
--- /dev/null
+++ b/s390x/snippets/c/stfle.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright IBM Corp. 2023
+ *
+ * Snippet used by the STLFE interpretive execution facilities test.
+ */
+#include <libcflat.h>
+#include <snippet-exit.h>
+
+int main(void)
+{
+ const unsigned int max_fac_len = 8;
+ uint64_t len_arg = max_fac_len - 1;
+ uint64_t res[max_fac_len + 1];
+ uint64_t fac[max_fac_len];
+
+ asm volatile ( "lgr 0,%[len]\n"
+ " stfle %[fac]\n"
+ " lgr %[len],0\n"
+ : [fac] "=Q"(fac),
+ [len] "+d"(len_arg)
+ :
+ : "%r0", "cc"
+ );
+ res[0] = len_arg;
+ memcpy(&res[1], fac, sizeof(fac));
+ force_exit_value((uint64_t)&res);
+ return 0;
+}
diff --git a/s390x/stfle-sie.c b/s390x/stfle-sie.c
new file mode 100644
index 00000000..21cf8ff8
--- /dev/null
+++ b/s390x/stfle-sie.c
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright IBM Corp. 2023
+ *
+ * SIE with STLFE interpretive execution facilities test.
+ */
+#include <libcflat.h>
+#include <stdlib.h>
+#include <asm/facility.h>
+#include <asm/time.h>
+#include <snippet.h>
+#include <snippet-exit.h>
+#include <alloc_page.h>
+#include <sclp.h>
+#include <rand.h>
+
+static struct vm vm;
+static uint64_t (*fac)[PAGE_SIZE / sizeof(uint64_t)];
+static prng_state prng_s;
+
+static void setup_guest(void)
+{
+ extern const char SNIPPET_NAME_START(c, stfle)[];
+ extern const char SNIPPET_NAME_END(c, stfle)[];
+
+ setup_vm();
+ fac = alloc_pages_flags(0, AREA_DMA31);
+
+ snippet_setup_guest(&vm, false);
+ snippet_init(&vm, SNIPPET_NAME_START(c, stfle),
+ SNIPPET_LEN(c, stfle), SNIPPET_UNPACK_OFF);
+}
+
+struct guest_stfle_res {
+ uint16_t len;
+ unsigned char *mem;
+};
+
+static struct guest_stfle_res run_guest(void)
+{
+ struct guest_stfle_res res;
+ uint64_t guest_stfle_addr;
+ uint64_t reg;
+
+ sie(&vm);
+ assert(snippet_is_force_exit_value(&vm));
+ guest_stfle_addr = snippet_get_force_exit_value(&vm);
+ res.mem = &vm.guest_mem[guest_stfle_addr];
+ memcpy(®, res.mem, sizeof(reg));
+ res.len = (reg & 0xff) + 1;
+ res.mem += sizeof(reg);
+ return res;
+}
+
+static void test_stfle_format_0(void)
+{
+ struct guest_stfle_res res;
+
+ report_prefix_push("format-0");
+ for (int j = 0; j < stfle_size(); j++)
+ WRITE_ONCE((*fac)[j], prng64(&prng_s));
+ vm.sblk->fac = (uint32_t)(uint64_t)fac;
+ res = run_guest();
+ report(res.len == stfle_size(), "stfle len correct");
+ report(!memcmp(*fac, res.mem, res.len * sizeof(uint64_t)),
+ "Guest facility list as specified");
+ report_prefix_pop();
+}
+
+struct args {
+ uint64_t seed;
+};
+
+static bool parse_uint64_t(const char *arg, uint64_t *out)
+{
+ char *end;
+ uint64_t num;
+
+ if (arg[0] == '\0')
+ return false;
+ num = strtoul(arg, &end, 0);
+ if (end[0] != '\0')
+ return false;
+ *out = num;
+ return true;
+}
+
+static struct args parse_args(int argc, char **argv)
+{
+ struct args args;
+ const char *flag;
+ unsigned int i;
+ uint64_t arg;
+ bool has_arg;
+
+ stck(&args.seed);
+
+ for (i = 1; i < argc; i++) {
+ if (i + 1 < argc)
+ has_arg = parse_uint64_t(argv[i + 1], &arg);
+ else
+ has_arg = false;
+
+ flag = "--seed";
+ if (!strcmp(flag, argv[i])) {
+ if (!has_arg)
+ report_abort("%s needs an uint64_t parameter", flag);
+ args.seed = arg;
+ ++i;
+ continue;
+ }
+ report_abort("Unsupported parameter '%s'",
+ argv[i]);
+ }
+
+ return args;
+}
+
+int main(int argc, char **argv)
+{
+ struct args args = parse_args(argc, argv);
+ bool run_format_0 = test_facility(7);
+
+ if (!sclp_facilities.has_sief2) {
+ report_skip("SIEF2 facility unavailable");
+ goto out;
+ }
+ if (!run_format_0)
+ report_skip("STFLE facility not available");
+
+ report_info("PRNG seed: 0x%lx", args.seed);
+ prng_s = prng_init(args.seed);
+ setup_guest();
+ if (run_format_0)
+ test_stfle_format_0();
+out:
+ return report_summary();
+}
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 3a9decc9..f2203069 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -392,3 +392,6 @@ file = sie-dat.elf
[pv-attest]
file = pv-attest.elf
+
+[stfle-sie]
+file = stfle-sie.elf
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 3/6] s390x: Add function for checking diagnose intercepts
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 3/6] s390x: Add function for checking diagnose intercepts Nina Schoetterl-Glausch
@ 2024-10-18 7:50 ` Janosch Frank
0 siblings, 0 replies; 17+ messages in thread
From: Janosch Frank @ 2024-10-18 7:50 UTC (permalink / raw)
To: Nina Schoetterl-Glausch, Nico Böhr, Claudio Imbrenda
Cc: David Hildenbrand, Thomas Huth, linux-s390, kvm, Nicholas Piggin
On 10/16/24 8:03 PM, Nina Schoetterl-Glausch wrote:
> sie_is_diag_icpt() checks if the intercept is due to an expected
> diagnose call and is valid.
> It subsumes pv_icptdata_check_diag.
>
> Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
That looks great, thanks for refactoring!
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet Nina Schoetterl-Glausch
@ 2024-10-18 8:02 ` Janosch Frank
2024-10-18 10:56 ` Nico Boehr
2024-12-10 10:20 ` Nico Boehr
1 sibling, 1 reply; 17+ messages in thread
From: Janosch Frank @ 2024-10-18 8:02 UTC (permalink / raw)
To: Nina Schoetterl-Glausch, Claudio Imbrenda, Thomas Huth,
Nico Böhr
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
On 10/16/24 8:03 PM, Nina Schoetterl-Glausch wrote:
> It is useful to be able to force an exit to the host from the snippet,
> as well as do so while returning a value.
> Add this functionality, also add helper functions for the host to check
> for an exit and get or check the value.
> Use diag 0x44 and 0x9c for this.
> Add a guest specific snippet header file and rename snippet.h to reflect
> that it is host specific.
>
> Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
> ---
> s390x/Makefile | 4 ++-
> lib/s390x/asm/arch_def.h | 13 +++++++++
> lib/s390x/snippet-exit.h | 47 +++++++++++++++++++++++++++++++
> s390x/snippets/lib/snippet-exit.h | 28 ++++++++++++++++++
> 4 files changed, 91 insertions(+), 1 deletion(-)
> create mode 100644 lib/s390x/snippet-exit.h
> create mode 100644 s390x/snippets/lib/snippet-exit.h
>
> diff --git a/s390x/Makefile b/s390x/Makefile
> index 0ad8d021..1caf221d 100644
> --- a/s390x/Makefile
> +++ b/s390x/Makefile
> @@ -70,7 +70,8 @@ test_cases: $(tests)
> test_cases_binary: $(tests_binary)
> test_cases_pv: $(tests_pv_binary)
>
> -INCLUDE_PATHS = $(SRCDIR)/lib $(SRCDIR)/lib/s390x $(SRCDIR)/s390x
> +SNIPPET_INCLUDE :=
> +INCLUDE_PATHS = $(SNIPPET_INCLUDE) $(SRCDIR)/lib $(SRCDIR)/lib/s390x $(SRCDIR)/s390x
> # Include generated header files (e.g. in case of out-of-source builds)
> INCLUDE_PATHS += lib
> CPPFLAGS = $(addprefix -I,$(INCLUDE_PATHS))
> @@ -151,6 +152,7 @@ endif
> $(SNIPPET_DIR)/asm/%.o: $(SNIPPET_DIR)/asm/%.S $(asm-offsets)
> $(CC) $(CFLAGS) -c -nostdlib -o $@ $<
>
> +$(SNIPPET_DIR)/c/%.o: SNIPPET_INCLUDE := $(SNIPPET_DIR)/lib
> $(SNIPPET_DIR)/c/%.o: $(SNIPPET_DIR)/c/%.c $(asm-offsets)
> $(CC) $(CFLAGS) -c -nostdlib -o $@ $<
>
> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
> index 745a3387..db04deca 100644
> --- a/lib/s390x/asm/arch_def.h
> +++ b/lib/s390x/asm/arch_def.h
> @@ -504,4 +504,17 @@ static inline uint32_t get_prefix(void)
> return current_prefix;
> }
>
> +static inline void diag44(void)
> +{
> + asm volatile("diag 0,0,0x44\n");
> +}
> +
> +static inline void diag9c(uint64_t val)
> +{
> + asm volatile("diag %[val],0,0x9c\n"
> + :
> + : [val] "d"(val)
> + );
> +}
> +
> #endif
> diff --git a/lib/s390x/snippet-exit.h b/lib/s390x/snippet-exit.h
> new file mode 100644
> index 00000000..f62f0068
> --- /dev/null
> +++ b/lib/s390x/snippet-exit.h
> @@ -0,0 +1,47 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Functionality handling snippet exits
> + *
> + * Copyright IBM Corp. 2024
> + */
> +
> +#ifndef _S390X_SNIPPET_EXIT_H_
> +#define _S390X_SNIPPET_EXIT_H_
> +
> +#include <libcflat.h>
> +#include <sie.h>
> +#include <sie-icpt.h>
> +
> +static inline bool snippet_is_force_exit(struct vm *vm)
> +{
> + return sie_is_diag_icpt(vm, 0x44);
> +}
> +
> +static inline bool snippet_is_force_exit_value(struct vm *vm)
> +{
> + return sie_is_diag_icpt(vm, 0x9c);
> +}
> +
> +static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
> +{
> + struct kvm_s390_sie_block *sblk = vm->sblk;
> +
> + assert(snippet_is_force_exit_value(vm));
> +
> + return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
> +}
The cpu address parameter for 9C is 16 bit.
While we could make it 64 bit for snippets I don't see a reason to do
so. The 16 bits are enough to indicate something to the host which can
then go and fetch memory for more data.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 5/6] s390x: Use library functions for snippet exit
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 5/6] s390x: Use library functions for snippet exit Nina Schoetterl-Glausch
@ 2024-10-18 8:03 ` Janosch Frank
0 siblings, 0 replies; 17+ messages in thread
From: Janosch Frank @ 2024-10-18 8:03 UTC (permalink / raw)
To: Nina Schoetterl-Glausch, Nico Böhr, Claudio Imbrenda,
Thomas Huth, Nicholas Piggin
Cc: kvm, linux-s390, David Hildenbrand
On 10/16/24 8:03 PM, Nina Schoetterl-Glausch wrote:
> Replace the existing code for exiting from snippets with the newly
> introduced library functionality.
>
> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
> Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-18 8:02 ` Janosch Frank
@ 2024-10-18 10:56 ` Nico Boehr
2024-10-18 12:53 ` Janosch Frank
0 siblings, 1 reply; 17+ messages in thread
From: Nico Boehr @ 2024-10-18 10:56 UTC (permalink / raw)
To: Claudio Imbrenda, Janosch Frank, Nina Schoetterl-Glausch,
Thomas Huth
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
Quoting Janosch Frank (2024-10-18 10:02:37)
[...]
> > +static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
> > +{
> > + struct kvm_s390_sie_block *sblk = vm->sblk;
> > +
> > + assert(snippet_is_force_exit_value(vm));
> > +
> > + return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
> > +}
>
> The cpu address parameter for 9C is 16 bit.
> While we could make it 64 bit for snippets I don't see a reason to do
> so. The 16 bits are enough to indicate something to the host which can
> then go and fetch memory for more data.
Mh, how exactly would you "fetch memory"? That requires knowledge on where
things are in guest memory which can be painful to figure out from the
host.
I've found it useful to be able to pass a pointer from guest to host. Maybe
a diag500 is the better option? gr2 contains the cookie which is a 64-bit
value - see Linux' Documentation/virt/kvm/s390/s390-diag.rst.
P.S. Did I miss the part in the docs where the 16-bit restriction of 9c is
documented or is it missing?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-18 10:56 ` Nico Boehr
@ 2024-10-18 12:53 ` Janosch Frank
2024-10-21 8:21 ` Nico Boehr
0 siblings, 1 reply; 17+ messages in thread
From: Janosch Frank @ 2024-10-18 12:53 UTC (permalink / raw)
To: Nico Boehr, Claudio Imbrenda, Nina Schoetterl-Glausch,
Thomas Huth
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
On 10/18/24 12:56 PM, Nico Boehr wrote:
> Quoting Janosch Frank (2024-10-18 10:02:37)
> [...]
>>> +static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
>>> +{
>>> + struct kvm_s390_sie_block *sblk = vm->sblk;
>>> +
>>> + assert(snippet_is_force_exit_value(vm));
>>> +
>>> + return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
>>> +}
>>
>> The cpu address parameter for 9C is 16 bit.
>> While we could make it 64 bit for snippets I don't see a reason to do
>> so. The 16 bits are enough to indicate something to the host which can
>> then go and fetch memory for more data.
>
> Mh, how exactly would you "fetch memory"? That requires knowledge on where
> things are in guest memory which can be painful to figure out from the
> host.
>
> I've found it useful to be able to pass a pointer from guest to host. Maybe
> a diag500 is the better option? gr2 contains the cookie which is a 64-bit
> value - see Linux' Documentation/virt/kvm/s390/s390-diag.rst.
>
> P.S. Did I miss the part in the docs where the 16-bit restriction of 9c is
> documented or is it missing?
For ASM snippets addresses 0x2000 to 0x4000 are a free area.
For C snippets that area is the stack.
The 16 bits should be good enough to point into that area.
If the snippet requires a lot of memory then you can use constant
addresses which are way over the snippet binary or just store a 64 bit
address in a "free" lowcore location.
As you mentioned we also have diag500 which has the drawback of
requiring to specify a couple more registers but that's not a huge
hassle. For some yet to be released PV tests I use the diag500 to
transfer 64 bits without the unshare.
If you want to write some funky code just do 4 diag9Cs to pass all 64
bits. Just don't ever show me that code :)
I've looked at the LPAR spec and that specifies bits 48-63 as the cpu
address. Send me a DM if you find a different specification.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-18 12:53 ` Janosch Frank
@ 2024-10-21 8:21 ` Nico Boehr
2024-10-21 13:04 ` Janosch Frank
0 siblings, 1 reply; 17+ messages in thread
From: Nico Boehr @ 2024-10-21 8:21 UTC (permalink / raw)
To: Claudio Imbrenda, Janosch Frank, Nina Schoetterl-Glausch,
Thomas Huth
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
Quoting Janosch Frank (2024-10-18 14:53:34)
> On 10/18/24 12:56 PM, Nico Boehr wrote:
> > Quoting Janosch Frank (2024-10-18 10:02:37)
> > [...]
> >>> +static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
> >>> +{
> >>> + struct kvm_s390_sie_block *sblk = vm->sblk;
> >>> +
> >>> + assert(snippet_is_force_exit_value(vm));
> >>> +
> >>> + return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
> >>> +}
> >>
> >> The cpu address parameter for 9C is 16 bit.
> >> While we could make it 64 bit for snippets I don't see a reason to do
> >> so. The 16 bits are enough to indicate something to the host which can
> >> then go and fetch memory for more data.
> >
> > Mh, how exactly would you "fetch memory"? That requires knowledge on where
> > things are in guest memory which can be painful to figure out from the
> > host.
> >
> > I've found it useful to be able to pass a pointer from guest to host. Maybe
> > a diag500 is the better option? gr2 contains the cookie which is a 64-bit
> > value - see Linux' Documentation/virt/kvm/s390/s390-diag.rst.
> >
> > P.S. Did I miss the part in the docs where the 16-bit restriction of 9c is
> > documented or is it missing?
>
> For ASM snippets addresses 0x2000 to 0x4000 are a free area.
> For C snippets that area is the stack.
> The 16 bits should be good enough to point into that area.
Actually, it's currently just enough to point into the stack (snippet stack
is 64K)... also requires additional fiddling in the host to figure out the
complete address. Probably also in the guest, if you do it r15-relative
(can't think of a different solution right now).
> If the snippet requires a lot of memory then you can use constant
> addresses which are way over the snippet binary or just store a 64 bit
> address in a "free" lowcore location.
Would you prefer any of those over the diag500 solution?
> As you mentioned we also have diag500 which has the drawback of
> requiring to specify a couple more registers but that's not a huge
> hassle.
Since Nina contributed this nice wrapper function, going diag500 seems to
be the best thing to do.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-21 8:21 ` Nico Boehr
@ 2024-10-21 13:04 ` Janosch Frank
0 siblings, 0 replies; 17+ messages in thread
From: Janosch Frank @ 2024-10-21 13:04 UTC (permalink / raw)
To: Nico Boehr, Claudio Imbrenda, Nina Schoetterl-Glausch,
Thomas Huth
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
On 10/21/24 10:21 AM, Nico Boehr wrote:
> Quoting Janosch Frank (2024-10-18 14:53:34)
>> On 10/18/24 12:56 PM, Nico Boehr wrote:
>>> Quoting Janosch Frank (2024-10-18 10:02:37)
>>> [...]
>>>>> +static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
>>>>> +{
>>>>> + struct kvm_s390_sie_block *sblk = vm->sblk;
>>>>> +
>>>>> + assert(snippet_is_force_exit_value(vm));
>>>>> +
>>>>> + return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
>>>>> +}
>>>>
>>>> The cpu address parameter for 9C is 16 bit.
>>>> While we could make it 64 bit for snippets I don't see a reason to do
>>>> so. The 16 bits are enough to indicate something to the host which can
>>>> then go and fetch memory for more data.
>>>
>>> Mh, how exactly would you "fetch memory"? That requires knowledge on where
>>> things are in guest memory which can be painful to figure out from the
>>> host.
>>>
>>> I've found it useful to be able to pass a pointer from guest to host. Maybe
>>> a diag500 is the better option? gr2 contains the cookie which is a 64-bit
>>> value - see Linux' Documentation/virt/kvm/s390/s390-diag.rst.
>>>
>>> P.S. Did I miss the part in the docs where the 16-bit restriction of 9c is
>>> documented or is it missing?
>>
>> For ASM snippets addresses 0x2000 to 0x4000 are a free area.
>> For C snippets that area is the stack.
>> The 16 bits should be good enough to point into that area.
>
> Actually, it's currently just enough to point into the stack (snippet stack
> is 64K)... also requires additional fiddling in the host to figure out the
> complete address. Probably also in the guest, if you do it r15-relative
> (can't think of a different solution right now).
I think you looked into the wrong lds; the unit tests have 64k, the
snippets don't.
The snippet stack is from 0x4000 to 0x2000 whereas the unit test stack
is located behind the binary.
I have no recollection about why I placed it there, though the mail
archive may or may not have answers.
>
>> If the snippet requires a lot of memory then you can use constant
>> addresses which are way over the snippet binary or just store a 64 bit
>> address in a "free" lowcore location.
>
> Would you prefer any of those over the diag500 solution?
I think the diag500 is a bit cleaner and more future proof.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet Nina Schoetterl-Glausch
2024-10-18 8:02 ` Janosch Frank
@ 2024-12-10 10:20 ` Nico Boehr
2024-12-12 15:33 ` Nina Schoetterl-Glausch
1 sibling, 1 reply; 17+ messages in thread
From: Nico Boehr @ 2024-12-10 10:20 UTC (permalink / raw)
To: Nina Schoetterl-Glausch, Claudio Imbrenda, Thomas Huth,
Janosch Frank
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
On Wed Oct 16, 2024 at 8:03 PM CEST, Nina Schoetterl-Glausch wrote:
> It is useful to be able to force an exit to the host from the snippet,
> as well as do so while returning a value.
> Add this functionality, also add helper functions for the host to check
> for an exit and get or check the value.
> Use diag 0x44 and 0x9c for this.
> Add a guest specific snippet header file and rename snippet.h to reflect
> that it is host specific.
>
> Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Hi Nina,
would you mind if I fix this up like this?
(copy-pasted so whitespace damage ahead)
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index 2dec7924..03adcd3c 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -510,11 +510,14 @@ static inline void diag44(void)
asm volatile("diag 0,0,0x44\n");
}
-static inline void diag9c(uint64_t val)
+static inline void diag500(uint64_t val)
{
- asm volatile("diag %[val],0,0x9c\n"
+ asm volatile(
+ "lgr 2,%[val]\n"
+ "diag 0,0,0x500\n"
:
: [val] "d"(val)
+ : "r2"
);
}
diff --git a/lib/s390x/snippet-exit.h b/lib/s390x/snippet-exit.h
index f62f0068..3ed4c22c 100644
--- a/lib/s390x/snippet-exit.h
+++ b/lib/s390x/snippet-exit.h
@@ -19,16 +19,14 @@ static inline bool snippet_is_force_exit(struct vm *vm)
static inline bool snippet_is_force_exit_value(struct vm *vm)
{
- return sie_is_diag_icpt(vm, 0x9c);
+ return sie_is_diag_icpt(vm, 0x500);
}
static inline uint64_t snippet_get_force_exit_value(struct vm *vm)
{
- struct kvm_s390_sie_block *sblk = vm->sblk;
-
assert(snippet_is_force_exit_value(vm));
- return vm->save_area.guest.grs[sblk_ip_as_diag(sblk).r_1];
+ return vm->save_area.guest.grs[2];
}
static inline void snippet_check_force_exit_value(struct vm *vm, uint64_t value_exp)
diff --git a/s390x/snippets/lib/snippet-exit.h b/s390x/snippets/lib/snippet-exit.h
index 0b483366..ac00de3f 100644
--- a/s390x/snippets/lib/snippet-exit.h
+++ b/s390x/snippets/lib/snippet-exit.h
@@ -21,7 +21,7 @@ static inline void force_exit(void)
static inline void force_exit_value(uint64_t val)
{
mb(); /* host may read any memory written by the guest before */
- diag9c(val);
+ diag500(val);
mb(); /* allow host to modify guest memory */
}
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-12-10 10:20 ` Nico Boehr
@ 2024-12-12 15:33 ` Nina Schoetterl-Glausch
2025-01-08 8:27 ` Nico Boehr
0 siblings, 1 reply; 17+ messages in thread
From: Nina Schoetterl-Glausch @ 2024-12-12 15:33 UTC (permalink / raw)
To: Nico Boehr, Claudio Imbrenda, Thomas Huth, Janosch Frank
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
On Tue, 2024-12-10 at 11:20 +0100, Nico Boehr wrote:
> On Wed Oct 16, 2024 at 8:03 PM CEST, Nina Schoetterl-Glausch wrote:
> > It is useful to be able to force an exit to the host from the snippet,
> > as well as do so while returning a value.
> > Add this functionality, also add helper functions for the host to check
> > for an exit and get or check the value.
> > Use diag 0x44 and 0x9c for this.
> > Add a guest specific snippet header file and rename snippet.h to reflect
> > that it is host specific.
> >
> > Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
>
> Hi Nina,
>
> would you mind if I fix this up like this?
Looks good to me.
Thanks!
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet
2024-12-12 15:33 ` Nina Schoetterl-Glausch
@ 2025-01-08 8:27 ` Nico Boehr
0 siblings, 0 replies; 17+ messages in thread
From: Nico Boehr @ 2025-01-08 8:27 UTC (permalink / raw)
To: Nina Schoetterl-Glausch, Claudio Imbrenda, Thomas Huth,
Janosch Frank
Cc: David Hildenbrand, kvm, Nicholas Piggin, linux-s390
On Thu Dec 12, 2024 at 4:33 PM CET, Nina Schoetterl-Glausch wrote:
> On Tue, 2024-12-10 at 11:20 +0100, Nico Boehr wrote:
> > On Wed Oct 16, 2024 at 8:03 PM CEST, Nina Schoetterl-Glausch wrote:
> > > It is useful to be able to force an exit to the host from the snippet,
> > > as well as do so while returning a value.
> > > Add this functionality, also add helper functions for the host to check
> > > for an exit and get or check the value.
> > > Use diag 0x44 and 0x9c for this.
> > > Add a guest specific snippet header file and rename snippet.h to reflect
> > > that it is host specific.
> > >
> > > Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
> >
> > Hi Nina,
> >
> > would you mind if I fix this up like this?
>
> Looks good to me.
> Thanks!
Alright, thanks. It's now in the CI for coverage. When no issues come up, I will pick it.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2025-01-08 8:27 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-16 18:03 [kvm-unit-tests PATCH v4 0/6] s390x: STFLE nested interpretation Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 1/6] s390x: lib: Remove double include Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 2/6] s390x: Add sie_is_pv Nina Schoetterl-Glausch
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 3/6] s390x: Add function for checking diagnose intercepts Nina Schoetterl-Glausch
2024-10-18 7:50 ` Janosch Frank
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 4/6] s390x: Add library functions for exiting from snippet Nina Schoetterl-Glausch
2024-10-18 8:02 ` Janosch Frank
2024-10-18 10:56 ` Nico Boehr
2024-10-18 12:53 ` Janosch Frank
2024-10-21 8:21 ` Nico Boehr
2024-10-21 13:04 ` Janosch Frank
2024-12-10 10:20 ` Nico Boehr
2024-12-12 15:33 ` Nina Schoetterl-Glausch
2025-01-08 8:27 ` Nico Boehr
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 5/6] s390x: Use library functions for snippet exit Nina Schoetterl-Glausch
2024-10-18 8:03 ` Janosch Frank
2024-10-16 18:03 ` [kvm-unit-tests PATCH v4 6/6] s390x: Add test for STFLE interpretive execution (format-0) Nina Schoetterl-Glausch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).