summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward O'Callaghan <quasisec@chromium.org>2019-11-26 23:48:51 +1100
committerEdward O'Callaghan <quasisec@chromium.org>2021-01-25 22:39:13 +0000
commita2d9a40ec486798db14593b6641e2d5920ca50a0 (patch)
treed18c052617f4df9aeb31e32e6003bc40a3aeb7c3
parent1a21cc70d69d9d8f34d6b1faab1f942f57888585 (diff)
downloadflashrom-a2d9a40ec486798db14593b6641e2d5920ca50a0.tar.gz
flashrom-a2d9a40ec486798db14593b6641e2d5920ca50a0.tar.bz2
flashrom-a2d9a40ec486798db14593b6641e2d5920ca50a0.zip
cbtable.c: don't assume high addresses can fully map 1 MiB
Forward port the downstream `commit b17e9e41838`. When using a forwarding table entry for finding the coreboot table don't assume one has access to a full 1 MiB where the forwarding table entry points to. The reason is that the 1 MiB may cover address regions that have differing cacheability type. As such the kernel will complain and the mapping will fail. Instead, check the header first then map in the bytes that it indicates after sanity validation. That way there is no attempt at requesting an invalid mapping that spans different memory cacheability attributes. V.2: Incorperate Nico's and Angels comments from upstream. BUG=b:66681446 BRANCH=None TEST=Can successfully run 'flashrom -p host --wp-status' on kahlee without generating PAT errors. Original-Change-Id: Ic6c5832b069300cced66e11f4ca4a0bbc6e496de Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/685608 Original-Reviewed-by: Martin Roth <martinroth@chromium.org> Original-Reviewed-by: Justin TerAvest <teravest@chromium.org> Change-Id: I43705c19dd7c816098d03f528bde6f180c4c8f24 Signed-off-by: Edward O'Callaghan <quasisec@chromium.org> Reviewed-on: https://review.coreboot.org/c/flashrom/+/37240 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Sam McNally <sammc@google.com>
-rw-r--r--cbtable.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/cbtable.c b/cbtable.c
index 6185f125a..1424f4548 100644
--- a/cbtable.c
+++ b/cbtable.c
@@ -210,6 +210,62 @@ static struct lb_header *find_lb_table(void *base, unsigned long start,
return NULL;
}
+static struct lb_header *find_lb_table_remap(unsigned long start_addr,
+ uint8_t **table_area)
+{
+ size_t offset;
+ unsigned long end;
+ size_t mapping_size;
+ void *base;
+
+ mapping_size = getpagesize();
+ offset = start_addr % getpagesize();
+ start_addr -= offset;
+
+ base = physmap_ro("high tables", start_addr, mapping_size);
+ if (ERROR_PTR == base) {
+ msg_perr("Failed getting access to coreboot high tables.\n");
+ return NULL;
+ }
+
+ for (end = getpagesize(); offset < end; offset += 16) {
+ struct lb_record *recs;
+ struct lb_header *head;
+
+ /* No more headers to check. */
+ if (end - offset < sizeof(*head))
+ return NULL;
+
+ head = (struct lb_header *)(((char *)base) + offset);
+
+ if (!lb_header_valid(head, offset))
+ continue;
+
+ if (mapping_size - offset < head->table_bytes + sizeof(*head)) {
+ size_t prev_mapping_size = mapping_size;
+ mapping_size = head->table_bytes + sizeof(*head);
+ mapping_size += offset;
+ mapping_size += getpagesize() - (mapping_size % getpagesize());
+ physunmap(base, prev_mapping_size);
+ base = physmap_ro("high tables", start_addr, mapping_size);
+ if (ERROR_PTR == base)
+ msg_perr("Failed getting access to coreboot high tables.\n");
+ else
+ head = (struct lb_header *)(((char *)base) + offset);
+ }
+
+ recs = (struct lb_record *)(((char *)base) + offset + sizeof(*head));
+ if (!lb_table_valid(head, recs))
+ continue;
+ msg_pdbg("Found coreboot table at 0x%08lx.\n", offset);
+ *table_area = base;
+ return head;
+ }
+
+ physunmap(base, mapping_size);
+ return NULL;
+}
+
static void find_mainboard(struct lb_record *ptr, unsigned long addr)
{
struct lb_mainboard *rec;
@@ -283,15 +339,8 @@ int cb_parse_table(const char **vendor, const char **model)
(((char *)lb_table) + lb_table->header_bytes);
if (forward->tag == LB_TAG_FORWARD) {
start = forward->forward;
- start &= ~(getpagesize() - 1);
physunmap_unaligned(table_area, BYTES_TO_MAP);
- // FIXME: table_area is never unmapped below, nor is it unmapped above in the no-forward case
- table_area = physmap_ro_unaligned("high tables", start, BYTES_TO_MAP);
- if (ERROR_PTR == table_area) {
- msg_perr("Failed getting access to coreboot high tables.\n");
- return -1;
- }
- lb_table = find_lb_table(table_area, 0x00000, 0x1000);
+ lb_table = find_lb_table_remap(start, &table_area);
}
}