~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to hw/intc/xics_kvm.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
 
41
41
#include <sys/ioctl.h>
42
42
 
43
 
typedef struct KVMXICSState {
44
 
    XICSState parent_obj;
45
 
 
46
 
    int kernel_xics_fd;
47
 
} KVMXICSState;
 
43
static int kernel_xics_fd = -1;
48
44
 
49
45
/*
50
46
 * ICP-KVM
51
47
 */
52
 
static void icp_get_kvm_state(ICPState *ss)
 
48
static void icp_get_kvm_state(ICPState *icp)
53
49
{
54
50
    uint64_t state;
55
51
    struct kvm_one_reg reg = {
59
55
    int ret;
60
56
 
61
57
    /* ICP for this CPU thread is not in use, exiting */
62
 
    if (!ss->cs) {
 
58
    if (!icp->cs) {
63
59
        return;
64
60
    }
65
61
 
66
 
    ret = kvm_vcpu_ioctl(ss->cs, KVM_GET_ONE_REG, &reg);
 
62
    ret = kvm_vcpu_ioctl(icp->cs, KVM_GET_ONE_REG, &reg);
67
63
    if (ret != 0) {
68
64
        error_report("Unable to retrieve KVM interrupt controller state"
69
 
                " for CPU %ld: %s", kvm_arch_vcpu_id(ss->cs), strerror(errno));
 
65
                " for CPU %ld: %s", kvm_arch_vcpu_id(icp->cs), strerror(errno));
70
66
        exit(1);
71
67
    }
72
68
 
73
 
    ss->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT;
74
 
    ss->mfrr = (state >> KVM_REG_PPC_ICP_MFRR_SHIFT)
 
69
    icp->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT;
 
70
    icp->mfrr = (state >> KVM_REG_PPC_ICP_MFRR_SHIFT)
75
71
        & KVM_REG_PPC_ICP_MFRR_MASK;
76
 
    ss->pending_priority = (state >> KVM_REG_PPC_ICP_PPRI_SHIFT)
 
72
    icp->pending_priority = (state >> KVM_REG_PPC_ICP_PPRI_SHIFT)
77
73
        & KVM_REG_PPC_ICP_PPRI_MASK;
78
74
}
79
75
 
80
 
static int icp_set_kvm_state(ICPState *ss, int version_id)
 
76
static int icp_set_kvm_state(ICPState *icp, int version_id)
81
77
{
82
78
    uint64_t state;
83
79
    struct kvm_one_reg reg = {
87
83
    int ret;
88
84
 
89
85
    /* ICP for this CPU thread is not in use, exiting */
90
 
    if (!ss->cs) {
 
86
    if (!icp->cs) {
91
87
        return 0;
92
88
    }
93
89
 
94
 
    state = ((uint64_t)ss->xirr << KVM_REG_PPC_ICP_XISR_SHIFT)
95
 
        | ((uint64_t)ss->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT)
96
 
        | ((uint64_t)ss->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);
 
90
    state = ((uint64_t)icp->xirr << KVM_REG_PPC_ICP_XISR_SHIFT)
 
91
        | ((uint64_t)icp->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT)
 
92
        | ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);
97
93
 
98
 
    ret = kvm_vcpu_ioctl(ss->cs, KVM_SET_ONE_REG, &reg);
 
94
    ret = kvm_vcpu_ioctl(icp->cs, KVM_SET_ONE_REG, &reg);
99
95
    if (ret != 0) {
100
96
        error_report("Unable to restore KVM interrupt controller state (0x%"
101
 
                PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(ss->cs),
 
97
                PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(icp->cs),
102
98
                strerror(errno));
103
99
        return ret;
104
100
    }
106
102
    return 0;
107
103
}
108
104
 
109
 
static void icp_kvm_reset(DeviceState *dev)
 
105
static void icp_kvm_reset(void *dev)
110
106
{
111
107
    ICPState *icp = ICP(dev);
112
108
 
122
118
    icp_set_kvm_state(icp, 1);
123
119
}
124
120
 
 
121
static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu)
 
122
{
 
123
    CPUState *cs = CPU(cpu);
 
124
    int ret;
 
125
 
 
126
    if (kernel_xics_fd == -1) {
 
127
        abort();
 
128
    }
 
129
 
 
130
    /*
 
131
     * If we are reusing a parked vCPU fd corresponding to the CPU
 
132
     * which was hot-removed earlier we don't have to renable
 
133
     * KVM_CAP_IRQ_XICS capability again.
 
134
     */
 
135
    if (icp->cap_irq_xics_enabled) {
 
136
        return;
 
137
    }
 
138
 
 
139
    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd,
 
140
                              kvm_arch_vcpu_id(cs));
 
141
    if (ret < 0) {
 
142
        error_report("Unable to connect CPU%ld to kernel XICS: %s",
 
143
                     kvm_arch_vcpu_id(cs), strerror(errno));
 
144
        exit(1);
 
145
    }
 
146
    icp->cap_irq_xics_enabled = true;
 
147
}
 
148
 
 
149
static void icp_kvm_realize(DeviceState *dev, Error **errp)
 
150
{
 
151
    qemu_register_reset(icp_kvm_reset, dev);
 
152
}
 
153
 
125
154
static void icp_kvm_class_init(ObjectClass *klass, void *data)
126
155
{
127
156
    DeviceClass *dc = DEVICE_CLASS(klass);
128
157
    ICPStateClass *icpc = ICP_CLASS(klass);
129
158
 
130
 
    dc->reset = icp_kvm_reset;
 
159
    dc->realize = icp_kvm_realize;
131
160
    icpc->pre_save = icp_get_kvm_state;
132
161
    icpc->post_load = icp_set_kvm_state;
 
162
    icpc->cpu_setup = icp_kvm_cpu_setup;
133
163
}
134
164
 
135
165
static const TypeInfo icp_kvm_info = {
145
175
 */
146
176
static void ics_get_kvm_state(ICSState *ics)
147
177
{
148
 
    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ics->xics);
149
178
    uint64_t state;
150
179
    struct kvm_device_attr attr = {
151
180
        .flags = 0,
160
189
 
161
190
        attr.attr = i + ics->offset;
162
191
 
163
 
        ret = ioctl(xicskvm->kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
 
192
        ret = ioctl(kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
164
193
        if (ret != 0) {
165
194
            error_report("Unable to retrieve KVM interrupt controller state"
166
195
                    " for IRQ %d: %s", i + ics->offset, strerror(errno));
204
233
 
205
234
static int ics_set_kvm_state(ICSState *ics, int version_id)
206
235
{
207
 
    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ics->xics);
208
236
    uint64_t state;
209
237
    struct kvm_device_attr attr = {
210
238
        .flags = 0,
238
266
            }
239
267
        }
240
268
 
241
 
        ret = ioctl(xicskvm->kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
 
269
        ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
242
270
        if (ret != 0) {
243
271
            error_report("Unable to restore KVM interrupt controller state"
244
272
                    " for IRQs %d: %s", i + ics->offset, strerror(errno));
270
298
    }
271
299
}
272
300
 
273
 
static void ics_kvm_reset(DeviceState *dev)
 
301
static void ics_kvm_reset(void *dev)
274
302
{
275
303
    ICSState *ics = ICS_SIMPLE(dev);
276
304
    int i;
301
329
    }
302
330
    ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
303
331
    ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs);
 
332
 
 
333
    qemu_register_reset(ics_kvm_reset, dev);
304
334
}
305
335
 
306
336
static void ics_kvm_class_init(ObjectClass *klass, void *data)
307
337
{
308
 
    DeviceClass *dc = DEVICE_CLASS(klass);
309
338
    ICSStateClass *icsc = ICS_BASE_CLASS(klass);
310
339
 
311
 
    dc->realize = ics_kvm_realize;
312
 
    dc->reset = ics_kvm_reset;
 
340
    icsc->realize = ics_kvm_realize;
313
341
    icsc->pre_save = ics_get_kvm_state;
314
342
    icsc->post_load = ics_set_kvm_state;
315
343
}
324
352
/*
325
353
 * XICS-KVM
326
354
 */
327
 
static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
328
 
{
329
 
    CPUState *cs;
330
 
    ICPState *ss;
331
 
    KVMXICSState *xicskvm = XICS_SPAPR_KVM(xics);
332
 
    int ret;
333
 
 
334
 
    cs = CPU(cpu);
335
 
    ss = &xics->ss[cs->cpu_index];
336
 
 
337
 
    assert(cs->cpu_index < xics->nr_servers);
338
 
    if (xicskvm->kernel_xics_fd == -1) {
339
 
        abort();
340
 
    }
341
 
 
342
 
    /*
343
 
     * If we are reusing a parked vCPU fd corresponding to the CPU
344
 
     * which was hot-removed earlier we don't have to renable
345
 
     * KVM_CAP_IRQ_XICS capability again.
346
 
     */
347
 
    if (ss->cap_irq_xics_enabled) {
348
 
        return;
349
 
    }
350
 
 
351
 
    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, xicskvm->kernel_xics_fd,
352
 
                              kvm_arch_vcpu_id(cs));
353
 
    if (ret < 0) {
354
 
        error_report("Unable to connect CPU%ld to kernel XICS: %s",
355
 
                     kvm_arch_vcpu_id(cs), strerror(errno));
356
 
        exit(1);
357
 
    }
358
 
    ss->cap_irq_xics_enabled = true;
359
 
}
360
 
 
361
 
static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
362
 
                                 Error **errp)
363
 
{
364
 
    ICSState *ics = QLIST_FIRST(&xics->ics);
365
 
 
366
 
    /* This needs to be deprecated ... */
367
 
    xics->nr_irqs = nr_irqs;
368
 
    if (ics) {
369
 
        ics->nr_irqs = nr_irqs;
370
 
    }
371
 
}
372
 
 
373
 
static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
374
 
                                    Error **errp)
375
 
{
376
 
    xics_set_nr_servers(xics, nr_servers, TYPE_KVM_ICP, errp);
377
 
}
378
355
 
379
356
static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
380
357
                       uint32_t token,
385
362
                 __func__);
386
363
}
387
364
 
388
 
static void xics_kvm_realize(DeviceState *dev, Error **errp)
 
365
int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
389
366
{
390
 
    KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
391
 
    XICSState *xics = XICS_COMMON(dev);
392
 
    ICSState *ics;
393
 
    int i, rc;
394
 
    Error *error = NULL;
 
367
    int rc;
395
368
    struct kvm_create_device xics_create_device = {
396
369
        .type = KVM_DEV_TYPE_XICS,
397
370
        .flags = 0,
439
412
        goto fail;
440
413
    }
441
414
 
442
 
    xicskvm->kernel_xics_fd = xics_create_device.fd;
443
 
 
444
 
    QLIST_FOREACH(ics, &xics->ics, list) {
445
 
        object_property_set_bool(OBJECT(ics), true, "realized", &error);
446
 
        if (error) {
447
 
            error_propagate(errp, error);
448
 
            goto fail;
449
 
        }
450
 
    }
451
 
 
452
 
    assert(xics->nr_servers);
453
 
    for (i = 0; i < xics->nr_servers; i++) {
454
 
        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
455
 
                                 &error);
456
 
        if (error) {
457
 
            error_propagate(errp, error);
458
 
            goto fail;
459
 
        }
460
 
    }
 
415
    kernel_xics_fd = xics_create_device.fd;
461
416
 
462
417
    kvm_kernel_irqchip = true;
463
418
    kvm_msi_via_irqfd_allowed = true;
464
419
    kvm_gsi_direct_mapping = true;
465
420
 
466
 
    return;
 
421
    return rc;
467
422
 
468
423
fail:
469
424
    kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
470
425
    kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
471
426
    kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
472
427
    kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
473
 
}
474
 
 
475
 
static void xics_kvm_initfn(Object *obj)
476
 
{
477
 
    XICSState *xics = XICS_COMMON(obj);
478
 
    ICSState *ics;
479
 
 
480
 
    ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
481
 
    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
482
 
    ics->xics = xics;
483
 
    QLIST_INSERT_HEAD(&xics->ics, ics, list);
484
 
}
485
 
 
486
 
static void xics_kvm_class_init(ObjectClass *oc, void *data)
487
 
{
488
 
    DeviceClass *dc = DEVICE_CLASS(oc);
489
 
    XICSStateClass *xsc = XICS_COMMON_CLASS(oc);
490
 
 
491
 
    dc->realize = xics_kvm_realize;
492
 
    xsc->cpu_setup = xics_kvm_cpu_setup;
493
 
    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
494
 
    xsc->set_nr_servers = xics_kvm_set_nr_servers;
495
 
}
496
 
 
497
 
static const TypeInfo xics_spapr_kvm_info = {
498
 
    .name          = TYPE_XICS_SPAPR_KVM,
499
 
    .parent        = TYPE_XICS_COMMON,
500
 
    .instance_size = sizeof(KVMXICSState),
501
 
    .class_init    = xics_kvm_class_init,
502
 
    .instance_init = xics_kvm_initfn,
503
 
};
 
428
    return -1;
 
429
}
504
430
 
505
431
static void xics_kvm_register_types(void)
506
432
{
507
 
    type_register_static(&xics_spapr_kvm_info);
508
433
    type_register_static(&ics_kvm_info);
509
434
    type_register_static(&icp_kvm_info);
510
435
}