Skip to content

rockchip_drm_gem.c: __GFP_DMA32 safety flag only applied under CONFIG_ARM_LPAE, never set on arm64 #588

Description

@henkwiedig

Summary

rockchip_gem_alloc_object() in drivers/gpu/drm/rockchip/rockchip_drm_gem.c only applies the __GFP_DMA32 allocation constraint by default when CONFIG_ARM_LPAE is defined:

#ifdef CONFIG_ARM_LPAE
	gfp_t gfp_mask = GFP_HIGHUSER | __GFP_RECLAIMABLE | __GFP_DMA32;
#else
	gfp_t gfp_mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
#endif

	if (flags & ROCKCHIP_BO_DMA32)
		gfp_mask |= __GFP_DMA32;

CONFIG_ARM_LPAE is a 32-bit ARM-only Kconfig symbol (Large Physical Address Extension) and is never defined on arm64 kernels. So on any arm64 board with >=4GB RAM, SHMEM-backed GEM buffers can be allocated at physical addresses >=4GB by default, with no opt-in required.

Impact

RGA2 (and RGA1) hardware has a 32-bit-only MMU and cannot address physical memory >=4GB (RGA_MMU unsupported memory larger than 4G!, checked in drivers/video/rockchip/rga3/rga_mm.c's rga_mm_check_memory_limit()). On an RK3566 board (Radxa Zero 3, 4GB variant) we confirmed via a field crash report that a GBM/GEM-allocated buffer used as an RGA source/destination landed at a physical address >=4GB, causing the RGA job to fail. The same board with 1GB RAM cannot reproduce this at all (no memory exists above 4GB to allocate from), which is presumably why it's easy to miss in testing.

Any caller that doesn't explicitly pass ROCKCHIP_BO_DMA32 is exposed on arm64 -- in practice most existing userspace, since that's an opt-in vendor extension flag that generic APIs like GBM have no way to request.

Suggested fix

Extend the #ifdef to also cover CONFIG_ARM64, matching what looks like the original intent (a hardware/MMU-generation constraint, not a CPU-mode check):

#if defined(CONFIG_ARM_LPAE) || defined(CONFIG_ARM64)

Happy to send this as a PR if useful -- raising it first in case there's a reason this was scoped to LPAE specifically that isn't obvious from the code.

Reproduction context

Kernel: this repo, commit 8b0634cfd2bc551f6c0641f30df9cb03f0bd62f0 (linux-6.1-stan-rkr4.1 base), built via openipc/sbc-groundstations for a Radxa Zero 3 (RK3566), 4GB RAM variant.

Field dmesg:

RGA_MMU unsupported memory larger than 4G!
scheduler core[4] unsupported mm_flag[0x0]

On the same device, dmesg zone ranges show DMA32 empty, Normal [mem 0x0000000100000000-0x00000001ffffffff] -- i.e. all general-purpose RAM is mapped starting exactly at the 4GB boundary, with only a small CMA reservation below it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions