3636#include <asm/traps.h>
3737#include <asm/vdso.h>
3838
39- #ifdef CONFIG_ARM64_GCS
4039#define GCS_SIGNAL_CAP (addr ) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
4140
42- static bool gcs_signal_cap_valid (u64 addr , u64 val )
43- {
44- return val == GCS_SIGNAL_CAP (addr );
45- }
46- #endif
47-
4841/*
4942 * Do a signal return; undo the signal stack. These are aligned to 128-bit.
5043 */
@@ -1062,8 +1055,7 @@ static int restore_sigframe(struct pt_regs *regs,
10621055#ifdef CONFIG_ARM64_GCS
10631056static int gcs_restore_signal (void )
10641057{
1065- unsigned long __user * gcspr_el0 ;
1066- u64 cap ;
1058+ u64 gcspr_el0 , cap ;
10671059 int ret ;
10681060
10691061 if (!system_supports_gcs ())
@@ -1072,7 +1064,7 @@ static int gcs_restore_signal(void)
10721064 if (!(current -> thread .gcs_el0_mode & PR_SHADOW_STACK_ENABLE ))
10731065 return 0 ;
10741066
1075- gcspr_el0 = ( unsigned long __user * ) read_sysreg_s (SYS_GCSPR_EL0 );
1067+ gcspr_el0 = read_sysreg_s (SYS_GCSPR_EL0 );
10761068
10771069 /*
10781070 * Ensure that any changes to the GCS done via GCS operations
@@ -1087,22 +1079,23 @@ static int gcs_restore_signal(void)
10871079 * then faults will be generated on GCS operations - the main
10881080 * concern is to protect GCS pages.
10891081 */
1090- ret = copy_from_user (& cap , gcspr_el0 , sizeof (cap ));
1082+ ret = copy_from_user (& cap , (unsigned long __user * )gcspr_el0 ,
1083+ sizeof (cap ));
10911084 if (ret )
10921085 return - EFAULT ;
10931086
10941087 /*
10951088 * Check that the cap is the actual GCS before replacing it.
10961089 */
1097- if (! gcs_signal_cap_valid (( u64 ) gcspr_el0 , cap ))
1090+ if (cap != GCS_SIGNAL_CAP ( gcspr_el0 ))
10981091 return - EINVAL ;
10991092
11001093 /* Invalidate the token to prevent reuse */
1101- put_user_gcs (0 , (__user void * )gcspr_el0 , & ret );
1094+ put_user_gcs (0 , (unsigned long __user * )gcspr_el0 , & ret );
11021095 if (ret != 0 )
11031096 return - EFAULT ;
11041097
1105- write_sysreg_s (gcspr_el0 + 1 , SYS_GCSPR_EL0 );
1098+ write_sysreg_s (gcspr_el0 + 8 , SYS_GCSPR_EL0 );
11061099
11071100 return 0 ;
11081101}
@@ -1421,7 +1414,7 @@ static int get_sigframe(struct rt_sigframe_user_layout *user,
14211414
14221415static int gcs_signal_entry (__sigrestore_t sigtramp , struct ksignal * ksig )
14231416{
1424- unsigned long __user * gcspr_el0 ;
1417+ u64 gcspr_el0 ;
14251418 int ret = 0 ;
14261419
14271420 if (!system_supports_gcs ())
@@ -1434,18 +1427,20 @@ static int gcs_signal_entry(__sigrestore_t sigtramp, struct ksignal *ksig)
14341427 * We are entering a signal handler, current register state is
14351428 * active.
14361429 */
1437- gcspr_el0 = ( unsigned long __user * ) read_sysreg_s (SYS_GCSPR_EL0 );
1430+ gcspr_el0 = read_sysreg_s (SYS_GCSPR_EL0 );
14381431
14391432 /*
14401433 * Push a cap and the GCS entry for the trampoline onto the GCS.
14411434 */
1442- put_user_gcs ((unsigned long )sigtramp , gcspr_el0 - 2 , & ret );
1443- put_user_gcs (GCS_SIGNAL_CAP (gcspr_el0 - 1 ), gcspr_el0 - 1 , & ret );
1435+ put_user_gcs ((unsigned long )sigtramp ,
1436+ (unsigned long __user * )(gcspr_el0 - 16 ), & ret );
1437+ put_user_gcs (GCS_SIGNAL_CAP (gcspr_el0 - 8 ),
1438+ (unsigned long __user * )(gcspr_el0 - 8 ), & ret );
14441439 if (ret != 0 )
14451440 return ret ;
14461441
1447- gcspr_el0 -= 2 ;
1448- write_sysreg_s (( unsigned long ) gcspr_el0 , SYS_GCSPR_EL0 );
1442+ gcspr_el0 -= 16 ;
1443+ write_sysreg_s (gcspr_el0 , SYS_GCSPR_EL0 );
14491444
14501445 return 0 ;
14511446}
0 commit comments