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
papr_rtas_blob_has_data(const struct papr_rtas_blob * blob)25 bool papr_rtas_blob_has_data(const struct papr_rtas_blob *blob)
26 {
27 return blob->data && blob->len;
28 }
29
papr_rtas_blob_free(const struct papr_rtas_blob * blob)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 */
papr_rtas_blob_extend(struct papr_rtas_blob * blob,const char * data,size_t len)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 *
papr_rtas_blob_generate(struct papr_rtas_sequence * seq)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
papr_rtas_sequence_set_err(struct papr_rtas_sequence * seq,int err)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 */
papr_rtas_run_sequence(struct papr_rtas_sequence * seq)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 */
papr_rtas_retrieve(struct papr_rtas_sequence * seq)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 */
papr_rtas_setup_file_interface(struct papr_rtas_sequence * seq,const struct file_operations * fops,char * name)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 */
papr_rtas_sequence_should_stop(const struct papr_rtas_sequence * seq,s32 status,bool init_state)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 */
papr_rtas_common_handle_read(struct file * file,char __user * buf,size_t size,loff_t * off)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
papr_rtas_common_handle_release(struct inode * inode,struct file * file)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
papr_rtas_common_handle_seek(struct file * file,loff_t off,int whence)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