moea64_cpu_bootstrap_native slbmte (and such) use: missing context synchronizations (isync's)?
Mark Millard
marklmi at yahoo.com
Wed May 1 00:26:05 UTC 2019
First some context that I base this note on . . .
For Data Access Synchronization:
slbie, slbia, slbmte all list a context-synchronizing instruction
as "Required Prior" and "Required After".
For Instruction Access Synchronization:
slbie, slbia, slbmte all list a context-synchronizing instruction
as "Required After". (There is also a note about not causing an
implicit branch in real space, up to the context synchronization
instruction.)
Both contexts list the note that says:
QUOTE
If an slbmte instruction alters the mapping, or associated attributes, of a currently mapped ESID, the slb- mte must be preceded by an slbie (or slbia) instruction that invalidates the existing translation. This applies even if the corresponding entry is no longer in the SLB (the translation may still be in implementa- tion-specific address translation lookaside information). No software synchronization is needed between the slbie and the slbmte, regardless of whether the index of the SLB entry (if any) containing the current translation is the same as the SLB index specified by the slbmte.
No slbie (or slbia) is needed if the slbmte instruction replaces a valid SLB entry with a mapping of a dif- ferent ESID (e.g., to satisfy an SLB miss). However, the slbie is needed later if and when the translation that was contained in the replaced SLB entry is to be invalidated.
END QUOTE
In:
static void
moea64_cpu_bootstrap_native(mmu_t mmup, int ap)
{
. . .
/*
* Install kernel SLB entries
*/
#ifdef __powerpc64__
__asm __volatile ("slbia");
__asm __volatile ("slbmfee %0,%1; slbie %0;" : "=r"(seg0) :
"r"(0));
for (i = 0; i < n_slbs; i++) {
if (!(slb[i].slbe & SLBE_VALID))
continue;
__asm __volatile ("slbmte %0, %1" ::
"r"(slb[i].slbv), "r"(slb[i].slbe));
}
#else
I do not see isync's or such used for this unless
the later else-case in:
if (cpu_features2 & PPC_FEATURE2_ARCH_3_00)
mtspr(SPR_PTCR,
((uintptr_t)moea64_part_table & ~DMAP_BASE_ADDRESS) |
flsl((PART_SIZE >> 12) - 1));
else
__asm __volatile ("ptesync; mtsdr1 %0; isync"
:: "r"(((uintptr_t)moea64_pteg_table & ~DMAP_BASE_ADDRESS)
| (uintptr_t)(flsl(moea64_pteg_mask >> 11))));
tlbia();
is supposed to always be sufficient (for at least after
the slbmte). TLBSYNC(), EIEIO(), and such from tlbia()
do not seem to do isync, unless I missed something. It
looks like Power9 (PPC_FEATURE2_ARCH_3_00) would not get
an isync at all from the range of code I reference.
===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)
More information about the freebsd-ppc
mailing list