xref: /openbmc/qemu/hw/s390x/s390-pci-inst.c (revision f4a69168)
1 /*
2  * s390 PCI instructions
3  *
4  * Copyright 2014 IBM Corp.
5  * Author(s): Frank Blaschka <frank.blaschka@de.ibm.com>
6  *            Hong Bo Li <lihbbj@cn.ibm.com>
7  *            Yi Min Zhao <zyimin@cn.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or (at
10  * your option) any later version. See the COPYING file in the top-level
11  * directory.
12  */
13 
14 #include "qemu/osdep.h"
15 #include "exec/memop.h"
16 #include "exec/memory.h"
17 #include "qemu/error-report.h"
18 #include "sysemu/hw_accel.h"
19 #include "hw/pci/pci_device.h"
20 #include "hw/s390x/s390-pci-inst.h"
21 #include "hw/s390x/s390-pci-bus.h"
22 #include "hw/s390x/s390-pci-kvm.h"
23 #include "hw/s390x/s390-pci-vfio.h"
24 #include "hw/s390x/tod.h"
25 
26 #include "trace.h"
27 
inc_dma_avail(S390PCIIOMMU * iommu)28 static inline void inc_dma_avail(S390PCIIOMMU *iommu)
29 {
30     if (iommu->dma_limit) {
31         iommu->dma_limit->avail++;
32     }
33 }
34 
dec_dma_avail(S390PCIIOMMU * iommu)35 static inline void dec_dma_avail(S390PCIIOMMU *iommu)
36 {
37     if (iommu->dma_limit) {
38         iommu->dma_limit->avail--;
39     }
40 }
41 
s390_set_status_code(CPUS390XState * env,uint8_t r,uint64_t status_code)42 static void s390_set_status_code(CPUS390XState *env,
43                                  uint8_t r, uint64_t status_code)
44 {
45     env->regs[r] &= ~0xff000000ULL;
46     env->regs[r] |= (status_code & 0xff) << 24;
47 }
48 
list_pci(ClpReqRspListPci * rrb,uint8_t * cc)49 static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
50 {
51     S390PCIBusDevice *pbdev = NULL;
52     S390pciState *s = s390_get_phb();
53     uint32_t res_code, initial_l2, g_l2;
54     int rc, i;
55     uint64_t resume_token;
56 
57     rc = 0;
58     if (lduw_p(&rrb->request.hdr.len) != 32) {
59         res_code = CLP_RC_LEN;
60         rc = -EINVAL;
61         goto out;
62     }
63 
64     if ((ldl_p(&rrb->request.fmt) & CLP_MASK_FMT) != 0) {
65         res_code = CLP_RC_FMT;
66         rc = -EINVAL;
67         goto out;
68     }
69 
70     if ((ldl_p(&rrb->request.fmt) & ~CLP_MASK_FMT) != 0 ||
71         ldq_p(&rrb->request.reserved1) != 0) {
72         res_code = CLP_RC_RESNOT0;
73         rc = -EINVAL;
74         goto out;
75     }
76 
77     resume_token = ldq_p(&rrb->request.resume_token);
78 
79     if (resume_token) {
80         pbdev = s390_pci_find_dev_by_idx(s, resume_token);
81         if (!pbdev) {
82             res_code = CLP_RC_LISTPCI_BADRT;
83             rc = -EINVAL;
84             goto out;
85         }
86     } else {
87         pbdev = s390_pci_find_next_avail_dev(s, NULL);
88     }
89 
90     if (lduw_p(&rrb->response.hdr.len) < 48) {
91         res_code = CLP_RC_8K;
92         rc = -EINVAL;
93         goto out;
94     }
95 
96     initial_l2 = lduw_p(&rrb->response.hdr.len);
97     if ((initial_l2 - LIST_PCI_HDR_LEN) % sizeof(ClpFhListEntry)
98         != 0) {
99         res_code = CLP_RC_LEN;
100         rc = -EINVAL;
101         *cc = 3;
102         goto out;
103     }
104 
105     stl_p(&rrb->response.fmt, 0);
106     stq_p(&rrb->response.reserved1, 0);
107     stl_p(&rrb->response.mdd, FH_MASK_SHM);
108     stw_p(&rrb->response.max_fn, PCI_MAX_FUNCTIONS);
109     rrb->response.flags = UID_CHECKING_ENABLED;
110     rrb->response.entry_size = sizeof(ClpFhListEntry);
111 
112     i = 0;
113     g_l2 = LIST_PCI_HDR_LEN;
114     while (g_l2 < initial_l2 && pbdev) {
115         stw_p(&rrb->response.fh_list[i].device_id,
116             pci_get_word(pbdev->pdev->config + PCI_DEVICE_ID));
117         stw_p(&rrb->response.fh_list[i].vendor_id,
118             pci_get_word(pbdev->pdev->config + PCI_VENDOR_ID));
119         /* Ignore RESERVED devices. */
120         stl_p(&rrb->response.fh_list[i].config,
121             pbdev->state == ZPCI_FS_STANDBY ? 0 : 1 << 31);
122         stl_p(&rrb->response.fh_list[i].fid, pbdev->fid);
123         stl_p(&rrb->response.fh_list[i].fh, pbdev->fh);
124 
125         g_l2 += sizeof(ClpFhListEntry);
126         /* Add endian check for DPRINTF? */
127         trace_s390_pci_list_entry(g_l2,
128                 lduw_p(&rrb->response.fh_list[i].vendor_id),
129                 lduw_p(&rrb->response.fh_list[i].device_id),
130                 ldl_p(&rrb->response.fh_list[i].fid),
131                 ldl_p(&rrb->response.fh_list[i].fh));
132         pbdev = s390_pci_find_next_avail_dev(s, pbdev);
133         i++;
134     }
135 
136     if (!pbdev) {
137         resume_token = 0;
138     } else {
139         resume_token = pbdev->fh & FH_MASK_INDEX;
140     }
141     stq_p(&rrb->response.resume_token, resume_token);
142     stw_p(&rrb->response.hdr.len, g_l2);
143     stw_p(&rrb->response.hdr.rsp, CLP_RC_OK);
144 out:
145     if (rc) {
146         trace_s390_pci_list(rc);
147         stw_p(&rrb->response.hdr.rsp, res_code);
148     }
149     return rc;
150 }
151 
clp_service_call(S390CPU * cpu,uint8_t r2,uintptr_t ra)152 int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
153 {
154     ClpReqHdr *reqh;
155     ClpRspHdr *resh;
156     S390PCIBusDevice *pbdev;
157     uint32_t req_len;
158     uint32_t res_len;
159     uint8_t buffer[4096 * 2];
160     uint8_t cc = 0;
161     CPUS390XState *env = &cpu->env;
162     S390pciState *s = s390_get_phb();
163     int i;
164 
165     if (env->psw.mask & PSW_MASK_PSTATE) {
166         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
167         return 0;
168     }
169 
170     if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) {
171         s390_cpu_virt_mem_handle_exc(cpu, ra);
172         return 0;
173     }
174     reqh = (ClpReqHdr *)buffer;
175     req_len = lduw_p(&reqh->len);
176     if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {
177         s390_program_interrupt(env, PGM_OPERAND, ra);
178         return 0;
179     }
180 
181     if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
182                                req_len + sizeof(*resh))) {
183         s390_cpu_virt_mem_handle_exc(cpu, ra);
184         return 0;
185     }
186     resh = (ClpRspHdr *)(buffer + req_len);
187     res_len = lduw_p(&resh->len);
188     if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {
189         s390_program_interrupt(env, PGM_OPERAND, ra);
190         return 0;
191     }
192     if ((req_len + res_len) > 8192) {
193         s390_program_interrupt(env, PGM_OPERAND, ra);
194         return 0;
195     }
196 
197     if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
198                                req_len + res_len)) {
199         s390_cpu_virt_mem_handle_exc(cpu, ra);
200         return 0;
201     }
202 
203     if (req_len != 32) {
204         stw_p(&resh->rsp, CLP_RC_LEN);
205         goto out;
206     }
207 
208     switch (lduw_p(&reqh->cmd)) {
209     case CLP_LIST_PCI: {
210         ClpReqRspListPci *rrb = (ClpReqRspListPci *)buffer;
211         list_pci(rrb, &cc);
212         break;
213     }
214     case CLP_SET_PCI_FN: {
215         ClpReqSetPci *reqsetpci = (ClpReqSetPci *)reqh;
216         ClpRspSetPci *ressetpci = (ClpRspSetPci *)resh;
217 
218         pbdev = s390_pci_find_dev_by_fh(s, ldl_p(&reqsetpci->fh));
219         if (!pbdev) {
220                 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FH);
221                 goto out;
222         }
223 
224         switch (reqsetpci->oc) {
225         case CLP_SET_ENABLE_PCI_FN:
226             switch (reqsetpci->ndas) {
227             case 0:
228                 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_DMAAS);
229                 goto out;
230             case 1:
231                 break;
232             default:
233                 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_RES);
234                 goto out;
235             }
236 
237             if (pbdev->fh & FH_MASK_ENABLE) {
238                 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
239                 goto out;
240             }
241 
242             /*
243              * Take this opportunity to make sure we still have an accurate
244              * host fh.  It's possible part of the handle changed while the
245              * device was disabled to the guest (e.g. vfio hot reset for
246              * ISM during plug)
247              */
248             if (pbdev->interp) {
249                 /* Take this opportunity to make sure we are sync'd with host */
250                 if (!s390_pci_get_host_fh(pbdev, &pbdev->fh) ||
251                     !(pbdev->fh & FH_MASK_ENABLE)) {
252                     stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FH);
253                     goto out;
254                 }
255             }
256             pbdev->fh |= FH_MASK_ENABLE;
257             pbdev->state = ZPCI_FS_ENABLED;
258             stl_p(&ressetpci->fh, pbdev->fh);
259             stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
260             break;
261         case CLP_SET_DISABLE_PCI_FN:
262             if (!(pbdev->fh & FH_MASK_ENABLE)) {
263                 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
264                 goto out;
265             }
266             device_cold_reset(DEVICE(pbdev));
267             pbdev->fh &= ~FH_MASK_ENABLE;
268             pbdev->state = ZPCI_FS_DISABLED;
269             stl_p(&ressetpci->fh, pbdev->fh);
270             stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
271             break;
272         default:
273             trace_s390_pci_unknown("set-pci", reqsetpci->oc);
274             stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
275             break;
276         }
277         break;
278     }
279     case CLP_QUERY_PCI_FN: {
280         ClpReqQueryPci *reqquery = (ClpReqQueryPci *)reqh;
281         ClpRspQueryPci *resquery = (ClpRspQueryPci *)resh;
282 
283         pbdev = s390_pci_find_dev_by_fh(s, ldl_p(&reqquery->fh));
284         if (!pbdev) {
285             trace_s390_pci_nodev("query", ldl_p(&reqquery->fh));
286             stw_p(&resquery->hdr.rsp, CLP_RC_SETPCIFN_FH);
287             goto out;
288         }
289 
290         stq_p(&resquery->sdma, pbdev->zpci_fn.sdma);
291         stq_p(&resquery->edma, pbdev->zpci_fn.edma);
292         stw_p(&resquery->pchid, pbdev->zpci_fn.pchid);
293         stw_p(&resquery->vfn, pbdev->zpci_fn.vfn);
294         resquery->flags = pbdev->zpci_fn.flags;
295         resquery->pfgid = pbdev->zpci_fn.pfgid;
296         resquery->pft = pbdev->zpci_fn.pft;
297         resquery->fmbl = pbdev->zpci_fn.fmbl;
298         stl_p(&resquery->fid, pbdev->zpci_fn.fid);
299         stl_p(&resquery->uid, pbdev->zpci_fn.uid);
300         memcpy(resquery->pfip, pbdev->zpci_fn.pfip, CLP_PFIP_NR_SEGMENTS);
301         memcpy(resquery->util_str, pbdev->zpci_fn.util_str, CLP_UTIL_STR_LEN);
302 
303         for (i = 0; i < PCI_BAR_COUNT; i++) {
304             uint32_t data = pci_get_long(pbdev->pdev->config +
305                 PCI_BASE_ADDRESS_0 + (i * 4));
306 
307             stl_p(&resquery->bar[i], data);
308             resquery->bar_size[i] = pbdev->pdev->io_regions[i].size ?
309                                     ctz64(pbdev->pdev->io_regions[i].size) : 0;
310             trace_s390_pci_bar(i,
311                     ldl_p(&resquery->bar[i]),
312                     pbdev->pdev->io_regions[i].size,
313                     resquery->bar_size[i]);
314         }
315 
316         stw_p(&resquery->hdr.rsp, CLP_RC_OK);
317         break;
318     }
319     case CLP_QUERY_PCI_FNGRP: {
320         ClpRspQueryPciGrp *resgrp = (ClpRspQueryPciGrp *)resh;
321 
322         ClpReqQueryPciGrp *reqgrp = (ClpReqQueryPciGrp *)reqh;
323         S390PCIGroup *group;
324 
325         group = s390_group_find(reqgrp->g);
326         if (!group) {
327             /* We do not allow access to unknown groups */
328             /* The group must have been obtained with a vfio device */
329             stw_p(&resgrp->hdr.rsp, CLP_RC_QUERYPCIFG_PFGID);
330             goto out;
331         }
332         resgrp->fr = group->zpci_group.fr;
333         stq_p(&resgrp->dasm, group->zpci_group.dasm);
334         stq_p(&resgrp->msia, group->zpci_group.msia);
335         stw_p(&resgrp->mui, group->zpci_group.mui);
336         stw_p(&resgrp->i, group->zpci_group.i);
337         stw_p(&resgrp->maxstbl, group->zpci_group.maxstbl);
338         resgrp->version = group->zpci_group.version;
339         resgrp->dtsm = group->zpci_group.dtsm;
340         stw_p(&resgrp->hdr.rsp, CLP_RC_OK);
341         break;
342     }
343     default:
344         trace_s390_pci_unknown("clp", lduw_p(&reqh->cmd));
345         stw_p(&resh->rsp, CLP_RC_CMD);
346         break;
347     }
348 
349 out:
350     if (s390_cpu_virt_mem_write(cpu, env->regs[r2], r2, buffer,
351                                 req_len + res_len)) {
352         s390_cpu_virt_mem_handle_exc(cpu, ra);
353         return 0;
354     }
355     setcc(cpu, cc);
356     return 0;
357 }
358 
359 /**
360  * Swap data contained in s390x big endian registers to little endian
361  * PCI bars.
362  *
363  * @ptr: a pointer to a uint64_t data field
364  * @len: the length of the valid data, must be 1,2,4 or 8
365  */
zpci_endian_swap(uint64_t * ptr,uint8_t len)366 static int zpci_endian_swap(uint64_t *ptr, uint8_t len)
367 {
368     uint64_t data = *ptr;
369 
370     switch (len) {
371     case 1:
372         break;
373     case 2:
374         data = bswap16(data);
375         break;
376     case 4:
377         data = bswap32(data);
378         break;
379     case 8:
380         data = bswap64(data);
381         break;
382     default:
383         return -EINVAL;
384     }
385     *ptr = data;
386     return 0;
387 }
388 
s390_get_subregion(MemoryRegion * mr,uint64_t offset,uint8_t len)389 static MemoryRegion *s390_get_subregion(MemoryRegion *mr, uint64_t offset,
390                                         uint8_t len)
391 {
392     MemoryRegion *subregion;
393     uint64_t subregion_size;
394 
395     QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
396         subregion_size = int128_get64(subregion->size);
397         if ((offset >= subregion->addr) &&
398             (offset + len) <= (subregion->addr + subregion_size)) {
399             mr = subregion;
400             break;
401         }
402     }
403     return mr;
404 }
405 
zpci_read_bar(S390PCIBusDevice * pbdev,uint8_t pcias,uint64_t offset,uint64_t * data,uint8_t len)406 static MemTxResult zpci_read_bar(S390PCIBusDevice *pbdev, uint8_t pcias,
407                                  uint64_t offset, uint64_t *data, uint8_t len)
408 {
409     MemoryRegion *mr;
410 
411     mr = pbdev->pdev->io_regions[pcias].memory;
412     mr = s390_get_subregion(mr, offset, len);
413     offset -= mr->addr;
414     return memory_region_dispatch_read(mr, offset, data,
415                                        size_memop(len) | MO_BE,
416                                        MEMTXATTRS_UNSPECIFIED);
417 }
418 
pcilg_service_call(S390CPU * cpu,uint8_t r1,uint8_t r2,uintptr_t ra)419 int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
420 {
421     CPUS390XState *env = &cpu->env;
422     S390PCIBusDevice *pbdev;
423     uint64_t offset;
424     uint64_t data;
425     MemTxResult result;
426     uint8_t len;
427     uint32_t fh;
428     uint8_t pcias;
429 
430     if (env->psw.mask & PSW_MASK_PSTATE) {
431         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
432         return 0;
433     }
434 
435     if (r2 & 0x1) {
436         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
437         return 0;
438     }
439 
440     fh = env->regs[r2] >> 32;
441     pcias = (env->regs[r2] >> 16) & 0xf;
442     len = env->regs[r2] & 0xf;
443     offset = env->regs[r2 + 1];
444 
445     if (!(fh & FH_MASK_ENABLE)) {
446         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
447         return 0;
448     }
449 
450     pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
451     if (!pbdev) {
452         trace_s390_pci_nodev("pcilg", fh);
453         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
454         return 0;
455     }
456 
457     switch (pbdev->state) {
458     case ZPCI_FS_PERMANENT_ERROR:
459     case ZPCI_FS_ERROR:
460         setcc(cpu, ZPCI_PCI_LS_ERR);
461         s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
462         return 0;
463     default:
464         break;
465     }
466 
467     switch (pcias) {
468     case ZPCI_IO_BAR_MIN...ZPCI_IO_BAR_MAX:
469         if (!len || (len > (8 - (offset & 0x7)))) {
470             s390_program_interrupt(env, PGM_OPERAND, ra);
471             return 0;
472         }
473         result = zpci_read_bar(pbdev, pcias, offset, &data, len);
474         if (result != MEMTX_OK) {
475             s390_program_interrupt(env, PGM_OPERAND, ra);
476             return 0;
477         }
478         break;
479     case ZPCI_CONFIG_BAR:
480         if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
481             s390_program_interrupt(env, PGM_OPERAND, ra);
482             return 0;
483         }
484         data =  pci_host_config_read_common(
485                    pbdev->pdev, offset, pci_config_size(pbdev->pdev), len);
486 
487         if (zpci_endian_swap(&data, len)) {
488             s390_program_interrupt(env, PGM_OPERAND, ra);
489             return 0;
490         }
491         break;
492     default:
493         trace_s390_pci_invalid("pcilg", fh);
494         setcc(cpu, ZPCI_PCI_LS_ERR);
495         s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS);
496         return 0;
497     }
498 
499     pbdev->fmb.counter[ZPCI_FMB_CNT_LD]++;
500 
501     env->regs[r1] = data;
502     setcc(cpu, ZPCI_PCI_LS_OK);
503     return 0;
504 }
505 
zpci_write_bar(S390PCIBusDevice * pbdev,uint8_t pcias,uint64_t offset,uint64_t data,uint8_t len)506 static MemTxResult zpci_write_bar(S390PCIBusDevice *pbdev, uint8_t pcias,
507                                   uint64_t offset, uint64_t data, uint8_t len)
508 {
509     MemoryRegion *mr;
510 
511     mr = pbdev->pdev->io_regions[pcias].memory;
512     mr = s390_get_subregion(mr, offset, len);
513     offset -= mr->addr;
514     return memory_region_dispatch_write(mr, offset, data,
515                                         size_memop(len) | MO_BE,
516                                         MEMTXATTRS_UNSPECIFIED);
517 }
518 
pcistg_service_call(S390CPU * cpu,uint8_t r1,uint8_t r2,uintptr_t ra)519 int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
520 {
521     CPUS390XState *env = &cpu->env;
522     uint64_t offset, data;
523     S390PCIBusDevice *pbdev;
524     MemTxResult result;
525     uint8_t len;
526     uint32_t fh;
527     uint8_t pcias;
528 
529     if (env->psw.mask & PSW_MASK_PSTATE) {
530         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
531         return 0;
532     }
533 
534     if (r2 & 0x1) {
535         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
536         return 0;
537     }
538 
539     fh = env->regs[r2] >> 32;
540     pcias = (env->regs[r2] >> 16) & 0xf;
541     len = env->regs[r2] & 0xf;
542     offset = env->regs[r2 + 1];
543     data = env->regs[r1];
544 
545     if (!(fh & FH_MASK_ENABLE)) {
546         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
547         return 0;
548     }
549 
550     pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
551     if (!pbdev) {
552         trace_s390_pci_nodev("pcistg", fh);
553         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
554         return 0;
555     }
556 
557     switch (pbdev->state) {
558     /* ZPCI_FS_RESERVED, ZPCI_FS_STANDBY and ZPCI_FS_DISABLED
559      * are already covered by the FH_MASK_ENABLE check above
560      */
561     case ZPCI_FS_PERMANENT_ERROR:
562     case ZPCI_FS_ERROR:
563         setcc(cpu, ZPCI_PCI_LS_ERR);
564         s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
565         return 0;
566     default:
567         break;
568     }
569 
570     switch (pcias) {
571         /* A ZPCI PCI card may use any BAR from BAR 0 to BAR 5 */
572     case ZPCI_IO_BAR_MIN...ZPCI_IO_BAR_MAX:
573         /* Check length:
574          * A length of 0 is invalid and length should not cross a double word
575          */
576         if (!len || (len > (8 - (offset & 0x7)))) {
577             s390_program_interrupt(env, PGM_OPERAND, ra);
578             return 0;
579         }
580 
581         result = zpci_write_bar(pbdev, pcias, offset, data, len);
582         if (result != MEMTX_OK) {
583             s390_program_interrupt(env, PGM_OPERAND, ra);
584             return 0;
585         }
586         break;
587     case ZPCI_CONFIG_BAR:
588         /* ZPCI uses the pseudo BAR number 15 as configuration space */
589         /* possible access lengths are 1,2,4 and must not cross a word */
590         if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
591             s390_program_interrupt(env, PGM_OPERAND, ra);
592             return 0;
593         }
594         /* len = 1,2,4 so we do not need to test */
595         zpci_endian_swap(&data, len);
596         pci_host_config_write_common(pbdev->pdev, offset,
597                                      pci_config_size(pbdev->pdev),
598                                      data, len);
599         break;
600     default:
601         trace_s390_pci_invalid("pcistg", fh);
602         setcc(cpu, ZPCI_PCI_LS_ERR);
603         s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS);
604         return 0;
605     }
606 
607     pbdev->fmb.counter[ZPCI_FMB_CNT_ST]++;
608 
609     setcc(cpu, ZPCI_PCI_LS_OK);
610     return 0;
611 }
612 
s390_pci_update_iotlb(S390PCIIOMMU * iommu,S390IOTLBEntry * entry)613 static uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
614                                       S390IOTLBEntry *entry)
615 {
616     S390IOTLBEntry *cache = g_hash_table_lookup(iommu->iotlb, &entry->iova);
617     IOMMUTLBEvent event = {
618         .type = entry->perm ? IOMMU_NOTIFIER_MAP : IOMMU_NOTIFIER_UNMAP,
619         .entry = {
620             .target_as = &address_space_memory,
621             .iova = entry->iova,
622             .translated_addr = entry->translated_addr,
623             .perm = entry->perm,
624             .addr_mask = ~TARGET_PAGE_MASK,
625         },
626     };
627 
628     if (event.type == IOMMU_NOTIFIER_UNMAP) {
629         if (!cache) {
630             goto out;
631         }
632         g_hash_table_remove(iommu->iotlb, &entry->iova);
633         inc_dma_avail(iommu);
634         /* Don't notify the iommu yet, maybe we can bundle contiguous unmaps */
635         goto out;
636     } else {
637         if (cache) {
638             if (cache->perm == entry->perm &&
639                 cache->translated_addr == entry->translated_addr) {
640                 goto out;
641             }
642 
643             event.type = IOMMU_NOTIFIER_UNMAP;
644             event.entry.perm = IOMMU_NONE;
645             memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
646             event.type = IOMMU_NOTIFIER_MAP;
647             event.entry.perm = entry->perm;
648         }
649 
650         cache = g_new(S390IOTLBEntry, 1);
651         cache->iova = entry->iova;
652         cache->translated_addr = entry->translated_addr;
653         cache->len = TARGET_PAGE_SIZE;
654         cache->perm = entry->perm;
655         g_hash_table_replace(iommu->iotlb, &cache->iova, cache);
656         dec_dma_avail(iommu);
657     }
658 
659     /*
660      * All associated iotlb entries have already been cleared, trigger the
661      * unmaps.
662      */
663     memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
664 
665 out:
666     return iommu->dma_limit ? iommu->dma_limit->avail : 1;
667 }
668 
s390_pci_batch_unmap(S390PCIIOMMU * iommu,uint64_t iova,uint64_t len)669 static void s390_pci_batch_unmap(S390PCIIOMMU *iommu, uint64_t iova,
670                                  uint64_t len)
671 {
672     uint64_t remain = len, start = iova, end = start + len - 1, mask, size;
673     IOMMUTLBEvent event = {
674         .type = IOMMU_NOTIFIER_UNMAP,
675         .entry = {
676             .target_as = &address_space_memory,
677             .translated_addr = 0,
678             .perm = IOMMU_NONE,
679         },
680     };
681 
682     while (remain >= TARGET_PAGE_SIZE) {
683         mask = dma_aligned_pow2_mask(start, end, 64);
684         size = mask + 1;
685         event.entry.iova = start;
686         event.entry.addr_mask = mask;
687         memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
688         start += size;
689         remain -= size;
690     }
691 }
692 
rpcit_service_call(S390CPU * cpu,uint8_t r1,uint8_t r2,uintptr_t ra)693 int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
694 {
695     CPUS390XState *env = &cpu->env;
696     uint64_t iova, coalesce = 0;
697     uint32_t fh;
698     uint16_t error = 0;
699     S390PCIBusDevice *pbdev;
700     S390PCIIOMMU *iommu;
701     S390IOTLBEntry entry;
702     hwaddr start, end, sstart;
703     uint32_t dma_avail;
704     bool again;
705 
706     if (env->psw.mask & PSW_MASK_PSTATE) {
707         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
708         return 0;
709     }
710 
711     if (r2 & 0x1) {
712         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
713         return 0;
714     }
715 
716     fh = env->regs[r1] >> 32;
717     sstart = start = env->regs[r2];
718     end = start + env->regs[r2 + 1];
719 
720     pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
721     if (!pbdev) {
722         trace_s390_pci_nodev("rpcit", fh);
723         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
724         return 0;
725     }
726 
727     switch (pbdev->state) {
728     case ZPCI_FS_RESERVED:
729     case ZPCI_FS_STANDBY:
730     case ZPCI_FS_DISABLED:
731     case ZPCI_FS_PERMANENT_ERROR:
732         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
733         return 0;
734     case ZPCI_FS_ERROR:
735         setcc(cpu, ZPCI_PCI_LS_ERR);
736         s390_set_status_code(env, r1, ZPCI_MOD_ST_ERROR_RECOVER);
737         return 0;
738     default:
739         break;
740     }
741 
742     iommu = pbdev->iommu;
743     if (iommu->dma_limit) {
744         dma_avail = iommu->dma_limit->avail;
745     } else {
746         dma_avail = 1;
747     }
748     if (!iommu->g_iota) {
749         error = ERR_EVENT_INVALAS;
750         goto err;
751     }
752 
753     if (end < iommu->pba || start > iommu->pal) {
754         error = ERR_EVENT_OORANGE;
755         goto err;
756     }
757 
758  retry:
759     start = sstart;
760     again = false;
761     while (start < end) {
762         error = s390_guest_io_table_walk(iommu->g_iota, start, &entry);
763         if (error) {
764             break;
765         }
766 
767         /*
768          * If this is an unmap of a PTE, let's try to coalesce multiple unmaps
769          * into as few notifier events as possible.
770          */
771         if (entry.perm == IOMMU_NONE && entry.len == TARGET_PAGE_SIZE) {
772             if (coalesce == 0) {
773                 iova = entry.iova;
774             }
775             coalesce += entry.len;
776         } else if (coalesce > 0) {
777             /* Unleash the coalesced unmap before processing a new map */
778             s390_pci_batch_unmap(iommu, iova, coalesce);
779             coalesce = 0;
780         }
781 
782         start += entry.len;
783         while (entry.iova < start && entry.iova < end) {
784             if (dma_avail > 0 || entry.perm == IOMMU_NONE) {
785                 dma_avail = s390_pci_update_iotlb(iommu, &entry);
786                 entry.iova += TARGET_PAGE_SIZE;
787                 entry.translated_addr += TARGET_PAGE_SIZE;
788             } else {
789                 /*
790                  * We are unable to make a new mapping at this time, continue
791                  * on and hopefully free up more space.  Then attempt another
792                  * pass.
793                  */
794                 again = true;
795                 break;
796             }
797         }
798     }
799     if (coalesce) {
800             /* Unleash the coalesced unmap before finishing rpcit */
801             s390_pci_batch_unmap(iommu, iova, coalesce);
802             coalesce = 0;
803     }
804     if (again && dma_avail > 0)
805         goto retry;
806 err:
807     if (error) {
808         pbdev->state = ZPCI_FS_ERROR;
809         setcc(cpu, ZPCI_PCI_LS_ERR);
810         s390_set_status_code(env, r1, ZPCI_PCI_ST_FUNC_IN_ERR);
811         s390_pci_generate_error_event(error, pbdev->fh, pbdev->fid, start, 0);
812     } else {
813         pbdev->fmb.counter[ZPCI_FMB_CNT_RPCIT]++;
814         if (dma_avail > 0) {
815             setcc(cpu, ZPCI_PCI_LS_OK);
816         } else {
817             /* vfio DMA mappings are exhausted, trigger a RPCIT */
818             setcc(cpu, ZPCI_PCI_LS_ERR);
819             s390_set_status_code(env, r1, ZPCI_RPCIT_ST_INSUFF_RES);
820         }
821     }
822     return 0;
823 }
824 
pcistb_service_call(S390CPU * cpu,uint8_t r1,uint8_t r3,uint64_t gaddr,uint8_t ar,uintptr_t ra)825 int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
826                         uint8_t ar, uintptr_t ra)
827 {
828     CPUS390XState *env = &cpu->env;
829     S390PCIBusDevice *pbdev;
830     MemoryRegion *mr;
831     MemTxResult result;
832     uint64_t offset;
833     int i;
834     uint32_t fh;
835     uint8_t pcias;
836     uint16_t len;
837     uint8_t buffer[128];
838 
839     if (env->psw.mask & PSW_MASK_PSTATE) {
840         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
841         return 0;
842     }
843 
844     fh = env->regs[r1] >> 32;
845     pcias = (env->regs[r1] >> 16) & 0xf;
846     len = env->regs[r1] & 0x1fff;
847     offset = env->regs[r3];
848 
849     if (!(fh & FH_MASK_ENABLE)) {
850         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
851         return 0;
852     }
853 
854     pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
855     if (!pbdev) {
856         trace_s390_pci_nodev("pcistb", fh);
857         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
858         return 0;
859     }
860 
861     switch (pbdev->state) {
862     case ZPCI_FS_PERMANENT_ERROR:
863     case ZPCI_FS_ERROR:
864         setcc(cpu, ZPCI_PCI_LS_ERR);
865         s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED);
866         return 0;
867     default:
868         break;
869     }
870 
871     if (pcias > ZPCI_IO_BAR_MAX) {
872         trace_s390_pci_invalid("pcistb", fh);
873         setcc(cpu, ZPCI_PCI_LS_ERR);
874         s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS);
875         return 0;
876     }
877 
878     /* Verify the address, offset and length */
879     /* offset must be a multiple of 8 */
880     if (offset % 8) {
881         goto specification_error;
882     }
883     /* Length must be greater than 8, a multiple of 8 */
884     /* and not greater than maxstbl */
885     if ((len <= 8) || (len % 8) ||
886         (len > pbdev->pci_group->zpci_group.maxstbl)) {
887         goto specification_error;
888     }
889     /* Do not cross a 4K-byte boundary */
890     if (((offset & 0xfff) + len) > 0x1000) {
891         goto specification_error;
892     }
893     /* Guest address must be double word aligned */
894     if (gaddr & 0x07UL) {
895         goto specification_error;
896     }
897 
898     mr = pbdev->pdev->io_regions[pcias].memory;
899     mr = s390_get_subregion(mr, offset, len);
900     offset -= mr->addr;
901 
902     for (i = 0; i < len; i += 8) {
903         if (!memory_region_access_valid(mr, offset + i, 8, true,
904                                         MEMTXATTRS_UNSPECIFIED)) {
905             s390_program_interrupt(env, PGM_OPERAND, ra);
906             return 0;
907         }
908     }
909 
910     if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) {
911         s390_cpu_virt_mem_handle_exc(cpu, ra);
912         return 0;
913     }
914 
915     for (i = 0; i < len / 8; i++) {
916         result = memory_region_dispatch_write(mr, offset + i * 8,
917                                               ldq_p(buffer + i * 8),
918                                               MO_64, MEMTXATTRS_UNSPECIFIED);
919         if (result != MEMTX_OK) {
920             s390_program_interrupt(env, PGM_OPERAND, ra);
921             return 0;
922         }
923     }
924 
925     pbdev->fmb.counter[ZPCI_FMB_CNT_STB]++;
926 
927     setcc(cpu, ZPCI_PCI_LS_OK);
928     return 0;
929 
930 specification_error:
931     s390_program_interrupt(env, PGM_SPECIFICATION, ra);
932     return 0;
933 }
934 
reg_irqs(CPUS390XState * env,S390PCIBusDevice * pbdev,ZpciFib fib)935 static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
936 {
937     int ret, len;
938     uint8_t isc = FIB_DATA_ISC(ldl_p(&fib.data));
939 
940     pbdev->routes.adapter.adapter_id = css_get_adapter_id(
941                                        CSS_IO_ADAPTER_PCI, isc);
942     pbdev->summary_ind = get_indicator(ldq_p(&fib.aisb), sizeof(uint64_t));
943     len = BITS_TO_LONGS(FIB_DATA_NOI(ldl_p(&fib.data))) * sizeof(unsigned long);
944     pbdev->indicator = get_indicator(ldq_p(&fib.aibv), len);
945 
946     ret = map_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
947     if (ret) {
948         goto out;
949     }
950 
951     ret = map_indicator(&pbdev->routes.adapter, pbdev->indicator);
952     if (ret) {
953         goto out;
954     }
955 
956     pbdev->routes.adapter.summary_addr = ldq_p(&fib.aisb);
957     pbdev->routes.adapter.summary_offset = FIB_DATA_AISBO(ldl_p(&fib.data));
958     pbdev->routes.adapter.ind_addr = ldq_p(&fib.aibv);
959     pbdev->routes.adapter.ind_offset = FIB_DATA_AIBVO(ldl_p(&fib.data));
960     pbdev->isc = isc;
961     pbdev->noi = FIB_DATA_NOI(ldl_p(&fib.data));
962     pbdev->sum = FIB_DATA_SUM(ldl_p(&fib.data));
963 
964     trace_s390_pci_irqs("register", pbdev->routes.adapter.adapter_id);
965     return 0;
966 out:
967     release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
968     release_indicator(&pbdev->routes.adapter, pbdev->indicator);
969     pbdev->summary_ind = NULL;
970     pbdev->indicator = NULL;
971     return ret;
972 }
973 
pci_dereg_irqs(S390PCIBusDevice * pbdev)974 int pci_dereg_irqs(S390PCIBusDevice *pbdev)
975 {
976     release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
977     release_indicator(&pbdev->routes.adapter, pbdev->indicator);
978 
979     pbdev->summary_ind = NULL;
980     pbdev->indicator = NULL;
981     pbdev->routes.adapter.summary_addr = 0;
982     pbdev->routes.adapter.summary_offset = 0;
983     pbdev->routes.adapter.ind_addr = 0;
984     pbdev->routes.adapter.ind_offset = 0;
985     pbdev->isc = 0;
986     pbdev->noi = 0;
987     pbdev->sum = 0;
988 
989     trace_s390_pci_irqs("unregister", pbdev->routes.adapter.adapter_id);
990     return 0;
991 }
992 
reg_ioat(CPUS390XState * env,S390PCIBusDevice * pbdev,ZpciFib fib,uintptr_t ra)993 static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
994                     uintptr_t ra)
995 {
996     S390PCIIOMMU *iommu = pbdev->iommu;
997     uint64_t pba = ldq_p(&fib.pba);
998     uint64_t pal = ldq_p(&fib.pal);
999     uint64_t g_iota = ldq_p(&fib.iota);
1000     uint8_t dt = (g_iota >> 2) & 0x7;
1001     uint8_t t = (g_iota >> 11) & 0x1;
1002 
1003     pba &= ~0xfff;
1004     pal |= 0xfff;
1005     if (pba > pal || pba < pbdev->zpci_fn.sdma || pal > pbdev->zpci_fn.edma) {
1006         s390_program_interrupt(env, PGM_OPERAND, ra);
1007         return -EINVAL;
1008     }
1009 
1010     /* currently we only support designation type 1 with translation */
1011     if (!(dt == ZPCI_IOTA_RTTO && t)) {
1012         error_report("unsupported ioat dt %d t %d", dt, t);
1013         s390_program_interrupt(env, PGM_OPERAND, ra);
1014         return -EINVAL;
1015     }
1016 
1017     iommu->pba = pba;
1018     iommu->pal = pal;
1019     iommu->g_iota = g_iota;
1020 
1021     s390_pci_iommu_enable(iommu);
1022 
1023     return 0;
1024 }
1025 
pci_dereg_ioat(S390PCIIOMMU * iommu)1026 void pci_dereg_ioat(S390PCIIOMMU *iommu)
1027 {
1028     s390_pci_iommu_disable(iommu);
1029     iommu->pba = 0;
1030     iommu->pal = 0;
1031     iommu->g_iota = 0;
1032 }
1033 
fmb_timer_free(S390PCIBusDevice * pbdev)1034 void fmb_timer_free(S390PCIBusDevice *pbdev)
1035 {
1036     if (pbdev->fmb_timer) {
1037         timer_free(pbdev->fmb_timer);
1038         pbdev->fmb_timer = NULL;
1039     }
1040     pbdev->fmb_addr = 0;
1041     memset(&pbdev->fmb, 0, sizeof(ZpciFmb));
1042 }
1043 
fmb_do_update(S390PCIBusDevice * pbdev,int offset,uint64_t val,int len)1044 static int fmb_do_update(S390PCIBusDevice *pbdev, int offset, uint64_t val,
1045                          int len)
1046 {
1047     MemTxResult ret;
1048     uint64_t dst = pbdev->fmb_addr + offset;
1049 
1050     switch (len) {
1051     case 8:
1052         address_space_stq_be(&address_space_memory, dst, val,
1053                              MEMTXATTRS_UNSPECIFIED,
1054                              &ret);
1055         break;
1056     case 4:
1057         address_space_stl_be(&address_space_memory, dst, val,
1058                              MEMTXATTRS_UNSPECIFIED,
1059                              &ret);
1060         break;
1061     case 2:
1062         address_space_stw_be(&address_space_memory, dst, val,
1063                              MEMTXATTRS_UNSPECIFIED,
1064                              &ret);
1065         break;
1066     case 1:
1067         address_space_stb(&address_space_memory, dst, val,
1068                           MEMTXATTRS_UNSPECIFIED,
1069                           &ret);
1070         break;
1071     default:
1072         ret = MEMTX_ERROR;
1073         break;
1074     }
1075     if (ret != MEMTX_OK) {
1076         s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
1077                                       pbdev->fmb_addr, 0);
1078         fmb_timer_free(pbdev);
1079     }
1080 
1081     return ret;
1082 }
1083 
fmb_update(void * opaque)1084 static void fmb_update(void *opaque)
1085 {
1086     S390PCIBusDevice *pbdev = opaque;
1087     int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1088     int i;
1089 
1090     /* Update U bit */
1091     pbdev->fmb.last_update *= 2;
1092     pbdev->fmb.last_update |= UPDATE_U_BIT;
1093     if (fmb_do_update(pbdev, offsetof(ZpciFmb, last_update),
1094                       pbdev->fmb.last_update,
1095                       sizeof(pbdev->fmb.last_update))) {
1096         return;
1097     }
1098 
1099     /* Update FMB sample count */
1100     if (fmb_do_update(pbdev, offsetof(ZpciFmb, sample),
1101                       pbdev->fmb.sample++,
1102                       sizeof(pbdev->fmb.sample))) {
1103         return;
1104     }
1105 
1106     /* Update FMB counters */
1107     for (i = 0; i < ZPCI_FMB_CNT_MAX; i++) {
1108         if (fmb_do_update(pbdev, offsetof(ZpciFmb, counter[i]),
1109                           pbdev->fmb.counter[i],
1110                           sizeof(pbdev->fmb.counter[0]))) {
1111             return;
1112         }
1113     }
1114 
1115     /* Clear U bit and update the time */
1116     pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
1117     pbdev->fmb.last_update *= 2;
1118     if (fmb_do_update(pbdev, offsetof(ZpciFmb, last_update),
1119                       pbdev->fmb.last_update,
1120                       sizeof(pbdev->fmb.last_update))) {
1121         return;
1122     }
1123     timer_mod(pbdev->fmb_timer, t + pbdev->pci_group->zpci_group.mui);
1124 }
1125 
mpcifc_reg_int_interp(S390PCIBusDevice * pbdev,ZpciFib * fib)1126 static int mpcifc_reg_int_interp(S390PCIBusDevice *pbdev, ZpciFib *fib)
1127 {
1128     int rc;
1129 
1130     rc = s390_pci_kvm_aif_enable(pbdev, fib, pbdev->forwarding_assist);
1131     if (rc) {
1132         trace_s390_pci_kvm_aif("enable");
1133         return rc;
1134     }
1135 
1136     return 0;
1137 }
1138 
mpcifc_dereg_int_interp(S390PCIBusDevice * pbdev,ZpciFib * fib)1139 static int mpcifc_dereg_int_interp(S390PCIBusDevice *pbdev, ZpciFib *fib)
1140 {
1141     int rc;
1142 
1143     rc = s390_pci_kvm_aif_disable(pbdev);
1144     if (rc) {
1145         trace_s390_pci_kvm_aif("disable");
1146         return rc;
1147     }
1148 
1149     return 0;
1150 }
1151 
mpcifc_service_call(S390CPU * cpu,uint8_t r1,uint64_t fiba,uint8_t ar,uintptr_t ra)1152 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
1153                         uintptr_t ra)
1154 {
1155     CPUS390XState *env = &cpu->env;
1156     uint8_t oc, dmaas;
1157     uint32_t fh;
1158     ZpciFib fib;
1159     S390PCIBusDevice *pbdev;
1160     uint64_t cc = ZPCI_PCI_LS_OK;
1161 
1162     if (env->psw.mask & PSW_MASK_PSTATE) {
1163         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
1164         return 0;
1165     }
1166 
1167     oc = env->regs[r1] & 0xff;
1168     dmaas = (env->regs[r1] >> 16) & 0xff;
1169     fh = env->regs[r1] >> 32;
1170 
1171     if (fiba & 0x7) {
1172         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1173         return 0;
1174     }
1175 
1176     pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
1177     if (!pbdev) {
1178         trace_s390_pci_nodev("mpcifc", fh);
1179         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
1180         return 0;
1181     }
1182 
1183     switch (pbdev->state) {
1184     case ZPCI_FS_RESERVED:
1185     case ZPCI_FS_STANDBY:
1186     case ZPCI_FS_DISABLED:
1187     case ZPCI_FS_PERMANENT_ERROR:
1188         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
1189         return 0;
1190     default:
1191         break;
1192     }
1193 
1194     if (s390_cpu_virt_mem_read(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
1195         s390_cpu_virt_mem_handle_exc(cpu, ra);
1196         return 0;
1197     }
1198 
1199     if (fib.fmt != 0) {
1200         s390_program_interrupt(env, PGM_OPERAND, ra);
1201         return 0;
1202     }
1203 
1204     switch (oc) {
1205     case ZPCI_MOD_FC_REG_INT:
1206         if (pbdev->interp) {
1207             if (mpcifc_reg_int_interp(pbdev, &fib)) {
1208                 cc = ZPCI_PCI_LS_ERR;
1209                 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1210             }
1211         } else if (pbdev->summary_ind) {
1212             cc = ZPCI_PCI_LS_ERR;
1213             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1214         } else if (reg_irqs(env, pbdev, fib)) {
1215             cc = ZPCI_PCI_LS_ERR;
1216             s390_set_status_code(env, r1, ZPCI_MOD_ST_RES_NOT_AVAIL);
1217         }
1218         break;
1219     case ZPCI_MOD_FC_DEREG_INT:
1220         if (pbdev->interp) {
1221             if (mpcifc_dereg_int_interp(pbdev, &fib)) {
1222                 cc = ZPCI_PCI_LS_ERR;
1223                 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1224             }
1225         } else if (!pbdev->summary_ind) {
1226             cc = ZPCI_PCI_LS_ERR;
1227             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1228         } else {
1229             pci_dereg_irqs(pbdev);
1230         }
1231         break;
1232     case ZPCI_MOD_FC_REG_IOAT:
1233         if (dmaas != 0) {
1234             cc = ZPCI_PCI_LS_ERR;
1235             s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
1236         } else if (pbdev->iommu->enabled) {
1237             cc = ZPCI_PCI_LS_ERR;
1238             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1239         } else if (reg_ioat(env, pbdev, fib, ra)) {
1240             cc = ZPCI_PCI_LS_ERR;
1241             s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
1242         }
1243         break;
1244     case ZPCI_MOD_FC_DEREG_IOAT:
1245         if (dmaas != 0) {
1246             cc = ZPCI_PCI_LS_ERR;
1247             s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
1248         } else if (!pbdev->iommu->enabled) {
1249             cc = ZPCI_PCI_LS_ERR;
1250             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1251         } else {
1252             pci_dereg_ioat(pbdev->iommu);
1253         }
1254         break;
1255     case ZPCI_MOD_FC_REREG_IOAT:
1256         if (dmaas != 0) {
1257             cc = ZPCI_PCI_LS_ERR;
1258             s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
1259         } else if (!pbdev->iommu->enabled) {
1260             cc = ZPCI_PCI_LS_ERR;
1261             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1262         } else {
1263             pci_dereg_ioat(pbdev->iommu);
1264             if (reg_ioat(env, pbdev, fib, ra)) {
1265                 cc = ZPCI_PCI_LS_ERR;
1266                 s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
1267             }
1268         }
1269         break;
1270     case ZPCI_MOD_FC_RESET_ERROR:
1271         switch (pbdev->state) {
1272         case ZPCI_FS_BLOCKED:
1273         case ZPCI_FS_ERROR:
1274             pbdev->state = ZPCI_FS_ENABLED;
1275             break;
1276         default:
1277             cc = ZPCI_PCI_LS_ERR;
1278             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1279         }
1280         break;
1281     case ZPCI_MOD_FC_RESET_BLOCK:
1282         switch (pbdev->state) {
1283         case ZPCI_FS_ERROR:
1284             pbdev->state = ZPCI_FS_BLOCKED;
1285             break;
1286         default:
1287             cc = ZPCI_PCI_LS_ERR;
1288             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
1289         }
1290         break;
1291     case ZPCI_MOD_FC_SET_MEASURE: {
1292         uint64_t fmb_addr = ldq_p(&fib.fmb_addr);
1293 
1294         if (fmb_addr & FMBK_MASK) {
1295             cc = ZPCI_PCI_LS_ERR;
1296             s390_pci_generate_error_event(ERR_EVENT_FMBPRO, pbdev->fh,
1297                                           pbdev->fid, fmb_addr, 0);
1298             fmb_timer_free(pbdev);
1299             break;
1300         }
1301 
1302         if (!fmb_addr) {
1303             /* Stop updating FMB. */
1304             fmb_timer_free(pbdev);
1305             break;
1306         }
1307 
1308         if (!pbdev->fmb_timer) {
1309             pbdev->fmb_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
1310                                             fmb_update, pbdev);
1311         } else if (timer_pending(pbdev->fmb_timer)) {
1312             /* Remove pending timer to update FMB address. */
1313             timer_del(pbdev->fmb_timer);
1314         }
1315         pbdev->fmb_addr = fmb_addr;
1316         timer_mod(pbdev->fmb_timer,
1317                   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
1318                                     pbdev->pci_group->zpci_group.mui);
1319         break;
1320     }
1321     default:
1322         s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
1323         cc = ZPCI_PCI_LS_ERR;
1324     }
1325 
1326     setcc(cpu, cc);
1327     return 0;
1328 }
1329 
stpcifc_service_call(S390CPU * cpu,uint8_t r1,uint64_t fiba,uint8_t ar,uintptr_t ra)1330 int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
1331                          uintptr_t ra)
1332 {
1333     CPUS390XState *env = &cpu->env;
1334     uint8_t dmaas;
1335     uint32_t fh;
1336     ZpciFib fib;
1337     S390PCIBusDevice *pbdev;
1338     uint32_t data;
1339     uint64_t cc = ZPCI_PCI_LS_OK;
1340 
1341     if (env->psw.mask & PSW_MASK_PSTATE) {
1342         s390_program_interrupt(env, PGM_PRIVILEGED, ra);
1343         return 0;
1344     }
1345 
1346     fh = env->regs[r1] >> 32;
1347     dmaas = (env->regs[r1] >> 16) & 0xff;
1348 
1349     if (dmaas) {
1350         setcc(cpu, ZPCI_PCI_LS_ERR);
1351         s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_INVAL_DMAAS);
1352         return 0;
1353     }
1354 
1355     if (fiba & 0x7) {
1356         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
1357         return 0;
1358     }
1359 
1360     pbdev = s390_pci_find_dev_by_idx(s390_get_phb(), fh & FH_MASK_INDEX);
1361     if (!pbdev) {
1362         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
1363         return 0;
1364     }
1365 
1366     memset(&fib, 0, sizeof(fib));
1367 
1368     switch (pbdev->state) {
1369     case ZPCI_FS_RESERVED:
1370     case ZPCI_FS_STANDBY:
1371         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
1372         return 0;
1373     case ZPCI_FS_DISABLED:
1374         if (fh & FH_MASK_ENABLE) {
1375             setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
1376             return 0;
1377         }
1378         goto out;
1379     /* BLOCKED bit is set to one coincident with the setting of ERROR bit.
1380      * FH Enabled bit is set to one in states of ENABLED, BLOCKED or ERROR. */
1381     case ZPCI_FS_ERROR:
1382         fib.fc |= 0x20;
1383         /* fallthrough */
1384     case ZPCI_FS_BLOCKED:
1385         fib.fc |= 0x40;
1386         /* fallthrough */
1387     case ZPCI_FS_ENABLED:
1388         fib.fc |= 0x80;
1389         if (pbdev->iommu->enabled) {
1390             fib.fc |= 0x10;
1391         }
1392         if (!(fh & FH_MASK_ENABLE)) {
1393             env->regs[r1] |= 1ULL << 63;
1394         }
1395         break;
1396     case ZPCI_FS_PERMANENT_ERROR:
1397         setcc(cpu, ZPCI_PCI_LS_ERR);
1398         s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_PERM_ERROR);
1399         return 0;
1400     }
1401 
1402     stq_p(&fib.pba, pbdev->iommu->pba);
1403     stq_p(&fib.pal, pbdev->iommu->pal);
1404     stq_p(&fib.iota, pbdev->iommu->g_iota);
1405     stq_p(&fib.aibv, pbdev->routes.adapter.ind_addr);
1406     stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
1407     stq_p(&fib.fmb_addr, pbdev->fmb_addr);
1408 
1409     data = ((uint32_t)pbdev->isc << 28) | ((uint32_t)pbdev->noi << 16) |
1410            ((uint32_t)pbdev->routes.adapter.ind_offset << 8) |
1411            ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset;
1412     stl_p(&fib.data, data);
1413 
1414 out:
1415     if (s390_cpu_virt_mem_write(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
1416         s390_cpu_virt_mem_handle_exc(cpu, ra);
1417         return 0;
1418     }
1419 
1420     setcc(cpu, cc);
1421     return 0;
1422 }
1423