- Timestamp:
- 2024-09-20T12:16:28Z (9 months ago)
- Branches:
- master
- Children:
- d3109ff
- Parents:
- 2cf8f994
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-20 11:42:13)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-20 12:16:28)
- Location:
- kernel
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/abs32le/src/userspace.c
r2cf8f994 r3fcea34 36 36 #include <stdbool.h> 37 37 #include <arch.h> 38 #include <abi/proc/uarg.h>39 38 #include <mm/as.h> 40 39 41 void userspace(uspace_arg_t *kernel_uarg) 40 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 41 { 42 return stack_base + stack_size; 43 } 44 45 void userspace(uintptr_t pc, uintptr_t sp) 42 46 { 43 47 /* -
kernel/arch/amd64/src/userspace.c
r2cf8f994 r3fcea34 39 39 #include <stdint.h> 40 40 #include <arch.h> 41 #include <abi/proc/uarg.h>42 41 #include <mm/as.h> 42 43 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 44 { 45 return stack_base + stack_size; 46 } 43 47 44 48 /** Enter userspace … … 47 51 * 48 52 */ 49 void userspace(u space_arg_t *kernel_uarg)53 void userspace(uintptr_t pc, uintptr_t sp) 50 54 { 51 55 uint64_t rflags = read_rflags(); … … 60 64 "pushq %[utext_des]\n" 61 65 "pushq %[entry]\n" 62 "movq %[uarg], %%rax\n"63 66 64 67 /* %rdi is defined to hold pcb_ptr - set it to 0 */ … … 66 69 "iretq\n" 67 70 :: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER), 68 [stack_top] "r" (kernel_uarg->uspace_stack + 69 kernel_uarg->uspace_stack_size), 71 [stack_top] "r" (sp), 70 72 [rflags] "r" (rflags), 71 73 [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER), 72 [entry] "r" (kernel_uarg->uspace_entry), 73 [uarg] "r" (kernel_uarg->uspace_uarg) 74 : "rax" 74 [entry] "r" (pc) 75 75 ); 76 76 -
kernel/arch/arm32/src/userspace.c
r2cf8f994 r3fcea34 61 61 } ustate_t; 62 62 63 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 64 { 65 return stack_base + stack_size; 66 } 67 63 68 /** Change processor mode 64 69 * … … 66 71 * 67 72 */ 68 void userspace(u space_arg_t *kernel_uarg)73 void userspace(uintptr_t pc, uintptr_t sp) 69 74 { 70 volatile ustate_t ustate; 71 72 /* set first parameter */ 73 ustate.r0 = kernel_uarg->uspace_uarg; 74 75 /* %r1 is defined to hold pcb_ptr - set it to 0 */ 76 ustate.r1 = 0; 75 volatile ustate_t ustate = { }; 77 76 78 77 /* pass the RAS page address in %r2 */ 79 78 ustate.r2 = (uintptr_t) ras_page; 80 79 81 /* clear other registers */ 82 ustate.r3 = 0; 83 ustate.r4 = 0; 84 ustate.r5 = 0; 85 ustate.r6 = 0; 86 ustate.r7 = 0; 87 ustate.r8 = 0; 88 ustate.r9 = 0; 89 ustate.r10 = 0; 90 ustate.r11 = 0; 91 ustate.r12 = 0; 92 ustate.lr = 0; 93 94 /* set user stack */ 95 ustate.sp = kernel_uarg->uspace_stack + 96 kernel_uarg->uspace_stack_size; 97 98 /* set where uspace execution starts */ 99 ustate.pc = kernel_uarg->uspace_entry; 80 ustate.sp = sp; 81 ustate.pc = pc; 100 82 101 83 /* status register in user mode */ -
kernel/arch/arm64/src/arm64.c
r2cf8f994 r3fcea34 146 146 } 147 147 148 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 149 { 150 return stack_base + stack_size; 151 } 152 148 153 /** Change processor mode. 149 154 * 150 155 * @param kernel_uarg Userspace settings (entry point, stack, ...). 151 156 */ 152 void userspace(u space_arg_t *kernel_uarg)157 void userspace(uintptr_t pc, uintptr_t sp) 153 158 { 154 159 /* Prepare return to EL0. */ … … 157 162 158 163 /* Set program entry. */ 159 ELR_EL1_write( kernel_uarg->uspace_entry);164 ELR_EL1_write(pc); 160 165 161 166 /* Set user stack. */ 162 SP_EL0_write(kernel_uarg->uspace_stack + 163 kernel_uarg->uspace_stack_size); 167 SP_EL0_write(sp); 164 168 165 169 /* Clear Thread ID register. */ … … 170 174 * Reset the kernel stack to its base value. 171 175 * 172 * Clear all general-purpose registers, 173 * except x0 that holds an argument for 174 * the user space. 176 * Clear all general-purpose registers. 175 177 */ 176 178 "mov sp, %[kstack]\n" 177 "mov x0, %[uspace_uarg]\n"179 "mov x0, #0\n" 178 180 "mov x1, #0\n" 179 181 "mov x2, #0\n" … … 207 209 "mov x30, #0\n" 208 210 "eret\n" 209 :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg), 210 [kstack] "r" (((uint64_t) (THREAD->kstack)) + 211 :: [kstack] "r" (((uint64_t) (THREAD->kstack)) + 211 212 MEM_STACK_SIZE - SP_DELTA) 212 213 ); -
kernel/arch/ia32/src/userspace.c
r2cf8f994 r3fcea34 38 38 #include <stdint.h> 39 39 #include <arch.h> 40 #include <abi/proc/uarg.h>41 40 #include <mm/as.h> 42 41 #include <arch/cpu.h> 43 42 #include <arch/asm.h> 43 44 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 45 { 46 return stack_base + stack_size; 47 } 44 48 45 49 /** Enter userspace … … 48 52 * 49 53 */ 50 void userspace(u space_arg_t *kernel_uarg)54 void userspace(uintptr_t pc, uintptr_t sp) 51 55 { 52 56 uint32_t eflags = read_eflags(); … … 61 65 "pushl %[utext_des]\n" 62 66 "pushl %[entry]\n" 63 "movl %[uarg], %%eax\n"64 67 65 68 /* %edi is defined to hold pcb_ptr - set it to 0 */ … … 70 73 : [eflags_mask] "i" (~EFLAGS_NT), 71 74 [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER), 72 [stack_top] "r" (kernel_uarg->uspace_stack + 73 kernel_uarg->uspace_stack_size), 75 [stack_top] "r" (sp), 74 76 [eflags] "r" ((eflags & ~(EFLAGS_NT)) | EFLAGS_IF), 75 77 [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER), 76 [entry] "r" (kernel_uarg->uspace_entry), 77 [uarg] "r" (kernel_uarg->uspace_uarg), 78 [entry] "r" (pc), 78 79 [vreg_des] "r" (GDT_SELECTOR(VREG_DES)) 79 80 : "eax"); -
kernel/arch/ia64/src/ia64.c
r2cf8f994 r3fcea34 218 218 } 219 219 220 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 221 { 222 return ALIGN_DOWN(stack_base + stack_size / 2, STACK_ALIGNMENT); 223 } 224 220 225 /** Enter userspace and never return. */ 221 void userspace(u space_arg_t *kernel_uarg)226 void userspace(uintptr_t pc, uintptr_t sp) 222 227 { 223 228 psr_t psr; … … 241 246 * 242 247 * When calculating stack addresses, mind the stack split between the 243 * memory stack and the RSE stack. Each occuppies244 * uspace_stack_size / 2 bytes.248 * memory stack and the RSE stack. 249 * Memory stack occupies area under sp, while RSE stack occupies area above. 245 250 */ 246 switch_to_userspace(kernel_uarg->uspace_entry, 247 kernel_uarg->uspace_stack + 248 kernel_uarg->uspace_stack_size / 2 - 249 ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), 250 kernel_uarg->uspace_stack + 251 kernel_uarg->uspace_stack_size / 2, 252 kernel_uarg->uspace_uarg, psr.value, rsc.value); 251 switch_to_userspace(pc, 252 sp, sp + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), 253 0, psr.value, rsc.value); 253 254 254 255 while (true) -
kernel/arch/mips32/include/arch/asm.h
r2cf8f994 r3fcea34 81 81 extern void cpu_halt(void) __attribute__((noreturn)); 82 82 extern void asm_delay_loop(uint32_t); 83 extern void userspace_asm(uintptr_t, uintptr_t , uintptr_t);83 extern void userspace_asm(uintptr_t, uintptr_t); 84 84 85 85 extern ipl_t interrupts_disable(void); -
kernel/arch/mips32/src/mips32.c
r2cf8f994 r3fcea34 163 163 } 164 164 165 void userspace(uspace_arg_t *kernel_uarg) 165 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 166 { 167 return stack_base + stack_size; 168 } 169 170 void userspace(uintptr_t pc, uintptr_t sp) 166 171 { 167 172 /* EXL = 1, UM = 1, IE = 1 */ 168 173 cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit | 169 174 cp0_status_um_bit | cp0_status_ie_enabled_bit)); 170 cp0_epc_write(kernel_uarg->uspace_entry); 171 userspace_asm(kernel_uarg->uspace_stack + 172 kernel_uarg->uspace_stack_size, 173 kernel_uarg->uspace_uarg, 174 kernel_uarg->uspace_entry); 175 cp0_epc_write(pc); 176 userspace_asm(sp, pc); 175 177 176 178 while (true) -
kernel/arch/mips32/src/start.S
r2cf8f994 r3fcea34 339 339 FUNCTION_BEGIN(userspace_asm) 340 340 move $sp, $a0 341 move $v0, $a1 342 move $t9, $a2 /* set up correct entry into PIC code */ 343 xor $a0, $a0, $a0 /* $a0 is defined to hold pcb_ptr */ 344 /* set it to 0 */ 341 xor $a0, $a0, $a0 /* $a0 is defined to hold pcb_ptr, set it to 0 */ 342 xor $fp, $fp, $fp // FIXME: wipe all userspace-accessible registers 343 xor $ra, $ra, $ra 345 344 eret 346 345 FUNCTION_END(userspace_asm) -
kernel/arch/ppc32/src/ppc32.c
r2cf8f994 r3fcea34 49 49 #include <mm/km.h> 50 50 #include <time/clock.h> 51 #include <abi/proc/uarg.h>52 51 #include <console/console.h> 53 52 #include <sysinfo/sysinfo.h> … … 290 289 } 291 290 292 void userspace(uspace_arg_t *kernel_uarg) 293 { 294 userspace_asm(kernel_uarg->uspace_uarg, 295 kernel_uarg->uspace_stack + 296 kernel_uarg->uspace_stack_size - SP_DELTA, 297 kernel_uarg->uspace_entry); 298 291 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 292 { 293 return stack_base + stack_size - SP_DELTA; 294 } 295 296 void userspace(uintptr_t pc, uintptr_t sp) 297 { 298 userspace_asm(0, sp, pc); 299 299 unreachable(); 300 300 } -
kernel/arch/riscv64/src/userspace.c
r2cf8f994 r3fcea34 33 33 */ 34 34 35 #include <abi/proc/uarg.h>36 35 #include <userspace.h> 37 36 38 void userspace(uspace_arg_t *kernel_uarg) 37 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 38 { 39 return stack_base + stack_size; 40 } 41 42 void userspace(uintptr_t pc, uintptr_t sp) 39 43 { 40 44 // FIXME -
kernel/arch/sparc64/src/sun4u/asm.S
r2cf8f994 r3fcea34 83 83 */ 84 84 FUNCTION_BEGIN(switch_to_userspace) 85 save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp85 save %o1, 0, %sp 86 86 flushw 87 87 wrpr %g0, 0, %cleanwin ! avoid information leak -
kernel/arch/sparc64/src/sun4u/sparc64.c
r2cf8f994 r3fcea34 159 159 } 160 160 161 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 162 { 163 return ALIGN_DOWN(stack_base + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16) - STACK_BIAS; 164 } 165 161 166 /** Switch to userspace. */ 162 void userspace(u space_arg_t *kernel_uarg)167 void userspace(uintptr_t pc, uintptr_t sp) 163 168 { 164 169 (void) interrupts_disable(); 165 switch_to_userspace(kernel_uarg->uspace_entry, 166 kernel_uarg->uspace_stack + 167 kernel_uarg->uspace_stack_size - 168 (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS), 169 kernel_uarg->uspace_uarg); 170 switch_to_userspace(pc, sp, 0); 170 171 171 172 /* Not reached */ -
kernel/arch/sparc64/src/sun4v/asm.S
r2cf8f994 r3fcea34 41 41 */ 42 42 FUNCTION_BEGIN(switch_to_userspace) 43 save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp43 save %o1, 0, %sp 44 44 flushw 45 45 wrpr %g0, 0, %cleanwin ! avoid information leak -
kernel/arch/sparc64/src/sun4v/sparc64.c
r2cf8f994 r3fcea34 157 157 } 158 158 159 uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size) 160 { 161 return ALIGN_DOWN(stack_base + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16) - STACK_BIAS; 162 } 163 159 164 /** Switch to userspace. */ 160 void userspace(u space_arg_t *kernel_uarg)165 void userspace(uintptr_t pc, uintptr_t sp) 161 166 { 162 167 (void) interrupts_disable(); 163 switch_to_userspace(kernel_uarg->uspace_entry, 164 kernel_uarg->uspace_stack + 165 kernel_uarg->uspace_stack_size - 166 (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS), 167 kernel_uarg->uspace_uarg); 168 switch_to_userspace(pc, sp, 0); 168 169 169 170 /* Not reached */ -
kernel/generic/include/main/uinit.h
r2cf8f994 r3fcea34 36 36 #define KERN_UINIT_H_ 37 37 38 #include <stdint.h> 39 40 typedef struct { 41 uintptr_t pc; 42 uintptr_t sp; 43 } uinit_arg_t; 44 38 45 extern void uinit(void *arg); 39 46 -
kernel/generic/include/proc/thread.h
r2cf8f994 r3fcea34 45 45 #include <arch/cpu.h> 46 46 #include <mm/tlb.h> 47 #include <abi/proc/uarg.h>48 47 #include <udebug/udebug.h> 49 48 #include <abi/proc/thread.h> -
kernel/generic/include/userspace.h
r2cf8f994 r3fcea34 39 39 #include <typedefs.h> 40 40 41 extern uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size); 42 41 43 /** Switch to user-space (CPU user priviledge level) */ 42 extern void userspace( uspace_arg_t *uarg) __attribute__((noreturn));44 extern void userspace(sysarg_t pc, sysarg_t sp) __attribute__((noreturn)); 43 45 44 46 #endif -
kernel/generic/src/main/uinit.c
r2cf8f994 r3fcea34 60 60 #endif 61 61 62 uspace_arg_t *uarg = arg; 63 uspace_arg_t local_uarg; 64 65 local_uarg.uspace_entry = uarg->uspace_entry; 66 local_uarg.uspace_stack = uarg->uspace_stack; 67 local_uarg.uspace_stack_size = uarg->uspace_stack_size; 68 local_uarg.uspace_uarg = uarg->uspace_uarg; 69 local_uarg.uspace_thread_function = USPACE_NULL; 70 local_uarg.uspace_thread_arg = USPACE_NULL; 71 62 uinit_arg_t *uarg = arg; 63 sysarg_t pc = uarg->pc; 64 sysarg_t sp = uarg->sp; 72 65 free(uarg); 73 66 74 userspace( &local_uarg);67 userspace(pc, sp); 75 68 } 76 69 -
kernel/generic/src/proc/program.c
r2cf8f994 r3fcea34 53 53 #include <syscall/copy.h> 54 54 #include <proc/program.h> 55 #include <userspace.h> 55 56 56 57 /** … … 72 73 errno_t program_create(as_t *as, uspace_addr_t entry_addr, char *name, program_t *prg) 73 74 { 74 uspace_arg_t *kernel_uarg = (uspace_arg_t *) 75 malloc(sizeof(uspace_arg_t)); 75 uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t)); 76 76 if (!kernel_uarg) 77 77 return ENOMEM; … … 104 104 } 105 105 106 kernel_uarg->uspace_entry = entry_addr; 107 kernel_uarg->uspace_stack = virt; 108 kernel_uarg->uspace_stack_size = STACK_SIZE_USER; 109 kernel_uarg->uspace_thread_function = USPACE_NULL; 110 kernel_uarg->uspace_thread_arg = USPACE_NULL; 111 kernel_uarg->uspace_uarg = USPACE_NULL; 106 kernel_uarg->pc = entry_addr; 107 kernel_uarg->sp = arch_get_initial_sp(virt, STACK_SIZE_USER); 112 108 113 109 /* -
kernel/generic/src/proc/thread.c
r2cf8f994 r3fcea34 944 944 945 945 /** Process syscall to create new thread. 946 * 947 */ 948 sys_errno_t sys_thread_create(uspace_ptr_uspace_arg_t uspace_uarg, uspace_ptr_char uspace_name, 949 size_t name_len, uspace_ptr_thread_id_t uspace_thread_id) 946 * The started thread will have initial pc and sp set to the exact values passed 947 * to the syscall. The kernel will not touch any stack data below the stack 948 * pointer, but some architectures may require some space to be available 949 * for use above it. See userspace() in kernel, and <libarch/thread.h> in libc. 950 * 951 */ 952 sys_errno_t sys_thread_create(sysarg_t pc, sysarg_t sp, 953 uspace_ptr_char uspace_name, size_t name_len) 950 954 { 951 955 if (name_len > THREAD_NAME_BUFLEN - 1) … … 963 967 * In case of success, kernel_uarg will be freed in uinit(). 964 968 */ 965 uspace_arg_t *kernel_uarg = 966 (uspace_arg_t *) malloc(sizeof(uspace_arg_t)); 969 uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t)); 967 970 if (!kernel_uarg) 968 971 return (sys_errno_t) ENOMEM; 969 972 970 rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t)); 971 if (rc != EOK) { 972 free(kernel_uarg); 973 return (sys_errno_t) rc; 974 } 973 kernel_uarg->pc = pc; 974 kernel_uarg->sp = sp; 975 976 // TODO: fix some unnecessary inconsistencies between architectures 975 977 976 978 thread_t *thread = thread_create(uinit, kernel_uarg, TASK, 977 979 THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf); 978 if (thread) { 979 if (uspace_thread_id) { 980 rc = copy_to_uspace(uspace_thread_id, &thread->tid, 981 sizeof(thread->tid)); 982 if (rc != EOK) { 983 /* 984 * We have encountered a failure, but the thread 985 * has already been created. We need to undo its 986 * creation now. 987 */ 988 989 /* 990 * The new thread structure is initialized, but 991 * is still not visible to the system. 992 * We can safely deallocate it. 993 */ 994 slab_free(thread_cache, thread); 995 free(kernel_uarg); 996 997 return (sys_errno_t) rc; 998 } 999 } 980 if (!thread) { 981 free(kernel_uarg); 982 return (sys_errno_t) ENOMEM; 983 } 1000 984 1001 985 #ifdef CONFIG_UDEBUG 1002 1003 1004 1005 1006 1007 1008 1009 986 /* 987 * Generate udebug THREAD_B event and attach the thread. 988 * This must be done atomically (with the debug locks held), 989 * otherwise we would either miss some thread or receive 990 * THREAD_B events for threads that already existed 991 * and could be detected with THREAD_READ before. 992 */ 993 udebug_thread_b_event_attach(thread, TASK); 1010 994 #else 1011 995 thread_attach(thread, TASK); 1012 996 #endif 1013 thread_start(thread); 1014 thread_put(thread); 1015 1016 return 0; 1017 } else 1018 free(kernel_uarg); 1019 1020 return (sys_errno_t) ENOMEM; 997 thread_start(thread); 998 thread_put(thread); 999 1000 return (sys_errno_t) EOK; 1021 1001 } 1022 1002
Note:
See TracChangeset
for help on using the changeset viewer.