mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/device-tree: Fix off-by-one bounds check in make_memory_node()
When building Xen with CONFIG_STATIC_SHM=n, booting a hardware
domain with exactly NR_MEM_BANKS (256) reserved-memory regions
causes a panic:
(XEN) Xen BUG at common/device-tree/domain-build.c:497
(XEN) Xen call trace:
(XEN) [<00000a0000289aa8>] make_memory_node+0x178/0x234 (PC)
This occurs due to an off-by-one error in the bounds checking of
the reg array in make_memory_node(). The check:
BUG_ON(nr_cells >= ARRAY_SIZE(reg));
incorrectly triggers when the array is exactly full (i.e., when
nr_cells == ARRAY_SIZE(reg)), preventing the 256th and final valid
memory region from being written.
When CONFIG_STATIC_SHM=y, this bug is usually hidden because
DT_MEM_NODE_REG_RANGE_SIZE adds extra space for SHM banks.
This extra capacity prevents the array from reaching its
maximum limit while processing the 256th memory region.
However, if a domain is configured with exactly NR_MEM_BANKS
and NR_SHMEM_BANKS, the array will completely fill up and trigger
the same panic.
Fix this by changing the condition to strictly greater than (>).
Apply the exact same fix to shm_mem_node_fill_reg_range() to
prevent the same error.
Fixes: cd8015b634 ("ARM/dom0: Avoid using a variable length array in make_memory_node()")
Fixes: 7846f7699f ("xen/arm: List static shared memory regions as /memory nodes")
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
9e8aa00f62
commit
fc453fef77
2 files changed
+2
-2
No files matched your search
@@ -494,7 +494,7 @@ int __init make_memory_node(const struct kernel_info *kinfo, int addrcells,
|
||||
continue;
|
||||
|
||||
nr_cells += reg_size;
|
||||
BUG_ON(nr_cells >= ARRAY_SIZE(reg));
|
||||
BUG_ON(nr_cells > ARRAY_SIZE(reg));
|
||||
dt_child_set_range(&cells, addrcells, sizecells, start, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -838,7 +838,7 @@ void __init shm_mem_node_fill_reg_range(const struct kernel_info *kinfo,
|
||||
paddr_t size = mem->bank[i].size;
|
||||
|
||||
*nr_cells += addrcells + sizecells;
|
||||
BUG_ON(*nr_cells >= DT_MEM_NODE_REG_RANGE_SIZE);
|
||||
BUG_ON(*nr_cells > DT_MEM_NODE_REG_RANGE_SIZE);
|
||||
dt_child_set_range(&cells, addrcells, sizecells, start, size);
|
||||
}
|
||||
}
|
||||
|
||||