xref: /linux/arch/powerpc/platforms/pseries/papr-phy-attest.c (revision e78f70bad29c5ae1e1076698b690b15794e9b81e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #define pr_fmt(fmt) "papr-phy-attest: " fmt
4 
5 #include <linux/build_bug.h>
6 #include <linux/file.h>
7 #include <linux/fs.h>
8 #include <linux/init.h>
9 #include <linux/lockdep.h>
10 #include <linux/kernel.h>
11 #include <linux/miscdevice.h>
12 #include <linux/signal.h>
13 #include <linux/slab.h>
14 #include <linux/string.h>
15 #include <linux/string_helpers.h>
16 #include <linux/uaccess.h>
17 #include <asm/machdep.h>
18 #include <asm/rtas-work-area.h>
19 #include <asm/rtas.h>
20 #include <uapi/asm/papr-physical-attestation.h>
21 #include "papr-rtas-common.h"
22 
23 /**
24  * struct rtas_phy_attest_params - Parameters (in and out) for
25  * ibm,physical-attestation.
26  *
27  * @cmd:  In: Caller-provided attestation command buffer. Must be
28  *        RTAS-addressable.
29  * @work_area: In: Caller-provided work area buffer for attestation
30  *             command structure
31  *             Out: Caller-provided work area buffer for the response
32  * @cmd_len:   In: Caller-provided attestation command structure
33  *             length
34  * @sequence:  In: Sequence number. Out: Next sequence number.
35  * @written:   Out: Bytes written by ibm,physical-attestation to
36  *             @work_area.
37  * @status:    Out: RTAS call status.
38  */
39 struct rtas_phy_attest_params {
40 	struct papr_phy_attest_io_block cmd;
41 	struct rtas_work_area *work_area;
42 	u32 cmd_len;
43 	u32 sequence;
44 	u32 written;
45 	s32 status;
46 };
47 
48 /**
49  * rtas_physical_attestation() - Call ibm,physical-attestation to
50  * fill a work area buffer.
51  * @params: See &struct rtas_phy_attest_params.
52  *
53  * Calls ibm,physical-attestation until it errors or successfully
54  * deposits data into the supplied work area. Handles RTAS retry
55  * statuses. Maps RTAS error statuses to reasonable errno values.
56  *
57  * The caller is expected to invoke rtas_physical_attestation()
58  * multiple times to retrieve all the data for the provided
59  * attestation command. Only one sequence should be in progress at
60  * any time; starting a new sequence will disrupt any sequence
61  * already in progress. Serialization of attestation retrieval
62  * sequences is the responsibility of the caller.
63  *
64  * The caller should inspect @params.status to determine whether more
65  * calls are needed to complete the sequence.
66  *
67  * Context: May sleep.
68  * Return: -ve on error, 0 otherwise.
69  */
70 static int rtas_physical_attestation(struct rtas_phy_attest_params *params)
71 {
72 	struct rtas_work_area *work_area;
73 	s32 fwrc, token;
74 	u32 rets[2];
75 	int ret;
76 
77 	work_area = params->work_area;
78 	token = rtas_function_token(RTAS_FN_IBM_PHYSICAL_ATTESTATION);
79 	if (token == RTAS_UNKNOWN_SERVICE)
80 		return -ENOENT;
81 
82 	lockdep_assert_held(&rtas_ibm_physical_attestation_lock);
83 
84 	do {
85 		fwrc = rtas_call(token, 3, 3, rets,
86 				 rtas_work_area_phys(work_area),
87 				 params->cmd_len,
88 				 params->sequence);
89 	} while (rtas_busy_delay(fwrc));
90 
91 	switch (fwrc) {
92 	case RTAS_HARDWARE_ERROR:
93 		ret = -EIO;
94 		break;
95 	case RTAS_INVALID_PARAMETER:
96 		ret = -EINVAL;
97 		break;
98 	case RTAS_SEQ_MORE_DATA:
99 		params->sequence = rets[0];
100 		fallthrough;
101 	case RTAS_SEQ_COMPLETE:
102 		params->written = rets[1];
103 		/*
104 		 * Kernel or firmware bug, do not continue.
105 		 */
106 		if (WARN(params->written > rtas_work_area_size(work_area),
107 			 "possible write beyond end of work area"))
108 			ret = -EFAULT;
109 		else
110 			ret = 0;
111 		break;
112 	default:
113 		ret = -EIO;
114 		pr_err_ratelimited("unexpected ibm,get-phy_attest status %d\n", fwrc);
115 		break;
116 	}
117 
118 	params->status = fwrc;
119 	return ret;
120 }
121 
122 /*
123  * Internal physical-attestation sequence APIs. A physical-attestation
124  * sequence is a series of calls to get ibm,physical-attestation
125  * for a given attestation command. The sequence ends when an error
126  * is encountered or all data for the attestation command has been
127  * returned.
128  */
129 
130 /**
131  * phy_attest_sequence_begin() - Begin a response data for attestation
132  * command retrieval sequence.
133  * @seq: user specified parameters for RTAS call from seq struct.
134  *
135  * Context: May sleep.
136  */
137 static void phy_attest_sequence_begin(struct papr_rtas_sequence *seq)
138 {
139 	struct rtas_phy_attest_params *param;
140 
141 	/*
142 	 * We could allocate the work area before acquiring the
143 	 * function lock, but that would allow concurrent requests to
144 	 * exhaust the limited work area pool for no benefit. So
145 	 * allocate the work area under the lock.
146 	 */
147 	mutex_lock(&rtas_ibm_physical_attestation_lock);
148 	param =  (struct rtas_phy_attest_params *)seq->params;
149 	param->work_area = rtas_work_area_alloc(SZ_4K);
150 	memcpy(rtas_work_area_raw_buf(param->work_area), &param->cmd,
151 			param->cmd_len);
152 	param->sequence = 1;
153 	param->status = 0;
154 }
155 
156 /**
157  * phy_attest_sequence_end() - Finalize a attestation command
158  * response retrieval sequence.
159  * @seq: Sequence state.
160  *
161  * Releases resources obtained by phy_attest_sequence_begin().
162  */
163 static void phy_attest_sequence_end(struct papr_rtas_sequence *seq)
164 {
165 	struct rtas_phy_attest_params *param;
166 
167 	param =  (struct rtas_phy_attest_params *)seq->params;
168 	rtas_work_area_free(param->work_area);
169 	mutex_unlock(&rtas_ibm_physical_attestation_lock);
170 	kfree(param);
171 }
172 
173 /*
174  * Generator function to be passed to papr_rtas_blob_generate().
175  */
176 static const char *phy_attest_sequence_fill_work_area(struct papr_rtas_sequence *seq,
177 						size_t *len)
178 {
179 	struct rtas_phy_attest_params *p;
180 	bool init_state;
181 
182 	p = (struct rtas_phy_attest_params *)seq->params;
183 	init_state = (p->written == 0) ? true : false;
184 
185 	if (papr_rtas_sequence_should_stop(seq, p->status, init_state))
186 		return NULL;
187 	if (papr_rtas_sequence_set_err(seq, rtas_physical_attestation(p)))
188 		return NULL;
189 	*len = p->written;
190 	return rtas_work_area_raw_buf(p->work_area);
191 }
192 
193 static const struct file_operations papr_phy_attest_handle_ops = {
194 	.read = papr_rtas_common_handle_read,
195 	.llseek = papr_rtas_common_handle_seek,
196 	.release = papr_rtas_common_handle_release,
197 };
198 
199 /**
200  * papr_phy_attest_create_handle() - Create a fd-based handle for
201  * reading the response for the given attestation command.
202  * @ulc: Attestation command in user memory; defines the scope of
203  *       data for the attestation command to retrieve.
204  *
205  * Handler for PAPR_PHYSICAL_ATTESTATION_IOC_CREATE_HANDLE ioctl
206  * command. Validates @ulc and instantiates an immutable response
207  * "blob" for attestation command. The blob is attached to a file
208  * descriptor for reading by user space. The memory backing the blob
209  * is freed when the file is released.
210  *
211  * The entire requested response buffer for the attestation command
212  * retrieved by this call and all necessary RTAS interactions are
213  * performed before returning the fd to user space. This keeps the
214  * read handler simple and ensures that kernel can prevent
215  * interleaving ibm,physical-attestation call sequences.
216  *
217  * Return: The installed fd number if successful, -ve errno otherwise.
218  */
219 static long papr_phy_attest_create_handle(struct papr_phy_attest_io_block __user *ulc)
220 {
221 	struct rtas_phy_attest_params *params;
222 	struct papr_rtas_sequence seq = {};
223 	int fd;
224 
225 	/*
226 	 * Freed in phy_attest_sequence_end().
227 	 */
228 	params =  kzalloc(sizeof(*params), GFP_KERNEL_ACCOUNT);
229 	if (!params)
230 		return -ENOMEM;
231 
232 	if (copy_from_user(&params->cmd, ulc,
233 			sizeof(struct papr_phy_attest_io_block)))
234 		return -EFAULT;
235 
236 	params->cmd_len = be32_to_cpu(params->cmd.length);
237 	seq = (struct papr_rtas_sequence) {
238 		.begin = phy_attest_sequence_begin,
239 		.end = phy_attest_sequence_end,
240 		.work = phy_attest_sequence_fill_work_area,
241 	};
242 
243 	seq.params = (void *)params;
244 
245 	fd = papr_rtas_setup_file_interface(&seq,
246 			&papr_phy_attest_handle_ops,
247 			"[papr-physical-attestation]");
248 
249 	return fd;
250 }
251 
252 /*
253  * Top-level ioctl handler for /dev/papr-physical-attestation.
254  */
255 static long papr_phy_attest_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
256 {
257 	void __user *argp = (__force void __user *)arg;
258 	long ret;
259 
260 	switch (ioctl) {
261 	case PAPR_PHY_ATTEST_IOC_HANDLE:
262 		ret = papr_phy_attest_create_handle(argp);
263 		break;
264 	default:
265 		ret = -ENOIOCTLCMD;
266 		break;
267 	}
268 	return ret;
269 }
270 
271 static const struct file_operations papr_phy_attest_ops = {
272 	.unlocked_ioctl = papr_phy_attest_dev_ioctl,
273 };
274 
275 static struct miscdevice papr_phy_attest_dev = {
276 	.minor = MISC_DYNAMIC_MINOR,
277 	.name = "papr-physical-attestation",
278 	.fops = &papr_phy_attest_ops,
279 };
280 
281 static __init int papr_phy_attest_init(void)
282 {
283 	if (!rtas_function_implemented(RTAS_FN_IBM_PHYSICAL_ATTESTATION))
284 		return -ENODEV;
285 
286 	return misc_register(&papr_phy_attest_dev);
287 }
288 machine_device_initcall(pseries, papr_phy_attest_init);
289