Introduce SYSCALL_INIT_HELPER and SYSCALL32_INIT_HELPER macros and
neccessary support functions to allow registering dynamically loaded syscalls from the MOD_LOAD handlers. Helpers handle registration failures semi-automatically. Reviewed by: jhb MFC after: 2 weeks
This commit is contained in:
parent
99b331a982
commit
0687ba3e90
@ -3084,6 +3084,36 @@ syscall32_module_handler(struct module *mod, int what, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
syscall32_helper_register(struct syscall_helper_data *sd)
|
||||
{
|
||||
struct syscall_helper_data *sd1;
|
||||
int error;
|
||||
|
||||
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
|
||||
error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
|
||||
&sd1->old_sysent);
|
||||
if (error != 0) {
|
||||
syscall32_helper_unregister(sd);
|
||||
return (error);
|
||||
}
|
||||
sd1->registered = 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
syscall32_helper_unregister(struct syscall_helper_data *sd)
|
||||
{
|
||||
struct syscall_helper_data *sd1;
|
||||
|
||||
for (sd1 = sd; sd1->registered != 0; sd1++) {
|
||||
syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent);
|
||||
sd1->registered = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
register_t *
|
||||
freebsd32_copyout_strings(struct image_params *imgp)
|
||||
{
|
||||
|
@ -78,10 +78,21 @@ SYSCALL32_MODULE(syscallname, \
|
||||
& syscallname##_syscall32, & syscallname##_sysent32,\
|
||||
NULL, NULL);
|
||||
|
||||
#define SYSCALL32_INIT_HELPER(syscallname) { \
|
||||
.new_sysent = { \
|
||||
.sy_narg = (sizeof(struct syscallname ## _args ) \
|
||||
/ sizeof(register_t)), \
|
||||
.sy_call = (sy_call_t *)& syscallname, \
|
||||
}, \
|
||||
.syscall_no = FREEBSD32_SYS_##syscallname \
|
||||
}
|
||||
|
||||
int syscall32_register(int *offset, struct sysent *new_sysent,
|
||||
struct sysent *old_sysent);
|
||||
int syscall32_deregister(int *offset, struct sysent *old_sysent);
|
||||
int syscall32_module_handler(struct module *mod, int what, void *arg);
|
||||
int syscall32_helper_register(struct syscall_helper_data *sd);
|
||||
int syscall32_helper_unregister(struct syscall_helper_data *sd);
|
||||
|
||||
register_t *freebsd32_copyout_strings(struct image_params *imgp);
|
||||
struct iovec32;
|
||||
|
@ -135,3 +135,33 @@ syscall_module_handler(struct module *mod, int what, void *arg)
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
syscall_helper_register(struct syscall_helper_data *sd)
|
||||
{
|
||||
struct syscall_helper_data *sd1;
|
||||
int error;
|
||||
|
||||
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
|
||||
error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
|
||||
&sd1->old_sysent);
|
||||
if (error != 0) {
|
||||
syscall_helper_unregister(sd);
|
||||
return (error);
|
||||
}
|
||||
sd1->registered = 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
syscall_helper_unregister(struct syscall_helper_data *sd)
|
||||
{
|
||||
struct syscall_helper_data *sd1;
|
||||
|
||||
for (sd1 = sd; sd1->registered != 0; sd1++) {
|
||||
syscall_deregister(&sd1->syscall_no, &sd1->old_sysent);
|
||||
sd1->registered = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -166,10 +166,34 @@ SYSCALL_MODULE(syscallname, \
|
||||
(sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmnosys && \
|
||||
sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmressys)
|
||||
|
||||
/*
|
||||
* Syscall registration helpers with resource allocation handling.
|
||||
*/
|
||||
struct syscall_helper_data {
|
||||
struct sysent new_sysent;
|
||||
struct sysent old_sysent;
|
||||
int syscall_no;
|
||||
int registered;
|
||||
};
|
||||
#define SYSCALL_INIT_HELPER(syscallname) { \
|
||||
.new_sysent = { \
|
||||
.sy_narg = (sizeof(struct syscallname ## _args ) \
|
||||
/ sizeof(register_t)), \
|
||||
.sy_call = (sy_call_t *)& syscallname, \
|
||||
.sy_auevent = SYS_AUE_##syscallname \
|
||||
}, \
|
||||
.syscall_no = SYS_##syscallname \
|
||||
}
|
||||
#define SYSCALL_INIT_LAST { \
|
||||
.syscall_no = NO_SYSCALL \
|
||||
}
|
||||
|
||||
int syscall_register(int *offset, struct sysent *new_sysent,
|
||||
struct sysent *old_sysent);
|
||||
int syscall_deregister(int *offset, struct sysent *old_sysent);
|
||||
int syscall_module_handler(struct module *mod, int what, void *arg);
|
||||
int syscall_helper_register(struct syscall_helper_data *sd);
|
||||
int syscall_helper_unregister(struct syscall_helper_data *sd);
|
||||
|
||||
/* Special purpose system call functions. */
|
||||
struct nosys_args;
|
||||
|
Loading…
x
Reference in New Issue
Block a user