Give RS a page table.
This commit is contained in:
parent
869a223d43
commit
06700d05d1
@ -1030,8 +1030,13 @@
|
|||||||
# define VM_RS_SRC_ENDPT m1_i1
|
# define VM_RS_SRC_ENDPT m1_i1
|
||||||
# define VM_RS_DST_ENDPT m1_i2
|
# define VM_RS_DST_ENDPT m1_i2
|
||||||
|
|
||||||
|
#define VM_RS_MEMCTL (VM_RQ_BASE+42)
|
||||||
|
# define VM_RS_CTL_ENDPT m1_i1
|
||||||
|
# define VM_RS_CTL_REQ m1_i2
|
||||||
|
# define VM_RS_MEM_PIN 0 /* pin memory */
|
||||||
|
|
||||||
/* Total. */
|
/* Total. */
|
||||||
#define NR_VM_CALLS 42
|
#define NR_VM_CALLS 43
|
||||||
#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 */
|
||||||
|
@ -23,9 +23,9 @@ _PROTOTYPE( void *vm_map_phys, (endpoint_t who, void *physaddr, size_t len));
|
|||||||
_PROTOTYPE( int vm_unmap_phys, (endpoint_t who, void *vaddr, size_t len));
|
_PROTOTYPE( int vm_unmap_phys, (endpoint_t who, void *vaddr, size_t len));
|
||||||
|
|
||||||
_PROTOTYPE( int vm_notify_sig, (endpoint_t ep, endpoint_t ipc_ep));
|
_PROTOTYPE( int vm_notify_sig, (endpoint_t ep, endpoint_t ipc_ep));
|
||||||
_PROTOTYPE( int vm_ctl, (int what, int param));
|
|
||||||
_PROTOTYPE( int vm_set_priv, (int procnr, void *buf));
|
_PROTOTYPE( int vm_set_priv, (int procnr, void *buf));
|
||||||
_PROTOTYPE( int vm_update, (endpoint_t src_e, endpoint_t dst_e));
|
_PROTOTYPE( int vm_update, (endpoint_t src_e, endpoint_t dst_e));
|
||||||
|
_PROTOTYPE( int vm_memctl, (endpoint_t ep, int req));
|
||||||
_PROTOTYPE( int vm_query_exit, (int *endpt));
|
_PROTOTYPE( int vm_query_exit, (int *endpt));
|
||||||
_PROTOTYPE( int vm_forgetblock, (u64_t id));
|
_PROTOTYPE( int vm_forgetblock, (u64_t id));
|
||||||
_PROTOTYPE( void vm_forgetblocks, (void));
|
_PROTOTYPE( void vm_forgetblocks, (void));
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "glo.h" /* global variables */
|
#include "glo.h" /* global variables */
|
||||||
#include "ipc.h" /* IPC constants */
|
#include "ipc.h" /* IPC constants */
|
||||||
#include "profile.h" /* system profiling */
|
#include "profile.h" /* system profiling */
|
||||||
|
#include "perf.h" /* performance-related definitions */
|
||||||
#include "debug.h" /* debugging, MUST be last kernel header */
|
#include "debug.h" /* debugging, MUST be last kernel header */
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#define MEM_TOP 0xFFFFFFFFUL
|
#define MEM_TOP 0xFFFFFFFFUL
|
||||||
|
|
||||||
#define USE_COW_SAFECOPY 0
|
|
||||||
|
|
||||||
FORWARD _PROTOTYPE(int safecopy, (struct proc *, endpoint_t, endpoint_t,
|
FORWARD _PROTOTYPE(int safecopy, (struct proc *, endpoint_t, endpoint_t,
|
||||||
cp_grant_id_t, int, int, size_t, vir_bytes, vir_bytes, int));
|
cp_grant_id_t, int, int, size_t, vir_bytes, vir_bytes, int));
|
||||||
|
|
||||||
@ -240,7 +238,7 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
|
|||||||
endpoint_t new_granter, *src, *dst;
|
endpoint_t new_granter, *src, *dst;
|
||||||
struct proc *granter_p;
|
struct proc *granter_p;
|
||||||
int r;
|
int r;
|
||||||
#if USE_COW_SAFECOPY
|
#if PERF_USE_COW_SAFECOPY
|
||||||
vir_bytes size;
|
vir_bytes size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -290,7 +288,7 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do the regular copy. */
|
/* Do the regular copy. */
|
||||||
#if USE_COW_SAFECOPY
|
#if PERF_USE_COW_SAFECOPY
|
||||||
if(v_offset % CLICK_SIZE != addr % CLICK_SIZE || bytes < CLICK_SIZE) {
|
if(v_offset % CLICK_SIZE != addr % CLICK_SIZE || bytes < CLICK_SIZE) {
|
||||||
/* Give up on COW immediately when offsets are not aligned
|
/* Give up on COW immediately when offsets are not aligned
|
||||||
* or we are copying less than a page.
|
* or we are copying less than a page.
|
||||||
|
@ -46,7 +46,11 @@
|
|||||||
PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
|
PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
|
||||||
|
|
||||||
/* Define boot process flags. */
|
/* Define boot process flags. */
|
||||||
#define BVM_F (PROC_FULLVM) /* boot processes with VM */
|
#define BVM_F (PROC_FULLVM) /* boot processes with VM */
|
||||||
|
#define OVM_F (PERF_SYS_CORE_FULLVM ? PROC_FULLVM : 0) /* critical boot
|
||||||
|
* processes with
|
||||||
|
* optional VM.
|
||||||
|
*/
|
||||||
|
|
||||||
/* The system image table lists all programs that are part of the boot image.
|
/* The system image table lists all programs that are part of the boot image.
|
||||||
* The order of the entries here MUST agree with the order of the programs
|
* The order of the entries here MUST agree with the order of the programs
|
||||||
@ -74,9 +78,9 @@ PUBLIC struct boot_image image[] = {
|
|||||||
{DS_PROC_NR, BVM_F, 50, 4, 0, "ds" },
|
{DS_PROC_NR, BVM_F, 50, 4, 0, "ds" },
|
||||||
{RS_PROC_NR, 0, 50, 4, 0, "rs" },
|
{RS_PROC_NR, 0, 50, 4, 0, "rs" },
|
||||||
|
|
||||||
{PM_PROC_NR, 0,500, 4, 0, "pm" },
|
{PM_PROC_NR, OVM_F,500, 4, 0, "pm" },
|
||||||
{SCHED_PROC_NR, 0,500, 4, 0, "sched" },
|
{SCHED_PROC_NR,OVM_F,500, 4, 0, "sched" },
|
||||||
{VFS_PROC_NR, 0,500, 5, 0, "vfs" },
|
{VFS_PROC_NR, OVM_F,500, 5, 0, "vfs" },
|
||||||
{MEM_PROC_NR, BVM_F, 50, 3, 0, "memory"},
|
{MEM_PROC_NR, BVM_F, 50, 3, 0, "memory"},
|
||||||
{LOG_PROC_NR, BVM_F, 50, 2, 0, "log" },
|
{LOG_PROC_NR, BVM_F, 50, 2, 0, "log" },
|
||||||
{TTY_PROC_NR, BVM_F, 50, 1, 0, "tty" },
|
{TTY_PROC_NR, BVM_F, 50, 1, 0, "tty" },
|
||||||
|
@ -32,6 +32,7 @@ SRCS+= \
|
|||||||
_svrctl.c \
|
_svrctl.c \
|
||||||
_sysuname.c \
|
_sysuname.c \
|
||||||
_vm_dmacalls.c \
|
_vm_dmacalls.c \
|
||||||
|
_vm_memctl.c \
|
||||||
_vm_set_priv.c \
|
_vm_set_priv.c \
|
||||||
_vm_update.c \
|
_vm_update.c \
|
||||||
_vm_query_exit.c \
|
_vm_query_exit.c \
|
||||||
|
@ -73,6 +73,7 @@ SRCS+= \
|
|||||||
munmap.S \
|
munmap.S \
|
||||||
vm_getphys.S \
|
vm_getphys.S \
|
||||||
vm_getrefcount.S \
|
vm_getrefcount.S \
|
||||||
|
vm_memctl.S \
|
||||||
vm_remap.S \
|
vm_remap.S \
|
||||||
vm_unmap.S \
|
vm_unmap.S \
|
||||||
vm_set_priv.S \
|
vm_set_priv.S \
|
||||||
|
@ -159,6 +159,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
|||||||
int s,i,j;
|
int s,i,j;
|
||||||
int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs;
|
int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs;
|
||||||
struct rproc *rp;
|
struct rproc *rp;
|
||||||
|
struct rproc *replica_rp;
|
||||||
struct rprocpub *rpub;
|
struct rprocpub *rpub;
|
||||||
struct boot_image image[NR_BOOT_PROCS];
|
struct boot_image image[NR_BOOT_PROCS];
|
||||||
struct mproc mproc[NR_PROCS];
|
struct mproc mproc[NR_PROCS];
|
||||||
@ -166,6 +167,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
|||||||
struct boot_image_priv *boot_image_priv;
|
struct boot_image_priv *boot_image_priv;
|
||||||
struct boot_image_sys *boot_image_sys;
|
struct boot_image_sys *boot_image_sys;
|
||||||
struct boot_image_dev *boot_image_dev;
|
struct boot_image_dev *boot_image_dev;
|
||||||
|
message m;
|
||||||
|
int pid, replica_pid;
|
||||||
|
endpoint_t replica_endpoint;
|
||||||
|
|
||||||
/* See if we run in verbose mode. */
|
/* See if we run in verbose mode. */
|
||||||
env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);
|
env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);
|
||||||
@ -293,23 +297,23 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
|||||||
/* Get heartbeat period. */
|
/* Get heartbeat period. */
|
||||||
rpub->period = boot_image_priv->period;
|
rpub->period = boot_image_priv->period;
|
||||||
|
|
||||||
if(boot_image_priv->endpoint != RS_PROC_NR) {
|
/* Force a static priv id for system services in the boot image. */
|
||||||
/* Force a static priv id for system services in the boot image. */
|
rp->r_priv.s_id = static_priv_id(
|
||||||
rp->r_priv.s_id = static_priv_id(
|
_ENDPOINT_P(boot_image_priv->endpoint));
|
||||||
_ENDPOINT_P(boot_image_priv->endpoint));
|
|
||||||
|
|
||||||
/* Initialize privilege bitmaps and signal manager. */
|
/* Initialize privilege bitmaps and signal manager. */
|
||||||
rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */
|
rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */
|
||||||
rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* traps */
|
rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* traps */
|
||||||
memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to,
|
memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to,
|
||||||
sizeof(rp->r_priv.s_ipc_to)); /* targets */
|
sizeof(rp->r_priv.s_ipc_to)); /* targets */
|
||||||
rp->r_priv.s_sig_mgr = boot_image_priv->sig_mgr; /* sig mgr */
|
rp->r_priv.s_sig_mgr = boot_image_priv->sig_mgr; /* sig mgr */
|
||||||
|
|
||||||
/* Initialize kernel call mask bitmap from unordered set. */
|
/* Initialize kernel call mask bitmap from unordered set. */
|
||||||
fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS,
|
fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS,
|
||||||
rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);
|
rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);
|
||||||
|
|
||||||
/* Set the privilege structure. */
|
/* Set the privilege structure. */
|
||||||
|
if(boot_image_priv->endpoint != RS_PROC_NR) {
|
||||||
if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
|
if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
|
||||||
!= OK) {
|
!= OK) {
|
||||||
panic("unable to set privilege structure: %d", s);
|
panic("unable to set privilege structure: %d", s);
|
||||||
@ -474,16 +478,75 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
|||||||
if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
|
if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
|
||||||
panic("couldn't set alarm: %d", s);
|
panic("couldn't set alarm: %d", s);
|
||||||
|
|
||||||
/* Map out our own text and data. This is normally done in crtso.o
|
/* Now create a new RS instance with a private page table and let the current
|
||||||
* but RS is an exception - we don't get to talk to VM so early on.
|
* instance live update into the replica. Clone RS' own slot first.
|
||||||
* That's why we override munmap() and munmap_text() in utility.c.
|
*/
|
||||||
*
|
rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)];
|
||||||
* _minix_unmapzero() is the same code in crtso.o that normally does
|
if((s = clone_slot(rp, &replica_rp)) != OK) {
|
||||||
* it on startup. It's best that it's there as crtso.o knows exactly
|
panic("unable to clone current RS instance: %d", s);
|
||||||
* what the ranges are of the filler data.
|
}
|
||||||
*/
|
|
||||||
unmap_ok = 1;
|
/* Fork a new RS instance. */
|
||||||
_minix_unmapzero();
|
pid = srv_fork();
|
||||||
|
if(pid == -1) {
|
||||||
|
panic("unable to fork a new RS instance");
|
||||||
|
}
|
||||||
|
replica_pid = pid ? pid : getpid();
|
||||||
|
replica_endpoint = getnprocnr(replica_pid);
|
||||||
|
replica_rp->r_pid = replica_pid;
|
||||||
|
replica_rp->r_pub->endpoint = replica_endpoint;
|
||||||
|
|
||||||
|
if(pid == 0) {
|
||||||
|
/* New RS instance running. */
|
||||||
|
|
||||||
|
/* Synchronize with the old instance. */
|
||||||
|
s = sef_receive(RS_PROC_NR, &m);
|
||||||
|
if(s != OK) {
|
||||||
|
panic("sef_receive failed: %d", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Live update the old instance into the new one. */
|
||||||
|
s = update_service(&rp, &replica_rp);
|
||||||
|
if(s != OK) {
|
||||||
|
panic("unable to live update RS: %d", s);
|
||||||
|
}
|
||||||
|
cpf_reload();
|
||||||
|
|
||||||
|
/* Clean up the old RS instance, the new instance will take over. */
|
||||||
|
cleanup_service(rp);
|
||||||
|
|
||||||
|
/* Map out our own text and data. */
|
||||||
|
unmap_ok = 1;
|
||||||
|
_minix_unmapzero();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Old RS instance running. */
|
||||||
|
|
||||||
|
/* Ask VM to pin memory for the new RS instance. */
|
||||||
|
s = vm_memctl(replica_endpoint, VM_RS_MEM_PIN);
|
||||||
|
if(s != OK) {
|
||||||
|
panic("unable to pin memory for the new RS instance: %d", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up privileges for the new instance and let it run. */
|
||||||
|
set_sys_bit(replica_rp->r_priv.s_ipc_to, static_priv_id(RS_PROC_NR));
|
||||||
|
s = sys_privctl(replica_endpoint, SYS_PRIV_SET_SYS, &(replica_rp->r_priv));
|
||||||
|
if(s != OK) {
|
||||||
|
panic("unable to set privileges for the new RS instance: %d", s);
|
||||||
|
}
|
||||||
|
s = sys_privctl(replica_endpoint, SYS_PRIV_ALLOW, NULL);
|
||||||
|
if(s != OK) {
|
||||||
|
panic("unable to let the new RS instance run: %d", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Synchronize with the new instance and go to sleep. */
|
||||||
|
m.m_type = RS_INIT;
|
||||||
|
s = sendrec(replica_endpoint, &m);
|
||||||
|
if(s != OK) {
|
||||||
|
panic("sendrec failed: %d", s);
|
||||||
|
}
|
||||||
|
/* Not reachable */
|
||||||
|
}
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
@ -1435,6 +1435,11 @@ struct rproc **clone_rpp;
|
|||||||
rpub = rp->r_pub;
|
rpub = rp->r_pub;
|
||||||
clone_rpub = clone_rp->r_pub;
|
clone_rpub = clone_rp->r_pub;
|
||||||
|
|
||||||
|
/* Synch the privilege structure of the source with the kernel. */
|
||||||
|
if ((r = sys_getpriv(&(rp->r_priv), rpub->endpoint)) != OK) {
|
||||||
|
panic("unable to synch privilege structure: %d", r);
|
||||||
|
}
|
||||||
|
|
||||||
/* Shallow copy. */
|
/* Shallow copy. */
|
||||||
*clone_rp = *rp;
|
*clone_rp = *rp;
|
||||||
*clone_rpub = *rpub;
|
*clone_rpub = *rpub;
|
||||||
|
@ -44,7 +44,8 @@ PRIVATE int
|
|||||||
VM_NOTIFY_SIG, SYS_NULL_C },
|
VM_NOTIFY_SIG, SYS_NULL_C },
|
||||||
sched_vmc[] ={ VM_BASIC_CALLS, SYS_NULL_C },
|
sched_vmc[] ={ VM_BASIC_CALLS, SYS_NULL_C },
|
||||||
vfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
|
vfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
|
||||||
rs_vmc[] = { VM_BASIC_CALLS, VM_RS_SET_PRIV, VM_RS_UPDATE, SYS_NULL_C },
|
rs_vmc[] = { VM_BASIC_CALLS, VM_RS_SET_PRIV, VM_RS_UPDATE, VM_RS_MEMCTL,
|
||||||
|
SYS_NULL_C },
|
||||||
ds_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
|
ds_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
|
||||||
vm_vmc[] = { SYS_NULL_C },
|
vm_vmc[] = { SYS_NULL_C },
|
||||||
tty_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
|
tty_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
|
||||||
|
@ -70,12 +70,17 @@ SANITYCHECK(SCL_FUNCTIONS);
|
|||||||
|
|
||||||
if(vmp->vm_flags & VMF_HAS_DMA) {
|
if(vmp->vm_flags & VMF_HAS_DMA) {
|
||||||
release_dma(vmp);
|
release_dma(vmp);
|
||||||
} else {
|
} else if(vmp->vm_flags & VMF_HASPT) {
|
||||||
assert(vmp->vm_flags & VMF_HASPT);
|
|
||||||
/* Free pagetable and pages allocated by pt code. */
|
/* Free pagetable and pages allocated by pt code. */
|
||||||
SANITYCHECK(SCL_DETAIL);
|
SANITYCHECK(SCL_DETAIL);
|
||||||
free_proc(vmp);
|
free_proc(vmp);
|
||||||
SANITYCHECK(SCL_DETAIL);
|
SANITYCHECK(SCL_DETAIL);
|
||||||
|
} else {
|
||||||
|
/* Free the data and stack segments. */
|
||||||
|
free_mem(vmp->vm_arch.vm_seg[D].mem_phys,
|
||||||
|
vmp->vm_arch.vm_seg[S].mem_vir +
|
||||||
|
vmp->vm_arch.vm_seg[S].mem_len -
|
||||||
|
vmp->vm_arch.vm_seg[D].mem_vir);
|
||||||
}
|
}
|
||||||
SANITYCHECK(SCL_DETAIL);
|
SANITYCHECK(SCL_DETAIL);
|
||||||
|
|
||||||
|
@ -344,6 +344,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
|||||||
/* Calls from RS */
|
/* Calls from RS */
|
||||||
CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv);
|
CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv);
|
||||||
CALLMAP(VM_RS_UPDATE, do_rs_update);
|
CALLMAP(VM_RS_UPDATE, do_rs_update);
|
||||||
|
CALLMAP(VM_RS_MEMCTL, do_rs_memctl);
|
||||||
|
|
||||||
/* Generic calls. */
|
/* Generic calls. */
|
||||||
CALLMAP(VM_REMAP, do_remap);
|
CALLMAP(VM_REMAP, do_remap);
|
||||||
|
@ -141,6 +141,7 @@ _PROTOTYPE(int map_proc_copy,(struct vmproc *dst, struct vmproc *src));
|
|||||||
_PROTOTYPE(struct vir_region *map_lookup,(struct vmproc *vmp, vir_bytes addr));
|
_PROTOTYPE(struct vir_region *map_lookup,(struct vmproc *vmp, vir_bytes addr));
|
||||||
_PROTOTYPE(int map_pf,(struct vmproc *vmp,
|
_PROTOTYPE(int map_pf,(struct vmproc *vmp,
|
||||||
struct vir_region *region, vir_bytes offset, int write));
|
struct vir_region *region, vir_bytes offset, int write));
|
||||||
|
_PROTOTYPE(int map_pin_memory,(struct vmproc *vmp));
|
||||||
_PROTOTYPE(int map_handle_memory,(struct vmproc *vmp,
|
_PROTOTYPE(int map_handle_memory,(struct vmproc *vmp,
|
||||||
struct vir_region *region, vir_bytes offset, vir_bytes len, int write));
|
struct vir_region *region, vir_bytes offset, vir_bytes len, int write));
|
||||||
_PROTOTYPE(void map_printmap, (struct vmproc *vmp));
|
_PROTOTYPE(void map_printmap, (struct vmproc *vmp));
|
||||||
@ -185,6 +186,7 @@ _PROTOTYPE( vir_bytes arch_addrok, (struct vmproc *vmp, vir_bytes addr));
|
|||||||
/* rs.c */
|
/* rs.c */
|
||||||
_PROTOTYPE(int do_rs_set_priv, (message *m));
|
_PROTOTYPE(int do_rs_set_priv, (message *m));
|
||||||
_PROTOTYPE(int do_rs_update, (message *m));
|
_PROTOTYPE(int do_rs_update, (message *m));
|
||||||
|
_PROTOTYPE(int do_rs_memctl, (message *m));
|
||||||
|
|
||||||
/* queryexit.c */
|
/* queryexit.c */
|
||||||
_PROTOTYPE(int do_query_exit, (message *m));
|
_PROTOTYPE(int do_query_exit, (message *m));
|
||||||
|
@ -1116,6 +1116,34 @@ int write;
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* map_pin_memory *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC int map_pin_memory(struct vmproc *vmp)
|
||||||
|
{
|
||||||
|
struct vir_region *vr;
|
||||||
|
int offset, r;
|
||||||
|
|
||||||
|
/* Scan all memory regions. */
|
||||||
|
for(vr = vmp->vm_regions; vr; vr = vr->next) {
|
||||||
|
vir_bytes offset;
|
||||||
|
/* Skip regions that can't pagefault. */
|
||||||
|
if((vr->flags & VR_NOPF) || (vr->flags & VR_SHARED)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Map other regions. */
|
||||||
|
for(offset=0;offset<vr->length;offset += VM_PAGE_SIZE) {
|
||||||
|
if((r=map_pf(vmp, vr, offset, 1 /* write */))
|
||||||
|
!= OK) {
|
||||||
|
printf("VM: map_pf failed\n");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* map_handle_memory *
|
* map_handle_memory *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
@ -38,7 +38,7 @@ PUBLIC int do_rs_set_priv(message *m)
|
|||||||
nr = m->VM_RS_NR;
|
nr = m->VM_RS_NR;
|
||||||
|
|
||||||
if ((r = vm_isokendpt(nr, &n)) != OK) {
|
if ((r = vm_isokendpt(nr, &n)) != OK) {
|
||||||
printf("do_rs_set_priv: message from strange source %d\n", nr);
|
printf("do_rs_set_priv: bad endpoint %d\n", nr);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ PUBLIC int do_rs_set_priv(message *m)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int do_rs_update(message *m_ptr)
|
PUBLIC int do_rs_update(message *m_ptr)
|
||||||
{
|
{
|
||||||
endpoint_t src_e, dst_e;
|
endpoint_t src_e, dst_e, reply_e;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
src_e = m_ptr->VM_RS_SRC_ENDPT;
|
src_e = m_ptr->VM_RS_SRC_ENDPT;
|
||||||
@ -74,7 +74,52 @@ PUBLIC int do_rs_update(message *m_ptr)
|
|||||||
|
|
||||||
/* Do the update in VM now. */
|
/* Do the update in VM now. */
|
||||||
r = swap_proc(src_e, dst_e);
|
r = swap_proc(src_e, dst_e);
|
||||||
|
if(r != OK) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
/* Reply, update-aware. */
|
||||||
|
reply_e = m_ptr->m_source;
|
||||||
|
if(reply_e == src_e) reply_e = dst_e;
|
||||||
|
if(reply_e == dst_e) reply_e = src_e;
|
||||||
|
m_ptr->m_type = OK;
|
||||||
|
r = send(reply_e, m_ptr);
|
||||||
|
if(r != OK) {
|
||||||
|
panic("send() error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUSPEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_rs_memctl *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC int do_rs_memctl(message *m_ptr)
|
||||||
|
{
|
||||||
|
endpoint_t ep;
|
||||||
|
int req, r, proc_nr;
|
||||||
|
struct vmproc *vmp;
|
||||||
|
|
||||||
|
ep = m_ptr->VM_RS_CTL_ENDPT;
|
||||||
|
req = m_ptr->VM_RS_CTL_REQ;
|
||||||
|
|
||||||
|
/* Lookup endpoint. */
|
||||||
|
if ((r = vm_isokendpt(ep, &proc_nr)) != OK) {
|
||||||
|
printf("do_rs_memctl: bad endpoint %d\n", ep);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
vmp = &vmproc[proc_nr];
|
||||||
|
|
||||||
|
/* Process request. */
|
||||||
|
switch(req)
|
||||||
|
{
|
||||||
|
case VM_RS_MEM_PIN:
|
||||||
|
r = map_pin_memory(vmp);
|
||||||
|
return r;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("do_rs_memctl: bad request %d\n", req);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,10 +286,10 @@ PUBLIC int swap_proc(endpoint_t src_e, endpoint_t dst_e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust page tables. */
|
/* Adjust page tables. */
|
||||||
assert(src_vmp->vm_flags & VMF_HASPT);
|
if(src_vmp->vm_flags & VMF_HASPT)
|
||||||
assert(dst_vmp->vm_flags & VMF_HASPT);
|
pt_bind(&src_vmp->vm_pt, src_vmp);
|
||||||
pt_bind(&src_vmp->vm_pt, src_vmp);
|
if(dst_vmp->vm_flags & VMF_HASPT)
|
||||||
pt_bind(&dst_vmp->vm_pt, dst_vmp);
|
pt_bind(&dst_vmp->vm_pt, dst_vmp);
|
||||||
if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) {
|
if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) {
|
||||||
panic("swap_proc: VMCTL_FLUSHTLB failed: %d", r);
|
panic("swap_proc: VMCTL_FLUSHTLB failed: %d", r);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user