aboutsummaryrefslogtreecommitdiff
path: root/target-s390x/misc_helper.c
diff options
context:
space:
mode:
authorXu Wang <gesaint@linux.vnet.ibm.com>2015-06-11 13:55:26 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-06-11 17:45:49 +0200
commit8fc639af4b62930671b6988c1f7eedf9e7c9f7bc (patch)
tree9c2259329b4884fd4486ef6c984b23dc3600059a /target-s390x/misc_helper.c
parent188f24c2c149bcb0088c6317e99e09afc007de34 (diff)
s390x/kvm: diag288 instruction interception and handling
Intercept the diag288 requests from kvm guests, and hand the requested command to the diag288 watchdog device for further handling. Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'target-s390x/misc_helper.c')
-rw-r--r--target-s390x/misc_helper.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index b375ab724b..6711504221 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -30,6 +30,7 @@
#include <linux/kvm.h>
#endif
#include "exec/cpu_ldst.h"
+#include "hw/watchdog/wdt_diag288.h"
#if !defined(CONFIG_USER_ONLY)
#include "sysemu/cpus.h"
@@ -153,6 +154,34 @@ static int load_normal_reset(S390CPU *cpu)
return 0;
}
+int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
+{
+ uint64_t func = env->regs[r1];
+ uint64_t timeout = env->regs[r1 + 1];
+ uint64_t action = env->regs[r3];
+ Object *obj;
+ DIAG288State *diag288;
+ DIAG288Class *diag288_class;
+
+ if (r1 % 2 || action != 0) {
+ return -1;
+ }
+
+ /* Timeout must be more than 15 seconds except for timer deletion */
+ if (func != WDT_DIAG288_CANCEL && timeout < 15) {
+ return -1;
+ }
+
+ obj = object_resolve_path_type("", TYPE_WDT_DIAG288, NULL);
+ if (!obj) {
+ return -1;
+ }
+
+ diag288 = DIAG288(obj);
+ diag288_class = DIAG288_GET_CLASS(diag288);
+ return diag288_class->handle_timer(diag288, func, timeout);
+}
+
#define DIAG_308_RC_OK 0x0001
#define DIAG_308_RC_NO_CONF 0x0102
#define DIAG_308_RC_INVALID 0x0402