mmap.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/fs.h>
  4. #include <linux/mm.h>
  5. #include <linux/mman.h>
  6. #include <linux/shm.h>
  7. #include <linux/sched.h>
  8. #include <linux/random.h>
  9. #include <linux/io.h>
  10. unsigned long shm_align_mask = (0x4000 >> 1) - 1; /* Sane caches */
  11. #define COLOUR_ALIGN(addr, pgoff) \
  12. ((((addr) + shm_align_mask) & ~shm_align_mask) + \
  13. (((pgoff) << PAGE_SHIFT) & shm_align_mask))
  14. unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
  15. unsigned long len, unsigned long pgoff, unsigned long flags)
  16. {
  17. struct vm_area_struct *vmm;
  18. int do_color_align;
  19. if (flags & MAP_FIXED) {
  20. /*
  21. * We do not accept a shared mapping if it would violate
  22. * cache aliasing constraints.
  23. */
  24. if ((flags & MAP_SHARED) &&
  25. ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
  26. return -EINVAL;
  27. return addr;
  28. }
  29. if (len > TASK_SIZE)
  30. return -ENOMEM;
  31. do_color_align = 0;
  32. if (filp || (flags & MAP_SHARED))
  33. do_color_align = 1;
  34. if (addr) {
  35. if (do_color_align)
  36. addr = COLOUR_ALIGN(addr, pgoff);
  37. else
  38. addr = PAGE_ALIGN(addr);
  39. vmm = find_vma(current->mm, addr);
  40. if (TASK_SIZE - len >= addr &&
  41. (!vmm || addr + len <= vmm->vm_start))
  42. return addr;
  43. }
  44. addr = TASK_UNMAPPED_BASE;
  45. if (do_color_align)
  46. addr = COLOUR_ALIGN(addr, pgoff);
  47. else
  48. addr = PAGE_ALIGN(addr);
  49. for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
  50. /* At this point: (!vmm || addr < vmm->vm_end). */
  51. if (TASK_SIZE - len < addr)
  52. return -ENOMEM;
  53. if (!vmm || addr + len <= vmm->vm_start)
  54. return addr;
  55. addr = vmm->vm_end;
  56. if (do_color_align)
  57. addr = COLOUR_ALIGN(addr, pgoff);
  58. }
  59. }