@@ -61,6 +61,7 @@ struct rt_sigframe_user_layout {
61
61
unsigned long za_offset ;
62
62
unsigned long zt_offset ;
63
63
unsigned long fpmr_offset ;
64
+ unsigned long poe_offset ;
64
65
unsigned long extra_offset ;
65
66
unsigned long end_offset ;
66
67
};
@@ -185,6 +186,8 @@ struct user_ctxs {
185
186
u32 zt_size ;
186
187
struct fpmr_context __user * fpmr ;
187
188
u32 fpmr_size ;
189
+ struct poe_context __user * poe ;
190
+ u32 poe_size ;
188
191
};
189
192
190
193
static int preserve_fpsimd_context (struct fpsimd_context __user * ctx )
@@ -258,6 +261,32 @@ static int restore_fpmr_context(struct user_ctxs *user)
258
261
return err ;
259
262
}
260
263
264
+ static int preserve_poe_context (struct poe_context __user * ctx )
265
+ {
266
+ int err = 0 ;
267
+
268
+ __put_user_error (POE_MAGIC , & ctx -> head .magic , err );
269
+ __put_user_error (sizeof (* ctx ), & ctx -> head .size , err );
270
+ __put_user_error (read_sysreg_s (SYS_POR_EL0 ), & ctx -> por_el0 , err );
271
+
272
+ return err ;
273
+ }
274
+
275
+ static int restore_poe_context (struct user_ctxs * user )
276
+ {
277
+ u64 por_el0 ;
278
+ int err = 0 ;
279
+
280
+ if (user -> poe_size != sizeof (* user -> poe ))
281
+ return - EINVAL ;
282
+
283
+ __get_user_error (por_el0 , & (user -> poe -> por_el0 ), err );
284
+ if (!err )
285
+ write_sysreg_s (por_el0 , SYS_POR_EL0 );
286
+
287
+ return err ;
288
+ }
289
+
261
290
#ifdef CONFIG_ARM64_SVE
262
291
263
292
static int preserve_sve_context (struct sve_context __user * ctx )
@@ -621,6 +650,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
621
650
user -> za = NULL ;
622
651
user -> zt = NULL ;
623
652
user -> fpmr = NULL ;
653
+ user -> poe = NULL ;
624
654
625
655
if (!IS_ALIGNED ((unsigned long )base , 16 ))
626
656
goto invalid ;
@@ -671,6 +701,17 @@ static int parse_user_sigframe(struct user_ctxs *user,
671
701
/* ignore */
672
702
break ;
673
703
704
+ case POE_MAGIC :
705
+ if (!system_supports_poe ())
706
+ goto invalid ;
707
+
708
+ if (user -> poe )
709
+ goto invalid ;
710
+
711
+ user -> poe = (struct poe_context __user * )head ;
712
+ user -> poe_size = size ;
713
+ break ;
714
+
674
715
case SVE_MAGIC :
675
716
if (!system_supports_sve () && !system_supports_sme ())
676
717
goto invalid ;
@@ -857,6 +898,9 @@ static int restore_sigframe(struct pt_regs *regs,
857
898
if (err == 0 && system_supports_sme2 () && user .zt )
858
899
err = restore_zt_context (& user );
859
900
901
+ if (err == 0 && system_supports_poe () && user .poe )
902
+ err = restore_poe_context (& user );
903
+
860
904
return err ;
861
905
}
862
906
@@ -980,6 +1024,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
980
1024
return err ;
981
1025
}
982
1026
1027
+ if (system_supports_poe ()) {
1028
+ err = sigframe_alloc (user , & user -> poe_offset ,
1029
+ sizeof (struct poe_context ));
1030
+ if (err )
1031
+ return err ;
1032
+ }
1033
+
983
1034
return sigframe_alloc_end (user );
984
1035
}
985
1036
@@ -1042,6 +1093,14 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
1042
1093
err |= preserve_fpmr_context (fpmr_ctx );
1043
1094
}
1044
1095
1096
+ if (system_supports_poe () && err == 0 && user -> poe_offset ) {
1097
+ struct poe_context __user * poe_ctx =
1098
+ apply_user_offset (user , user -> poe_offset );
1099
+
1100
+ err |= preserve_poe_context (poe_ctx );
1101
+ }
1102
+
1103
+
1045
1104
/* ZA state if present */
1046
1105
if (system_supports_sme () && err == 0 && user -> za_offset ) {
1047
1106
struct za_context __user * za_ctx =
@@ -1178,6 +1237,9 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
1178
1237
sme_smstop ();
1179
1238
}
1180
1239
1240
+ if (system_supports_poe ())
1241
+ write_sysreg_s (POR_EL0_INIT , SYS_POR_EL0 );
1242
+
1181
1243
if (ka -> sa .sa_flags & SA_RESTORER )
1182
1244
sigtramp = ka -> sa .sa_restorer ;
1183
1245
else
0 commit comments