/*
 * QEMU KVM Hyper-V support
 *
 * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
 *
 * Authors:
 *  Andrey Smetanin <asmetanin@virtuozzo.com>
 *
 * 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 "hyperv.h"
#include "standard-headers/asm-x86/hyperv.h"

int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
{
    CPUX86State *env = &cpu->env;

    switch (exit->type) {
    case KVM_EXIT_HYPERV_SYNIC:
        if (!cpu->hyperv_synic) {
            return -1;
        }

        /*
         * For now just track changes in SynIC control and msg/evt pages msr's.
         * When SynIC messaging/events processing will be added in future
         * here we will do messages queues flushing and pages remapping.
         */
        switch (exit->u.synic.msr) {
        case HV_X64_MSR_SCONTROL:
            env->msr_hv_synic_control = exit->u.synic.control;
            break;
        case HV_X64_MSR_SIMP:
            env->msr_hv_synic_msg_page = exit->u.synic.msg_page;
            break;
        case HV_X64_MSR_SIEFP:
            env->msr_hv_synic_evt_page = exit->u.synic.evt_page;
            break;
        default:
            return -1;
        }
        return 0;
    case KVM_EXIT_HYPERV_HCALL: {
        uint16_t code;

        code  = exit->u.hcall.input & 0xffff;
        switch (code) {
        case HVCALL_POST_MESSAGE:
        case HVCALL_SIGNAL_EVENT:
        default:
            exit->u.hcall.result = HV_STATUS_INVALID_HYPERCALL_CODE;
            return 0;
        }
    }
    default:
        return -1;
    }
}

static void kvm_hv_sint_ack_handler(EventNotifier *notifier)
{
    HvSintRoute *sint_route = container_of(notifier, HvSintRoute,
                                           sint_ack_notifier);
    event_notifier_test_and_clear(notifier);
    if (sint_route->sint_ack_clb) {
        sint_route->sint_ack_clb(sint_route);
    }
}

HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
                                      HvSintAckClb sint_ack_clb)
{
    HvSintRoute *sint_route;
    int r, gsi;

    sint_route = g_malloc0(sizeof(*sint_route));
    r = event_notifier_init(&sint_route->sint_set_notifier, false);
    if (r) {
        goto err;
    }

    r = event_notifier_init(&sint_route->sint_ack_notifier, false);
    if (r) {
        goto err_sint_set_notifier;
    }

    event_notifier_set_handler(&sint_route->sint_ack_notifier, false,
                               kvm_hv_sint_ack_handler);

    gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint);
    if (gsi < 0) {
        goto err_gsi;
    }

    r = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state,
                                           &sint_route->sint_set_notifier,
                                           &sint_route->sint_ack_notifier, gsi);
    if (r) {
        goto err_irqfd;
    }
    sint_route->gsi = gsi;
    sint_route->sint_ack_clb = sint_ack_clb;
    sint_route->vcpu_id = vcpu_id;
    sint_route->sint = sint;

    return sint_route;

err_irqfd:
    kvm_irqchip_release_virq(kvm_state, gsi);
err_gsi:
    event_notifier_set_handler(&sint_route->sint_ack_notifier, false, NULL);
    event_notifier_cleanup(&sint_route->sint_ack_notifier);
err_sint_set_notifier:
    event_notifier_cleanup(&sint_route->sint_set_notifier);
err:
    g_free(sint_route);

    return NULL;
}

void kvm_hv_sint_route_destroy(HvSintRoute *sint_route)
{
    kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state,
                                          &sint_route->sint_set_notifier,
                                          sint_route->gsi);
    kvm_irqchip_release_virq(kvm_state, sint_route->gsi);
    event_notifier_set_handler(&sint_route->sint_ack_notifier, false, NULL);
    event_notifier_cleanup(&sint_route->sint_ack_notifier);
    event_notifier_cleanup(&sint_route->sint_set_notifier);
    g_free(sint_route);
}

int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route)
{
    return event_notifier_set(&sint_route->sint_set_notifier);
}
