Re: Bug: PHYS_OFFSET no longer points to DRAM physical starting address with CONFIG_ARM64_VA_BITS_52
Chen-Yu Tsai <[email protected]>
| Newsgroups | org.infradead.lists.linux-arm-kernel,dev.linux.lists.linux-sunxi |
|---|---|
| Message-ID | <CAGb2v656c+7VfPhA6K58qXJvMJRm2geXD8GEzdUQvO5ApCSMbA@mail.gmail.com> |
On Sat, Aug 22, 2026 at 9:40 PM Ard Biesheuvel <[email protected]> wrote: > > > > On Sat, 22 Aug 2026, at 16:28, Chen-Yu Tsai wrote: > > On Sat, Aug 22, 2026 at 8:50 PM Ard Biesheuvel <[email protected]> wrote: > >> > >> Hello Chen-Yu, > >> > >> On Sat, 22 Aug 2026, at 15:39, Chen-Yu Tsai wrote: > >> > Hi, > >> > > >> > On the Allwinner H6 & H616 SoC (and likely others), if running a kernel > >> > compiled with CONFIG_ARM64_VA_BITS_52 and CONFIG_ARM64_PA_BITS_52, > >> > PHYS_OFFSET no longer points to the start of DRAM (0x40000000) but instead > >> > points to 0xfff1000040000000. > >> > > >> > > >> > I've observed this for quite some time but hadn't really nailed down what > >> > was going on. For context: the IOMMU on these SoCs can only do 32-bit > >> > addresses, and that's pretty fine since the SoC only supports up to 4 GB > >> > DRAM. However the DRAM starts at 1GB offset in the physical address space. > >> > We want to be able to map the highest 1GB I/O virtual address space and > >> > thus need to check if the physical address is within 4GB without the > >> > offset. Having only 32-bits addressing, the address will wrap around fine. > >> > So we check the address against PHYS_OFFSE, which breaks with the mangled > >> > address. > >> > > >> > > >> > I suspect this is the result of the following commits: > >> > > >> > 7bc1a0f9e176 arm64: mm: use single quantity to represent the PA to > >> > VA translation > >> > 9684ec186f8f arm64: Enable LPA2 at boot if supported by the system > >> > > >> > The first commit introduces a negative (wrapped around) offset to > >> > memstart_addr (PHYS_OFFSET) to work around mapping restrictions, and the > >> > second commit makes the offset dependent on hardware. > >> > > >> > > >> > I hope that Ard and the maintainers can look into it and make PHYS_OFFSET > >> > always point to the physical start of DRAM. > >> > > >> > >> On what basis are you claiming that PHYS_OFFSET must always point to the > >> start of physical, non-secure DRAM? > > > > AFAIK we've been using this since armv7 in our older drivers to deal with > > PA <-> IOVA offsets. This was then concentrated into one interconnect > > driver: drivers/soc/sunxi/sunxi_mbus.c > > > > The driver applies PHYS_OFFSET as the DMA address offset for a class of > > devices when the system is using an older device tree that lacks interconnect > > properties. > > > > That sounds like a hack to me tbh. There was little documentation around the actual interconnect, and the offset only really caused issues for devices with 2 GB DRAM, which was quite rare back in the day. So the driver "workarounds" were added as issues were found. > > > > There's also Documentation/admin-guide/kdump/vmcoreinfo.rst which states: > > > > ARM64 > > ===== > > > > PHYS_OFFSET > > ----------- > > > > Indicates the physical address of the start of memory. Similar to > > kimage_voffset, which is used to translate virtual to physical > > addresses. > > > > This information is inaccurate. kimage_voffset is the offset between the > kernel mapping in the vmalloc space and the associated physical memory. > It has nothing to do with PHYS_OFFSET or with the start of memory. > > >> On arm64, PHYS_OFFSET is the physical address of the start of memory, > >> where 'start of memory' == PAGE_OFFSET, i.e., the start of the linear > >> map. When running a 52-bit VA kernel on hardware that is not LPA2 capable, > >> the hardware does not support mapping memory at PAGE_OFFSET, so it is moved > >> upward in the linear map. > > > > So it held true until 52-bit VA support was introduced? > > > > It still holds true. Well, yes. I guess I meant the physical start of the linear map == PHYS_OFFSET. > >> I don't quite follow why you need to compare with PHYS_OFFSET in your IOMMU > >> driver: could you elaborate? > > > > Our IOMMU only supports 32-bit of address space. On our SoCs, DRAM physically > > starts at 0x40000000 (1 GB offset), meaning any physical DRAM above 3GB > > would wrap around. However putting this number in drivers was discouraged > > in the past and we were told to use PHYS_OFFSET (on ARMv7) instead. Also, > > in the past there was this one chip that put DRAM at a different offset, > > so using a fixed number in the driver won't always work. > > > > Right now we're just blocking any physical address above 32 bits. Ideally > > we want to allow up to "start of DRAM + 4GB". So we need to know the DRAM > > start address. (And we probably want to block anything below start of DRAM > > as well.) > > > > Should you be using memblock_start_of_DRAM() instead perhaps? That seems like the thing we want. Thanks for the pointer, and sorry for the noise. ChenYu