From: Eric Farman <[email protected]> virtio-ccw uses a single virtual CHPID for all devices and device-types, but vfio-ccw (passthrough) shares real CHPID information with the guest. A sufficiently large passthrough configuration would exceed the defined response payload.
Fix this by limiting the number of CHPID descriptions that are returned based on the given response format. Cc: [email protected] Reviewed-by: Christian Borntraeger <[email protected]> Reviewed-by: Matthew Rosato <[email protected]> Signed-off-by: Eric Farman <[email protected]> Signed-off-by: Christian Borntraeger <[email protected]> Message-ID: <[email protected]> Signed-off-by: Cornelia Huck <[email protected]> (cherry picked from commit 22f2da06a8b291c975a7caf05dbd3b180c856741) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 738800c98df..38d2d90028c 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -1900,6 +1900,7 @@ int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid, int i, desc_size; uint32_t words[8]; uint32_t chpid_type_word; + uint32_t max_chpids, chpid_count = 0; CssImage *css; if (!m && !cssid) { @@ -1910,9 +1911,25 @@ int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid, if (!css) { return 0; } + + if (rfmt == 0) { + max_chpids = 256; + } else if (rfmt == 1) { + max_chpids = 127; + } else { + /* Should be rejected by caller */ + return 0; + } + desc_size = 0; for (i = f_chpid; i <= l_chpid; i++) { if (css->chpids[i].in_use) { + /* Limit number of CHPIDs sent back */ + if (chpid_count == max_chpids) { + break; + } + + chpid_count++; chpid_type_word = 0x80000000 | (css->chpids[i].type << 8) | i; if (rfmt == 0) { words[0] = cpu_to_be32(chpid_type_word); -- 2.47.3
