2021-12-04 02:19:05

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 0/3] OpenRISC Switch and Clone cleanups

These are a few patches that came after auditing the OpenRISC switch code
recently following the discussion with Rob and Arnd and the clone and clone3
wrappers [0].

I noticed a few places where OpenRISC could shave a few instructions and also
that we need a ABI wrapper for clone3.

[0] https://lore.kernel.org/all/[email protected]/T/#m9c0cdb2703813b9df4da04cf6b30de1f1aa89944

Stafford Horne (3):
openrisc: Cleanup switch code and comments
openrisc: Use delay slot for clone and fork wrappers
openrisc: Add clone3 ABI wrapper

arch/openrisc/include/asm/syscalls.h | 2 ++
arch/openrisc/kernel/entry.S | 27 +++++++++++++--------------
2 files changed, 15 insertions(+), 14 deletions(-)

--
2.31.1



2021-12-04 02:19:15

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 2/3] openrisc: Use delay slot for clone and fork wrappers

This saves one instruction.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/entry.S | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index c608f76e5753..8cd2113057c5 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -1162,15 +1162,13 @@ _fork_save_extra_regs_and_call:

ENTRY(__sys_clone)
l.movhi r29,hi(sys_clone)
- l.ori r29,r29,lo(sys_clone)
l.j _fork_save_extra_regs_and_call
- l.nop
+ l.ori r29,r29,lo(sys_clone)

ENTRY(__sys_fork)
l.movhi r29,hi(sys_fork)
- l.ori r29,r29,lo(sys_fork)
l.j _fork_save_extra_regs_and_call
- l.nop
+ l.ori r29,r29,lo(sys_fork)

ENTRY(sys_rt_sigreturn)
l.jal _sys_rt_sigreturn
--
2.31.1


2021-12-04 02:19:15

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 1/3] openrisc: Cleanup switch code and comments

The saving of the r12 register was there for a compiler bug referring
to a port that was never upstreamed. It should be safe to use this
as the new compiler is what we use and the old deprecated.

Also, clean up some typos and references to old names in the switch
comments.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/entry.S | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index 59c6d3aa7081..c608f76e5753 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -1001,11 +1001,10 @@ ENTRY(ret_from_fork)
l.lwz r11,PT_GPR11(r1)

/* The syscall fast path return expects call-saved registers
- * r12-r28 to be untouched, so we restore them here as they
+ * r14-r28 to be untouched, so we restore them here as they
* will have been effectively clobbered when arriving here
* via the call to switch()
*/
- l.lwz r12,PT_GPR12(r1)
l.lwz r14,PT_GPR14(r1)
l.lwz r16,PT_GPR16(r1)
l.lwz r18,PT_GPR18(r1)
@@ -1037,10 +1036,10 @@ ENTRY(ret_from_fork)

/* _switch MUST never lay on page boundry, cause it runs from
* effective addresses and beeing interrupted by iTLB miss would kill it.
- * dTLB miss seams to never accour in the bad place since data accesses
+ * dTLB miss seems to never accour in the bad place since data accesses
* are from task structures which are always page aligned.
*
- * The problem happens in RESTORE_ALL_NO_R11 where we first set the EPCR
+ * The problem happens in RESTORE_ALL where we first set the EPCR
* register, then load the previous register values and only at the end call
* the l.rfe instruction. If get TLB miss in beetwen the EPCR register gets
* garbled and we end up calling l.rfe with the wrong EPCR. (same probably
@@ -1068,9 +1067,8 @@ ENTRY(_switch)
/* No need to store r1/PT_SP as it goes into KSP below */
l.sw PT_GPR2(r1),r2
l.sw PT_GPR9(r1),r9
- /* This is wrong, r12 shouldn't be here... but GCC is broken for the time being
- * and expects r12 to be callee-saved... */
- l.sw PT_GPR12(r1),r12
+
+ /* Save callee-saved registers to the new pt_regs */
l.sw PT_GPR14(r1),r14
l.sw PT_GPR16(r1),r16
l.sw PT_GPR18(r1),r18
@@ -1111,9 +1109,7 @@ ENTRY(_switch)
/* No need to restore r10 */
/* ...and do not restore r11 */

- /* This is wrong, r12 shouldn't be here... but GCC is broken for the time being
- * and expects r12 to be callee-saved... */
- l.lwz r12,PT_GPR12(r1)
+ /* Restore callee-saved registers */
l.lwz r14,PT_GPR14(r1)
l.lwz r16,PT_GPR16(r1)
l.lwz r18,PT_GPR18(r1)
--
2.31.1


2021-12-04 02:19:21

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 3/3] openrisc: Add clone3 ABI wrapper

Like fork and clone the clone3 syscall needs a wrapper to save callee
saved registers, which is required by the OpenRISC ABI. This came up
after auditing code following a discussion with Rob Landley and Arnd
Bergmann [0].

Tested with the clone3 kselftests and there were no issues.

[0] https://lore.kernel.org/all/[email protected]/T/#m9c0cdb2703813b9df4da04cf6b30de1f1aa89944

Fixes: 07e83dfbe16c ("openrisc: Enable the clone3 syscall")
Cc: Rob Landley <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/include/asm/syscalls.h | 2 ++
arch/openrisc/kernel/entry.S | 5 +++++
2 files changed, 7 insertions(+)

diff --git a/arch/openrisc/include/asm/syscalls.h b/arch/openrisc/include/asm/syscalls.h
index 3a7eeae6f56a..aa1c7e98722e 100644
--- a/arch/openrisc/include/asm/syscalls.h
+++ b/arch/openrisc/include/asm/syscalls.h
@@ -22,9 +22,11 @@ asmlinkage long sys_or1k_atomic(unsigned long type, unsigned long *v1,

asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid, int tls);
+asmlinkage long __sys_clone3(struct clone_args __user *uargs, size_t size);
asmlinkage long __sys_fork(void);

#define sys_clone __sys_clone
+#define sys_clone3 __sys_clone3
#define sys_fork __sys_fork

#endif /* __ASM_OPENRISC_SYSCALLS_H */
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index 8cd2113057c5..3ca1b1f490b9 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -1165,6 +1165,11 @@ ENTRY(__sys_clone)
l.j _fork_save_extra_regs_and_call
l.ori r29,r29,lo(sys_clone)

+ENTRY(__sys_clone3)
+ l.movhi r29,hi(sys_clone3)
+ l.j _fork_save_extra_regs_and_call
+ l.ori r29,r29,lo(sys_clone3)
+
ENTRY(__sys_fork)
l.movhi r29,hi(sys_fork)
l.j _fork_save_extra_regs_and_call
--
2.31.1