__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * In-kernel FPU support functions
 *
 *
 * Consider these guidelines before using in-kernel FPU functions:
 *
 *  1. Use kernel_fpu_begin() and kernel_fpu_end() to enclose all in-kernel
 *     use of floating-point or vector registers and instructions.
 *
 *  2. For kernel_fpu_begin(), specify the vector register range you want to
 *     use with the KERNEL_VXR_* constants. Consider these usage guidelines:
 *
 *     a) If your function typically runs in process-context, use the lower
 *	  half of the vector registers, for example, specify KERNEL_VXR_LOW.
 *     b) If your function typically runs in soft-irq or hard-irq context,
 *	  prefer using the upper half of the vector registers, for example,
 *	  specify KERNEL_VXR_HIGH.
 *
 *     If you adhere to these guidelines, an interrupted process context
 *     does not require to save and restore vector registers because of
 *     disjoint register ranges.
 *
 *     Also note that the __kernel_fpu_begin()/__kernel_fpu_end() functions
 *     includes logic to save and restore up to 16 vector registers at once.
 *
 *  3. You can nest kernel_fpu_begin()/kernel_fpu_end() by using different
 *     struct kernel_fpu states.  Vector registers that are in use by outer
 *     levels are saved and restored.  You can minimize the save and restore
 *     effort by choosing disjoint vector register ranges.
 *
 *  5. To use vector floating-point instructions, specify the KERNEL_FPC
 *     flag to save and restore floating-point controls in addition to any
 *     vector register range.
 *
 *  6. To use floating-point registers and instructions only, specify the
 *     KERNEL_FPR flag.  This flag triggers a save and restore of vector
 *     registers V0 to V15 and floating-point controls.
 *
 * Copyright IBM Corp. 2015
 * Author(s): Hendrik Brueckner <[email protected]>
 */

#ifndef _ASM_S390_FPU_H
#define _ASM_S390_FPU_H

#include <linux/processor.h>
#include <linux/preempt.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <asm/sigcontext.h>
#include <asm/fpu-types.h>
#include <asm/fpu-insn.h>
#include <asm/facility.h>

static inline bool cpu_has_vx(void)
{
	return likely(test_facility(129));
}

enum {
	KERNEL_FPC_BIT = 0,
	KERNEL_VXR_V0V7_BIT,
	KERNEL_VXR_V8V15_BIT,
	KERNEL_VXR_V16V23_BIT,
	KERNEL_VXR_V24V31_BIT,
};

#define KERNEL_FPC		BIT(KERNEL_FPC_BIT)
#define KERNEL_VXR_V0V7		BIT(KERNEL_VXR_V0V7_BIT)
#define KERNEL_VXR_V8V15	BIT(KERNEL_VXR_V8V15_BIT)
#define KERNEL_VXR_V16V23	BIT(KERNEL_VXR_V16V23_BIT)
#define KERNEL_VXR_V24V31	BIT(KERNEL_VXR_V24V31_BIT)

#define KERNEL_VXR_LOW		(KERNEL_VXR_V0V7   | KERNEL_VXR_V8V15)
#define KERNEL_VXR_MID		(KERNEL_VXR_V8V15  | KERNEL_VXR_V16V23)
#define KERNEL_VXR_HIGH		(KERNEL_VXR_V16V23 | KERNEL_VXR_V24V31)

#define KERNEL_VXR		(KERNEL_VXR_LOW	   | KERNEL_VXR_HIGH)
#define KERNEL_FPR		(KERNEL_FPC	   | KERNEL_VXR_LOW)

void load_fpu_state(struct fpu *state, int flags);
void save_fpu_state(struct fpu *state, int flags);
void __kernel_fpu_begin(struct kernel_fpu *state, int flags);
void __kernel_fpu_end(struct kernel_fpu *state, int flags);

static __always_inline void save_vx_regs(__vector128 *vxrs)
{
	fpu_vstm(0, 15, &vxrs[0]);
	fpu_vstm(16, 31, &vxrs[16]);
}

static __always_inline void load_vx_regs(__vector128 *vxrs)
{
	fpu_vlm(0, 15, &vxrs[0]);
	fpu_vlm(16, 31, &vxrs[16]);
}

static __always_inline void __save_fp_regs(freg_t *fprs, unsigned int offset)
{
	fpu_std(0, &fprs[0 * offset]);
	fpu_std(1, &fprs[1 * offset]);
	fpu_std(2, &fprs[2 * offset]);
	fpu_std(3, &fprs[3 * offset]);
	fpu_std(4, &fprs[4 * offset]);
	fpu_std(5, &fprs[5 * offset]);
	fpu_std(6, &fprs[6 * offset]);
	fpu_std(7, &fprs[7 * offset]);
	fpu_std(8, &fprs[8 * offset]);
	fpu_std(9, &fprs[9 * offset]);
	fpu_std(10, &fprs[10 * offset]);
	fpu_std(11, &fprs[11 * offset]);
	fpu_std(12, &fprs[12 * offset]);
	fpu_std(13, &fprs[13 * offset]);
	fpu_std(14, &fprs[14 * offset]);
	fpu_std(15, &fprs[15 * offset]);
}

static __always_inline void __load_fp_regs(freg_t *fprs, unsigned int offset)
{
	fpu_ld(0, &fprs[0 * offset]);
	fpu_ld(1, &fprs[1 * offset]);
	fpu_ld(2, &fprs[2 * offset]);
	fpu_ld(3, &fprs[3 * offset]);
	fpu_ld(4, &fprs[4 * offset]);
	fpu_ld(5, &fprs[5 * offset]);
	fpu_ld(6, &fprs[6 * offset]);
	fpu_ld(7, &fprs[7 * offset]);
	fpu_ld(8, &fprs[8 * offset]);
	fpu_ld(9, &fprs[9 * offset]);
	fpu_ld(10, &fprs[10 * offset]);
	fpu_ld(11, &fprs[11 * offset]);
	fpu_ld(12, &fprs[12 * offset]);
	fpu_ld(13, &fprs[13 * offset]);
	fpu_ld(14, &fprs[14 * offset]);
	fpu_ld(15, &fprs[15 * offset]);
}

static __always_inline void save_fp_regs(freg_t *fprs)
{
	__save_fp_regs(fprs, sizeof(freg_t) / sizeof(freg_t));
}

static __always_inline void load_fp_regs(freg_t *fprs)
{
	__load_fp_regs(fprs, sizeof(freg_t) / sizeof(freg_t));
}

static __always_inline void save_fp_regs_vx(__vector128 *vxrs)
{
	freg_t *fprs = (freg_t *)&vxrs[0].high;

	__save_fp_regs(fprs, sizeof(__vector128) / sizeof(freg_t));
}

static __always_inline void load_fp_regs_vx(__vector128 *vxrs)
{
	freg_t *fprs = (freg_t *)&vxrs[0].high;

	__load_fp_regs(fprs, sizeof(__vector128) / sizeof(freg_t));
}

static inline void load_user_fpu_regs(void)
{
	struct thread_struct *thread = &current->thread;

	if (!thread->ufpu_flags)
		return;
	load_fpu_state(&thread->ufpu, thread->ufpu_flags);
	thread->ufpu_flags = 0;
}

static __always_inline void __save_user_fpu_regs(struct thread_struct *thread, int flags)
{
	save_fpu_state(&thread->ufpu, flags);
	__atomic_or(flags, &thread->ufpu_flags);
}

static inline void save_user_fpu_regs(void)
{
	struct thread_struct *thread = &current->thread;
	int mask, flags;

	mask = __atomic_or(KERNEL_FPC | KERNEL_VXR, &thread->kfpu_flags);
	flags = ~READ_ONCE(thread->ufpu_flags) & (KERNEL_FPC | KERNEL_VXR);
	if (flags)
		__save_user_fpu_regs(thread, flags);
	barrier();
	WRITE_ONCE(thread->kfpu_flags, mask);
}

static __always_inline void _kernel_fpu_begin(struct kernel_fpu *state, int flags)
{
	struct thread_struct *thread = &current->thread;
	int mask, uflags;

	mask = __atomic_or(flags, &thread->kfpu_flags);
	state->hdr.mask = mask;
	uflags = READ_ONCE(thread->ufpu_flags);
	if ((uflags & flags) != flags)
		__save_user_fpu_regs(thread, ~uflags & flags);
	if (mask & flags)
		__kernel_fpu_begin(state, flags);
}

static __always_inline void _kernel_fpu_end(struct kernel_fpu *state, int flags)
{
	int mask = state->hdr.mask;

	if (mask & flags)
		__kernel_fpu_end(state, flags);
	barrier();
	WRITE_ONCE(current->thread.kfpu_flags, mask);
}

void __kernel_fpu_invalid_size(void);

static __always_inline void kernel_fpu_check_size(int flags, unsigned int size)
{
	unsigned int cnt = 0;

	if (flags & KERNEL_VXR_V0V7)
		cnt += 8;
	if (flags & KERNEL_VXR_V8V15)
		cnt += 8;
	if (flags & KERNEL_VXR_V16V23)
		cnt += 8;
	if (flags & KERNEL_VXR_V24V31)
		cnt += 8;
	if (cnt != size)
		__kernel_fpu_invalid_size();
}

#define kernel_fpu_begin(state, flags)					\
{									\
	typeof(state) s = (state);					\
	int _flags = (flags);						\
									\
	kernel_fpu_check_size(_flags, ARRAY_SIZE(s->vxrs));		\
	_kernel_fpu_begin((struct kernel_fpu *)s, _flags);		\
}

#define kernel_fpu_end(state, flags)					\
{									\
	typeof(state) s = (state);					\
	int _flags = (flags);						\
									\
	kernel_fpu_check_size(_flags, ARRAY_SIZE(s->vxrs));		\
	_kernel_fpu_end((struct kernel_fpu *)s, _flags);		\
}

static inline void save_kernel_fpu_regs(struct thread_struct *thread)
{
	if (!thread->kfpu_flags)
		return;
	save_fpu_state(&thread->kfpu, thread->kfpu_flags);
}

static inline void restore_kernel_fpu_regs(struct thread_struct *thread)
{
	if (!thread->kfpu_flags)
		return;
	load_fpu_state(&thread->kfpu, thread->kfpu_flags);
}

static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
{
	int i;

	for (i = 0; i < __NUM_FPRS; i++)
		fprs[i].ui = vxrs[i].high;
}

static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
{
	int i;

	for (i = 0; i < __NUM_FPRS; i++)
		vxrs[i].high = fprs[i].ui;
}

static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
{
	fpregs->pad = 0;
	fpregs->fpc = fpu->fpc;
	convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
}

static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
{
	fpu->fpc = fpregs->fpc;
	convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
}

#endif /* _ASM_S390_FPU_H */

Filemanager

Name Type Size Permission Actions
trace Folder 0755
vdso Folder 0755
Kbuild File 253 B 0644
abs_lowcore.h File 703 B 0644
access-regs.h File 806 B 0644
airq.h File 3.29 KB 0644
alternative.h File 7.2 KB 0644
ap.h File 15.71 KB 0644
appldata.h File 1.57 KB 0644
arch_hweight.h File 1.66 KB 0644
archrandom.h File 947 B 0644
asm-const.h File 376 B 0644
asm-extable.h File 3.29 KB 0644
asm-prototypes.h File 384 B 0644
asm.h File 1.84 KB 0644
atomic.h File 6.61 KB 0644
atomic_ops.h File 7.12 KB 0644
barrier.h File 1.93 KB 0644
bitops.h File 6.69 KB 0644
boot_data.h File 1.62 KB 0644
bug.h File 1.5 KB 0644
cache.h File 389 B 0644
ccwdev.h File 8.33 KB 0644
ccwgroup.h File 2.25 KB 0644
checksum.h File 3.18 KB 0644
chpid.h File 979 B 0644
chsc.h File 1.7 KB 0644
cio.h File 9.01 KB 0644
clocksource.h File 184 B 0644
clp.h File 1.39 KB 0644
cmb.h File 425 B 0644
cmpxchg.h File 6.04 KB 0644
compat.h File 2.78 KB 0644
cpacf.h File 21.03 KB 0644
cpcmd.h File 1.11 KB 0644
cpu.h File 620 B 0644
cpu_mf-insn.h File 478 B 0644
cpu_mf.h File 8.49 KB 0644
cpufeature.h File 464 B 0644
cputime.h File 393 B 0644
crw.h File 1.81 KB 0644
css_chars.h File 904 B 0644
ctlreg.h File 7.82 KB 0644
current.h File 407 B 0644
dat-bits.h File 4.91 KB 0644
debug.h File 14.36 KB 0644
delay.h File 647 B 0644
diag.h File 7.72 KB 0644
dis.h File 636 B 0644
dma-types.h File 2.5 KB 0644
dma.h File 359 B 0644
dwarf.h File 952 B 0644
eadm.h File 2.07 KB 0644
ebcdic.h File 1.4 KB 0644
elf.h File 11.2 KB 0644
entry-common.h File 1.43 KB 0644
exec.h File 269 B 0644
extable.h File 1.88 KB 0644
extmem.h File 1.04 KB 0644
facility.h File 3.41 KB 0644
fault.h File 730 B 0644
fcx.h File 7.96 KB 0644
fprobe.h File 229 B 0644
fpu-insn-asm.h File 15.4 KB 0644
fpu-insn.h File 11.35 KB 0644
fpu-types.h File 1.06 KB 0644
fpu.h File 8.18 KB 0644
ftrace.h File 4.32 KB 0644
ftrace.lds.h File 720 B 0644
futex.h File 2.56 KB 0644
gmap.h File 6.31 KB 0644
hardirq.h File 783 B 0644
hiperdispatch.h File 295 B 0644
hugetlb.h File 2.81 KB 0644
hw_irq.h File 210 B 0644
idals.h File 6.1 KB 0644
idle.h File 614 B 0644
io.h File 2.49 KB 0644
ipl.h File 4.05 KB 0644
irq.h File 2.55 KB 0644
irq_work.h File 204 B 0644
irqflags.h File 2.07 KB 0644
isc.h File 1.01 KB 0644
itcw.h File 950 B 0644
jump_label.h File 1.32 KB 0644
kasan.h File 460 B 0644
kdebug.h File 397 B 0644
kexec.h File 3.17 KB 0644
kfence.h File 1.13 KB 0644
kmsan.h File 1.54 KB 0644
kprobes.h File 2.02 KB 0644
kvm_host.h File 27.71 KB 0644
kvm_para.h File 3.67 KB 0644
linkage.h File 223 B 0644
lowcore.h File 7.22 KB 0644
maccess.h File 564 B 0644
march.h File 722 B 0644
mem_encrypt.h File 304 B 0644
mmu.h File 1.38 KB 0644
mmu_context.h File 3.42 KB 0644
module.h File 1.54 KB 0644
msi.h File 527 B 0644
nmi.h File 3.51 KB 0644
nospec-branch.h File 1.18 KB 0644
nospec-insn.h File 2.43 KB 0644
numa.h File 386 B 0644
os_info.h File 1.67 KB 0644
page-states.h File 1.75 KB 0644
page.h File 6.76 KB 0644
pai.h File 2.03 KB 0644
pci.h File 8.64 KB 0644
pci_clp.h File 5.35 KB 0644
pci_debug.h File 722 B 0644
pci_dma.h File 2.89 KB 0644
pci_insn.h File 3.99 KB 0644
pci_io.h File 4.28 KB 0644
percpu.h File 6.33 KB 0644
perf_event.h File 1.93 KB 0644
pfault.h File 461 B 0644
pgalloc.h File 4.39 KB 0644
pgtable.h File 60.39 KB 0644
physmem_info.h File 4.92 KB 0644
pkey.h File 754 B 0644
pnet.h File 325 B 0644
preempt.h File 3.51 KB 0644
processor.h File 10.96 KB 0644
ptrace.h File 7.56 KB 0644
purgatory.h File 329 B 0644
qdio.h File 9.92 KB 0644
runtime-const.h File 1.92 KB 0644
runtime_instr.h File 634 B 0644
rwonce.h File 691 B 0644
schid.h File 525 B 0644
sclp.h File 4.97 KB 0644
scsw.h File 25.06 KB 0644
seccomp.h File 808 B 0644
sections.h File 1.03 KB 0644
set_memory.h File 2.12 KB 0644
setup.h File 4.8 KB 0644
signal.h File 644 B 0644
sigp.h File 1.87 KB 0644
smp.h File 2.06 KB 0644
softirq_stack.h File 372 B 0644
sparsemem.h File 506 B 0644
spinlock.h File 3.31 KB 0644
spinlock_types.h File 413 B 0644
stacktrace.h File 7.88 KB 0644
stp.h File 1.69 KB 0644
string.h File 5.49 KB 0644
syscall.h File 3.81 KB 0644
syscall_wrapper.h File 4.67 KB 0644
sysinfo.h File 4.33 KB 0644
text-patching.h File 301 B 0644
thread_info.h File 3.74 KB 0644
timex.h File 6.6 KB 0644
tlb.h File 4.68 KB 0644
tlbflush.h File 2.98 KB 0644
topology.h File 2.91 KB 0644
tpi.h File 736 B 0644
types.h File 318 B 0644
uaccess.h File 18.89 KB 0644
unistd.h File 1.01 KB 0644
unwind.h File 3.3 KB 0644
uprobes.h File 588 B 0644
user.h File 3.16 KB 0644
uv.h File 16.12 KB 0644
vdso-symbols.h File 499 B 0644
vdso.h File 326 B 0644
vmalloc.h File 90 B 0644
vmlinux.lds.h File 1.14 KB 0644
vtime.h File 612 B 0644
vtimer.h File 830 B 0644
word-at-a-time.h File 1.52 KB 0644
xor.h File 454 B 0644
Filemanager