Commit 30410373 authored by Heiko Carstens's avatar Heiko Carstens
Browse files

s390/acrs: cleanup access register handling



save_access_regs() and restore_access_regs() are only available by
including switch_to.h. This is done by a couple of C files, which have
nothing to do with switch_to(), but only need these functions.

Move both functions to a new header file and improve the implementation:

- Get rid of typedef

- Add memory access instrumentation support

- Use long displacement instructions lamy/stamy instead of lam/stam - all
  current users end up with better code because of this

Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent f78bcb2e
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright IBM Corp. 1999, 2024
 */

#ifndef __ASM_S390_ACCESS_REGS_H
#define __ASM_S390_ACCESS_REGS_H

#include <linux/instrumented.h>
#include <asm/sigcontext.h>

struct access_regs {
	unsigned int regs[NUM_ACRS];
};

static inline void save_access_regs(unsigned int *acrs)
{
	struct access_regs *regs = (struct access_regs *)acrs;

	instrument_write(regs, sizeof(*regs));
	asm volatile("stamy	0,15,%[regs]"
		     : [regs] "=QS" (*regs)
		     :
		     : "memory");
}

static inline void restore_access_regs(unsigned int *acrs)
{
	struct access_regs *regs = (struct access_regs *)acrs;

	instrument_read(regs, sizeof(*regs));
	asm volatile("lamy	0,15,%[regs]"
		     :
		     : [regs] "QS" (*regs)
		     : "memory");
}

#endif /* __ASM_S390_ACCESS_REGS_H */
+1 −14
Original line number Diff line number Diff line
@@ -10,26 +10,13 @@

#include <linux/thread_info.h>
#include <asm/fpu/api.h>
#include <asm/access-regs.h>
#include <asm/ptrace.h>
#include <asm/guarded_storage.h>

extern struct task_struct *__switch_to(void *, void *);
extern void update_cr_regs(struct task_struct *task);

static inline void save_access_regs(unsigned int *acrs)
{
	typedef struct { int _[NUM_ACRS]; } acrstype;

	asm volatile("stam 0,15,%0" : "=Q" (*(acrstype *)acrs));
}

static inline void restore_access_regs(unsigned int *acrs)
{
	typedef struct { int _[NUM_ACRS]; } acrstype;

	asm volatile("lam 0,15,%0" : : "Q" (*(acrstype *)acrs));
}

#define switch_to(prev, next, last) do {				\
	/* save_fpu_regs() sets the CIF_FPU flag, which enforces	\
	 * a restore of the floating point / vector registers as	\
+1 −1
Original line number Diff line number Diff line
@@ -24,10 +24,10 @@
#include <linux/tty.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <asm/access-regs.h>
#include <asm/ucontext.h>
#include <linux/uaccess.h>
#include <asm/lowcore.h>
#include <asm/switch_to.h>
#include <asm/vdso.h>
#include <asm/fpu/api.h>
#include "compat_linux.h"
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <linux/kernel.h>
#include <asm/asm-extable.h>
#include <linux/memblock.h>
#include <asm/access-regs.h>
#include <asm/fpu/api.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/ipl.h>
@@ -31,7 +33,6 @@
#include <asm/sclp.h>
#include <asm/facility.h>
#include <asm/boot_data.h>
#include <asm/switch_to.h>
#include "entry.h"

#define decompressor_handled_param(param)			\
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/seccomp.h>
#include <linux/compat.h>
#include <trace/syscall.h>
#include <asm/access-regs.h>
#include <asm/page.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
Loading