xref: /qemu/target/i386/kvm/xen-emu.c (revision 61491cf4410423b2d3162143c43b9aeb4ccf7f26)
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