lwp_mmap_fix_private.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-08-22 Shell test case for aspace_map with varea_expand
  9. */
  10. #include "common.h"
  11. #include "lwp_user_mm.h"
  12. #include "mm_fault.h"
  13. #include <mm_aspace.h>
  14. #include <rtthread.h>
  15. static long fd = -1;
  16. static long pgoffset = 0;
  17. static size_t flags = MAP_FIXED | MAP_ANONYMOUS;
  18. static size_t prot = PROT_READ | PROT_WRITE;
  19. static char *ex_vaddr = (char *)0x100000000;
  20. static size_t ex_size = 0x5000;
  21. static char *private0 = (char *)0x100000000;
  22. static char *private1 = (char *)0x100000000 + 0x1000;
  23. static char *private2 = (char *)0x100000000 + 0x2000;
  24. static char *private3 = (char *)0x100000000 + 0x3000;
  25. static char *private4 = (char *)0x100000000 + 0x4000;
  26. /**
  27. * todo: suppoprt prefetch pages, so more than 1 page can install to private at a time
  28. * static size_t priv_size = 0x1000;
  29. */
  30. static size_t former_vsz;
  31. static size_t former_vcount;
  32. static struct rt_lwp *lwp;
  33. static int _count_vsz(rt_varea_t varea, void *arg)
  34. {
  35. rt_base_t *pvsz = arg;
  36. *pvsz += 1;
  37. return 0;
  38. }
  39. static rt_base_t count_vcount(rt_aspace_t aspace)
  40. {
  41. rt_base_t vcount = 0;
  42. rt_aspace_traversal(aspace, _count_vsz, &vcount);
  43. return vcount;
  44. }
  45. static void test_mmap_fix_private(void)
  46. {
  47. char *next_va;
  48. struct rt_aspace_fault_msg msg;
  49. msg.fault_op = MM_FAULT_OP_WRITE;
  50. msg.fault_type = MM_FAULT_TYPE_ACCESS_FAULT;
  51. /* map new pages at ex_vaddr to anonymous */
  52. next_va = ex_vaddr;
  53. former_vsz = rt_aspace_count_vsz(lwp->aspace);
  54. former_vcount = count_vcount(lwp->aspace);
  55. next_va = lwp_mmap2(lwp, next_va, ex_size, prot, flags, fd, pgoffset);
  56. uassert_true(next_va == ex_vaddr);
  57. utest_int_equal(former_vsz + ex_size, rt_aspace_count_vsz(lwp->aspace));
  58. utest_int_equal(former_vcount + 1, count_vcount(lwp->aspace));
  59. former_vsz += ex_size;
  60. former_vcount += 1;
  61. /* fix private in the middle */
  62. msg.fault_vaddr = private2;
  63. utest_int_equal(MM_FAULT_FIXABLE_TRUE, rt_aspace_fault_try_fix(lwp->aspace, &msg));
  64. utest_int_equal(former_vsz, rt_aspace_count_vsz(lwp->aspace));
  65. utest_int_equal(former_vcount + 2, count_vcount(lwp->aspace));
  66. former_vcount += 2;
  67. /* fix private from left most */
  68. msg.fault_vaddr = private0;
  69. utest_int_equal(MM_FAULT_FIXABLE_TRUE, rt_aspace_fault_try_fix(lwp->aspace, &msg));
  70. utest_int_equal(former_vsz, rt_aspace_count_vsz(lwp->aspace));
  71. utest_int_equal(former_vcount + 1, count_vcount(lwp->aspace));
  72. former_vcount += 1;
  73. /* fix private from right most */
  74. msg.fault_vaddr = private4;
  75. utest_int_equal(MM_FAULT_FIXABLE_TRUE, rt_aspace_fault_try_fix(lwp->aspace, &msg));
  76. utest_int_equal(former_vsz, rt_aspace_count_vsz(lwp->aspace));
  77. utest_int_equal(former_vcount + 1, count_vcount(lwp->aspace));
  78. former_vcount += 1;
  79. /* fix private from left-middle */
  80. msg.fault_vaddr = private1;
  81. utest_int_equal(MM_FAULT_FIXABLE_TRUE, rt_aspace_fault_try_fix(lwp->aspace, &msg));
  82. utest_int_equal(former_vsz, rt_aspace_count_vsz(lwp->aspace));
  83. utest_int_equal(former_vcount - 1, count_vcount(lwp->aspace));
  84. former_vcount -= 1;
  85. /* fix private from right-middle */
  86. msg.fault_vaddr = private3;
  87. utest_int_equal(MM_FAULT_FIXABLE_TRUE, rt_aspace_fault_try_fix(lwp->aspace, &msg));
  88. utest_int_equal(former_vsz, rt_aspace_count_vsz(lwp->aspace));
  89. utest_int_equal(former_vcount - 1, count_vcount(lwp->aspace));
  90. former_vcount -= 1;
  91. /* clear mapping */
  92. utest_int_equal(RT_EOK, rt_aspace_unmap_range(lwp->aspace, ex_vaddr, ex_size));
  93. rt_free(lwp->aspace->private_object);
  94. lwp->aspace->private_object = RT_NULL;
  95. }
  96. static void testcase_main(void)
  97. {
  98. CONSIST_HEAP(test_mmap_fix_private());
  99. }
  100. static rt_err_t utest_tc_init(void)
  101. {
  102. lwp = lwp_create(0);
  103. if (lwp)
  104. lwp_user_space_init(lwp, 1);
  105. else
  106. return -RT_ENOMEM;
  107. return RT_EOK;
  108. }
  109. static rt_err_t utest_tc_cleanup(void)
  110. {
  111. lwp_ref_dec(lwp);
  112. return RT_EOK;
  113. }
  114. static void testcase(void)
  115. {
  116. UTEST_UNIT_RUN(testcase_main);
  117. }
  118. UTEST_TC_EXPORT(testcase, "testcases.lwp.mman.mmap_anon.fix_private", utest_tc_init, utest_tc_cleanup, 10);