| 1069 | } |
| 1070 | |
| 1071 | void *rt_aspace_mremap_range(rt_aspace_t aspace, void *old_address, size_t old_size, |
| 1072 | size_t new_size, int flags, void *new_address) |
| 1073 | { |
| 1074 | void *ret = RT_NULL; |
| 1075 | |
| 1076 | if (!aspace) |
| 1077 | { |
| 1078 | LOG_I("%s: Invalid input", __func__); |
| 1079 | } |
| 1080 | else if (_not_in_range(MMF_MAP_FIXED, old_address, old_size, |
| 1081 | aspace->start, aspace->size)) |
| 1082 | { |
| 1083 | LOG_I("%s: %lx not in range of aspace[%lx:%lx]", __func__, old_address, |
| 1084 | aspace->start, (char *)aspace->start + aspace->size); |
| 1085 | } |
| 1086 | else if (!ALIGNED(old_address)) |
| 1087 | { |
| 1088 | LOG_I("%s(old_address=%p): Unaligned address", __func__, old_address); |
| 1089 | } |
| 1090 | else |
| 1091 | { |
| 1092 | /** |
| 1093 | * Brief: re-arrange the address space to remove existing pages mapping |
| 1094 | * in [unmap_start, unmap_start + unmap_len) |
| 1095 | */ |
| 1096 | old_size = RT_ALIGN(old_size, ARCH_PAGE_SIZE); |
| 1097 | |
| 1098 | WR_LOCK(aspace); |
| 1099 | { |
| 1100 | rt_varea_t existed; |
| 1101 | struct _mm_range unmap_range; |
| 1102 | |
| 1103 | unmap_range.start = old_address; |
| 1104 | unmap_range.end = old_address + old_size - 1; |
| 1105 | |
| 1106 | existed = _aspace_bst_search_overlap(aspace, unmap_range); |
| 1107 | if (existed && existed->mem_obj && existed->mem_obj->on_varea_mremap) |
| 1108 | { |
| 1109 | ret = existed->mem_obj->on_varea_mremap(existed, new_size, flags, new_address); |
| 1110 | } |
| 1111 | } |
| 1112 | WR_UNLOCK(aspace); |
| 1113 | |
| 1114 | if (ret) |
| 1115 | { |
| 1116 | int error = rt_aspace_unmap_range(aspace, old_address, old_size); |
| 1117 | if (error != RT_EOK) |
| 1118 | { |
| 1119 | LOG_I("%s: unmap old failed, addr %p size %p", __func__, old_address, old_size); |
| 1120 | } |
| 1121 | } |
| 1122 | } |
| 1123 | |
| 1124 | return ret; |
| 1125 | } |
| 1126 | |
| 1127 | static inline void *_lower(void *a, void *b) |
| 1128 | { |
no test coverage detected