{ "INFO", VM_INFO },
{ "RS_UPDATE", VM_RS_UPDATE },
{ "RS_MEMCTL", VM_RS_MEMCTL },
+ { "PROCCTL", VM_PROCCTL },
{ NULL, 0 },
};
RS_SET_PRIV # 37
RS_UPDATE # 41
RS_MEMCTL # 42
+ PROCCTL
;
io NONE; # No I/O range allowed
irq NONE; # No IRQ allowed
UMAP # 14
VIRCOPY # 15
;
- vm BASIC; # Only basic VM calls allowed
+ vm PROCCTL;
io NONE; # No I/O range allowed
irq NONE; # No IRQ allowed
sigmgr rs; # Signal manager is RS
# define VMM_FLAGS m5_s2
# define VMM_FD m5_i1
# define VMM_OFFSET m5_i2
+# define VMM_FORWHOM m5_l3
# define VMM_RETADDR m5_l1 /* result */
#define VM_UMAP (VM_RQ_BASE+11)
# define VMU_SEG m1_i1
#define VM_REMAP_RO (VM_RQ_BASE+44)
/* 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. */
-#define NR_VM_CALLS 45
+#define NR_VM_CALLS 46
#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 */
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
count, vir_bytes *next);
+int vm_procctl(endpoint_t ep, int param);
#endif /* _MINIX_VM_H */
#include <sys/featuretest.h>
#include <machine/ansi.h>
+#include <minix/type.h>
#ifdef _BSD_SIZE_T_
typedef _BSD_SIZE_T_ size_t;
#define MAP_ALIGN64K 0x0040 /* physically aligned at 64kB */
#define MAP_LOWER1M 0x0080 /* physically below 16MB */
#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_THIRDPARTY 0x0400 /* perform on behalf of any process */
/*
* Error indicator returned by mmap(2)
int munmap(void *, size_t);
#else
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_text(void *, size_t);
void * vm_remap(int d, int s, void *da, void *sa, size_t si);
#include <string.h>
#include <errno.h>
-void *minix_mmap(void *addr, size_t len, int prot, int flags,
- int fd, off_t offset)
+void *minix_mmap_for(endpoint_t forwhom,
+ void *addr, size_t len, int prot, int flags, int fd, off_t offset)
{
message m;
int r;
m.VMM_FLAGS = flags;
m.VMM_FD = fd;
m.VMM_OFFSET = offset;
+ m.VMM_FORWHOM = forwhom;
+
+ if(forwhom != SELF) {
+ m.VMM_FLAGS |= MAP_THIRDPARTY;
+ }
r = _syscall(VM_PROC_NR, VM_MMAP, &m);
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)
{
message m;
vm_push_sig.c \
vm_umap.c \
vm_yield_get_block.c \
+ vm_procctl.c \
vprintf.c \
.if ${MKCOVERAGE} != "no"
--- /dev/null
+
+#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);
+}
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;
+}
+
CALLMAP(VM_RS_UPDATE, do_rs_update);
CALLMAP(VM_RS_MEMCTL, do_rs_memctl);
+ /* Calls from RS/VFS */
+ CALLMAP(VM_PROCCTL, do_procctl);
+
/* Generic calls. */
CALLMAP(VM_REMAP, do_remap);
CALLMAP(VM_REMAP_RO, do_remap);
vir_bytes addr;
struct vir_region *vr = NULL;
- if((r=vm_isokendpt(m->m_source, &n)) != OK) {
- panic("do_mmap: message from strange source: %d", m->m_source);
+ if(m->VMM_FLAGS & MAP_THIRDPARTY) {
+ /* 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];
void clear_proc(struct vmproc *vmp);
int do_exit(message *msg);
int do_willexit(message *msg);
+int do_procctl(message *msg);
void free_proc(struct vmproc *vmp);
/* fork.c */