On 12/02/2024 16:54, Akram Ahmad wrote:
The __morello_thread_init_user helper requires setting values in several system control registers. This is currently achieved by a series of inline assembly instructions; this patch defines the read_sysreg_c, write_sysreg_c, and clear_sysreg_c helpers to simplify the __morello_thread_init_user helper, and replaces the original inline assembly with calls to these helpers.
Signed-off-by: Akram Ahmad Akram.Ahmad@arm.com
arch/arm64/include/asm/morello.h | 16 ++++++++++++++++ arch/arm64/kernel/morello.c | 18 ++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/morello.h b/arch/arm64/include/asm/morello.h index 357f403d073d..4cc7822fb77a 100644 --- a/arch/arm64/include/asm/morello.h +++ b/arch/arm64/include/asm/morello.h @@ -27,6 +27,22 @@ struct morello_state { unsigned long cctlr; }; +#define read_sysreg_c(r) ({ \
- uintcap_t __cap; \
- asm volatile("mrs %0, " __stringify(r) : "=r" (__cap)); \
- __cap; \
+})
+#define write_sysreg_c(v, r) do { \
- uintcap_t __cap = (uintcap_t)(v); \
- asm volatile("msr " __stringify(r) ", %x0" \
There is no appropriate operand modifier for "rZ" with capabilities (i.e. potentially czr). Let's use %0 for now.
: : "rZ" (__cap)); \
+} while (0)
+#define clear_sysreg_c(r) ({ \
- write_sysreg_c(0, r); \
+})
A few things: * I'm concerned that using _c as suffix may be confusing because the _s suffix is already used for the macros that encode the instruction themselves. Maybe better to use {read,write,clear}_cap_sysreg(), as introduced by Beata in her KVM patches. * I'd rather have those next to their 64-bit counterparts in sysreg.h. They should be enclosed with #ifdef CONFIG_ARM64_MORELLO as they cannot be used otherwise. * Let's introduce those in a separate preparatory patch, first in the series. This way all the helpers can use them directly. * Make sure that the continuation \ are aligned (with tabs only), preferably all at the same level of indentation.
void morello_cap_get_val_tag(uintcap_t cap, __uint128_t *val, u8 *tag); /* diff --git a/arch/arm64/kernel/morello.c b/arch/arm64/kernel/morello.c index 644edfd44b46..a32780f9af4d 100644 --- a/arch/arm64/kernel/morello.c +++ b/arch/arm64/kernel/morello.c @@ -20,6 +20,13 @@ #include <asm/morello.h> #include <asm/ptrace.h> +#define CID_EL0 cid_el0 +#define DDC_EL0 ddc_el0 +#define RDDC_EL0 rddc_el0 +#define CTPIDR_EL0 ctpidr_el0 +#define RCTPIDR_EL0 rctpidr_el0 +#define CCTLR_EL0 cctlr_el0
Not sure I see the point of those, just use the register names directly?
Kevin
void __morello_cap_lo_hi_tag(uintcap_t cap, u64 *lo_val, u64 *hi_val, u8 *tag) { @@ -53,12 +60,11 @@ void __morello_thread_init_user(struct task_struct *tsk, uintcap_t ddc) * RDDC is set to a null capability as processes are always started in * Executive. */
- asm("msr rctpidr_el0, czr\n\t"
"msr ddc_el0, %0\n\t"
"msr rddc_el0, czr\n\t"
"msr cid_el0, czr\n\t"
"msr cctlr_el0, xzr"
: /* outputs */ :/* inputs */ "r"(ddc) : /*clobbers */);
- clear_sysreg_c(RCTPIDR_EL0);
- clear_sysreg_c(CID_EL0);
- clear_sysreg_c(RDDC_EL0);
- write_sysreg_c(ddc, DDC_EL0);
- write_sysreg(0, CCTLR_EL0);
} static uintcap_t morello_sentry_unsealcap __ro_after_init;