Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AMD Secure Processor driver
0004  *
0005  * Copyright (C) 2017-2018 Advanced Micro Devices, Inc.
0006  *
0007  * Author: Tom Lendacky <thomas.lendacky@amd.com>
0008  * Author: Gary R Hook <gary.hook@amd.com>
0009  * Author: Brijesh Singh <brijesh.singh@amd.com>
0010  */
0011 
0012 #include <linux/module.h>
0013 #include <linux/kernel.h>
0014 #include <linux/kthread.h>
0015 #include <linux/sched.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/spinlock_types.h>
0019 #include <linux/types.h>
0020 #include <linux/ccp.h>
0021 
0022 #include "ccp-dev.h"
0023 #include "sp-dev.h"
0024 
0025 MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
0026 MODULE_AUTHOR("Gary R Hook <gary.hook@amd.com>");
0027 MODULE_LICENSE("GPL");
0028 MODULE_VERSION("1.1.0");
0029 MODULE_DESCRIPTION("AMD Secure Processor driver");
0030 
0031 /* List of SPs, SP count, read-write access lock, and access functions
0032  *
0033  * Lock structure: get sp_unit_lock for reading whenever we need to
0034  * examine the SP list.
0035  */
0036 static DEFINE_RWLOCK(sp_unit_lock);
0037 static LIST_HEAD(sp_units);
0038 
0039 /* Ever-increasing value to produce unique unit numbers */
0040 static atomic_t sp_ordinal;
0041 
0042 static void sp_add_device(struct sp_device *sp)
0043 {
0044     unsigned long flags;
0045 
0046     write_lock_irqsave(&sp_unit_lock, flags);
0047 
0048     list_add_tail(&sp->entry, &sp_units);
0049 
0050     write_unlock_irqrestore(&sp_unit_lock, flags);
0051 }
0052 
0053 static void sp_del_device(struct sp_device *sp)
0054 {
0055     unsigned long flags;
0056 
0057     write_lock_irqsave(&sp_unit_lock, flags);
0058 
0059     list_del(&sp->entry);
0060 
0061     write_unlock_irqrestore(&sp_unit_lock, flags);
0062 }
0063 
0064 static irqreturn_t sp_irq_handler(int irq, void *data)
0065 {
0066     struct sp_device *sp = data;
0067 
0068     if (sp->ccp_irq_handler)
0069         sp->ccp_irq_handler(irq, sp->ccp_irq_data);
0070 
0071     if (sp->psp_irq_handler)
0072         sp->psp_irq_handler(irq, sp->psp_irq_data);
0073 
0074     return IRQ_HANDLED;
0075 }
0076 
0077 int sp_request_ccp_irq(struct sp_device *sp, irq_handler_t handler,
0078                const char *name, void *data)
0079 {
0080     int ret;
0081 
0082     if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->psp_vdata) {
0083         /* Need a common routine to manage all interrupts */
0084         sp->ccp_irq_data = data;
0085         sp->ccp_irq_handler = handler;
0086 
0087         if (!sp->irq_registered) {
0088             ret = request_irq(sp->ccp_irq, sp_irq_handler, 0,
0089                       sp->name, sp);
0090             if (ret)
0091                 return ret;
0092 
0093             sp->irq_registered = true;
0094         }
0095     } else {
0096         /* Each sub-device can manage it's own interrupt */
0097         ret = request_irq(sp->ccp_irq, handler, 0, name, data);
0098         if (ret)
0099             return ret;
0100     }
0101 
0102     return 0;
0103 }
0104 
0105 int sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler,
0106                const char *name, void *data)
0107 {
0108     int ret;
0109 
0110     if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->ccp_vdata) {
0111         /* Need a common routine to manage all interrupts */
0112         sp->psp_irq_data = data;
0113         sp->psp_irq_handler = handler;
0114 
0115         if (!sp->irq_registered) {
0116             ret = request_irq(sp->psp_irq, sp_irq_handler, 0,
0117                       sp->name, sp);
0118             if (ret)
0119                 return ret;
0120 
0121             sp->irq_registered = true;
0122         }
0123     } else {
0124         /* Each sub-device can manage it's own interrupt */
0125         ret = request_irq(sp->psp_irq, handler, 0, name, data);
0126         if (ret)
0127             return ret;
0128     }
0129 
0130     return 0;
0131 }
0132 
0133 void sp_free_ccp_irq(struct sp_device *sp, void *data)
0134 {
0135     if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->psp_vdata) {
0136         /* Using common routine to manage all interrupts */
0137         if (!sp->psp_irq_handler) {
0138             /* Nothing else using it, so free it */
0139             free_irq(sp->ccp_irq, sp);
0140 
0141             sp->irq_registered = false;
0142         }
0143 
0144         sp->ccp_irq_handler = NULL;
0145         sp->ccp_irq_data = NULL;
0146     } else {
0147         /* Each sub-device can manage it's own interrupt */
0148         free_irq(sp->ccp_irq, data);
0149     }
0150 }
0151 
0152 void sp_free_psp_irq(struct sp_device *sp, void *data)
0153 {
0154     if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->ccp_vdata) {
0155         /* Using common routine to manage all interrupts */
0156         if (!sp->ccp_irq_handler) {
0157             /* Nothing else using it, so free it */
0158             free_irq(sp->psp_irq, sp);
0159 
0160             sp->irq_registered = false;
0161         }
0162 
0163         sp->psp_irq_handler = NULL;
0164         sp->psp_irq_data = NULL;
0165     } else {
0166         /* Each sub-device can manage it's own interrupt */
0167         free_irq(sp->psp_irq, data);
0168     }
0169 }
0170 
0171 /**
0172  * sp_alloc_struct - allocate and initialize the sp_device struct
0173  *
0174  * @dev: device struct of the SP
0175  */
0176 struct sp_device *sp_alloc_struct(struct device *dev)
0177 {
0178     struct sp_device *sp;
0179 
0180     sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL);
0181     if (!sp)
0182         return NULL;
0183 
0184     sp->dev = dev;
0185     sp->ord = atomic_inc_return(&sp_ordinal);
0186     snprintf(sp->name, SP_MAX_NAME_LEN, "sp-%u", sp->ord);
0187 
0188     return sp;
0189 }
0190 
0191 int sp_init(struct sp_device *sp)
0192 {
0193     sp_add_device(sp);
0194 
0195     if (sp->dev_vdata->ccp_vdata)
0196         ccp_dev_init(sp);
0197 
0198     if (sp->dev_vdata->psp_vdata)
0199         psp_dev_init(sp);
0200     return 0;
0201 }
0202 
0203 void sp_destroy(struct sp_device *sp)
0204 {
0205     if (sp->dev_vdata->ccp_vdata)
0206         ccp_dev_destroy(sp);
0207 
0208     if (sp->dev_vdata->psp_vdata)
0209         psp_dev_destroy(sp);
0210 
0211     sp_del_device(sp);
0212 }
0213 
0214 int sp_suspend(struct sp_device *sp)
0215 {
0216     if (sp->dev_vdata->ccp_vdata) {
0217         ccp_dev_suspend(sp);
0218     }
0219 
0220     return 0;
0221 }
0222 
0223 int sp_resume(struct sp_device *sp)
0224 {
0225     if (sp->dev_vdata->ccp_vdata) {
0226         ccp_dev_resume(sp);
0227     }
0228 
0229     return 0;
0230 }
0231 
0232 struct sp_device *sp_get_psp_master_device(void)
0233 {
0234     struct sp_device *i, *ret = NULL;
0235     unsigned long flags;
0236 
0237     write_lock_irqsave(&sp_unit_lock, flags);
0238     if (list_empty(&sp_units))
0239         goto unlock;
0240 
0241     list_for_each_entry(i, &sp_units, entry) {
0242         if (i->psp_data && i->get_psp_master_device) {
0243             ret = i->get_psp_master_device();
0244             break;
0245         }
0246     }
0247 
0248 unlock:
0249     write_unlock_irqrestore(&sp_unit_lock, flags);
0250     return ret;
0251 }
0252 
0253 static int __init sp_mod_init(void)
0254 {
0255 #ifdef CONFIG_X86
0256     int ret;
0257 
0258     ret = sp_pci_init();
0259     if (ret)
0260         return ret;
0261 
0262 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
0263     psp_pci_init();
0264 #endif
0265 
0266     return 0;
0267 #endif
0268 
0269 #ifdef CONFIG_ARM64
0270     int ret;
0271 
0272     ret = sp_platform_init();
0273     if (ret)
0274         return ret;
0275 
0276     return 0;
0277 #endif
0278 
0279     return -ENODEV;
0280 }
0281 
0282 static void __exit sp_mod_exit(void)
0283 {
0284 #ifdef CONFIG_X86
0285 
0286 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
0287     psp_pci_exit();
0288 #endif
0289 
0290     sp_pci_exit();
0291 #endif
0292 
0293 #ifdef CONFIG_ARM64
0294     sp_platform_exit();
0295 #endif
0296 }
0297 
0298 module_init(sp_mod_init);
0299 module_exit(sp_mod_exit);