VM: 64-bit mmap()
Some (backwards-compatible) changes in mmap() call message fields that allow for a 64-bit offset. minix_mmap() takes an off_t and minix_mmap64() takes a u64_t. Some mmap() work in VM goes into a separate function, using the new fields, so that that can be re-used when files are to be mapped (future commit). Change-Id: Ifb77a90b593dd3c33cf81b396068e4da1ec5fb1c
This commit is contained in:
parent
75c5fe4c26
commit
9e88c40e40
4 changed files with 71 additions and 40 deletions
|
@ -942,8 +942,9 @@
|
||||||
# define VMM_PROT m5_s1
|
# define VMM_PROT m5_s1
|
||||||
# define VMM_FLAGS m5_s2
|
# define VMM_FLAGS m5_s2
|
||||||
# define VMM_FD m5_i1
|
# define VMM_FD m5_i1
|
||||||
# define VMM_OFFSET m5_i2
|
# define VMM_OFFSET_LO m5_i2
|
||||||
# define VMM_FORWHOM m5_l3
|
# define VMM_FORWHOM m5_l3
|
||||||
|
# define VMM_OFFSET_HI m5_l3
|
||||||
# define VMM_RETADDR m5_l1 /* result */
|
# define VMM_RETADDR m5_l1 /* result */
|
||||||
#define VM_UMAP (VM_RQ_BASE+11)
|
#define VM_UMAP (VM_RQ_BASE+11)
|
||||||
# define VMU_SEG m1_i1
|
# define VMU_SEG m1_i1
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#include "namespace.h"
|
#include "namespace.h"
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
|
#include <minix/u64.h>
|
||||||
|
#include <minix/vm.h>
|
||||||
|
|
||||||
/* INCLUDES HERE */
|
/* INCLUDES HERE */
|
||||||
|
|
||||||
|
@ -21,7 +23,7 @@ __weak_alias(minix_munmap, _minix_munmap)
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
void *minix_mmap_for(endpoint_t forwhom,
|
void *minix_mmap_for(endpoint_t forwhom,
|
||||||
void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
void *addr, size_t len, int prot, int flags, int fd, u64_t offset)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
int r;
|
int r;
|
||||||
|
@ -31,11 +33,13 @@ void *minix_mmap_for(endpoint_t forwhom,
|
||||||
m.VMM_PROT = prot;
|
m.VMM_PROT = prot;
|
||||||
m.VMM_FLAGS = flags;
|
m.VMM_FLAGS = flags;
|
||||||
m.VMM_FD = fd;
|
m.VMM_FD = fd;
|
||||||
m.VMM_OFFSET = offset;
|
m.VMM_OFFSET_LO = ex64lo(offset);
|
||||||
m.VMM_FORWHOM = forwhom;
|
|
||||||
|
|
||||||
if(forwhom != SELF) {
|
if(forwhom != SELF) {
|
||||||
m.VMM_FLAGS |= MAP_THIRDPARTY;
|
m.VMM_FLAGS |= MAP_THIRDPARTY;
|
||||||
|
m.VMM_FORWHOM = forwhom;
|
||||||
|
} else {
|
||||||
|
m.VMM_OFFSET_HI = ex64hi(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = _syscall(VM_PROC_NR, VM_MMAP, &m);
|
r = _syscall(VM_PROC_NR, VM_MMAP, &m);
|
||||||
|
|
|
@ -32,6 +32,58 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct vir_region *mmap_region(struct vmproc *vmp, vir_bytes addr,
|
||||||
|
u32_t vmm_flags, size_t len, u32_t vrflags,
|
||||||
|
mem_type_t *mt, int execpriv)
|
||||||
|
{
|
||||||
|
u32_t mfflags = 0;
|
||||||
|
struct vir_region *vr = NULL;
|
||||||
|
|
||||||
|
if(vmm_flags & MAP_LOWER16M) vrflags |= VR_LOWER16MB;
|
||||||
|
if(vmm_flags & MAP_LOWER1M) vrflags |= VR_LOWER1MB;
|
||||||
|
if(vmm_flags & MAP_ALIGN64K) vrflags |= VR_PHYS64K;
|
||||||
|
if(vmm_flags & MAP_PREALLOC) mfflags |= MF_PREALLOC;
|
||||||
|
if(vmm_flags & MAP_UNINITIALIZED) {
|
||||||
|
if(!execpriv) return NULL;
|
||||||
|
vrflags |= VR_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len <= 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len % VM_PAGE_SIZE)
|
||||||
|
len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* MAP_FIXED is restored in a later commit */
|
||||||
|
if (addr && (vmm_flags & MAP_FIXED)) {
|
||||||
|
int r = map_unmap_range(vmp, addr, len);
|
||||||
|
if(r != OK) {
|
||||||
|
printf("mmap_region: map_unmap_range failed (%d)\n", r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (addr || (vmm_flags & MAP_FIXED)) {
|
||||||
|
/* An address is given, first try at that address. */
|
||||||
|
vr = map_page_region(vmp, addr, 0, len,
|
||||||
|
vrflags, mfflags, mt);
|
||||||
|
if(!vr && (vmm_flags & MAP_FIXED))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vr) {
|
||||||
|
/* No address given or address already in use. */
|
||||||
|
vr = map_page_region(vmp, VM_PAGE_SIZE, VM_DATATOP, len,
|
||||||
|
vrflags, mfflags, mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_mmap *
|
* do_mmap *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
@ -39,10 +91,10 @@ int do_mmap(message *m)
|
||||||
{
|
{
|
||||||
int r, n;
|
int r, n;
|
||||||
struct vmproc *vmp;
|
struct vmproc *vmp;
|
||||||
int mfflags = 0;
|
vir_bytes addr = m->VMM_ADDR;
|
||||||
vir_bytes addr;
|
|
||||||
struct vir_region *vr = NULL;
|
struct vir_region *vr = NULL;
|
||||||
int execpriv = 0;
|
int execpriv = 0;
|
||||||
|
size_t len = (vir_bytes) m->VMM_LEN;
|
||||||
|
|
||||||
/* RS and VFS can do slightly more special mmap() things */
|
/* RS and VFS can do slightly more special mmap() things */
|
||||||
if(m->m_source == VFS_PROC_NR || m->m_source == RS_PROC_NR)
|
if(m->m_source == VFS_PROC_NR || m->m_source == RS_PROC_NR)
|
||||||
|
@ -63,11 +115,11 @@ int do_mmap(message *m)
|
||||||
vmp = &vmproc[n];
|
vmp = &vmproc[n];
|
||||||
|
|
||||||
if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
|
if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
|
||||||
mem_type_t *mt;
|
/* actual memory in some form */
|
||||||
u32_t vrflags = VR_ANON | VR_WRITABLE;
|
mem_type_t *mt = NULL;
|
||||||
size_t len = (vir_bytes) m->VMM_LEN;
|
|
||||||
|
|
||||||
if(m->VMM_FD != -1 || len <= 0) {
|
if(m->VMM_FD != -1 || len <= 0) {
|
||||||
|
printf("VM: mmap: fd %d, len 0x%x\n", m->VMM_FD, len);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,48 +128,21 @@ int do_mmap(message *m)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m->VMM_FLAGS & MAP_PREALLOC) mfflags |= MF_PREALLOC;
|
|
||||||
if(m->VMM_FLAGS & MAP_LOWER16M) vrflags |= VR_LOWER16MB;
|
|
||||||
if(m->VMM_FLAGS & MAP_LOWER1M) vrflags |= VR_LOWER1MB;
|
|
||||||
if(m->VMM_FLAGS & MAP_ALIGN64K) vrflags |= VR_PHYS64K;
|
|
||||||
if(m->VMM_FLAGS & MAP_UNINITIALIZED) {
|
|
||||||
if(!execpriv) return EPERM;
|
|
||||||
vrflags |= VR_UNINITIALIZED;
|
|
||||||
}
|
|
||||||
if(m->VMM_FLAGS & MAP_CONTIG) {
|
if(m->VMM_FLAGS & MAP_CONTIG) {
|
||||||
vrflags |= VR_CONTIG;
|
|
||||||
mt = &mem_type_anon_contig;
|
mt = &mem_type_anon_contig;
|
||||||
} else mt = &mem_type_anon;
|
} else mt = &mem_type_anon;
|
||||||
|
|
||||||
if(len % VM_PAGE_SIZE)
|
if(!(vr = mmap_region(vmp, addr, m->VMM_FLAGS, len,
|
||||||
len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
|
VR_WRITABLE | VR_ANON, mt, execpriv))) {
|
||||||
|
|
||||||
vr = NULL;
|
|
||||||
if (m->VMM_ADDR || (m->VMM_FLAGS & MAP_FIXED)) {
|
|
||||||
/* An address is given, first try at that address. */
|
|
||||||
addr = m->VMM_ADDR;
|
|
||||||
vr = map_page_region(vmp, addr, 0, len,
|
|
||||||
vrflags, mfflags, mt);
|
|
||||||
if(!vr && (m->VMM_FLAGS & MAP_FIXED))
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
if (!vr) {
|
|
||||||
/* No address given or address already in use. */
|
|
||||||
vr = map_page_region(vmp, 0, VM_DATATOP, len,
|
|
||||||
vrflags, mfflags, mt);
|
|
||||||
}
|
|
||||||
if (!vr) {
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return ENOSYS;
|
return ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return mapping, as seen from process. */
|
/* Return mapping, as seen from process. */
|
||||||
assert(vr);
|
|
||||||
m->VMM_RETADDR = vr->vaddr;
|
m->VMM_RETADDR = vr->vaddr;
|
||||||
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,8 @@ void * mmap(void *, size_t, int, int, int, off_t);
|
||||||
int munmap(void *, size_t);
|
int munmap(void *, size_t);
|
||||||
#else
|
#else
|
||||||
void * minix_mmap(void *, size_t, int, int, int, off_t);
|
void * minix_mmap(void *, size_t, int, int, int, off_t);
|
||||||
void * minix_mmap_for(endpoint_t, void *, size_t, int, int, int, off_t);
|
void * minix_mmap64(void *, size_t, int, int, int, u64_t);
|
||||||
|
void * minix_mmap_for(endpoint_t, void *, size_t, int, int, int, u64_t);
|
||||||
int minix_munmap(void *, size_t);
|
int minix_munmap(void *, size_t);
|
||||||
void * vm_remap(endpoint_t d, endpoint_t s, void *da, void *sa, size_t si);
|
void * vm_remap(endpoint_t d, endpoint_t s, void *da, void *sa, size_t si);
|
||||||
void * vm_remap_ro(endpoint_t d, endpoint_t s, void *da, void *sa, size_t si);
|
void * vm_remap_ro(endpoint_t d, endpoint_t s, void *da, void *sa, size_t si);
|
||||||
|
|
Loading…
Reference in a new issue