--- /dev/null
+From f3c74b38a55aefe1004200d15a83f109b510068c Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Sat, 20 Apr 2019 13:27:51 +0200
+Subject: RAS/CEC: Fix binary search function
+
+From: Borislav Petkov <bp@suse.de>
+
+commit f3c74b38a55aefe1004200d15a83f109b510068c upstream.
+
+Switch to using Donald Knuth's binary search algorithm (The Art of
+Computer Programming, vol. 3, section 6.2.1). This should've been done
+from the very beginning but the author must've been smoking something
+very potent at the time.
+
+The problem with the current one was that it would return the wrong
+element index in certain situations:
+
+ https://lkml.kernel.org/r/CAM_iQpVd02zkVJ846cj-Fg1yUNuz6tY5q1Vpj4LrXmE06dPYYg@mail.gmail.com
+
+and the noodling code after the loop was fishy at best.
+
+So switch to using Knuth's binary search. The final result is much
+cleaner and straightforward.
+
+Fixes: 011d82611172 ("RAS: Add a Corrected Errors Collector")
+Reported-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ras/cec.c | 34 ++++++++++++++++++++--------------
+ 1 file changed, 20 insertions(+), 14 deletions(-)
+
+--- a/drivers/ras/cec.c
++++ b/drivers/ras/cec.c
+@@ -185,32 +185,38 @@ static void cec_timer_fn(unsigned long d
+ */
+ static int __find_elem(struct ce_array *ca, u64 pfn, unsigned int *to)
+ {
++ int min = 0, max = ca->n - 1;
+ u64 this_pfn;
+- int min = 0, max = ca->n;
+
+- while (min < max) {
+- int tmp = (max + min) >> 1;
++ while (min <= max) {
++ int i = (min + max) >> 1;
+
+- this_pfn = PFN(ca->array[tmp]);
++ this_pfn = PFN(ca->array[i]);
+
+ if (this_pfn < pfn)
+- min = tmp + 1;
++ min = i + 1;
+ else if (this_pfn > pfn)
+- max = tmp;
+- else {
+- min = tmp;
+- break;
++ max = i - 1;
++ else if (this_pfn == pfn) {
++ if (to)
++ *to = i;
++
++ return i;
+ }
+ }
+
++ /*
++ * When the loop terminates without finding @pfn, min has the index of
++ * the element slot where the new @pfn should be inserted. The loop
++ * terminates when min > max, which means the min index points to the
++ * bigger element while the max index to the smaller element, in-between
++ * which the new @pfn belongs to.
++ *
++ * For more details, see exercise 1, Section 6.2.1 in TAOCP, vol. 3.
++ */
+ if (to)
+ *to = min;
+
+- this_pfn = PFN(ca->array[min]);
+-
+- if (this_pfn == pfn)
+- return min;
+-
+ return -ENOKEY;
+ }
+