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 <CAGb2v64cNU+dyuGUwNk2xNN9CJZVXPTJE_u9YrZUp9XwfNGSvg@mail.gmail.com>
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.


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.

> 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?

> 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.)


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.