diff --git a/lib/libsys/_libsys.h b/lib/libsys/_libsys.h --- a/lib/libsys/_libsys.h +++ b/lib/libsys/_libsys.h @@ -32,6 +32,7 @@ struct itimerval; struct jail; struct kevent; +struct kexec_segment; struct kld_file_stat; struct mac; struct module_stat; @@ -468,6 +469,7 @@ typedef int (__sys_exterrctl_t)(u_int, u_int, void *); typedef int (__sys_inotify_add_watch_at_t)(int, int, const char *, uint32_t); typedef int (__sys_inotify_rm_watch_t)(int, int); +typedef int (__sys_kexec_load_t)(uint64_t, unsigned long, struct kexec_segment *, unsigned long); void __sys_exit(int rval); int __sys_fork(void); @@ -872,6 +874,7 @@ int __sys_exterrctl(u_int op, u_int flags, void * ptr); int __sys_inotify_add_watch_at(int fd, int dfd, const char * path, uint32_t mask); int __sys_inotify_rm_watch(int fd, int wd); +int __sys_kexec_load(uint64_t entry, unsigned long nseg, struct kexec_segment * segments, unsigned long flags); __END_DECLS #endif /* __LIBSYS_H_ */ diff --git a/lib/libsys/syscalls.map b/lib/libsys/syscalls.map --- a/lib/libsys/syscalls.map +++ b/lib/libsys/syscalls.map @@ -813,4 +813,6 @@ __sys_inotify_add_watch_at; _inotify_rm_watch; __sys_inotify_rm_watch; + _kexec_load; + __sys_kexec_load; }; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -661,4 +661,5 @@ { .sy_narg = AS(exterrctl_args), .sy_call = (sy_call_t *)sys_exterrctl, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 592 = exterrctl */ { .sy_narg = AS(inotify_add_watch_at_args), .sy_call = (sy_call_t *)sys_inotify_add_watch_at, .sy_auevent = AUE_INOTIFY, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 593 = inotify_add_watch_at */ { .sy_narg = AS(inotify_rm_watch_args), .sy_call = (sy_call_t *)sys_inotify_rm_watch, .sy_auevent = AUE_INOTIFY, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 594 = inotify_rm_watch */ + { .sy_narg = AS(kexec_load_args), .sy_call = (sy_call_t *)sys_kexec_load, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 595 = kexec_load */ }; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -600,4 +600,5 @@ "exterrctl", /* 592 = exterrctl */ "inotify_add_watch_at", /* 593 = inotify_add_watch_at */ "inotify_rm_watch", /* 594 = inotify_rm_watch */ + "kexec_load", /* 595 = kexec_load */ }; diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -3500,6 +3500,16 @@ *n_args = 2; break; } + /* kexec_load */ + case 595: { + struct kexec_load_args *p = params; + uarg[a++] = p->entry; /* uint64_t */ + uarg[a++] = p->nseg; /* unsigned long */ + uarg[a++] = (intptr_t)p->segments; /* struct kexec_segment * */ + uarg[a++] = p->flags; /* unsigned long */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -9367,6 +9377,25 @@ break; }; break; + /* kexec_load */ + case 595: + switch (ndx) { + case 0: + p = "uint64_t"; + break; + case 1: + p = "unsigned long"; + break; + case 2: + p = "userland struct kexec_segment *"; + break; + case 3: + p = "unsigned long"; + break; + default: + break; + }; + break; default: break; }; @@ -11365,6 +11394,11 @@ if (ndx == 0 || ndx == 1) p = "int"; break; + /* kexec_load */ + case 595: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -531,4 +531,5 @@ #define SYS_exterrctl 592 #define SYS_inotify_add_watch_at 593 #define SYS_inotify_rm_watch 594 -#define SYS_MAXSYSCALL 595 +#define SYS_kexec_load 595 +#define SYS_MAXSYSCALL 596 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -436,4 +436,5 @@ setcred.o \ exterrctl.o \ inotify_add_watch_at.o \ - inotify_rm_watch.o + inotify_rm_watch.o \ + kexec_load.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -1901,6 +1901,12 @@ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; char wd_l_[PADL_(int)]; int wd; char wd_r_[PADR_(int)]; }; +struct kexec_load_args { + char entry_l_[PADL_(uint64_t)]; uint64_t entry; char entry_r_[PADR_(uint64_t)]; + char nseg_l_[PADL_(unsigned long)]; unsigned long nseg; char nseg_r_[PADR_(unsigned long)]; + char segments_l_[PADL_(struct kexec_segment *)]; struct kexec_segment * segments; char segments_r_[PADR_(struct kexec_segment *)]; + char flags_l_[PADL_(unsigned long)]; unsigned long flags; char flags_r_[PADR_(unsigned long)]; +}; int sys_exit(struct thread *, struct exit_args *); int sys_fork(struct thread *, struct fork_args *); int sys_read(struct thread *, struct read_args *); @@ -2305,6 +2311,7 @@ int sys_exterrctl(struct thread *, struct exterrctl_args *); int sys_inotify_add_watch_at(struct thread *, struct inotify_add_watch_at_args *); int sys_inotify_rm_watch(struct thread *, struct inotify_rm_watch_args *); +int sys_kexec_load(struct thread *, struct kexec_load_args *); #ifdef COMPAT_43 @@ -3289,6 +3296,7 @@ #define SYS_AUE_exterrctl AUE_NULL #define SYS_AUE_inotify_add_watch_at AUE_INOTIFY #define SYS_AUE_inotify_rm_watch AUE_INOTIFY +#define SYS_AUE_kexec_load AUE_NULL #undef PAD_ #undef PADL_