+ pos = list_entry(pos->head.next, struct mm_region, head);
+ }
+
+ if (length) {
+ return ENOMEM;
+ }
+
+ return 0;
+}
+
+void
+mem_unmap_region(ptr_t mnt, struct mm_region* region)
+{
+ if (!region) {
+ return;
+ }
+
+ valloc_ensure_valid(region);
+
+ pfn_t pglen = leaf_count(region->end - region->start);
+ mem_sync_pages(mnt, region, region->start, pglen * PAGE_SIZE, 0);
+
+ pte_t* ptep = mkptep_va(mnt, region->start);
+ __remove_ranged_mappings(ptep, pglen);
+
+ tlb_flush_vmr_all(region);
+
+ llist_delete(®ion->head);
+ region_release(region);
+}
+
+// Case: head inseted, tail inseted
+#define CASE_HITI(vmr, addr, len) \
+ ((vmr)->start <= (addr) && ((addr) + (len)) <= (vmr)->end)
+
+// Case: head inseted, tail extruded
+#define CASE_HITE(vmr, addr, len) \
+ ((vmr)->start <= (addr) && ((addr) + (len)) > (vmr)->end)
+
+// Case: head extruded, tail inseted
+#define CASE_HETI(vmr, addr, len) \
+ ((vmr)->start > (addr) && ((addr) + (len)) <= (vmr)->end)
+
+// Case: head extruded, tail extruded
+#define CASE_HETE(vmr, addr, len) \
+ ((vmr)->start > (addr) && ((addr) + (len)) > (vmr)->end)
+
+static void
+__unmap_overlapped_cases(ptr_t mnt,
+ struct mm_region* vmr,
+ ptr_t* addr,
+ size_t* length)
+{
+ // seg start, umapped segement start
+ ptr_t seg_start = *addr, umps_start = 0;
+
+ // seg len, umapped segement len
+ size_t seg_len = *length, umps_len = 0;
+
+ size_t displ = 0, shrink = 0;