xref: /openbmc/qemu/hw/intc/xics_kvm.c (revision e7bbc9b1)
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 "qemu/osdep.h"
29 #include "qapi/error.h"
30 #include "qemu-common.h"
31 #include "cpu.h"
32 #include "hw/hw.h"
33 #include "trace.h"
34 #include "sysemu/kvm.h"
35 #include "hw/ppc/spapr.h"
36 #include "hw/ppc/xics.h"
37 #include "hw/ppc/xics_spapr.h"
38 #include "kvm_ppc.h"
39 #include "qemu/config-file.h"
40 #include "qemu/error-report.h"
41 
42 #include <sys/ioctl.h>
43 
44 static int kernel_xics_fd = -1;
45 
46 typedef struct KVMEnabledICP {
47     unsigned long vcpu_id;
48     QLIST_ENTRY(KVMEnabledICP) node;
49 } KVMEnabledICP;
50 
51 static QLIST_HEAD(, KVMEnabledICP)
52     kvm_enabled_icps = QLIST_HEAD_INITIALIZER(&kvm_enabled_icps);
53 
54 /*
55  * ICP-KVM
56  */
57 void icp_get_kvm_state(ICPState *icp)
58 {
59     uint64_t state;
60     int ret;
61 
62     /* ICP for this CPU thread is not in use, exiting */
63     if (!icp->cs) {
64         return;
65     }
66 
67     ret = kvm_get_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
68     if (ret != 0) {
69         error_report("Unable to retrieve KVM interrupt controller state"
70                 " for CPU %ld: %s", kvm_arch_vcpu_id(icp->cs), strerror(errno));
71         exit(1);
72     }
73 
74     icp->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT;
75     icp->mfrr = (state >> KVM_REG_PPC_ICP_MFRR_SHIFT)
76         & KVM_REG_PPC_ICP_MFRR_MASK;
77     icp->pending_priority = (state >> KVM_REG_PPC_ICP_PPRI_SHIFT)
78         & KVM_REG_PPC_ICP_PPRI_MASK;
79 }
80 
81 static void do_icp_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
82 {
83     icp_get_kvm_state(arg.host_ptr);
84 }
85 
86 void icp_synchronize_state(ICPState *icp)
87 {
88     if (icp->cs) {
89         run_on_cpu(icp->cs, do_icp_synchronize_state, RUN_ON_CPU_HOST_PTR(icp));
90     }
91 }
92 
93 int icp_set_kvm_state(ICPState *icp)
94 {
95     uint64_t state;
96     int ret;
97 
98     /* ICP for this CPU thread is not in use, exiting */
99     if (!icp->cs) {
100         return 0;
101     }
102 
103     state = ((uint64_t)icp->xirr << KVM_REG_PPC_ICP_XISR_SHIFT)
104         | ((uint64_t)icp->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT)
105         | ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);
106 
107     ret = kvm_set_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
108     if (ret != 0) {
109         error_report("Unable to restore KVM interrupt controller state (0x%"
110                 PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(icp->cs),
111                 strerror(errno));
112         return ret;
113     }
114 
115     return 0;
116 }
117 
118 void icp_kvm_realize(DeviceState *dev, Error **errp)
119 {
120     ICPState *icp = ICP(dev);
121     CPUState *cs;
122     KVMEnabledICP *enabled_icp;
123     unsigned long vcpu_id;
124     int ret;
125 
126     if (kernel_xics_fd == -1) {
127         abort();
128     }
129 
130     cs = icp->cs;
131     vcpu_id = kvm_arch_vcpu_id(cs);
132 
133     /*
134      * If we are reusing a parked vCPU fd corresponding to the CPU
135      * which was hot-removed earlier we don't have to renable
136      * KVM_CAP_IRQ_XICS capability again.
137      */
138     QLIST_FOREACH(enabled_icp, &kvm_enabled_icps, node) {
139         if (enabled_icp->vcpu_id == vcpu_id) {
140             return;
141         }
142     }
143 
144     ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd, vcpu_id);
145     if (ret < 0) {
146         error_setg(errp, "Unable to connect CPU%ld to kernel XICS: %s", vcpu_id,
147                    strerror(errno));
148         return;
149     }
150     enabled_icp = g_malloc(sizeof(*enabled_icp));
151     enabled_icp->vcpu_id = vcpu_id;
152     QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node);
153 }
154 
155 /*
156  * ICS-KVM
157  */
158 void ics_get_kvm_state(ICSState *ics)
159 {
160     uint64_t state;
161     int i;
162 
163     for (i = 0; i < ics->nr_irqs; i++) {
164         ICSIRQState *irq = &ics->irqs[i];
165 
166         kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
167                           i + ics->offset, &state, false, &error_fatal);
168 
169         irq->server = state & KVM_XICS_DESTINATION_MASK;
170         irq->saved_priority = (state >> KVM_XICS_PRIORITY_SHIFT)
171             & KVM_XICS_PRIORITY_MASK;
172         /*
173          * To be consistent with the software emulation in xics.c, we
174          * split out the masked state + priority that we get from the
175          * kernel into 'current priority' (0xff if masked) and
176          * 'saved priority' (if masked, this is the priority the
177          * interrupt had before it was masked).  Masking and unmasking
178          * are done with the ibm,int-off and ibm,int-on RTAS calls.
179          */
180         if (state & KVM_XICS_MASKED) {
181             irq->priority = 0xff;
182         } else {
183             irq->priority = irq->saved_priority;
184         }
185 
186         irq->status = 0;
187         if (state & KVM_XICS_PENDING) {
188             if (state & KVM_XICS_LEVEL_SENSITIVE) {
189                 irq->status |= XICS_STATUS_ASSERTED;
190             } else {
191                 /*
192                  * A pending edge-triggered interrupt (or MSI)
193                  * must have been rejected previously when we
194                  * first detected it and tried to deliver it,
195                  * so mark it as pending and previously rejected
196                  * for consistency with how xics.c works.
197                  */
198                 irq->status |= XICS_STATUS_MASKED_PENDING
199                     | XICS_STATUS_REJECTED;
200             }
201         }
202         if (state & KVM_XICS_PRESENTED) {
203                 irq->status |= XICS_STATUS_PRESENTED;
204         }
205         if (state & KVM_XICS_QUEUED) {
206                 irq->status |= XICS_STATUS_QUEUED;
207         }
208     }
209 }
210 
211 void ics_synchronize_state(ICSState *ics)
212 {
213     ics_get_kvm_state(ics);
214 }
215 
216 int ics_set_kvm_state(ICSState *ics)
217 {
218     uint64_t state;
219     int i;
220     Error *local_err = NULL;
221 
222     for (i = 0; i < ics->nr_irqs; i++) {
223         ICSIRQState *irq = &ics->irqs[i];
224         int ret;
225 
226         state = irq->server;
227         state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK)
228             << KVM_XICS_PRIORITY_SHIFT;
229         if (irq->priority != irq->saved_priority) {
230             assert(irq->priority == 0xff);
231             state |= KVM_XICS_MASKED;
232         }
233 
234         if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
235             state |= KVM_XICS_LEVEL_SENSITIVE;
236             if (irq->status & XICS_STATUS_ASSERTED) {
237                 state |= KVM_XICS_PENDING;
238             }
239         } else {
240             if (irq->status & XICS_STATUS_MASKED_PENDING) {
241                 state |= KVM_XICS_PENDING;
242             }
243         }
244         if (irq->status & XICS_STATUS_PRESENTED) {
245                 state |= KVM_XICS_PRESENTED;
246         }
247         if (irq->status & XICS_STATUS_QUEUED) {
248                 state |= KVM_XICS_QUEUED;
249         }
250 
251         ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
252                                 i + ics->offset, &state, true, &local_err);
253         if (local_err) {
254             error_report_err(local_err);
255             return ret;
256         }
257     }
258 
259     return 0;
260 }
261 
262 void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
263 {
264     struct kvm_irq_level args;
265     int rc;
266 
267     args.irq = srcno + ics->offset;
268     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MSI) {
269         if (!val) {
270             return;
271         }
272         args.level = KVM_INTERRUPT_SET;
273     } else {
274         args.level = val ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
275     }
276     rc = kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args);
277     if (rc < 0) {
278         perror("kvm_irq_line");
279     }
280 }
281 
282 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
283                        uint32_t token,
284                        uint32_t nargs, target_ulong args,
285                        uint32_t nret, target_ulong rets)
286 {
287     error_report("pseries: %s must never be called for in-kernel XICS",
288                  __func__);
289 }
290 
291 int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
292 {
293     int rc;
294 
295     if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
296         error_setg(errp,
297                    "KVM and IRQ_XICS capability must be present for in-kernel XICS");
298         goto fail;
299     }
300 
301     spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
302     spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
303     spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
304     spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
305 
306     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
307     if (rc < 0) {
308         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
309         goto fail;
310     }
311 
312     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_GET_XIVE, "ibm,get-xive");
313     if (rc < 0) {
314         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,get-xive");
315         goto fail;
316     }
317 
318     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_ON, "ibm,int-on");
319     if (rc < 0) {
320         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-on");
321         goto fail;
322     }
323 
324     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_OFF, "ibm,int-off");
325     if (rc < 0) {
326         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-off");
327         goto fail;
328     }
329 
330     /* Create the KVM XICS device */
331     rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
332     if (rc < 0) {
333         error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS");
334         goto fail;
335     }
336 
337     kernel_xics_fd = rc;
338     kvm_kernel_irqchip = true;
339     kvm_msi_via_irqfd_allowed = true;
340     kvm_gsi_direct_mapping = true;
341 
342     return 0;
343 
344 fail:
345     kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
346     kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
347     kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
348     kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
349     return -1;
350 }
351