diff options
author | Benjamin Berg <benjamin@sipsolutions.net> | 2024-07-03 15:45:28 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2024-07-03 17:09:49 +0200 |
commit | 76ed9158e1d474e963fc59da7a461b27a2212c5a (patch) | |
tree | 815dd1fd2568cdcc27d75178249cc809027ca80b /arch/um/include/shared | |
parent | 542dc79f6ea601788704a79ff54283c2bea265e9 (diff) |
um: Rework syscall handling
Rework syscall handling to be platform independent. Also create a clean
split between queueing of syscalls and flushing them out, removing the
need to keep state in the code that triggers the syscalls.
The code adds syscall_data_len to the global mm_id structure. This will
be used later to allow surrounding code to track whether syscalls still
need to run and if errors occurred.
Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
Link: https://patch.msgid.link/20240703134536.1161108-5-benjamin@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'arch/um/include/shared')
-rw-r--r-- | arch/um/include/shared/os.h | 22 | ||||
-rw-r--r-- | arch/um/include/shared/skas/mm_id.h | 1 | ||||
-rw-r--r-- | arch/um/include/shared/skas/stub-data.h | 35 | ||||
-rw-r--r-- | arch/um/include/shared/user.h | 8 |
4 files changed, 51 insertions, 15 deletions
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index d269637adcd6..d1331d20fd2b 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -272,19 +272,15 @@ extern long long os_persistent_clock_emulation(void); extern long long os_nsecs(void); /* skas/mem.c */ -extern long run_syscall_stub(struct mm_id * mm_idp, - int syscall, unsigned long *args, long expected, - void **addr, int done); -extern long syscall_stub_data(struct mm_id * mm_idp, - unsigned long *data, int data_count, - void **addr, void **stub_addr); -extern int map(struct mm_id * mm_idp, unsigned long virt, - unsigned long len, int prot, int phys_fd, - unsigned long long offset, int done, void **data); -extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, - int done, void **data); -extern int protect(struct mm_id * mm_idp, unsigned long addr, - unsigned long len, unsigned int prot, int done, void **data); +int syscall_stub_flush(struct mm_id *mm_idp); +struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp); + +void map(struct mm_id *mm_idp, unsigned long virt, + unsigned long len, int prot, int phys_fd, + unsigned long long offset); +void unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len); +void protect(struct mm_id *mm_idp, unsigned long addr, + unsigned long len, unsigned int prot); /* skas/process.c */ extern int is_skas_winch(int pid, int fd, void *data); diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h index 92dbf727e384..4c5311abe42c 100644 --- a/arch/um/include/shared/skas/mm_id.h +++ b/arch/um/include/shared/skas/mm_id.h @@ -13,6 +13,7 @@ struct mm_id { } u; unsigned long stack; int kill; + int syscall_data_len; }; void __switch_mm(struct mm_id *mm_idp); diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h index 779d2a3bac5d..6ffa9fb5218c 100644 --- a/arch/um/include/shared/skas/stub-data.h +++ b/arch/um/include/shared/skas/stub-data.h @@ -10,14 +10,45 @@ #include <linux/compiler_types.h> #include <as-layout.h> +#include <sysdep/tls.h> + +#define STUB_NEXT_SYSCALL(s) \ + ((struct stub_syscall *) (((unsigned long) s) + (s)->cmd_len)) + +enum stub_syscall_type { + STUB_SYSCALL_UNSET = 0, + STUB_SYSCALL_MMAP, + STUB_SYSCALL_MUNMAP, + STUB_SYSCALL_MPROTECT, + STUB_SYSCALL_LDT, +}; + +struct stub_syscall { + union { + struct { + unsigned long addr; + unsigned long length; + unsigned long offset; + int fd; + int prot; + } mem; + struct { + user_desc_t desc; + int func; + } ldt; + }; + + enum stub_syscall_type syscall; +}; struct stub_data { unsigned long offset; int fd; - long parent_err, child_err; + long err, child_err; + int syscall_data_len; /* 128 leaves enough room for additional fields in the struct */ - unsigned char syscall_data[UM_KERN_PAGE_SIZE - 128] __aligned(16); + struct stub_syscall syscall_data[(UM_KERN_PAGE_SIZE - 128) / sizeof(struct stub_syscall)] __aligned(16); /* Stack for our signal handlers and for calling into . */ unsigned char sigstack[UM_KERN_PAGE_SIZE] __aligned(UM_KERN_PAGE_SIZE); diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 326e52450e41..bbab79c0c074 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -42,11 +42,19 @@ extern void panic(const char *fmt, ...) #define printk(...) _printk(__VA_ARGS__) extern int _printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +extern void print_hex_dump(const char *level, const char *prefix_str, + int prefix_type, int rowsize, int groupsize, + const void *buf, size_t len, _Bool ascii); #else static inline int printk(const char *fmt, ...) { return 0; } +static inline void print_hex_dump(const char *level, const char *prefix_str, + int prefix_type, int rowsize, int groupsize, + const void *buf, size_t len, _Bool ascii) +{ +} #endif extern int in_aton(char *str); |