- ppnum_t pn_src = (ppnum_t)(src >> PAGE_SHIFT);
- ppnum_t pn_dst = (ppnum_t)(dst >> PAGE_SHIFT);
-
-#ifdef __ARM_COHERENT_IO__
- if (pmap_valid_address(src) &&
- pmap_valid_address(dst) &&
- (mmu_kvtop_wpreflight(phystokv((pmap_paddr_t) dst)))) {
- bcopy((char *)phystokv((pmap_paddr_t) src), (char *)phystokv((pmap_paddr_t) dst), bytes);
- return;
- }
+ ppnum_t pn_src;
+ ppnum_t pn_dst;
+ addr64_t end __assert_only;
+ kern_return_t res = KERN_SUCCESS;
+
+ assert(!__improbable(os_add_overflow(src, bytes, &end)));
+ assert(!__improbable(os_add_overflow(dst, bytes, &end)));
+
+ while ((bytes > 0) && (res == KERN_SUCCESS)) {
+ src_offset = src & PAGE_MASK;
+ dst_offset = dst & PAGE_MASK;
+ boolean_t use_copy_window_src = FALSE;
+ boolean_t use_copy_window_dst = FALSE;
+ vm_size_t count = bytes;
+ vm_size_t count2 = bytes;
+ if (BCOPY_PHYS_SRC_IS_PHYS(flags)) {
+ use_copy_window_src = !pmap_valid_address(src);
+ pn_src = (ppnum_t)(src >> PAGE_SHIFT);
+#if !defined(__ARM_COHERENT_IO__) && !__ARM_PTE_PHYSMAP__
+ count = PAGE_SIZE - src_offset;
+ wimg_bits_src = pmap_cache_attributes(pn_src);
+ if ((wimg_bits_src & VM_WIMG_MASK) != VM_WIMG_DEFAULT) {
+ use_copy_window_src = TRUE;
+ }
+#else
+ if (use_copy_window_src) {
+ wimg_bits_src = pmap_cache_attributes(pn_src);
+ count = PAGE_SIZE - src_offset;
+ }
+#endif
+ }
+ if (BCOPY_PHYS_DST_IS_PHYS(flags)) {
+ // write preflighting needed for things like dtrace which may write static read-only mappings
+ use_copy_window_dst = (!pmap_valid_address(dst) || !mmu_kvtop_wpreflight(phystokv((pmap_paddr_t)dst)));
+ pn_dst = (ppnum_t)(dst >> PAGE_SHIFT);
+#if !defined(__ARM_COHERENT_IO__) && !__ARM_PTE_PHYSMAP__
+ count2 = PAGE_SIZE - dst_offset;
+ wimg_bits_dst = pmap_cache_attributes(pn_dst);
+ if ((wimg_bits_dst & VM_WIMG_MASK) != VM_WIMG_DEFAULT) {
+ use_copy_window_dst = TRUE;
+ }
+#else
+ if (use_copy_window_dst) {
+ wimg_bits_dst = pmap_cache_attributes(pn_dst);
+ count2 = PAGE_SIZE - dst_offset;
+ }