/*
 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
 *
 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics, in-kernel emulation
 *
 * Copyright (c) 2013 David Gibson, IBM Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "trace.h"
#include "sysemu/kvm.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/xics.h"
#include "hw/ppc/xics_spapr.h"
#include "kvm_ppc.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"

#include <sys/ioctl.h>

static int kernel_xics_fd = -1;

typedef struct KVMEnabledICP {
    unsigned long vcpu_id;
    QLIST_ENTRY(KVMEnabledICP) node;
} KVMEnabledICP;

static QLIST_HEAD(, KVMEnabledICP)
    kvm_enabled_icps = QLIST_HEAD_INITIALIZER(&kvm_enabled_icps);

static void kvm_disable_icps(void)
{
    KVMEnabledICP *enabled_icp, *next;

    QLIST_FOREACH_SAFE(enabled_icp, &kvm_enabled_icps, node, next) {
        QLIST_REMOVE(enabled_icp, node);
        g_free(enabled_icp);
    }
}

/*
 * ICP-KVM
 */
void icp_get_kvm_state(ICPState *icp)
{
    uint64_t state;
    int ret;

    /* The KVM XICS device is not in use */
    if (kernel_xics_fd == -1) {
        return;
    }

    /* ICP for this CPU thread is not in use, exiting */
    if (!icp->cs) {
        return;
    }

    ret = kvm_get_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
    if (ret != 0) {
        error_report("Unable to retrieve KVM interrupt controller state"
                " for CPU %ld: %s", kvm_arch_vcpu_id(icp->cs), strerror(errno));
        exit(1);
    }

    icp->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT;
    icp->mfrr = (state >> KVM_REG_PPC_ICP_MFRR_SHIFT)
        & KVM_REG_PPC_ICP_MFRR_MASK;
    icp->pending_priority = (state >> KVM_REG_PPC_ICP_PPRI_SHIFT)
        & KVM_REG_PPC_ICP_PPRI_MASK;
}

static void do_icp_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
    icp_get_kvm_state(arg.host_ptr);
}

void icp_synchronize_state(ICPState *icp)
{
    if (icp->cs) {
        run_on_cpu(icp->cs, do_icp_synchronize_state, RUN_ON_CPU_HOST_PTR(icp));
    }
}

int icp_set_kvm_state(ICPState *icp, Error **errp)
{
    uint64_t state;
    int ret;

    /* The KVM XICS device is not in use */
    if (kernel_xics_fd == -1) {
        return 0;
    }

    /* ICP for this CPU thread is not in use, exiting */
    if (!icp->cs) {
        return 0;
    }

    state = ((uint64_t)icp->xirr << KVM_REG_PPC_ICP_XISR_SHIFT)
        | ((uint64_t)icp->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT)
        | ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);

    ret = kvm_set_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
    if (ret < 0) {
        error_setg_errno(errp, -ret,
                         "Unable to restore KVM interrupt controller state (0x%"
                         PRIx64 ") for CPU %ld", state,
                         kvm_arch_vcpu_id(icp->cs));
        return ret;
    }

    return 0;
}

void icp_kvm_realize(DeviceState *dev, Error **errp)
{
    ICPState *icp = ICP(dev);
    CPUState *cs;
    KVMEnabledICP *enabled_icp;
    unsigned long vcpu_id;
    int ret;

    /* The KVM XICS device is not in use */
    if (kernel_xics_fd == -1) {
        return;
    }

    cs = icp->cs;
    vcpu_id = kvm_arch_vcpu_id(cs);

    /*
     * If we are reusing a parked vCPU fd corresponding to the CPU
     * which was hot-removed earlier we don't have to renable
     * KVM_CAP_IRQ_XICS capability again.
     */
    QLIST_FOREACH(enabled_icp, &kvm_enabled_icps, node) {
        if (enabled_icp->vcpu_id == vcpu_id) {
            return;
        }
    }

    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd, vcpu_id);
    if (ret < 0) {
        Error *local_err = NULL;

        error_setg(&local_err, "Unable to connect CPU%ld to kernel XICS: %s",
                   vcpu_id, strerror(errno));
        if (errno == ENOSPC) {
            error_append_hint(&local_err, "Try -smp maxcpus=N with N < %u\n",
                              MACHINE(qdev_get_machine())->smp.max_cpus);
        }
        error_propagate(errp, local_err);
        return;
    }
    enabled_icp = g_malloc(sizeof(*enabled_icp));
    enabled_icp->vcpu_id = vcpu_id;
    QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node);
}

/*
 * ICS-KVM
 */
void ics_get_kvm_state(ICSState *ics)
{
    uint64_t state;
    int i;

    /* The KVM XICS device is not in use */
    if (kernel_xics_fd == -1) {
        return;
    }

    for (i = 0; i < ics->nr_irqs; i++) {
        ICSIRQState *irq = &ics->irqs[i];

        if (ics_irq_free(ics, i)) {
            continue;
        }

        kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
                          i + ics->offset, &state, false, &error_fatal);

        irq->server = state & KVM_XICS_DESTINATION_MASK;
        irq->saved_priority = (state >> KVM_XICS_PRIORITY_SHIFT)
            & KVM_XICS_PRIORITY_MASK;
        /*
         * To be consistent with the software emulation in xics.c, we
         * split out the masked state + priority that we get from the
         * kernel into 'current priority' (0xff if masked) and
         * 'saved priority' (if masked, this is the priority the
         * interrupt had before it was masked).  Masking and unmasking
         * are done with the ibm,int-off and ibm,int-on RTAS calls.
         */
        if (state & KVM_XICS_MASKED) {
            irq->priority = 0xff;
        } else {
            irq->priority = irq->saved_priority;
        }

        irq->status = 0;
        if (state & KVM_XICS_PENDING) {
            if (state & KVM_XICS_LEVEL_SENSITIVE) {
                irq->status |= XICS_STATUS_ASSERTED;
            } else {
                /*
                 * A pending edge-triggered interrupt (or MSI)
                 * must have been rejected previously when we
                 * first detected it and tried to deliver it,
                 * so mark it as pending and previously rejected
                 * for consistency with how xics.c works.
                 */
                irq->status |= XICS_STATUS_MASKED_PENDING
                    | XICS_STATUS_REJECTED;
            }
        }
        if (state & KVM_XICS_PRESENTED) {
                irq->status |= XICS_STATUS_PRESENTED;
        }
        if (state & KVM_XICS_QUEUED) {
                irq->status |= XICS_STATUS_QUEUED;
        }
    }
}

void ics_synchronize_state(ICSState *ics)
{
    ics_get_kvm_state(ics);
}

int ics_set_kvm_state_one(ICSState *ics, int srcno, Error **errp)
{
    uint64_t state;
    ICSIRQState *irq = &ics->irqs[srcno];
    int ret;

    /* The KVM XICS device is not in use */
    if (kernel_xics_fd == -1) {
        return 0;
    }

    state = irq->server;
    state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK)
        << KVM_XICS_PRIORITY_SHIFT;
    if (irq->priority != irq->saved_priority) {
        assert(irq->priority == 0xff);
    }

    if (irq->priority == 0xff) {
        state |= KVM_XICS_MASKED;
    }

    if (irq->flags & XICS_FLAGS_IRQ_LSI) {
        state |= KVM_XICS_LEVEL_SENSITIVE;
        if (irq->status & XICS_STATUS_ASSERTED) {
            state |= KVM_XICS_PENDING;
        }
    } else {
        if (irq->status & XICS_STATUS_MASKED_PENDING) {
            state |= KVM_XICS_PENDING;
        }
    }
    if (irq->status & XICS_STATUS_PRESENTED) {
        state |= KVM_XICS_PRESENTED;
    }
    if (irq->status & XICS_STATUS_QUEUED) {
        state |= KVM_XICS_QUEUED;
    }

    ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
                            srcno + ics->offset, &state, true, errp);
    if (ret < 0) {
        return ret;
    }

    return 0;
}

int ics_set_kvm_state(ICSState *ics, Error **errp)
{
    int i;

    /* The KVM XICS device is not in use */
    if (kernel_xics_fd == -1) {
        return 0;
    }

    for (i = 0; i < ics->nr_irqs; i++) {
        int ret;

        if (ics_irq_free(ics, i)) {
            continue;
        }

        ret = ics_set_kvm_state_one(ics, i, errp);
        if (ret < 0) {
            return ret;
        }
    }

    return 0;
}

void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
{
    struct kvm_irq_level args;
    int rc;

    /* The KVM XICS device should be in use */
    assert(kernel_xics_fd != -1);

    args.irq = srcno + ics->offset;
    if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MSI) {
        if (!val) {
            return;
        }
        args.level = KVM_INTERRUPT_SET;
    } else {
        args.level = val ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
    }
    rc = kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args);
    if (rc < 0) {
        perror("kvm_irq_line");
    }
}

int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
                     Error **errp)
{
    ICSState *ics = ICS_SPAPR(intc);
    int rc;
    CPUState *cs;
    Error *local_err = NULL;

    /*
     * The KVM XICS device already in use. This is the case when
     * rebooting under the XICS-only interrupt mode.
     */
    if (kernel_xics_fd != -1) {
        return 0;
    }

    if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
        error_setg(errp,
                   "KVM and IRQ_XICS capability must be present for in-kernel XICS");
        return -1;
    }

    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
    if (rc < 0) {
        error_setg_errno(&local_err, -rc,
                         "kvmppc_define_rtas_kernel_token: ibm,set-xive");
        goto fail;
    }

    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_GET_XIVE, "ibm,get-xive");
    if (rc < 0) {
        error_setg_errno(&local_err, -rc,
                         "kvmppc_define_rtas_kernel_token: ibm,get-xive");
        goto fail;
    }

    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_ON, "ibm,int-on");
    if (rc < 0) {
        error_setg_errno(&local_err, -rc,
                         "kvmppc_define_rtas_kernel_token: ibm,int-on");
        goto fail;
    }

    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_OFF, "ibm,int-off");
    if (rc < 0) {
        error_setg_errno(&local_err, -rc,
                         "kvmppc_define_rtas_kernel_token: ibm,int-off");
        goto fail;
    }

    /* Create the KVM XICS device */
    rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
    if (rc < 0) {
        error_setg_errno(&local_err, -rc, "Error on KVM_CREATE_DEVICE for XICS");
        goto fail;
    }

    /* Tell KVM about the # of VCPUs we may have (POWER9 and newer only) */
    if (kvm_device_check_attr(rc, KVM_DEV_XICS_GRP_CTRL,
                              KVM_DEV_XICS_NR_SERVERS)) {
        if (kvm_device_access(rc, KVM_DEV_XICS_GRP_CTRL,
                              KVM_DEV_XICS_NR_SERVERS, &nr_servers, true,
                              &local_err)) {
            goto fail;
        }
    }

    kernel_xics_fd = rc;
    kvm_kernel_irqchip = true;
    kvm_msi_via_irqfd_allowed = true;
    kvm_gsi_direct_mapping = true;

    /* Create the presenters */
    CPU_FOREACH(cs) {
        PowerPCCPU *cpu = POWERPC_CPU(cs);

        icp_kvm_realize(DEVICE(spapr_cpu_state(cpu)->icp), &local_err);
        if (local_err) {
            goto fail;
        }
    }

    /* Update the KVM sources */
    ics_set_kvm_state(ics, &local_err);
    if (local_err) {
        goto fail;
    }

    /* Connect the presenters to the initial VCPUs of the machine */
    CPU_FOREACH(cs) {
        PowerPCCPU *cpu = POWERPC_CPU(cs);
        icp_set_kvm_state(spapr_cpu_state(cpu)->icp, &local_err);
        if (local_err) {
            goto fail;
        }
    }

    return 0;

fail:
    error_propagate(errp, local_err);
    xics_kvm_disconnect(intc);
    return -1;
}

void xics_kvm_disconnect(SpaprInterruptController *intc)
{
    /*
     * Only on P9 using the XICS-on XIVE KVM device:
     *
     * When the KVM device fd is closed, the device is destroyed and
     * removed from the list of devices of the VM. The VCPU presenters
     * are also detached from the device.
     */
    if (kernel_xics_fd != -1) {
        close(kernel_xics_fd);
        kernel_xics_fd = -1;
    }

    kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
    kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
    kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
    kvmppc_define_rtas_kernel_token(0, "ibm,int-off");

    kvm_kernel_irqchip = false;
    kvm_msi_via_irqfd_allowed = false;
    kvm_gsi_direct_mapping = false;

    /* Clear the presenter from the VCPUs */
    kvm_disable_icps();
}

/*
 * This is a heuristic to detect older KVMs on POWER9 hosts that don't
 * support destruction of a KVM XICS device while the VM is running.
 * Required to start a spapr machine with ic-mode=dual,kernel-irqchip=on.
 */
bool xics_kvm_has_broken_disconnect(void)
{
    int rc;

    rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
    if (rc < 0) {
        /*
         * The error is ignored on purpose. The KVM XICS setup code
         * will catch it again anyway. The goal here is to see if
         * close() actually destroys the device or not.
         */
        return false;
    }

    close(rc);

    rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
    if (rc >= 0) {
        close(rc);
        return false;
    }

    return errno == EEXIST;
}
