int check_ipc_filter(struct ipc_filter_s *ipcf, int fill_flags);
int allow_ipc_filtered_msg(struct proc *rp, endpoint_t src_e,
vir_bytes m_src_v, message *m_src_p);
+int priv_add_irq(struct proc *rp, int irq);
+int priv_add_io(struct proc *rp, struct io_range *ior);
+int priv_add_mem(struct proc *rp, struct minix_mem_range *memr);
/* system/do_vtimer.c */
void vtimer_check(struct proc *rp);
return allow;
}
+/*===========================================================================*
+ * priv_add_irq *
+ *===========================================================================*/
+int priv_add_irq(struct proc *rp, int irq)
+{
+ struct priv *priv = priv(rp);
+ int i;
+
+ priv->s_flags |= CHECK_IRQ; /* Check IRQ */
+
+ /* When restarting a driver, check if it already has the permission */
+ for (i = 0; i < priv->s_nr_irq; i++) {
+ if (priv->s_irq_tab[i] == irq)
+ return OK;
+ }
+
+ i= priv->s_nr_irq;
+ if (i >= NR_IRQ) {
+ printf("do_privctl: %d already has %d irq's.\n",
+ rp->p_endpoint, i);
+ return ENOMEM;
+ }
+ priv->s_irq_tab[i]= irq;
+ priv->s_nr_irq++;
+ return OK;
+}
+
+/*===========================================================================*
+ * priv_add_io *
+ *===========================================================================*/
+int priv_add_io(struct proc *rp, struct io_range *ior)
+{
+ struct priv *priv = priv(rp);
+ int i;
+
+ priv->s_flags |= CHECK_IO_PORT; /* Check I/O accesses */
+
+ for (i = 0; i < priv->s_nr_io_range; i++) {
+ if (priv->s_io_tab[i].ior_base == ior->ior_base &&
+ priv->s_io_tab[i].ior_limit == ior->ior_limit)
+ return OK;
+ }
+
+ i= priv->s_nr_io_range;
+ if (i >= NR_IO_RANGE) {
+ printf("do_privctl: %d already has %d i/o ranges.\n",
+ rp->p_endpoint, i);
+ return ENOMEM;
+ }
+
+ priv->s_io_tab[i] = *ior;
+ priv->s_nr_io_range++;
+ return OK;
+}
+
+/*===========================================================================*
+ * priv_add_mem *
+ *===========================================================================*/
+int priv_add_mem(struct proc *rp, struct minix_mem_range *memr)
+{
+ struct priv *priv = priv(rp);
+ int i;
+
+ priv->s_flags |= CHECK_MEM; /* Check memory mappings */
+
+ /* When restarting a driver, check if it already has the permission */
+ for (i = 0; i < priv->s_nr_mem_range; i++) {
+ if (priv->s_mem_tab[i].mr_base == memr->mr_base &&
+ priv->s_mem_tab[i].mr_limit == memr->mr_limit)
+ return OK;
+ }
+
+ i= priv->s_nr_mem_range;
+ if (i >= NR_MEM_RANGE) {
+ printf("do_privctl: %d already has %d mem ranges.\n",
+ rp->p_endpoint, i);
+ return ENOMEM;
+ }
+ priv->s_mem_tab[i]= *memr;
+ priv->s_nr_mem_range++;
+ return OK;
+}
+
/* Get the I/O range */
data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
KERNEL, (vir_bytes) &io_range, sizeof(io_range));
- priv(rp)->s_flags |= CHECK_IO_PORT; /* Check I/O accesses */
-
- for (i = 0; i < priv(rp)->s_nr_io_range; i++) {
- if (priv(rp)->s_io_tab[i].ior_base == io_range.ior_base &&
- priv(rp)->s_io_tab[i].ior_limit == io_range.ior_limit)
- return OK;
- }
-
- i= priv(rp)->s_nr_io_range;
- if (i >= NR_IO_RANGE) {
- printf("do_privctl: %d already has %d i/o ranges.\n",
- rp->p_endpoint, i);
- return ENOMEM;
- }
-
- priv(rp)->s_io_tab[i].ior_base= io_range.ior_base;
- priv(rp)->s_io_tab[i].ior_limit= io_range.ior_limit;
- priv(rp)->s_nr_io_range++;
-
- return OK;
+ /* Add the I/O range */
+ return priv_add_io(rp, &io_range);
case SYS_PRIV_ADD_MEM:
if (RTS_ISSET(rp, RTS_NO_PRIV))
m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
(vir_bytes) &mem_range, sizeof(mem_range))) != OK)
return r;
- priv(rp)->s_flags |= CHECK_MEM; /* Check memory mappings */
-
- /* When restarting a driver, check if it already has the permission */
- for (i = 0; i < priv(rp)->s_nr_mem_range; i++) {
- if (priv(rp)->s_mem_tab[i].mr_base == mem_range.mr_base &&
- priv(rp)->s_mem_tab[i].mr_limit == mem_range.mr_limit)
- return OK;
- }
-
- i= priv(rp)->s_nr_mem_range;
- if (i >= NR_MEM_RANGE) {
- printf("do_privctl: %d already has %d mem ranges.\n",
- rp->p_endpoint, i);
- return ENOMEM;
- }
-
- priv(rp)->s_mem_tab[i].mr_base= mem_range.mr_base;
- priv(rp)->s_mem_tab[i].mr_limit= mem_range.mr_limit;
- priv(rp)->s_nr_mem_range++;
-
- return OK;
+ /* Add the memory range */
+ return priv_add_mem(rp, &mem_range);
case SYS_PRIV_ADD_IRQ:
if (RTS_ISSET(rp, RTS_NO_PRIV))
#endif
data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
KERNEL, (vir_bytes) &irq, sizeof(irq));
- priv(rp)->s_flags |= CHECK_IRQ; /* Check IRQs */
-
- /* When restarting a driver, check if it already has the permission */
- for (i = 0; i < priv(rp)->s_nr_irq; i++) {
- if (priv(rp)->s_irq_tab[i] == irq)
- return OK;
- }
-
- i= priv(rp)->s_nr_irq;
- if (i >= NR_IRQ) {
- printf("do_privctl: %d already has %d irq's.\n",
- rp->p_endpoint, i);
- return ENOMEM;
- }
- priv(rp)->s_irq_tab[i]= irq;
- priv(rp)->s_nr_irq++;
+ /* Add the IRQ. */
+ return priv_add_irq(rp, irq);
- return OK;
case SYS_PRIV_QUERY_MEM:
{
phys_bytes addr, limit;
(RTS_ISSET(p, RTS_NO_PRIV) || RTS_ISSET(p, RTS_SIG_PENDING) \
|| (RTS_ISSET(p, RTS_RECEIVING) && !RTS_ISSET(p, RTS_SENDING)))
+static int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp);
+static int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp);
+static int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp);
static void adjust_proc_slot(struct proc *rp, struct proc *from_rp);
static void adjust_priv_slot(struct priv *privp, struct priv
*from_privp);
struct proc orig_dst_proc;
struct priv orig_src_priv;
struct priv orig_dst_priv;
- int i;
+ int i, r;
/* Lookup slots for source and destination process. */
src_e = m_ptr->SYS_UPD_SRC_ENDPT;
printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint);
#endif
+ /* Let destination inherit allowed IRQ, I/O ranges, and memory ranges. */
+ r = inherit_priv_irq(src_rp, dst_rp);
+ if(r != OK) {
+ return r;
+ }
+ r = inherit_priv_io(src_rp, dst_rp);
+ if(r != OK) {
+ return r;
+ }
+ r = inherit_priv_mem(src_rp, dst_rp);
+ if(r != OK) {
+ return r;
+ }
+
/* Let destination inherit the target mask from source. */
for (i=0; i < NR_SYS_PROCS; i++) {
if (get_sys_bit(priv(src_rp)->s_ipc_to, i)) {
return OK;
}
+/*===========================================================================*
+ * inherit_priv_irq *
+ *===========================================================================*/
+int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp)
+{
+ int i, r;
+ for (i= 0; i<priv(src_rp)->s_nr_irq; i++) {
+ r = priv_add_irq(dst_rp, priv(src_rp)->s_irq_tab[i]);
+ if(r != OK) {
+ return r;
+ }
+ }
+
+ return OK;
+}
+
+/*===========================================================================*
+ * inherit_priv_io *
+ *===========================================================================*/
+ int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp)
+{
+ int i, r;
+ for (i= 0; i<priv(src_rp)->s_nr_io_range; i++) {
+ r = priv_add_io(dst_rp, &(priv(src_rp)->s_io_tab[i]));
+ if(r != OK) {
+ return r;
+ }
+ }
+
+ return OK;
+}
+
+/*===========================================================================*
+ * inherit_priv_mem *
+ *===========================================================================*/
+int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp)
+{
+ int i, r;
+ for (i= 0; i<priv(src_rp)->s_nr_mem_range; i++) {
+ r = priv_add_mem(dst_rp, &(priv(src_rp)->s_mem_tab[i]));
+ if(r != OK) {
+ return r;
+ }
+ }
+
+ return OK;
+}
+
/*===========================================================================*
* adjust_proc_slot *
*===========================================================================*/