kern_syscalls.c (6f3544cd7084abbadd83637993a4f41fd30e6ccd) kern_syscalls.c (e015b1ab0a428e65297e44471d257d7eb589b383)
1/*-
2 * Copyright (c) 1999 Assar Westerlund
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 91 unchanged lines hidden (view full) ---

100 if ((oldcnt & SY_THR_STATIC) != 0)
101 return;
102 cnt = oldcnt - SY_THR_INCR;
103 } while (atomic_cmpset_rel_32(&se->sy_thrcnt, oldcnt, cnt) == 0);
104}
105
106int
107syscall_register(int *offset, struct sysent *new_sysent,
1/*-
2 * Copyright (c) 1999 Assar Westerlund
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 91 unchanged lines hidden (view full) ---

100 if ((oldcnt & SY_THR_STATIC) != 0)
101 return;
102 cnt = oldcnt - SY_THR_INCR;
103 } while (atomic_cmpset_rel_32(&se->sy_thrcnt, oldcnt, cnt) == 0);
104}
105
106int
107syscall_register(int *offset, struct sysent *new_sysent,
108 struct sysent *old_sysent)
108 struct sysent *old_sysent, int flags)
109{
110 int i;
111
109{
110 int i;
111
112 if ((flags & ~SY_THR_STATIC) != 0)
113 return (EINVAL);
114
112 if (*offset == NO_SYSCALL) {
113 for (i = 1; i < SYS_MAXSYSCALL; ++i)
114 if (sysent[i].sy_call == (sy_call_t *)lkmnosys)
115 break;
116 if (i == SYS_MAXSYSCALL)
117 return (ENFILE);
118 *offset = i;
119 } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL)
120 return (EINVAL);
121 else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys &&
122 sysent[*offset].sy_call != (sy_call_t *)lkmressys)
123 return (EEXIST);
124
125 KASSERT(sysent[*offset].sy_thrcnt == SY_THR_ABSENT,
126 ("dynamic syscall is not protected"));
127 *old_sysent = sysent[*offset];
128 new_sysent->sy_thrcnt = SY_THR_ABSENT;
129 sysent[*offset] = *new_sysent;
115 if (*offset == NO_SYSCALL) {
116 for (i = 1; i < SYS_MAXSYSCALL; ++i)
117 if (sysent[i].sy_call == (sy_call_t *)lkmnosys)
118 break;
119 if (i == SYS_MAXSYSCALL)
120 return (ENFILE);
121 *offset = i;
122 } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL)
123 return (EINVAL);
124 else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys &&
125 sysent[*offset].sy_call != (sy_call_t *)lkmressys)
126 return (EEXIST);
127
128 KASSERT(sysent[*offset].sy_thrcnt == SY_THR_ABSENT,
129 ("dynamic syscall is not protected"));
130 *old_sysent = sysent[*offset];
131 new_sysent->sy_thrcnt = SY_THR_ABSENT;
132 sysent[*offset] = *new_sysent;
130 atomic_store_rel_32(&sysent[*offset].sy_thrcnt, 0);
133 atomic_store_rel_32(&sysent[*offset].sy_thrcnt, flags);
131 return (0);
132}
133
134int
135syscall_deregister(int *offset, struct sysent *old_sysent)
136{
134 return (0);
135}
136
137int
138syscall_deregister(int *offset, struct sysent *old_sysent)
139{
140 struct sysent *se;
137
141
138 if (*offset) {
139 syscall_thread_drain(&sysent[*offset]);
140 sysent[*offset] = *old_sysent;
141 }
142 if (*offset == 0)
143 return (0); /* XXX? */
144
145 se = &sysent[*offset];
146 if ((se->sy_thrcnt & SY_THR_STATIC) != 0)
147 return (EINVAL);
148 syscall_thread_drain(se);
149 sysent[*offset] = *old_sysent;
142 return (0);
143}
144
145int
146syscall_module_handler(struct module *mod, int what, void *arg)
147{
148 struct syscall_module_data *data = arg;
149 modspecific_t ms;
150 int error;
151
152 switch (what) {
153 case MOD_LOAD:
154 error = syscall_register(data->offset, data->new_sysent,
150 return (0);
151}
152
153int
154syscall_module_handler(struct module *mod, int what, void *arg)
155{
156 struct syscall_module_data *data = arg;
157 modspecific_t ms;
158 int error;
159
160 switch (what) {
161 case MOD_LOAD:
162 error = syscall_register(data->offset, data->new_sysent,
155 &data->old_sysent);
163 &data->old_sysent, SY_THR_STATIC_KLD);
156 if (error) {
157 /* Leave a mark so we know to safely unload below. */
158 data->offset = NULL;
159 return (error);
160 }
161 ms.intval = *data->offset;
162 MOD_XLOCK;
163 module_setspecific(mod, &ms);

--- 21 unchanged lines hidden (view full) ---

185 return (data->chainevh(mod, what, data->chainarg));
186 return (EOPNOTSUPP);
187 }
188
189 /* NOTREACHED */
190}
191
192int
164 if (error) {
165 /* Leave a mark so we know to safely unload below. */
166 data->offset = NULL;
167 return (error);
168 }
169 ms.intval = *data->offset;
170 MOD_XLOCK;
171 module_setspecific(mod, &ms);

--- 21 unchanged lines hidden (view full) ---

193 return (data->chainevh(mod, what, data->chainarg));
194 return (EOPNOTSUPP);
195 }
196
197 /* NOTREACHED */
198}
199
200int
193syscall_helper_register(struct syscall_helper_data *sd)
201syscall_helper_register(struct syscall_helper_data *sd, int flags)
194{
195 struct syscall_helper_data *sd1;
196 int error;
197
198 for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
199 error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
202{
203 struct syscall_helper_data *sd1;
204 int error;
205
206 for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
207 error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
200 &sd1->old_sysent);
208 &sd1->old_sysent, flags);
201 if (error != 0) {
202 syscall_helper_unregister(sd);
203 return (error);
204 }
205 sd1->registered = 1;
206 }
207 return (0);
208}

--- 12 unchanged lines hidden ---
209 if (error != 0) {
210 syscall_helper_unregister(sd);
211 return (error);
212 }
213 sd1->registered = 1;
214 }
215 return (0);
216}

--- 12 unchanged lines hidden ---