Skip to content

Commit 9160f7e

Browse files
jgoulywilldeacon
authored andcommitted
arm64: add POE signal support
Add PKEY support to signals, by saving and restoring POR_EL0 from the stackframe. Signed-off-by: Joey Gouly <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Reviewed-by: Mark Brown <[email protected]> Acked-by: Szabolcs Nagy <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Reviewed-by: Anshuman Khandual <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 7f955be commit 9160f7e

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

arch/arm64/include/uapi/asm/sigcontext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ struct esr_context {
9898
__u64 esr;
9999
};
100100

101+
#define POE_MAGIC 0x504f4530
102+
103+
struct poe_context {
104+
struct _aarch64_ctx head;
105+
__u64 por_el0;
106+
};
107+
101108
/*
102109
* extra_context: describes extra space in the signal frame for
103110
* additional structures that don't fit in sigcontext.__reserved[].

arch/arm64/kernel/signal.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct rt_sigframe_user_layout {
6161
unsigned long za_offset;
6262
unsigned long zt_offset;
6363
unsigned long fpmr_offset;
64+
unsigned long poe_offset;
6465
unsigned long extra_offset;
6566
unsigned long end_offset;
6667
};
@@ -185,6 +186,8 @@ struct user_ctxs {
185186
u32 zt_size;
186187
struct fpmr_context __user *fpmr;
187188
u32 fpmr_size;
189+
struct poe_context __user *poe;
190+
u32 poe_size;
188191
};
189192

190193
static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
@@ -258,6 +261,32 @@ static int restore_fpmr_context(struct user_ctxs *user)
258261
return err;
259262
}
260263

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+
261290
#ifdef CONFIG_ARM64_SVE
262291

263292
static int preserve_sve_context(struct sve_context __user *ctx)
@@ -621,6 +650,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
621650
user->za = NULL;
622651
user->zt = NULL;
623652
user->fpmr = NULL;
653+
user->poe = NULL;
624654

625655
if (!IS_ALIGNED((unsigned long)base, 16))
626656
goto invalid;
@@ -671,6 +701,17 @@ static int parse_user_sigframe(struct user_ctxs *user,
671701
/* ignore */
672702
break;
673703

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+
674715
case SVE_MAGIC:
675716
if (!system_supports_sve() && !system_supports_sme())
676717
goto invalid;
@@ -857,6 +898,9 @@ static int restore_sigframe(struct pt_regs *regs,
857898
if (err == 0 && system_supports_sme2() && user.zt)
858899
err = restore_zt_context(&user);
859900

901+
if (err == 0 && system_supports_poe() && user.poe)
902+
err = restore_poe_context(&user);
903+
860904
return err;
861905
}
862906

@@ -980,6 +1024,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
9801024
return err;
9811025
}
9821026

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+
9831034
return sigframe_alloc_end(user);
9841035
}
9851036

@@ -1042,6 +1093,14 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
10421093
err |= preserve_fpmr_context(fpmr_ctx);
10431094
}
10441095

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+
10451104
/* ZA state if present */
10461105
if (system_supports_sme() && err == 0 && user->za_offset) {
10471106
struct za_context __user *za_ctx =
@@ -1178,6 +1237,9 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
11781237
sme_smstop();
11791238
}
11801239

1240+
if (system_supports_poe())
1241+
write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0);
1242+
11811243
if (ka->sa.sa_flags & SA_RESTORER)
11821244
sigtramp = ka->sa.sa_restorer;
11831245
else

0 commit comments

Comments
 (0)