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

spufs.h (10848B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * SPU file system
      4 *
      5 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
      6 *
      7 * Author: Arnd Bergmann <arndb@de.ibm.com>
      8 */
      9#ifndef SPUFS_H
     10#define SPUFS_H
     11
     12#include <linux/kref.h>
     13#include <linux/mutex.h>
     14#include <linux/spinlock.h>
     15#include <linux/fs.h>
     16#include <linux/cpumask.h>
     17#include <linux/sched/signal.h>
     18
     19#include <asm/spu.h>
     20#include <asm/spu_csa.h>
     21#include <asm/spu_info.h>
     22
     23#define SPUFS_PS_MAP_SIZE	0x20000
     24#define SPUFS_MFC_MAP_SIZE	0x1000
     25#define SPUFS_CNTL_MAP_SIZE	0x1000
     26#define SPUFS_SIGNAL_MAP_SIZE	PAGE_SIZE
     27#define SPUFS_MSS_MAP_SIZE	0x1000
     28
     29/* The magic number for our file system */
     30enum {
     31	SPUFS_MAGIC = 0x23c9b64e,
     32};
     33
     34struct spu_context_ops;
     35struct spu_gang;
     36
     37/* ctx->sched_flags */
     38enum {
     39	SPU_SCHED_NOTIFY_ACTIVE,
     40	SPU_SCHED_WAS_ACTIVE,	/* was active upon spu_acquire_saved()  */
     41	SPU_SCHED_SPU_RUN,	/* context is within spu_run */
     42};
     43
     44enum {
     45	SWITCH_LOG_BUFSIZE = 4096,
     46};
     47
     48enum {
     49	SWITCH_LOG_START,
     50	SWITCH_LOG_STOP,
     51	SWITCH_LOG_EXIT,
     52};
     53
     54struct switch_log {
     55	wait_queue_head_t	wait;
     56	unsigned long		head;
     57	unsigned long		tail;
     58	struct switch_log_entry {
     59		struct timespec64 tstamp;
     60		s32		spu_id;
     61		u32		type;
     62		u32		val;
     63		u64		timebase;
     64	} log[];
     65};
     66
     67struct spu_context {
     68	struct spu *spu;		  /* pointer to a physical SPU */
     69	struct spu_state csa;		  /* SPU context save area. */
     70	spinlock_t mmio_lock;		  /* protects mmio access */
     71	struct address_space *local_store; /* local store mapping.  */
     72	struct address_space *mfc;	   /* 'mfc' area mappings. */
     73	struct address_space *cntl;	   /* 'control' area mappings. */
     74	struct address_space *signal1;	   /* 'signal1' area mappings. */
     75	struct address_space *signal2;	   /* 'signal2' area mappings. */
     76	struct address_space *mss;	   /* 'mss' area mappings. */
     77	struct address_space *psmap;	   /* 'psmap' area mappings. */
     78	struct mutex mapping_lock;
     79	u64 object_id;		   /* user space pointer for oprofile */
     80
     81	enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
     82	struct mutex state_mutex;
     83	struct mutex run_mutex;
     84
     85	struct mm_struct *owner;
     86
     87	struct kref kref;
     88	wait_queue_head_t ibox_wq;
     89	wait_queue_head_t wbox_wq;
     90	wait_queue_head_t stop_wq;
     91	wait_queue_head_t mfc_wq;
     92	wait_queue_head_t run_wq;
     93	u32 tagwait;
     94	struct spu_context_ops *ops;
     95	struct work_struct reap_work;
     96	unsigned long flags;
     97	unsigned long event_return;
     98
     99	struct list_head gang_list;
    100	struct spu_gang *gang;
    101	struct kref *prof_priv_kref;
    102	void ( * prof_priv_release) (struct kref *kref);
    103
    104	/* owner thread */
    105	pid_t tid;
    106
    107	/* scheduler fields */
    108	struct list_head rq;
    109	unsigned int time_slice;
    110	unsigned long sched_flags;
    111	cpumask_t cpus_allowed;
    112	int policy;
    113	int prio;
    114	int last_ran;
    115
    116	/* statistics */
    117	struct {
    118		/* updates protected by ctx->state_mutex */
    119		enum spu_utilization_state util_state;
    120		unsigned long long tstamp;	/* time of last state switch */
    121		unsigned long long times[SPU_UTIL_MAX];
    122		unsigned long long vol_ctx_switch;
    123		unsigned long long invol_ctx_switch;
    124		unsigned long long min_flt;
    125		unsigned long long maj_flt;
    126		unsigned long long hash_flt;
    127		unsigned long long slb_flt;
    128		unsigned long long slb_flt_base; /* # at last ctx switch */
    129		unsigned long long class2_intr;
    130		unsigned long long class2_intr_base; /* # at last ctx switch */
    131		unsigned long long libassist;
    132	} stats;
    133
    134	/* context switch log */
    135	struct switch_log *switch_log;
    136
    137	struct list_head aff_list;
    138	int aff_head;
    139	int aff_offset;
    140};
    141
    142struct spu_gang {
    143	struct list_head list;
    144	struct mutex mutex;
    145	struct kref kref;
    146	int contexts;
    147
    148	struct spu_context *aff_ref_ctx;
    149	struct list_head aff_list_head;
    150	struct mutex aff_mutex;
    151	int aff_flags;
    152	struct spu *aff_ref_spu;
    153	atomic_t aff_sched_count;
    154};
    155
    156/* Flag bits for spu_gang aff_flags */
    157#define AFF_OFFSETS_SET		1
    158#define AFF_MERGED		2
    159
    160struct mfc_dma_command {
    161	int32_t pad;	/* reserved */
    162	uint32_t lsa;	/* local storage address */
    163	uint64_t ea;	/* effective address */
    164	uint16_t size;	/* transfer size */
    165	uint16_t tag;	/* command tag */
    166	uint16_t class;	/* class ID */
    167	uint16_t cmd;	/* command opcode */
    168};
    169
    170
    171/* SPU context query/set operations. */
    172struct spu_context_ops {
    173	int (*mbox_read) (struct spu_context * ctx, u32 * data);
    174	 u32(*mbox_stat_read) (struct spu_context * ctx);
    175	__poll_t (*mbox_stat_poll)(struct spu_context *ctx, __poll_t events);
    176	int (*ibox_read) (struct spu_context * ctx, u32 * data);
    177	int (*wbox_write) (struct spu_context * ctx, u32 data);
    178	 u32(*signal1_read) (struct spu_context * ctx);
    179	void (*signal1_write) (struct spu_context * ctx, u32 data);
    180	 u32(*signal2_read) (struct spu_context * ctx);
    181	void (*signal2_write) (struct spu_context * ctx, u32 data);
    182	void (*signal1_type_set) (struct spu_context * ctx, u64 val);
    183	 u64(*signal1_type_get) (struct spu_context * ctx);
    184	void (*signal2_type_set) (struct spu_context * ctx, u64 val);
    185	 u64(*signal2_type_get) (struct spu_context * ctx);
    186	 u32(*npc_read) (struct spu_context * ctx);
    187	void (*npc_write) (struct spu_context * ctx, u32 data);
    188	 u32(*status_read) (struct spu_context * ctx);
    189	char*(*get_ls) (struct spu_context * ctx);
    190	void (*privcntl_write) (struct spu_context *ctx, u64 data);
    191	 u32 (*runcntl_read) (struct spu_context * ctx);
    192	void (*runcntl_write) (struct spu_context * ctx, u32 data);
    193	void (*runcntl_stop) (struct spu_context * ctx);
    194	void (*master_start) (struct spu_context * ctx);
    195	void (*master_stop) (struct spu_context * ctx);
    196	int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
    197	u32 (*read_mfc_tagstatus)(struct spu_context * ctx);
    198	u32 (*get_mfc_free_elements)(struct spu_context *ctx);
    199	int (*send_mfc_command)(struct spu_context * ctx,
    200				struct mfc_dma_command * cmd);
    201	void (*dma_info_read) (struct spu_context * ctx,
    202			       struct spu_dma_info * info);
    203	void (*proxydma_info_read) (struct spu_context * ctx,
    204				    struct spu_proxydma_info * info);
    205	void (*restart_dma)(struct spu_context *ctx);
    206};
    207
    208extern struct spu_context_ops spu_hw_ops;
    209extern struct spu_context_ops spu_backing_ops;
    210
    211struct spufs_inode_info {
    212	struct spu_context *i_ctx;
    213	struct spu_gang *i_gang;
    214	struct inode vfs_inode;
    215	int i_openers;
    216};
    217#define SPUFS_I(inode) \
    218	container_of(inode, struct spufs_inode_info, vfs_inode)
    219
    220struct spufs_tree_descr {
    221	const char *name;
    222	const struct file_operations *ops;
    223	umode_t mode;
    224	size_t size;
    225};
    226
    227extern const struct spufs_tree_descr spufs_dir_contents[];
    228extern const struct spufs_tree_descr spufs_dir_nosched_contents[];
    229extern const struct spufs_tree_descr spufs_dir_debug_contents[];
    230
    231/* system call implementation */
    232extern struct spufs_calls spufs_calls;
    233struct coredump_params;
    234long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
    235long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags,
    236			umode_t mode, struct file *filp);
    237/* ELF coredump callbacks for writing SPU ELF notes */
    238extern int spufs_coredump_extra_notes_size(void);
    239extern int spufs_coredump_extra_notes_write(struct coredump_params *cprm);
    240
    241extern const struct file_operations spufs_context_fops;
    242
    243/* gang management */
    244struct spu_gang *alloc_spu_gang(void);
    245struct spu_gang *get_spu_gang(struct spu_gang *gang);
    246int put_spu_gang(struct spu_gang *gang);
    247void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx);
    248void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
    249
    250/* fault handling */
    251int spufs_handle_class1(struct spu_context *ctx);
    252int spufs_handle_class0(struct spu_context *ctx);
    253
    254/* affinity */
    255struct spu *affinity_check(struct spu_context *ctx);
    256
    257/* context management */
    258extern atomic_t nr_spu_contexts;
    259static inline int __must_check spu_acquire(struct spu_context *ctx)
    260{
    261	return mutex_lock_interruptible(&ctx->state_mutex);
    262}
    263
    264static inline void spu_release(struct spu_context *ctx)
    265{
    266	mutex_unlock(&ctx->state_mutex);
    267}
    268
    269struct spu_context * alloc_spu_context(struct spu_gang *gang);
    270void destroy_spu_context(struct kref *kref);
    271struct spu_context * get_spu_context(struct spu_context *ctx);
    272int put_spu_context(struct spu_context *ctx);
    273void spu_unmap_mappings(struct spu_context *ctx);
    274
    275void spu_forget(struct spu_context *ctx);
    276int __must_check spu_acquire_saved(struct spu_context *ctx);
    277void spu_release_saved(struct spu_context *ctx);
    278
    279int spu_stopped(struct spu_context *ctx, u32 * stat);
    280void spu_del_from_rq(struct spu_context *ctx);
    281int spu_activate(struct spu_context *ctx, unsigned long flags);
    282void spu_deactivate(struct spu_context *ctx);
    283void spu_yield(struct spu_context *ctx);
    284void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
    285		u32 type, u32 val);
    286void spu_set_timeslice(struct spu_context *ctx);
    287void spu_update_sched_info(struct spu_context *ctx);
    288void __spu_update_sched_info(struct spu_context *ctx);
    289int __init spu_sched_init(void);
    290void spu_sched_exit(void);
    291
    292extern char *isolated_loader;
    293
    294/*
    295 * spufs_wait
    296 *	Same as wait_event_interruptible(), except that here
    297 *	we need to call spu_release(ctx) before sleeping, and
    298 *	then spu_acquire(ctx) when awoken.
    299 *
    300 * 	Returns with state_mutex re-acquired when successful or
    301 * 	with -ERESTARTSYS and the state_mutex dropped when interrupted.
    302 */
    303
    304#define spufs_wait(wq, condition)					\
    305({									\
    306	int __ret = 0;							\
    307	DEFINE_WAIT(__wait);						\
    308	for (;;) {							\
    309		prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE);	\
    310		if (condition)						\
    311			break;						\
    312		spu_release(ctx);					\
    313		if (signal_pending(current)) {				\
    314			__ret = -ERESTARTSYS;				\
    315			break;						\
    316		}							\
    317		schedule();						\
    318		__ret = spu_acquire(ctx);				\
    319		if (__ret)						\
    320			break;						\
    321	}								\
    322	finish_wait(&(wq), &__wait);					\
    323	__ret;								\
    324})
    325
    326size_t spu_wbox_write(struct spu_context *ctx, u32 data);
    327size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
    328
    329/* irq callback funcs. */
    330void spufs_ibox_callback(struct spu *spu);
    331void spufs_wbox_callback(struct spu *spu);
    332void spufs_stop_callback(struct spu *spu, int irq);
    333void spufs_mfc_callback(struct spu *spu);
    334void spufs_dma_callback(struct spu *spu, int type);
    335
    336extern struct spu_coredump_calls spufs_coredump_calls;
    337struct spufs_coredump_reader {
    338	char *name;
    339	ssize_t (*dump)(struct spu_context *ctx, struct coredump_params *cprm);
    340	u64 (*get)(struct spu_context *ctx);
    341	size_t size;
    342};
    343extern const struct spufs_coredump_reader spufs_coredump_read[];
    344extern int spufs_coredump_num_notes;
    345
    346extern int spu_init_csa(struct spu_state *csa);
    347extern void spu_fini_csa(struct spu_state *csa);
    348extern int spu_save(struct spu_state *prev, struct spu *spu);
    349extern int spu_restore(struct spu_state *new, struct spu *spu);
    350extern int spu_switch(struct spu_state *prev, struct spu_state *new,
    351		      struct spu *spu);
    352extern int spu_alloc_lscsa(struct spu_state *csa);
    353extern void spu_free_lscsa(struct spu_state *csa);
    354
    355extern void spuctx_switch_state(struct spu_context *ctx,
    356		enum spu_utilization_state new_state);
    357
    358#endif