3rd fix for improper behaviour on crashing driver with safe_io_conversion
This commit is contained in:
parent
407eefe63a
commit
0323892f71
|
@ -32,10 +32,11 @@
|
||||||
|
|
||||||
#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))
|
#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))
|
||||||
|
|
||||||
FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t, int,
|
FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t,
|
||||||
cp_grant_id_t *, int *, cp_grant_id_t *, int, endpoint_t *,
|
cp_grant_id_t *, int *, cp_grant_id_t *, int, endpoint_t *,
|
||||||
void *, int *, vir_bytes, off_t *));
|
void **, int *, vir_bytes, off_t *));
|
||||||
FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *, int));
|
FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *,
|
||||||
|
int));
|
||||||
|
|
||||||
extern int dmap_size;
|
extern int dmap_size;
|
||||||
PRIVATE int dummyproc;
|
PRIVATE int dummyproc;
|
||||||
|
@ -143,10 +144,12 @@ PUBLIC void dev_status(message *m)
|
||||||
revive(endpt, st.REP_STATUS);
|
revive(endpt, st.REP_STATUS);
|
||||||
break;
|
break;
|
||||||
case DEV_IO_READY:
|
case DEV_IO_READY:
|
||||||
select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS);
|
select_notified(d, st.DEV_MINOR,
|
||||||
|
st.DEV_SEL_OPS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("FS: unrecognized reply %d to DEV_STATUS\n", st.m_type);
|
printf("FS: unrecognized reply %d to "
|
||||||
|
"DEV_STATUS\n", st.m_type);
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case DEV_NO_STATUS:
|
case DEV_NO_STATUS:
|
||||||
get_more = 0;
|
get_more = 0;
|
||||||
|
@ -160,16 +163,15 @@ PUBLIC void dev_status(message *m)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* safe_io_conversion *
|
* safe_io_conversion *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int safe_io_conversion(driver, dev, gid, op, gids, gids_size,
|
PRIVATE int safe_io_conversion(driver, gid, op, gids, gids_size,
|
||||||
io_ept, buf, vec_grants, bytes, pos)
|
io_ept, buf, vec_grants, bytes, pos)
|
||||||
endpoint_t driver;
|
endpoint_t driver;
|
||||||
int dev;
|
|
||||||
cp_grant_id_t *gid;
|
cp_grant_id_t *gid;
|
||||||
int *op;
|
int *op;
|
||||||
cp_grant_id_t *gids;
|
cp_grant_id_t *gids;
|
||||||
int gids_size;
|
int gids_size;
|
||||||
endpoint_t *io_ept;
|
endpoint_t *io_ept;
|
||||||
void *buf;
|
void **buf;
|
||||||
int *vec_grants;
|
int *vec_grants;
|
||||||
vir_bytes bytes;
|
vir_bytes bytes;
|
||||||
off_t *pos;
|
off_t *pos;
|
||||||
|
@ -177,7 +179,7 @@ off_t *pos;
|
||||||
int access = 0, size;
|
int access = 0, size;
|
||||||
int j;
|
int j;
|
||||||
iovec_t *v;
|
iovec_t *v;
|
||||||
static iovec_t new_iovec[NR_IOREQS];
|
static iovec_t new_iovec[NR_IOREQS];
|
||||||
|
|
||||||
/* Number of grants allocated in vector I/O. */
|
/* Number of grants allocated in vector I/O. */
|
||||||
*vec_grants = 0;
|
*vec_grants = 0;
|
||||||
|
@ -193,7 +195,7 @@ off_t *pos;
|
||||||
*op = *op == DEV_READ ? DEV_READ_S : DEV_WRITE_S;
|
*op = *op == DEV_READ ? DEV_READ_S : DEV_WRITE_S;
|
||||||
|
|
||||||
if((*gid=cpf_grant_magic(driver, *io_ept,
|
if((*gid=cpf_grant_magic(driver, *io_ept,
|
||||||
(vir_bytes) buf, bytes,
|
(vir_bytes) *buf, bytes,
|
||||||
*op == DEV_READ_S ? CPF_WRITE : CPF_READ)) < 0) {
|
*op == DEV_READ_S ? CPF_WRITE : CPF_READ)) < 0) {
|
||||||
panic(__FILE__,
|
panic(__FILE__,
|
||||||
"cpf_grant_magic of buffer failed\n", NO_NUM);
|
"cpf_grant_magic of buffer failed\n", NO_NUM);
|
||||||
|
@ -206,15 +208,17 @@ off_t *pos;
|
||||||
*op = *op == DEV_GATHER ? DEV_GATHER_S : DEV_SCATTER_S;
|
*op = *op == DEV_GATHER ? DEV_GATHER_S : DEV_SCATTER_S;
|
||||||
|
|
||||||
/* Grant access to my new i/o vector. */
|
/* Grant access to my new i/o vector. */
|
||||||
if((*gid = cpf_grant_direct(driver, (vir_bytes)
|
if((*gid = cpf_grant_direct(driver,
|
||||||
new_iovec, bytes * sizeof(iovec_t),
|
(vir_bytes) new_iovec, bytes * sizeof(iovec_t),
|
||||||
CPF_READ | CPF_WRITE)) < 0) {
|
CPF_READ | CPF_WRITE)) < 0) {
|
||||||
panic(__FILE__,
|
panic(__FILE__,
|
||||||
"cpf_grant_direct of vector failed", NO_NUM);
|
"cpf_grant_direct of vector failed", NO_NUM);
|
||||||
}
|
}
|
||||||
v = (iovec_t *) buf;
|
v = (iovec_t *) *buf;
|
||||||
/* Grant access to i/o buffers. */
|
/* Grant access to i/o buffers. */
|
||||||
for(j = 0; j < bytes; j++) {
|
for(j = 0; j < bytes; j++) {
|
||||||
|
if(j >= NR_IOREQS)
|
||||||
|
panic(__FILE__, "vec too big", bytes);
|
||||||
new_iovec[j].iov_addr = gids[j] =
|
new_iovec[j].iov_addr = gids[j] =
|
||||||
cpf_grant_direct(driver, (vir_bytes)
|
cpf_grant_direct(driver, (vir_bytes)
|
||||||
v[j].iov_addr, v[j].iov_size,
|
v[j].iov_addr, v[j].iov_size,
|
||||||
|
@ -226,6 +230,9 @@ off_t *pos;
|
||||||
new_iovec[j].iov_size = v[j].iov_size;
|
new_iovec[j].iov_size = v[j].iov_size;
|
||||||
(*vec_grants)++;
|
(*vec_grants)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set user's vector to the new one. */
|
||||||
|
*buf = new_iovec;
|
||||||
break;
|
break;
|
||||||
case DEV_IOCTL:
|
case DEV_IOCTL:
|
||||||
*pos = *io_ept; /* Old endpoint in POSITION field. */
|
*pos = *io_ept; /* Old endpoint in POSITION field. */
|
||||||
|
@ -238,7 +245,7 @@ off_t *pos;
|
||||||
* order to disambiguate requests with DEV_IOCTL_S.
|
* order to disambiguate requests with DEV_IOCTL_S.
|
||||||
*/
|
*/
|
||||||
if((*gid=cpf_grant_magic(driver, *io_ept,
|
if((*gid=cpf_grant_magic(driver, *io_ept,
|
||||||
(vir_bytes) buf, size, access)) < 0) {
|
(vir_bytes) *buf, size, access)) < 0) {
|
||||||
panic(__FILE__,
|
panic(__FILE__,
|
||||||
"cpf_grant_magic failed (ioctl)\n",
|
"cpf_grant_magic failed (ioctl)\n",
|
||||||
NO_NUM);
|
NO_NUM);
|
||||||
|
@ -293,13 +300,21 @@ int bytes; /* how many bytes to transfer */
|
||||||
struct dmap *dp;
|
struct dmap *dp;
|
||||||
int r, safe;
|
int r, safe;
|
||||||
message m;
|
message m;
|
||||||
|
iovec_t *v;
|
||||||
|
cp_grant_id_t gid = GRANT_INVALID;
|
||||||
|
int vec_grants;
|
||||||
|
|
||||||
/* Determine task dmap. */
|
/* Determine task dmap. */
|
||||||
dp = &dmap[(dev >> MAJOR) & BYTE];
|
dp = &dmap[(dev >> MAJOR) & BYTE];
|
||||||
|
|
||||||
|
/* The io vector copying relies on this I/O being for FS itself. */
|
||||||
|
if(proc_e != FS_PROC_NR)
|
||||||
|
panic(__FILE__, "doing dev_bio for non-self", proc_e);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int op_used;
|
int op_used;
|
||||||
|
void *buf_used;
|
||||||
static cp_grant_id_t gids[NR_IOREQS];
|
static cp_grant_id_t gids[NR_IOREQS];
|
||||||
cp_grant_id_t gid = GRANT_INVALID;
|
cp_grant_id_t gid = GRANT_INVALID;
|
||||||
int vec_grants;
|
int vec_grants;
|
||||||
|
@ -311,17 +326,19 @@ int bytes; /* how many bytes to transfer */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* By default, these are right. */
|
/* By default, these are right. */
|
||||||
m.IO_ENDPT = proc_e;
|
m.IO_ENDPT = proc_e;
|
||||||
m.ADDRESS = buf;
|
m.ADDRESS = buf;
|
||||||
|
buf_used = buf;
|
||||||
|
|
||||||
/* Convert parameters to 'safe mode'. */
|
/* Convert parameters to 'safe mode'. */
|
||||||
op_used = op;
|
op_used = op;
|
||||||
safe = safe_io_conversion(dp->dmap_driver, dev, &gid,
|
safe = safe_io_conversion(dp->dmap_driver, &gid,
|
||||||
&op_used, gids, NR_IOREQS, &m.IO_ENDPT, buf,
|
&op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used,
|
||||||
&vec_grants, bytes, &pos);
|
&vec_grants, bytes, &pos);
|
||||||
|
|
||||||
/* Set up rest of the message. */
|
/* Set up rest of the message. */
|
||||||
if(safe) m.IO_GRANT = (char *) gid;
|
if(safe) m.IO_GRANT = (char *) gid;
|
||||||
|
|
||||||
m.m_type = op_used;
|
m.m_type = op_used;
|
||||||
m.DEVICE = (dev >> MINOR) & BYTE;
|
m.DEVICE = (dev >> MINOR) & BYTE;
|
||||||
m.POSITION = pos;
|
m.POSITION = pos;
|
||||||
|
@ -377,6 +394,11 @@ int bytes; /* how many bytes to transfer */
|
||||||
if (m.REP_STATUS == SUSPEND) {
|
if (m.REP_STATUS == SUSPEND) {
|
||||||
panic(__FILE__, "dev_bio: driver returned SUSPEND", NO_NUM);
|
panic(__FILE__, "dev_bio: driver returned SUSPEND", NO_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(buf != buf_used) {
|
||||||
|
memcpy(buf, buf_used, bytes * sizeof(iovec_t));
|
||||||
|
}
|
||||||
|
|
||||||
return(m.REP_STATUS);
|
return(m.REP_STATUS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,6 +421,7 @@ int flags; /* special flags, like O_NONBLOCK */
|
||||||
cp_grant_id_t gid = GRANT_INVALID;
|
cp_grant_id_t gid = GRANT_INVALID;
|
||||||
static cp_grant_id_t gids[NR_IOREQS];
|
static cp_grant_id_t gids[NR_IOREQS];
|
||||||
int vec_grants = 0, orig_op, safe;
|
int vec_grants = 0, orig_op, safe;
|
||||||
|
void *buf_used;
|
||||||
|
|
||||||
/* Determine task dmap. */
|
/* Determine task dmap. */
|
||||||
dp = &dmap[(dev >> MAJOR) & BYTE];
|
dp = &dmap[(dev >> MAJOR) & BYTE];
|
||||||
|
@ -421,8 +444,13 @@ int flags; /* special flags, like O_NONBLOCK */
|
||||||
dev_mess.ADDRESS = buf;
|
dev_mess.ADDRESS = buf;
|
||||||
|
|
||||||
/* Convert DEV_* to DEV_*_S variants. */
|
/* Convert DEV_* to DEV_*_S variants. */
|
||||||
safe = safe_io_conversion(dp->dmap_driver, dev, &gid,
|
buf_used = buf;
|
||||||
&op, gids, NR_IOREQS, &dev_mess.IO_ENDPT, buf, &vec_grants, bytes, &pos);
|
safe = safe_io_conversion(dp->dmap_driver, &gid,
|
||||||
|
&op, gids, NR_IOREQS, &dev_mess.IO_ENDPT, &buf_used,
|
||||||
|
&vec_grants, bytes, &pos);
|
||||||
|
|
||||||
|
if(buf != buf_used)
|
||||||
|
panic(__FILE__,"dev_io: safe_io_conversion changed buffer", NO_NUM);
|
||||||
|
|
||||||
/* If the safe conversion was done, set the ADDRESS to
|
/* If the safe conversion was done, set the ADDRESS to
|
||||||
* the grant id.
|
* the grant id.
|
||||||
|
|
Loading…
Reference in a new issue