xref: /openbmc/qemu/hw/s390x/css.c (revision 33577b47)
1 /*
2  * Channel subsystem base support.
3  *
4  * Copyright 2012 IBM Corp.
5  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2 or (at
8  * your option) any later version. See the COPYING file in the top-level
9  * directory.
10  */
11 
12 #include "qemu/osdep.h"
13 #include <hw/qdev.h>
14 #include "qemu/bitops.h"
15 #include "exec/address-spaces.h"
16 #include "cpu.h"
17 #include "ioinst.h"
18 #include "css.h"
19 #include "trace.h"
20 #include "hw/s390x/s390_flic.h"
21 
22 typedef struct CrwContainer {
23     CRW crw;
24     QTAILQ_ENTRY(CrwContainer) sibling;
25 } CrwContainer;
26 
27 typedef struct ChpInfo {
28     uint8_t in_use;
29     uint8_t type;
30     uint8_t is_virtual;
31 } ChpInfo;
32 
33 typedef struct SubchSet {
34     SubchDev *sch[MAX_SCHID + 1];
35     unsigned long schids_used[BITS_TO_LONGS(MAX_SCHID + 1)];
36     unsigned long devnos_used[BITS_TO_LONGS(MAX_SCHID + 1)];
37 } SubchSet;
38 
39 typedef struct CssImage {
40     SubchSet *sch_set[MAX_SSID + 1];
41     ChpInfo chpids[MAX_CHPID + 1];
42 } CssImage;
43 
44 typedef struct IoAdapter {
45     uint32_t id;
46     uint8_t type;
47     uint8_t isc;
48     QTAILQ_ENTRY(IoAdapter) sibling;
49 } IoAdapter;
50 
51 typedef struct ChannelSubSys {
52     QTAILQ_HEAD(, CrwContainer) pending_crws;
53     bool sei_pending;
54     bool do_crw_mchk;
55     bool crws_lost;
56     uint8_t max_cssid;
57     uint8_t max_ssid;
58     bool chnmon_active;
59     uint64_t chnmon_area;
60     CssImage *css[MAX_CSSID + 1];
61     uint8_t default_cssid;
62     QTAILQ_HEAD(, IoAdapter) io_adapters;
63     QTAILQ_HEAD(, IndAddr) indicator_addresses;
64 } ChannelSubSys;
65 
66 static ChannelSubSys channel_subsys = {
67     .pending_crws = QTAILQ_HEAD_INITIALIZER(channel_subsys.pending_crws),
68     .do_crw_mchk = true,
69     .sei_pending = false,
70     .do_crw_mchk = true,
71     .crws_lost = false,
72     .chnmon_active = false,
73     .io_adapters = QTAILQ_HEAD_INITIALIZER(channel_subsys.io_adapters),
74     .indicator_addresses =
75         QTAILQ_HEAD_INITIALIZER(channel_subsys.indicator_addresses),
76 };
77 
78 IndAddr *get_indicator(hwaddr ind_addr, int len)
79 {
80     IndAddr *indicator;
81 
82     QTAILQ_FOREACH(indicator, &channel_subsys.indicator_addresses, sibling) {
83         if (indicator->addr == ind_addr) {
84             indicator->refcnt++;
85             return indicator;
86         }
87     }
88     indicator = g_new0(IndAddr, 1);
89     indicator->addr = ind_addr;
90     indicator->len = len;
91     indicator->refcnt = 1;
92     QTAILQ_INSERT_TAIL(&channel_subsys.indicator_addresses,
93                        indicator, sibling);
94     return indicator;
95 }
96 
97 static int s390_io_adapter_map(AdapterInfo *adapter, uint64_t map_addr,
98                                bool do_map)
99 {
100     S390FLICState *fs = s390_get_flic();
101     S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
102 
103     return fsc->io_adapter_map(fs, adapter->adapter_id, map_addr, do_map);
104 }
105 
106 void release_indicator(AdapterInfo *adapter, IndAddr *indicator)
107 {
108     assert(indicator->refcnt > 0);
109     indicator->refcnt--;
110     if (indicator->refcnt > 0) {
111         return;
112     }
113     QTAILQ_REMOVE(&channel_subsys.indicator_addresses, indicator, sibling);
114     if (indicator->map) {
115         s390_io_adapter_map(adapter, indicator->map, false);
116     }
117     g_free(indicator);
118 }
119 
120 int map_indicator(AdapterInfo *adapter, IndAddr *indicator)
121 {
122     int ret;
123 
124     if (indicator->map) {
125         return 0; /* already mapped is not an error */
126     }
127     indicator->map = indicator->addr;
128     ret = s390_io_adapter_map(adapter, indicator->map, true);
129     if ((ret != 0) && (ret != -ENOSYS)) {
130         goto out_err;
131     }
132     return 0;
133 
134 out_err:
135     indicator->map = 0;
136     return ret;
137 }
138 
139 int css_create_css_image(uint8_t cssid, bool default_image)
140 {
141     trace_css_new_image(cssid, default_image ? "(default)" : "");
142     if (cssid > MAX_CSSID) {
143         return -EINVAL;
144     }
145     if (channel_subsys.css[cssid]) {
146         return -EBUSY;
147     }
148     channel_subsys.css[cssid] = g_malloc0(sizeof(CssImage));
149     if (default_image) {
150         channel_subsys.default_cssid = cssid;
151     }
152     return 0;
153 }
154 
155 int css_register_io_adapter(uint8_t type, uint8_t isc, bool swap,
156                             bool maskable, uint32_t *id)
157 {
158     IoAdapter *adapter;
159     bool found = false;
160     int ret;
161     S390FLICState *fs = s390_get_flic();
162     S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
163 
164     *id = 0;
165     QTAILQ_FOREACH(adapter, &channel_subsys.io_adapters, sibling) {
166         if ((adapter->type == type) && (adapter->isc == isc)) {
167             *id = adapter->id;
168             found = true;
169             ret = 0;
170             break;
171         }
172         if (adapter->id >= *id) {
173             *id = adapter->id + 1;
174         }
175     }
176     if (found) {
177         goto out;
178     }
179     adapter = g_new0(IoAdapter, 1);
180     ret = fsc->register_io_adapter(fs, *id, isc, swap, maskable);
181     if (ret == 0) {
182         adapter->id = *id;
183         adapter->isc = isc;
184         adapter->type = type;
185         QTAILQ_INSERT_TAIL(&channel_subsys.io_adapters, adapter, sibling);
186     } else {
187         g_free(adapter);
188         fprintf(stderr, "Unexpected error %d when registering adapter %d\n",
189                 ret, *id);
190     }
191 out:
192     return ret;
193 }
194 
195 uint16_t css_build_subchannel_id(SubchDev *sch)
196 {
197     if (channel_subsys.max_cssid > 0) {
198         return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
199     }
200     return (sch->ssid << 1) | 1;
201 }
202 
203 static void css_inject_io_interrupt(SubchDev *sch)
204 {
205     uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
206 
207     trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
208                            sch->curr_status.pmcw.intparm, isc, "");
209     s390_io_interrupt(css_build_subchannel_id(sch),
210                       sch->schid,
211                       sch->curr_status.pmcw.intparm,
212                       isc << 27);
213 }
214 
215 void css_conditional_io_interrupt(SubchDev *sch)
216 {
217     /*
218      * If the subchannel is not currently status pending, make it pending
219      * with alert status.
220      */
221     if (!(sch->curr_status.scsw.ctrl & SCSW_STCTL_STATUS_PEND)) {
222         uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
223 
224         trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
225                                sch->curr_status.pmcw.intparm, isc,
226                                "(unsolicited)");
227         sch->curr_status.scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
228         sch->curr_status.scsw.ctrl |=
229             SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
230         /* Inject an I/O interrupt. */
231         s390_io_interrupt(css_build_subchannel_id(sch),
232                           sch->schid,
233                           sch->curr_status.pmcw.intparm,
234                           isc << 27);
235     }
236 }
237 
238 void css_adapter_interrupt(uint8_t isc)
239 {
240     uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI;
241 
242     trace_css_adapter_interrupt(isc);
243     s390_io_interrupt(0, 0, 0, io_int_word);
244 }
245 
246 static void sch_handle_clear_func(SubchDev *sch)
247 {
248     PMCW *p = &sch->curr_status.pmcw;
249     SCSW *s = &sch->curr_status.scsw;
250     int path;
251 
252     /* Path management: In our simple css, we always choose the only path. */
253     path = 0x80;
254 
255     /* Reset values prior to 'issuing the clear signal'. */
256     p->lpum = 0;
257     p->pom = 0xff;
258     s->flags &= ~SCSW_FLAGS_MASK_PNO;
259 
260     /* We always 'attempt to issue the clear signal', and we always succeed. */
261     sch->channel_prog = 0x0;
262     sch->last_cmd_valid = false;
263     s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
264     s->ctrl |= SCSW_STCTL_STATUS_PEND;
265 
266     s->dstat = 0;
267     s->cstat = 0;
268     p->lpum = path;
269 
270 }
271 
272 static void sch_handle_halt_func(SubchDev *sch)
273 {
274 
275     PMCW *p = &sch->curr_status.pmcw;
276     SCSW *s = &sch->curr_status.scsw;
277     hwaddr curr_ccw = sch->channel_prog;
278     int path;
279 
280     /* Path management: In our simple css, we always choose the only path. */
281     path = 0x80;
282 
283     /* We always 'attempt to issue the halt signal', and we always succeed. */
284     sch->channel_prog = 0x0;
285     sch->last_cmd_valid = false;
286     s->ctrl &= ~SCSW_ACTL_HALT_PEND;
287     s->ctrl |= SCSW_STCTL_STATUS_PEND;
288 
289     if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
290         !((s->ctrl & SCSW_ACTL_START_PEND) ||
291           (s->ctrl & SCSW_ACTL_SUSP))) {
292         s->dstat = SCSW_DSTAT_DEVICE_END;
293     }
294     if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
295         (s->ctrl & SCSW_ACTL_SUSP)) {
296         s->cpa = curr_ccw + 8;
297     }
298     s->cstat = 0;
299     p->lpum = path;
300 
301 }
302 
303 static void copy_sense_id_to_guest(SenseId *dest, SenseId *src)
304 {
305     int i;
306 
307     dest->reserved = src->reserved;
308     dest->cu_type = cpu_to_be16(src->cu_type);
309     dest->cu_model = src->cu_model;
310     dest->dev_type = cpu_to_be16(src->dev_type);
311     dest->dev_model = src->dev_model;
312     dest->unused = src->unused;
313     for (i = 0; i < ARRAY_SIZE(dest->ciw); i++) {
314         dest->ciw[i].type = src->ciw[i].type;
315         dest->ciw[i].command = src->ciw[i].command;
316         dest->ciw[i].count = cpu_to_be16(src->ciw[i].count);
317     }
318 }
319 
320 static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
321 {
322     CCW0 tmp0;
323     CCW1 tmp1;
324     CCW1 ret;
325 
326     if (fmt1) {
327         cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1));
328         ret.cmd_code = tmp1.cmd_code;
329         ret.flags = tmp1.flags;
330         ret.count = be16_to_cpu(tmp1.count);
331         ret.cda = be32_to_cpu(tmp1.cda);
332     } else {
333         cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0));
334         ret.cmd_code = tmp0.cmd_code;
335         ret.flags = tmp0.flags;
336         ret.count = be16_to_cpu(tmp0.count);
337         ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
338         if ((ret.cmd_code & 0x0f) == CCW_CMD_TIC) {
339             ret.cmd_code &= 0x0f;
340         }
341     }
342     return ret;
343 }
344 
345 static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
346                              bool suspend_allowed)
347 {
348     int ret;
349     bool check_len;
350     int len;
351     CCW1 ccw;
352 
353     if (!ccw_addr) {
354         return -EIO;
355     }
356 
357     /* Translate everything to format-1 ccws - the information is the same. */
358     ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);
359 
360     /* Check for invalid command codes. */
361     if ((ccw.cmd_code & 0x0f) == 0) {
362         return -EINVAL;
363     }
364     if (((ccw.cmd_code & 0x0f) == CCW_CMD_TIC) &&
365         ((ccw.cmd_code & 0xf0) != 0)) {
366         return -EINVAL;
367     }
368     if (!sch->ccw_fmt_1 && (ccw.count == 0) &&
369         (ccw.cmd_code != CCW_CMD_TIC)) {
370         return -EINVAL;
371     }
372 
373     if (ccw.flags & CCW_FLAG_SUSPEND) {
374         return suspend_allowed ? -EINPROGRESS : -EINVAL;
375     }
376 
377     check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
378 
379     if (!ccw.cda) {
380         if (sch->ccw_no_data_cnt == 255) {
381             return -EINVAL;
382         }
383         sch->ccw_no_data_cnt++;
384     }
385 
386     /* Look at the command. */
387     switch (ccw.cmd_code) {
388     case CCW_CMD_NOOP:
389         /* Nothing to do. */
390         ret = 0;
391         break;
392     case CCW_CMD_BASIC_SENSE:
393         if (check_len) {
394             if (ccw.count != sizeof(sch->sense_data)) {
395                 ret = -EINVAL;
396                 break;
397             }
398         }
399         len = MIN(ccw.count, sizeof(sch->sense_data));
400         cpu_physical_memory_write(ccw.cda, sch->sense_data, len);
401         sch->curr_status.scsw.count = ccw.count - len;
402         memset(sch->sense_data, 0, sizeof(sch->sense_data));
403         ret = 0;
404         break;
405     case CCW_CMD_SENSE_ID:
406     {
407         SenseId sense_id;
408 
409         copy_sense_id_to_guest(&sense_id, &sch->id);
410         /* Sense ID information is device specific. */
411         if (check_len) {
412             if (ccw.count != sizeof(sense_id)) {
413                 ret = -EINVAL;
414                 break;
415             }
416         }
417         len = MIN(ccw.count, sizeof(sense_id));
418         /*
419          * Only indicate 0xff in the first sense byte if we actually
420          * have enough place to store at least bytes 0-3.
421          */
422         if (len >= 4) {
423             sense_id.reserved = 0xff;
424         } else {
425             sense_id.reserved = 0;
426         }
427         cpu_physical_memory_write(ccw.cda, &sense_id, len);
428         sch->curr_status.scsw.count = ccw.count - len;
429         ret = 0;
430         break;
431     }
432     case CCW_CMD_TIC:
433         if (sch->last_cmd_valid && (sch->last_cmd.cmd_code == CCW_CMD_TIC)) {
434             ret = -EINVAL;
435             break;
436         }
437         if (ccw.flags & (CCW_FLAG_CC | CCW_FLAG_DC)) {
438             ret = -EINVAL;
439             break;
440         }
441         sch->channel_prog = ccw.cda;
442         ret = -EAGAIN;
443         break;
444     default:
445         if (sch->ccw_cb) {
446             /* Handle device specific commands. */
447             ret = sch->ccw_cb(sch, ccw);
448         } else {
449             ret = -ENOSYS;
450         }
451         break;
452     }
453     sch->last_cmd = ccw;
454     sch->last_cmd_valid = true;
455     if (ret == 0) {
456         if (ccw.flags & CCW_FLAG_CC) {
457             sch->channel_prog += 8;
458             ret = -EAGAIN;
459         }
460     }
461 
462     return ret;
463 }
464 
465 static void sch_handle_start_func(SubchDev *sch, ORB *orb)
466 {
467 
468     PMCW *p = &sch->curr_status.pmcw;
469     SCSW *s = &sch->curr_status.scsw;
470     int path;
471     int ret;
472     bool suspend_allowed;
473 
474     /* Path management: In our simple css, we always choose the only path. */
475     path = 0x80;
476 
477     if (!(s->ctrl & SCSW_ACTL_SUSP)) {
478         s->cstat = 0;
479         s->dstat = 0;
480         /* Look at the orb and try to execute the channel program. */
481         assert(orb != NULL); /* resume does not pass an orb */
482         p->intparm = orb->intparm;
483         if (!(orb->lpm & path)) {
484             /* Generate a deferred cc 3 condition. */
485             s->flags |= SCSW_FLAGS_MASK_CC;
486             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
487             s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
488             return;
489         }
490         sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
491         sch->ccw_no_data_cnt = 0;
492         suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
493     } else {
494         s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
495         /* The channel program had been suspended before. */
496         suspend_allowed = true;
497     }
498     sch->last_cmd_valid = false;
499     do {
500         ret = css_interpret_ccw(sch, sch->channel_prog, suspend_allowed);
501         switch (ret) {
502         case -EAGAIN:
503             /* ccw chain, continue processing */
504             break;
505         case 0:
506             /* success */
507             s->ctrl &= ~SCSW_ACTL_START_PEND;
508             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
509             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
510                     SCSW_STCTL_STATUS_PEND;
511             s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
512             s->cpa = sch->channel_prog + 8;
513             break;
514         case -ENOSYS:
515             /* unsupported command, generate unit check (command reject) */
516             s->ctrl &= ~SCSW_ACTL_START_PEND;
517             s->dstat = SCSW_DSTAT_UNIT_CHECK;
518             /* Set sense bit 0 in ecw0. */
519             sch->sense_data[0] = 0x80;
520             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
521             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
522                     SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
523             s->cpa = sch->channel_prog + 8;
524             break;
525         case -EFAULT:
526             /* memory problem, generate channel data check */
527             s->ctrl &= ~SCSW_ACTL_START_PEND;
528             s->cstat = SCSW_CSTAT_DATA_CHECK;
529             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
530             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
531                     SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
532             s->cpa = sch->channel_prog + 8;
533             break;
534         case -EBUSY:
535             /* subchannel busy, generate deferred cc 1 */
536             s->flags &= ~SCSW_FLAGS_MASK_CC;
537             s->flags |= (1 << 8);
538             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
539             s->ctrl |= SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
540             break;
541         case -EINPROGRESS:
542             /* channel program has been suspended */
543             s->ctrl &= ~SCSW_ACTL_START_PEND;
544             s->ctrl |= SCSW_ACTL_SUSP;
545             break;
546         default:
547             /* error, generate channel program check */
548             s->ctrl &= ~SCSW_ACTL_START_PEND;
549             s->cstat = SCSW_CSTAT_PROG_CHECK;
550             s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
551             s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
552                     SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
553             s->cpa = sch->channel_prog + 8;
554             break;
555         }
556     } while (ret == -EAGAIN);
557 
558 }
559 
560 /*
561  * On real machines, this would run asynchronously to the main vcpus.
562  * We might want to make some parts of the ssch handling (interpreting
563  * read/writes) asynchronous later on if we start supporting more than
564  * our current very simple devices.
565  */
566 static void do_subchannel_work(SubchDev *sch, ORB *orb)
567 {
568 
569     SCSW *s = &sch->curr_status.scsw;
570 
571     if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
572         sch_handle_clear_func(sch);
573     } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
574         sch_handle_halt_func(sch);
575     } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
576         sch_handle_start_func(sch, orb);
577     } else {
578         /* Cannot happen. */
579         return;
580     }
581     css_inject_io_interrupt(sch);
582 }
583 
584 static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
585 {
586     int i;
587 
588     dest->intparm = cpu_to_be32(src->intparm);
589     dest->flags = cpu_to_be16(src->flags);
590     dest->devno = cpu_to_be16(src->devno);
591     dest->lpm = src->lpm;
592     dest->pnom = src->pnom;
593     dest->lpum = src->lpum;
594     dest->pim = src->pim;
595     dest->mbi = cpu_to_be16(src->mbi);
596     dest->pom = src->pom;
597     dest->pam = src->pam;
598     for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
599         dest->chpid[i] = src->chpid[i];
600     }
601     dest->chars = cpu_to_be32(src->chars);
602 }
603 
604 static void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
605 {
606     dest->flags = cpu_to_be16(src->flags);
607     dest->ctrl = cpu_to_be16(src->ctrl);
608     dest->cpa = cpu_to_be32(src->cpa);
609     dest->dstat = src->dstat;
610     dest->cstat = src->cstat;
611     dest->count = cpu_to_be16(src->count);
612 }
613 
614 static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
615 {
616     int i;
617 
618     copy_pmcw_to_guest(&dest->pmcw, &src->pmcw);
619     copy_scsw_to_guest(&dest->scsw, &src->scsw);
620     dest->mba = cpu_to_be64(src->mba);
621     for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
622         dest->mda[i] = src->mda[i];
623     }
624 }
625 
626 int css_do_stsch(SubchDev *sch, SCHIB *schib)
627 {
628     /* Use current status. */
629     copy_schib_to_guest(schib, &sch->curr_status);
630     return 0;
631 }
632 
633 static void copy_pmcw_from_guest(PMCW *dest, const PMCW *src)
634 {
635     int i;
636 
637     dest->intparm = be32_to_cpu(src->intparm);
638     dest->flags = be16_to_cpu(src->flags);
639     dest->devno = be16_to_cpu(src->devno);
640     dest->lpm = src->lpm;
641     dest->pnom = src->pnom;
642     dest->lpum = src->lpum;
643     dest->pim = src->pim;
644     dest->mbi = be16_to_cpu(src->mbi);
645     dest->pom = src->pom;
646     dest->pam = src->pam;
647     for (i = 0; i < ARRAY_SIZE(dest->chpid); i++) {
648         dest->chpid[i] = src->chpid[i];
649     }
650     dest->chars = be32_to_cpu(src->chars);
651 }
652 
653 static void copy_scsw_from_guest(SCSW *dest, const SCSW *src)
654 {
655     dest->flags = be16_to_cpu(src->flags);
656     dest->ctrl = be16_to_cpu(src->ctrl);
657     dest->cpa = be32_to_cpu(src->cpa);
658     dest->dstat = src->dstat;
659     dest->cstat = src->cstat;
660     dest->count = be16_to_cpu(src->count);
661 }
662 
663 static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src)
664 {
665     int i;
666 
667     copy_pmcw_from_guest(&dest->pmcw, &src->pmcw);
668     copy_scsw_from_guest(&dest->scsw, &src->scsw);
669     dest->mba = be64_to_cpu(src->mba);
670     for (i = 0; i < ARRAY_SIZE(dest->mda); i++) {
671         dest->mda[i] = src->mda[i];
672     }
673 }
674 
675 int css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
676 {
677     SCSW *s = &sch->curr_status.scsw;
678     PMCW *p = &sch->curr_status.pmcw;
679     uint16_t oldflags;
680     int ret;
681     SCHIB schib;
682 
683     if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
684         ret = 0;
685         goto out;
686     }
687 
688     if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
689         ret = -EINPROGRESS;
690         goto out;
691     }
692 
693     if (s->ctrl &
694         (SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
695         ret = -EBUSY;
696         goto out;
697     }
698 
699     copy_schib_from_guest(&schib, orig_schib);
700     /* Only update the program-modifiable fields. */
701     p->intparm = schib.pmcw.intparm;
702     oldflags = p->flags;
703     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
704                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
705                   PMCW_FLAGS_MASK_MP);
706     p->flags |= schib.pmcw.flags &
707             (PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
708              PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
709              PMCW_FLAGS_MASK_MP);
710     p->lpm = schib.pmcw.lpm;
711     p->mbi = schib.pmcw.mbi;
712     p->pom = schib.pmcw.pom;
713     p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
714     p->chars |= schib.pmcw.chars &
715             (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
716     sch->curr_status.mba = schib.mba;
717 
718     /* Has the channel been disabled? */
719     if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
720         && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
721         sch->disable_cb(sch);
722     }
723 
724     ret = 0;
725 
726 out:
727     return ret;
728 }
729 
730 int css_do_xsch(SubchDev *sch)
731 {
732     SCSW *s = &sch->curr_status.scsw;
733     PMCW *p = &sch->curr_status.pmcw;
734     int ret;
735 
736     if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
737         ret = -ENODEV;
738         goto out;
739     }
740 
741     if (!(s->ctrl & SCSW_CTRL_MASK_FCTL) ||
742         ((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
743         (!(s->ctrl &
744            (SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) ||
745         (s->ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
746         ret = -EINPROGRESS;
747         goto out;
748     }
749 
750     if (s->ctrl & SCSW_CTRL_MASK_STCTL) {
751         ret = -EBUSY;
752         goto out;
753     }
754 
755     /* Cancel the current operation. */
756     s->ctrl &= ~(SCSW_FCTL_START_FUNC |
757                  SCSW_ACTL_RESUME_PEND |
758                  SCSW_ACTL_START_PEND |
759                  SCSW_ACTL_SUSP);
760     sch->channel_prog = 0x0;
761     sch->last_cmd_valid = false;
762     s->dstat = 0;
763     s->cstat = 0;
764     ret = 0;
765 
766 out:
767     return ret;
768 }
769 
770 int css_do_csch(SubchDev *sch)
771 {
772     SCSW *s = &sch->curr_status.scsw;
773     PMCW *p = &sch->curr_status.pmcw;
774     int ret;
775 
776     if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
777         ret = -ENODEV;
778         goto out;
779     }
780 
781     /* Trigger the clear function. */
782     s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
783     s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
784 
785     do_subchannel_work(sch, NULL);
786     ret = 0;
787 
788 out:
789     return ret;
790 }
791 
792 int css_do_hsch(SubchDev *sch)
793 {
794     SCSW *s = &sch->curr_status.scsw;
795     PMCW *p = &sch->curr_status.pmcw;
796     int ret;
797 
798     if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
799         ret = -ENODEV;
800         goto out;
801     }
802 
803     if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
804         (s->ctrl & (SCSW_STCTL_PRIMARY |
805                     SCSW_STCTL_SECONDARY |
806                     SCSW_STCTL_ALERT))) {
807         ret = -EINPROGRESS;
808         goto out;
809     }
810 
811     if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
812         ret = -EBUSY;
813         goto out;
814     }
815 
816     /* Trigger the halt function. */
817     s->ctrl |= SCSW_FCTL_HALT_FUNC;
818     s->ctrl &= ~SCSW_FCTL_START_FUNC;
819     if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==
820          (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
821         ((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {
822         s->ctrl &= ~SCSW_STCTL_STATUS_PEND;
823     }
824     s->ctrl |= SCSW_ACTL_HALT_PEND;
825 
826     do_subchannel_work(sch, NULL);
827     ret = 0;
828 
829 out:
830     return ret;
831 }
832 
833 static void css_update_chnmon(SubchDev *sch)
834 {
835     if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_MME)) {
836         /* Not active. */
837         return;
838     }
839     /* The counter is conveniently located at the beginning of the struct. */
840     if (sch->curr_status.pmcw.chars & PMCW_CHARS_MASK_MBFC) {
841         /* Format 1, per-subchannel area. */
842         uint32_t count;
843 
844         count = address_space_ldl(&address_space_memory,
845                                   sch->curr_status.mba,
846                                   MEMTXATTRS_UNSPECIFIED,
847                                   NULL);
848         count++;
849         address_space_stl(&address_space_memory, sch->curr_status.mba, count,
850                           MEMTXATTRS_UNSPECIFIED, NULL);
851     } else {
852         /* Format 0, global area. */
853         uint32_t offset;
854         uint16_t count;
855 
856         offset = sch->curr_status.pmcw.mbi << 5;
857         count = address_space_lduw(&address_space_memory,
858                                    channel_subsys.chnmon_area + offset,
859                                    MEMTXATTRS_UNSPECIFIED,
860                                    NULL);
861         count++;
862         address_space_stw(&address_space_memory,
863                           channel_subsys.chnmon_area + offset, count,
864                           MEMTXATTRS_UNSPECIFIED, NULL);
865     }
866 }
867 
868 int css_do_ssch(SubchDev *sch, ORB *orb)
869 {
870     SCSW *s = &sch->curr_status.scsw;
871     PMCW *p = &sch->curr_status.pmcw;
872     int ret;
873 
874     if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
875         ret = -ENODEV;
876         goto out;
877     }
878 
879     if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
880         ret = -EINPROGRESS;
881         goto out;
882     }
883 
884     if (s->ctrl & (SCSW_FCTL_START_FUNC |
885                    SCSW_FCTL_HALT_FUNC |
886                    SCSW_FCTL_CLEAR_FUNC)) {
887         ret = -EBUSY;
888         goto out;
889     }
890 
891     /* If monitoring is active, update counter. */
892     if (channel_subsys.chnmon_active) {
893         css_update_chnmon(sch);
894     }
895     sch->channel_prog = orb->cpa;
896     /* Trigger the start function. */
897     s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
898     s->flags &= ~SCSW_FLAGS_MASK_PNO;
899 
900     do_subchannel_work(sch, orb);
901     ret = 0;
902 
903 out:
904     return ret;
905 }
906 
907 static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
908                               int *irb_len)
909 {
910     int i;
911     uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
912     uint16_t actl = src->scsw.ctrl & SCSW_CTRL_MASK_ACTL;
913 
914     copy_scsw_to_guest(&dest->scsw, &src->scsw);
915 
916     for (i = 0; i < ARRAY_SIZE(dest->esw); i++) {
917         dest->esw[i] = cpu_to_be32(src->esw[i]);
918     }
919     for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) {
920         dest->ecw[i] = cpu_to_be32(src->ecw[i]);
921     }
922     *irb_len = sizeof(*dest) - sizeof(dest->emw);
923 
924     /* extended measurements enabled? */
925     if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) ||
926         !(pmcw->flags & PMCW_FLAGS_MASK_TF) ||
927         !(pmcw->chars & PMCW_CHARS_MASK_XMWME)) {
928         return;
929     }
930     /* extended measurements pending? */
931     if (!(stctl & SCSW_STCTL_STATUS_PEND)) {
932         return;
933     }
934     if ((stctl & SCSW_STCTL_PRIMARY) ||
935         (stctl == SCSW_STCTL_SECONDARY) ||
936         ((stctl & SCSW_STCTL_INTERMEDIATE) && (actl & SCSW_ACTL_SUSP))) {
937         for (i = 0; i < ARRAY_SIZE(dest->emw); i++) {
938             dest->emw[i] = cpu_to_be32(src->emw[i]);
939         }
940     }
941     *irb_len = sizeof(*dest);
942 }
943 
944 int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
945 {
946     SCSW *s = &sch->curr_status.scsw;
947     PMCW *p = &sch->curr_status.pmcw;
948     uint16_t stctl;
949     IRB irb;
950 
951     if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
952         return 3;
953     }
954 
955     stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
956 
957     /* Prepare the irb for the guest. */
958     memset(&irb, 0, sizeof(IRB));
959 
960     /* Copy scsw from current status. */
961     memcpy(&irb.scsw, s, sizeof(SCSW));
962     if (stctl & SCSW_STCTL_STATUS_PEND) {
963         if (s->cstat & (SCSW_CSTAT_DATA_CHECK |
964                         SCSW_CSTAT_CHN_CTRL_CHK |
965                         SCSW_CSTAT_INTF_CTRL_CHK)) {
966             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
967             irb.esw[0] = 0x04804000;
968         } else {
969             irb.esw[0] = 0x00800000;
970         }
971         /* If a unit check is pending, copy sense data. */
972         if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
973             (p->chars & PMCW_CHARS_MASK_CSENSE)) {
974             int i;
975 
976             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
977             /* Attention: sense_data is already BE! */
978             memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
979             for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
980                 irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
981             }
982             irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
983         }
984     }
985     /* Store the irb to the guest. */
986     copy_irb_to_guest(target_irb, &irb, p, irb_len);
987 
988     return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
989 }
990 
991 void css_do_tsch_update_subch(SubchDev *sch)
992 {
993     SCSW *s = &sch->curr_status.scsw;
994     PMCW *p = &sch->curr_status.pmcw;
995     uint16_t stctl;
996     uint16_t fctl;
997     uint16_t actl;
998 
999     stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
1000     fctl = s->ctrl & SCSW_CTRL_MASK_FCTL;
1001     actl = s->ctrl & SCSW_CTRL_MASK_ACTL;
1002 
1003     /* Clear conditions on subchannel, if applicable. */
1004     if (stctl & SCSW_STCTL_STATUS_PEND) {
1005         s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
1006         if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
1007             ((fctl & SCSW_FCTL_HALT_FUNC) &&
1008              (actl & SCSW_ACTL_SUSP))) {
1009             s->ctrl &= ~SCSW_CTRL_MASK_FCTL;
1010         }
1011         if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
1012             s->flags &= ~SCSW_FLAGS_MASK_PNO;
1013             s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
1014                          SCSW_ACTL_START_PEND |
1015                          SCSW_ACTL_HALT_PEND |
1016                          SCSW_ACTL_CLEAR_PEND |
1017                          SCSW_ACTL_SUSP);
1018         } else {
1019             if ((actl & SCSW_ACTL_SUSP) &&
1020                 (fctl & SCSW_FCTL_START_FUNC)) {
1021                 s->flags &= ~SCSW_FLAGS_MASK_PNO;
1022                 if (fctl & SCSW_FCTL_HALT_FUNC) {
1023                     s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
1024                                  SCSW_ACTL_START_PEND |
1025                                  SCSW_ACTL_HALT_PEND |
1026                                  SCSW_ACTL_CLEAR_PEND |
1027                                  SCSW_ACTL_SUSP);
1028                 } else {
1029                     s->ctrl &= ~SCSW_ACTL_RESUME_PEND;
1030                 }
1031             }
1032         }
1033         /* Clear pending sense data. */
1034         if (p->chars & PMCW_CHARS_MASK_CSENSE) {
1035             memset(sch->sense_data, 0 , sizeof(sch->sense_data));
1036         }
1037     }
1038 }
1039 
1040 static void copy_crw_to_guest(CRW *dest, const CRW *src)
1041 {
1042     dest->flags = cpu_to_be16(src->flags);
1043     dest->rsid = cpu_to_be16(src->rsid);
1044 }
1045 
1046 int css_do_stcrw(CRW *crw)
1047 {
1048     CrwContainer *crw_cont;
1049     int ret;
1050 
1051     crw_cont = QTAILQ_FIRST(&channel_subsys.pending_crws);
1052     if (crw_cont) {
1053         QTAILQ_REMOVE(&channel_subsys.pending_crws, crw_cont, sibling);
1054         copy_crw_to_guest(crw, &crw_cont->crw);
1055         g_free(crw_cont);
1056         ret = 0;
1057     } else {
1058         /* List was empty, turn crw machine checks on again. */
1059         memset(crw, 0, sizeof(*crw));
1060         channel_subsys.do_crw_mchk = true;
1061         ret = 1;
1062     }
1063 
1064     return ret;
1065 }
1066 
1067 static void copy_crw_from_guest(CRW *dest, const CRW *src)
1068 {
1069     dest->flags = be16_to_cpu(src->flags);
1070     dest->rsid = be16_to_cpu(src->rsid);
1071 }
1072 
1073 void css_undo_stcrw(CRW *crw)
1074 {
1075     CrwContainer *crw_cont;
1076 
1077     crw_cont = g_try_malloc0(sizeof(CrwContainer));
1078     if (!crw_cont) {
1079         channel_subsys.crws_lost = true;
1080         return;
1081     }
1082     copy_crw_from_guest(&crw_cont->crw, crw);
1083 
1084     QTAILQ_INSERT_HEAD(&channel_subsys.pending_crws, crw_cont, sibling);
1085 }
1086 
1087 int css_do_tpi(IOIntCode *int_code, int lowcore)
1088 {
1089     /* No pending interrupts for !KVM. */
1090     return 0;
1091  }
1092 
1093 int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
1094                          int rfmt, void *buf)
1095 {
1096     int i, desc_size;
1097     uint32_t words[8];
1098     uint32_t chpid_type_word;
1099     CssImage *css;
1100 
1101     if (!m && !cssid) {
1102         css = channel_subsys.css[channel_subsys.default_cssid];
1103     } else {
1104         css = channel_subsys.css[cssid];
1105     }
1106     if (!css) {
1107         return 0;
1108     }
1109     desc_size = 0;
1110     for (i = f_chpid; i <= l_chpid; i++) {
1111         if (css->chpids[i].in_use) {
1112             chpid_type_word = 0x80000000 | (css->chpids[i].type << 8) | i;
1113             if (rfmt == 0) {
1114                 words[0] = cpu_to_be32(chpid_type_word);
1115                 words[1] = 0;
1116                 memcpy(buf + desc_size, words, 8);
1117                 desc_size += 8;
1118             } else if (rfmt == 1) {
1119                 words[0] = cpu_to_be32(chpid_type_word);
1120                 words[1] = 0;
1121                 words[2] = 0;
1122                 words[3] = 0;
1123                 words[4] = 0;
1124                 words[5] = 0;
1125                 words[6] = 0;
1126                 words[7] = 0;
1127                 memcpy(buf + desc_size, words, 32);
1128                 desc_size += 32;
1129             }
1130         }
1131     }
1132     return desc_size;
1133 }
1134 
1135 void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
1136 {
1137     /* dct is currently ignored (not really meaningful for our devices) */
1138     /* TODO: Don't ignore mbk. */
1139     if (update && !channel_subsys.chnmon_active) {
1140         /* Enable measuring. */
1141         channel_subsys.chnmon_area = mbo;
1142         channel_subsys.chnmon_active = true;
1143     }
1144     if (!update && channel_subsys.chnmon_active) {
1145         /* Disable measuring. */
1146         channel_subsys.chnmon_area = 0;
1147         channel_subsys.chnmon_active = false;
1148     }
1149 }
1150 
1151 int css_do_rsch(SubchDev *sch)
1152 {
1153     SCSW *s = &sch->curr_status.scsw;
1154     PMCW *p = &sch->curr_status.pmcw;
1155     int ret;
1156 
1157     if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {
1158         ret = -ENODEV;
1159         goto out;
1160     }
1161 
1162     if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
1163         ret = -EINPROGRESS;
1164         goto out;
1165     }
1166 
1167     if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
1168         (s->ctrl & SCSW_ACTL_RESUME_PEND) ||
1169         (!(s->ctrl & SCSW_ACTL_SUSP))) {
1170         ret = -EINVAL;
1171         goto out;
1172     }
1173 
1174     /* If monitoring is active, update counter. */
1175     if (channel_subsys.chnmon_active) {
1176         css_update_chnmon(sch);
1177     }
1178 
1179     s->ctrl |= SCSW_ACTL_RESUME_PEND;
1180     do_subchannel_work(sch, NULL);
1181     ret = 0;
1182 
1183 out:
1184     return ret;
1185 }
1186 
1187 int css_do_rchp(uint8_t cssid, uint8_t chpid)
1188 {
1189     uint8_t real_cssid;
1190 
1191     if (cssid > channel_subsys.max_cssid) {
1192         return -EINVAL;
1193     }
1194     if (channel_subsys.max_cssid == 0) {
1195         real_cssid = channel_subsys.default_cssid;
1196     } else {
1197         real_cssid = cssid;
1198     }
1199     if (!channel_subsys.css[real_cssid]) {
1200         return -EINVAL;
1201     }
1202 
1203     if (!channel_subsys.css[real_cssid]->chpids[chpid].in_use) {
1204         return -ENODEV;
1205     }
1206 
1207     if (!channel_subsys.css[real_cssid]->chpids[chpid].is_virtual) {
1208         fprintf(stderr,
1209                 "rchp unsupported for non-virtual chpid %x.%02x!\n",
1210                 real_cssid, chpid);
1211         return -ENODEV;
1212     }
1213 
1214     /* We don't really use a channel path, so we're done here. */
1215     css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT,
1216                   channel_subsys.max_cssid > 0 ? 1 : 0, chpid);
1217     if (channel_subsys.max_cssid > 0) {
1218         css_queue_crw(CRW_RSC_CHP, CRW_ERC_INIT, 0, real_cssid << 8);
1219     }
1220     return 0;
1221 }
1222 
1223 bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
1224 {
1225     SubchSet *set;
1226     uint8_t real_cssid;
1227 
1228     real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
1229     if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
1230         !channel_subsys.css[real_cssid] ||
1231         !channel_subsys.css[real_cssid]->sch_set[ssid]) {
1232         return true;
1233     }
1234     set = channel_subsys.css[real_cssid]->sch_set[ssid];
1235     return schid > find_last_bit(set->schids_used,
1236                                  (MAX_SCHID + 1) / sizeof(unsigned long));
1237 }
1238 
1239 static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
1240 {
1241     CssImage *css;
1242 
1243     trace_css_chpid_add(cssid, chpid, type);
1244     if (cssid > MAX_CSSID) {
1245         return -EINVAL;
1246     }
1247     css = channel_subsys.css[cssid];
1248     if (!css) {
1249         return -EINVAL;
1250     }
1251     if (css->chpids[chpid].in_use) {
1252         return -EEXIST;
1253     }
1254     css->chpids[chpid].in_use = 1;
1255     css->chpids[chpid].type = type;
1256     css->chpids[chpid].is_virtual = 1;
1257 
1258     css_generate_chp_crws(cssid, chpid);
1259 
1260     return 0;
1261 }
1262 
1263 void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
1264 {
1265     PMCW *p = &sch->curr_status.pmcw;
1266     SCSW *s = &sch->curr_status.scsw;
1267     int i;
1268     CssImage *css = channel_subsys.css[sch->cssid];
1269 
1270     assert(css != NULL);
1271     memset(p, 0, sizeof(PMCW));
1272     p->flags |= PMCW_FLAGS_MASK_DNV;
1273     p->devno = sch->devno;
1274     /* single path */
1275     p->pim = 0x80;
1276     p->pom = 0xff;
1277     p->pam = 0x80;
1278     p->chpid[0] = chpid;
1279     if (!css->chpids[chpid].in_use) {
1280         css_add_virtual_chpid(sch->cssid, chpid, type);
1281     }
1282 
1283     memset(s, 0, sizeof(SCSW));
1284     sch->curr_status.mba = 0;
1285     for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
1286         sch->curr_status.mda[i] = 0;
1287     }
1288 }
1289 
1290 SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, uint16_t schid)
1291 {
1292     uint8_t real_cssid;
1293 
1294     real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
1295 
1296     if (!channel_subsys.css[real_cssid]) {
1297         return NULL;
1298     }
1299 
1300     if (!channel_subsys.css[real_cssid]->sch_set[ssid]) {
1301         return NULL;
1302     }
1303 
1304     return channel_subsys.css[real_cssid]->sch_set[ssid]->sch[schid];
1305 }
1306 
1307 bool css_subch_visible(SubchDev *sch)
1308 {
1309     if (sch->ssid > channel_subsys.max_ssid) {
1310         return false;
1311     }
1312 
1313     if (sch->cssid != channel_subsys.default_cssid) {
1314         return (channel_subsys.max_cssid > 0);
1315     }
1316 
1317     return true;
1318 }
1319 
1320 bool css_present(uint8_t cssid)
1321 {
1322     return (channel_subsys.css[cssid] != NULL);
1323 }
1324 
1325 bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno)
1326 {
1327     if (!channel_subsys.css[cssid]) {
1328         return false;
1329     }
1330     if (!channel_subsys.css[cssid]->sch_set[ssid]) {
1331         return false;
1332     }
1333 
1334     return !!test_bit(devno,
1335                       channel_subsys.css[cssid]->sch_set[ssid]->devnos_used);
1336 }
1337 
1338 void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
1339                       uint16_t devno, SubchDev *sch)
1340 {
1341     CssImage *css;
1342     SubchSet *s_set;
1343 
1344     trace_css_assign_subch(sch ? "assign" : "deassign", cssid, ssid, schid,
1345                            devno);
1346     if (!channel_subsys.css[cssid]) {
1347         fprintf(stderr,
1348                 "Suspicious call to %s (%x.%x.%04x) for non-existing css!\n",
1349                 __func__, cssid, ssid, schid);
1350         return;
1351     }
1352     css = channel_subsys.css[cssid];
1353 
1354     if (!css->sch_set[ssid]) {
1355         css->sch_set[ssid] = g_malloc0(sizeof(SubchSet));
1356     }
1357     s_set = css->sch_set[ssid];
1358 
1359     s_set->sch[schid] = sch;
1360     if (sch) {
1361         set_bit(schid, s_set->schids_used);
1362         set_bit(devno, s_set->devnos_used);
1363     } else {
1364         clear_bit(schid, s_set->schids_used);
1365         clear_bit(devno, s_set->devnos_used);
1366     }
1367 }
1368 
1369 void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid)
1370 {
1371     CrwContainer *crw_cont;
1372 
1373     trace_css_crw(rsc, erc, rsid, chain ? "(chained)" : "");
1374     /* TODO: Maybe use a static crw pool? */
1375     crw_cont = g_try_malloc0(sizeof(CrwContainer));
1376     if (!crw_cont) {
1377         channel_subsys.crws_lost = true;
1378         return;
1379     }
1380     crw_cont->crw.flags = (rsc << 8) | erc;
1381     if (chain) {
1382         crw_cont->crw.flags |= CRW_FLAGS_MASK_C;
1383     }
1384     crw_cont->crw.rsid = rsid;
1385     if (channel_subsys.crws_lost) {
1386         crw_cont->crw.flags |= CRW_FLAGS_MASK_R;
1387         channel_subsys.crws_lost = false;
1388     }
1389 
1390     QTAILQ_INSERT_TAIL(&channel_subsys.pending_crws, crw_cont, sibling);
1391 
1392     if (channel_subsys.do_crw_mchk) {
1393         channel_subsys.do_crw_mchk = false;
1394         /* Inject crw pending machine check. */
1395         s390_crw_mchk();
1396     }
1397 }
1398 
1399 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
1400                            int hotplugged, int add)
1401 {
1402     uint8_t guest_cssid;
1403     bool chain_crw;
1404 
1405     if (add && !hotplugged) {
1406         return;
1407     }
1408     if (channel_subsys.max_cssid == 0) {
1409         /* Default cssid shows up as 0. */
1410         guest_cssid = (cssid == channel_subsys.default_cssid) ? 0 : cssid;
1411     } else {
1412         /* Show real cssid to the guest. */
1413         guest_cssid = cssid;
1414     }
1415     /*
1416      * Only notify for higher subchannel sets/channel subsystems if the
1417      * guest has enabled it.
1418      */
1419     if ((ssid > channel_subsys.max_ssid) ||
1420         (guest_cssid > channel_subsys.max_cssid) ||
1421         ((channel_subsys.max_cssid == 0) &&
1422          (cssid != channel_subsys.default_cssid))) {
1423         return;
1424     }
1425     chain_crw = (channel_subsys.max_ssid > 0) ||
1426             (channel_subsys.max_cssid > 0);
1427     css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, chain_crw ? 1 : 0, schid);
1428     if (chain_crw) {
1429         css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0,
1430                       (guest_cssid << 8) | (ssid << 4));
1431     }
1432 }
1433 
1434 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
1435 {
1436     /* TODO */
1437 }
1438 
1439 void css_generate_css_crws(uint8_t cssid)
1440 {
1441     if (!channel_subsys.sei_pending) {
1442         css_queue_crw(CRW_RSC_CSS, 0, 0, cssid);
1443     }
1444     channel_subsys.sei_pending = true;
1445 }
1446 
1447 void css_clear_sei_pending(void)
1448 {
1449     channel_subsys.sei_pending = false;
1450 }
1451 
1452 int css_enable_mcsse(void)
1453 {
1454     trace_css_enable_facility("mcsse");
1455     channel_subsys.max_cssid = MAX_CSSID;
1456     return 0;
1457 }
1458 
1459 int css_enable_mss(void)
1460 {
1461     trace_css_enable_facility("mss");
1462     channel_subsys.max_ssid = MAX_SSID;
1463     return 0;
1464 }
1465 
1466 void subch_device_save(SubchDev *s, QEMUFile *f)
1467 {
1468     int i;
1469 
1470     qemu_put_byte(f, s->cssid);
1471     qemu_put_byte(f, s->ssid);
1472     qemu_put_be16(f, s->schid);
1473     qemu_put_be16(f, s->devno);
1474     qemu_put_byte(f, s->thinint_active);
1475     /* SCHIB */
1476     /*     PMCW */
1477     qemu_put_be32(f, s->curr_status.pmcw.intparm);
1478     qemu_put_be16(f, s->curr_status.pmcw.flags);
1479     qemu_put_be16(f, s->curr_status.pmcw.devno);
1480     qemu_put_byte(f, s->curr_status.pmcw.lpm);
1481     qemu_put_byte(f, s->curr_status.pmcw.pnom);
1482     qemu_put_byte(f, s->curr_status.pmcw.lpum);
1483     qemu_put_byte(f, s->curr_status.pmcw.pim);
1484     qemu_put_be16(f, s->curr_status.pmcw.mbi);
1485     qemu_put_byte(f, s->curr_status.pmcw.pom);
1486     qemu_put_byte(f, s->curr_status.pmcw.pam);
1487     qemu_put_buffer(f, s->curr_status.pmcw.chpid, 8);
1488     qemu_put_be32(f, s->curr_status.pmcw.chars);
1489     /*     SCSW */
1490     qemu_put_be16(f, s->curr_status.scsw.flags);
1491     qemu_put_be16(f, s->curr_status.scsw.ctrl);
1492     qemu_put_be32(f, s->curr_status.scsw.cpa);
1493     qemu_put_byte(f, s->curr_status.scsw.dstat);
1494     qemu_put_byte(f, s->curr_status.scsw.cstat);
1495     qemu_put_be16(f, s->curr_status.scsw.count);
1496     qemu_put_be64(f, s->curr_status.mba);
1497     qemu_put_buffer(f, s->curr_status.mda, 4);
1498     /* end SCHIB */
1499     qemu_put_buffer(f, s->sense_data, 32);
1500     qemu_put_be64(f, s->channel_prog);
1501     /* last cmd */
1502     qemu_put_byte(f, s->last_cmd.cmd_code);
1503     qemu_put_byte(f, s->last_cmd.flags);
1504     qemu_put_be16(f, s->last_cmd.count);
1505     qemu_put_be32(f, s->last_cmd.cda);
1506     qemu_put_byte(f, s->last_cmd_valid);
1507     qemu_put_byte(f, s->id.reserved);
1508     qemu_put_be16(f, s->id.cu_type);
1509     qemu_put_byte(f, s->id.cu_model);
1510     qemu_put_be16(f, s->id.dev_type);
1511     qemu_put_byte(f, s->id.dev_model);
1512     qemu_put_byte(f, s->id.unused);
1513     for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) {
1514         qemu_put_byte(f, s->id.ciw[i].type);
1515         qemu_put_byte(f, s->id.ciw[i].command);
1516         qemu_put_be16(f, s->id.ciw[i].count);
1517     }
1518     qemu_put_byte(f, s->ccw_fmt_1);
1519     qemu_put_byte(f, s->ccw_no_data_cnt);
1520 }
1521 
1522 int subch_device_load(SubchDev *s, QEMUFile *f)
1523 {
1524     int i;
1525 
1526     s->cssid = qemu_get_byte(f);
1527     s->ssid = qemu_get_byte(f);
1528     s->schid = qemu_get_be16(f);
1529     s->devno = qemu_get_be16(f);
1530     s->thinint_active = qemu_get_byte(f);
1531     /* SCHIB */
1532     /*     PMCW */
1533     s->curr_status.pmcw.intparm = qemu_get_be32(f);
1534     s->curr_status.pmcw.flags = qemu_get_be16(f);
1535     s->curr_status.pmcw.devno = qemu_get_be16(f);
1536     s->curr_status.pmcw.lpm = qemu_get_byte(f);
1537     s->curr_status.pmcw.pnom  = qemu_get_byte(f);
1538     s->curr_status.pmcw.lpum = qemu_get_byte(f);
1539     s->curr_status.pmcw.pim = qemu_get_byte(f);
1540     s->curr_status.pmcw.mbi = qemu_get_be16(f);
1541     s->curr_status.pmcw.pom = qemu_get_byte(f);
1542     s->curr_status.pmcw.pam = qemu_get_byte(f);
1543     qemu_get_buffer(f, s->curr_status.pmcw.chpid, 8);
1544     s->curr_status.pmcw.chars = qemu_get_be32(f);
1545     /*     SCSW */
1546     s->curr_status.scsw.flags = qemu_get_be16(f);
1547     s->curr_status.scsw.ctrl = qemu_get_be16(f);
1548     s->curr_status.scsw.cpa = qemu_get_be32(f);
1549     s->curr_status.scsw.dstat = qemu_get_byte(f);
1550     s->curr_status.scsw.cstat = qemu_get_byte(f);
1551     s->curr_status.scsw.count = qemu_get_be16(f);
1552     s->curr_status.mba = qemu_get_be64(f);
1553     qemu_get_buffer(f, s->curr_status.mda, 4);
1554     /* end SCHIB */
1555     qemu_get_buffer(f, s->sense_data, 32);
1556     s->channel_prog = qemu_get_be64(f);
1557     /* last cmd */
1558     s->last_cmd.cmd_code = qemu_get_byte(f);
1559     s->last_cmd.flags = qemu_get_byte(f);
1560     s->last_cmd.count = qemu_get_be16(f);
1561     s->last_cmd.cda = qemu_get_be32(f);
1562     s->last_cmd_valid = qemu_get_byte(f);
1563     s->id.reserved = qemu_get_byte(f);
1564     s->id.cu_type = qemu_get_be16(f);
1565     s->id.cu_model = qemu_get_byte(f);
1566     s->id.dev_type = qemu_get_be16(f);
1567     s->id.dev_model = qemu_get_byte(f);
1568     s->id.unused = qemu_get_byte(f);
1569     for (i = 0; i < ARRAY_SIZE(s->id.ciw); i++) {
1570         s->id.ciw[i].type = qemu_get_byte(f);
1571         s->id.ciw[i].command = qemu_get_byte(f);
1572         s->id.ciw[i].count = qemu_get_be16(f);
1573     }
1574     s->ccw_fmt_1 = qemu_get_byte(f);
1575     s->ccw_no_data_cnt = qemu_get_byte(f);
1576     /*
1577      * Hack alert. We don't migrate the channel subsystem status (no
1578      * device!), but we need to find out if the guest enabled mss/mcss-e.
1579      * If the subchannel is enabled, it certainly was able to access it,
1580      * so adjust the max_ssid/max_cssid values for relevant ssid/cssid
1581      * values. This is not watertight, but better than nothing.
1582      */
1583     if (s->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA) {
1584         if (s->ssid) {
1585             channel_subsys.max_ssid = MAX_SSID;
1586         }
1587         if (s->cssid != channel_subsys.default_cssid) {
1588             channel_subsys.max_cssid = MAX_CSSID;
1589         }
1590     }
1591     return 0;
1592 }
1593 
1594 void css_reset_sch(SubchDev *sch)
1595 {
1596     PMCW *p = &sch->curr_status.pmcw;
1597 
1598     if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
1599         sch->disable_cb(sch);
1600     }
1601 
1602     p->intparm = 0;
1603     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
1604                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
1605                   PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
1606     p->flags |= PMCW_FLAGS_MASK_DNV;
1607     p->devno = sch->devno;
1608     p->pim = 0x80;
1609     p->lpm = p->pim;
1610     p->pnom = 0;
1611     p->lpum = 0;
1612     p->mbi = 0;
1613     p->pom = 0xff;
1614     p->pam = 0x80;
1615     p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
1616                   PMCW_CHARS_MASK_CSENSE);
1617 
1618     memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw));
1619     sch->curr_status.mba = 0;
1620 
1621     sch->channel_prog = 0x0;
1622     sch->last_cmd_valid = false;
1623     sch->thinint_active = false;
1624 }
1625 
1626 void css_reset(void)
1627 {
1628     CrwContainer *crw_cont;
1629 
1630     /* Clean up monitoring. */
1631     channel_subsys.chnmon_active = false;
1632     channel_subsys.chnmon_area = 0;
1633 
1634     /* Clear pending CRWs. */
1635     while ((crw_cont = QTAILQ_FIRST(&channel_subsys.pending_crws))) {
1636         QTAILQ_REMOVE(&channel_subsys.pending_crws, crw_cont, sibling);
1637         g_free(crw_cont);
1638     }
1639     channel_subsys.sei_pending = false;
1640     channel_subsys.do_crw_mchk = true;
1641     channel_subsys.crws_lost = false;
1642 
1643     /* Reset maximum ids. */
1644     channel_subsys.max_cssid = 0;
1645     channel_subsys.max_ssid = 0;
1646 }
1647