} 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
#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. */
} 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
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;
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
#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;
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;
+ }
+}
#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