i386/xen: handle guest hypercalls
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> [dwmw2: Add CPL to hypercall tracing, disallow hypercalls from CPL > 0] Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Reviewed-by: Paul Durrant <paul@xen.org>
This commit is contained in:
parent
bb346fae38
commit
55a3f666b4
|
@ -5493,6 +5493,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_EMU
|
||||
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;
|
||||
|
|
|
@ -5,3 +5,6 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %"
|
|||
kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
|
||||
kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
|
||||
kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
|
||||
|
||||
# xen-emu.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%" PRIx64
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "sysemu/kvm_int.h"
|
||||
#include "sysemu/kvm_xen.h"
|
||||
#include "kvm/kvm_i386.h"
|
||||
#include "xen-emu.h"
|
||||
#include "trace.h"
|
||||
|
||||
int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
|
||||
{
|
||||
|
@ -84,3 +86,45 @@ uint32_t kvm_xen_get_caps(void)
|
|||
{
|
||||
return kvm_state->xen_caps;
|
||||
}
|
||||
|
||||
static bool do_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 true;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
|
||||
{
|
||||
if (exit->type != KVM_EXIT_XEN_HCALL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!do_kvm_xen_handle_exit(cpu, exit)) {
|
||||
/*
|
||||
* Some hypercalls will be deliberately "implemented" by returning
|
||||
* -ENOSYS. This case is for hypercalls which are unexpected.
|
||||
*/
|
||||
exit->u.hcall.result = -ENOSYS;
|
||||
qemu_log_mask(LOG_UNIMP, "Unimplemented Xen hypercall %"
|
||||
PRId64 " (0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 ")\n",
|
||||
(uint64_t)exit->u.hcall.input,
|
||||
(uint64_t)exit->u.hcall.params[0],
|
||||
(uint64_t)exit->u.hcall.params[1],
|
||||
(uint64_t)exit->u.hcall.params[2]);
|
||||
}
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
|
|
@ -25,5 +25,6 @@
|
|||
|
||||
int kvm_xen_init(KVMState *s, uint32_t hypercall_msr);
|
||||
int kvm_xen_init_vcpu(CPUState *cs);
|
||||
int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit);
|
||||
|
||||
#endif /* QEMU_I386_KVM_XEN_EMU_H */
|
||||
|
|
Loading…
Reference in New Issue