Edward O'Callaghan has uploaded this change for review.

View Change

cbtable.c: don't assume high addresses can fully map 1MB

I do not know a clean way to compose find_lb_table() and
find_lb_table_remap() or why this cannot always been done.

However this is a fix ported from downstream found here:
https://chromium-review.googlesource.com/685608

Change-Id: Ibf2323a0a793f693928b81c64acd09bb932a6b98
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
---
M cbtable.c
1 file changed, 61 insertions(+), 7 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/21/45521/1
diff --git a/cbtable.c b/cbtable.c
index 6185f12..6dd4059 100644
--- a/cbtable.c
+++ b/cbtable.c
@@ -205,8 +205,68 @@
msg_pdbg("Found coreboot table at 0x%08lx.\n", addr);
return head;

+ };
+
+ return NULL;
+}
+
+static struct lb_header *find_lb_table_remap(unsigned long start_addr,
+ uint8_t **table_area)
+{
+ size_t offset;
+ unsigned long addr, 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 (addr = offset, end = getpagesize(); addr < end; addr += 16) {
+ struct lb_record *recs;
+ struct lb_header *head;
+
+ /* No more headers to check. */
+ if (end - addr < sizeof(*head))
+ return NULL;
+
+ head = (struct lb_header *)(((char *)base) + addr);
+
+ if (!lb_header_valid(head, addr))
+ continue;
+
+ if (mapping_size - addr < head->table_bytes + sizeof(*head)) {
+ size_t prev_mapping_size = mapping_size;
+ mapping_size = head->table_bytes + sizeof(*head);
+ mapping_size += addr;
+ 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");
+ return NULL;
+ }
+ }
+
+ head = (struct lb_header *)(((char *)base) + addr);
+ recs =
+ (struct lb_record *)(((char *)base) + addr + sizeof(*head));
+ if (!lb_table_valid(head, recs))
+ continue;
+ msg_pdbg("Found coreboot table at 0x%08lx.\n", addr);
+ *table_area = base;
+ return head;
+ }
+
+ physunmap(base, mapping_size);
return NULL;
}

@@ -283,15 +343,9 @@
(((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);
}
}


To view, visit change 45521. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: Ibf2323a0a793f693928b81c64acd09bb932a6b98
Gerrit-Change-Number: 45521
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-MessageType: newchange