(Incomplete) support for access control in PCI (pci_set_acl).
-script argument to service for crash recovery scripts -config argument to service for driver resource configuration restart command in service to restart a driver after a crash (for use in crash recovery scripts). down and refresh now take labels instead of pids. verious changes in rs to make this work.
This commit is contained in:
+94
-3
@@ -5,6 +5,7 @@ main.c
|
||||
#include "../drivers.h"
|
||||
|
||||
#include <ibm/pci.h>
|
||||
#include <minix/rs.h>
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
@@ -16,6 +17,12 @@ PRIVATE struct name
|
||||
int tasknr;
|
||||
} names[NR_DRIVERS];
|
||||
|
||||
PRIVATE struct acl
|
||||
{
|
||||
int inuse;
|
||||
struct rs_pci acl;
|
||||
} acl[NR_DRIVERS];
|
||||
|
||||
FORWARD _PROTOTYPE( void do_init, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_sig_handler, (void) );
|
||||
FORWARD _PROTOTYPE( void do_first_dev, (message *mp) );
|
||||
@@ -26,6 +33,7 @@ FORWARD _PROTOTYPE( void do_dev_name, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_dev_name_s, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_slot_name, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_slot_name_s, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_acl, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_reserve, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_attr_r8, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_attr_r16, (message *mp) );
|
||||
@@ -34,6 +42,8 @@ FORWARD _PROTOTYPE( void do_attr_w8, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_attr_w16, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_attr_w32, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_rescan_bus, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void reply, (message *mp, int result) );
|
||||
FORWARD _PROTOTYPE( struct rs_pci *find_acl, (int endpoint) );
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -72,6 +82,7 @@ int main(void)
|
||||
case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
|
||||
case BUSC_PCI_DEV_NAME_S: do_dev_name_s(&m); break;
|
||||
case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
|
||||
case BUSC_PCI_ACL: do_acl(&m); break;
|
||||
case PROC_EVENT: do_sig_handler(); break;
|
||||
default:
|
||||
printf("PCI: got message from %d, type %d\n",
|
||||
@@ -140,10 +151,16 @@ message *mp;
|
||||
PRIVATE void do_first_dev(mp)
|
||||
message *mp;
|
||||
{
|
||||
int r, devind;
|
||||
int i, r, devind;
|
||||
u16_t vid, did;
|
||||
struct rs_pci *aclp;
|
||||
|
||||
r= pci_first_dev(&devind, &vid, &did);
|
||||
aclp= find_acl(mp->m_source);
|
||||
|
||||
if (!aclp)
|
||||
printf("do_first_dev: no acl for caller %d\n", mp->m_source);
|
||||
|
||||
r= pci_first_dev_a(aclp, &devind, &vid, &did);
|
||||
if (r == 1)
|
||||
{
|
||||
mp->m1_i1= devind;
|
||||
@@ -164,10 +181,12 @@ message *mp;
|
||||
{
|
||||
int r, devind;
|
||||
u16_t vid, did;
|
||||
struct rs_pci *aclp;
|
||||
|
||||
devind= mp->m1_i1;
|
||||
aclp= find_acl(mp->m_source);
|
||||
|
||||
r= pci_next_dev(&devind, &vid, &did);
|
||||
r= pci_next_dev_a(aclp, &devind, &vid, &did);
|
||||
if (r == 1)
|
||||
{
|
||||
mp->m1_i1= devind;
|
||||
@@ -354,6 +373,48 @@ message *mp;
|
||||
}
|
||||
}
|
||||
|
||||
PRIVATE void do_acl(mp)
|
||||
message *mp;
|
||||
{
|
||||
int i, r, gid;
|
||||
|
||||
if (mp->m_source != RS_PROC_NR)
|
||||
{
|
||||
printf("do_acl: not from RS\n");
|
||||
reply(mp, EPERM);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i= 0; i<NR_DRIVERS; i++)
|
||||
{
|
||||
if (!acl[i].inuse)
|
||||
break;
|
||||
}
|
||||
if (i >= NR_DRIVERS)
|
||||
{
|
||||
printf("do_acl: table is full\n");
|
||||
reply(mp, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
gid= mp->m1_i1;
|
||||
|
||||
r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&acl[i].acl,
|
||||
sizeof(acl[i].acl), D);
|
||||
if (r != OK)
|
||||
{
|
||||
printf("do_acl: safecopyfrom failed\n");
|
||||
reply(mp, r);
|
||||
return;
|
||||
}
|
||||
acl[i].inuse= 1;
|
||||
printf("do_acl: setting ACL for %d ('%s') at entry %d\n",
|
||||
acl[i].acl.rsp_endpoint, acl[i].acl.rsp_label,
|
||||
i);
|
||||
|
||||
reply(mp, OK);
|
||||
}
|
||||
|
||||
PRIVATE void do_reserve(mp)
|
||||
message *mp;
|
||||
{
|
||||
@@ -521,3 +582,33 @@ message *mp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRIVATE void reply(mp, result)
|
||||
message *mp;
|
||||
int result;
|
||||
{
|
||||
int r;
|
||||
message m;
|
||||
|
||||
m.m_type= result;
|
||||
r= send(mp->m_source, &m);
|
||||
if (r != 0)
|
||||
printf("reply: unable to send to %d: %d\n", mp->m_source, r);
|
||||
}
|
||||
|
||||
|
||||
PRIVATE struct rs_pci *find_acl(endpoint)
|
||||
int endpoint;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Find ACL entry for caller */
|
||||
for (i= 0; i<NR_DRIVERS; i++)
|
||||
{
|
||||
if (!acl[i].inuse)
|
||||
continue;
|
||||
if (acl[i].acl.rsp_endpoint == endpoint)
|
||||
return &acl[i].acl;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+60
-8
@@ -13,6 +13,7 @@ Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
|
||||
#include <ibm/pci.h>
|
||||
#include <sys/vm.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/rs.h>
|
||||
#include <minix/syslib.h>
|
||||
|
||||
#include "pci.h"
|
||||
@@ -146,6 +147,7 @@ FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,
|
||||
FORWARD _PROTOTYPE( u16_t pcii_rsts, (int busind) );
|
||||
FORWARD _PROTOTYPE( void pcii_wsts, (int busind, U16_t value) );
|
||||
FORWARD _PROTOTYPE( void print_capabilities, (int devind) );
|
||||
FORWARD _PROTOTYPE( int visible, (struct rs_pci *aclp, int devind) );
|
||||
|
||||
/*===========================================================================*
|
||||
* helper functions for I/O *
|
||||
@@ -248,19 +250,23 @@ int *devindp;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* pci_first_dev *
|
||||
* pci_first_dev_a *
|
||||
*===========================================================================*/
|
||||
PUBLIC int pci_first_dev(devindp, vidp, didp)
|
||||
PUBLIC int pci_first_dev_a(aclp, devindp, vidp, didp)
|
||||
struct rs_pci *aclp;
|
||||
int *devindp;
|
||||
u16_t *vidp;
|
||||
u16_t *didp;
|
||||
{
|
||||
int devind;
|
||||
int i, devind;
|
||||
|
||||
for (devind= 0; devind < nr_pcidev; devind++)
|
||||
{
|
||||
if (!pcidev[devind].pd_inuse)
|
||||
break;
|
||||
if (pcidev[devind].pd_inuse)
|
||||
continue;
|
||||
if (!visible(aclp, devind))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (devind >= nr_pcidev)
|
||||
return 0;
|
||||
@@ -273,7 +279,8 @@ u16_t *didp;
|
||||
/*===========================================================================*
|
||||
* pci_next_dev *
|
||||
*===========================================================================*/
|
||||
PUBLIC int pci_next_dev(devindp, vidp, didp)
|
||||
PUBLIC int pci_next_dev_a(aclp, devindp, vidp, didp)
|
||||
struct rs_pci *aclp;
|
||||
int *devindp;
|
||||
u16_t *vidp;
|
||||
u16_t *didp;
|
||||
@@ -282,8 +289,11 @@ u16_t *didp;
|
||||
|
||||
for (devind= *devindp+1; devind < nr_pcidev; devind++)
|
||||
{
|
||||
if (!pcidev[devind].pd_inuse)
|
||||
break;
|
||||
if (pcidev[devind].pd_inuse)
|
||||
continue;
|
||||
if (!visible(aclp, devind))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (devind >= nr_pcidev)
|
||||
return 0;
|
||||
@@ -2428,6 +2438,48 @@ int devind;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* visible *
|
||||
*===========================================================================*/
|
||||
PRIVATE int visible(aclp, devind)
|
||||
struct rs_pci *aclp;
|
||||
int devind;
|
||||
{
|
||||
int i;
|
||||
u32_t class_id;
|
||||
|
||||
if (!aclp)
|
||||
return TRUE; /* Should be changed when ACLs become
|
||||
* mandatory.
|
||||
*/
|
||||
/* Check whether the caller is allowed to get this device. */
|
||||
for (i= 0; i<aclp->rsp_nr_device; i++)
|
||||
{
|
||||
if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
|
||||
aclp->rsp_device[i].did == pcidev[devind].pd_did)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (!aclp->rsp_nr_class)
|
||||
return FALSE;
|
||||
|
||||
class_id= (pcidev[devind].pd_baseclass << 16) |
|
||||
(pcidev[devind].pd_subclass << 8) |
|
||||
pcidev[devind].pd_infclass;
|
||||
for (i= 0; i<aclp->rsp_nr_class; i++)
|
||||
{
|
||||
if (aclp->rsp_class[i].class ==
|
||||
(class_id & aclp->rsp_class[i].mask))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $
|
||||
*/
|
||||
|
||||
@@ -84,6 +84,10 @@ extern struct pci_pcibridge pci_pcibridge[];
|
||||
/* Utility functions */
|
||||
_PROTOTYPE( void pci_reserve3, (int devind, int proc, char name[M3_STRING]));
|
||||
_PROTOTYPE( void pci_release, (char name[M3_STRING]) );
|
||||
_PROTOTYPE( int pci_first_dev_a, (struct rs_pci *aclp, int *devindp,
|
||||
u16_t *vidp, u16_t *didp) );
|
||||
_PROTOTYPE( int pci_next_dev_a, (struct rs_pci *aclp, int *devindp,
|
||||
u16_t *vidp, u16_t *didp) );
|
||||
|
||||
/*
|
||||
* $PchId: pci.h,v 1.4 2001/12/06 20:21:22 philip Exp $
|
||||
|
||||
Reference in New Issue
Block a user