* We require the caller to unmap the entire entry. This allows us to * safely decrement shm_kmappings when a mapping is removed. */
| 1736 | * safely decrement shm_kmappings when a mapping is removed. |
| 1737 | */ |
| 1738 | int |
| 1739 | shm_unmap(struct file *fp, void *mem, size_t size) |
| 1740 | { |
| 1741 | struct shmfd *shmfd; |
| 1742 | vm_map_entry_t entry; |
| 1743 | vm_offset_t kva, ofs; |
| 1744 | vm_object_t obj; |
| 1745 | vm_pindex_t pindex; |
| 1746 | vm_prot_t prot; |
| 1747 | boolean_t wired; |
| 1748 | vm_map_t map; |
| 1749 | int rv; |
| 1750 | |
| 1751 | if (fp->f_type != DTYPE_SHM) |
| 1752 | return (EINVAL); |
| 1753 | shmfd = fp->f_data; |
| 1754 | kva = (vm_offset_t)mem; |
| 1755 | ofs = kva & PAGE_MASK; |
| 1756 | kva = trunc_page(kva); |
| 1757 | size = round_page(size + ofs); |
| 1758 | map = kernel_map; |
| 1759 | rv = vm_map_lookup(&map, kva, VM_PROT_READ | VM_PROT_WRITE, &entry, |
| 1760 | &obj, &pindex, &prot, &wired); |
| 1761 | if (rv != KERN_SUCCESS) |
| 1762 | return (EINVAL); |
| 1763 | if (entry->start != kva || entry->end != kva + size) { |
| 1764 | vm_map_lookup_done(map, entry); |
| 1765 | return (EINVAL); |
| 1766 | } |
| 1767 | vm_map_lookup_done(map, entry); |
| 1768 | if (obj != shmfd->shm_object) |
| 1769 | return (EINVAL); |
| 1770 | vm_map_remove(map, kva, kva + size); |
| 1771 | VM_OBJECT_WLOCK(obj); |
| 1772 | KASSERT(shmfd->shm_kmappings > 0, ("shm_unmap: object not mapped")); |
| 1773 | shmfd->shm_kmappings--; |
| 1774 | VM_OBJECT_WUNLOCK(obj); |
| 1775 | return (0); |
| 1776 | } |
| 1777 | |
| 1778 | static int |
| 1779 | shm_fill_kinfo_locked(struct shmfd *shmfd, struct kinfo_file *kif, bool list) |
nothing calls this directly
no test coverage detected