1 // SPDX-License-Identifier: GPL-2.0-only
3 * AMD Platform Security Processor (PSP) interface
5 * Copyright (C) 2016,2019 Advanced Micro Devices, Inc.
10 #include <linux/kernel.h>
11 #include <linux/irqreturn.h>
17 #include "platform-access.h"
19 struct psp_device *psp_master;
21 static struct psp_device *psp_alloc_struct(struct sp_device *sp)
23 struct device *dev = sp->dev;
24 struct psp_device *psp;
26 psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
33 snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
38 static irqreturn_t psp_irq_handler(int irq, void *data)
40 struct psp_device *psp = data;
43 /* Read the interrupt status: */
44 status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
46 /* Clear the interrupt status by writing the same value we read. */
47 iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
49 /* invoke subdevice interrupt handlers */
51 if (psp->sev_irq_handler)
52 psp->sev_irq_handler(irq, psp->sev_irq_data, status);
58 static unsigned int psp_get_capability(struct psp_device *psp)
60 unsigned int val = ioread32(psp->io_regs + psp->vdata->feature_reg);
63 * Check for a access to the registers. If this read returns
64 * 0xffffffff, it's likely that the system is running a broken
65 * BIOS which disallows access to the device. Stop here and
66 * fail the PSP initialization (but not the load, as the CCP
67 * could get properly initialized).
69 if (val == 0xffffffff) {
70 dev_notice(psp->dev, "psp: unable to access the device: you might be running a broken BIOS.\n");
73 psp->capability = val;
75 /* Detect if TSME and SME are both enabled */
76 if (psp->capability & PSP_CAPABILITY_PSP_SECURITY_REPORTING &&
77 psp->capability & (PSP_SECURITY_TSME_STATUS << PSP_CAPABILITY_PSP_SECURITY_OFFSET) &&
78 cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
79 dev_notice(psp->dev, "psp: Both TSME and SME are active, SME is unnecessary when TSME is active.\n");
84 static int psp_check_sev_support(struct psp_device *psp)
86 /* Check if device supports SEV feature */
87 if (!(psp->capability & PSP_CAPABILITY_SEV)) {
88 dev_dbg(psp->dev, "psp does not support SEV\n");
95 static int psp_check_tee_support(struct psp_device *psp)
97 /* Check if device supports TEE feature */
98 if (!(psp->capability & PSP_CAPABILITY_TEE)) {
99 dev_dbg(psp->dev, "psp does not support TEE\n");
106 static void psp_init_platform_access(struct psp_device *psp)
110 ret = platform_access_dev_init(psp);
112 dev_warn(psp->dev, "platform access init failed: %d\n", ret);
117 static int psp_init(struct psp_device *psp)
121 if (!psp_check_sev_support(psp)) {
122 ret = sev_dev_init(psp);
127 if (!psp_check_tee_support(psp)) {
128 ret = tee_dev_init(psp);
133 if (psp->vdata->platform_access)
134 psp_init_platform_access(psp);
139 int psp_dev_init(struct sp_device *sp)
141 struct device *dev = sp->dev;
142 struct psp_device *psp;
146 psp = psp_alloc_struct(sp);
152 psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
155 dev_err(dev, "missing driver data\n");
159 psp->io_regs = sp->io_map;
161 ret = psp_get_capability(psp);
165 /* Disable and clear interrupts until ready */
166 iowrite32(0, psp->io_regs + psp->vdata->inten_reg);
167 iowrite32(-1, psp->io_regs + psp->vdata->intsts_reg);
170 ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
172 dev_err(dev, "psp: unable to allocate an IRQ\n");
180 if (sp->set_psp_master_device)
181 sp->set_psp_master_device(sp);
183 /* Enable interrupt */
184 iowrite32(-1, psp->io_regs + psp->vdata->inten_reg);
186 dev_notice(dev, "psp enabled\n");
191 sp_free_psp_irq(psp->sp, psp);
195 dev_notice(dev, "psp initialization failed\n");
205 void psp_dev_destroy(struct sp_device *sp)
207 struct psp_device *psp = sp->psp_data;
212 sev_dev_destroy(psp);
214 tee_dev_destroy(psp);
216 platform_access_dev_destroy(psp);
218 sp_free_psp_irq(sp, psp);
220 if (sp->clear_psp_master_device)
221 sp->clear_psp_master_device(sp);
224 void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
227 psp->sev_irq_data = data;
228 psp->sev_irq_handler = handler;
231 void psp_clear_sev_irq_handler(struct psp_device *psp)
233 psp_set_sev_irq_handler(psp, NULL, NULL);
236 struct psp_device *psp_get_master_device(void)
238 struct sp_device *sp = sp_get_psp_master_device();
240 return sp ? sp->psp_data : NULL;
243 void psp_pci_init(void)
245 psp_master = psp_get_master_device();
253 void psp_pci_exit(void)