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