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
					
				@ -731,6 +731,7 @@ struct
 | 
			
		||||
	{ "INFO",		VM_INFO },
 | 
			
		||||
	{ "RS_UPDATE",		VM_RS_UPDATE },
 | 
			
		||||
	{ "RS_MEMCTL",		VM_RS_MEMCTL },
 | 
			
		||||
	{ "PROCCTL",		VM_PROCCTL },
 | 
			
		||||
	{ NULL,			0 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ service rs
 | 
			
		||||
		RS_SET_PRIV	# 37
 | 
			
		||||
		RS_UPDATE	# 41
 | 
			
		||||
		RS_MEMCTL	# 42
 | 
			
		||||
		PROCCTL
 | 
			
		||||
		;
 | 
			
		||||
	io	NONE;		# No I/O range allowed
 | 
			
		||||
	irq	NONE;		# No IRQ allowed
 | 
			
		||||
@ -93,7 +94,7 @@ service vfs
 | 
			
		||||
		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
 | 
			
		||||
 | 
			
		||||
@ -942,6 +942,7 @@
 | 
			
		||||
#	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
 | 
			
		||||
@ -1076,8 +1077,14 @@
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
@ -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_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 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@
 | 
			
		||||
#include <sys/featuretest.h>
 | 
			
		||||
 | 
			
		||||
#include <machine/ansi.h>
 | 
			
		||||
#include <minix/type.h>
 | 
			
		||||
 | 
			
		||||
#ifdef	_BSD_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_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)
 | 
			
		||||
@ -71,6 +73,7 @@ void *	mmap(void *, size_t, int, int, int, off_t);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,8 @@ __weak_alias(minix_munmap_text, _minix_munmap_text)
 | 
			
		||||
#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;
 | 
			
		||||
@ -33,6 +33,11 @@ void *minix_mmap(void *addr, size_t len, int prot, int flags,
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
@ -43,6 +48,12 @@ void *minix_mmap(void *addr, size_t len, int prot, int flags,
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
@ -127,6 +127,7 @@ SRCS=  \
 | 
			
		||||
	vm_push_sig.c \
 | 
			
		||||
	vm_umap.c \
 | 
			
		||||
	vm_yield_get_block.c \
 | 
			
		||||
	vm_procctl.c \
 | 
			
		||||
	vprintf.c \
 | 
			
		||||
 | 
			
		||||
.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_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);
 | 
			
		||||
 | 
			
		||||
@ -43,8 +43,18 @@ int do_mmap(message *m)
 | 
			
		||||
	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];
 | 
			
		||||
 | 
			
		||||
@ -52,6 +52,7 @@ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp);
 | 
			
		||||
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 */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user