idmap.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include <linux/kernel.h>
  2. #include <asm/cputype.h>
  3. #include <asm/pgalloc.h>
  4. #include <asm/pgtable.h>
  5. static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
  6. unsigned long prot)
  7. {
  8. pmd_t *pmd = pmd_offset(pgd, addr);
  9. addr = (addr & PMD_MASK) | prot;
  10. pmd[0] = __pmd(addr);
  11. addr += SECTION_SIZE;
  12. pmd[1] = __pmd(addr);
  13. flush_pmd_entry(pmd);
  14. }
  15. void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
  16. {
  17. unsigned long prot, next;
  18. prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
  19. if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
  20. prot |= PMD_BIT4;
  21. pgd += pgd_index(addr);
  22. do {
  23. next = pgd_addr_end(addr, end);
  24. idmap_add_pmd(pgd, addr, next, prot);
  25. } while (pgd++, addr = next, addr != end);
  26. }
  27. #ifdef CONFIG_SMP
  28. static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end)
  29. {
  30. pmd_t *pmd = pmd_offset(pgd, addr);
  31. pmd_clear(pmd);
  32. }
  33. void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
  34. {
  35. unsigned long next;
  36. pgd += pgd_index(addr);
  37. do {
  38. next = pgd_addr_end(addr, end);
  39. idmap_del_pmd(pgd, addr, next);
  40. } while (pgd++, addr = next, addr != end);
  41. }
  42. #endif
  43. /*
  44. * In order to soft-boot, we need to insert a 1:1 mapping in place of
  45. * the user-mode pages. This will then ensure that we have predictable
  46. * results when turning the mmu off
  47. */
  48. void setup_mm_for_reboot(char mode)
  49. {
  50. /*
  51. * We need to access to user-mode page tables here. For kernel threads
  52. * we don't have any user-mode mappings so we use the context that we
  53. * "borrowed".
  54. */
  55. identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
  56. local_flush_tlb_all();
  57. }