--- a/sys/dev/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -180,8 +180,21 @@ pages_per_node = ~0ul; num_nodes = 1; } else { + /* + * The node-count bound num_nodes = DIV_ROUND_UP(num_pages, + * pages_per_node) and the rounddown_pow_of_two() split in the + * loop below both assume pages_per_node is a power of two. + * mem->page_alignment is not guaranteed to be one: it derives + * from user GEM_CREATE in.alignment via + * amdgpu_gem_object_create()/amdgpu_bo_do_create(), which only + * clamp alignment < PAGE_SIZE. With a non-power-of-two + * pages_per_node, loop 1 can insert nodes smaller than + * pages_per_node and index past the kvmalloc_array()-allocated + * node array. + */ pages_per_node = max((uint32_t)amdgpu_vram_page_split, mem->page_alignment); + pages_per_node = rounddown_pow_of_two(pages_per_node); num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node); }