Lines Matching +full:data +full:- +full:addr

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Stand-alone page-table allocator for hyp stage-1 and guest stage-2.
56 u64 addr; member
60 #define KVM_PHYS_INVALID (-1ULL)
67 static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level) in kvm_block_mapping_supported() argument
74 if (granule > (end - addr)) in kvm_block_mapping_supported()
80 return IS_ALIGNED(addr, granule); in kvm_block_mapping_supported()
83 static u32 kvm_pgtable_idx(struct kvm_pgtable_walk_data *data, u32 level) in kvm_pgtable_idx() argument
86 u64 mask = BIT(PAGE_SHIFT - 3) - 1; in kvm_pgtable_idx()
88 return (data->addr >> shift) & mask; in kvm_pgtable_idx()
91 static u32 __kvm_pgd_page_idx(struct kvm_pgtable *pgt, u64 addr) in __kvm_pgd_page_idx() argument
93 u64 shift = kvm_granule_shift(pgt->start_level - 1); /* May underflow */ in __kvm_pgd_page_idx()
94 u64 mask = BIT(pgt->ia_bits) - 1; in __kvm_pgd_page_idx()
96 return (addr & mask) >> shift; in __kvm_pgd_page_idx()
99 static u32 kvm_pgd_page_idx(struct kvm_pgtable_walk_data *data) in kvm_pgd_page_idx() argument
101 return __kvm_pgd_page_idx(data->pgt, data->addr); in kvm_pgd_page_idx()
111 return __kvm_pgd_page_idx(&pgt, -1ULL) + 1; in kvm_pgd_pages()
116 if (level == KVM_PGTABLE_MAX_LEVELS - 1) in kvm_pte_table()
137 return mm_ops->phys_to_virt(kvm_pte_to_phys(pte)); in kvm_pte_follow()
148 kvm_pte_t old = *ptep, pte = kvm_phys_to_pte(mm_ops->virt_to_phys(childp)); in kvm_set_table_pte()
160 u64 type = (level == KVM_PGTABLE_MAX_LEVELS - 1) ? KVM_PTE_TYPE_PAGE : in kvm_init_valid_leaf_pte()
175 static int kvm_pgtable_visitor_cb(struct kvm_pgtable_walk_data *data, u64 addr, in kvm_pgtable_visitor_cb() argument
179 struct kvm_pgtable_walker *walker = data->walker; in kvm_pgtable_visitor_cb()
180 return walker->cb(addr, data->end, level, ptep, flag, walker->arg); in kvm_pgtable_visitor_cb()
183 static int __kvm_pgtable_walk(struct kvm_pgtable_walk_data *data,
186 static inline int __kvm_pgtable_visit(struct kvm_pgtable_walk_data *data, in __kvm_pgtable_visit() argument
190 u64 addr = data->addr; in __kvm_pgtable_visit() local
193 enum kvm_pgtable_walk_flags flags = data->walker->flags; in __kvm_pgtable_visit()
196 ret = kvm_pgtable_visitor_cb(data, addr, level, ptep, in __kvm_pgtable_visit()
201 ret = kvm_pgtable_visitor_cb(data, addr, level, ptep, in __kvm_pgtable_visit()
211 data->addr = ALIGN_DOWN(data->addr, kvm_granule_size(level)); in __kvm_pgtable_visit()
212 data->addr += kvm_granule_size(level); in __kvm_pgtable_visit()
216 childp = kvm_pte_follow(pte, data->pgt->mm_ops); in __kvm_pgtable_visit()
217 ret = __kvm_pgtable_walk(data, childp, level + 1); in __kvm_pgtable_visit()
222 ret = kvm_pgtable_visitor_cb(data, addr, level, ptep, in __kvm_pgtable_visit()
230 static int __kvm_pgtable_walk(struct kvm_pgtable_walk_data *data, in __kvm_pgtable_walk() argument
237 return -EINVAL; in __kvm_pgtable_walk()
239 for (idx = kvm_pgtable_idx(data, level); idx < PTRS_PER_PTE; ++idx) { in __kvm_pgtable_walk()
242 if (data->addr >= data->end) in __kvm_pgtable_walk()
245 ret = __kvm_pgtable_visit(data, ptep, level); in __kvm_pgtable_walk()
253 static int _kvm_pgtable_walk(struct kvm_pgtable_walk_data *data) in _kvm_pgtable_walk() argument
257 struct kvm_pgtable *pgt = data->pgt; in _kvm_pgtable_walk()
258 u64 limit = BIT(pgt->ia_bits); in _kvm_pgtable_walk()
260 if (data->addr > limit || data->end > limit) in _kvm_pgtable_walk()
261 return -ERANGE; in _kvm_pgtable_walk()
263 if (!pgt->pgd) in _kvm_pgtable_walk()
264 return -EINVAL; in _kvm_pgtable_walk()
266 for (idx = kvm_pgd_page_idx(data); data->addr < data->end; ++idx) { in _kvm_pgtable_walk()
267 kvm_pte_t *ptep = &pgt->pgd[idx * PTRS_PER_PTE]; in _kvm_pgtable_walk()
269 ret = __kvm_pgtable_walk(data, ptep, pgt->start_level); in _kvm_pgtable_walk()
277 int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, in kvm_pgtable_walk() argument
282 .addr = ALIGN_DOWN(addr, PAGE_SIZE), in kvm_pgtable_walk()
283 .end = PAGE_ALIGN(walk_data.addr + size), in kvm_pgtable_walk()
295 static int leaf_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in leaf_walker() argument
298 struct leaf_walk_data *data = arg; in leaf_walker() local
300 data->pte = *ptep; in leaf_walker()
301 data->level = level; in leaf_walker()
306 int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, in kvm_pgtable_get_leaf() argument
309 struct leaf_walk_data data; in kvm_pgtable_get_leaf() local
313 .arg = &data, in kvm_pgtable_get_leaf()
317 ret = kvm_pgtable_walk(pgt, ALIGN_DOWN(addr, PAGE_SIZE), in kvm_pgtable_get_leaf()
321 *ptep = data.pte; in kvm_pgtable_get_leaf()
323 *level = data.level; in kvm_pgtable_get_leaf()
345 return -EINVAL; in hyp_set_prot_attr()
349 return -EINVAL; in hyp_set_prot_attr()
352 return -EINVAL; in hyp_set_prot_attr()
401 static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, in hyp_map_walker_try_leaf() argument
402 kvm_pte_t *ptep, struct hyp_map_data *data) in hyp_map_walker_try_leaf() argument
405 u64 granule = kvm_granule_size(level), phys = data->phys; in hyp_map_walker_try_leaf()
407 if (!kvm_block_mapping_supported(addr, end, phys, level)) in hyp_map_walker_try_leaf()
410 new = kvm_init_valid_leaf_pte(phys, data->attr, level); in hyp_map_walker_try_leaf()
414 data->phys += granule; in hyp_map_walker_try_leaf()
418 static int hyp_map_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in hyp_map_walker() argument
422 struct hyp_map_data *data = arg; in hyp_map_walker() local
423 struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; in hyp_map_walker()
425 if (hyp_map_walker_try_leaf(addr, end, level, ptep, arg)) in hyp_map_walker()
428 if (WARN_ON(level == KVM_PGTABLE_MAX_LEVELS - 1)) in hyp_map_walker()
429 return -EINVAL; in hyp_map_walker()
431 childp = (kvm_pte_t *)mm_ops->zalloc_page(NULL); in hyp_map_walker()
433 return -ENOMEM; in hyp_map_walker()
439 int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys, in kvm_pgtable_hyp_map() argument
445 .mm_ops = pgt->mm_ops, in kvm_pgtable_hyp_map()
457 ret = kvm_pgtable_walk(pgt, addr, size, &walker); in kvm_pgtable_hyp_map()
468 pgt->pgd = (kvm_pte_t *)mm_ops->zalloc_page(NULL); in kvm_pgtable_hyp_init()
469 if (!pgt->pgd) in kvm_pgtable_hyp_init()
470 return -ENOMEM; in kvm_pgtable_hyp_init()
472 pgt->ia_bits = va_bits; in kvm_pgtable_hyp_init()
473 pgt->start_level = KVM_PGTABLE_MAX_LEVELS - levels; in kvm_pgtable_hyp_init()
474 pgt->mm_ops = mm_ops; in kvm_pgtable_hyp_init()
475 pgt->mmu = NULL; in kvm_pgtable_hyp_init()
476 pgt->force_pte_cb = NULL; in kvm_pgtable_hyp_init()
481 static int hyp_free_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in hyp_free_walker() argument
486 mm_ops->put_page((void *)kvm_pte_follow(*ptep, mm_ops)); in hyp_free_walker()
495 .arg = pgt->mm_ops, in kvm_pgtable_hyp_destroy()
498 WARN_ON(kvm_pgtable_walk(pgt, 0, BIT(pgt->ia_bits), &walker)); in kvm_pgtable_hyp_destroy()
499 pgt->mm_ops->put_page(pgt->pgd); in kvm_pgtable_hyp_destroy()
500 pgt->pgd = NULL; in kvm_pgtable_hyp_destroy()
556 return !(pgt->flags & KVM_PGTABLE_S2_NOFWB); in stage2_has_fwb()
572 return -EINVAL; in stage2_set_prot_attr()
617 * encode ownership of a page to another entity than the page-table in stage2_pte_is_counted()
623 static void stage2_put_pte(kvm_pte_t *ptep, struct kvm_s2_mmu *mmu, u64 addr, in stage2_put_pte() argument
627 * Clear the existing PTE, and perform break-before-make with in stage2_put_pte()
632 kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, addr, level); in stage2_put_pte()
635 mm_ops->put_page(ptep); in stage2_put_pte()
649 static bool stage2_leaf_mapping_allowed(u64 addr, u64 end, u32 level, in stage2_leaf_mapping_allowed() argument
650 struct stage2_map_data *data) in stage2_leaf_mapping_allowed() argument
652 if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1))) in stage2_leaf_mapping_allowed()
655 return kvm_block_mapping_supported(addr, end, data->phys, level); in stage2_leaf_mapping_allowed()
658 static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, in stage2_map_walker_try_leaf() argument
660 struct stage2_map_data *data) in stage2_map_walker_try_leaf() argument
663 u64 granule = kvm_granule_size(level), phys = data->phys; in stage2_map_walker_try_leaf()
664 struct kvm_pgtable *pgt = data->mmu->pgt; in stage2_map_walker_try_leaf()
665 struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; in stage2_map_walker_try_leaf()
667 if (!stage2_leaf_mapping_allowed(addr, end, level, data)) in stage2_map_walker_try_leaf()
668 return -E2BIG; in stage2_map_walker_try_leaf()
671 new = kvm_init_valid_leaf_pte(phys, data->attr, level); in stage2_map_walker_try_leaf()
673 new = kvm_init_invalid_leaf_owner(data->owner_id); in stage2_map_walker_try_leaf()
683 return -EAGAIN; in stage2_map_walker_try_leaf()
685 stage2_put_pte(ptep, data->mmu, addr, level, mm_ops); in stage2_map_walker_try_leaf()
688 /* Perform CMOs before installation of the guest stage-2 PTE */ in stage2_map_walker_try_leaf()
689 if (mm_ops->dcache_clean_inval_poc && stage2_pte_cacheable(pgt, new)) in stage2_map_walker_try_leaf()
690 mm_ops->dcache_clean_inval_poc(kvm_pte_follow(new, mm_ops), in stage2_map_walker_try_leaf()
693 if (mm_ops->icache_inval_pou && stage2_pte_executable(new)) in stage2_map_walker_try_leaf()
694 mm_ops->icache_inval_pou(kvm_pte_follow(new, mm_ops), granule); in stage2_map_walker_try_leaf()
698 mm_ops->get_page(ptep); in stage2_map_walker_try_leaf()
700 data->phys += granule; in stage2_map_walker_try_leaf()
704 static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level, in stage2_map_walk_table_pre() argument
706 struct stage2_map_data *data) in stage2_map_walk_table_pre() argument
708 if (data->anchor) in stage2_map_walk_table_pre()
711 if (!stage2_leaf_mapping_allowed(addr, end, level, data)) in stage2_map_walk_table_pre()
714 data->childp = kvm_pte_follow(*ptep, data->mm_ops); in stage2_map_walk_table_pre()
718 * Invalidate the whole stage-2, as we may have numerous leaf in stage2_map_walk_table_pre()
722 kvm_call_hyp(__kvm_tlb_flush_vmid, data->mmu); in stage2_map_walk_table_pre()
723 data->anchor = ptep; in stage2_map_walk_table_pre()
727 static int stage2_map_walk_leaf(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in stage2_map_walk_leaf() argument
728 struct stage2_map_data *data) in stage2_map_walk_leaf() argument
730 struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; in stage2_map_walk_leaf()
734 if (data->anchor) { in stage2_map_walk_leaf()
736 mm_ops->put_page(ptep); in stage2_map_walk_leaf()
741 ret = stage2_map_walker_try_leaf(addr, end, level, ptep, data); in stage2_map_walk_leaf()
742 if (ret != -E2BIG) in stage2_map_walk_leaf()
745 if (WARN_ON(level == KVM_PGTABLE_MAX_LEVELS - 1)) in stage2_map_walk_leaf()
746 return -EINVAL; in stage2_map_walk_leaf()
748 if (!data->memcache) in stage2_map_walk_leaf()
749 return -ENOMEM; in stage2_map_walk_leaf()
751 childp = mm_ops->zalloc_page(data->memcache); in stage2_map_walk_leaf()
753 return -ENOMEM; in stage2_map_walk_leaf()
761 stage2_put_pte(ptep, data->mmu, addr, level, mm_ops); in stage2_map_walk_leaf()
764 mm_ops->get_page(ptep); in stage2_map_walk_leaf()
769 static int stage2_map_walk_table_post(u64 addr, u64 end, u32 level, in stage2_map_walk_table_post() argument
771 struct stage2_map_data *data) in stage2_map_walk_table_post() argument
773 struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; in stage2_map_walk_table_post()
777 if (!data->anchor) in stage2_map_walk_table_post()
780 if (data->anchor == ptep) { in stage2_map_walk_table_post()
781 childp = data->childp; in stage2_map_walk_table_post()
782 data->anchor = NULL; in stage2_map_walk_table_post()
783 data->childp = NULL; in stage2_map_walk_table_post()
784 ret = stage2_map_walk_leaf(addr, end, level, ptep, data); in stage2_map_walk_table_post()
789 mm_ops->put_page(childp); in stage2_map_walk_table_post()
790 mm_ops->put_page(ptep); in stage2_map_walk_table_post()
810 * been set, but otherwise frees the page-table pages while walking back up
811 * the page-table, installing the block entry when it revisits the anchor
814 static int stage2_map_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in stage2_map_walker() argument
817 struct stage2_map_data *data = arg; in stage2_map_walker() local
821 return stage2_map_walk_table_pre(addr, end, level, ptep, data); in stage2_map_walker()
823 return stage2_map_walk_leaf(addr, end, level, ptep, data); in stage2_map_walker()
825 return stage2_map_walk_table_post(addr, end, level, ptep, data); in stage2_map_walker()
828 return -EINVAL; in stage2_map_walker()
831 int kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, in kvm_pgtable_stage2_map() argument
838 .mmu = pgt->mmu, in kvm_pgtable_stage2_map()
840 .mm_ops = pgt->mm_ops, in kvm_pgtable_stage2_map()
841 .force_pte = pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot), in kvm_pgtable_stage2_map()
851 if (WARN_ON((pgt->flags & KVM_PGTABLE_S2_IDMAP) && (addr != phys))) in kvm_pgtable_stage2_map()
852 return -EINVAL; in kvm_pgtable_stage2_map()
858 ret = kvm_pgtable_walk(pgt, addr, size, &walker); in kvm_pgtable_stage2_map()
863 int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size, in kvm_pgtable_stage2_set_owner() argument
869 .mmu = pgt->mmu, in kvm_pgtable_stage2_set_owner()
871 .mm_ops = pgt->mm_ops, in kvm_pgtable_stage2_set_owner()
884 return -EINVAL; in kvm_pgtable_stage2_set_owner()
886 ret = kvm_pgtable_walk(pgt, addr, size, &walker); in kvm_pgtable_stage2_set_owner()
890 static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in stage2_unmap_walker() argument
895 struct kvm_s2_mmu *mmu = pgt->mmu; in stage2_unmap_walker()
896 struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops; in stage2_unmap_walker()
903 mm_ops->put_page(ptep); in stage2_unmap_walker()
911 if (mm_ops->page_count(childp) != 1) in stage2_unmap_walker()
922 stage2_put_pte(ptep, mmu, addr, level, mm_ops); in stage2_unmap_walker()
933 mm_ops->put_page(childp); in stage2_unmap_walker()
938 int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size) in kvm_pgtable_stage2_unmap() argument
946 return kvm_pgtable_walk(pgt, addr, size, &walker); in kvm_pgtable_stage2_unmap()
957 static int stage2_attr_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in stage2_attr_walker() argument
962 struct stage2_attr_data *data = arg; in stage2_attr_walker() local
963 struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; in stage2_attr_walker()
968 data->level = level; in stage2_attr_walker()
969 data->pte = pte; in stage2_attr_walker()
970 pte &= ~data->attr_clr; in stage2_attr_walker()
971 pte |= data->attr_set; in stage2_attr_walker()
975 * but worst-case the access flag update gets lost and will be in stage2_attr_walker()
978 if (data->pte != pte) { in stage2_attr_walker()
981 * stage-2 PTE if we are going to add executable permission. in stage2_attr_walker()
983 if (mm_ops->icache_inval_pou && in stage2_attr_walker()
985 mm_ops->icache_inval_pou(kvm_pte_follow(pte, mm_ops), in stage2_attr_walker()
993 static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr, in stage2_update_leaf_attrs() argument
1000 struct stage2_attr_data data = { in stage2_update_leaf_attrs() local
1003 .mm_ops = pgt->mm_ops, in stage2_update_leaf_attrs()
1007 .arg = &data, in stage2_update_leaf_attrs()
1011 ret = kvm_pgtable_walk(pgt, addr, size, &walker); in stage2_update_leaf_attrs()
1016 *orig_pte = data.pte; in stage2_update_leaf_attrs()
1019 *level = data.level; in stage2_update_leaf_attrs()
1023 int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size) in kvm_pgtable_stage2_wrprotect() argument
1025 return stage2_update_leaf_attrs(pgt, addr, size, 0, in kvm_pgtable_stage2_wrprotect()
1030 kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr) in kvm_pgtable_stage2_mkyoung() argument
1033 stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0, in kvm_pgtable_stage2_mkyoung()
1039 kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr) in kvm_pgtable_stage2_mkold() argument
1042 stage2_update_leaf_attrs(pgt, addr, 1, 0, KVM_PTE_LEAF_ATTR_LO_S2_AF, in kvm_pgtable_stage2_mkold()
1048 * See the '->clear_flush_young()' callback on the KVM mmu notifier. in kvm_pgtable_stage2_mkold()
1053 bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr) in kvm_pgtable_stage2_is_young() argument
1056 stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &pte, NULL); in kvm_pgtable_stage2_is_young()
1060 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, in kvm_pgtable_stage2_relax_perms() argument
1068 return -EINVAL; in kvm_pgtable_stage2_relax_perms()
1079 ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level); in kvm_pgtable_stage2_relax_perms()
1081 kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, pgt->mmu, addr, level); in kvm_pgtable_stage2_relax_perms()
1085 static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in stage2_flush_walker() argument
1090 struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops; in stage2_flush_walker()
1104 int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size) in kvm_pgtable_stage2_flush() argument
1115 return kvm_pgtable_walk(pgt, addr, size, &walker); in kvm_pgtable_stage2_flush()
1125 u64 vtcr = arch->vtcr; in __kvm_pgtable_stage2_init()
1128 u32 start_level = VTCR_EL2_TGRAN_SL0_BASE - sl0; in __kvm_pgtable_stage2_init()
1131 pgt->pgd = mm_ops->zalloc_pages_exact(pgd_sz); in __kvm_pgtable_stage2_init()
1132 if (!pgt->pgd) in __kvm_pgtable_stage2_init()
1133 return -ENOMEM; in __kvm_pgtable_stage2_init()
1135 pgt->ia_bits = ia_bits; in __kvm_pgtable_stage2_init()
1136 pgt->start_level = start_level; in __kvm_pgtable_stage2_init()
1137 pgt->mm_ops = mm_ops; in __kvm_pgtable_stage2_init()
1138 pgt->mmu = &arch->mmu; in __kvm_pgtable_stage2_init()
1139 pgt->flags = flags; in __kvm_pgtable_stage2_init()
1140 pgt->force_pte_cb = force_pte_cb; in __kvm_pgtable_stage2_init()
1147 static int stage2_free_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, in stage2_free_walker() argument
1157 mm_ops->put_page(ptep); in stage2_free_walker()
1160 mm_ops->put_page(kvm_pte_follow(pte, mm_ops)); in stage2_free_walker()
1172 .arg = pgt->mm_ops, in kvm_pgtable_stage2_destroy()
1175 WARN_ON(kvm_pgtable_walk(pgt, 0, BIT(pgt->ia_bits), &walker)); in kvm_pgtable_stage2_destroy()
1176 pgd_sz = kvm_pgd_pages(pgt->ia_bits, pgt->start_level) * PAGE_SIZE; in kvm_pgtable_stage2_destroy()
1177 pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz); in kvm_pgtable_stage2_destroy()
1178 pgt->pgd = NULL; in kvm_pgtable_stage2_destroy()