[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen staging-4.18] target/s390x: Fix the "ignored match" case in VSTRS



commit 179a37924d55e645e660731f0e389d70a277a1c2
Author:     Ilya Leoshkevich <iii@xxxxxxxxxxxxx>
AuthorDate: Sat Aug 5 01:03:18 2023 +0200
Commit:     Michael Tokarev <mjt@xxxxxxxxxx>
CommitDate: Sun Sep 10 19:39:41 2023 +0300

    target/s390x: Fix the "ignored match" case in VSTRS
    
    Currently the emulation of VSTRS recognizes partial matches in presence
    of \0 in the haystack, which, according to PoP, is not correct:
    
        If the ZS flag is one and a zero byte was detected
        in the second operand, then there can not be a
        partial match ...
    
    Add a check for this. While at it, fold a number of explicitly handled
    special cases into the generic logic.
    
    Cc: qemu-stable@xxxxxxxxxx
    Reported-by: Claudio Fontana <cfontana@xxxxxxx>
    Closes: https://lists.gnu.org/archive/html/qemu-devel/2023-08/msg00633.html
    Fixes: 1d706f314191 ("target/s390x: vxeh2: vector string search")
    Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx>
    Message-Id: <20230804233748.218935-3-iii@xxxxxxxxxxxxx>
    Tested-by: Claudio Fontana <cfontana@xxxxxxx>
    Acked-by: David Hildenbrand <david@xxxxxxxxxx>
    Signed-off-by: Thomas Huth <thuth@xxxxxxxxxx>
    (cherry picked from commit 791b2b6a930273db694b9ba48bbb406e78715927)
    Signed-off-by: Michael Tokarev <mjt@xxxxxxxxxx>
---
 target/s390x/tcg/vec_string_helper.c | 54 ++++++++++++------------------------
 1 file changed, 17 insertions(+), 37 deletions(-)

diff --git a/target/s390x/tcg/vec_string_helper.c 
b/target/s390x/tcg/vec_string_helper.c
index 9b85becdfb..a19f429768 100644
--- a/target/s390x/tcg/vec_string_helper.c
+++ b/target/s390x/tcg/vec_string_helper.c
@@ -474,9 +474,9 @@ DEF_VSTRC_CC_RT_HELPER(32)
 static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
                  const S390Vector *v4, uint8_t es, bool zs)
 {
-    int substr_elen, substr_0, str_elen, i, j, k, cc;
+    int substr_elen, i, j, k, cc;
     int nelem = 16 >> es;
-    bool eos = false;
+    int str_leftmost_0;
 
     substr_elen = s390_vec_read_element8(v4, 7) >> es;
 
@@ -498,47 +498,20 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, 
const S390Vector *v3,
     }
 
     /* If ZS, look for eos in the searched string. */
+    str_leftmost_0 = nelem;
     if (zs) {
         for (k = 0; k < nelem; k++) {
             if (s390_vec_read_element(v2, k, es) == 0) {
-                eos = true;
+                str_leftmost_0 = k;
                 break;
             }
         }
-        str_elen = k;
-    } else {
-        str_elen = nelem;
     }
 
-    substr_0 = s390_vec_read_element(v3, 0, es);
-
-    for (k = 0; ; k++) {
-        for (; k < str_elen; k++) {
-            if (s390_vec_read_element(v2, k, es) == substr_0) {
-                break;
-            }
-        }
-
-        /* If we reached the end of the string, no match. */
-        if (k == str_elen) {
-            cc = eos; /* no match (with or without zero char) */
-            goto done;
-        }
-
-        /* If the substring is only one char, match. */
-        if (substr_elen == 1) {
-            cc = 2; /* full match */
-            goto done;
-        }
-
-        /* If the match begins at the last char, we have a partial match. */
-        if (k == str_elen - 1) {
-            cc = 3; /* partial match */
-            goto done;
-        }
-
+    cc = str_leftmost_0 == nelem ? 0 : 1;  /* No match. */
+    for (k = 0; k < nelem; k++) {
         i = MIN(nelem, k + substr_elen);
-        for (j = k + 1; j < i; j++) {
+        for (j = k; j < i; j++) {
             uint32_t e2 = s390_vec_read_element(v2, j, es);
             uint32_t e3 = s390_vec_read_element(v3, j - k, es);
             if (e2 != e3) {
@@ -546,9 +519,16 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, 
const S390Vector *v3,
             }
         }
         if (j == i) {
-            /* Matched up until "end". */
-            cc = i - k == substr_elen ? 2 : 3; /* full or partial match */
-            goto done;
+            /* All elements matched. */
+            if (k > str_leftmost_0) {
+                cc = 1;  /* Ignored match. */
+                k = nelem;
+            } else if (i - k == substr_elen) {
+                cc = 2;  /* Full match. */
+            } else {
+                cc = 3;  /* Partial match. */
+            }
+            break;
         }
     }
 
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#staging-4.18



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.