Merge of Wu's GSOC 09 branch (src.20090525.r4372.wu)

Main changes:
- COW optimization for safecopy.
- safemap, a grant-based interface for sharing memory regions between processes.
- Integration with safemap and complete rework of DS, supporting new data types
  natively (labels, memory ranges, memory mapped ranges).
- For further information:
  http://wiki.minix3.org/en/SummerOfCode2009/MemoryGrants

Additional changes not included in the original Wu's branch:
- Fixed unhandled case in VM when using COW optimization for safecopy in case
  of a block that has already been shared as SMAP.
- Better interface and naming scheme for sys_saferevmap and ds_retrieve_map
  calls.
- Better input checking in syslib: check for page alignment when creating
  memory mapping grants.
- DS notifies subscribers when an entry is deleted.
- Documented the behavior of indirect grants in case of memory mapping.
- Test suite in /usr/src/test/safeperf|safecopy|safemap|ds/* reworked
  and extended.
- Minor fixes and general cleanup.
- TO-DO: Grant ids should be generated and managed the way endpoints are to make
sure grant slots are never misreused.
This commit is contained in:
Cristiano Giuffrida
2010-01-14 15:24:16 +00:00
parent da3b64d8bc
commit c5b309ff07
99 changed files with 3594 additions and 851 deletions

View File

@@ -6,10 +6,10 @@ all-gnu:
makefiles: Makefile
Makedepend-ack Makedepend-gnu:
sh generate.sh . obj-ack/ obj-gnu
sh ./generate.sh . obj-ack obj-gnu
Makefile: Makefile.in Makedepend-ack Makedepend-gnu
sh generate.sh . obj-ack/ obj-gnu
sh ./generate.sh . obj-ack obj-gnu
@echo
@echo *Attention*
@echo Makefile is regenerated... rerun command to see changes
@@ -17,47 +17,47 @@ Makefile: Makefile.in Makedepend-ack Makedepend-gnu
@echo
all-ack: makefiles
mkdir -p obj-ack//./ansi
mkdir -p obj-ack/./ansi
cd ansi && $(MAKE) $@
mkdir -p obj-ack//./curses
mkdir -p obj-ack/./curses
cd curses && $(MAKE) $@
mkdir -p obj-ack//./dummy
mkdir -p obj-ack/./dummy
cd dummy && $(MAKE) $@
mkdir -p obj-ack//./editline
mkdir -p obj-ack/./editline
cd editline && $(MAKE) $@
mkdir -p obj-ack//./end
mkdir -p obj-ack/./end
cd end && $(MAKE) $@
mkdir -p obj-ack//./ip
mkdir -p obj-ack/./ip
cd ip && $(MAKE) $@
mkdir -p obj-ack//./math
mkdir -p obj-ack/./math
cd math && $(MAKE) $@
mkdir -p obj-ack//./other
mkdir -p obj-ack/./other
cd other && $(MAKE) $@
mkdir -p obj-ack//./posix
mkdir -p obj-ack/./posix
cd posix && $(MAKE) $@
mkdir -p obj-ack//./regex
mkdir -p obj-ack/./regex
cd regex && $(MAKE) $@
mkdir -p obj-ack//./stdio
mkdir -p obj-ack/./stdio
cd stdio && $(MAKE) $@
mkdir -p obj-ack//./stdtime
mkdir -p obj-ack/./stdtime
cd stdtime && $(MAKE) $@
mkdir -p obj-ack//./syscall
mkdir -p obj-ack/./syscall
cd syscall && $(MAKE) $@
mkdir -p obj-ack//./syslib
mkdir -p obj-ack/./syslib
cd syslib && $(MAKE) $@
mkdir -p obj-ack//./util
mkdir -p obj-ack/./util
cd util && $(MAKE) $@
mkdir -p obj-ack//./sysutil
mkdir -p obj-ack/./sysutil
cd sysutil && $(MAKE) $@
mkdir -p obj-ack//./sysvipc
mkdir -p obj-ack/./sysvipc
cd sysvipc && $(MAKE) $@
mkdir -p obj-ack//./timers
mkdir -p obj-ack/./timers
cd timers && $(MAKE) $@
mkdir -p obj-ack//./i386
mkdir -p obj-ack/./i386
cd i386 && $(MAKE) $@
mkdir -p obj-ack//./ack
mkdir -p obj-ack/./ack
cd ack && $(MAKE) $@
mkdir -p obj-ack//./gnu
mkdir -p obj-ack/./gnu
cd gnu && $(MAKE) $@
all-gnu: makefiles
@@ -150,56 +150,56 @@ makefiles: ack/Makefile
makefiles: gnu/Makefile
ansi/Makefile: ansi/Makefile.in
cd ansi && sh ../generate.sh ./ansi ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd ansi && sh .././generate.sh ./ansi ../obj-ack ../obj-gnu && $(MAKE) makefiles
curses/Makefile: curses/Makefile.in
cd curses && sh ../generate.sh ./curses ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd curses && sh .././generate.sh ./curses ../obj-ack ../obj-gnu && $(MAKE) makefiles
dummy/Makefile: dummy/Makefile.in
cd dummy && sh ../generate.sh ./dummy ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd dummy && sh .././generate.sh ./dummy ../obj-ack ../obj-gnu && $(MAKE) makefiles
editline/Makefile: editline/Makefile.in
cd editline && sh ../generate.sh ./editline ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd editline && sh .././generate.sh ./editline ../obj-ack ../obj-gnu && $(MAKE) makefiles
end/Makefile: end/Makefile.in
cd end && sh ../generate.sh ./end ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd end && sh .././generate.sh ./end ../obj-ack ../obj-gnu && $(MAKE) makefiles
ip/Makefile: ip/Makefile.in
cd ip && sh ../generate.sh ./ip ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd ip && sh .././generate.sh ./ip ../obj-ack ../obj-gnu && $(MAKE) makefiles
math/Makefile: math/Makefile.in
cd math && sh ../generate.sh ./math ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd math && sh .././generate.sh ./math ../obj-ack ../obj-gnu && $(MAKE) makefiles
other/Makefile: other/Makefile.in
cd other && sh ../generate.sh ./other ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd other && sh .././generate.sh ./other ../obj-ack ../obj-gnu && $(MAKE) makefiles
posix/Makefile: posix/Makefile.in
cd posix && sh ../generate.sh ./posix ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd posix && sh .././generate.sh ./posix ../obj-ack ../obj-gnu && $(MAKE) makefiles
regex/Makefile: regex/Makefile.in
cd regex && sh ../generate.sh ./regex ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd regex && sh .././generate.sh ./regex ../obj-ack ../obj-gnu && $(MAKE) makefiles
stdio/Makefile: stdio/Makefile.in
cd stdio && sh ../generate.sh ./stdio ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd stdio && sh .././generate.sh ./stdio ../obj-ack ../obj-gnu && $(MAKE) makefiles
stdtime/Makefile: stdtime/Makefile.in
cd stdtime && sh ../generate.sh ./stdtime ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd stdtime && sh .././generate.sh ./stdtime ../obj-ack ../obj-gnu && $(MAKE) makefiles
syscall/Makefile: syscall/Makefile.in
cd syscall && sh ../generate.sh ./syscall ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd syscall && sh .././generate.sh ./syscall ../obj-ack ../obj-gnu && $(MAKE) makefiles
syslib/Makefile: syslib/Makefile.in
cd syslib && sh ../generate.sh ./syslib ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd syslib && sh .././generate.sh ./syslib ../obj-ack ../obj-gnu && $(MAKE) makefiles
util/Makefile: util/Makefile.in
cd util && sh ../generate.sh ./util ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd util && sh .././generate.sh ./util ../obj-ack ../obj-gnu && $(MAKE) makefiles
sysutil/Makefile: sysutil/Makefile.in
cd sysutil && sh ../generate.sh ./sysutil ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd sysutil && sh .././generate.sh ./sysutil ../obj-ack ../obj-gnu && $(MAKE) makefiles
sysvipc/Makefile: sysvipc/Makefile.in
cd sysvipc && sh ../generate.sh ./sysvipc ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd sysvipc && sh .././generate.sh ./sysvipc ../obj-ack ../obj-gnu && $(MAKE) makefiles
timers/Makefile: timers/Makefile.in
cd timers && sh ../generate.sh ./timers ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd timers && sh .././generate.sh ./timers ../obj-ack ../obj-gnu && $(MAKE) makefiles
i386/Makefile: i386/Makefile.in
cd i386 && sh ../generate.sh ./i386 ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd i386 && sh .././generate.sh ./i386 ../obj-ack ../obj-gnu && $(MAKE) makefiles
ack/Makefile: ack/Makefile.in
cd ack && sh ../generate.sh ./ack ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd ack && sh .././generate.sh ./ack ../obj-ack ../obj-gnu && $(MAKE) makefiles
gnu/Makefile: gnu/Makefile.in
cd gnu && sh ../generate.sh ./gnu ../obj-ack/ ../obj-gnu && $(MAKE) makefiles
cd gnu && sh .././generate.sh ./gnu ../obj-ack ../obj-gnu && $(MAKE) makefiles
clean::
rm -f obj-ack//./*
rm -f obj-ack/./*
rm -f obj-gnu/./*
install: install-ack
install-ack: all-ack
cp obj-ack//*.[ao] /usr/lib/i386
cp obj-ack/*.[ao] /usr/lib/i386
install-gnu: all-gnu
cp obj-gnu/*.[ao] /usr/gnu/lib

View File

@@ -52,6 +52,7 @@ libsys_FILES=" \
sys_readbios.c \
sys_runctl.c \
sys_safecopy.c \
sys_safemap.c \
sys_sysctl.c \
sys_vsafecopy.c \
sys_profbuf.c \

View File

@@ -4,260 +4,257 @@
#include "syslib.h"
#define GRANTBAD -1001
static message m;
int
ds_subscribe(ds_name_regexp, type, flags)
char *ds_name_regexp;
int type;
int flags;
PRIVATE int do_invoke_ds(int type, const char *ds_name)
{
int r;
message m;
cp_grant_id_t g;
size_t len;
cp_grant_id_t g_key;
size_t len_key;
int access, r;
len = strlen(ds_name_regexp)+1;
g = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_name_regexp, len, CPF_READ);
if(type == DS_CHECK || type == DS_RETRIEVE_LABEL) {
len_key = DS_MAX_KEYLEN;
access = CPF_WRITE;
} else {
len_key = strlen(ds_name)+1;
access = CPF_READ;
}
if(!GRANT_VALID(g))
return GRANTBAD;
/* Grant for key. */
g_key = cpf_grant_direct(DS_PROC_NR, (vir_bytes) ds_name,
len_key, access);
if(!GRANT_VALID(g_key))
return errno;
flags &= DS_INITIAL;
m.DS_KEY_GRANT = g_key;
m.DS_KEY_LEN = len_key;
m.DS_KEY_GRANT = (char *) g;
m.DS_KEY_LEN = len;
m.DS_FLAGS = flags | (type & DS_TYPE_MASK);
r = _taskcall(DS_PROC_NR, DS_SUBSCRIBE, &m);
cpf_revoke(g);
r = _taskcall(DS_PROC_NR, type, &m);
cpf_revoke(g_key);
return r;
}
int ds_publish_u32(ds_name, value)
char *ds_name;
u32_t value;
int ds_publish_label(const char *ds_name, u32_t value, int flags)
{
int r;
message m;
cp_grant_id_t g;
size_t len;
len = strlen(ds_name)+1;
g = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_name, len, CPF_READ);
if(!GRANT_VALID(g))
return GRANTBAD;
m.DS_KEY_GRANT = (char *) g;
m.DS_KEY_LEN = len;
m.DS_FLAGS = DS_TYPE_U32;
m.DS_VAL = value;
m.DS_VAL_LEN = sizeof(value);
m.DS_FLAGS = DSF_TYPE_LABEL | flags;
return do_invoke_ds(DS_PUBLISH, ds_name);
}
r = _taskcall(DS_PROC_NR, DS_PUBLISH, &m);
int ds_publish_u32(const char *ds_name, u32_t value, int flags)
{
m.DS_VAL = value;
m.DS_FLAGS = DSF_TYPE_U32 | flags;
return do_invoke_ds(DS_PUBLISH, ds_name);
}
cpf_revoke(g);
int ds_publish_str(const char *ds_name, char *value, int flags)
{
if(strlen(value) >= DS_MAX_STRLEN)
return EINVAL;
strcpy((char *)(&m.DS_STRING), value);
m.DS_FLAGS = DSF_TYPE_STR | flags;
return do_invoke_ds(DS_PUBLISH, ds_name);
}
int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags)
{
cp_grant_id_t gid;
int r;
/* Grant for memory range. */
gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, length, CPF_READ);
if(!GRANT_VALID(gid))
return errno;
m.DS_VAL = gid;
m.DS_VAL_LEN = length;
m.DS_FLAGS = DSF_TYPE_MEM | flags;
r = do_invoke_ds(DS_PUBLISH, ds_name);
cpf_revoke(gid);
return r;
}
int ds_publish_str(ds_name, value)
char *ds_name;
char *value;
int ds_publish_map(const char *ds_name, void *vaddr, size_t length, int flags)
{
cp_grant_id_t gid;
int r;
message m;
cp_grant_id_t g_key, g_str;
size_t len_key, len_str;
/* Grant for key. */
len_key = strlen(ds_name)+1;
g_key = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_name, len_key, CPF_READ);
if(!GRANT_VALID(g_key))
return GRANTBAD;
if(((vir_bytes)vaddr % CLICK_SIZE != 0) || (length % CLICK_SIZE != 0))
return EINVAL;
/* Grant for value. */
len_str = strlen(value)+1;
g_str = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) value, len_str, CPF_READ);
/* Grant for mapped memory range. */
gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, length,
CPF_READ | CPF_MAP);
if(!GRANT_VALID(gid))
return errno;
if(!GRANT_VALID(g_str)) {
cpf_revoke(g_key);
return GRANTBAD;
}
m.DS_VAL = gid;
m.DS_VAL_LEN = length;
m.DS_FLAGS = DSF_TYPE_MAP | flags;
m.DS_KEY_GRANT = (char *) g_key;
m.DS_KEY_LEN = len_key;
m.DS_FLAGS = DS_TYPE_STR;
m.DS_VAL = g_str;
m.DS_VAL_LEN = len_str;
r = _taskcall(DS_PROC_NR, DS_PUBLISH, &m);
cpf_revoke(g_key);
cpf_revoke(g_str);
r = do_invoke_ds(DS_PUBLISH, ds_name);
cpf_revoke(gid);
return r;
}
int ds_retrieve_u32(ds_name, value)
char *ds_name;
u32_t *value;
int ds_snapshot_map(const char *ds_name, int *nr_snapshot)
{
int r;
message m;
cp_grant_id_t g_key;
size_t len_key;
/* Grant for key. */
len_key = strlen(ds_name)+1;
g_key = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_name, len_key, CPF_READ);
if(!GRANT_VALID(g_key))
return GRANTBAD;
/* Do request. */
m.DS_KEY_GRANT = (char *) g_key;
m.DS_KEY_LEN = len_key;
m.DS_FLAGS = DS_TYPE_U32;
r = _taskcall(DS_PROC_NR, DS_RETRIEVE, &m);
cpf_revoke(g_key);
if(r == OK) {
/* Assign u32 value. */
*value = m.DS_VAL;
}
r = do_invoke_ds(DS_SNAPSHOT, ds_name);
*nr_snapshot = m.DS_NR_SNAPSHOT;
return r;
}
int ds_retrieve_str(ds_name, value, len_str)
char *ds_name;
char *value;
size_t len_str;
int ds_retrieve_label_name(char *ds_name, u32_t num)
{
int r;
message m;
cp_grant_id_t g_key, g_str;
size_t len_key;
/* Grant for key. */
len_key = strlen(ds_name)+1;
g_key = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_name, len_key, CPF_READ);
if(!GRANT_VALID(g_key))
return GRANTBAD;
/* Grant for value. */
g_str = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) value, len_str, CPF_WRITE);
if(!GRANT_VALID(g_str)) {
cpf_revoke(g_key);
return GRANTBAD;
}
/* Do request. */
m.DS_KEY_GRANT = (char *) g_key;
m.DS_KEY_LEN = len_key;
m.DS_FLAGS = DS_TYPE_STR;
m.DS_VAL = g_str;
m.DS_VAL_LEN = len_str;
r = _taskcall(DS_PROC_NR, DS_RETRIEVE, &m);
cpf_revoke(g_key);
cpf_revoke(g_str);
m.DS_VAL = num;
r = do_invoke_ds(DS_RETRIEVE_LABEL, ds_name);
return r;
}
int ds_check_str(ds_key, len_key, value, len_str)
char *ds_key;
size_t len_key;
char *value;
size_t len_str;
int ds_retrieve_label_num(const char *ds_name, u32_t *value)
{
int r;
message m;
cp_grant_id_t g_key, g_str;
if(len_key < 1 || len_str < 1) return -1002;
/* Grant for key. */
g_key = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_key, len_key, CPF_WRITE);
if(!GRANT_VALID(g_key))
return GRANTBAD;
/* Grant for value. */
g_str = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) value, len_str, CPF_WRITE);
if(!GRANT_VALID(g_str)) {
cpf_revoke(g_key);
return GRANTBAD;
}
/* Do request. */
m.DS_KEY_GRANT = (char *) g_key;
m.DS_KEY_LEN = len_key;
m.DS_FLAGS = DS_TYPE_STR;
m.DS_VAL = g_str;
m.DS_VAL_LEN = len_str;
r = _taskcall(DS_PROC_NR, DS_CHECK, &m);
cpf_revoke(g_key);
cpf_revoke(g_str);
ds_key[len_key-1] = '\0';
value[len_str-1] = '\0';
return r;
}
int ds_check_u32(ds_key, len_key, value)
char *ds_key;
size_t len_key;
u32_t *value;
{
int r;
message m;
cp_grant_id_t g_key;
if(len_key < 1) return -1;
/* Grant for key. */
g_key = cpf_grant_direct(DS_PROC_NR,
(vir_bytes) ds_key, len_key, CPF_WRITE);
if(!GRANT_VALID(g_key))
return GRANTBAD;
/* Do request. */
m.DS_KEY_GRANT = (char *) g_key;
m.DS_KEY_LEN = len_key;
m.DS_FLAGS = DS_TYPE_U32;
r = _taskcall(DS_PROC_NR, DS_CHECK, &m);
cpf_revoke(g_key);
ds_key[len_key-1] = '\0';
/* Assign u32 value. */
m.DS_FLAGS = DSF_TYPE_LABEL;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
*value = m.DS_VAL;
return r;
}
int ds_retrieve_u32(const char *ds_name, u32_t *value)
{
int r;
m.DS_FLAGS = DSF_TYPE_U32;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
*value = m.DS_VAL;
return r;
}
int ds_retrieve_str(const char *ds_name, char *value, size_t len_str)
{
int r;
m.DS_FLAGS = DSF_TYPE_STR;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
strncpy(value, (char *)(&m.DS_STRING), DS_MAX_STRLEN);
value[DS_MAX_STRLEN - 1] = '\0';
return r;
}
int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length)
{
cp_grant_id_t gid;
int r;
/* Grant for memory range. */
gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, *length, CPF_WRITE);
if(!GRANT_VALID(gid))
return errno;
m.DS_VAL = gid;
m.DS_VAL_LEN = *length;
m.DS_FLAGS = DSF_TYPE_MEM;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
*length = m.DS_VAL_LEN;
cpf_revoke(gid);
return r;
}
int ds_retrieve_map(const char *ds_name, char *vaddr, size_t *length,
int nr_snapshot, int flags)
{
cp_grant_id_t gid;
int r;
/* Map a mapped memory range. */
if(flags & DSMF_MAP_MAPPED) {
/* Request DS to grant. */
m.DS_FLAGS = DSF_TYPE_MAP | DSMF_MAP_MAPPED;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
if(r != OK)
return r;
/* Do the safemap. */
if(*length > m.DS_VAL_LEN)
*length = m.DS_VAL_LEN;
*length = (size_t) CLICK_FLOOR(*length);
r = sys_safemap(DS_PROC_NR, m.DS_VAL, 0,
(vir_bytes)vaddr, *length, D, 0);
/* Copy mapped memory range or a snapshot. */
} else if(flags & (DSMF_COPY_MAPPED|DSMF_COPY_SNAPSHOT)) {
/* Grant for memory range first. */
gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr,
*length, CPF_WRITE);
if(!GRANT_VALID(gid))
return errno;
m.DS_VAL = gid;
m.DS_VAL_LEN = *length;
if(flags & DSMF_COPY_MAPPED) {
m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_MAPPED;
}
else {
m.DS_NR_SNAPSHOT = nr_snapshot;
m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_SNAPSHOT;
}
r = do_invoke_ds(DS_RETRIEVE, ds_name);
*length = m.DS_VAL_LEN;
cpf_revoke(gid);
}
else {
return EINVAL;
}
return r;
}
int ds_delete_u32(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_U32;
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_delete_str(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_STR;
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_delete_mem(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_MEM;
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_delete_map(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_MAP;
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_delete_label(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_LABEL;
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_subscribe(const char *regexp, int flags)
{
m.DS_FLAGS = flags;
return do_invoke_ds(DS_SUBSCRIBE, regexp);
}
int ds_check(char *ds_key, int *type)
{
int r;
r = do_invoke_ds(DS_CHECK, ds_key);
*type = m.DS_FLAGS;
return r;
}

View File

@@ -21,7 +21,7 @@ endpoint_t proc_ep;
if (pci_procnr == ANY)
{
r= ds_retrieve_u32("pci", &u32);
r= ds_retrieve_label_num("pci", &u32);
if (r != 0)
{
panic("syslib/" __FILE__,

View File

@@ -22,9 +22,9 @@ char *name;
size_t len;
message m;
r= ds_retrieve_u32("pci", &u32);
r= ds_retrieve_label_num("pci", &u32);
if (r != 0)
panic("syslib/" __FILE__, "pci_init1: ds_retrieve_u32 failed for 'pci'", r);
panic("syslib/" __FILE__, "pci_init1: ds_retrieve_label_num failed for 'pci'", r);
pci_procnr= u32;
m.m_type= BUSC_PCI_INIT;

View File

@@ -22,11 +22,11 @@ struct rs_pci *rs_pci;
if (pci_procnr == ANY)
{
r= ds_retrieve_u32("pci", &u32);
r= ds_retrieve_label_num("pci", &u32);
if (r != 0)
{
panic("syslib/" __FILE__,
"pci_set_acl: ds_retrieve_u32 failed for 'pci'",
"pci_set_acl: ds_retrieve_label_num failed for 'pci'",
r);
}
pci_procnr = u32;

View File

@@ -16,7 +16,7 @@
#include <string.h>
#define ACCESS_CHECK(a) { \
if((a) & ~(CPF_READ|CPF_WRITE)) { \
if((a) & ~(CPF_READ|CPF_WRITE|CPF_MAP)) { \
errno = EINVAL; \
return -1; \
} \
@@ -37,6 +37,13 @@
} \
}
#define CLICK_ALIGNMENT_CHECK(addr, bytes) { \
if(((vir_bytes)(addr) % CLICK_SIZE != 0) \
|| ((vir_bytes)(bytes) % CLICK_SIZE != 0)) { \
return EINVAL; \
} \
}
#define NR_STATIC_GRANTS 2
PRIVATE cp_grant_t static_grants[NR_STATIC_GRANTS];
PRIVATE cp_grant_t *grants = NULL;
@@ -206,8 +213,16 @@ PUBLIC int
cpf_revoke(cp_grant_id_t g)
{
/* Revoke previously granted access, identified by grant id. */
int r;
GID_CHECK_USED(g);
/* If this grant is for memory mapping, revoke the mapping first. */
if(grants[g].cp_flags & CPF_MAP) {
r = sys_saferevmap_gid(g);
if(r != 0)
return r;
}
/* Make grant invalid by setting flags to 0, clearing CPF_USED.
* This invalidates the grant.
*/
@@ -262,6 +277,12 @@ int access;
GID_CHECK(gid);
ACCESS_CHECK(access);
/* Check click alignment in case of memory mapping grant. */
if(access & CPF_MAP) {
CLICK_ALIGNMENT_CHECK(addr, bytes);
}
/* Fill in new slot data. */
grants[gid].cp_flags = access | CPF_DIRECT | CPF_USED | CPF_VALID;
grants[gid].cp_u.cp_direct.cp_who_to = who;
grants[gid].cp_u.cp_direct.cp_start = addr;
@@ -298,6 +319,11 @@ int access;
GID_CHECK(gid);
ACCESS_CHECK(access);
/* Check click alignment in case of memory mapping grant. */
if(access & CPF_MAP) {
CLICK_ALIGNMENT_CHECK(addr, bytes);
}
/* Fill in new slot data. */
grants[gid].cp_flags = CPF_USED | CPF_MAGIC | CPF_VALID | access;
grants[gid].cp_u.cp_magic.cp_who_to = who_to;

72
lib/syslib/sys_safemap.c Normal file
View File

@@ -0,0 +1,72 @@
#include "syslib.h"
#include <minix/safecopies.h>
/*===========================================================================*
* sys_safemap *
*===========================================================================*/
PUBLIC int sys_safemap(endpoint_t grantor, cp_grant_id_t grant,
vir_bytes grant_offset, vir_bytes my_address,
size_t bytes, int my_seg, int writable)
{
/* Map a block of data for which the other process has previously
* granted permission.
*/
message copy_mess;
copy_mess.SMAP_EP = grantor;
copy_mess.SMAP_GID = grant;
copy_mess.SMAP_OFFSET = grant_offset;
copy_mess.SMAP_SEG = (void*) my_seg;
copy_mess.SMAP_ADDRESS = my_address;
copy_mess.SMAP_BYTES = bytes;
copy_mess.SMAP_FLAG = writable;
return(_taskcall(SYSTASK, SYS_SAFEMAP, &copy_mess));
}
/*===========================================================================*
* sys_saferevmap_gid *
*===========================================================================*/
PUBLIC int sys_saferevmap_gid(cp_grant_id_t grant)
{
/* Grantor revokes safemap by grant id. */
message copy_mess;
copy_mess.SMAP_FLAG = 1;
copy_mess.SMAP_GID = grant;
return(_taskcall(SYSTASK, SYS_SAFEREVMAP, &copy_mess));
}
/*===========================================================================*
* sys_saferevmap_addr *
*===========================================================================*/
PUBLIC int sys_saferevmap_addr(vir_bytes addr)
{
/* Grantor revokes safemap by address. */
message copy_mess;
copy_mess.SMAP_FLAG = 0;
copy_mess.SMAP_GID = addr;
return(_taskcall(SYSTASK, SYS_SAFEREVMAP, &copy_mess));
}
/*===========================================================================*
* sys_safeunmap *
*===========================================================================*/
PUBLIC int sys_safeunmap(int my_seg, vir_bytes my_address)
{
/* Requestor unmaps safemap. */
message copy_mess;
copy_mess.SMAP_SEG = (void*) my_seg;
copy_mess.SMAP_ADDRESS = my_address;
return(_taskcall(SYSTASK, SYS_SAFEUNMAP, &copy_mess));
}

View File

@@ -43,7 +43,8 @@ PUBLIC int sys_vmctl_get_cr3_i386(endpoint_t who, u32_t *cr3)
}
PUBLIC int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem,
vir_bytes *len, int *wrflag, endpoint_t *requestor)
vir_bytes *len, int *wrflag, endpoint_t *who_s, vir_bytes *mem_s,
endpoint_t *requestor)
{
message m;
int r;
@@ -51,11 +52,13 @@ PUBLIC int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem,
m.SVMCTL_WHO = SELF;
m.SVMCTL_PARAM = VMCTL_MEMREQ_GET;
r = _taskcall(SYSTASK, SYS_VMCTL, &m);
if(r == OK) {
*who = m.SVMCTL_MRG_EP;
*mem = (vir_bytes) m.SVMCTL_MRG_ADDR;
*len = m.SVMCTL_MRG_LEN;
*wrflag = m.SVMCTL_MRG_WRITE;
if(r >= 0) {
*who = m.SVMCTL_MRG_TARGET;
*mem = m.SVMCTL_MRG_ADDR;
*len = m.SVMCTL_MRG_LENGTH;
*wrflag = m.SVMCTL_MRG_FLAG;
*who_s = m.SVMCTL_MRG_EP2;
*mem_s = m.SVMCTL_MRG_ADDR2;
*requestor = (endpoint_t) m.SVMCTL_MRG_REQUESTOR;
}
return r;

View File

@@ -18,7 +18,7 @@ libsys_FILES=" \
env_panic.c \
env_prefix.c \
fkey_ctl.c \
micro_delay.c \
tsc_util.c \
report.c \
taskcall.c \
read_tsc.s \

View File

@@ -17,15 +17,15 @@
#define CALIBRATE \
if(!calibrated) { \
int r; \
if((r=micro_delay_calibrate()) != OK) \
panic(__FILE__, "micro_delay: calibrate failed\n", r); \
if((r=tsc_calibrate()) != OK) \
panic(__FILE__, "calibrate failed\n", r); \
}
static u32_t calib_tsc, Hz = 0;
static int calibrated = 0;
int
micro_delay_calibrate(void)
tsc_calibrate(void)
{
u64_t start, end, diff;
struct tms tms;
@@ -50,11 +50,11 @@ micro_delay_calibrate(void)
diff = sub64(end, start);
if(ex64hi(diff) != 0)
panic(__FILE__,
"micro_delay_calibrate: CALIBRATE_TICKS too high "
"tsc_calibrate: CALIBRATE_TICKS too high "
"for TSC frequency\n", NO_NUM);
calib_tsc = ex64lo(diff);
#if 0
printf("micro_delay_calibrate: "
printf("tsc_calibrate: "
"%lu cycles/%d ticks of %d Hz; %lu cycles/s\n",
calib_tsc, CALIBRATE_TICKS(Hz), Hz,
div64u(mul64u(calib_tsc, Hz), CALIBRATE_TICKS(Hz)));
@@ -94,3 +94,23 @@ micro_delay(u32_t micros)
return OK;
}
u32_t tsc_64_to_micros(u64_t tsc)
{
return tsc_to_micros(ex64lo(tsc), ex64hi(tsc));
}
u32_t tsc_to_micros(u32_t low, u32_t high)
{
u32_t micros;
if(high) {
return 0;
}
CALIBRATE;
micros = (div64u(mul64u(low, MICROHZ * CALIBRATE_TICKS(Hz)),
calib_tsc)/Hz);
return micros;
}