aboutsummaryrefslogtreecommitdiff
path: root/external
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2019-10-03 15:23:42 +0930
committerOliver O'Halloran <oohall@gmail.com>2019-10-14 16:27:10 +1100
commit96ddf4b5d3e18ed9fbf726d0dabebe1ec2424fac (patch)
tree416dd1e61f3056fd8b17250fb41311e2422367c4 /external
parenta950fd789c1ce0fbdc4f5486ccdd8301d6258ba7 (diff)
downloadskiboot-96ddf4b5d3e18ed9fbf726d0dabebe1ec2424fac.zip
skiboot-96ddf4b5d3e18ed9fbf726d0dabebe1ec2424fac.tar.gz
skiboot-96ddf4b5d3e18ed9fbf726d0dabebe1ec2424fac.tar.bz2
blocklevel: smart_write: Fix unaligned writes to ECC partitions
Currently trying to clear a gard record results in errors: $ ./opal-gard -pef part create /sys0/node0/proc1 $ ./opal-gard -pef part list ID | Error | Type | Path --------------------------------------------------------- 00000001 | 00000000 | Manual | /Sys0/Node0/Proc1 ========================================================= $ ./opal-gard -pef part clear 00000001 Clearing gard record 0x00000001...done ECC: uncorrectable error: ffffff00ffffffff ff libflash ecc invalid $ A little wrapper around hexdump(1) helps show where the error lies by grouping output in blocks of nine such that the last byte is the ECC byte: $ declare -f ecchd ecchd () { hexdump -e '"%08_ax""\t"' -e '9/1 "%02x ""\t""|"' -e '9/1 "%_p""|\n"' "$@" } A clean GARD partition displays as: $ ecchd part 0002c000 ff ff ff ff ff ff ff ff 00 |.........| * 00030ffb ff ff ff ff ff |.....| $ Dumping the corrupt partition shows: $ ecchd part 0002c000 ff ff ff ff ff ff ff ff 00 |.........| * 0002c024 ff ff ff ff ff ff ff ff ff |.........| 0002c02d ff ff ff 00 ff ff ff ff ff |.........| * 0002c051 ff ff ff 00 ff ff ff ff 00 |.........| 0002c05a ff ff ff ff ff ff ff ff 00 |.........| * 00030ffb ff ff ff ff ff |.....| $ blocklevel_smart_write() turned out to not be quite as smart as it thought it was in that any unaligned write to ECC protected partitions aligned the calculated ECC values to the start of the write buffer and not relative to the start of the partition. Fixes: 29d1e6f78109 ("libflash/blocklevel: add a smart write function which wraps up eraseing and writing") Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'external')
-rw-r--r--external/gard/test/results/11-clear-first.err0
-rw-r--r--external/gard/test/results/11-clear-first.out13
-rw-r--r--external/gard/test/tests/11-clear-first26
3 files changed, 39 insertions, 0 deletions
diff --git a/external/gard/test/results/11-clear-first.err b/external/gard/test/results/11-clear-first.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/external/gard/test/results/11-clear-first.err
diff --git a/external/gard/test/results/11-clear-first.out b/external/gard/test/results/11-clear-first.out
new file mode 100644
index 0000000..3b67689
--- /dev/null
+++ b/external/gard/test/results/11-clear-first.out
@@ -0,0 +1,13 @@
+Clearing the entire gard partition...done
+ ID | Error | Type | Path
+---------------------------------------------------------
+ 00000001 | 00000000 | Manual | /Sys0/Node0/Proc0
+ 00000002 | 00000000 | Manual | /Sys0/Node0/Proc1
+=========================================================
+Clearing gard record 0x00000001...done
+ ID | Error | Type | Path
+---------------------------------------------------------
+ 00000002 | 00000000 | Manual | /Sys0/Node0/Proc1
+=========================================================
+Clearing gard record 0x00000002...done
+No GARD entries to display
diff --git a/external/gard/test/tests/11-clear-first b/external/gard/test/tests/11-clear-first
new file mode 100644
index 0000000..c59fcc8
--- /dev/null
+++ b/external/gard/test/tests/11-clear-first
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+DATA=$(mktemp)
+
+cleanup() {
+ rm -f $DATA
+}
+
+trap cleanup EXIT
+
+dd if=/dev/zero of=$DATA bs=$((0x1000)) count=5 2>/dev/null
+
+run_binary "./opal-gard" "-p -e -f $DATA clear all"
+run_binary "./opal-gard" "-p -e -f $DATA create /sys0/node0/proc0"
+run_binary "./opal-gard" "-p -e -f $DATA create /sys0/node0/proc1"
+run_binary "./opal-gard" "-p -e -f $DATA list"
+run_binary "./opal-gard" "-p -e -f $DATA clear 00000001"
+run_binary "./opal-gard" "-p -e -f $DATA list"
+run_binary "./opal-gard" "-p -e -f $DATA clear 00000002"
+run_binary "./opal-gard" "-p -e -f $DATA list"
+
+diff_with_result
+
+pass_test