Page MenuHomeFreeBSD

Switch to an empty ttbr0 pagetable when the MMU is enabled
ClosedPublic

Authored by andrew on Nov 29 2019, 3:51 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Nov 7, 4:02 PM
Unknown Object (File)
Thu, Nov 7, 4:05 AM
Unknown Object (File)
Thu, Nov 7, 4:05 AM
Unknown Object (File)
Thu, Nov 7, 4:01 AM
Unknown Object (File)
Thu, Nov 7, 4:01 AM
Unknown Object (File)
Thu, Nov 7, 4:00 AM
Unknown Object (File)
Tue, Nov 5, 4:33 PM
Unknown Object (File)
Tue, Nov 5, 11:57 AM

Details

Summary

We don't need these pagetables after the early boot. Remove the chance
we write to memory we didn't expect to and remove architectural undefined
behaviour.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Feel free to cross this task off from the list at https://wiki.freebsd.org/PmapReview :-)

This revision is now accepted and ready to land.Nov 29 2019, 7:20 PM
mmel added a subscriber: mmel.

Tested on RockPro64 an Tegra TX1 without problems. Unfortunately, it doesn't affect RK3399 issues in either way...

sys/arm64/arm64/locore.S
652 ↗(On Diff #65050)

Should we have a dsb instruction here to ensure that the invalidation has completed before setting the SCTLR register below?

i just realized that this breaks EARLY_UART because SOCDEV_PA mapping is not passed to initarm().
So I think that we should postpone change of kernel ttbt0 until cninit() is processed.

@@ -1164,6 +1164,7 @@ initarm(struct arm64_bootparams *abp)
        valid = bus_probe();

        cninit();
+       set_ttbr0((uint64_t)pagetable_l0_ttbr0 - abp->kern_delta);

        if (!valid)
                panic("Invalid bus configuration: %s",

Also, summary is slightly misleading. This patch doesn't fully remove architectural undefined behavior (and I'm able to demonstrate this on RK3399) because it still exist - same physical memory is mapped in identity map as uncached and in kernel map as cached. This is direct violation of B2.9 in ARMv8 ARM, and it causes lost of coherency visible later in boot process.
Moreover, same problem (Mismatched memory attributes) exist also for DMAPed memory, memory attribute changes are not propagated to it. Worstly, only legal way how to change attribute for page mapped to multiple VA is break before make approach (thus we should unmaps all VA first ...)

In D22606#494706, @mmel wrote:

i just realized that this breaks EARLY_UART because SOCDEV_PA mapping is not passed to initarm().
So I think that we should postpone change of kernel ttbt0 until cninit() is processed.

@@ -1164,6 +1164,7 @@ initarm(struct arm64_bootparams *abp)
        valid = bus_probe();

        cninit();
+       set_ttbr0((uint64_t)pagetable_l0_ttbr0 - abp->kern_delta);

        if (!valid)
                panic("Invalid bus configuration: %s",

Also, summary is slightly misleading. This patch doesn't fully remove architectural undefined behavior (and I'm able to demonstrate this on RK3399) because it still exist - same physical memory is mapped in identity map as uncached and in kernel map as cached. This is direct violation of B2.9 in ARMv8 ARM, and it causes lost of coherency visible later in boot process.

Why does locore.S set up the identity mapping as uncached? I've never come across an explanation. Does it overlap with one or more devices on some platforms?

Switch to the empty ttbr0 after cninit is called

This revision now requires review to proceed.Dec 5 2019, 1:24 PM
sys/arm64/arm64/machdep.c
1164 ↗(On Diff #65262)

This is replacing the page table that is associated with ASID 0, so it needs to be followed by a complete TLB invalidation.

Ping. Andrew, please, do you want to finish (and commit) by yourself? Alternatively, I can manage it if you prefer.

Invalidate the tlb after calling set_ttbr0

This revision is now accepted and ready to land.Sep 1 2020, 3:49 PM