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


Reply via email to