|
|
1.1 ! root 1: /* ! 2: * System V Compatible Shared Memory Device Driver ! 3: * ! 4: * This device driver provides System V compatible shared memory operations. ! 5: * Operations are performed through the shared memory device (/dev/shm). ! 6: * and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt ! 7: * utilities. ! 8: * ! 9: * Author: Allan Cornish. ! 10: * ! 11: */ ! 12: ! 13: #include <sys/coherent.h> ! 14: #include <sys/sched.h> ! 15: #include <sys/types.h> ! 16: #include <sys/uproc.h> ! 17: #include <errno.h> ! 18: #include <sys/stat.h> ! 19: #include <sys/con.h> ! 20: #include <sys/seg.h> ! 21: #include <sys/shm.h> ! 22: #ifndef _I386 ! 23: #define getusd(arg) getuwd(arg) ! 24: #define putusd(arg1, arg2) putuwd(arg1, arg2) ! 25: #endif ! 26: ! 27: #ifndef EIDRM ! 28: #define EIDRM EDOM ! 29: #endif ! 30: ! 31: /* ! 32: * Functions. ! 33: */ ! 34: ! 35: int shmload(); ! 36: int shmread(); ! 37: int shmwrite(); ! 38: int shmioctl(); ! 39: int nulldev(); ! 40: int nonedev(); ! 41: ! 42: /* ! 43: * Device Configuration. ! 44: */ ! 45: ! 46: CON shmcon = { ! 47: DFCHR, /* Flags */ ! 48: 24, /* Major Index */ ! 49: nulldev, /* Open */ ! 50: nulldev, /* Close */ ! 51: nonedev, /* Block */ ! 52: shmread, /* Read */ ! 53: shmwrite, /* Write */ ! 54: shmioctl, /* Ioctl */ ! 55: nulldev, /* Power fail */ ! 56: nulldev, /* Timeout */ ! 57: shmload, /* Load */ ! 58: nulldev /* Unload */ ! 59: }; ! 60: ! 61: unsigned NSHMID = 16; ! 62: struct shmid_ds *shmids; ! 63: struct seg **shmsegs; ! 64: ! 65: /* ! 66: * Shared Memory Device Load. ! 67: */ ! 68: ! 69: static ! 70: shmload() ! 71: { ! 72: register struct shmid_ds * idp; ! 73: register unsigned wanted; ! 74: ! 75: if (NSHMID == 0) ! 76: return 0; ! 77: ! 78: wanted = NSHMID * (sizeof(struct shmid_ds) + sizeof(struct seg *)); ! 79: ! 80: /* allocate space for structs */ ! 81: ! 82: if ((shmids = kalloc(wanted)) == 0) { ! 83: printf("couldn't kalloc %u shared memory ids\n", NSHMID); ! 84: NSHMID = 0; ! 85: return 0; ! 86: } ! 87: shmsegs = (struct seg *) &shmids[ NSHMID ]; ! 88: ! 89: for (idp = &shmids[NSHMID]; --idp >= shmids;) ! 90: idp->shm_perm.mode = 0; ! 91: ! 92: return 0; ! 93: } ! 94: ! 95: /* ! 96: ** Shared Memory Read. ! 97: */ ! 98: ! 99: ! 100: ! 101: static ! 102: shmread(dev, iop) ! 103: ! 104: dev_t dev; ! 105: register IO *iop; ! 106: ! 107: { ! 108: register struct shmid_ds *idp; ! 109: int shmid; ! 110: unsigned off; ! 111: #ifndef _I386 ! 112: faddr_t faddr; ! 113: #endif ! 114: ! 115: #ifdef _I386 ! 116: off = ((unsigned short *) &iop->io_seek)[0]; ! 117: shmid = ((unsigned short *) &iop->io_seek)[1]; ! 118: #else ! 119: off = ((unsigned *) &iop->io_seek)[0]; ! 120: shmid = ((unsigned *) &iop->io_seek)[1]; ! 121: #endif ! 122: ! 123: /* is shmid valid? */ ! 124: if (shmid >= NSHMID) { ! 125: u.u_error = EFAULT; ! 126: return -1; ! 127: } ! 128: ! 129: idp = &shmids[shmid]; /* point to struct _ds being used */ ! 130: ! 131: /* check mode */ ! 132: if ((idp->shm_perm.mode & IPC_ALLOC) == 0) { ! 133: u.u_error = EIDRM; ! 134: return -1; ! 135: } ! 136: ! 137: /* check permissions */ ! 138: if ((ipcaccess(&idp->shm_perm) & SHM_R) == 0) { ! 139: u.u_error = EACCES; ! 140: return -1; ! 141: } ! 142: ! 143: /* are we about to exceed our segment size? */ ! 144: if (((long) off + iop->io_ioc) > idp->shm_segsz) { ! 145: u.u_error = EFAULT; ! 146: return -1; ! 147: } ! 148: ! 149: /* copy from kernel data to user data */ ! 150: #ifndef _I386 ! 151: FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr); ! 152: FP_OFF(faddr) = off; ! 153: #endif ! 154: #ifdef _I386 ! 155: if (!kucopy(shmsegs[shmid], iop->io.vbase, ! 156: iop->io_ioc)){ ! 157: #else ! 158: if (! fucopy(faddr, iop->io_base, iop->io_ioc)) { ! 159: #endif ! 160: u.u_error = EFAULT; ! 161: return -1; ! 162: } ! 163: ! 164: iop->io_ioc = 0; ! 165: return 0; ! 166: } ! 167: ! 168: ! 169: ! 170: /* ! 171: ** Shared Memory Write. ! 172: */ ! 173: ! 174: ! 175: static ! 176: shmwrite(dev, iop) ! 177: ! 178: dev_t dev; ! 179: register IO *iop; ! 180: ! 181: { ! 182: register struct shmid_ds *idp; ! 183: int shmid; ! 184: unsigned off; ! 185: #ifndef _I386 ! 186: faddr_t faddr; ! 187: #endif ! 188: ! 189: ! 190: #ifdef _I386 ! 191: off = ((unsigned short *) &iop->io_seek)[0]; ! 192: shmid = ((unsigned short *) &iop->io_seek)[1]; ! 193: #else ! 194: off = ((unsigned *) &iop->io_seek)[0]; ! 195: shmid = ((unsigned *) &iop->io_seek)[1]; ! 196: #endif ! 197: ! 198: /* validate id # */ ! 199: if (shmid >= NSHMID) { ! 200: u.u_error = EFAULT; ! 201: return -1; ! 202: } ! 203: ! 204: idp = &shmids[shmid]; /* set our pointer to struct we're working on*/ ! 205: ! 206: /* verify mode */ ! 207: if ((idp->shm_perm.mode & IPC_ALLOC) == 0) { ! 208: u.u_error = EIDRM; ! 209: return -1; ! 210: } ! 211: ! 212: /* verify Permissions */ ! 213: if ((ipcaccess(&idp->shm_perm) & SHM_W) == 0) { ! 214: u.u_error = EFAULT; ! 215: return -1; ! 216: } ! 217: ! 218: /* verify that we won't overwrite our space */ ! 219: if (((long) off + iop->io_ioc) > idp->shm_segsz) { ! 220: u.u_error = EFAULT; ! 221: return -1; ! 222: } ! 223: ! 224: /* copy from user memory to shared segment */ ! 225: #ifndef _I386 ! 226: FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr); ! 227: FP_OFF(faddr) = off; ! 228: #endif ! 229: #ifdef _I386 ! 230: if (!ukcopy( iop->io.vbase, shmsegs[shmid], ! 231: iop->io_ioc)){ ! 232: #else ! 233: if (! ufcopy(iop->io_base, faddr, iop->io_ioc)) { ! 234: #endif ! 235: u.u_error = EFAULT; ! 236: return -1; ! 237: } ! 238: ! 239: iop->io_ioc = 0; ! 240: return 0; ! 241: } ! 242: ! 243: ! 244: ! 245: ! 246: /* ! 247: * Shared Memory Device Ioctl. ! 248: * ! 249: * Input: dev = shared memory device (/dev/shm). ! 250: * com = command to perform (SHMCTL, SHMGET,SHMAT). ! 251: * vec = pointer to return value, followed by parameters. ! 252: * ! 253: * Action: Initiate command. ! 254: * Save commands return value in *vec. ! 255: */ ! 256: ! 257: static ! 258: shmioctl(dev, com, vec) ! 259: ! 260: dev_t dev; ! 261: int com; ! 262: int *vec; ! 263: ! 264: { ! 265: switch (com) { ! 266: ! 267: case SHMCTL: ! 268: putusd(vec+0, ! 269: ushmctl(getusd(vec+1), ! 270: getusd(vec+2), ! 271: getusd(vec+3))); ! 272: break; ! 273: ! 274: case SHMGET: ! 275: putusd(vec+0, ! 276: ushmget(getusd(vec+1), ! 277: getusd(vec+2), ! 278: getusd(vec+3), ! 279: getusd(vec+4))); ! 280: break; ! 281: ! 282: default: ! 283: u.u_error = EINVAL; ! 284: break; ! 285: } ! 286: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.