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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.