diff options
author | David Woodhouse <dwmw2@infradead.org> | 2019-06-13 16:25:13 +0100 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2019-06-18 18:42:19 -0400 |
commit | 6e56ed129c9782ba050a5fbfbf4ac12335b230f7 (patch) | |
tree | 34eaadf4905d616870674ccdf98050affd7b0a3d | |
parent | 85137fb5f2dfa5f83e9e340ca881c634ae14d4e9 (diff) | |
download | seabios-6e56ed129c9782ba050a5fbfbf4ac12335b230f7.tar.gz |
csm: Sanitise alignment constraint in Legacy16GetTableAddress
The alignment constraint is defined in the CSM specifications as
"Bit mapped. First non-zero bit from the right is the alignment."
Use __fls() to sanitise the alignment given that definition, since
passing a non-power-of-two alignment to _malloc() isn't going to work
well. And cope with being passed zero, which was happening for the
E820 table allocation from EDK2.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | src/fw/csm.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/fw/csm.c b/src/fw/csm.c index 03b4bb81..3fcc2529 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -258,11 +258,21 @@ handle_csm_0006(struct bregs *regs) u16 region = regs->bx; // (1 for F000 seg, 2 for E000 seg, 0 for either) void *chunk = NULL; + dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n", + size, align, region); + if (!region) region = 3; - dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n", - size, align, region); + // DX = Required address alignment. Bit mapped. + // First non-zero bit from the right is the alignment.*/ + if (align) { + align = 1 << __ffs(align); + if (align < MALLOC_MIN_ALIGN) + align = MALLOC_MIN_ALIGN; + } else { + align = MALLOC_MIN_ALIGN; + } if (region & 2) chunk = _malloc(&ZoneLow, size, align); |