Commit 0ca2c879 authored by Catalin Marinas's avatar Catalin Marinas

Architecture compliant TTBR changing sequence

On newer architectures (ARMv6, ARMv7), the depth of the prefetch and
branch prediction is implementation defined and there is a small risk
of wrong ASID tagging when changing TTBR0 before setting the new
context id. The recommended solution is to set a reserved ASID during
TTBR changing. This patch reserves ASID 0.
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 5d418355
...@@ -19,7 +19,8 @@ unsigned int cpu_last_asid = { 1 << ASID_BITS }; ...@@ -19,7 +19,8 @@ unsigned int cpu_last_asid = { 1 << ASID_BITS };
/* /*
* We fork()ed a process, and we need a new context for the child * We fork()ed a process, and we need a new context for the child
* to run in. We reserve version 0 for initial tasks so we will * to run in. We reserve version 0 for initial tasks so we will
* always allocate an ASID. * always allocate an ASID. The ASID 0 is reserved for the TTBR
* register changing sequence.
*/ */
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{ {
...@@ -38,8 +39,15 @@ void __new_context(struct mm_struct *mm) ...@@ -38,8 +39,15 @@ void __new_context(struct mm_struct *mm)
* If we've used up all our ASIDs, we need * If we've used up all our ASIDs, we need
* to start a new version and flush the TLB. * to start a new version and flush the TLB.
*/ */
if ((asid & ~ASID_MASK) == 0) if ((asid & ~ASID_MASK) == 0) {
asid = ++cpu_last_asid;
/* set the reserved ASID before flushing the TLB */
asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n"
:
: "r" (0));
isb();
flush_tlb_all(); flush_tlb_all();
}
mm->context.id = asid; mm->context.id = asid;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment