1*61491cf4SDavid Woodhouse /* 2*61491cf4SDavid Woodhouse * Xen HVM emulation support in KVM 3*61491cf4SDavid Woodhouse * 4*61491cf4SDavid Woodhouse * Copyright © 2019 Oracle and/or its affiliates. All rights reserved. 5*61491cf4SDavid Woodhouse * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. 6*61491cf4SDavid Woodhouse * 7*61491cf4SDavid Woodhouse * This work is licensed under the terms of the GNU GPL, version 2 or later. 8*61491cf4SDavid Woodhouse * See the COPYING file in the top-level directory. 9*61491cf4SDavid Woodhouse * 10*61491cf4SDavid Woodhouse */ 11*61491cf4SDavid Woodhouse 12*61491cf4SDavid Woodhouse #include "qemu/osdep.h" 13*61491cf4SDavid Woodhouse #include "sysemu/kvm_int.h" 14*61491cf4SDavid Woodhouse #include "sysemu/kvm_xen.h" 15*61491cf4SDavid Woodhouse #include "kvm/kvm_i386.h" 16*61491cf4SDavid Woodhouse #include "xen-emu.h" 17*61491cf4SDavid Woodhouse 18*61491cf4SDavid Woodhouse int kvm_xen_init(KVMState *s) 19*61491cf4SDavid Woodhouse { 20*61491cf4SDavid Woodhouse const int required_caps = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR | 21*61491cf4SDavid Woodhouse KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INFO; 22*61491cf4SDavid Woodhouse struct kvm_xen_hvm_config cfg = { 23*61491cf4SDavid Woodhouse .msr = XEN_HYPERCALL_MSR, 24*61491cf4SDavid Woodhouse .flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL, 25*61491cf4SDavid Woodhouse }; 26*61491cf4SDavid Woodhouse int xen_caps, ret; 27*61491cf4SDavid Woodhouse 28*61491cf4SDavid Woodhouse xen_caps = kvm_check_extension(s, KVM_CAP_XEN_HVM); 29*61491cf4SDavid Woodhouse if (required_caps & ~xen_caps) { 30*61491cf4SDavid Woodhouse error_report("kvm: Xen HVM guest support not present or insufficient"); 31*61491cf4SDavid Woodhouse return -ENOSYS; 32*61491cf4SDavid Woodhouse } 33*61491cf4SDavid Woodhouse 34*61491cf4SDavid Woodhouse if (xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_SEND) { 35*61491cf4SDavid Woodhouse struct kvm_xen_hvm_attr ha = { 36*61491cf4SDavid Woodhouse .type = KVM_XEN_ATTR_TYPE_XEN_VERSION, 37*61491cf4SDavid Woodhouse .u.xen_version = s->xen_version, 38*61491cf4SDavid Woodhouse }; 39*61491cf4SDavid Woodhouse (void)kvm_vm_ioctl(s, KVM_XEN_HVM_SET_ATTR, &ha); 40*61491cf4SDavid Woodhouse 41*61491cf4SDavid Woodhouse cfg.flags |= KVM_XEN_HVM_CONFIG_EVTCHN_SEND; 42*61491cf4SDavid Woodhouse } 43*61491cf4SDavid Woodhouse 44*61491cf4SDavid Woodhouse ret = kvm_vm_ioctl(s, KVM_XEN_HVM_CONFIG, &cfg); 45*61491cf4SDavid Woodhouse if (ret < 0) { 46*61491cf4SDavid Woodhouse error_report("kvm: Failed to enable Xen HVM support: %s", 47*61491cf4SDavid Woodhouse strerror(-ret)); 48*61491cf4SDavid Woodhouse return ret; 49*61491cf4SDavid Woodhouse } 50*61491cf4SDavid Woodhouse 51*61491cf4SDavid Woodhouse s->xen_caps = xen_caps; 52*61491cf4SDavid Woodhouse return 0; 53*61491cf4SDavid Woodhouse } 54*61491cf4SDavid Woodhouse 55*61491cf4SDavid Woodhouse uint32_t kvm_xen_get_caps(void) 56*61491cf4SDavid Woodhouse { 57*61491cf4SDavid Woodhouse return kvm_state->xen_caps; 58*61491cf4SDavid Woodhouse } 59