* Copy the range specified by src_addr/len * from the source map to the range dst_addr/len * in the destination map. * * This routine is only advisory and need not do anything. */
| 7563 | * This routine is only advisory and need not do anything. |
| 7564 | */ |
| 7565 | void |
| 7566 | pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, |
| 7567 | vm_offset_t src_addr) |
| 7568 | { |
| 7569 | struct rwlock *lock; |
| 7570 | pml4_entry_t *pml4e; |
| 7571 | pdp_entry_t *pdpe; |
| 7572 | pd_entry_t *pde, srcptepaddr; |
| 7573 | pt_entry_t *dst_pte, PG_A, PG_M, PG_V, ptetemp, *src_pte; |
| 7574 | vm_offset_t addr, end_addr, va_next; |
| 7575 | vm_page_t dst_pdpg, dstmpte, srcmpte; |
| 7576 | |
| 7577 | if (dst_addr != src_addr) |
| 7578 | return; |
| 7579 | |
| 7580 | if (dst_pmap->pm_type != src_pmap->pm_type) |
| 7581 | return; |
| 7582 | |
| 7583 | /* |
| 7584 | * EPT page table entries that require emulation of A/D bits are |
| 7585 | * sensitive to clearing the PG_A bit (aka EPT_PG_READ). Although |
| 7586 | * we clear PG_M (aka EPT_PG_WRITE) concomitantly, the PG_U bit |
| 7587 | * (aka EPT_PG_EXECUTE) could still be set. Since some EPT |
| 7588 | * implementations flag an EPT misconfiguration for exec-only |
| 7589 | * mappings we skip this function entirely for emulated pmaps. |
| 7590 | */ |
| 7591 | if (pmap_emulate_ad_bits(dst_pmap)) |
| 7592 | return; |
| 7593 | |
| 7594 | end_addr = src_addr + len; |
| 7595 | lock = NULL; |
| 7596 | if (dst_pmap < src_pmap) { |
| 7597 | PMAP_LOCK(dst_pmap); |
| 7598 | PMAP_LOCK(src_pmap); |
| 7599 | } else { |
| 7600 | PMAP_LOCK(src_pmap); |
| 7601 | PMAP_LOCK(dst_pmap); |
| 7602 | } |
| 7603 | |
| 7604 | PG_A = pmap_accessed_bit(dst_pmap); |
| 7605 | PG_M = pmap_modified_bit(dst_pmap); |
| 7606 | PG_V = pmap_valid_bit(dst_pmap); |
| 7607 | |
| 7608 | for (addr = src_addr; addr < end_addr; addr = va_next) { |
| 7609 | KASSERT(addr < UPT_MIN_ADDRESS, |
| 7610 | ("pmap_copy: invalid to pmap_copy page tables")); |
| 7611 | |
| 7612 | pml4e = pmap_pml4e(src_pmap, addr); |
| 7613 | if (pml4e == NULL || (*pml4e & PG_V) == 0) { |
| 7614 | va_next = (addr + NBPML4) & ~PML4MASK; |
| 7615 | if (va_next < addr) |
| 7616 | va_next = end_addr; |
| 7617 | continue; |
| 7618 | } |
| 7619 | |
| 7620 | va_next = (addr + NBPDP) & ~PDPMASK; |
| 7621 | if (va_next < addr) |
| 7622 | va_next = end_addr; |
nothing calls this directly
no test coverage detected