From: Thomas Huth <th...@linux.vnet.ibm.com>

So far, the DIAG 500 hypervisor call was only setting -EINVAL in
R2 when a guest tried to call this function with an illegal subcode.
This patch now changes the behavior so that a specification exception
is thrown instead, since this is the common behavior of other DIAG
functions (and other CPU instructions) when being called with illegal
parameters.

Signed-off-by: Thomas Huth <th...@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.h...@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntrae...@de.ibm.com>
---
 hw/s390x/s390-virtio-hcall.c | 3 ++-
 target-s390x/kvm.c           | 9 +++++++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-virtio-hcall.c
index 0e328d8..c7bdc20 100644
--- a/hw/s390x/s390-virtio-hcall.c
+++ b/hw/s390x/s390-virtio-hcall.c
@@ -31,7 +31,8 @@ int s390_virtio_hypercall(CPUS390XState *env)
     if (env->regs[1] < MAX_DIAG_SUBCODES) {
         fn = s390_diag500_table[env->regs[1]];
         if (fn) {
-            return fn(&env->regs[2]);
+            env->regs[2] = fn(&env->regs[2]);
+            return 0;
         }
     }
 
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index b93fe84..2fa374a 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -559,11 +559,16 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run,
 static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
 {
     CPUS390XState *env = &cpu->env;
+    int ret;
 
     cpu_synchronize_state(CPU(cpu));
-    env->regs[2] = s390_virtio_hypercall(env);
+    ret = s390_virtio_hypercall(env);
+    if (ret == -EINVAL) {
+        enter_pgmcheck(cpu, PGM_SPECIFICATION);
+        return 0;
+    }
 
-    return 0;
+    return ret;
 }
 
 static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run)
-- 
1.8.4.2


Reply via email to