Re: [kvm-unit-tests PATCH v2 3/5] s390x: Add library functions for exiting from snippet

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 1/5/24 23:54, 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@xxxxxxxxxxxxx>
---
  s390x/Makefile                          |  1 +
  lib/s390x/asm/arch_def.h                | 13 ++++++++
  lib/s390x/sie.h                         |  1 +
  lib/s390x/snippet-guest.h               | 26 +++++++++++++++
  lib/s390x/{snippet.h => snippet-host.h} | 10 ++++--
  lib/s390x/sie.c                         | 31 ++++++++++++++++++
  lib/s390x/snippet-host.c                | 42 +++++++++++++++++++++++++
  lib/s390x/uv.c                          |  2 +-
  s390x/mvpg-sie.c                        |  2 +-
  s390x/pv-diags.c                        |  2 +-
  s390x/pv-icptcode.c                     |  2 +-
  s390x/pv-ipl.c                          |  2 +-
  s390x/sie-dat.c                         |  2 +-
  s390x/spec_ex-sie.c                     |  2 +-
  s390x/uv-host.c                         |  2 +-
  15 files changed, 129 insertions(+), 11 deletions(-)
  create mode 100644 lib/s390x/snippet-guest.h
  rename lib/s390x/{snippet.h => snippet-host.h} (92%)
  create mode 100644 lib/s390x/snippet-host.c

diff --git a/s390x/Makefile b/s390x/Makefile
index f79fd009..a10695a2 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -109,6 +109,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/snippet-host.o
  cflatobjs += lib/s390x/fault.o
OBJDIRS += lib/s390x
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/sie.h b/lib/s390x/sie.h
index c1724cf2..18fdd72e 100644
--- a/lib/s390x/sie.h
+++ b/lib/s390x/sie.h
@@ -281,6 +281,7 @@ 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);
diff --git a/lib/s390x/snippet-guest.h b/lib/s390x/snippet-guest.h
new file mode 100644
index 00000000..e82e8e29
--- /dev/null
+++ b/lib/s390x/snippet-guest.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Snippet functionality for the guest.
+ *
+ * Copyright IBM Corp. 2023
+ */
+
+#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
diff --git a/lib/s390x/snippet.h b/lib/s390x/snippet-host.h
similarity index 92%
rename from lib/s390x/snippet.h
rename to lib/s390x/snippet-host.h
index 910849aa..230b25b0 100644
--- a/lib/s390x/snippet.h
+++ b/lib/s390x/snippet-host.h
@@ -1,13 +1,13 @@
  /* SPDX-License-Identifier: GPL-2.0-only */
  /*
- * Snippet definitions
+ * Snippet functionality for the host.
   *
   * Copyright IBM Corp. 2021
   * Author: Janosch Frank <frankja@xxxxxxxxxxxxx>
   */
-#ifndef _S390X_SNIPPET_H_
-#define _S390X_SNIPPET_H_
+#ifndef _S390X_SNIPPET_HOST_H_
+#define _S390X_SNIPPET_HOST_H_
#include <sie.h>
  #include <uv.h>
@@ -144,4 +144,8 @@ 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
diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c
index 40936bd2..6bda493d 100644
--- a/lib/s390x/sie.c
+++ b/lib/s390x/sie.c
@@ -42,6 +42,37 @@ 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);

You're calling it is_diag_icpt and only allow two.
Do you have a reason for clamping this down?

I was considering consolidating pv_icptdata_check_diag() into this.




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux