1
+ use aero_syscall:: AeroSyscallError ;
1
2
use raw_cpuid:: CpuId ;
2
3
3
4
use crate :: arch:: gdt:: GdtEntryType ;
5
+ use crate :: mem:: paging:: VirtAddr ;
6
+ use crate :: userland:: scheduler;
4
7
use crate :: utils:: io;
5
8
6
9
use super :: interrupts:: InterruptStack ;
@@ -9,30 +12,78 @@ extern "C" {
9
12
fn x86_64_syscall_handler ( ) ;
10
13
}
11
14
15
+ const ARCH_SET_GS : usize = 0x1001 ;
16
+ const ARCH_SET_FS : usize = 0x1002 ;
17
+ const ARCH_GET_FS : usize = 0x1003 ;
18
+ const ARCH_GET_GS : usize = 0x1004 ;
19
+
20
+ fn arch_prctl ( command : usize , address : usize ) -> Result < usize , AeroSyscallError > {
21
+ match command {
22
+ ARCH_SET_FS => unsafe {
23
+ scheduler:: get_scheduler ( )
24
+ . current_task ( )
25
+ . arch_task_mut ( )
26
+ . set_fs_base ( VirtAddr :: new ( address as u64 ) ) ;
27
+
28
+ Ok ( 0x00 )
29
+ } ,
30
+
31
+ ARCH_GET_FS => Ok ( scheduler:: get_scheduler ( )
32
+ . current_task ( )
33
+ . arch_task ( )
34
+ . get_fs_base ( )
35
+ . as_u64 ( ) as usize ) ,
36
+
37
+ ARCH_SET_GS => unsafe {
38
+ scheduler:: get_scheduler ( )
39
+ . current_task ( )
40
+ . arch_task_mut ( )
41
+ . set_gs_base ( VirtAddr :: new ( address as u64 ) ) ;
42
+
43
+ Ok ( 0x00 )
44
+ } ,
45
+
46
+ ARCH_GET_GS => Ok ( scheduler:: get_scheduler ( )
47
+ . current_task ( )
48
+ . arch_task ( )
49
+ . get_gs_base ( )
50
+ . as_u64 ( ) as usize ) ,
51
+
52
+ _ => Err ( AeroSyscallError :: EINVAL ) ,
53
+ }
54
+ }
55
+
12
56
#[ no_mangle]
13
57
extern "C" fn x86_64_do_syscall ( stack : & mut InterruptStack ) {
14
- let syscall_number = stack. scratch . rax as usize ;
58
+ let syscall_number = stack. scratch . rax as usize ; // syscall number
59
+ let a = stack. scratch . rdi as usize ; // argument 1
60
+ let b = stack. scratch . rsi as usize ; // argument 2
61
+ let c = stack. scratch . rdx as usize ; // argument 3
62
+ let d = stack. scratch . r10 as usize ; // argument 4
63
+ let e = stack. scratch . r8 as usize ; // argument 5
64
+ let f = stack. scratch . r9 as usize ; // argument 6
15
65
16
66
match syscall_number {
17
- aero_syscall :: prelude :: SYS_EXIT => { }
67
+ // handle arch-specific syscalls (`sigreturn` and `arch_prctl`):
18
68
aero_syscall:: prelude:: SYS_SIGRETURN => {
19
69
let result = super :: signals:: sigreturn ( stack) ;
20
70
stack. scratch . rax = result as u64 ;
21
71
return ;
22
72
}
23
73
74
+ aero_syscall:: prelude:: SYS_ARCH_PRCTL => {
75
+ let result = self :: arch_prctl ( a, b) ;
76
+ let result_usize = aero_syscall:: syscall_result_as_usize ( result) ;
77
+
78
+ stack. scratch . rax = result_usize as _ ;
79
+ return ;
80
+ }
81
+
82
+ aero_syscall:: prelude:: SYS_EXIT => { }
24
83
_ => unsafe { super :: interrupts:: enable_interrupts ( ) } ,
25
84
}
26
85
27
- let result_usize = crate :: syscall:: generic_do_syscall (
28
- syscall_number,
29
- stack. scratch . rdi as usize , // argument 1
30
- stack. scratch . rsi as usize , // argument 2
31
- stack. scratch . rdx as usize , // argument 3
32
- stack. scratch . r10 as usize , // argument 4
33
- stack. scratch . r8 as usize , // argument 5
34
- stack. scratch . r9 as usize , // argument 6
35
- ) ;
86
+ let result_usize = crate :: syscall:: generic_do_syscall ( syscall_number, a, b, c, d, e, f) ;
36
87
37
88
super :: signals:: syscall_check_signals ( result_usize as isize , stack) ;
38
89
stack. scratch . rax = result_usize as _ ;
0 commit comments