/*
 * Xen HVM emulation support in KVM
 *
 * Copyright © 2019 Oracle and/or its affiliates. All rights reserved.
 * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "hw/xen/xen.h"
#include "sysemu/kvm_int.h"
#include "sysemu/kvm_xen.h"
#include "kvm/kvm_i386.h"
#include "exec/address-spaces.h"
#include "xen-emu.h"
#include "trace.h"
#include "sysemu/runstate.h"

#include "hw/pci/msi.h"
#include "hw/i386/apic-msidef.h"
#include "hw/i386/e820_memory_layout.h"
#include "hw/i386/kvm/xen_overlay.h"
#include "hw/i386/kvm/xen_evtchn.h"
#include "hw/i386/kvm/xen_gnttab.h"
#include "hw/i386/kvm/xen_primary_console.h"
#include "hw/i386/kvm/xen_xenstore.h"

#include "hw/xen/interface/version.h"
#include "hw/xen/interface/sched.h"
#include "hw/xen/interface/memory.h"
#include "hw/xen/interface/hvm/hvm_op.h"
#include "hw/xen/interface/hvm/params.h"
#include "hw/xen/interface/vcpu.h"
#include "hw/xen/interface/event_channel.h"
#include "hw/xen/interface/grant_table.h"

#include "xen-compat.h"

static void xen_vcpu_singleshot_timer_event(void *opaque);
static void xen_vcpu_periodic_timer_event(void *opaque);
static int vcpuop_stop_singleshot_timer(CPUState *cs);

#ifdef TARGET_X86_64
#define hypercall_compat32(longmode) (!(longmode))
#else
#define hypercall_compat32(longmode) (false)
#endif

static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
                           size_t *len, bool is_write)
{
        struct kvm_translation tr = {
            .linear_address = gva,
        };

        if (len) {
            *len = TARGET_PAGE_SIZE - (gva & ~TARGET_PAGE_MASK);
        }

        if (kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr) || !tr.valid ||
            (is_write && !tr.writeable)) {
            return false;
        }
        *gpa = tr.physical_address;
        return true;
}

static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz,
                      bool is_write)
{
    uint8_t *buf = (uint8_t *)_buf;
    uint64_t gpa;
    size_t len;

    while (sz) {
        if (!kvm_gva_to_gpa(cs, gva, &gpa, &len, is_write)) {
            return -EFAULT;
        }
        if (len > sz) {
            len = sz;
        }

        cpu_physical_memory_rw(gpa, buf, len, is_write);

        buf += len;
        sz -= len;
        gva += len;
    }

    return 0;
}

static inline int kvm_copy_from_gva(CPUState *cs, uint64_t gva, void *buf,
                                    size_t sz)
{
    return kvm_gva_rw(cs, gva, buf, sz, false);
}

static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf,
                                  size_t sz)
{
    return kvm_gva_rw(cs, gva, buf, sz, true);
}

int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
{
    const int required_caps = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |
        KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INFO;
    struct kvm_xen_hvm_config cfg = {
        .msr = hypercall_msr,
        .flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL,
    };
    int xen_caps, ret;

    xen_caps = kvm_check_extension(s, KVM_CAP_XEN_HVM);
    if (required_caps & ~xen_caps) {
        error_report("kvm: Xen HVM guest support not present or insufficient");
        return -ENOSYS;
    }

    if (xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_SEND) {
        struct kvm_xen_hvm_attr ha = {
            .type = KVM_XEN_ATTR_TYPE_XEN_VERSION,
            .u.xen_version = s->xen_version,
        };
        (void)kvm_vm_ioctl(s, KVM_XEN_HVM_SET_ATTR, &ha);

        cfg.flags |= KVM_XEN_HVM_CONFIG_EVTCHN_SEND;
    }

    ret = kvm_vm_ioctl(s, KVM_XEN_HVM_CONFIG, &cfg);
    if (ret < 0) {
        error_report("kvm: Failed to enable Xen HVM support: %s",
                     strerror(-ret));
        return ret;
    }

    /* If called a second time, don't repeat the rest of the setup. */
    if (s->xen_caps) {
        return 0;
    }

    /*
     * Event channel delivery via GSI/PCI_INTX needs to poll the vcpu_info
     * of vCPU0 to deassert the IRQ when ->evtchn_upcall_pending is cleared.
     *
     * In the kernel, there's a notifier hook on the PIC/IOAPIC which allows
     * such things to be polled at precisely the right time. We *could* do
     * it nicely in the kernel: check vcpu_info[0]->evtchn_upcall_pending at
     * the moment the IRQ is acked, and see if it should be reasserted.
     *
     * But the in-kernel irqchip is deprecated, so we're unlikely to add
     * that support in the kernel. Insist on using the split irqchip mode
     * instead.
     *
     * This leaves us polling for the level going low in QEMU, which lacks
     * the appropriate hooks in its PIC/IOAPIC code. Even VFIO is sending a
     * spurious 'ack' to an INTX IRQ every time there's any MMIO access to
     * the device (for which it has to unmap the device and trap access, for
     * some period after an IRQ!!). In the Xen case, we do it on exit from
     * KVM_RUN, if the flag is set to say that the GSI is currently asserted.
     * Which is kind of icky, but less so than the VFIO one. I may fix them
     * both later...
     */
    if (!kvm_kernel_irqchip_split()) {
        error_report("kvm: Xen support requires kernel-irqchip=split");
        return -EINVAL;
    }

    s->xen_caps = xen_caps;

    /* Tell fw_cfg to notify the BIOS to reserve the range. */
    e820_add_entry(XEN_SPECIAL_AREA_ADDR, XEN_SPECIAL_AREA_SIZE, E820_RESERVED);

    /* The pages couldn't be overlaid until KVM was initialized */
    xen_primary_console_reset();
    xen_xenstore_reset();

    return 0;
}

int kvm_xen_init_vcpu(CPUState *cs)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;
    int err;

    /*
     * The kernel needs to know the Xen/ACPI vCPU ID because that's
     * what the guest uses in hypercalls such as timers. It doesn't
     * match the APIC ID which is generally used for talking to the
     * kernel about vCPUs. And if vCPU threads race with creating
     * their KVM vCPUs out of order, it doesn't necessarily match
     * with the kernel's internal vCPU indices either.
     */
    if (kvm_xen_has_cap(EVTCHN_SEND)) {
        struct kvm_xen_vcpu_attr va = {
            .type = KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID,
            .u.vcpu_id = cs->cpu_index,
        };
        err = kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &va);
        if (err) {
            error_report("kvm: Failed to set Xen vCPU ID attribute: %s",
                         strerror(-err));
            return err;
        }
    }

    env->xen_vcpu_info_gpa = INVALID_GPA;
    env->xen_vcpu_info_default_gpa = INVALID_GPA;
    env->xen_vcpu_time_info_gpa = INVALID_GPA;
    env->xen_vcpu_runstate_gpa = INVALID_GPA;

    qemu_mutex_init(&env->xen_timers_lock);
    env->xen_singleshot_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                             xen_vcpu_singleshot_timer_event,
                                             cpu);
    if (!env->xen_singleshot_timer) {
        return -ENOMEM;
    }
    env->xen_singleshot_timer->opaque = cs;

    env->xen_periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                           xen_vcpu_periodic_timer_event,
                                           cpu);
    if (!env->xen_periodic_timer) {
        return -ENOMEM;
    }
    env->xen_periodic_timer->opaque = cs;

    return 0;
}

uint32_t kvm_xen_get_caps(void)
{
    return kvm_state->xen_caps;
}

static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit *exit, X86CPU *cpu,
                                     int cmd, uint64_t arg)
{
    int err = 0;

    switch (cmd) {
    case XENVER_get_features: {
        struct xen_feature_info fi;

        /* No need for 32/64 compat handling */
        qemu_build_assert(sizeof(fi) == 8);

        err = kvm_copy_from_gva(CPU(cpu), arg, &fi, sizeof(fi));
        if (err) {
            break;
        }

        fi.submap = 0;
        if (fi.submap_idx == 0) {
            fi.submap |= 1 << XENFEAT_writable_page_tables |
                         1 << XENFEAT_writable_descriptor_tables |
                         1 << XENFEAT_auto_translated_physmap |
                         1 << XENFEAT_hvm_callback_vector |
                         1 << XENFEAT_hvm_safe_pvclock |
                         1 << XENFEAT_hvm_pirqs;
        }

        err = kvm_copy_to_gva(CPU(cpu), arg, &fi, sizeof(fi));
        break;
    }

    default:
        return false;
    }

    exit->u.hcall.result = err;
    return true;
}

static int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa)
{
    struct kvm_xen_vcpu_attr xhsi;

    xhsi.type = type;
    xhsi.u.gpa = gpa;

    trace_kvm_xen_set_vcpu_attr(cs->cpu_index, type, gpa);

    return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi);
}

static int kvm_xen_set_vcpu_callback_vector(CPUState *cs)
{
    uint8_t vector = X86_CPU(cs)->env.xen_vcpu_callback_vector;
    struct kvm_xen_vcpu_attr xva;

    xva.type = KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR;
    xva.u.vector = vector;

    trace_kvm_xen_set_vcpu_callback(cs->cpu_index, vector);

    return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xva);
}

static void do_set_vcpu_callback_vector(CPUState *cs, run_on_cpu_data data)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    env->xen_vcpu_callback_vector = data.host_int;

    if (kvm_xen_has_cap(EVTCHN_SEND)) {
        kvm_xen_set_vcpu_callback_vector(cs);
    }
}

static int set_vcpu_info(CPUState *cs, uint64_t gpa)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;
    MemoryRegionSection mrs = { .mr = NULL };
    void *vcpu_info_hva = NULL;
    int ret;

    ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, gpa);
    if (ret || gpa == INVALID_GPA) {
        goto out;
    }

    mrs = memory_region_find(get_system_memory(), gpa,
                             sizeof(struct vcpu_info));
    if (mrs.mr && mrs.mr->ram_block &&
        !int128_lt(mrs.size, int128_make64(sizeof(struct vcpu_info)))) {
        vcpu_info_hva = qemu_map_ram_ptr(mrs.mr->ram_block,
                                         mrs.offset_within_region);
    }
    if (!vcpu_info_hva) {
        if (mrs.mr) {
            memory_region_unref(mrs.mr);
            mrs.mr = NULL;
        }
        ret = -EINVAL;
    }

 out:
    if (env->xen_vcpu_info_mr) {
        memory_region_unref(env->xen_vcpu_info_mr);
    }
    env->xen_vcpu_info_hva = vcpu_info_hva;
    env->xen_vcpu_info_mr = mrs.mr;
    return ret;
}

static void do_set_vcpu_info_default_gpa(CPUState *cs, run_on_cpu_data data)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    env->xen_vcpu_info_default_gpa = data.host_ulong;

    /* Changing the default does nothing if a vcpu_info was explicitly set. */
    if (env->xen_vcpu_info_gpa == INVALID_GPA) {
        set_vcpu_info(cs, env->xen_vcpu_info_default_gpa);
    }
}

static void do_set_vcpu_info_gpa(CPUState *cs, run_on_cpu_data data)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    env->xen_vcpu_info_gpa = data.host_ulong;

    set_vcpu_info(cs, env->xen_vcpu_info_gpa);
}

void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id)
{
    CPUState *cs = qemu_get_cpu(vcpu_id);
    if (!cs) {
        return NULL;
    }

    return X86_CPU(cs)->env.xen_vcpu_info_hva;
}

void kvm_xen_maybe_deassert_callback(CPUState *cs)
{
    CPUX86State *env = &X86_CPU(cs)->env;
    struct vcpu_info *vi = env->xen_vcpu_info_hva;
    if (!vi) {
        return;
    }

    /* If the evtchn_upcall_pending flag is cleared, turn the GSI off. */
    if (!vi->evtchn_upcall_pending) {
        bql_lock();
        /*
         * Check again now we have the lock, because it may have been
         * asserted in the interim. And we don't want to take the lock
         * every time because this is a fast path.
         */
        if (!vi->evtchn_upcall_pending) {
            X86_CPU(cs)->env.xen_callback_asserted = false;
            xen_evtchn_set_callback_level(0);
        }
        bql_unlock();
    }
}

void kvm_xen_set_callback_asserted(void)
{
    CPUState *cs = qemu_get_cpu(0);

    if (cs) {
        X86_CPU(cs)->env.xen_callback_asserted = true;
    }
}

bool kvm_xen_has_vcpu_callback_vector(void)
{
    CPUState *cs = qemu_get_cpu(0);

    return cs && !!X86_CPU(cs)->env.xen_vcpu_callback_vector;
}

void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type)
{
    CPUState *cs = qemu_get_cpu(vcpu_id);
    uint8_t vector;

    if (!cs) {
        return;
    }

    vector = X86_CPU(cs)->env.xen_vcpu_callback_vector;
    if (vector) {
        /*
         * The per-vCPU callback vector injected via lapic. Just
         * deliver it as an MSI.
         */
        MSIMessage msg = {
            .address = APIC_DEFAULT_ADDRESS |
                       (X86_CPU(cs)->apic_id << MSI_ADDR_DEST_ID_SHIFT),
            .data = vector | (1UL << MSI_DATA_LEVEL_SHIFT),
        };
        kvm_irqchip_send_msi(kvm_state, msg);
        return;
    }

    switch (type) {
    case HVM_PARAM_CALLBACK_TYPE_VECTOR:
        /*
         * If the evtchn_upcall_pending field in the vcpu_info is set, then
         * KVM will automatically deliver the vector on entering the vCPU
         * so all we have to do is kick it out.
         */
        qemu_cpu_kick(cs);
        break;

    case HVM_PARAM_CALLBACK_TYPE_GSI:
    case HVM_PARAM_CALLBACK_TYPE_PCI_INTX:
        if (vcpu_id == 0) {
            xen_evtchn_set_callback_level(1);
        }
        break;
    }
}

/* Must always be called with xen_timers_lock held */
static int kvm_xen_set_vcpu_timer(CPUState *cs)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    struct kvm_xen_vcpu_attr va = {
        .type = KVM_XEN_VCPU_ATTR_TYPE_TIMER,
        .u.timer.port = env->xen_virq[VIRQ_TIMER],
        .u.timer.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL,
        .u.timer.expires_ns = env->xen_singleshot_timer_ns,
    };

    return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &va);
}

static void do_set_vcpu_timer_virq(CPUState *cs, run_on_cpu_data data)
{
    QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock);
    kvm_xen_set_vcpu_timer(cs);
}

int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port)
{
    CPUState *cs = qemu_get_cpu(vcpu_id);

    if (!cs) {
        return -ENOENT;
    }

    /* cpu.h doesn't include the actual Xen header. */
    qemu_build_assert(NR_VIRQS == XEN_NR_VIRQS);

    if (virq >= NR_VIRQS) {
        return -EINVAL;
    }

    if (port && X86_CPU(cs)->env.xen_virq[virq]) {
        return -EEXIST;
    }

    X86_CPU(cs)->env.xen_virq[virq] = port;
    if (virq == VIRQ_TIMER && kvm_xen_has_cap(EVTCHN_SEND)) {
        async_run_on_cpu(cs, do_set_vcpu_timer_virq,
                         RUN_ON_CPU_HOST_INT(port));
    }
    return 0;
}

static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    env->xen_vcpu_time_info_gpa = data.host_ulong;

    kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO,
                          env->xen_vcpu_time_info_gpa);
}

static void do_set_vcpu_runstate_gpa(CPUState *cs, run_on_cpu_data data)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    env->xen_vcpu_runstate_gpa = data.host_ulong;

    kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,
                          env->xen_vcpu_runstate_gpa);
}

static void do_vcpu_soft_reset(CPUState *cs, run_on_cpu_data data)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    env->xen_vcpu_info_gpa = INVALID_GPA;
    env->xen_vcpu_info_default_gpa = INVALID_GPA;
    env->xen_vcpu_time_info_gpa = INVALID_GPA;
    env->xen_vcpu_runstate_gpa = INVALID_GPA;
    env->xen_vcpu_callback_vector = 0;
    memset(env->xen_virq, 0, sizeof(env->xen_virq));

    set_vcpu_info(cs, INVALID_GPA);
    kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO,
                          INVALID_GPA);
    kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,
                          INVALID_GPA);
    if (kvm_xen_has_cap(EVTCHN_SEND)) {
        kvm_xen_set_vcpu_callback_vector(cs);

        QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock);
        env->xen_singleshot_timer_ns = 0;
        kvm_xen_set_vcpu_timer(cs);
    } else {
        vcpuop_stop_singleshot_timer(cs);
    };

}

static int xen_set_shared_info(uint64_t gfn)
{
    uint64_t gpa = gfn << TARGET_PAGE_BITS;
    int i, err;

    BQL_LOCK_GUARD();

    /*
     * The xen_overlay device tells KVM about it too, since it had to
     * do that on migration load anyway (unless we're going to jump
     * through lots of hoops to maintain the fiction that this isn't
     * KVM-specific.
     */
    err = xen_overlay_map_shinfo_page(gpa);
    if (err) {
            return err;
    }

    trace_kvm_xen_set_shared_info(gfn);

    for (i = 0; i < XEN_LEGACY_MAX_VCPUS; i++) {
        CPUState *cpu = qemu_get_cpu(i);
        if (cpu) {
            async_run_on_cpu(cpu, do_set_vcpu_info_default_gpa,
                             RUN_ON_CPU_HOST_ULONG(gpa));
        }
        gpa += sizeof(vcpu_info_t);
    }

    return err;
}

static int add_to_physmap_one(uint32_t space, uint64_t idx, uint64_t gfn)
{
    switch (space) {
    case XENMAPSPACE_shared_info:
        if (idx > 0) {
            return -EINVAL;
        }
        return xen_set_shared_info(gfn);

    case XENMAPSPACE_grant_table:
        return xen_gnttab_map_page(idx, gfn);

    case XENMAPSPACE_gmfn:
    case XENMAPSPACE_gmfn_range:
        return -ENOTSUP;

    case XENMAPSPACE_gmfn_foreign:
    case XENMAPSPACE_dev_mmio:
        return -EPERM;

    default:
        return -EINVAL;
    }
}

static int do_add_to_physmap(struct kvm_xen_exit *exit, X86CPU *cpu,
                             uint64_t arg)
{
    struct xen_add_to_physmap xatp;
    CPUState *cs = CPU(cpu);

    if (hypercall_compat32(exit->u.hcall.longmode)) {
        struct compat_xen_add_to_physmap xatp32;

        qemu_build_assert(sizeof(struct compat_xen_add_to_physmap) == 16);
        if (kvm_copy_from_gva(cs, arg, &xatp32, sizeof(xatp32))) {
            return -EFAULT;
        }
        xatp.domid = xatp32.domid;
        xatp.size = xatp32.size;
        xatp.space = xatp32.space;
        xatp.idx = xatp32.idx;
        xatp.gpfn = xatp32.gpfn;
    } else {
        if (kvm_copy_from_gva(cs, arg, &xatp, sizeof(xatp))) {
            return -EFAULT;
        }
    }

    if (xatp.domid != DOMID_SELF && xatp.domid != xen_domid) {
        return -ESRCH;
    }

    return add_to_physmap_one(xatp.space, xatp.idx, xatp.gpfn);
}

static int do_add_to_physmap_batch(struct kvm_xen_exit *exit, X86CPU *cpu,
                                   uint64_t arg)
{
    struct xen_add_to_physmap_batch xatpb;
    unsigned long idxs_gva, gpfns_gva, errs_gva;
    CPUState *cs = CPU(cpu);
    size_t op_sz;

    if (hypercall_compat32(exit->u.hcall.longmode)) {
        struct compat_xen_add_to_physmap_batch xatpb32;

        qemu_build_assert(sizeof(struct compat_xen_add_to_physmap_batch) == 20);
        if (kvm_copy_from_gva(cs, arg, &xatpb32, sizeof(xatpb32))) {
            return -EFAULT;
        }
        xatpb.domid = xatpb32.domid;
        xatpb.space = xatpb32.space;
        xatpb.size = xatpb32.size;

        idxs_gva = xatpb32.idxs.c;
        gpfns_gva = xatpb32.gpfns.c;
        errs_gva = xatpb32.errs.c;
        op_sz = sizeof(uint32_t);
    } else {
        if (kvm_copy_from_gva(cs, arg, &xatpb, sizeof(xatpb))) {
            return -EFAULT;
        }
        op_sz = sizeof(unsigned long);
        idxs_gva = (unsigned long)xatpb.idxs.p;
        gpfns_gva = (unsigned long)xatpb.gpfns.p;
        errs_gva = (unsigned long)xatpb.errs.p;
    }

    if (xatpb.domid != DOMID_SELF && xatpb.domid != xen_domid) {
        return -ESRCH;
    }

    /* Explicitly invalid for the batch op. Not that we implement it anyway. */
    if (xatpb.space == XENMAPSPACE_gmfn_range) {
        return -EINVAL;
    }

    while (xatpb.size--) {
        unsigned long idx = 0;
        unsigned long gpfn = 0;
        int err;

        /* For 32-bit compat this only copies the low 32 bits of each */
        if (kvm_copy_from_gva(cs, idxs_gva, &idx, op_sz) ||
            kvm_copy_from_gva(cs, gpfns_gva, &gpfn, op_sz)) {
            return -EFAULT;
        }
        idxs_gva += op_sz;
        gpfns_gva += op_sz;

        err = add_to_physmap_one(xatpb.space, idx, gpfn);

        if (kvm_copy_to_gva(cs, errs_gva, &err, sizeof(err))) {
            return -EFAULT;
        }
        errs_gva += sizeof(err);
    }
    return 0;
}

static bool kvm_xen_hcall_memory_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                   int cmd, uint64_t arg)
{
    int err;

    switch (cmd) {
    case XENMEM_add_to_physmap:
        err = do_add_to_physmap(exit, cpu, arg);
        break;

    case XENMEM_add_to_physmap_batch:
        err = do_add_to_physmap_batch(exit, cpu, arg);
        break;

    default:
        return false;
    }

    exit->u.hcall.result = err;
    return true;
}

static bool handle_set_param(struct kvm_xen_exit *exit, X86CPU *cpu,
                             uint64_t arg)
{
    CPUState *cs = CPU(cpu);
    struct xen_hvm_param hp;
    int err = 0;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(hp) == 16);

    if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) {
        err = -EFAULT;
        goto out;
    }

    if (hp.domid != DOMID_SELF && hp.domid != xen_domid) {
        err = -ESRCH;
        goto out;
    }

    switch (hp.index) {
    case HVM_PARAM_CALLBACK_IRQ:
        bql_lock();
        err = xen_evtchn_set_callback_param(hp.value);
        bql_unlock();
        xen_set_long_mode(exit->u.hcall.longmode);
        break;
    default:
        return false;
    }

out:
    exit->u.hcall.result = err;
    return true;
}

static bool handle_get_param(struct kvm_xen_exit *exit, X86CPU *cpu,
                             uint64_t arg)
{
    CPUState *cs = CPU(cpu);
    struct xen_hvm_param hp;
    int err = 0;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(hp) == 16);

    if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) {
        err = -EFAULT;
        goto out;
    }

    if (hp.domid != DOMID_SELF && hp.domid != xen_domid) {
        err = -ESRCH;
        goto out;
    }

    switch (hp.index) {
    case HVM_PARAM_STORE_PFN:
        hp.value = XEN_SPECIAL_PFN(XENSTORE);
        break;
    case HVM_PARAM_STORE_EVTCHN:
        hp.value = xen_xenstore_get_port();
        break;
    case HVM_PARAM_CONSOLE_PFN:
        hp.value = xen_primary_console_get_pfn();
        if (!hp.value) {
            err = -EINVAL;
        }
        break;
    case HVM_PARAM_CONSOLE_EVTCHN:
        hp.value = xen_primary_console_get_port();
        if (!hp.value) {
            err = -EINVAL;
        }
        break;
    default:
        return false;
    }

    if (!err && kvm_copy_to_gva(cs, arg, &hp, sizeof(hp))) {
        err = -EFAULT;
    }
out:
    exit->u.hcall.result = err;
    return true;
}

static int kvm_xen_hcall_evtchn_upcall_vector(struct kvm_xen_exit *exit,
                                              X86CPU *cpu, uint64_t arg)
{
    struct xen_hvm_evtchn_upcall_vector up;
    CPUState *target_cs;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(up) == 8);

    if (kvm_copy_from_gva(CPU(cpu), arg, &up, sizeof(up))) {
        return -EFAULT;
    }

    if (up.vector < 0x10) {
        return -EINVAL;
    }

    target_cs = qemu_get_cpu(up.vcpu);
    if (!target_cs) {
        return -EINVAL;
    }

    async_run_on_cpu(target_cs, do_set_vcpu_callback_vector,
                     RUN_ON_CPU_HOST_INT(up.vector));
    return 0;
}

static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                 int cmd, uint64_t arg)
{
    int ret = -ENOSYS;
    switch (cmd) {
    case HVMOP_set_evtchn_upcall_vector:
        ret = kvm_xen_hcall_evtchn_upcall_vector(exit, cpu, arg);
        break;

    case HVMOP_pagetable_dying:
        ret = -ENOSYS;
        break;

    case HVMOP_set_param:
        return handle_set_param(exit, cpu, arg);

    case HVMOP_get_param:
        return handle_get_param(exit, cpu, arg);

    default:
        return false;
    }

    exit->u.hcall.result = ret;
    return true;
}

static int vcpuop_register_vcpu_info(CPUState *cs, CPUState *target,
                                     uint64_t arg)
{
    struct vcpu_register_vcpu_info rvi;
    uint64_t gpa;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(rvi) == 16);
    qemu_build_assert(sizeof(struct vcpu_info) == 64);

    if (!target) {
        return -ENOENT;
    }

    if (kvm_copy_from_gva(cs, arg, &rvi, sizeof(rvi))) {
        return -EFAULT;
    }

    if (rvi.offset > TARGET_PAGE_SIZE - sizeof(struct vcpu_info)) {
        return -EINVAL;
    }

    gpa = ((rvi.mfn << TARGET_PAGE_BITS) + rvi.offset);
    async_run_on_cpu(target, do_set_vcpu_info_gpa, RUN_ON_CPU_HOST_ULONG(gpa));
    return 0;
}

static int vcpuop_register_vcpu_time_info(CPUState *cs, CPUState *target,
                                          uint64_t arg)
{
    struct vcpu_register_time_memory_area tma;
    uint64_t gpa;
    size_t len;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(tma) == 8);
    qemu_build_assert(sizeof(struct vcpu_time_info) == 32);

    if (!target) {
        return -ENOENT;
    }

    if (kvm_copy_from_gva(cs, arg, &tma, sizeof(tma))) {
        return -EFAULT;
    }

    /*
     * Xen actually uses the GVA and does the translation through the guest
     * page tables each time. But Linux/KVM uses the GPA, on the assumption
     * that guests only ever use *global* addresses (kernel virtual addresses)
     * for it. If Linux is changed to redo the GVA→GPA translation each time,
     * it will offer a new vCPU attribute for that, and we'll use it instead.
     */
    if (!kvm_gva_to_gpa(cs, tma.addr.p, &gpa, &len, false) ||
        len < sizeof(struct vcpu_time_info)) {
        return -EFAULT;
    }

    async_run_on_cpu(target, do_set_vcpu_time_info_gpa,
                     RUN_ON_CPU_HOST_ULONG(gpa));
    return 0;
}

static int vcpuop_register_runstate_info(CPUState *cs, CPUState *target,
                                         uint64_t arg)
{
    struct vcpu_register_runstate_memory_area rma;
    uint64_t gpa;
    size_t len;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(rma) == 8);
    /* The runstate area actually does change size, but Linux copes. */

    if (!target) {
        return -ENOENT;
    }

    if (kvm_copy_from_gva(cs, arg, &rma, sizeof(rma))) {
        return -EFAULT;
    }

    /* As with vcpu_time_info, Xen actually uses the GVA but KVM doesn't. */
    if (!kvm_gva_to_gpa(cs, rma.addr.p, &gpa, &len, false)) {
        return -EFAULT;
    }

    async_run_on_cpu(target, do_set_vcpu_runstate_gpa,
                     RUN_ON_CPU_HOST_ULONG(gpa));
    return 0;
}

static uint64_t kvm_get_current_ns(void)
{
    struct kvm_clock_data data;
    int ret;

    ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
    if (ret < 0) {
        fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
                abort();
    }

    return data.clock;
}

static void xen_vcpu_singleshot_timer_event(void *opaque)
{
    CPUState *cpu = opaque;
    CPUX86State *env = &X86_CPU(cpu)->env;
    uint16_t port = env->xen_virq[VIRQ_TIMER];

    if (likely(port)) {
        xen_evtchn_set_port(port);
    }

    qemu_mutex_lock(&env->xen_timers_lock);
    env->xen_singleshot_timer_ns = 0;
    qemu_mutex_unlock(&env->xen_timers_lock);
}

static void xen_vcpu_periodic_timer_event(void *opaque)
{
    CPUState *cpu = opaque;
    CPUX86State *env = &X86_CPU(cpu)->env;
    uint16_t port = env->xen_virq[VIRQ_TIMER];
    int64_t qemu_now;

    if (likely(port)) {
        xen_evtchn_set_port(port);
    }

    qemu_mutex_lock(&env->xen_timers_lock);

    qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    timer_mod_ns(env->xen_periodic_timer,
                 qemu_now + env->xen_periodic_timer_period);

    qemu_mutex_unlock(&env->xen_timers_lock);
}

static int do_set_periodic_timer(CPUState *target, uint64_t period_ns)
{
    CPUX86State *tenv = &X86_CPU(target)->env;
    int64_t qemu_now;

    timer_del(tenv->xen_periodic_timer);

    qemu_mutex_lock(&tenv->xen_timers_lock);

    qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    timer_mod_ns(tenv->xen_periodic_timer, qemu_now + period_ns);
    tenv->xen_periodic_timer_period = period_ns;

    qemu_mutex_unlock(&tenv->xen_timers_lock);
    return 0;
}

#define MILLISECS(_ms)  ((int64_t)((_ms) * 1000000ULL))
#define MICROSECS(_us)  ((int64_t)((_us) * 1000ULL))
#define STIME_MAX ((time_t)((int64_t)~0ull >> 1))
/* Chosen so (NOW() + delta) won't overflow without an uptime of 200 years */
#define STIME_DELTA_MAX ((int64_t)((uint64_t)~0ull >> 2))

static int vcpuop_set_periodic_timer(CPUState *cs, CPUState *target,
                                     uint64_t arg)
{
    struct vcpu_set_periodic_timer spt;

    qemu_build_assert(sizeof(spt) == 8);
    if (kvm_copy_from_gva(cs, arg, &spt, sizeof(spt))) {
        return -EFAULT;
    }

    if (spt.period_ns < MILLISECS(1) || spt.period_ns > STIME_DELTA_MAX) {
        return -EINVAL;
    }

    return do_set_periodic_timer(target, spt.period_ns);
}

static int vcpuop_stop_periodic_timer(CPUState *target)
{
    CPUX86State *tenv = &X86_CPU(target)->env;

    qemu_mutex_lock(&tenv->xen_timers_lock);

    timer_del(tenv->xen_periodic_timer);
    tenv->xen_periodic_timer_period = 0;

    qemu_mutex_unlock(&tenv->xen_timers_lock);
    return 0;
}

/*
 * Userspace handling of timer, for older kernels.
 * Must always be called with xen_timers_lock held.
 */
static int do_set_singleshot_timer(CPUState *cs, uint64_t timeout_abs,
                                   bool linux_wa)
{
    CPUX86State *env = &X86_CPU(cs)->env;
    int64_t now = kvm_get_current_ns();
    int64_t qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    int64_t delta = timeout_abs - now;

    if (linux_wa && unlikely((int64_t)timeout_abs < 0 ||
                             (delta > 0 && (uint32_t)(delta >> 50) != 0))) {
        /*
         * Xen has a 'Linux workaround' in do_set_timer_op() which checks
         * for negative absolute timeout values (caused by integer
         * overflow), and for values about 13 days in the future (2^50ns)
         * which would be caused by jiffies overflow. For those cases, it
         * sets the timeout 100ms in the future (not *too* soon, since if
         * a guest really did set a long timeout on purpose we don't want
         * to keep churning CPU time by waking it up).
         */
        delta = (100 * SCALE_MS);
        timeout_abs = now + delta;
    }

    timer_mod_ns(env->xen_singleshot_timer, qemu_now + delta);
    env->xen_singleshot_timer_ns = now + delta;
    return 0;
}

static int vcpuop_set_singleshot_timer(CPUState *cs, uint64_t arg)
{
    struct vcpu_set_singleshot_timer sst = { 0 };

    /*
     * The struct is a uint64_t followed by a uint32_t. On 32-bit that
     * makes it 12 bytes. On 64-bit it gets padded to 16. The parts
     * that get used are identical, and there's four bytes of padding
     * unused at the end. For true Xen compatibility we should attempt
     * to copy the full 16 bytes from 64-bit guests, and return -EFAULT
     * if we can't get the padding too. But that's daft. Just copy what
     * we need.
     */
    qemu_build_assert(offsetof(struct vcpu_set_singleshot_timer, flags) == 8);
    qemu_build_assert(sizeof(sst) >= 12);

    if (kvm_copy_from_gva(cs, arg, &sst, 12)) {
        return -EFAULT;
    }

    QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock);

    /*
     * We ignore the VCPU_SSHOTTMR_future flag, just as Xen now does.
     * The only guest that ever used it, got it wrong.
     * https://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=19c6cbd909
     */
    return do_set_singleshot_timer(cs, sst.timeout_abs_ns, false);
}

static int vcpuop_stop_singleshot_timer(CPUState *cs)
{
    CPUX86State *env = &X86_CPU(cs)->env;

    qemu_mutex_lock(&env->xen_timers_lock);

    timer_del(env->xen_singleshot_timer);
    env->xen_singleshot_timer_ns = 0;

    qemu_mutex_unlock(&env->xen_timers_lock);
    return 0;
}

static bool kvm_xen_hcall_set_timer_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                       uint64_t timeout)
{
    int err;

    if (unlikely(timeout == 0)) {
        err = vcpuop_stop_singleshot_timer(CPU(cpu));
    } else {
        QEMU_LOCK_GUARD(&X86_CPU(cpu)->env.xen_timers_lock);
        err = do_set_singleshot_timer(CPU(cpu), timeout, true);
    }
    exit->u.hcall.result = err;
    return true;
}

static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                  int cmd, int vcpu_id, uint64_t arg)
{
    CPUState *cs = CPU(cpu);
    CPUState *dest = cs->cpu_index == vcpu_id ? cs : qemu_get_cpu(vcpu_id);
    int err;

    if (!dest) {
        err = -ENOENT;
        goto out;
    }

    switch (cmd) {
    case VCPUOP_register_runstate_memory_area:
        err = vcpuop_register_runstate_info(cs, dest, arg);
        break;
    case VCPUOP_register_vcpu_time_memory_area:
        err = vcpuop_register_vcpu_time_info(cs, dest, arg);
        break;
    case VCPUOP_register_vcpu_info:
        err = vcpuop_register_vcpu_info(cs, dest, arg);
        break;
    case VCPUOP_set_singleshot_timer: {
        if (cs->cpu_index == vcpu_id) {
            err = vcpuop_set_singleshot_timer(dest, arg);
        } else {
            err = -EINVAL;
        }
        break;
    }
    case VCPUOP_stop_singleshot_timer:
        if (cs->cpu_index == vcpu_id) {
            err = vcpuop_stop_singleshot_timer(dest);
        } else {
            err = -EINVAL;
        }
        break;
    case VCPUOP_set_periodic_timer: {
        err = vcpuop_set_periodic_timer(cs, dest, arg);
        break;
    }
    case VCPUOP_stop_periodic_timer:
        err = vcpuop_stop_periodic_timer(dest);
        break;

    default:
        return false;
    }

 out:
    exit->u.hcall.result = err;
    return true;
}

static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                    int cmd, uint64_t arg)
{
    CPUState *cs = CPU(cpu);
    int err = -ENOSYS;

    switch (cmd) {
    case EVTCHNOP_init_control:
    case EVTCHNOP_expand_array:
    case EVTCHNOP_set_priority:
        /* We do not support FIFO channels at this point */
        err = -ENOSYS;
        break;

    case EVTCHNOP_status: {
        struct evtchn_status status;

        qemu_build_assert(sizeof(status) == 24);
        if (kvm_copy_from_gva(cs, arg, &status, sizeof(status))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_status_op(&status);
        if (!err && kvm_copy_to_gva(cs, arg, &status, sizeof(status))) {
            err = -EFAULT;
        }
        break;
    }
    case EVTCHNOP_close: {
        struct evtchn_close close;

        qemu_build_assert(sizeof(close) == 4);
        if (kvm_copy_from_gva(cs, arg, &close, sizeof(close))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_close_op(&close);
        break;
    }
    case EVTCHNOP_unmask: {
        struct evtchn_unmask unmask;

        qemu_build_assert(sizeof(unmask) == 4);
        if (kvm_copy_from_gva(cs, arg, &unmask, sizeof(unmask))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_unmask_op(&unmask);
        break;
    }
    case EVTCHNOP_bind_virq: {
        struct evtchn_bind_virq virq;

        qemu_build_assert(sizeof(virq) == 12);
        if (kvm_copy_from_gva(cs, arg, &virq, sizeof(virq))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_bind_virq_op(&virq);
        if (!err && kvm_copy_to_gva(cs, arg, &virq, sizeof(virq))) {
            err = -EFAULT;
        }
        break;
    }
    case EVTCHNOP_bind_pirq: {
        struct evtchn_bind_pirq pirq;

        qemu_build_assert(sizeof(pirq) == 12);
        if (kvm_copy_from_gva(cs, arg, &pirq, sizeof(pirq))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_bind_pirq_op(&pirq);
        if (!err && kvm_copy_to_gva(cs, arg, &pirq, sizeof(pirq))) {
            err = -EFAULT;
        }
        break;
    }
    case EVTCHNOP_bind_ipi: {
        struct evtchn_bind_ipi ipi;

        qemu_build_assert(sizeof(ipi) == 8);
        if (kvm_copy_from_gva(cs, arg, &ipi, sizeof(ipi))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_bind_ipi_op(&ipi);
        if (!err && kvm_copy_to_gva(cs, arg, &ipi, sizeof(ipi))) {
            err = -EFAULT;
        }
        break;
    }
    case EVTCHNOP_send: {
        struct evtchn_send send;

        qemu_build_assert(sizeof(send) == 4);
        if (kvm_copy_from_gva(cs, arg, &send, sizeof(send))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_send_op(&send);
        break;
    }
    case EVTCHNOP_alloc_unbound: {
        struct evtchn_alloc_unbound alloc;

        qemu_build_assert(sizeof(alloc) == 8);
        if (kvm_copy_from_gva(cs, arg, &alloc, sizeof(alloc))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_alloc_unbound_op(&alloc);
        if (!err && kvm_copy_to_gva(cs, arg, &alloc, sizeof(alloc))) {
            err = -EFAULT;
        }
        break;
    }
    case EVTCHNOP_bind_interdomain: {
        struct evtchn_bind_interdomain interdomain;

        qemu_build_assert(sizeof(interdomain) == 12);
        if (kvm_copy_from_gva(cs, arg, &interdomain, sizeof(interdomain))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_bind_interdomain_op(&interdomain);
        if (!err &&
            kvm_copy_to_gva(cs, arg, &interdomain, sizeof(interdomain))) {
            err = -EFAULT;
        }
        break;
    }
    case EVTCHNOP_bind_vcpu: {
        struct evtchn_bind_vcpu vcpu;

        qemu_build_assert(sizeof(vcpu) == 8);
        if (kvm_copy_from_gva(cs, arg, &vcpu, sizeof(vcpu))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_bind_vcpu_op(&vcpu);
        break;
    }
    case EVTCHNOP_reset: {
        struct evtchn_reset reset;

        qemu_build_assert(sizeof(reset) == 2);
        if (kvm_copy_from_gva(cs, arg, &reset, sizeof(reset))) {
            err = -EFAULT;
            break;
        }

        err = xen_evtchn_reset_op(&reset);
        break;
    }
    default:
        return false;
    }

    exit->u.hcall.result = err;
    return true;
}

int kvm_xen_soft_reset(void)
{
    CPUState *cpu;
    int err;

    assert(bql_locked());

    trace_kvm_xen_soft_reset();

    err = xen_evtchn_soft_reset();
    if (err) {
        return err;
    }

    /*
     * Zero is the reset/startup state for HVM_PARAM_CALLBACK_IRQ. Strictly,
     * it maps to HVM_PARAM_CALLBACK_TYPE_GSI with GSI#0, but Xen refuses to
     * to deliver to the timer interrupt and treats that as 'disabled'.
     */
    err = xen_evtchn_set_callback_param(0);
    if (err) {
        return err;
    }

    CPU_FOREACH(cpu) {
        async_run_on_cpu(cpu, do_vcpu_soft_reset, RUN_ON_CPU_NULL);
    }

    err = xen_overlay_map_shinfo_page(INVALID_GFN);
    if (err) {
        return err;
    }

    err = xen_gnttab_reset();
    if (err) {
        return err;
    }

    err = xen_primary_console_reset();
    if (err) {
        return err;
    }

    err = xen_xenstore_reset();
    if (err) {
        return err;
    }

    return 0;
}

static int schedop_shutdown(CPUState *cs, uint64_t arg)
{
    struct sched_shutdown shutdown;
    int ret = 0;

    /* No need for 32/64 compat handling */
    qemu_build_assert(sizeof(shutdown) == 4);

    if (kvm_copy_from_gva(cs, arg, &shutdown, sizeof(shutdown))) {
        return -EFAULT;
    }

    switch (shutdown.reason) {
    case SHUTDOWN_crash:
        cpu_dump_state(cs, stderr, CPU_DUMP_CODE);
        qemu_system_guest_panicked(NULL);
        break;

    case SHUTDOWN_reboot:
        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
        break;

    case SHUTDOWN_poweroff:
        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
        break;

    case SHUTDOWN_soft_reset:
        bql_lock();
        ret = kvm_xen_soft_reset();
        bql_unlock();
        break;

    default:
        ret = -EINVAL;
        break;
    }

    return ret;
}

static bool kvm_xen_hcall_sched_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                   int cmd, uint64_t arg)
{
    CPUState *cs = CPU(cpu);
    int err = -ENOSYS;

    switch (cmd) {
    case SCHEDOP_shutdown:
        err = schedop_shutdown(cs, arg);
        break;

    case SCHEDOP_poll:
        /*
         * Linux will panic if this doesn't work. Just yield; it's not
         * worth overthinking it because with event channel handling
         * in KVM, the kernel will intercept this and it will never
         * reach QEMU anyway. The semantics of the hypercall explicltly
         * permit spurious wakeups.
         */
    case SCHEDOP_yield:
        sched_yield();
        err = 0;
        break;

    default:
        return false;
    }

    exit->u.hcall.result = err;
    return true;
}

static bool kvm_xen_hcall_gnttab_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                    int cmd, uint64_t arg, int count)
{
    CPUState *cs = CPU(cpu);
    int err;

    switch (cmd) {
    case GNTTABOP_set_version: {
        struct gnttab_set_version set;

        qemu_build_assert(sizeof(set) == 4);
        if (kvm_copy_from_gva(cs, arg, &set, sizeof(set))) {
            err = -EFAULT;
            break;
        }

        err = xen_gnttab_set_version_op(&set);
        if (!err && kvm_copy_to_gva(cs, arg, &set, sizeof(set))) {
            err = -EFAULT;
        }
        break;
    }
    case GNTTABOP_get_version: {
        struct gnttab_get_version get;

        qemu_build_assert(sizeof(get) == 8);
        if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) {
            err = -EFAULT;
            break;
        }

        err = xen_gnttab_get_version_op(&get);
        if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) {
            err = -EFAULT;
        }
        break;
    }
    case GNTTABOP_query_size: {
        struct gnttab_query_size size;

        qemu_build_assert(sizeof(size) == 16);
        if (kvm_copy_from_gva(cs, arg, &size, sizeof(size))) {
            err = -EFAULT;
            break;
        }

        err = xen_gnttab_query_size_op(&size);
        if (!err && kvm_copy_to_gva(cs, arg, &size, sizeof(size))) {
            err = -EFAULT;
        }
        break;
    }
    case GNTTABOP_setup_table:
    case GNTTABOP_copy:
    case GNTTABOP_map_grant_ref:
    case GNTTABOP_unmap_grant_ref:
    case GNTTABOP_swap_grant_ref:
        return false;

    default:
        /* Xen explicitly returns -ENOSYS to HVM guests for all others */
        err = -ENOSYS;
        break;
    }

    exit->u.hcall.result = err;
    return true;
}

static bool kvm_xen_hcall_physdev_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                     int cmd, uint64_t arg)
{
    CPUState *cs = CPU(cpu);
    int err;

    switch (cmd) {
    case PHYSDEVOP_map_pirq: {
        struct physdev_map_pirq map;

        if (hypercall_compat32(exit->u.hcall.longmode)) {
            struct compat_physdev_map_pirq *map32 = (void *)&map;

            if (kvm_copy_from_gva(cs, arg, map32, sizeof(*map32))) {
                return -EFAULT;
            }

            /*
             * The only thing that's different is the alignment of the
             * uint64_t table_base at the end, which gets padding to make
             * it 64-bit aligned in the 64-bit version.
             */
            qemu_build_assert(sizeof(*map32) == 36);
            qemu_build_assert(offsetof(struct physdev_map_pirq, entry_nr) ==
                              offsetof(struct compat_physdev_map_pirq, entry_nr));
            memmove(&map.table_base, &map32->table_base, sizeof(map.table_base));
        } else {
            if (kvm_copy_from_gva(cs, arg, &map, sizeof(map))) {
                err = -EFAULT;
                break;
            }
        }
        err = xen_physdev_map_pirq(&map);
        /*
         * Since table_base is an IN parameter and won't be changed, just
         * copy the size of the compat structure back to the guest.
         */
        if (!err && kvm_copy_to_gva(cs, arg, &map,
                                    sizeof(struct compat_physdev_map_pirq))) {
            err = -EFAULT;
        }
        break;
    }
    case PHYSDEVOP_unmap_pirq: {
        struct physdev_unmap_pirq unmap;

        qemu_build_assert(sizeof(unmap) == 8);
        if (kvm_copy_from_gva(cs, arg, &unmap, sizeof(unmap))) {
            err = -EFAULT;
            break;
        }

        err = xen_physdev_unmap_pirq(&unmap);
        if (!err && kvm_copy_to_gva(cs, arg, &unmap, sizeof(unmap))) {
            err = -EFAULT;
        }
        break;
    }
    case PHYSDEVOP_eoi: {
        struct physdev_eoi eoi;

        qemu_build_assert(sizeof(eoi) == 4);
        if (kvm_copy_from_gva(cs, arg, &eoi, sizeof(eoi))) {
            err = -EFAULT;
            break;
        }

        err = xen_physdev_eoi_pirq(&eoi);
        if (!err && kvm_copy_to_gva(cs, arg, &eoi, sizeof(eoi))) {
            err = -EFAULT;
        }
        break;
    }
    case PHYSDEVOP_irq_status_query: {
        struct physdev_irq_status_query query;

        qemu_build_assert(sizeof(query) == 8);
        if (kvm_copy_from_gva(cs, arg, &query, sizeof(query))) {
            err = -EFAULT;
            break;
        }

        err = xen_physdev_query_pirq(&query);
        if (!err && kvm_copy_to_gva(cs, arg, &query, sizeof(query))) {
            err = -EFAULT;
        }
        break;
    }
    case PHYSDEVOP_get_free_pirq: {
        struct physdev_get_free_pirq get;

        qemu_build_assert(sizeof(get) == 8);
        if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) {
            err = -EFAULT;
            break;
        }

        err = xen_physdev_get_free_pirq(&get);
        if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) {
            err = -EFAULT;
        }
        break;
    }
    case PHYSDEVOP_pirq_eoi_gmfn_v2: /* FreeBSD 13 makes this hypercall */
        err = -ENOSYS;
        break;

    default:
        return false;
    }

    exit->u.hcall.result = err;
    return true;
}

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) {
    case __HYPERVISOR_set_timer_op:
        if (exit->u.hcall.longmode) {
            return kvm_xen_hcall_set_timer_op(exit, cpu,
                                              exit->u.hcall.params[0]);
        } else {
            /* In 32-bit mode, the 64-bit timer value is in two args. */
            uint64_t val = ((uint64_t)exit->u.hcall.params[1]) << 32 |
                (uint32_t)exit->u.hcall.params[0];
            return kvm_xen_hcall_set_timer_op(exit, cpu, val);
        }
    case __HYPERVISOR_grant_table_op:
        return kvm_xen_hcall_gnttab_op(exit, cpu, exit->u.hcall.params[0],
                                       exit->u.hcall.params[1],
                                       exit->u.hcall.params[2]);
    case __HYPERVISOR_sched_op:
        return kvm_xen_hcall_sched_op(exit, cpu, exit->u.hcall.params[0],
                                      exit->u.hcall.params[1]);
    case __HYPERVISOR_event_channel_op:
        return kvm_xen_hcall_evtchn_op(exit, cpu, exit->u.hcall.params[0],
                                       exit->u.hcall.params[1]);
    case __HYPERVISOR_vcpu_op:
        return kvm_xen_hcall_vcpu_op(exit, cpu,
                                     exit->u.hcall.params[0],
                                     exit->u.hcall.params[1],
                                     exit->u.hcall.params[2]);
    case __HYPERVISOR_hvm_op:
        return kvm_xen_hcall_hvm_op(exit, cpu, exit->u.hcall.params[0],
                                    exit->u.hcall.params[1]);
    case __HYPERVISOR_memory_op:
        return kvm_xen_hcall_memory_op(exit, cpu, exit->u.hcall.params[0],
                                       exit->u.hcall.params[1]);
    case __HYPERVISOR_physdev_op:
        return kvm_xen_hcall_physdev_op(exit, cpu, exit->u.hcall.params[0],
                                        exit->u.hcall.params[1]);
    case __HYPERVISOR_xen_version:
        return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0],
                                         exit->u.hcall.params[1]);
    default:
        return false;
    }
}

int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
{
    if (exit->type != KVM_EXIT_XEN_HCALL) {
        return -1;
    }

    /*
     * The kernel latches the guest 32/64 mode when the MSR is used to fill
     * the hypercall page. So if we see a hypercall in a mode that doesn't
     * match our own idea of the guest mode, fetch the kernel's idea of the
     * "long mode" to remain in sync.
     */
    if (exit->u.hcall.longmode != xen_is_long_mode()) {
        xen_sync_long_mode();
    }

    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;
}

uint16_t kvm_xen_get_gnttab_max_frames(void)
{
    KVMState *s = KVM_STATE(current_accel());
    return s->xen_gnttab_max_frames;
}

uint16_t kvm_xen_get_evtchn_max_pirq(void)
{
    KVMState *s = KVM_STATE(current_accel());
    return s->xen_evtchn_max_pirq;
}

int kvm_put_xen_state(CPUState *cs)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;
    uint64_t gpa;
    int ret;

    gpa = env->xen_vcpu_info_gpa;
    if (gpa == INVALID_GPA) {
        gpa = env->xen_vcpu_info_default_gpa;
    }

    if (gpa != INVALID_GPA) {
        ret = set_vcpu_info(cs, gpa);
        if (ret < 0) {
            return ret;
        }
    }

    gpa = env->xen_vcpu_time_info_gpa;
    if (gpa != INVALID_GPA) {
        ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO,
                                    gpa);
        if (ret < 0) {
            return ret;
        }
    }

    gpa = env->xen_vcpu_runstate_gpa;
    if (gpa != INVALID_GPA) {
        ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,
                                    gpa);
        if (ret < 0) {
            return ret;
        }
    }

    if (env->xen_periodic_timer_period) {
        ret = do_set_periodic_timer(cs, env->xen_periodic_timer_period);
        if (ret < 0) {
            return ret;
        }
    }

    if (!kvm_xen_has_cap(EVTCHN_SEND)) {
        /*
         * If the kernel has EVTCHN_SEND support then it handles timers too,
         * so the timer will be restored by kvm_xen_set_vcpu_timer() below.
         */
        QEMU_LOCK_GUARD(&env->xen_timers_lock);
        if (env->xen_singleshot_timer_ns) {
            ret = do_set_singleshot_timer(cs, env->xen_singleshot_timer_ns,
                                          false);
            if (ret < 0) {
                return ret;
            }
        }
        return 0;
    }

    if (env->xen_vcpu_callback_vector) {
        ret = kvm_xen_set_vcpu_callback_vector(cs);
        if (ret < 0) {
            return ret;
        }
    }

    if (env->xen_virq[VIRQ_TIMER]) {
        do_set_vcpu_timer_virq(cs,
                               RUN_ON_CPU_HOST_INT(env->xen_virq[VIRQ_TIMER]));
    }
    return 0;
}

int kvm_get_xen_state(CPUState *cs)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;
    uint64_t gpa;
    int ret;

    /*
     * The kernel does not mark vcpu_info as dirty when it delivers interrupts
     * to it. It's up to userspace to *assume* that any page shared thus is
     * always considered dirty. The shared_info page is different since it's
     * an overlay and migrated separately anyway.
     */
    gpa = env->xen_vcpu_info_gpa;
    if (gpa == INVALID_GPA) {
        gpa = env->xen_vcpu_info_default_gpa;
    }
    if (gpa != INVALID_GPA) {
        MemoryRegionSection mrs = memory_region_find(get_system_memory(),
                                                     gpa,
                                                     sizeof(struct vcpu_info));
        if (mrs.mr &&
            !int128_lt(mrs.size, int128_make64(sizeof(struct vcpu_info)))) {
            memory_region_set_dirty(mrs.mr, mrs.offset_within_region,
                                    sizeof(struct vcpu_info));
        }
    }

    if (!kvm_xen_has_cap(EVTCHN_SEND)) {
        return 0;
    }

    /*
     * If the kernel is accelerating timers, read out the current value of the
     * singleshot timer deadline.
     */
    if (env->xen_virq[VIRQ_TIMER]) {
        struct kvm_xen_vcpu_attr va = {
            .type = KVM_XEN_VCPU_ATTR_TYPE_TIMER,
        };
        ret = kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_GET_ATTR, &va);
        if (ret < 0) {
            return ret;
        }

        /*
         * This locking is fairly pointless, and is here to appease Coverity.
         * There is an unavoidable race condition if a different vCPU sets a
         * timer for this vCPU after the value has been read out. But that's
         * OK in practice because *all* the vCPUs need to be stopped before
         * we set about migrating their state.
         */
        QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock);
        env->xen_singleshot_timer_ns = va.u.timer.expires_ns;
    }

    return 0;
}
