DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process) { /* * Check for unsupported stuff. */ AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED); if (uAlignment > PAGE_SIZE) return VERR_NOT_SUPPORTED; int rc; PRTR0MEMOBJFREEBSD pMemToMapFreeBSD = (PRTR0MEMOBJFREEBSD)pMemToMap; struct proc *pProc = (struct proc *)R0Process; struct vm_map *pProcMap = &pProc->p_vmspace->vm_map; /* calc protection */ vm_prot_t ProtectionFlags = 0; if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE) ProtectionFlags = VM_PROT_NONE; if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ) ProtectionFlags |= VM_PROT_READ; if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE) ProtectionFlags |= VM_PROT_WRITE; if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC) ProtectionFlags |= VM_PROT_EXECUTE; /* calc mapping address */ vm_offset_t AddrR3; if (R3PtrFixed == (RTR3PTR)-1) { /** @todo: is this needed?. */ PROC_LOCK(pProc); AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA)); PROC_UNLOCK(pProc); } else AddrR3 = (vm_offset_t)R3PtrFixed; /* Insert the pObject in the map. */ vm_object_reference(pMemToMapFreeBSD->pObject); rc = vm_map_find(pProcMap, /* Map to insert the object in */ pMemToMapFreeBSD->pObject, /* Object to map */ 0, /* Start offset in the object */ &AddrR3, /* Start address IN/OUT */ pMemToMap->cb, /* Size of the mapping */ #if __FreeBSD_version >= 1000055 0, /* Upper bound of the mapping */ #endif R3PtrFixed == (RTR3PTR)-1 ? VMFS_ANY_SPACE : VMFS_NO_SPACE, /* Whether a suitable address should be searched for first */ ProtectionFlags, /* protection flags */ VM_PROT_ALL, /* Maximum protection flags */ 0); /* copy-on-write and similar flags */ if (rc == KERN_SUCCESS) { rc = vm_map_wire(pProcMap, AddrR3, AddrR3 + pMemToMap->cb, VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); rc = vm_map_inherit(pProcMap, AddrR3, AddrR3 + pMemToMap->cb, VM_INHERIT_SHARE); AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); /* * Create a mapping object for it. */ PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(RTR0MEMOBJFREEBSD), RTR0MEMOBJTYPE_MAPPING, (void *)AddrR3, pMemToMap->cb); if (pMemFreeBSD) { Assert((vm_offset_t)pMemFreeBSD->Core.pv == AddrR3); pMemFreeBSD->Core.u.Mapping.R0Process = R0Process; *ppMem = &pMemFreeBSD->Core; return VINF_SUCCESS; } rc = vm_map_remove(pProcMap, AddrR3, AddrR3 + pMemToMap->cb); AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n")); } else vm_object_deallocate(pMemToMapFreeBSD->pObject); return VERR_NO_MEMORY; }
int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process) { #if 0 /* * Check for unsupported stuff. */ AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED); AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED); if (uAlignment > PAGE_SIZE) return VERR_NOT_SUPPORTED; int rc; PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap; struct proc *pProc = (struct proc *)R0Process; struct vm_map *pProcMap = &pProc->p_vmspace->vm_map; /* calc protection */ vm_prot_t ProtectionFlags = 0; if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE) ProtectionFlags = VM_PROT_NONE; if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ) ProtectionFlags |= VM_PROT_READ; if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE) ProtectionFlags |= VM_PROT_WRITE; if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC) ProtectionFlags |= VM_PROT_EXECUTE; /* calc mapping address */ PROC_LOCK(pProc); vm_offset_t AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA)); PROC_UNLOCK(pProc); /* Insert the object in the map. */ rc = vm_map_find(pProcMap, /* Map to insert the object in */ NULL, /* Object to map */ 0, /* Start offset in the object */ &AddrR3, /* Start address IN/OUT */ pMemToMap->cb, /* Size of the mapping */ TRUE, /* Whether a suitable address should be searched for first */ ProtectionFlags, /* protection flags */ VM_PROT_ALL, /* Maximum protection flags */ 0); /* Copy on write */ /* Map the memory page by page into the destination map. */ if (rc == KERN_SUCCESS) { size_t cPages = pMemToMap->cb >> PAGE_SHIFT;; pmap_t pPhysicalMap = pProcMap->pmap; vm_offset_t AddrR3Dst = AddrR3; if ( pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS || pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS_NC || pMemToMap->enmType == RTR0MEMOBJTYPE_PAGE) { /* Mapping physical allocations */ Assert(cPages == pMemToMapHaiku->u.Phys.cPages); /* Insert the memory page by page into the mapping. */ for (uint32_t iPage = 0; iPage < cPages; iPage++) { vm_page_t pPage = pMemToMapHaiku->u.Phys.apPages[iPage]; MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE); AddrR3Dst += PAGE_SIZE; } } else { /* Mapping cont or low memory types */ vm_offset_t AddrToMap = (vm_offset_t)pMemToMap->pv; for (uint32_t iPage = 0; iPage < cPages; iPage++) { vm_page_t pPage = PHYS_TO_VM_PAGE(vtophys(AddrToMap)); MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE); AddrR3Dst += PAGE_SIZE; AddrToMap += PAGE_SIZE; } } }