/*
 * qemu/kvm integration
 *
 * Copyright (C) 2006-2008 Qumranet Technologies
 *
 * Licensed under the terms of the GNU GPL version 2 or higher.
 */
#include "config.h"
#include "config-host.h"

#include <assert.h>
#include <string.h>
#include "hw/hw.h"
#include "sysemu.h"
#include "qemu-common.h"
#include "console.h"
#include "block.h"
#include "compatfd.h"
#include "gdbstub.h"
#include "monitor.h"
#include "cpus.h"

#include "qemu-kvm.h"

#define EXPECTED_KVM_API_VERSION 12

#if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
#error libkvm: userspace and kernel version mismatch
#endif

#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))

static inline void set_gsi(KVMState *s, unsigned int gsi)
{
    uint32_t *bitmap = s->used_gsi_bitmap;

    if (gsi < s->max_gsi) {
        bitmap[gsi / 32] |= 1U << (gsi % 32);
    } else {
        DPRINTF("Invalid GSI %u\n", gsi);
    }
}

static inline void clear_gsi(KVMState *s, unsigned int gsi)
{
    uint32_t *bitmap = s->used_gsi_bitmap;

    if (gsi < s->max_gsi) {
        bitmap[gsi / 32] &= ~(1U << (gsi % 32));
    } else {
        DPRINTF("Invalid GSI %u\n", gsi);
    }
}

static int kvm_init_irq_routing(KVMState *s)
{
#ifdef KVM_CAP_IRQ_ROUTING
    int r, gsi_count;

    gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING);
    if (gsi_count > 0) {
        int gsi_bits, i;

        /* Round up so we can search ints using ffs */
        gsi_bits = ALIGN(gsi_count, 32);
        s->used_gsi_bitmap = g_malloc0(gsi_bits / 8);
        s->max_gsi = gsi_bits;

        /* Mark any over-allocated bits as already in use */
        for (i = gsi_count; i < gsi_bits; i++) {
            set_gsi(s, i);
        }
    }

    s->irq_routes = g_malloc0(sizeof(*s->irq_routes));
    s->nr_allocated_irq_routes = 0;

    r = kvm_arch_init_irq_routing();
    if (r < 0) {
        return r;
    }
#endif

    return 0;
}

int kvm_create_irqchip(KVMState *s)
{
#ifdef KVM_CAP_IRQCHIP
    int r;

    if (!kvm_irqchip || !kvm_check_extension(s, KVM_CAP_IRQCHIP)) {
        return 0;
    }

    r = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
    if (r < 0) {
        fprintf(stderr, "Create kernel PIC irqchip failed\n");
        return r;
    }

    s->irqchip_inject_ioctl = KVM_IRQ_LINE;
#if defined(KVM_CAP_IRQ_INJECT_STATUS) && defined(KVM_IRQ_LINE_STATUS)
    if (kvm_check_extension(s, KVM_CAP_IRQ_INJECT_STATUS)) {
        s->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS;
    }
#endif
    kvm_kernel_irqchip = true;

    r = kvm_init_irq_routing(s);
    if (r < 0) {
        return r;
    }
#endif

    return 0;
}

#ifdef KVM_CAP_IRQCHIP

int kvm_set_irq(int irq, int level, int *status)
{
    struct kvm_irq_level event;
    int r;

    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    event.level = level;
    event.irq = irq;
    r = kvm_vm_ioctl(kvm_state, kvm_state->irqchip_inject_ioctl,
                     &event);
    if (r < 0) {
        perror("kvm_set_irq");
    }

    if (status) {
#ifdef KVM_CAP_IRQ_INJECT_STATUS
        *status = (kvm_state->irqchip_inject_ioctl == KVM_IRQ_LINE) ?
            1 : event.status;
#else
        *status = 1;
#endif
    }

    return 1;
}

int kvm_get_irqchip(KVMState *s, struct kvm_irqchip *chip)
{
    int r;

    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    r = kvm_vm_ioctl(s, KVM_GET_IRQCHIP, chip);
    if (r < 0) {
        perror("kvm_get_irqchip\n");
    }
    return r;
}

int kvm_set_irqchip(KVMState *s, struct kvm_irqchip *chip)
{
    int r;

    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    r = kvm_vm_ioctl(s, KVM_SET_IRQCHIP, chip);
    if (r < 0) {
        perror("kvm_set_irqchip\n");
    }
    return r;
}

#endif

#ifdef KVM_CAP_DEVICE_ASSIGNMENT
int kvm_assign_pci_device(KVMState *s,
                          struct kvm_assigned_pci_dev *assigned_dev)
{
    return kvm_vm_ioctl(s, KVM_ASSIGN_PCI_DEVICE, assigned_dev);
}

static int kvm_old_assign_irq(KVMState *s,
                              struct kvm_assigned_irq *assigned_irq)
{
    return kvm_vm_ioctl(s, KVM_ASSIGN_IRQ, assigned_irq);
}

#ifdef KVM_CAP_ASSIGN_DEV_IRQ
int kvm_assign_irq(KVMState *s, struct kvm_assigned_irq *assigned_irq)
{
    int ret;

    ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_ASSIGN_DEV_IRQ);
    if (ret > 0) {
        return kvm_vm_ioctl(s, KVM_ASSIGN_DEV_IRQ, assigned_irq);
    }

    return kvm_old_assign_irq(s, assigned_irq);
}

int kvm_deassign_irq(KVMState *s, struct kvm_assigned_irq *assigned_irq)
{
    return kvm_vm_ioctl(s, KVM_DEASSIGN_DEV_IRQ, assigned_irq);
}
#else
int kvm_assign_irq(KVMState *s, struct kvm_assigned_irq *assigned_irq)
{
    return kvm_old_assign_irq(s, assigned_irq);
}
#endif
#endif

#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
int kvm_deassign_pci_device(KVMState *s,
                            struct kvm_assigned_pci_dev *assigned_dev)
{
    return kvm_vm_ioctl(s, KVM_DEASSIGN_PCI_DEVICE, assigned_dev);
}
#endif

int kvm_reinject_control(KVMState *s, int pit_reinject)
{
#ifdef KVM_CAP_REINJECT_CONTROL
    int r;
    struct kvm_reinject_control control;

    control.pit_reinject = pit_reinject;

    r = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_REINJECT_CONTROL);
    if (r > 0) {
        return kvm_vm_ioctl(s, KVM_REINJECT_CONTROL, &control);
    }
#endif
    return -ENOSYS;
}

int kvm_clear_gsi_routes(void)
{
#ifdef KVM_CAP_IRQ_ROUTING
    kvm_state->irq_routes->nr = 0;
    return 0;
#else
    return -EINVAL;
#endif
}

int kvm_add_routing_entry(struct kvm_irq_routing_entry *entry)
{
#ifdef KVM_CAP_IRQ_ROUTING
    KVMState *s = kvm_state;
    struct kvm_irq_routing *z;
    struct kvm_irq_routing_entry *new;
    int n, size;

    if (s->irq_routes->nr == s->nr_allocated_irq_routes) {
        n = s->nr_allocated_irq_routes * 2;
        if (n < 64) {
            n = 64;
        }
        size = sizeof(struct kvm_irq_routing);
        size += n * sizeof(*new);
        z = realloc(s->irq_routes, size);
        if (!z) {
            return -ENOMEM;
        }
        s->nr_allocated_irq_routes = n;
        s->irq_routes = z;
    }
    n = s->irq_routes->nr++;
    new = &s->irq_routes->entries[n];
    memset(new, 0, sizeof(*new));
    new->gsi = entry->gsi;
    new->type = entry->type;
    new->flags = entry->flags;
    new->u = entry->u;

    set_gsi(s, entry->gsi);

    return 0;
#else
    return -ENOSYS;
#endif
}

int kvm_add_irq_route(int gsi, int irqchip, int pin)
{
#ifdef KVM_CAP_IRQ_ROUTING
    struct kvm_irq_routing_entry e;

    e.gsi = gsi;
    e.type = KVM_IRQ_ROUTING_IRQCHIP;
    e.flags = 0;
    e.u.irqchip.irqchip = irqchip;
    e.u.irqchip.pin = pin;
    return kvm_add_routing_entry(&e);
#else
    return -ENOSYS;
#endif
}

int kvm_del_routing_entry(struct kvm_irq_routing_entry *entry)
{
#ifdef KVM_CAP_IRQ_ROUTING
    KVMState *s = kvm_state;
    struct kvm_irq_routing_entry *e, *p;
    int i, gsi, found = 0;

    gsi = entry->gsi;

    for (i = 0; i < s->irq_routes->nr; ++i) {
        e = &s->irq_routes->entries[i];
        if (e->type == entry->type && e->gsi == gsi) {
            switch (e->type) {
            case KVM_IRQ_ROUTING_IRQCHIP:{
                    if (e->u.irqchip.irqchip ==
                        entry->u.irqchip.irqchip
                        && e->u.irqchip.pin == entry->u.irqchip.pin) {
                        p = &s->irq_routes->entries[--s->irq_routes->nr];
                        *e = *p;
                        found = 1;
                    }
                    break;
                }
            case KVM_IRQ_ROUTING_MSI:{
                    if (e->u.msi.address_lo ==
                        entry->u.msi.address_lo
                        && e->u.msi.address_hi ==
                        entry->u.msi.address_hi
                        && e->u.msi.data == entry->u.msi.data) {
                        p = &s->irq_routes->entries[--s->irq_routes->nr];
                        *e = *p;
                        found = 1;
                    }
                    break;
                }
            default:
                break;
            }
            if (found) {
                /* If there are no other users of this GSI
                 * mark it available in the bitmap */
                for (i = 0; i < s->irq_routes->nr; i++) {
                    e = &s->irq_routes->entries[i];
                    if (e->gsi == gsi)
                        break;
                }
                if (i == s->irq_routes->nr) {
                    clear_gsi(s, gsi);
                }

                return 0;
            }
        }
    }
    return -ESRCH;
#else
    return -ENOSYS;
#endif
}

int kvm_update_routing_entry(struct kvm_irq_routing_entry *entry,
                             struct kvm_irq_routing_entry *newentry)
{
#ifdef KVM_CAP_IRQ_ROUTING
    KVMState *s = kvm_state;
    struct kvm_irq_routing_entry *e;
    int i;

    if (entry->gsi != newentry->gsi || entry->type != newentry->type) {
        return -EINVAL;
    }

    for (i = 0; i < s->irq_routes->nr; ++i) {
        e = &s->irq_routes->entries[i];
        if (e->type != entry->type || e->gsi != entry->gsi) {
            continue;
        }
        switch (e->type) {
        case KVM_IRQ_ROUTING_IRQCHIP:
            if (e->u.irqchip.irqchip == entry->u.irqchip.irqchip &&
                e->u.irqchip.pin == entry->u.irqchip.pin) {
                memcpy(&e->u.irqchip, &newentry->u.irqchip,
                       sizeof e->u.irqchip);
                return 0;
            }
            break;
        case KVM_IRQ_ROUTING_MSI:
            if (e->u.msi.address_lo == entry->u.msi.address_lo &&
                e->u.msi.address_hi == entry->u.msi.address_hi &&
                e->u.msi.data == entry->u.msi.data) {
                memcpy(&e->u.msi, &newentry->u.msi, sizeof e->u.msi);
                return 0;
            }
            break;
        default:
            break;
        }
    }
    return -ESRCH;
#else
    return -ENOSYS;
#endif
}

int kvm_del_irq_route(int gsi, int irqchip, int pin)
{
#ifdef KVM_CAP_IRQ_ROUTING
    struct kvm_irq_routing_entry e;

    e.gsi = gsi;
    e.type = KVM_IRQ_ROUTING_IRQCHIP;
    e.flags = 0;
    e.u.irqchip.irqchip = irqchip;
    e.u.irqchip.pin = pin;
    return kvm_del_routing_entry(&e);
#else
    return -ENOSYS;
#endif
}

int kvm_commit_irq_routes(void)
{
#ifdef KVM_CAP_IRQ_ROUTING
    KVMState *s = kvm_state;

    s->irq_routes->flags = 0;
    return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
#else
    return -ENOSYS;
#endif
}

int kvm_get_irq_route_gsi(void)
{
    KVMState *s = kvm_state;
    int i, bit;
    uint32_t *buf = s->used_gsi_bitmap;

    /* Return the lowest unused GSI in the bitmap */
    for (i = 0; i < s->max_gsi / 32; i++) {
        bit = ffs(~buf[i]);
        if (!bit) {
            continue;
        }

        return bit - 1 + i * 32;
    }

    return -ENOSPC;
}

static void kvm_msi_routing_entry(struct kvm_irq_routing_entry *e,
                                  KVMMsiMessage *msg)

{
    e->gsi = msg->gsi;
    e->type = KVM_IRQ_ROUTING_MSI;
    e->flags = 0;
    e->u.msi.address_lo = msg->addr_lo;
    e->u.msi.address_hi = msg->addr_hi;
    e->u.msi.data = msg->data;
}

int kvm_msi_message_add(KVMMsiMessage *msg)
{
    struct kvm_irq_routing_entry e;
    int ret;

    ret = kvm_get_irq_route_gsi();
    if (ret < 0) {
        return ret;
    }
    msg->gsi = ret;

    kvm_msi_routing_entry(&e, msg);
    return kvm_add_routing_entry(&e);
}

int kvm_msi_message_del(KVMMsiMessage *msg)
{
    struct kvm_irq_routing_entry e;

    kvm_msi_routing_entry(&e, msg);
    return kvm_del_routing_entry(&e);
}

int kvm_msi_message_update(KVMMsiMessage *old, KVMMsiMessage *new)
{
    struct kvm_irq_routing_entry e1, e2;
    int ret;

    new->gsi = old->gsi;
    if (memcmp(old, new, sizeof(KVMMsiMessage)) == 0) {
        return 0;
    }

    kvm_msi_routing_entry(&e1, old);
    kvm_msi_routing_entry(&e2, new);

    ret = kvm_update_routing_entry(&e1, &e2);
    if (ret < 0) {
        return ret;
    }

    return 1;
}


#ifdef KVM_CAP_DEVICE_MSIX
int kvm_assign_set_msix_nr(KVMState *s, struct kvm_assigned_msix_nr *msix_nr)
{
    return kvm_vm_ioctl(s, KVM_ASSIGN_SET_MSIX_NR, msix_nr);
}

int kvm_assign_set_msix_entry(KVMState *s,
                              struct kvm_assigned_msix_entry *entry)
{
    return kvm_vm_ioctl(s, KVM_ASSIGN_SET_MSIX_ENTRY, entry);
}
#endif

#ifdef TARGET_I386
void kvm_hpet_disable_kpit(void)
{
    struct kvm_pit_state2 ps2;

    kvm_get_pit2(kvm_state, &ps2);
    ps2.flags |= KVM_PIT_FLAGS_HPET_LEGACY;
    kvm_set_pit2(kvm_state, &ps2);
}

void kvm_hpet_enable_kpit(void)
{
    struct kvm_pit_state2 ps2;

    kvm_get_pit2(kvm_state, &ps2);
    ps2.flags &= ~KVM_PIT_FLAGS_HPET_LEGACY;
    kvm_set_pit2(kvm_state, &ps2);
}
#endif

#if !defined(TARGET_I386)
int kvm_arch_init_irq_routing(void)
{
    return 0;
}
#endif

#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
typedef struct KVMIOPortRegion {
    unsigned long start;
    unsigned long size;
    int status;
    QLIST_ENTRY(KVMIOPortRegion) entry;
} KVMIOPortRegion;

static QLIST_HEAD(, KVMIOPortRegion) ioport_regions;

static void do_set_ioport_access(void *data)
{
    KVMIOPortRegion *region = data;
    bool enable = region->status > 0;
    int r;

    r = kvm_arch_set_ioport_access(region->start, region->size, enable);
    if (r < 0) {
        region->status = r;
    } else {
        region->status = 1;
    }
}

int kvm_add_ioport_region(unsigned long start, unsigned long size,
                          bool is_hot_plug)
{
    KVMIOPortRegion *region = g_malloc0(sizeof(KVMIOPortRegion));
    CPUState *env;
    int r = 0;

    region->start = start;
    region->size = size;
    region->status = 1;
    QLIST_INSERT_HEAD(&ioport_regions, region, entry);

    if (is_hot_plug) {
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
            run_on_cpu(env, do_set_ioport_access, region);
            if (region->status < 0) {
                r = region->status;
                kvm_remove_ioport_region(start, size, is_hot_plug);
                break;
            }
        }
    }
    return r;
}

int kvm_remove_ioport_region(unsigned long start, unsigned long size,
                             bool is_hot_unplug)
{
    KVMIOPortRegion *region, *tmp;
    CPUState *env;
    int r = -ENOENT;

    QLIST_FOREACH_SAFE(region, &ioport_regions, entry, tmp) {
        if (region->start == start && region->size == size) {
            region->status = 0;
        }
        if (is_hot_unplug) {
            for (env = first_cpu; env != NULL; env = env->next_cpu) {
                run_on_cpu(env, do_set_ioport_access, region);
            }
        }
        QLIST_REMOVE(region, entry);
        g_free(region);
        r = 0;
    }
    return r;
}
#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */

int kvm_update_ioport_access(CPUState *env)
{
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
    KVMIOPortRegion *region;
    int r;

    assert(qemu_cpu_is_self(env));

    QLIST_FOREACH(region, &ioport_regions, entry) {
        bool enable = region->status > 0;

        r = kvm_arch_set_ioport_access(region->start, region->size, enable);
        if (r < 0) {
            return r;
        }
    }
#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */
    return 0;
}
