@@ -76,35 +76,38 @@ pub fn sys_set_tid_address(tid_ptd: UserConstPtr<i32>) -> LinuxResult<isize> {
7676
7777#[ cfg( target_arch = "x86_64" ) ]
7878#[ apply( syscall_instrument) ]
79- pub fn sys_arch_prctl ( code : i32 , addr : u64 ) -> LinuxResult < isize > {
79+ pub fn sys_arch_prctl ( code : i32 , addr : UserPtr < u64 > ) -> LinuxResult < isize > {
8080 use axerrno:: LinuxError ;
81- match ArchPrctlCode :: try_from ( code) {
82- // TODO: check the legality of the address
83- Ok ( ArchPrctlCode :: SetFs ) => {
81+ match ArchPrctlCode :: try_from ( code) . map_err ( |_| LinuxError :: EINVAL ) ? {
82+ // According to Linux implementation, SetFs & SetGs does not return
83+ // error at all
84+ ArchPrctlCode :: SetFs => {
8485 unsafe {
85- axhal:: arch:: write_thread_pointer ( addr as usize ) ;
86+ axhal:: arch:: write_thread_pointer ( addr. address ( ) . as_usize ( ) ) ;
8687 }
8788 Ok ( 0 )
8889 }
89- Ok ( ArchPrctlCode :: GetFs ) => {
90+ ArchPrctlCode :: SetGs => {
9091 unsafe {
91- * ( addr as * mut u64 ) = axhal :: arch :: read_thread_pointer ( ) as u64 ;
92+ x86 :: msr :: wrmsr ( x86 :: msr :: IA32_KERNEL_GSBASE , addr . address ( ) . as_usize ( ) as _ ) ;
9293 }
9394 Ok ( 0 )
9495 }
95- Ok ( ArchPrctlCode :: SetGs ) => {
96+ ArchPrctlCode :: GetFs => {
9697 unsafe {
97- x86 :: msr :: wrmsr ( x86 :: msr :: IA32_KERNEL_GSBASE , addr ) ;
98+ * addr . get ( ) ? = axhal :: arch :: read_thread_pointer ( ) as u64 ;
9899 }
99100 Ok ( 0 )
100101 }
101- Ok ( ArchPrctlCode :: GetGs ) => {
102+
103+ ArchPrctlCode :: GetGs => {
102104 unsafe {
103- * ( addr as * mut u64 ) = x86:: msr:: rdmsr ( x86:: msr:: IA32_KERNEL_GSBASE ) ;
105+ * addr. get ( ) ? = x86:: msr:: rdmsr ( x86:: msr:: IA32_KERNEL_GSBASE ) ;
104106 }
105107 Ok ( 0 )
106108 }
107- _ => Err ( LinuxError :: ENOSYS ) ,
109+ ArchPrctlCode :: GetCpuid => Ok ( 0 ) ,
110+ ArchPrctlCode :: SetCpuid => Err ( LinuxError :: ENODEV ) ,
108111 }
109112}
110113
0 commit comments