]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
i386/xen: handle guest hypercalls
authorJoao Martins <joao.m.martins@oracle.com>
Wed, 13 Jun 2018 14:14:31 +0000 (10:14 -0400)
committerJoao Martins <joao.m.martins@oracle.com>
Tue, 19 Feb 2019 14:00:57 +0000 (09:00 -0500)
This means handling the new exit reason for Xen but still
crashing on purpose. As we implement each of the hypercalls
we will then return the right return code.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
linux-headers/linux/kvm.h
target/i386/kvm.c
target/i386/trace-events
target/i386/xen.c
target/i386/xen.h

index b53ee59748027b42ab9dc1b92209dabee0ebfb31..6a7b0a4d98632b86c05e70cc2aa7204c39fb22c2 100644 (file)
@@ -204,6 +204,18 @@ struct kvm_hyperv_exit {
        } u;
 };
 
+struct kvm_xen_exit {
+#define KVM_EXIT_XEN_HCALL             1
+       __u32 type;
+       union {
+               struct {
+                       __u64 input;
+                       __u64 result;
+                       __u64 params[5];
+               } hcall;
+       } u;
+};
+
 #define KVM_S390_GET_SKEYS_NONE   1
 #define KVM_S390_SKEYS_MAX        1048576
 
@@ -235,6 +247,7 @@ struct kvm_hyperv_exit {
 #define KVM_EXIT_S390_STSI        25
 #define KVM_EXIT_IOAPIC_EOI       26
 #define KVM_EXIT_HYPERV           27
+#define KVM_EXIT_XEN              28
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -392,8 +405,9 @@ struct kvm_run {
                } eoi;
                /* KVM_EXIT_HYPERV */
                struct kvm_hyperv_exit hyperv;
+               struct kvm_xen_exit xen;
                /* Fix the size of the union. */
-               char padding[256];
+               char padding[196];
        };
 
        /* 2048 is the size of the char array used to bound/pad the size
index 4eb0629db577b90f77125a24a8d5ddfbdc1525f1..1271e78e61f369d532cfd18909de1c679977c9ba 100644 (file)
@@ -3712,6 +3712,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
         ioapic_eoi_broadcast(run->eoi.vector);
         ret = 0;
         break;
+    case KVM_EXIT_XEN:
+        ret = kvm_xen_handle_exit(cpu, &run->xen);
+        break;
     default:
         fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
         ret = -1;
index 6a19a69af5d0a5bbff1c30047de265732462e231..aa7a5c6a5fb23cf6ff9564f230dfc8be3c378e2e 100644 (file)
@@ -15,3 +15,6 @@ kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session
 kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
 kvm_sev_launch_measurement(const char *value) "data %s"
 kvm_sev_launch_finish(void) ""
+
+# target/i386/xen.c
+kvm_xen_hypercall(int cpu, uint64_t input, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d input %" PRIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIu64
index efd5b91309f37e9c74b315c19ddd5831497a62e1..8a4dd62bfa6becb26d202b7e190e6926f9c8af3e 100644 (file)
 
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
+#include "qemu/log.h"
 #include "linux/kvm.h"
 #include "cpu.h"
 #include "xen.h"
 
+#include "trace.h"
+
+/*
+ * Unhandled hypercalls error:
+ *
+ * -1 crash and dump registers
+ *  0 no abort and guest handles -ENOSYS (default)
+ */
+#ifndef HCALL_ERR
+#define HCALL_ERR      0
+#endif
+
 static void arch_init_hypercall_page(CPUState *cs, void *addr)
 {
     CPUX86State *env = cs->env_ptr;
@@ -61,3 +74,31 @@ int kvm_xen_set_hypercall_page(CPUState *env)
 
     return kvm_vm_ioctl(env->kvm_state, KVM_XEN_HVM_CONFIG, &cfg);
 }
+
+static int __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
+{
+    uint16_t code = exit->u.hcall.input;
+
+    switch (code) {
+    default:
+        exit->u.hcall.result = -ENOSYS;
+        return HCALL_ERR;
+    }
+}
+
+int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
+{
+    int ret = HCALL_ERR;
+
+    switch (exit->type) {
+    case KVM_EXIT_XEN_HCALL: {
+        ret = __kvm_xen_handle_exit(cpu, exit);
+        trace_kvm_xen_hypercall(CPU(cpu)->cpu_index, exit->u.hcall.input,
+                           exit->u.hcall.params[0], exit->u.hcall.params[1],
+                           exit->u.hcall.params[2], exit->u.hcall.result);
+        return ret;
+    }
+    default:
+        return ret;
+    }
+}
index 4512e127000fe1dbb0644f5a89cad757ce097a83..025cab7badad23c2fbb1af13416afef901e886fa 100644 (file)
@@ -22,5 +22,6 @@
 #define XEN_CPUID_HVM              0x40000004
 
 int kvm_xen_set_hypercall_page(CPUState *env);
+int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit);
 
 #endif