Skip to content

Commit

Permalink
arm64: SW PAN: Update saved ttbr0 value on enter_lazy_tlb
Browse files Browse the repository at this point in the history
enter_lazy_tlb is called when a kernel thread rides on the back of
another mm, due to a context switch or an explicit call to unuse_mm
where a call to switch_mm is elided.

In these cases, it's important to keep the saved ttbr value up to date
with the active mm, otherwise we can end up with a stale value which
points to a potentially freed page table.

This patch implements enter_lazy_tlb for arm64, so that the saved ttbr0
is kept up-to-date with the active mm for kernel threads.

Cc: Mark Rutland <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Vinayak Menon <[email protected]>
Cc: <[email protected]>
Fixes: 39bc88e ("arm64: Disable TTBR0_EL1 during normal kernel execution")
Reviewed-by: Catalin Marinas <[email protected]>
Reviewed-by: Mark Rutland <[email protected]>
Reported-by: Vinayak Menon <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
wildea01 committed Dec 6, 2017
1 parent 0adbdfd commit d96cc49
Showing 1 changed file with 10 additions and 14 deletions.
24 changes: 10 additions & 14 deletions arch/arm64/include/asm/mmu_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,6 @@ void check_and_switch_context(struct mm_struct *mm, unsigned int cpu);

#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; })

/*
* This is called when "tsk" is about to enter lazy TLB mode.
*
* mm: describes the currently active mm context
* tsk: task which is entering lazy tlb
* cpu: cpu number which is entering lazy tlb
*
* tsk->mm will be NULL
*/
static inline void
enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
}

#ifdef CONFIG_ARM64_SW_TTBR0_PAN
static inline void update_saved_ttbr0(struct task_struct *tsk,
struct mm_struct *mm)
Expand All @@ -193,6 +179,16 @@ static inline void update_saved_ttbr0(struct task_struct *tsk,
}
#endif

static inline void
enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
/*
* We don't actually care about the ttbr0 mapping, so point it at the
* zero page.
*/
update_saved_ttbr0(tsk, &init_mm);
}

static inline void __switch_mm(struct mm_struct *next)
{
unsigned int cpu = smp_processor_id();
Expand Down

0 comments on commit d96cc49

Please sign in to comment.