Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * AMD Platform Security Processor (PSP) interface
  4 *
  5 * Copyright (C) 2016,2019 Advanced Micro Devices, Inc.
  6 *
  7 * Author: Brijesh Singh <brijesh.singh@amd.com>
 
 
 
 
  8 */
  9
 
 10#include <linux/kernel.h>
 11#include <linux/irqreturn.h>
 
 
 
 
 
 
 
 
 
 12
 13#include "sp-dev.h"
 14#include "psp-dev.h"
 15#include "sev-dev.h"
 16#include "tee-dev.h"
 17
 18struct psp_device *psp_master;
 
 
 
 
 19
 20static struct psp_device *psp_alloc_struct(struct sp_device *sp)
 21{
 22	struct device *dev = sp->dev;
 23	struct psp_device *psp;
 24
 25	psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
 26	if (!psp)
 27		return NULL;
 28
 29	psp->dev = dev;
 30	psp->sp = sp;
 31
 32	snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
 33
 34	return psp;
 35}
 36
 37static irqreturn_t psp_irq_handler(int irq, void *data)
 38{
 39	struct psp_device *psp = data;
 40	unsigned int status;
 
 41
 42	/* Read the interrupt status: */
 43	status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
 44
 45	/* invoke subdevice interrupt handlers */
 46	if (status) {
 47		if (psp->sev_irq_handler)
 48			psp->sev_irq_handler(irq, psp->sev_irq_data, status);
 49
 50		if (psp->tee_irq_handler)
 51			psp->tee_irq_handler(irq, psp->tee_irq_data, status);
 
 
 52	}
 53
 
 54	/* Clear the interrupt status by writing the same value we read. */
 55	iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
 56
 57	return IRQ_HANDLED;
 58}
 59
 60static unsigned int psp_get_capability(struct psp_device *psp)
 61{
 62	unsigned int val = ioread32(psp->io_regs + psp->vdata->feature_reg);
 63
 64	/*
 65	 * Check for a access to the registers.  If this read returns
 66	 * 0xffffffff, it's likely that the system is running a broken
 67	 * BIOS which disallows access to the device. Stop here and
 68	 * fail the PSP initialization (but not the load, as the CCP
 69	 * could get properly initialized).
 70	 */
 71	if (val == 0xffffffff) {
 72		dev_notice(psp->dev, "psp: unable to access the device: you might be running a broken BIOS.\n");
 73		return -ENODEV;
 74	}
 75	psp->capability = val;
 76
 77	/* Detect if TSME and SME are both enabled */
 78	if (psp->capability & PSP_CAPABILITY_PSP_SECURITY_REPORTING &&
 79	    psp->capability & (PSP_SECURITY_TSME_STATUS << PSP_CAPABILITY_PSP_SECURITY_OFFSET) &&
 80	    cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
 81		dev_notice(psp->dev, "psp: Both TSME and SME are active, SME is unnecessary when TSME is active.\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 82
 83	return 0;
 84}
 85
 86static int psp_check_sev_support(struct psp_device *psp)
 87{
 88	/* Check if device supports SEV feature */
 89	if (!(psp->capability & PSP_CAPABILITY_SEV)) {
 90		dev_dbg(psp->dev, "psp does not support SEV\n");
 
 
 91		return -ENODEV;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 92	}
 93
 94	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 95}
 96
 97static int psp_check_tee_support(struct psp_device *psp)
 98{
 99	/* Check if device supports TEE feature */
100	if (!(psp->capability & PSP_CAPABILITY_TEE)) {
101		dev_dbg(psp->dev, "psp does not support TEE\n");
 
102		return -ENODEV;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103	}
104
105	return 0;
106}
107
108static int psp_init(struct psp_device *psp)
109{
 
110	int ret;
111
112	if (!psp_check_sev_support(psp)) {
113		ret = sev_dev_init(psp);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114		if (ret)
115			return ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116	}
117
118	if (!psp_check_tee_support(psp)) {
119		ret = tee_dev_init(psp);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120		if (ret)
121			return ret;
 
 
 
 
122	}
123
 
 
 
 
124	return 0;
125}
126
 
 
 
 
 
 
 
 
 
 
 
127int psp_dev_init(struct sp_device *sp)
128{
129	struct device *dev = sp->dev;
130	struct psp_device *psp;
131	int ret;
132
133	ret = -ENOMEM;
134	psp = psp_alloc_struct(sp);
135	if (!psp)
136		goto e_err;
137
138	sp->psp_data = psp;
139
140	psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
141	if (!psp->vdata) {
142		ret = -ENODEV;
143		dev_err(dev, "missing driver data\n");
144		goto e_err;
145	}
146
147	psp->io_regs = sp->io_map;
148
149	ret = psp_get_capability(psp);
150	if (ret)
151		goto e_disable;
152
153	/* Disable and clear interrupts until ready */
154	iowrite32(0, psp->io_regs + psp->vdata->inten_reg);
155	iowrite32(-1, psp->io_regs + psp->vdata->intsts_reg);
156
157	/* Request an irq */
158	ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
159	if (ret) {
160		dev_err(dev, "psp: unable to allocate an IRQ\n");
161		goto e_err;
162	}
163
164	ret = psp_init(psp);
165	if (ret)
166		goto e_irq;
167
168	if (sp->set_psp_master_device)
169		sp->set_psp_master_device(sp);
170
171	/* Enable interrupt */
172	iowrite32(-1, psp->io_regs + psp->vdata->inten_reg);
173
174	dev_notice(dev, "psp enabled\n");
175
176	return 0;
177
178e_irq:
179	sp_free_psp_irq(psp->sp, psp);
180e_err:
181	sp->psp_data = NULL;
182
183	dev_notice(dev, "psp initialization failed\n");
184
185	return ret;
186
187e_disable:
188	sp->psp_data = NULL;
189
190	return ret;
191}
192
193void psp_dev_destroy(struct sp_device *sp)
194{
195	struct psp_device *psp = sp->psp_data;
196
197	if (!psp)
198		return;
199
200	sev_dev_destroy(psp);
201
202	tee_dev_destroy(psp);
203
204	sp_free_psp_irq(sp, psp);
205
206	if (sp->clear_psp_master_device)
207		sp->clear_psp_master_device(sp);
208}
209
210void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
211			     void *data)
212{
213	psp->sev_irq_data = data;
214	psp->sev_irq_handler = handler;
215}
216
217void psp_clear_sev_irq_handler(struct psp_device *psp)
218{
219	psp_set_sev_irq_handler(psp, NULL, NULL);
220}
 
221
222void psp_set_tee_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
223			     void *data)
224{
225	psp->tee_irq_data = data;
226	psp->tee_irq_handler = handler;
227}
228
229void psp_clear_tee_irq_handler(struct psp_device *psp)
230{
231	psp_set_tee_irq_handler(psp, NULL, NULL);
232}
233
234struct psp_device *psp_get_master_device(void)
235{
236	struct sp_device *sp = sp_get_psp_master_device();
237
238	return sp ? sp->psp_data : NULL;
239}
 
 
 
 
240
241void psp_pci_init(void)
242{
243	psp_master = psp_get_master_device();
 
 
 
 
244
245	if (!psp_master)
246		return;
 
247
248	sev_pci_init();
 
249}
250
251void psp_pci_exit(void)
252{
253	if (!psp_master)
254		return;
255
256	sev_pci_exit();
257}
v4.17
 
  1/*
  2 * AMD Platform Security Processor (PSP) interface
  3 *
  4 * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
  5 *
  6 * Author: Brijesh Singh <brijesh.singh@amd.com>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License version 2 as
 10 * published by the Free Software Foundation.
 11 */
 12
 13#include <linux/module.h>
 14#include <linux/kernel.h>
 15#include <linux/kthread.h>
 16#include <linux/sched.h>
 17#include <linux/interrupt.h>
 18#include <linux/spinlock.h>
 19#include <linux/spinlock_types.h>
 20#include <linux/types.h>
 21#include <linux/mutex.h>
 22#include <linux/delay.h>
 23#include <linux/hw_random.h>
 24#include <linux/ccp.h>
 25
 26#include "sp-dev.h"
 27#include "psp-dev.h"
 
 
 28
 29#define DEVICE_NAME	"sev"
 30
 31static DEFINE_MUTEX(sev_cmd_mutex);
 32static struct sev_misc_dev *misc_dev;
 33static struct psp_device *psp_master;
 34
 35static struct psp_device *psp_alloc_struct(struct sp_device *sp)
 36{
 37	struct device *dev = sp->dev;
 38	struct psp_device *psp;
 39
 40	psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
 41	if (!psp)
 42		return NULL;
 43
 44	psp->dev = dev;
 45	psp->sp = sp;
 46
 47	snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
 48
 49	return psp;
 50}
 51
 52static irqreturn_t psp_irq_handler(int irq, void *data)
 53{
 54	struct psp_device *psp = data;
 55	unsigned int status;
 56	int reg;
 57
 58	/* Read the interrupt status: */
 59	status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
 60
 61	/* Check if it is command completion: */
 62	if (!(status & BIT(PSP_CMD_COMPLETE_REG)))
 63		goto done;
 64
 65	/* Check if it is SEV command completion: */
 66	reg = ioread32(psp->io_regs + PSP_CMDRESP);
 67	if (reg & PSP_CMDRESP_RESP) {
 68		psp->sev_int_rcvd = 1;
 69		wake_up(&psp->sev_int_queue);
 70	}
 71
 72done:
 73	/* Clear the interrupt status by writing the same value we read. */
 74	iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);
 75
 76	return IRQ_HANDLED;
 77}
 78
 79static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
 80{
 81	psp->sev_int_rcvd = 0;
 82
 83	wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
 84	*reg = ioread32(psp->io_regs + PSP_CMDRESP);
 85}
 
 
 
 
 
 
 
 
 
 86
 87static int sev_cmd_buffer_len(int cmd)
 88{
 89	switch (cmd) {
 90	case SEV_CMD_INIT:			return sizeof(struct sev_data_init);
 91	case SEV_CMD_PLATFORM_STATUS:		return sizeof(struct sev_user_data_status);
 92	case SEV_CMD_PEK_CSR:			return sizeof(struct sev_data_pek_csr);
 93	case SEV_CMD_PEK_CERT_IMPORT:		return sizeof(struct sev_data_pek_cert_import);
 94	case SEV_CMD_PDH_CERT_EXPORT:		return sizeof(struct sev_data_pdh_cert_export);
 95	case SEV_CMD_LAUNCH_START:		return sizeof(struct sev_data_launch_start);
 96	case SEV_CMD_LAUNCH_UPDATE_DATA:	return sizeof(struct sev_data_launch_update_data);
 97	case SEV_CMD_LAUNCH_UPDATE_VMSA:	return sizeof(struct sev_data_launch_update_vmsa);
 98	case SEV_CMD_LAUNCH_FINISH:		return sizeof(struct sev_data_launch_finish);
 99	case SEV_CMD_LAUNCH_MEASURE:		return sizeof(struct sev_data_launch_measure);
100	case SEV_CMD_ACTIVATE:			return sizeof(struct sev_data_activate);
101	case SEV_CMD_DEACTIVATE:		return sizeof(struct sev_data_deactivate);
102	case SEV_CMD_DECOMMISSION:		return sizeof(struct sev_data_decommission);
103	case SEV_CMD_GUEST_STATUS:		return sizeof(struct sev_data_guest_status);
104	case SEV_CMD_DBG_DECRYPT:		return sizeof(struct sev_data_dbg);
105	case SEV_CMD_DBG_ENCRYPT:		return sizeof(struct sev_data_dbg);
106	case SEV_CMD_SEND_START:		return sizeof(struct sev_data_send_start);
107	case SEV_CMD_SEND_UPDATE_DATA:		return sizeof(struct sev_data_send_update_data);
108	case SEV_CMD_SEND_UPDATE_VMSA:		return sizeof(struct sev_data_send_update_vmsa);
109	case SEV_CMD_SEND_FINISH:		return sizeof(struct sev_data_send_finish);
110	case SEV_CMD_RECEIVE_START:		return sizeof(struct sev_data_receive_start);
111	case SEV_CMD_RECEIVE_FINISH:		return sizeof(struct sev_data_receive_finish);
112	case SEV_CMD_RECEIVE_UPDATE_DATA:	return sizeof(struct sev_data_receive_update_data);
113	case SEV_CMD_RECEIVE_UPDATE_VMSA:	return sizeof(struct sev_data_receive_update_vmsa);
114	case SEV_CMD_LAUNCH_UPDATE_SECRET:	return sizeof(struct sev_data_launch_secret);
115	default:				return 0;
116	}
117
118	return 0;
119}
120
121static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
122{
123	struct psp_device *psp = psp_master;
124	unsigned int phys_lsb, phys_msb;
125	unsigned int reg, ret = 0;
126
127	if (!psp)
128		return -ENODEV;
129
130	/* Get the physical address of the command buffer */
131	phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0;
132	phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0;
133
134	dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x\n",
135		cmd, phys_msb, phys_lsb);
136
137	print_hex_dump_debug("(in):  ", DUMP_PREFIX_OFFSET, 16, 2, data,
138			     sev_cmd_buffer_len(cmd), false);
139
140	iowrite32(phys_lsb, psp->io_regs + PSP_CMDBUFF_ADDR_LO);
141	iowrite32(phys_msb, psp->io_regs + PSP_CMDBUFF_ADDR_HI);
142
143	reg = cmd;
144	reg <<= PSP_CMDRESP_CMD_SHIFT;
145	reg |= PSP_CMDRESP_IOC;
146	iowrite32(reg, psp->io_regs + PSP_CMDRESP);
147
148	/* wait for command completion */
149	sev_wait_cmd_ioc(psp, &reg);
150
151	if (psp_ret)
152		*psp_ret = reg & PSP_CMDRESP_ERR_MASK;
153
154	if (reg & PSP_CMDRESP_ERR_MASK) {
155		dev_dbg(psp->dev, "sev command %#x failed (%#010x)\n",
156			cmd, reg & PSP_CMDRESP_ERR_MASK);
157		ret = -EIO;
158	}
159
160	print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
161			     sev_cmd_buffer_len(cmd), false);
162
163	return ret;
164}
165
166static int sev_do_cmd(int cmd, void *data, int *psp_ret)
167{
168	int rc;
169
170	mutex_lock(&sev_cmd_mutex);
171	rc = __sev_do_cmd_locked(cmd, data, psp_ret);
172	mutex_unlock(&sev_cmd_mutex);
173
174	return rc;
175}
176
177static int __sev_platform_init_locked(int *error)
178{
179	struct psp_device *psp = psp_master;
180	int rc = 0;
181
182	if (!psp)
183		return -ENODEV;
184
185	if (psp->sev_state == SEV_STATE_INIT)
186		return 0;
187
188	rc = __sev_do_cmd_locked(SEV_CMD_INIT, &psp->init_cmd_buf, error);
189	if (rc)
190		return rc;
191
192	psp->sev_state = SEV_STATE_INIT;
193	dev_dbg(psp->dev, "SEV firmware initialized\n");
194
195	return rc;
196}
197
198int sev_platform_init(int *error)
199{
200	int rc;
201
202	mutex_lock(&sev_cmd_mutex);
203	rc = __sev_platform_init_locked(error);
204	mutex_unlock(&sev_cmd_mutex);
205
206	return rc;
207}
208EXPORT_SYMBOL_GPL(sev_platform_init);
209
210static int __sev_platform_shutdown_locked(int *error)
211{
212	int ret;
213
214	ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
215	if (ret)
216		return ret;
217
218	psp_master->sev_state = SEV_STATE_UNINIT;
219	dev_dbg(psp_master->dev, "SEV firmware shutdown\n");
220
221	return ret;
222}
223
224static int sev_platform_shutdown(int *error)
225{
226	int rc;
227
228	mutex_lock(&sev_cmd_mutex);
229	rc = __sev_platform_shutdown_locked(NULL);
230	mutex_unlock(&sev_cmd_mutex);
231
232	return rc;
233}
234
235static int sev_get_platform_state(int *state, int *error)
236{
237	int rc;
238
239	rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS,
240				 &psp_master->status_cmd_buf, error);
241	if (rc)
242		return rc;
243
244	*state = psp_master->status_cmd_buf.state;
245	return rc;
246}
247
248static int sev_ioctl_do_reset(struct sev_issue_cmd *argp)
249{
250	int state, rc;
251
252	/*
253	 * The SEV spec requires that FACTORY_RESET must be issued in
254	 * UNINIT state. Before we go further lets check if any guest is
255	 * active.
256	 *
257	 * If FW is in WORKING state then deny the request otherwise issue
258	 * SHUTDOWN command do INIT -> UNINIT before issuing the FACTORY_RESET.
259	 *
260	 */
261	rc = sev_get_platform_state(&state, &argp->error);
262	if (rc)
263		return rc;
264
265	if (state == SEV_STATE_WORKING)
266		return -EBUSY;
267
268	if (state == SEV_STATE_INIT) {
269		rc = __sev_platform_shutdown_locked(&argp->error);
270		if (rc)
271			return rc;
272	}
273
274	return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, NULL, &argp->error);
275}
276
277static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
278{
279	struct sev_user_data_status *data = &psp_master->status_cmd_buf;
280	int ret;
281
282	ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error);
283	if (ret)
284		return ret;
285
286	if (copy_to_user((void __user *)argp->data, data, sizeof(*data)))
287		ret = -EFAULT;
288
289	return ret;
290}
291
292static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp)
293{
294	int rc;
295
296	if (psp_master->sev_state == SEV_STATE_UNINIT) {
297		rc = __sev_platform_init_locked(&argp->error);
298		if (rc)
299			return rc;
300	}
301
302	return __sev_do_cmd_locked(cmd, NULL, &argp->error);
303}
304
305static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp)
306{
307	struct sev_user_data_pek_csr input;
308	struct sev_data_pek_csr *data;
309	void *blob = NULL;
310	int ret;
311
312	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
313		return -EFAULT;
314
315	data = kzalloc(sizeof(*data), GFP_KERNEL);
316	if (!data)
317		return -ENOMEM;
318
319	/* userspace wants to query CSR length */
320	if (!input.address || !input.length)
321		goto cmd;
322
323	/* allocate a physically contiguous buffer to store the CSR blob */
324	if (!access_ok(VERIFY_WRITE, input.address, input.length) ||
325	    input.length > SEV_FW_BLOB_MAX_SIZE) {
326		ret = -EFAULT;
327		goto e_free;
328	}
329
330	blob = kmalloc(input.length, GFP_KERNEL);
331	if (!blob) {
332		ret = -ENOMEM;
333		goto e_free;
334	}
335
336	data->address = __psp_pa(blob);
337	data->len = input.length;
338
339cmd:
340	if (psp_master->sev_state == SEV_STATE_UNINIT) {
341		ret = __sev_platform_init_locked(&argp->error);
342		if (ret)
343			goto e_free_blob;
344	}
345
346	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error);
347
348	 /* If we query the CSR length, FW responded with expected data. */
349	input.length = data->len;
350
351	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
352		ret = -EFAULT;
353		goto e_free_blob;
354	}
355
356	if (blob) {
357		if (copy_to_user((void __user *)input.address, blob, input.length))
358			ret = -EFAULT;
359	}
360
361e_free_blob:
362	kfree(blob);
363e_free:
364	kfree(data);
365	return ret;
366}
367
368void *psp_copy_user_blob(u64 __user uaddr, u32 len)
369{
370	if (!uaddr || !len)
371		return ERR_PTR(-EINVAL);
372
373	/* verify that blob length does not exceed our limit */
374	if (len > SEV_FW_BLOB_MAX_SIZE)
375		return ERR_PTR(-EINVAL);
376
377	return memdup_user((void __user *)(uintptr_t)uaddr, len);
378}
379EXPORT_SYMBOL_GPL(psp_copy_user_blob);
380
381static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp)
382{
383	struct sev_user_data_pek_cert_import input;
384	struct sev_data_pek_cert_import *data;
385	void *pek_blob, *oca_blob;
386	int ret;
387
388	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
389		return -EFAULT;
390
391	data = kzalloc(sizeof(*data), GFP_KERNEL);
392	if (!data)
393		return -ENOMEM;
394
395	/* copy PEK certificate blobs from userspace */
396	pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len);
397	if (IS_ERR(pek_blob)) {
398		ret = PTR_ERR(pek_blob);
399		goto e_free;
400	}
401
402	data->pek_cert_address = __psp_pa(pek_blob);
403	data->pek_cert_len = input.pek_cert_len;
404
405	/* copy PEK certificate blobs from userspace */
406	oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len);
407	if (IS_ERR(oca_blob)) {
408		ret = PTR_ERR(oca_blob);
409		goto e_free_pek;
410	}
411
412	data->oca_cert_address = __psp_pa(oca_blob);
413	data->oca_cert_len = input.oca_cert_len;
414
415	/* If platform is not in INIT state then transition it to INIT */
416	if (psp_master->sev_state != SEV_STATE_INIT) {
417		ret = __sev_platform_init_locked(&argp->error);
418		if (ret)
419			goto e_free_oca;
420	}
421
422	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, data, &argp->error);
423
424e_free_oca:
425	kfree(oca_blob);
426e_free_pek:
427	kfree(pek_blob);
428e_free:
429	kfree(data);
430	return ret;
431}
432
433static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp)
434{
435	struct sev_user_data_pdh_cert_export input;
436	void *pdh_blob = NULL, *cert_blob = NULL;
437	struct sev_data_pdh_cert_export *data;
438	int ret;
439
440	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
441		return -EFAULT;
442
443	data = kzalloc(sizeof(*data), GFP_KERNEL);
444	if (!data)
445		return -ENOMEM;
446
447	/* Userspace wants to query the certificate length. */
448	if (!input.pdh_cert_address ||
449	    !input.pdh_cert_len ||
450	    !input.cert_chain_address)
451		goto cmd;
452
453	/* Allocate a physically contiguous buffer to store the PDH blob. */
454	if ((input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) ||
455	    !access_ok(VERIFY_WRITE, input.pdh_cert_address, input.pdh_cert_len)) {
456		ret = -EFAULT;
457		goto e_free;
458	}
459
460	/* Allocate a physically contiguous buffer to store the cert chain blob. */
461	if ((input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) ||
462	    !access_ok(VERIFY_WRITE, input.cert_chain_address, input.cert_chain_len)) {
463		ret = -EFAULT;
464		goto e_free;
465	}
466
467	pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
468	if (!pdh_blob) {
469		ret = -ENOMEM;
470		goto e_free;
471	}
472
473	data->pdh_cert_address = __psp_pa(pdh_blob);
474	data->pdh_cert_len = input.pdh_cert_len;
475
476	cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
477	if (!cert_blob) {
478		ret = -ENOMEM;
479		goto e_free_pdh;
480	}
481
482	data->cert_chain_address = __psp_pa(cert_blob);
483	data->cert_chain_len = input.cert_chain_len;
484
485cmd:
486	/* If platform is not in INIT state then transition it to INIT. */
487	if (psp_master->sev_state != SEV_STATE_INIT) {
488		ret = __sev_platform_init_locked(&argp->error);
489		if (ret)
490			goto e_free_cert;
491	}
492
493	ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, data, &argp->error);
494
495	/* If we query the length, FW responded with expected data. */
496	input.cert_chain_len = data->cert_chain_len;
497	input.pdh_cert_len = data->pdh_cert_len;
498
499	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
500		ret = -EFAULT;
501		goto e_free_cert;
502	}
503
504	if (pdh_blob) {
505		if (copy_to_user((void __user *)input.pdh_cert_address,
506				 pdh_blob, input.pdh_cert_len)) {
507			ret = -EFAULT;
508			goto e_free_cert;
509		}
510	}
511
512	if (cert_blob) {
513		if (copy_to_user((void __user *)input.cert_chain_address,
514				 cert_blob, input.cert_chain_len))
515			ret = -EFAULT;
516	}
517
518e_free_cert:
519	kfree(cert_blob);
520e_free_pdh:
521	kfree(pdh_blob);
522e_free:
523	kfree(data);
524	return ret;
525}
526
527static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
528{
529	void __user *argp = (void __user *)arg;
530	struct sev_issue_cmd input;
531	int ret = -EFAULT;
532
533	if (!psp_master)
534		return -ENODEV;
535
536	if (ioctl != SEV_ISSUE_CMD)
537		return -EINVAL;
538
539	if (copy_from_user(&input, argp, sizeof(struct sev_issue_cmd)))
540		return -EFAULT;
541
542	if (input.cmd > SEV_MAX)
543		return -EINVAL;
544
545	mutex_lock(&sev_cmd_mutex);
546
547	switch (input.cmd) {
548
549	case SEV_FACTORY_RESET:
550		ret = sev_ioctl_do_reset(&input);
551		break;
552	case SEV_PLATFORM_STATUS:
553		ret = sev_ioctl_do_platform_status(&input);
554		break;
555	case SEV_PEK_GEN:
556		ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PEK_GEN, &input);
557		break;
558	case SEV_PDH_GEN:
559		ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PDH_GEN, &input);
560		break;
561	case SEV_PEK_CSR:
562		ret = sev_ioctl_do_pek_csr(&input);
563		break;
564	case SEV_PEK_CERT_IMPORT:
565		ret = sev_ioctl_do_pek_import(&input);
566		break;
567	case SEV_PDH_CERT_EXPORT:
568		ret = sev_ioctl_do_pdh_export(&input);
569		break;
570	default:
571		ret = -EINVAL;
572		goto out;
573	}
574
575	if (copy_to_user(argp, &input, sizeof(struct sev_issue_cmd)))
576		ret = -EFAULT;
577out:
578	mutex_unlock(&sev_cmd_mutex);
579
580	return ret;
581}
582
583static const struct file_operations sev_fops = {
584	.owner	= THIS_MODULE,
585	.unlocked_ioctl = sev_ioctl,
586};
587
588int sev_platform_status(struct sev_user_data_status *data, int *error)
589{
590	return sev_do_cmd(SEV_CMD_PLATFORM_STATUS, data, error);
591}
592EXPORT_SYMBOL_GPL(sev_platform_status);
593
594int sev_guest_deactivate(struct sev_data_deactivate *data, int *error)
595{
596	return sev_do_cmd(SEV_CMD_DEACTIVATE, data, error);
597}
598EXPORT_SYMBOL_GPL(sev_guest_deactivate);
599
600int sev_guest_activate(struct sev_data_activate *data, int *error)
601{
602	return sev_do_cmd(SEV_CMD_ACTIVATE, data, error);
603}
604EXPORT_SYMBOL_GPL(sev_guest_activate);
605
606int sev_guest_decommission(struct sev_data_decommission *data, int *error)
607{
608	return sev_do_cmd(SEV_CMD_DECOMMISSION, data, error);
609}
610EXPORT_SYMBOL_GPL(sev_guest_decommission);
611
612int sev_guest_df_flush(int *error)
613{
614	return sev_do_cmd(SEV_CMD_DF_FLUSH, NULL, error);
615}
616EXPORT_SYMBOL_GPL(sev_guest_df_flush);
617
618static void sev_exit(struct kref *ref)
619{
620	struct sev_misc_dev *misc_dev = container_of(ref, struct sev_misc_dev, refcount);
621
622	misc_deregister(&misc_dev->misc);
623}
624
625static int sev_misc_init(struct psp_device *psp)
626{
627	struct device *dev = psp->dev;
628	int ret;
629
630	/*
631	 * SEV feature support can be detected on multiple devices but the SEV
632	 * FW commands must be issued on the master. During probe, we do not
633	 * know the master hence we create /dev/sev on the first device probe.
634	 * sev_do_cmd() finds the right master device to which to issue the
635	 * command to the firmware.
636	 */
637	if (!misc_dev) {
638		struct miscdevice *misc;
639
640		misc_dev = devm_kzalloc(dev, sizeof(*misc_dev), GFP_KERNEL);
641		if (!misc_dev)
642			return -ENOMEM;
643
644		misc = &misc_dev->misc;
645		misc->minor = MISC_DYNAMIC_MINOR;
646		misc->name = DEVICE_NAME;
647		misc->fops = &sev_fops;
648
649		ret = misc_register(misc);
650		if (ret)
651			return ret;
652
653		kref_init(&misc_dev->refcount);
654	} else {
655		kref_get(&misc_dev->refcount);
656	}
657
658	init_waitqueue_head(&psp->sev_int_queue);
659	psp->sev_misc = misc_dev;
660	dev_dbg(dev, "registered SEV device\n");
661
662	return 0;
663}
664
665static int sev_init(struct psp_device *psp)
666{
667	/* Check if device supports SEV feature */
668	if (!(ioread32(psp->io_regs + PSP_FEATURE_REG) & 1)) {
669		dev_dbg(psp->dev, "device does not support SEV\n");
670		return 1;
671	}
672
673	return sev_misc_init(psp);
674}
675
676int psp_dev_init(struct sp_device *sp)
677{
678	struct device *dev = sp->dev;
679	struct psp_device *psp;
680	int ret;
681
682	ret = -ENOMEM;
683	psp = psp_alloc_struct(sp);
684	if (!psp)
685		goto e_err;
686
687	sp->psp_data = psp;
688
689	psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
690	if (!psp->vdata) {
691		ret = -ENODEV;
692		dev_err(dev, "missing driver data\n");
693		goto e_err;
694	}
695
696	psp->io_regs = sp->io_map + psp->vdata->offset;
 
 
 
 
697
698	/* Disable and clear interrupts until ready */
699	iowrite32(0, psp->io_regs + PSP_P2CMSG_INTEN);
700	iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTSTS);
701
702	/* Request an irq */
703	ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
704	if (ret) {
705		dev_err(dev, "psp: unable to allocate an IRQ\n");
706		goto e_err;
707	}
708
709	ret = sev_init(psp);
710	if (ret)
711		goto e_irq;
712
713	if (sp->set_psp_master_device)
714		sp->set_psp_master_device(sp);
715
716	/* Enable interrupt */
717	iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTEN);
 
 
718
719	return 0;
720
721e_irq:
722	sp_free_psp_irq(psp->sp, psp);
723e_err:
724	sp->psp_data = NULL;
725
726	dev_notice(dev, "psp initialization failed\n");
727
728	return ret;
 
 
 
 
 
729}
730
731void psp_dev_destroy(struct sp_device *sp)
732{
733	struct psp_device *psp = sp->psp_data;
734
735	if (psp->sev_misc)
736		kref_put(&misc_dev->refcount, sev_exit);
 
 
 
 
737
738	sp_free_psp_irq(sp, psp);
 
 
 
739}
740
741int sev_issue_cmd_external_user(struct file *filep, unsigned int cmd,
742				void *data, int *error)
743{
744	if (!filep || filep->f_op != &sev_fops)
745		return -EBADF;
 
746
747	return  sev_do_cmd(cmd, data, error);
 
 
748}
749EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);
750
751void psp_pci_init(void)
 
752{
753	struct sev_user_data_status *status;
754	struct sp_device *sp;
755	int error, rc;
756
757	sp = sp_get_psp_master_device();
758	if (!sp)
759		return;
 
760
761	psp_master = sp->psp_data;
 
 
762
763	/* Initialize the platform */
764	rc = sev_platform_init(&error);
765	if (rc) {
766		dev_err(sp->dev, "SEV: failed to INIT error %#x\n", error);
767		goto err;
768	}
769
770	/* Display SEV firmware version */
771	status = &psp_master->status_cmd_buf;
772	rc = sev_platform_status(status, &error);
773	if (rc) {
774		dev_err(sp->dev, "SEV: failed to get status error %#x\n", error);
775		goto err;
776	}
777
778	dev_info(sp->dev, "SEV API:%d.%d build:%d\n", status->api_major,
779		 status->api_minor, status->build);
780	return;
781
782err:
783	psp_master = NULL;
784}
785
786void psp_pci_exit(void)
787{
788	if (!psp_master)
789		return;
790
791	sev_platform_shutdown(NULL);
792}