From: Kevin Brodsky kevin.brodsky@arm.com
RDDC is currently considered as an EL0 register. However, Restricted registers are not banked, and as a result this assumes that the kernel itself does not modify it.
To enable the kernel to make use of RDDC, context-switch it on every kernel entry/return, instead of when rescheduling (__switch_to). As a result its value is saved in pt_regs instead of morello_state, and a few places need fixing up accordingly.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/include/asm/morello.h | 1 - arch/arm64/include/asm/ptrace.h | 1 + arch/arm64/include/asm/suspend.h | 2 +- arch/arm64/kernel/asm-offsets.c | 1 + arch/arm64/kernel/entry.S | 6 ++++++ arch/arm64/kernel/morello.c | 4 ---- arch/arm64/kernel/ptrace.c | 4 ++-- arch/arm64/mm/proc.S | 14 ++++++-------- 8 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/include/asm/morello.h b/arch/arm64/include/asm/morello.h index 556af690ed4d..c33a7193b397 100644 --- a/arch/arm64/include/asm/morello.h +++ b/arch/arm64/include/asm/morello.h @@ -19,7 +19,6 @@ struct morello_state { uintcap_t ctpidr; uintcap_t rctpidr; uintcap_t ddc; - uintcap_t rddc; uintcap_t cid; unsigned long cctlr; }; diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index c7fa869f9191..1be90aebfcd5 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -208,6 +208,7 @@ struct pt_regs { uintcap_t csp; uintcap_t rcsp; uintcap_t pcc; + uintcap_t rddc; #endif };
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h index 7d49c553b8df..d7672c60aa9f 100644 --- a/arch/arm64/include/asm/suspend.h +++ b/arch/arm64/include/asm/suspend.h @@ -5,7 +5,7 @@ #include <asm/morello.h>
#define NR_CTX_REGS 13 -#define NR_CTX_CREGS 6 +#define NR_CTX_CREGS 5 #define NR_CALLEE_SAVED_REGS 12
/* diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index defc1f6f5d11..efa3431db4cb 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -85,6 +85,7 @@ int main(void) DEFINE(S_CREGS, offsetof(struct pt_regs, cregs)); DEFINE(S_CSP, offsetof(struct pt_regs, csp)); DEFINE(S_PCC, offsetof(struct pt_regs, pcc)); + DEFINE(S_RDDC, offsetof(struct pt_regs, rddc)); #endif DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); BLANK(); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index cfc1abc396af..949c6869daa7 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -239,6 +239,9 @@ alternative_cb_end
mrs c26, celr_el1 str c26, [sp, #S_PCC] + + mrs c27, rddc_el0 + str c27, [sp, #S_RDDC] #endif
.if \el == 0 @@ -490,6 +493,9 @@ alternative_else_nop_endif msr spsr_el1, x22
#ifdef CONFIG_ARM64_MORELLO + ldr c25, [sp, #S_RDDC] + msr rddc_el0, c25 + morello_merge_c_x 26, x21 // merge PC into PCC msr celr_el1, c26
diff --git a/arch/arm64/kernel/morello.c b/arch/arm64/kernel/morello.c index da9d8b1f2578..7003c53445f9 100644 --- a/arch/arm64/kernel/morello.c +++ b/arch/arm64/kernel/morello.c @@ -172,9 +172,7 @@ void morello_thread_init_user(void) write_cap_sysreg(0, rctpidr_el0);
write_cap_sysreg(ddc, ddc_el0); - write_cap_sysreg(0, rddc_el0); morello_state->ddc = ddc; - morello_state->rddc = (uintcap_t)0;
write_cap_sysreg(0, cid_el0); morello_state->cid = (uintcap_t)0; @@ -205,7 +203,6 @@ void morello_thread_save_user_state(struct task_struct *tsk)
/* (R)CTPIDR is handled by task_save_user_tls */ morello_state->ddc = read_cap_sysreg(ddc_el0); - morello_state->rddc = read_cap_sysreg(rddc_el0); morello_state->cid = read_cap_sysreg(cid_el0); morello_state->cctlr = read_sysreg(cctlr_el0); } @@ -216,7 +213,6 @@ void morello_thread_restore_user_state(struct task_struct *tsk)
/* (R)CTPIDR is handled by task_restore_user_tls */ write_cap_sysreg(morello_state->ddc, ddc_el0); - write_cap_sysreg(morello_state->rddc, rddc_el0); write_cap_sysreg(morello_state->cid, cid_el0); write_sysreg(morello_state->cctlr, cctlr_el0); } diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index be1faed4908e..57aa2c49f6d0 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -1472,7 +1472,7 @@ static int morello_get(struct task_struct *target, MORELLO_STATE_COPY_VAL_TAG(out, ctpidr, morello_state->ctpidr);
MORELLO_STATE_COPY_VAL_TAG(out, rcsp, regs->rcsp); - MORELLO_STATE_COPY_VAL_TAG(out, rddc, morello_state->rddc); + MORELLO_STATE_COPY_VAL_TAG(out, rddc, regs->rddc); MORELLO_STATE_COPY_VAL_TAG(out, rctpidr, morello_state->rctpidr);
MORELLO_STATE_COPY_VAL_TAG(out, cid, morello_state->cid); @@ -1514,7 +1514,7 @@ static int morello_set(struct task_struct *target, MORELLO_STATE_BUILD_CAP(new_state, ctpidr, morello_state->ctpidr);
MORELLO_STATE_BUILD_CAP(new_state, rcsp, regs->rcsp); - MORELLO_STATE_BUILD_CAP(new_state, rddc, morello_state->rddc); + MORELLO_STATE_BUILD_CAP(new_state, rddc, regs->rddc); MORELLO_STATE_BUILD_CAP(new_state, rctpidr, morello_state->rctpidr);
MORELLO_STATE_BUILD_CAP(new_state, cid, morello_state->cid); diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index f16186d16d2a..f67a1a17e909 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -92,12 +92,11 @@ SYM_FUNC_START(cpu_do_suspend) mrs c9, ctpidr_el0 mrs c10, rctpidr_el0 mrs c11, ddc_el0 - mrs c12, rddc_el0 - mrs c13, cid_el0 - mrs c14, cvbar_el1 + mrs c12, cid_el0 + mrs c13, cvbar_el1 stp c9, c10, [x0, #CPU_CTX_CREGS] stp c11, c12, [x0, #CPU_CTX_CREGS + 32] - stp c13, c14, [x0, #CPU_CTX_CREGS + 64] + str c13, [x0, #CPU_CTX_CREGS + 64] #else /* CONFIG_ARM64_MORELLO */ mrs x2, tpidr_el0 mrs x8, vbar_el1 @@ -170,10 +169,9 @@ SYM_FUNC_START(cpu_do_resume) msr rctpidr_el0, c3 ldp c2, c3, [x0, #CPU_CTX_CREGS + 32] msr ddc_el0, c2 - msr rddc_el0, c3 - ldp c2, c3, [x0, #CPU_CTX_CREGS + 64] - msr cid_el0, c2 - msr cvbar_el1, c3 + msr cid_el0, c3 + ldr c2, [x0, #CPU_CTX_CREGS + 64] + msr cvbar_el1, c2 #else /* CONFIG_ARM64_MORELLO */ msr tpidr_el0, x2 msr vbar_el1, x9