xref: /linux/arch/powerpc/platforms/pseries/papr-rtas-common.c (revision 746680ec6696585e30db3e18c93a63df9cbec39c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #define pr_fmt(fmt) "papr-common: " fmt
4 
5 #include <linux/types.h>
6 #include <linux/kernel.h>
7 #include <linux/signal.h>
8 #include <linux/slab.h>
9 #include <linux/file.h>
10 #include <linux/fs.h>
11 #include <linux/anon_inodes.h>
12 #include <linux/sched/signal.h>
13 #include "papr-rtas-common.h"
14 
15 /*
16  * Sequence based RTAS HCALL has to issue multiple times to retrieve
17  * complete data from the hypervisor. For some of these RTAS calls,
18  * the OS should not interleave calls with different input until the
19  * sequence is completed. So data is collected for these calls during
20  * ioctl handle and export to user space with read() handle.
21  * This file provides common functions needed for such sequence based
22  * RTAS calls Ex: ibm,get-vpd and ibm,get-indices.
23  */
24 
25 bool papr_rtas_blob_has_data(const struct papr_rtas_blob *blob)
26 {
27 	return blob->data && blob->len;
28 }
29 
30 void papr_rtas_blob_free(const struct papr_rtas_blob *blob)
31 {
32 	if (blob) {
33 		kvfree(blob->data);
34 		kfree(blob);
35 	}
36 }
37 
38 /**
39  * papr_rtas_blob_extend() - Append data to a &struct papr_rtas_blob.
40  * @blob: The blob to extend.
41  * @data: The new data to append to @blob.
42  * @len:  The length of @data.
43  *
44  * Context: May sleep.
45  * Return: -ENOMEM on allocation failure, 0 otherwise.
46  */
47 static int papr_rtas_blob_extend(struct papr_rtas_blob *blob,
48 				const char *data, size_t len)
49 {
50 	const size_t new_len = blob->len + len;
51 	const size_t old_len = blob->len;
52 	const char *old_ptr = blob->data;
53 	char *new_ptr;
54 
55 	new_ptr = kvrealloc(old_ptr, new_len, GFP_KERNEL_ACCOUNT);
56 	if (!new_ptr)
57 		return -ENOMEM;
58 
59 	memcpy(&new_ptr[old_len], data, len);
60 	blob->data = new_ptr;
61 	blob->len = new_len;
62 	return 0;
63 }
64 
65 /**
66  * papr_rtas_blob_generate() - Construct a new &struct papr_rtas_blob.
67  * @seq: work function of the caller that is called to obtain
68  *       data with the caller RTAS call.
69  *
70  * The @work callback is invoked until it returns NULL. @seq is
71  * passed to @work in its first argument on each call. When
72  * @work returns data, it should store the data length in its
73  * second argument.
74  *
75  * Context: May sleep.
76  * Return: A completely populated &struct papr_rtas_blob, or NULL on error.
77  */
78 static const struct papr_rtas_blob *
79 papr_rtas_blob_generate(struct papr_rtas_sequence *seq)
80 {
81 	struct papr_rtas_blob *blob;
82 	const char *buf;
83 	size_t len;
84 	int err = 0;
85 
86 	blob  = kzalloc(sizeof(*blob), GFP_KERNEL_ACCOUNT);
87 	if (!blob)
88 		return NULL;
89 
90 	if (!seq->work)
91 		return ERR_PTR(-EINVAL);
92 
93 
94 	while (err == 0 && (buf = seq->work(seq, &len)))
95 		err = papr_rtas_blob_extend(blob, buf, len);
96 
97 	if (err != 0 || !papr_rtas_blob_has_data(blob))
98 		goto free_blob;
99 
100 	return blob;
101 free_blob:
102 	papr_rtas_blob_free(blob);
103 	return NULL;
104 }
105 
106 int papr_rtas_sequence_set_err(struct papr_rtas_sequence *seq, int err)
107 {
108 	/* Preserve the first error recorded. */
109 	if (seq->error == 0)
110 		seq->error = err;
111 
112 	return seq->error;
113 }
114 
115 /*
116  * Higher-level retrieval code below. These functions use the
117  * papr_rtas_blob_* and sequence_* APIs defined above to create fd-based
118  * handles for consumption by user space.
119  */
120 
121 /**
122  * papr_rtas_run_sequence() - Run a single retrieval sequence.
123  * @seq:	Functions of the caller to complete the sequence
124  *
125  * Context: May sleep. Holds a mutex and an RTAS work area for its
126  *          duration. Typically performs multiple sleepable slab
127  *          allocations.
128  *
129  * Return: A populated &struct papr_rtas_blob on success. Encoded error
130  * pointer otherwise.
131  */
132 static const struct papr_rtas_blob *papr_rtas_run_sequence(struct papr_rtas_sequence *seq)
133 {
134 	const struct papr_rtas_blob *blob;
135 
136 	if (seq->begin)
137 		seq->begin(seq);
138 
139 	blob = papr_rtas_blob_generate(seq);
140 	if (!blob)
141 		papr_rtas_sequence_set_err(seq, -ENOMEM);
142 
143 	if (seq->end)
144 		seq->end(seq);
145 
146 
147 	if (seq->error) {
148 		papr_rtas_blob_free(blob);
149 		return ERR_PTR(seq->error);
150 	}
151 
152 	return blob;
153 }
154 
155 /**
156  * papr_rtas_retrieve() - Return the data blob that is exposed to
157  * user space.
158  * @seq: RTAS call specific functions to be invoked until the
159  *       sequence is completed.
160  *
161  * Run sequences against @param until a blob is successfully
162  * instantiated, or a hard error is encountered, or a fatal signal is
163  * pending.
164  *
165  * Context: May sleep.
166  * Return: A fully populated data blob when successful. Encoded error
167  * pointer otherwise.
168  */
169 const struct papr_rtas_blob *papr_rtas_retrieve(struct papr_rtas_sequence *seq)
170 {
171 	const struct papr_rtas_blob *blob;
172 
173 	/*
174 	 * EAGAIN means the sequence returns error with a -4 (data
175 	 * changed and need to start the sequence) status from RTAS calls
176 	 * and we should attempt a new sequence. PAPR+ (v2.13 R1–7.3.20–5
177 	 * - ibm,get-vpd, R1–7.3.17–6 - ibm,get-indices) indicates that
178 	 * this should be a transient condition, not something that
179 	 * happens continuously. But we'll stop trying on a fatal signal.
180 	 */
181 	do {
182 		blob = papr_rtas_run_sequence(seq);
183 		if (!IS_ERR(blob)) /* Success. */
184 			break;
185 		if (PTR_ERR(blob) != -EAGAIN) /* Hard error. */
186 			break;
187 		cond_resched();
188 	} while (!fatal_signal_pending(current));
189 
190 	return blob;
191 }
192 
193 /**
194  * papr_rtas_setup_file_interface - Complete the sequence and obtain
195  * the data and export to user space with fd-based handles. Then the
196  * user spave gets the data with read() handle.
197  * @seq: RTAS call specific functions to get the data.
198  * @fops: RTAS call specific file operations such as read().
199  * @name: RTAS call specific char device node.
200  *
201  * Return: FD handle for consumption by user space
202  */
203 long papr_rtas_setup_file_interface(struct papr_rtas_sequence *seq,
204 				const struct file_operations *fops,
205 				char *name)
206 {
207 	const struct papr_rtas_blob *blob;
208 	struct file *file;
209 	long ret;
210 	int fd;
211 
212 	blob = papr_rtas_retrieve(seq);
213 	if (IS_ERR(blob))
214 		return PTR_ERR(blob);
215 
216 	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
217 	if (fd < 0) {
218 		ret = fd;
219 		goto free_blob;
220 	}
221 
222 	file = anon_inode_getfile_fmode(name, fops, (void *)blob,
223 			O_RDONLY, FMODE_LSEEK | FMODE_PREAD);
224 	if (IS_ERR(file)) {
225 		ret = PTR_ERR(file);
226 		goto put_fd;
227 	}
228 
229 	fd_install(fd, file);
230 	return fd;
231 
232 put_fd:
233 	put_unused_fd(fd);
234 free_blob:
235 	papr_rtas_blob_free(blob);
236 	return ret;
237 }
238 
239 /*
240  * papr_rtas_sequence_should_stop() - Determine whether RTAS retrieval
241  *                                    sequence should continue.
242  *
243  * Examines the sequence error state and outputs of the last call to
244  * the specific RTAS to determine whether the sequence in progress
245  * should continue or stop.
246  *
247  * Return: True if the sequence has encountered an error or if all data
248  *         for this sequence has been retrieved. False otherwise.
249  */
250 bool papr_rtas_sequence_should_stop(const struct papr_rtas_sequence *seq,
251 				s32 status, bool init_state)
252 {
253 	bool done;
254 
255 	if (seq->error)
256 		return true;
257 
258 	switch (status) {
259 	case RTAS_SEQ_COMPLETE:
260 		if (init_state)
261 			done = false; /* Initial state. */
262 		else
263 			done = true; /* All data consumed. */
264 		break;
265 	case RTAS_SEQ_MORE_DATA:
266 		done = false; /* More data available. */
267 		break;
268 	default:
269 		done = true; /* Error encountered. */
270 		break;
271 	}
272 
273 	return done;
274 }
275 
276 /*
277  * User space read to retrieve data for the corresponding RTAS call.
278  * papr_rtas_blob is filled with the data using the corresponding RTAS
279  * call sequence API.
280  */
281 ssize_t papr_rtas_common_handle_read(struct file *file,
282 	       char __user *buf, size_t size, loff_t *off)
283 {
284 	const struct papr_rtas_blob *blob = file->private_data;
285 
286 	/* We should not instantiate a handle without any data attached. */
287 	if (!papr_rtas_blob_has_data(blob)) {
288 		pr_err_once("handle without data\n");
289 		return -EIO;
290 	}
291 
292 	return simple_read_from_buffer(buf, size, off, blob->data, blob->len);
293 }
294 
295 int papr_rtas_common_handle_release(struct inode *inode,
296 		struct file *file)
297 {
298 	const struct papr_rtas_blob *blob = file->private_data;
299 
300 	papr_rtas_blob_free(blob);
301 
302 	return 0;
303 }
304 
305 loff_t papr_rtas_common_handle_seek(struct file *file, loff_t off,
306 					int whence)
307 {
308 	const struct papr_rtas_blob *blob = file->private_data;
309 
310 	return fixed_size_llseek(file, off, whence, blob->len);
311 }
312