| 111 | } |
| 112 | |
| 113 | int |
| 114 | kern_syscall_register(struct sysent *sysents, int *offset, |
| 115 | struct sysent *new_sysent, struct sysent *old_sysent, int flags) |
| 116 | { |
| 117 | int i; |
| 118 | |
| 119 | if ((flags & ~SY_THR_STATIC) != 0) |
| 120 | return (EINVAL); |
| 121 | |
| 122 | if (*offset == NO_SYSCALL) { |
| 123 | for (i = 1; i < SYS_MAXSYSCALL; ++i) |
| 124 | if (sysents[i].sy_call == (sy_call_t *)lkmnosys) |
| 125 | break; |
| 126 | if (i == SYS_MAXSYSCALL) |
| 127 | return (ENFILE); |
| 128 | *offset = i; |
| 129 | } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL) { |
| 130 | return (EINVAL); |
| 131 | } else if (sysents[*offset].sy_call != (sy_call_t *)lkmnosys && |
| 132 | sysents[*offset].sy_call != (sy_call_t *)lkmressys) { |
| 133 | KASSERT(sysents[*offset].sy_call != NULL, |
| 134 | ("undefined syscall %d", *offset)); |
| 135 | return (EEXIST); |
| 136 | } |
| 137 | |
| 138 | KASSERT(sysents[*offset].sy_thrcnt == SY_THR_ABSENT, |
| 139 | ("dynamic syscall is not protected")); |
| 140 | *old_sysent = sysents[*offset]; |
| 141 | new_sysent->sy_thrcnt = SY_THR_ABSENT; |
| 142 | sysents[*offset] = *new_sysent; |
| 143 | atomic_store_rel_32(&sysents[*offset].sy_thrcnt, flags); |
| 144 | return (0); |
| 145 | } |
| 146 | |
| 147 | int |
| 148 | kern_syscall_deregister(struct sysent *sysents, int offset, |
no test coverage detected