^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * MMU context handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009 Wind River Systems Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/cpuinfo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/tlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* The pids position and mask in context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PID_BITS (cpuinfo.tlb_pid_num_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PID_MASK ((1UL << PID_BITS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* The versions position and mask in context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define VERSION_BITS (32 - PID_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define VERSION_SHIFT (PID_SHIFT + PID_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define VERSION_MASK ((1UL << VERSION_BITS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Return the version part of a context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CTX_VERSION(c) (((c) >> VERSION_SHIFT) & VERSION_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Return the pid part of a context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CTX_PID(c) (((c) >> PID_SHIFT) & PID_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Value of the first context (version 1, pid 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define FIRST_CTX ((1UL << VERSION_SHIFT) | (0 << PID_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static mm_context_t next_mmu_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Initialize MMU context management stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void __init mmu_context_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* We need to set this here because the value depends on runtime data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * from cpuinfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) next_mmu_context = FIRST_CTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Set new context (pid), keep way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void set_context(mm_context_t context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) set_mmu_pid(CTX_PID(context));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static mm_context_t get_new_context(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Return the next pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) next_mmu_context += (1UL << PID_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* If the pid field wraps around we increase the version and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * flush the tlb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (unlikely(CTX_PID(next_mmu_context) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Version is incremented since the pid increment above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * overflows info version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) flush_cache_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) flush_tlb_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* If the version wraps we start over with the first generation, we do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * not need to flush the tlb here since it's always done above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (unlikely(CTX_VERSION(next_mmu_context) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) next_mmu_context = FIRST_CTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return next_mmu_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void switch_mm(struct mm_struct *prev, struct mm_struct *next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct task_struct *tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* If the process context we are swapping in has a different context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * generation then we have it should get a new generation/pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (unlikely(CTX_VERSION(next->context) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) CTX_VERSION(next_mmu_context)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) next->context = get_new_context();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Save the current pgd so the fast tlb handler can find it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) pgd_current = next->pgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Set the current context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) set_context(next->context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * After we have set current->mm to a new value, this activates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * the context for the new mm so we see the new mappings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void activate_mm(struct mm_struct *prev, struct mm_struct *next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) next->context = get_new_context();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) set_context(next->context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pgd_current = next->pgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned long get_pid_from_context(mm_context_t *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return CTX_PID((*context));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }