qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

s390x/css: handle cssid 255 correctly

The cssid 255 is reserved but still valid from an architectural
point of view. However, feeding a bogus schid of 0xffffffff into
the virtio hypercall will lead to a crash:

Stack trace of thread 138363:
#0 0x00000000100d168c css_find_subch (qemu-system-s390x)
#1 0x00000000100d3290 virtio_ccw_hcall_notify
#2 0x00000000100cbf60 s390_virtio_hypercall
#3 0x000000001010ff7a handle_hypercall
#4 0x0000000010079ed4 kvm_cpu_exec (qemu-system-s390x)
#5 0x00000000100609b4 qemu_kvm_cpu_thread_fn
#6 0x000003ff8b887bb4 start_thread (libpthread.so.0)
#7 0x000003ff8b78df0a thread_start (libc.so.6)

This is because the css array was only allocated for 0..254
instead of 0..255.

Let's fix this by bumping MAX_CSSID to 255 and fencing off the
reserved cssid of 255 during css image allocation.

Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

+4 -6
+3 -5
hw/s390x/css.c
··· 141 141 int css_create_css_image(uint8_t cssid, bool default_image) 142 142 { 143 143 trace_css_new_image(cssid, default_image ? "(default)" : ""); 144 - if (cssid > MAX_CSSID) { 144 + /* 255 is reserved */ 145 + if (cssid == 255) { 145 146 return -EINVAL; 146 147 } 147 148 if (channel_subsys.css[cssid]) { ··· 1267 1268 uint8_t real_cssid; 1268 1269 1269 1270 real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid; 1270 - if (real_cssid > MAX_CSSID || ssid > MAX_SSID || 1271 + if (ssid > MAX_SSID || 1271 1272 !channel_subsys.css[real_cssid] || 1272 1273 !channel_subsys.css[real_cssid]->sch_set[ssid]) { 1273 1274 return true; ··· 1282 1283 CssImage *css; 1283 1284 1284 1285 trace_css_chpid_add(cssid, chpid, type); 1285 - if (cssid > MAX_CSSID) { 1286 - return -EINVAL; 1287 - } 1288 1286 css = channel_subsys.css[cssid]; 1289 1287 if (!css) { 1290 1288 return -EINVAL;
+1 -1
include/hw/s390x/css.h
··· 20 20 #define MAX_DEVNO 65535 21 21 #define MAX_SCHID 65535 22 22 #define MAX_SSID 3 23 - #define MAX_CSSID 254 /* 255 is reserved */ 23 + #define MAX_CSSID 255 24 24 #define MAX_CHPID 255 25 25 26 26 #define MAX_CIWS 62