cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsp-impl.h (3860B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
      4 *
      5 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
      6 */
      7#ifndef __ASM_ARC_DSP_IMPL_H
      8#define __ASM_ARC_DSP_IMPL_H
      9
     10#include <asm/dsp.h>
     11
     12#define DSP_CTRL_DISABLED_ALL		0
     13
     14#ifdef __ASSEMBLY__
     15
     16/* clobbers r5 register */
     17.macro DSP_EARLY_INIT
     18#ifdef CONFIG_ISA_ARCV2
     19	lr	r5, [ARC_AUX_DSP_BUILD]
     20	bmsk	r5, r5, 7
     21	breq    r5, 0, 1f
     22	mov	r5, DSP_CTRL_DISABLED_ALL
     23	sr	r5, [ARC_AUX_DSP_CTRL]
     241:
     25#endif
     26.endm
     27
     28/* clobbers r10, r11 registers pair */
     29.macro DSP_SAVE_REGFILE_IRQ
     30#if defined(CONFIG_ARC_DSP_KERNEL)
     31	/*
     32	 * Drop any changes to DSP_CTRL made by userspace so userspace won't be
     33	 * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
     34	 */
     35	mov	r10, DSP_CTRL_DISABLED_ALL
     36	sr	r10, [ARC_AUX_DSP_CTRL]
     37
     38#elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
     39	/*
     40	 * Save DSP_CTRL register and reset it to value suitable for kernel
     41	 * (DSP_CTRL_DISABLED_ALL)
     42	 */
     43	mov	r10, DSP_CTRL_DISABLED_ALL
     44	aex	r10, [ARC_AUX_DSP_CTRL]
     45	st	r10, [sp, PT_DSP_CTRL]
     46
     47#endif
     48.endm
     49
     50/* clobbers r10, r11 registers pair */
     51.macro DSP_RESTORE_REGFILE_IRQ
     52#if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
     53	ld	r10, [sp, PT_DSP_CTRL]
     54	sr	r10, [ARC_AUX_DSP_CTRL]
     55
     56#endif
     57.endm
     58
     59#else /* __ASEMBLY__ */
     60
     61#include <linux/sched.h>
     62#include <asm/asserts.h>
     63#include <asm/switch_to.h>
     64
     65#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
     66
     67/*
     68 * As we save new and restore old AUX register value in the same place we
     69 * can optimize a bit and use AEX instruction (swap contents of an auxiliary
     70 * register with a core register) instead of LR + SR pair.
     71 */
     72#define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux)		\
     73do {									\
     74	long unsigned int _scratch;					\
     75									\
     76	__asm__ __volatile__(						\
     77		"ld	%0, [%2, %4]			\n"		\
     78		"aex	%0, [%3]			\n"		\
     79		"st	%0, [%1, %4]			\n"		\
     80		:							\
     81		  "=&r" (_scratch)	/* must be early clobber */	\
     82		:							\
     83		   "r" (_saveto),					\
     84		   "r" (_readfrom),					\
     85		   "Ir" (_aux),						\
     86		   "Ir" (_offt)						\
     87		:							\
     88		  "memory"						\
     89	);								\
     90} while (0)
     91
     92#define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux)			\
     93	AUX_SAVE_RESTORE(_saveto, _readfrom,				\
     94		offsetof(struct dsp_callee_regs, _aux),			\
     95		ARC_AUX_##_aux)
     96
     97static inline void dsp_save_restore(struct task_struct *prev,
     98					struct task_struct *next)
     99{
    100	long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
    101	long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
    102
    103	DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
    104	DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
    105
    106	DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
    107	DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
    108
    109#ifdef CONFIG_ARC_DSP_AGU_USERSPACE
    110	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
    111	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
    112	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
    113	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
    114
    115	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
    116	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
    117
    118	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
    119	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
    120	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
    121	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
    122#endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
    123}
    124
    125#else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
    126#define dsp_save_restore(p, n)
    127#endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
    128
    129static inline bool dsp_exist(void)
    130{
    131	struct bcr_generic bcr;
    132
    133	READ_BCR(ARC_AUX_DSP_BUILD, bcr);
    134	return !!bcr.ver;
    135}
    136
    137static inline bool agu_exist(void)
    138{
    139	struct bcr_generic bcr;
    140
    141	READ_BCR(ARC_AUX_AGU_BUILD, bcr);
    142	return !!bcr.ver;
    143}
    144
    145static inline void dsp_config_check(void)
    146{
    147	CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
    148	CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
    149}
    150
    151#endif /* __ASEMBLY__ */
    152#endif /* __ASM_ARC_DSP_IMPL_H */