qemu/hw/intc/xics_kvm.c
<<
>>
Prefs
   1/*
   2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
   3 *
   4 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics, in-kernel emulation
   5 *
   6 * Copyright (c) 2013 David Gibson, IBM Corporation.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 *
  26 */
  27
  28#include "hw/hw.h"
  29#include "trace.h"
  30#include "hw/ppc/spapr.h"
  31#include "hw/ppc/xics.h"
  32#include "kvm_ppc.h"
  33#include "qemu/config-file.h"
  34#include "qemu/error-report.h"
  35
  36#include <sys/ioctl.h>
  37
  38typedef struct KVMXICSState {
  39    XICSState parent_obj;
  40
  41    int kernel_xics_fd;
  42} KVMXICSState;
  43
  44/*
  45 * ICP-KVM
  46 */
  47static void icp_get_kvm_state(ICPState *ss)
  48{
  49    uint64_t state;
  50    struct kvm_one_reg reg = {
  51        .id = KVM_REG_PPC_ICP_STATE,
  52        .addr = (uintptr_t)&state,
  53    };
  54    int ret;
  55
  56    /* ICP for this CPU thread is not in use, exiting */
  57    if (!ss->cs) {
  58        return;
  59    }
  60
  61    ret = kvm_vcpu_ioctl(ss->cs, KVM_GET_ONE_REG, &reg);
  62    if (ret != 0) {
  63        error_report("Unable to retrieve KVM interrupt controller state"
  64                " for CPU %ld: %s", kvm_arch_vcpu_id(ss->cs), strerror(errno));
  65        exit(1);
  66    }
  67
  68    ss->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT;
  69    ss->mfrr = (state >> KVM_REG_PPC_ICP_MFRR_SHIFT)
  70        & KVM_REG_PPC_ICP_MFRR_MASK;
  71    ss->pending_priority = (state >> KVM_REG_PPC_ICP_PPRI_SHIFT)
  72        & KVM_REG_PPC_ICP_PPRI_MASK;
  73}
  74
  75static int icp_set_kvm_state(ICPState *ss, int version_id)
  76{
  77    uint64_t state;
  78    struct kvm_one_reg reg = {
  79        .id = KVM_REG_PPC_ICP_STATE,
  80        .addr = (uintptr_t)&state,
  81    };
  82    int ret;
  83
  84    /* ICP for this CPU thread is not in use, exiting */
  85    if (!ss->cs) {
  86        return 0;
  87    }
  88
  89    state = ((uint64_t)ss->xirr << KVM_REG_PPC_ICP_XISR_SHIFT)
  90        | ((uint64_t)ss->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT)
  91        | ((uint64_t)ss->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);
  92
  93    ret = kvm_vcpu_ioctl(ss->cs, KVM_SET_ONE_REG, &reg);
  94    if (ret != 0) {
  95        error_report("Unable to restore KVM interrupt controller state (0x%"
  96                PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(ss->cs),
  97                strerror(errno));
  98        return ret;
  99    }
 100
 101    return 0;
 102}
 103
 104static void icp_kvm_reset(DeviceState *dev)
 105{
 106    ICPState *icp = ICP(dev);
 107
 108    icp->xirr = 0;
 109    icp->pending_priority = 0xff;
 110    icp->mfrr = 0xff;
 111
 112    /* Make all outputs are deasserted */
 113    qemu_set_irq(icp->output, 0);
 114
 115    icp_set_kvm_state(icp, 1);
 116}
 117
 118static void icp_kvm_class_init(ObjectClass *klass, void *data)
 119{
 120    DeviceClass *dc = DEVICE_CLASS(klass);
 121    ICPStateClass *icpc = ICP_CLASS(klass);
 122
 123    dc->reset = icp_kvm_reset;
 124    icpc->pre_save = icp_get_kvm_state;
 125    icpc->post_load = icp_set_kvm_state;
 126}
 127
 128static const TypeInfo icp_kvm_info = {
 129    .name = TYPE_KVM_ICP,
 130    .parent = TYPE_ICP,
 131    .instance_size = sizeof(ICPState),
 132    .class_init = icp_kvm_class_init,
 133    .class_size = sizeof(ICPStateClass),
 134};
 135
 136/*
 137 * ICS-KVM
 138 */
 139static void ics_get_kvm_state(ICSState *ics)
 140{
 141    KVMXICSState *icpkvm = KVM_XICS(ics->icp);
 142    uint64_t state;
 143    struct kvm_device_attr attr = {
 144        .flags = 0,
 145        .group = KVM_DEV_XICS_GRP_SOURCES,
 146        .addr = (uint64_t)(uintptr_t)&state,
 147    };
 148    int i;
 149
 150    for (i = 0; i < ics->nr_irqs; i++) {
 151        ICSIRQState *irq = &ics->irqs[i];
 152        int ret;
 153
 154        attr.attr = i + ics->offset;
 155
 156        ret = ioctl(icpkvm->kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
 157        if (ret != 0) {
 158            error_report("Unable to retrieve KVM interrupt controller state"
 159                    " for IRQ %d: %s", i + ics->offset, strerror(errno));
 160            exit(1);
 161        }
 162
 163        irq->server = state & KVM_XICS_DESTINATION_MASK;
 164        irq->saved_priority = (state >> KVM_XICS_PRIORITY_SHIFT)
 165            & KVM_XICS_PRIORITY_MASK;
 166        /*
 167         * To be consistent with the software emulation in xics.c, we
 168         * split out the masked state + priority that we get from the
 169         * kernel into 'current priority' (0xff if masked) and
 170         * 'saved priority' (if masked, this is the priority the
 171         * interrupt had before it was masked).  Masking and unmasking
 172         * are done with the ibm,int-off and ibm,int-on RTAS calls.
 173         */
 174        if (state & KVM_XICS_MASKED) {
 175            irq->priority = 0xff;
 176        } else {
 177            irq->priority = irq->saved_priority;
 178        }
 179
 180        if (state & KVM_XICS_PENDING) {
 181            if (state & KVM_XICS_LEVEL_SENSITIVE) {
 182                irq->status |= XICS_STATUS_ASSERTED;
 183            } else {
 184                /*
 185                 * A pending edge-triggered interrupt (or MSI)
 186                 * must have been rejected previously when we
 187                 * first detected it and tried to deliver it,
 188                 * so mark it as pending and previously rejected
 189                 * for consistency with how xics.c works.
 190                 */
 191                irq->status |= XICS_STATUS_MASKED_PENDING
 192                    | XICS_STATUS_REJECTED;
 193            }
 194        }
 195    }
 196}
 197
 198static int ics_set_kvm_state(ICSState *ics, int version_id)
 199{
 200    KVMXICSState *icpkvm = KVM_XICS(ics->icp);
 201    uint64_t state;
 202    struct kvm_device_attr attr = {
 203        .flags = 0,
 204        .group = KVM_DEV_XICS_GRP_SOURCES,
 205        .addr = (uint64_t)(uintptr_t)&state,
 206    };
 207    int i;
 208
 209    for (i = 0; i < ics->nr_irqs; i++) {
 210        ICSIRQState *irq = &ics->irqs[i];
 211        int ret;
 212
 213        attr.attr = i + ics->offset;
 214
 215        state = irq->server;
 216        state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK)
 217            << KVM_XICS_PRIORITY_SHIFT;
 218        if (irq->priority != irq->saved_priority) {
 219            assert(irq->priority == 0xff);
 220            state |= KVM_XICS_MASKED;
 221        }
 222
 223        if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
 224            state |= KVM_XICS_LEVEL_SENSITIVE;
 225            if (irq->status & XICS_STATUS_ASSERTED) {
 226                state |= KVM_XICS_PENDING;
 227            }
 228        } else {
 229            if (irq->status & XICS_STATUS_MASKED_PENDING) {
 230                state |= KVM_XICS_PENDING;
 231            }
 232        }
 233
 234        ret = ioctl(icpkvm->kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
 235        if (ret != 0) {
 236            error_report("Unable to restore KVM interrupt controller state"
 237                    " for IRQs %d: %s", i + ics->offset, strerror(errno));
 238            return ret;
 239        }
 240    }
 241
 242    return 0;
 243}
 244
 245static void ics_kvm_set_irq(void *opaque, int srcno, int val)
 246{
 247    ICSState *ics = opaque;
 248    struct kvm_irq_level args;
 249    int rc;
 250
 251    args.irq = srcno + ics->offset;
 252    if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MSI) {
 253        if (!val) {
 254            return;
 255        }
 256        args.level = KVM_INTERRUPT_SET;
 257    } else {
 258        args.level = val ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
 259    }
 260    rc = kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args);
 261    if (rc < 0) {
 262        perror("kvm_irq_line");
 263    }
 264}
 265
 266static void ics_kvm_reset(DeviceState *dev)
 267{
 268    ICSState *ics = ICS(dev);
 269    int i;
 270    uint8_t flags[ics->nr_irqs];
 271
 272    for (i = 0; i < ics->nr_irqs; i++) {
 273        flags[i] = ics->irqs[i].flags;
 274    }
 275
 276    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
 277
 278    for (i = 0; i < ics->nr_irqs; i++) {
 279        ics->irqs[i].priority = 0xff;
 280        ics->irqs[i].saved_priority = 0xff;
 281        ics->irqs[i].flags = flags[i];
 282    }
 283
 284    ics_set_kvm_state(ics, 1);
 285}
 286
 287static void ics_kvm_realize(DeviceState *dev, Error **errp)
 288{
 289    ICSState *ics = ICS(dev);
 290
 291    if (!ics->nr_irqs) {
 292        error_setg(errp, "Number of interrupts needs to be greater 0");
 293        return;
 294    }
 295    ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
 296    ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs);
 297}
 298
 299static void ics_kvm_class_init(ObjectClass *klass, void *data)
 300{
 301    DeviceClass *dc = DEVICE_CLASS(klass);
 302    ICSStateClass *icsc = ICS_CLASS(klass);
 303
 304    dc->realize = ics_kvm_realize;
 305    dc->reset = ics_kvm_reset;
 306    icsc->pre_save = ics_get_kvm_state;
 307    icsc->post_load = ics_set_kvm_state;
 308}
 309
 310static const TypeInfo ics_kvm_info = {
 311    .name = TYPE_KVM_ICS,
 312    .parent = TYPE_ICS,
 313    .instance_size = sizeof(ICSState),
 314    .class_init = ics_kvm_class_init,
 315};
 316
 317/*
 318 * XICS-KVM
 319 */
 320static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
 321{
 322    CPUState *cs;
 323    ICPState *ss;
 324    KVMXICSState *icpkvm = KVM_XICS(icp);
 325
 326    cs = CPU(cpu);
 327    ss = &icp->ss[cs->cpu_index];
 328
 329    assert(cs->cpu_index < icp->nr_servers);
 330    if (icpkvm->kernel_xics_fd == -1) {
 331        abort();
 332    }
 333
 334    /*
 335     * If we are reusing a parked vCPU fd corresponding to the CPU
 336     * which was hot-removed earlier we don't have to renable
 337     * KVM_CAP_IRQ_XICS capability again.
 338     */
 339    if (ss->cap_irq_xics_enabled) {
 340        return;
 341    }
 342
 343    if (icpkvm->kernel_xics_fd != -1) {
 344        int ret;
 345
 346        ss->cs = cs;
 347
 348        ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0,
 349                                  icpkvm->kernel_xics_fd, kvm_arch_vcpu_id(cs));
 350        if (ret < 0) {
 351            error_report("Unable to connect CPU%ld to kernel XICS: %s",
 352                    kvm_arch_vcpu_id(cs), strerror(errno));
 353            exit(1);
 354        }
 355        ss->cap_irq_xics_enabled = true;
 356    }
 357}
 358
 359static void xics_kvm_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
 360{
 361    icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
 362}
 363
 364static void xics_kvm_set_nr_servers(XICSState *icp, uint32_t nr_servers,
 365                                    Error **errp)
 366{
 367    int i;
 368
 369    icp->nr_servers = nr_servers;
 370
 371    icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
 372    for (i = 0; i < icp->nr_servers; i++) {
 373        char buffer[32];
 374        object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_KVM_ICP);
 375        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
 376        object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
 377                                  errp);
 378    }
 379}
 380
 381static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 382                       uint32_t token,
 383                       uint32_t nargs, target_ulong args,
 384                       uint32_t nret, target_ulong rets)
 385{
 386    error_report("pseries: %s must never be called for in-kernel XICS",
 387                 __func__);
 388}
 389
 390static void xics_kvm_realize(DeviceState *dev, Error **errp)
 391{
 392    KVMXICSState *icpkvm = KVM_XICS(dev);
 393    XICSState *icp = XICS_COMMON(dev);
 394    int i, rc;
 395    Error *error = NULL;
 396    struct kvm_create_device xics_create_device = {
 397        .type = KVM_DEV_TYPE_XICS,
 398        .flags = 0,
 399    };
 400
 401    if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
 402        error_setg(errp,
 403                   "KVM and IRQ_XICS capability must be present for in-kernel XICS");
 404        goto fail;
 405    }
 406
 407    spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
 408    spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
 409    spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
 410    spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
 411
 412    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
 413    if (rc < 0) {
 414        error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
 415        goto fail;
 416    }
 417
 418    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_GET_XIVE, "ibm,get-xive");
 419    if (rc < 0) {
 420        error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,get-xive");
 421        goto fail;
 422    }
 423
 424    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_ON, "ibm,int-on");
 425    if (rc < 0) {
 426        error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-on");
 427        goto fail;
 428    }
 429
 430    rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_OFF, "ibm,int-off");
 431    if (rc < 0) {
 432        error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-off");
 433        goto fail;
 434    }
 435
 436    /* Create the kernel ICP */
 437    rc = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &xics_create_device);
 438    if (rc < 0) {
 439        error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS");
 440        goto fail;
 441    }
 442
 443    icpkvm->kernel_xics_fd = xics_create_device.fd;
 444
 445    object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
 446    if (error) {
 447        error_propagate(errp, error);
 448        goto fail;
 449    }
 450
 451    assert(icp->nr_servers);
 452    for (i = 0; i < icp->nr_servers; i++) {
 453        object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
 454        if (error) {
 455            error_propagate(errp, error);
 456            goto fail;
 457        }
 458    }
 459
 460    kvm_kernel_irqchip = true;
 461    kvm_msi_via_irqfd_allowed = true;
 462    kvm_gsi_direct_mapping = true;
 463
 464    return;
 465
 466fail:
 467    kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
 468    kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
 469    kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
 470    kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
 471}
 472
 473static void xics_kvm_initfn(Object *obj)
 474{
 475    XICSState *xics = XICS_COMMON(obj);
 476
 477    xics->ics = ICS(object_new(TYPE_KVM_ICS));
 478    object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
 479    xics->ics->icp = xics;
 480}
 481
 482static void xics_kvm_class_init(ObjectClass *oc, void *data)
 483{
 484    DeviceClass *dc = DEVICE_CLASS(oc);
 485    XICSStateClass *xsc = XICS_COMMON_CLASS(oc);
 486
 487    dc->realize = xics_kvm_realize;
 488    xsc->cpu_setup = xics_kvm_cpu_setup;
 489    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
 490    xsc->set_nr_servers = xics_kvm_set_nr_servers;
 491}
 492
 493static const TypeInfo xics_kvm_info = {
 494    .name          = TYPE_KVM_XICS,
 495    .parent        = TYPE_XICS_COMMON,
 496    .instance_size = sizeof(KVMXICSState),
 497    .class_init    = xics_kvm_class_init,
 498    .instance_init = xics_kvm_initfn,
 499};
 500
 501static void xics_kvm_register_types(void)
 502{
 503    type_register_static(&xics_kvm_info);
 504    type_register_static(&ics_kvm_info);
 505    type_register_static(&icp_kvm_info);
 506}
 507
 508type_init(xics_kvm_register_types)
 509