vm: add third-party mmap() mode and PROCCTL
these two functions will be used to support all exec() functionality going into a single library shared by RS and VFS and exec() knowledge leaving VM. . third-party mmap: allow certain processes (VFS, RS) to do mmap() on behalf of another process . PROCCTL: used to free and clear a process' address space
This commit is contained in:
parent
1daf36038c
commit
ee4016155e
12 changed files with 98 additions and 7 deletions
|
@ -731,6 +731,7 @@ struct
|
||||||
{ "INFO", VM_INFO },
|
{ "INFO", VM_INFO },
|
||||||
{ "RS_UPDATE", VM_RS_UPDATE },
|
{ "RS_UPDATE", VM_RS_UPDATE },
|
||||||
{ "RS_MEMCTL", VM_RS_MEMCTL },
|
{ "RS_MEMCTL", VM_RS_MEMCTL },
|
||||||
|
{ "PROCCTL", VM_PROCCTL },
|
||||||
{ NULL, 0 },
|
{ NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ service rs
|
||||||
RS_SET_PRIV # 37
|
RS_SET_PRIV # 37
|
||||||
RS_UPDATE # 41
|
RS_UPDATE # 41
|
||||||
RS_MEMCTL # 42
|
RS_MEMCTL # 42
|
||||||
|
PROCCTL
|
||||||
;
|
;
|
||||||
io NONE; # No I/O range allowed
|
io NONE; # No I/O range allowed
|
||||||
irq NONE; # No IRQ allowed
|
irq NONE; # No IRQ allowed
|
||||||
|
@ -93,7 +94,7 @@ service vfs
|
||||||
UMAP # 14
|
UMAP # 14
|
||||||
VIRCOPY # 15
|
VIRCOPY # 15
|
||||||
;
|
;
|
||||||
vm BASIC; # Only basic VM calls allowed
|
vm PROCCTL;
|
||||||
io NONE; # No I/O range allowed
|
io NONE; # No I/O range allowed
|
||||||
irq NONE; # No IRQ allowed
|
irq NONE; # No IRQ allowed
|
||||||
sigmgr rs; # Signal manager is RS
|
sigmgr rs; # Signal manager is RS
|
||||||
|
|
|
@ -942,6 +942,7 @@
|
||||||
# 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 m5_i2
|
||||||
|
# define VMM_FORWHOM 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
|
||||||
|
@ -1076,8 +1077,14 @@
|
||||||
#define VM_REMAP_RO (VM_RQ_BASE+44)
|
#define VM_REMAP_RO (VM_RQ_BASE+44)
|
||||||
/* same args as VM_REMAP */
|
/* same args as VM_REMAP */
|
||||||
|
|
||||||
|
#define VM_PROCCTL (VM_RQ_BASE+45)
|
||||||
|
#define VMPCTL_PARAM m1_i1
|
||||||
|
#define VMPCTL_WHO m1_i2
|
||||||
|
|
||||||
|
#define VMPPARAM_CLEAR 1 /* values for VMPCTL_PARAM */
|
||||||
|
|
||||||
/* Total. */
|
/* Total. */
|
||||||
#define NR_VM_CALLS 45
|
#define NR_VM_CALLS 46
|
||||||
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
|
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
|
||||||
|
|
||||||
/* not handled as a normal VM call, thus at the end of the reserved rage */
|
/* not handled as a normal VM call, thus at the end of the reserved rage */
|
||||||
|
|
|
@ -70,6 +70,7 @@ int vm_info_stats(struct vm_stats_info *vfi);
|
||||||
int vm_info_usage(endpoint_t who, struct vm_usage_info *vui);
|
int vm_info_usage(endpoint_t who, struct vm_usage_info *vui);
|
||||||
int vm_info_region(endpoint_t who, struct vm_region_info *vri, int
|
int vm_info_region(endpoint_t who, struct vm_region_info *vri, int
|
||||||
count, vir_bytes *next);
|
count, vir_bytes *next);
|
||||||
|
int vm_procctl(endpoint_t ep, int param);
|
||||||
|
|
||||||
#endif /* _MINIX_VM_H */
|
#endif /* _MINIX_VM_H */
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <sys/featuretest.h>
|
#include <sys/featuretest.h>
|
||||||
|
|
||||||
#include <machine/ansi.h>
|
#include <machine/ansi.h>
|
||||||
|
#include <minix/type.h>
|
||||||
|
|
||||||
#ifdef _BSD_SIZE_T_
|
#ifdef _BSD_SIZE_T_
|
||||||
typedef _BSD_SIZE_T_ size_t;
|
typedef _BSD_SIZE_T_ size_t;
|
||||||
|
@ -54,9 +55,10 @@ typedef __off_t off_t; /* file offset */
|
||||||
#define MAP_ALIGN64K 0x0040 /* physically aligned at 64kB */
|
#define MAP_ALIGN64K 0x0040 /* physically aligned at 64kB */
|
||||||
#define MAP_LOWER1M 0x0080 /* physically below 16MB */
|
#define MAP_LOWER1M 0x0080 /* physically below 16MB */
|
||||||
#define MAP_ALIGNMENT_64KB MAP_ALIGN64K
|
#define MAP_ALIGNMENT_64KB MAP_ALIGN64K
|
||||||
#define MAP_IPC_SHARED 0x0100 /* share changes */
|
#define MAP_IPC_SHARED 0x0100 /* share changes */
|
||||||
|
|
||||||
#define MAP_FIXED 0x0200 /* require mapping to happen at hint */
|
#define MAP_FIXED 0x0200 /* require mapping to happen at hint */
|
||||||
|
#define MAP_THIRDPARTY 0x0400 /* perform on behalf of any process */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error indicator returned by mmap(2)
|
* Error indicator returned by mmap(2)
|
||||||
|
@ -71,6 +73,7 @@ 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);
|
||||||
int minix_munmap(void *, size_t);
|
int minix_munmap(void *, size_t);
|
||||||
int minix_munmap_text(void *, size_t);
|
int minix_munmap_text(void *, size_t);
|
||||||
void * vm_remap(int d, int s, void *da, void *sa, size_t si);
|
void * vm_remap(int d, int s, void *da, void *sa, size_t si);
|
||||||
|
|
|
@ -21,8 +21,8 @@ __weak_alias(minix_munmap_text, _minix_munmap_text)
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
void *minix_mmap(void *addr, size_t len, int prot, int flags,
|
void *minix_mmap_for(endpoint_t forwhom,
|
||||||
int fd, off_t offset)
|
void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
int r;
|
int r;
|
||||||
|
@ -33,6 +33,11 @@ void *minix_mmap(void *addr, size_t len, int prot, int flags,
|
||||||
m.VMM_FLAGS = flags;
|
m.VMM_FLAGS = flags;
|
||||||
m.VMM_FD = fd;
|
m.VMM_FD = fd;
|
||||||
m.VMM_OFFSET = offset;
|
m.VMM_OFFSET = offset;
|
||||||
|
m.VMM_FORWHOM = forwhom;
|
||||||
|
|
||||||
|
if(forwhom != SELF) {
|
||||||
|
m.VMM_FLAGS |= MAP_THIRDPARTY;
|
||||||
|
}
|
||||||
|
|
||||||
r = _syscall(VM_PROC_NR, VM_MMAP, &m);
|
r = _syscall(VM_PROC_NR, VM_MMAP, &m);
|
||||||
|
|
||||||
|
@ -43,6 +48,12 @@ void *minix_mmap(void *addr, size_t len, int prot, int flags,
|
||||||
return (void *) m.VMM_RETADDR;
|
return (void *) m.VMM_RETADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *minix_mmap(void *addr, size_t len, int prot, int flags,
|
||||||
|
int fd, off_t offset)
|
||||||
|
{
|
||||||
|
return minix_mmap_for(SELF, addr, len, prot, flags, fd, offset);
|
||||||
|
}
|
||||||
|
|
||||||
int minix_munmap(void *addr, size_t len)
|
int minix_munmap(void *addr, size_t len)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
|
|
@ -127,6 +127,7 @@ SRCS= \
|
||||||
vm_push_sig.c \
|
vm_push_sig.c \
|
||||||
vm_umap.c \
|
vm_umap.c \
|
||||||
vm_yield_get_block.c \
|
vm_yield_get_block.c \
|
||||||
|
vm_procctl.c \
|
||||||
vprintf.c \
|
vprintf.c \
|
||||||
|
|
||||||
.if ${MKCOVERAGE} != "no"
|
.if ${MKCOVERAGE} != "no"
|
||||||
|
|
22
lib/libsys/vm_procctl.c
Normal file
22
lib/libsys/vm_procctl.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
#include "syslib.h"
|
||||||
|
|
||||||
|
#include <minix/vm.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* vm_exit *
|
||||||
|
*===========================================================================*/
|
||||||
|
int vm_procctl(endpoint_t ep, int param)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
memset(&m, 0, sizeof(m));
|
||||||
|
|
||||||
|
m.VMPCTL_WHO = ep;
|
||||||
|
m.VMPCTL_PARAM = param;
|
||||||
|
|
||||||
|
result = _taskcall(VM_PROC_NR, VM_PROCCTL, &m);
|
||||||
|
return(result);
|
||||||
|
}
|
|
@ -114,3 +114,33 @@ int do_willexit(message *msg)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int do_procctl(message *msg)
|
||||||
|
{
|
||||||
|
endpoint_t proc;
|
||||||
|
struct vmproc *vmp;
|
||||||
|
|
||||||
|
if(vm_isokendpt(msg->VMPCTL_WHO, &proc) != OK) {
|
||||||
|
printf("VM: bogus endpoint VM_PROCCTL %d\n",
|
||||||
|
msg->VMPCTL_WHO);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
vmp = &vmproc[proc];
|
||||||
|
|
||||||
|
switch(msg->VMPCTL_PARAM) {
|
||||||
|
case VMPPARAM_CLEAR:
|
||||||
|
if(msg->m_source != RS_PROC_NR
|
||||||
|
&& msg->m_source != VFS_PROC_NR)
|
||||||
|
return EPERM;
|
||||||
|
free_proc(vmp);
|
||||||
|
pt_new(&vmp->vm_pt);
|
||||||
|
vmp->vm_flags |= VMF_HASPT;
|
||||||
|
pt_bind(&vmp->vm_pt, vmp);
|
||||||
|
return OK;
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -357,6 +357,9 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
||||||
CALLMAP(VM_RS_UPDATE, do_rs_update);
|
CALLMAP(VM_RS_UPDATE, do_rs_update);
|
||||||
CALLMAP(VM_RS_MEMCTL, do_rs_memctl);
|
CALLMAP(VM_RS_MEMCTL, do_rs_memctl);
|
||||||
|
|
||||||
|
/* Calls from RS/VFS */
|
||||||
|
CALLMAP(VM_PROCCTL, do_procctl);
|
||||||
|
|
||||||
/* Generic calls. */
|
/* Generic calls. */
|
||||||
CALLMAP(VM_REMAP, do_remap);
|
CALLMAP(VM_REMAP, do_remap);
|
||||||
CALLMAP(VM_REMAP_RO, do_remap);
|
CALLMAP(VM_REMAP_RO, do_remap);
|
||||||
|
|
|
@ -43,8 +43,18 @@ int do_mmap(message *m)
|
||||||
vir_bytes addr;
|
vir_bytes addr;
|
||||||
struct vir_region *vr = NULL;
|
struct vir_region *vr = NULL;
|
||||||
|
|
||||||
if((r=vm_isokendpt(m->m_source, &n)) != OK) {
|
if(m->VMM_FLAGS & MAP_THIRDPARTY) {
|
||||||
panic("do_mmap: message from strange source: %d", m->m_source);
|
/* exec()ers, i.e. RS & VFS, can mmap() on behalf of anyone. */
|
||||||
|
if(m->m_source != VFS_PROC_NR && m->m_source != RS_PROC_NR)
|
||||||
|
return EPERM;
|
||||||
|
if((r=vm_isokendpt(m->VMM_FORWHOM, &n)) != OK)
|
||||||
|
return ESRCH;
|
||||||
|
} else {
|
||||||
|
/* regular mmap, i.e. for caller */
|
||||||
|
if((r=vm_isokendpt(m->m_source, &n)) != OK) {
|
||||||
|
panic("do_mmap: message from strange source: %d",
|
||||||
|
m->m_source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmp = &vmproc[n];
|
vmp = &vmproc[n];
|
||||||
|
|
|
@ -52,6 +52,7 @@ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp);
|
||||||
void clear_proc(struct vmproc *vmp);
|
void clear_proc(struct vmproc *vmp);
|
||||||
int do_exit(message *msg);
|
int do_exit(message *msg);
|
||||||
int do_willexit(message *msg);
|
int do_willexit(message *msg);
|
||||||
|
int do_procctl(message *msg);
|
||||||
void free_proc(struct vmproc *vmp);
|
void free_proc(struct vmproc *vmp);
|
||||||
|
|
||||||
/* fork.c */
|
/* fork.c */
|
||||||
|
|
Loading…
Reference in a new issue