/*
 * 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

int kvm_irqchip = 1;
int kvm_pit = 1;
int kvm_pit_reinject = 1;
int kvm_nested = 0;

#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 = qemu_mallocz(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 = qemu_mallocz(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
    s->irqchip_in_kernel = 1;

    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_state->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 (!s->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 (!s->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_has_gsi_routing(void)
{
    int r = 0;

#ifdef KVM_CAP_IRQ_ROUTING
    r = kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING);
#endif
    return r;
}

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)
{
    KVMIOPortRegion *region = qemu_mallocz(sizeof(KVMIOPortRegion));
    CPUState *env;
    int r = 0;

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

    if (qemu_system_is_ready()) {
        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);
                break;
            }
        }
    }
    return r;
}

int kvm_remove_ioport_region(unsigned long start, unsigned long size)
{
    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 (qemu_system_is_ready()) {
            for (env = first_cpu; env != NULL; env = env->next_cpu) {
                run_on_cpu(env, do_set_ioport_access, region);
            }
        }
        QLIST_REMOVE(region, entry);
        qemu_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;
}
