When finding the physical address of a device allow intermediate addresses
to be 64-bit on 32-bit architectures. It is not uncommon for device trees to use the upper 32-bits to store what effectively is an index into the parent ranges property. In this case, when running with a 32-bit bus_addr_t and bus_size_t, we would previously truncate the address, this may then incorrectly match the wrong range, and return the wrong address. Tested by: bz (earlier version)
This commit is contained in:
parent
d28e78bacf
commit
b958a08eb7
@ -75,8 +75,8 @@ ofw_reg_to_paddr(phandle_t dev, int regno, bus_addr_t *paddr,
|
|||||||
bus_size_t *psize, pcell_t *ppci_hi)
|
bus_size_t *psize, pcell_t *ppci_hi)
|
||||||
{
|
{
|
||||||
pcell_t cell[32], pci_hi;
|
pcell_t cell[32], pci_hi;
|
||||||
bus_addr_t addr, raddr, baddr;
|
uint64_t addr, raddr, baddr;
|
||||||
bus_size_t size, rsize;
|
uint64_t size, rsize;
|
||||||
uint32_t c, nbridge, naddr, nsize;
|
uint32_t c, nbridge, naddr, nsize;
|
||||||
phandle_t bridge, parent;
|
phandle_t bridge, parent;
|
||||||
u_int spc, rspc;
|
u_int spc, rspc;
|
||||||
@ -167,6 +167,11 @@ ofw_reg_to_paddr(phandle_t dev, int regno, bus_addr_t *paddr,
|
|||||||
get_addr_props(bridge, &naddr, &nsize, &pci);
|
get_addr_props(bridge, &naddr, &nsize, &pci);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KASSERT(addr <= BUS_SPACE_MAXADDR,
|
||||||
|
("Bus sddress is too large: %jx", (intmax_t)addr));
|
||||||
|
KASSERT(size <= BUS_SPACE_MAXSIZE,
|
||||||
|
("Bus size is too large: %jx", (intmax_t)addr));
|
||||||
|
|
||||||
*paddr = addr;
|
*paddr = addr;
|
||||||
*psize = size;
|
*psize = size;
|
||||||
if (ppci_hi != NULL)
|
if (ppci_hi != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user