arch/s390/include/asm/fpu-insn.h

Source file repositories/reference/linux-study-clean/arch/s390/include/asm/fpu-insn.h

File Facts

System
Linux kernel
Corpus path
arch/s390/include/asm/fpu-insn.h
Extension
.h
Size
11726 bytes
Lines
484
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef __ASM_S390_FPU_INSN_H
#define __ASM_S390_FPU_INSN_H

#include <asm/fpu-insn-asm.h>

#ifndef __ASSEMBLER__

#include <linux/instrumented.h>
#include <linux/kmsan.h>
#include <asm/asm-extable.h>

asm(".include \"asm/insn-common-asm.h\"\n");
asm(".include \"asm/fpu-insn-asm.h\"\n");

/*
 * Various small helper functions, which can and should be used within
 * kernel fpu code sections. Each function represents only one floating
 * point or vector instruction (except for helper functions which require
 * exception handling).
 *
 * This allows to use floating point and vector instructions like C
 * functions, which has the advantage that all supporting code, like
 * e.g. loops, can be written in easy to read C code.
 *
 * Each of the helper functions provides support for code instrumentation,
 * like e.g. KASAN. Therefore instrumentation is also covered automatically
 * when using these functions.
 *
 * In order to ensure that code generated with the helper functions stays
 * within kernel fpu sections, which are guarded with kernel_fpu_begin()
 * and kernel_fpu_end() calls, each function has a mandatory "memory"
 * barrier.
 */

static __always_inline void fpu_cefbr(u8 f1, s32 val)
{
	asm volatile("cefbr	%[f1],%[val]"
		     :
		     : [f1] "I" (f1), [val] "d" (val)
		     : "memory");
}

static __always_inline unsigned long fpu_cgebr(u8 f2, u8 mode)
{
	unsigned long val;

	asm volatile("cgebr	%[val],%[mode],%[f2]"
		     : [val] "=d" (val)
		     : [f2] "I" (f2), [mode] "I" (mode)
		     : "memory");
	return val;
}

static __always_inline void fpu_debr(u8 f1, u8 f2)
{
	asm volatile("debr	%[f1],%[f2]"
		     :
		     : [f1] "I" (f1), [f2] "I" (f2)
		     : "memory");
}

static __always_inline void fpu_ld(unsigned short fpr, freg_t *reg)
{
	instrument_read(reg, sizeof(*reg));
	asm volatile("ld	 %[fpr],%[reg]"
		     :
		     : [fpr] "I" (fpr), [reg] "Q" (reg->ui)
		     : "memory");
}

static __always_inline void fpu_ldgr(u8 f1, u32 val)
{
	asm volatile("ldgr	%[f1],%[val]"
		     :
		     : [f1] "I" (f1), [val] "d" (val)
		     : "memory");
}

static __always_inline void fpu_lfpc(unsigned int *fpc)
{
	instrument_read(fpc, sizeof(*fpc));
	asm volatile("lfpc	%[fpc]"
		     :
		     : [fpc] "Q" (*fpc)
		     : "memory");
}

/**
 * fpu_lfpc_safe - Load floating point control register safely.
 * @fpc: new value for floating point control register

Annotation

Implementation Notes