xref: /openbmc/qemu/hw/intc/xics_kvm.c (revision 99d46107)
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_one(ICSState *ics, int srcno)
217 {
218     uint64_t state;
219     Error *local_err = NULL;
220     ICSIRQState *irq = &ics->irqs[srcno];
221     int ret;
222 
223     state = irq->server;
224     state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK)
225         << KVM_XICS_PRIORITY_SHIFT;
226     if (irq->priority != irq->saved_priority) {
227         assert(irq->priority == 0xff);
228         state |= KVM_XICS_MASKED;
229     }
230 
231     if (irq->flags & XICS_FLAGS_IRQ_LSI) {
232         state |= KVM_XICS_LEVEL_SENSITIVE;
233         if (irq->status & XICS_STATUS_ASSERTED) {
234             state |= KVM_XICS_PENDING;
235         }
236     } else {
237         if (irq->status & XICS_STATUS_MASKED_PENDING) {
238             state |= KVM_XICS_PENDING;
239         }
240     }
241     if (irq->status & XICS_STATUS_PRESENTED) {
242         state |= KVM_XICS_PRESENTED;
243     }
244     if (irq->status & XICS_STATUS_QUEUED) {
245         state |= KVM_XICS_QUEUED;
246     }
247 
248     ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
249                             srcno + ics->offset, &state, true, &local_err);
250     if (local_err) {
251         error_report_err(local_err);
252         return ret;
253     }
254 
255     return 0;
256 }
257 
258 int ics_set_kvm_state(ICSState *ics)
259 {
260     int i;
261 
262     for (i = 0; i < ics->nr_irqs; i++) {
263         int ret;
264 
265         ret = ics_set_kvm_state_one(ics, i);
266         if (ret) {
267             return ret;
268         }
269     }
270 
271     return 0;
272 }
273 
274 void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
275 {
276     struct kvm_irq_level args;
277     int rc;
278 
279     args.irq = srcno + ics->offset;
280     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MSI) {
281         if (!val) {
282             return;
283         }
284         args.level = KVM_INTERRUPT_SET;
285     } else {
286         args.level = val ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
287     }
288     rc = kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args);
289     if (rc < 0) {
290         perror("kvm_irq_line");
291     }
292 }
293 
294 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
295                        uint32_t token,
296                        uint32_t nargs, target_ulong args,
297                        uint32_t nret, target_ulong rets)
298 {
299     error_report("pseries: %s must never be called for in-kernel XICS",
300                  __func__);
301 }
302 
303 int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
304 {
305     int rc;
306 
307     if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
308         error_setg(errp,
309                    "KVM and IRQ_XICS capability must be present for in-kernel XICS");
310         goto fail;
311     }
312 
313     spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
314     spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
315     spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
316     spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
317 
318     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
319     if (rc < 0) {
320         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
321         goto fail;
322     }
323 
324     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_GET_XIVE, "ibm,get-xive");
325     if (rc < 0) {
326         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,get-xive");
327         goto fail;
328     }
329 
330     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_ON, "ibm,int-on");
331     if (rc < 0) {
332         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-on");
333         goto fail;
334     }
335 
336     rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_OFF, "ibm,int-off");
337     if (rc < 0) {
338         error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-off");
339         goto fail;
340     }
341 
342     /* Create the KVM XICS device */
343     rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
344     if (rc < 0) {
345         error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS");
346         goto fail;
347     }
348 
349     kernel_xics_fd = rc;
350     kvm_kernel_irqchip = true;
351     kvm_msi_via_irqfd_allowed = true;
352     kvm_gsi_direct_mapping = true;
353 
354     return 0;
355 
356 fail:
357     kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
358     kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
359     kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
360     kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
361     return -1;
362 }
363