@@ -97,4 +97,18 @@ static inline void low_prot_disable(void)
ctl_clear_bit(0, CTL0_LOW_ADDR_PROT);
}
+/**
+ * read_pgm_int_code - Get the program interruption code of the last pgm int
+ * on the current CPU.
+ *
+ * This is similar to clear_pgm_int(), except that it doesn't clear the
+ * interruption information from lowcore.
+ *
+ * Returns 0 when none occurred.
+ */
+static inline uint16_t read_pgm_int_code(void)
+{
+ return lowcore.pgm_int_code;
+}
+
#endif
@@ -8,6 +8,7 @@
#ifndef _ASMS390X_MEM_H_
#define _ASMS390X_MEM_H_
#include <asm/arch_def.h>
+#include <asm/facility.h>
/* create pointer while avoiding compiler warnings */
#define OPAQUE_PTR(x) ((void *)(((uint64_t)&lowcore) + (x)))
@@ -13,6 +13,7 @@
#include <libcflat.h>
#include <sie.h>
#include <asm/page.h>
+#include <asm/interrupt.h>
#include <libcflat.h>
#include <alloc_page.h>
@@ -79,7 +80,8 @@ void sie(struct vm *vm)
/* also handle all interruptions in home space while in SIE */
irq_set_dat_mode(true, AS_HOME);
- while (vm->sblk->icptcode == 0) {
+ /* leave SIE when we have an intercept or an interrupt so the test can react to it */
+ while (vm->sblk->icptcode == 0 && !read_pgm_int_code()) {
sie64a(vm->sblk, &vm->save_area);
sie_handle_validity(vm);
}