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

pstore.h (7808B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Persistent Storage - pstore.h
      4 *
      5 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
      6 *
      7 * This code is the generic layer to export data records from platform
      8 * level persistent storage via a file system.
      9 */
     10#ifndef _LINUX_PSTORE_H
     11#define _LINUX_PSTORE_H
     12
     13#include <linux/compiler.h>
     14#include <linux/errno.h>
     15#include <linux/kmsg_dump.h>
     16#include <linux/mutex.h>
     17#include <linux/spinlock.h>
     18#include <linux/time.h>
     19#include <linux/types.h>
     20
     21struct module;
     22
     23/*
     24 * pstore record types (see fs/pstore/platform.c for pstore_type_names[])
     25 * These values may be written to storage (see EFI vars backend), so
     26 * they are kind of an ABI. Be careful changing the mappings.
     27 */
     28enum pstore_type_id {
     29	/* Frontend storage types */
     30	PSTORE_TYPE_DMESG	= 0,
     31	PSTORE_TYPE_MCE		= 1,
     32	PSTORE_TYPE_CONSOLE	= 2,
     33	PSTORE_TYPE_FTRACE	= 3,
     34
     35	/* PPC64-specific partition types */
     36	PSTORE_TYPE_PPC_RTAS	= 4,
     37	PSTORE_TYPE_PPC_OF	= 5,
     38	PSTORE_TYPE_PPC_COMMON	= 6,
     39	PSTORE_TYPE_PMSG	= 7,
     40	PSTORE_TYPE_PPC_OPAL	= 8,
     41
     42	/* End of the list */
     43	PSTORE_TYPE_MAX
     44};
     45
     46const char *pstore_type_to_name(enum pstore_type_id type);
     47enum pstore_type_id pstore_name_to_type(const char *name);
     48
     49struct pstore_info;
     50/**
     51 * struct pstore_record - details of a pstore record entry
     52 * @psi:	pstore backend driver information
     53 * @type:	pstore record type
     54 * @id:		per-type unique identifier for record
     55 * @time:	timestamp of the record
     56 * @buf:	pointer to record contents
     57 * @size:	size of @buf
     58 * @ecc_notice_size:
     59 *		ECC information for @buf
     60 *
     61 * Valid for PSTORE_TYPE_DMESG @type:
     62 *
     63 * @count:	Oops count since boot
     64 * @reason:	kdump reason for notification
     65 * @part:	position in a multipart record
     66 * @compressed:	whether the buffer is compressed
     67 *
     68 */
     69struct pstore_record {
     70	struct pstore_info	*psi;
     71	enum pstore_type_id	type;
     72	u64			id;
     73	struct timespec64	time;
     74	char			*buf;
     75	ssize_t			size;
     76	ssize_t			ecc_notice_size;
     77
     78	int			count;
     79	enum kmsg_dump_reason	reason;
     80	unsigned int		part;
     81	bool			compressed;
     82};
     83
     84/**
     85 * struct pstore_info - backend pstore driver structure
     86 *
     87 * @owner:	module which is responsible for this backend driver
     88 * @name:	name of the backend driver
     89 *
     90 * @buf_lock:	spinlock to serialize access to @buf
     91 * @buf:	preallocated crash dump buffer
     92 * @bufsize:	size of @buf available for crash dump bytes (must match
     93 *		smallest number of bytes available for writing to a
     94 *		backend entry, since compressed bytes don't take kindly
     95 *		to being truncated)
     96 *
     97 * @read_mutex:	serializes @open, @read, @close, and @erase callbacks
     98 * @flags:	bitfield of frontends the backend can accept writes for
     99 * @max_reason:	Used when PSTORE_FLAGS_DMESG is set. Contains the
    100 *		kmsg_dump_reason enum value. KMSG_DUMP_UNDEF means
    101 *		"use existing kmsg_dump() filtering, based on the
    102 *		printk.always_kmsg_dump boot param" (which is either
    103 *		KMSG_DUMP_OOPS when false, or KMSG_DUMP_MAX when
    104 *		true); see printk.always_kmsg_dump for more details.
    105 * @data:	backend-private pointer passed back during callbacks
    106 *
    107 * Callbacks:
    108 *
    109 * @open:
    110 *	Notify backend that pstore is starting a full read of backend
    111 *	records. Followed by one or more @read calls, and a final @close.
    112 *
    113 *	@psi:	in: pointer to the struct pstore_info for the backend
    114 *
    115 *	Returns 0 on success, and non-zero on error.
    116 *
    117 * @close:
    118 *	Notify backend that pstore has finished a full read of backend
    119 *	records. Always preceded by an @open call and one or more @read
    120 *	calls.
    121 *
    122 *	@psi:	in: pointer to the struct pstore_info for the backend
    123 *
    124 *	Returns 0 on success, and non-zero on error. (Though pstore will
    125 *	ignore the error.)
    126 *
    127 * @read:
    128 *	Read next available backend record. Called after a successful
    129 *	@open.
    130 *
    131 *	@record:
    132 *		pointer to record to populate. @buf should be allocated
    133 *		by the backend and filled. At least @type and @id should
    134 *		be populated, since these are used when creating pstorefs
    135 *		file names.
    136 *
    137 *	Returns record size on success, zero when no more records are
    138 *	available, or negative on error.
    139 *
    140 * @write:
    141 *	A newly generated record needs to be written to backend storage.
    142 *
    143 *	@record:
    144 *		pointer to record metadata. When @type is PSTORE_TYPE_DMESG,
    145 *		@buf will be pointing to the preallocated @psi.buf, since
    146 *		memory allocation may be broken during an Oops. Regardless,
    147 *		@buf must be proccesed or copied before returning. The
    148 *		backend is also expected to write @id with something that
    149 *		can help identify this record to a future @erase callback.
    150 *		The @time field will be prepopulated with the current time,
    151 *		when available. The @size field will have the size of data
    152 *		in @buf.
    153 *
    154 *	Returns 0 on success, and non-zero on error.
    155 *
    156 * @write_user:
    157 *	Perform a frontend write to a backend record, using a specified
    158 *	buffer that is coming directly from userspace, instead of the
    159 *	@record @buf.
    160 *
    161 *	@record:	pointer to record metadata.
    162 *	@buf:		pointer to userspace contents to write to backend
    163 *
    164 *	Returns 0 on success, and non-zero on error.
    165 *
    166 * @erase:
    167 *	Delete a record from backend storage.  Different backends
    168 *	identify records differently, so entire original record is
    169 *	passed back to assist in identification of what the backend
    170 *	should remove from storage.
    171 *
    172 *	@record:	pointer to record metadata.
    173 *
    174 *	Returns 0 on success, and non-zero on error.
    175 *
    176 */
    177struct pstore_info {
    178	struct module	*owner;
    179	const char	*name;
    180
    181	spinlock_t	buf_lock;
    182	char		*buf;
    183	size_t		bufsize;
    184
    185	struct mutex	read_mutex;
    186
    187	int		flags;
    188	int		max_reason;
    189	void		*data;
    190
    191	int		(*open)(struct pstore_info *psi);
    192	int		(*close)(struct pstore_info *psi);
    193	ssize_t		(*read)(struct pstore_record *record);
    194	int		(*write)(struct pstore_record *record);
    195	int		(*write_user)(struct pstore_record *record,
    196				      const char __user *buf);
    197	int		(*erase)(struct pstore_record *record);
    198};
    199
    200/* Supported frontends */
    201#define PSTORE_FLAGS_DMESG	BIT(0)
    202#define PSTORE_FLAGS_CONSOLE	BIT(1)
    203#define PSTORE_FLAGS_FTRACE	BIT(2)
    204#define PSTORE_FLAGS_PMSG	BIT(3)
    205
    206extern int pstore_register(struct pstore_info *);
    207extern void pstore_unregister(struct pstore_info *);
    208
    209struct pstore_ftrace_record {
    210	unsigned long ip;
    211	unsigned long parent_ip;
    212	u64 ts;
    213};
    214
    215/*
    216 * ftrace related stuff: Both backends and frontends need these so expose
    217 * them here.
    218 */
    219
    220#if NR_CPUS <= 2 && defined(CONFIG_ARM_THUMB)
    221#define PSTORE_CPU_IN_IP 0x1
    222#elif NR_CPUS <= 4 && defined(CONFIG_ARM)
    223#define PSTORE_CPU_IN_IP 0x3
    224#endif
    225
    226#define TS_CPU_SHIFT 8
    227#define TS_CPU_MASK (BIT(TS_CPU_SHIFT) - 1)
    228
    229/*
    230 * If CPU number can be stored in IP, store it there, otherwise store it in
    231 * the time stamp. This means more timestamp resolution is available when
    232 * the CPU can be stored in the IP.
    233 */
    234#ifdef PSTORE_CPU_IN_IP
    235static inline void
    236pstore_ftrace_encode_cpu(struct pstore_ftrace_record *rec, unsigned int cpu)
    237{
    238	rec->ip |= cpu;
    239}
    240
    241static inline unsigned int
    242pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
    243{
    244	return rec->ip & PSTORE_CPU_IN_IP;
    245}
    246
    247static inline u64
    248pstore_ftrace_read_timestamp(struct pstore_ftrace_record *rec)
    249{
    250	return rec->ts;
    251}
    252
    253static inline void
    254pstore_ftrace_write_timestamp(struct pstore_ftrace_record *rec, u64 val)
    255{
    256	rec->ts = val;
    257}
    258#else
    259static inline void
    260pstore_ftrace_encode_cpu(struct pstore_ftrace_record *rec, unsigned int cpu)
    261{
    262	rec->ts &= ~(TS_CPU_MASK);
    263	rec->ts |= cpu;
    264}
    265
    266static inline unsigned int
    267pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
    268{
    269	return rec->ts & TS_CPU_MASK;
    270}
    271
    272static inline u64
    273pstore_ftrace_read_timestamp(struct pstore_ftrace_record *rec)
    274{
    275	return rec->ts >> TS_CPU_SHIFT;
    276}
    277
    278static inline void
    279pstore_ftrace_write_timestamp(struct pstore_ftrace_record *rec, u64 val)
    280{
    281	rec->ts = (rec->ts & TS_CPU_MASK) | (val << TS_CPU_SHIFT);
    282}
    283#endif
    284
    285#endif /*_LINUX_PSTORE_H*/