From: Joao Martins <joao.m.mart...@oracle.com> 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.mart...@oracle.com> [dwmw2: Add CPL to hypercall tracing, disallow hypercalls from CPL > 0] Signed-off-by: David Woodhouse <d...@amazon.co.uk> --- target/i386/kvm/kvm.c | 5 +++++ target/i386/trace-events | 3 +++ target/i386/xen.c | 45 ++++++++++++++++++++++++++++++++++++++++ target/i386/xen.h | 1 + 4 files changed, 54 insertions(+) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 4b21d03250..6396d11f1e 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -5468,6 +5468,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) assert(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER); ret = kvm_handle_wrmsr(cpu, run); break; +#ifdef CONFIG_XEN + case KVM_EXIT_XEN: + ret = kvm_xen_handle_exit(cpu, &run->xen); + break; +#endif default: fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); ret = -1; diff --git a/target/i386/trace-events b/target/i386/trace-events index 2cd8726eeb..3fb9ee3add 100644 --- a/target/i386/trace-events +++ b/target/i386/trace-events @@ -11,3 +11,6 @@ kvm_sev_launch_measurement(const char *value) "data %s" kvm_sev_launch_finish(void) "" kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" + +# target/i386/xen.c +kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIu64 diff --git a/target/i386/xen.c b/target/i386/xen.c index bc183dce4e..d7e942289c 100644 --- a/target/i386/xen.c +++ b/target/i386/xen.c @@ -12,6 +12,17 @@ #include "qemu/osdep.h" #include "kvm/kvm_i386.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 int kvm_xen_init(KVMState *s, uint32_t xen_version) { @@ -47,3 +58,37 @@ int kvm_xen_init(KVMState *s, uint32_t xen_version) return 0; } + +static int __kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) +{ + uint16_t code = exit->u.hcall.input; + + if (exit->u.hcall.cpl > 0) { + exit->u.hcall.result = -EPERM; + return HCALL_ERR; + } + + 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.cpl, + 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; + } +} diff --git a/target/i386/xen.h b/target/i386/xen.h index d4903ecfa1..3537415d31 100644 --- a/target/i386/xen.h +++ b/target/i386/xen.h @@ -23,5 +23,6 @@ #define XEN_VERSION(maj, min) ((maj) << 16 | (min)) int kvm_xen_init(KVMState *s, uint32_t xen_version); +int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit); #endif /* QEMU_I386_XEN_H */ -- 2.35.3