stand: Avoid unaligned access in smbios code
This code was written on x86 where unaligned accesses were easy. LinuxBoot running on aarch64 uses mmap of /dev/mem to read the smbios table. Linux's mapping of this memory doesn't allow the normal unaligned fixup, so we get a bus error instead. We can't use the more natural le16dec and friends because they optimize into a single, unaligned memory load. We don't see this issue on aarch64 UEFI because memory is mapped such that unaligned accesses are fixed up. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D39793
This commit is contained in:
parent
a083d08676
commit
c5e433b99e
@ -96,10 +96,47 @@ __FBSDID("$FreeBSD$");
|
||||
#define SMBIOS3_SIG "_SM3_"
|
||||
#define SMBIOS_DMI_SIG "_DMI_"
|
||||
|
||||
#define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off)))
|
||||
#define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off)))
|
||||
#define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off)))
|
||||
#define SMBIOS_GET64(base, off) (*(uint64_t *)((base) + (off)))
|
||||
/*
|
||||
* 5.1 General
|
||||
*...
|
||||
* NOTE The Entry Point Structure and all SMBIOS structures assume a
|
||||
* little-endian ordering convention...
|
||||
* ...
|
||||
*
|
||||
* We use memcpy to avoid unaligned access to memory. To normal memory, this is
|
||||
* fine, but the memory we are using might be mmap'd /dev/mem which under Linux
|
||||
* on aarch64 doesn't allow unaligned access. leXdec and friends can't be used
|
||||
* because those can optimize to an unaligned load (which often is fine, but not
|
||||
* for mmap'd /dev/mem which has special memory attributes).
|
||||
*/
|
||||
static inline uint8_t SMBIOS_GET8(const caddr_t base, int off) { return (base[off]); }
|
||||
|
||||
static inline uint16_t
|
||||
SMBIOS_GET16(const caddr_t base, int off)
|
||||
{
|
||||
uint16_t v;
|
||||
|
||||
memcpy(&v, base + off, sizeof(v));
|
||||
return (le16toh(v));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
SMBIOS_GET32(const caddr_t base, int off)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
memcpy(&v, base + off, sizeof(v));
|
||||
return (le32toh(v));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
SMBIOS_GET64(const caddr_t base, int off)
|
||||
{
|
||||
uint64_t v;
|
||||
|
||||
memcpy(&v, base + off, sizeof(v));
|
||||
return (le64toh(v));
|
||||
}
|
||||
|
||||
#define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01)
|
||||
#define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base))
|
||||
@ -195,7 +232,7 @@ smbios_setenv(const char *name, caddr_t addr, const int offset)
|
||||
#define UUID_TYPE uint32_t
|
||||
#define UUID_STEP sizeof(UUID_TYPE)
|
||||
#define UUID_ALL_BITS (UUID_SIZE / UUID_STEP)
|
||||
#define UUID_GET(base, off) (*(UUID_TYPE *)((base) + (off)))
|
||||
#define UUID_GET(base, off) SMBIOS_GET32(base, off)
|
||||
|
||||
static void
|
||||
smbios_setuuid(const char *name, const caddr_t addr, const int ver __unused)
|
||||
|
Loading…
Reference in New Issue
Block a user