1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * AMD Secure Processor driver 4 * 5 * Copyright (C) 2017-2018 Advanced Micro Devices, Inc. 6 * 7 * Author: Tom Lendacky <thomas.lendacky@amd.com> 8 * Author: Gary R Hook <gary.hook@amd.com> 9 * Author: Brijesh Singh <brijesh.singh@amd.com> 10 */ 11 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/kthread.h> 15 #include <linux/sched.h> 16 #include <linux/interrupt.h> 17 #include <linux/spinlock.h> 18 #include <linux/spinlock_types.h> 19 #include <linux/types.h> 20 #include <linux/ccp.h> 21 22 #include "sev-dev.h" 23 #include "ccp-dev.h" 24 #include "sp-dev.h" 25 26 MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>"); 27 MODULE_AUTHOR("Gary R Hook <gary.hook@amd.com>"); 28 MODULE_LICENSE("GPL"); 29 MODULE_VERSION("1.1.0"); 30 MODULE_DESCRIPTION("AMD Secure Processor driver"); 31 32 /* List of SPs, SP count, read-write access lock, and access functions 33 * 34 * Lock structure: get sp_unit_lock for reading whenever we need to 35 * examine the SP list. 36 */ 37 static DEFINE_RWLOCK(sp_unit_lock); 38 static LIST_HEAD(sp_units); 39 40 /* Ever-increasing value to produce unique unit numbers */ 41 static atomic_t sp_ordinal; 42 43 static void sp_add_device(struct sp_device *sp) 44 { 45 unsigned long flags; 46 47 write_lock_irqsave(&sp_unit_lock, flags); 48 49 list_add_tail(&sp->entry, &sp_units); 50 51 write_unlock_irqrestore(&sp_unit_lock, flags); 52 } 53 54 static void sp_del_device(struct sp_device *sp) 55 { 56 unsigned long flags; 57 58 write_lock_irqsave(&sp_unit_lock, flags); 59 60 list_del(&sp->entry); 61 62 write_unlock_irqrestore(&sp_unit_lock, flags); 63 } 64 65 static irqreturn_t sp_irq_handler(int irq, void *data) 66 { 67 struct sp_device *sp = data; 68 69 if (sp->ccp_irq_handler) 70 sp->ccp_irq_handler(irq, sp->ccp_irq_data); 71 72 if (sp->psp_irq_handler) 73 sp->psp_irq_handler(irq, sp->psp_irq_data); 74 75 return IRQ_HANDLED; 76 } 77 78 int sp_request_ccp_irq(struct sp_device *sp, irq_handler_t handler, 79 const char *name, void *data) 80 { 81 int ret; 82 83 if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->psp_vdata) { 84 /* Need a common routine to manage all interrupts */ 85 sp->ccp_irq_data = data; 86 sp->ccp_irq_handler = handler; 87 88 if (!sp->irq_registered) { 89 ret = request_irq(sp->ccp_irq, sp_irq_handler, 0, 90 sp->name, sp); 91 if (ret) 92 return ret; 93 94 sp->irq_registered = true; 95 } 96 } else { 97 /* Each sub-device can manage it's own interrupt */ 98 ret = request_irq(sp->ccp_irq, handler, 0, name, data); 99 if (ret) 100 return ret; 101 } 102 103 return 0; 104 } 105 106 int sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler, 107 const char *name, void *data) 108 { 109 int ret; 110 111 if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->ccp_vdata) { 112 /* Need a common routine to manage all interrupts */ 113 sp->psp_irq_data = data; 114 sp->psp_irq_handler = handler; 115 116 if (!sp->irq_registered) { 117 ret = request_irq(sp->psp_irq, sp_irq_handler, 0, 118 sp->name, sp); 119 if (ret) 120 return ret; 121 122 sp->irq_registered = true; 123 } 124 } else { 125 /* Each sub-device can manage it's own interrupt */ 126 ret = request_irq(sp->psp_irq, handler, 0, name, data); 127 if (ret) 128 return ret; 129 } 130 131 return 0; 132 } 133 134 void sp_free_ccp_irq(struct sp_device *sp, void *data) 135 { 136 if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->psp_vdata) { 137 /* Using common routine to manage all interrupts */ 138 if (!sp->psp_irq_handler) { 139 /* Nothing else using it, so free it */ 140 free_irq(sp->ccp_irq, sp); 141 142 sp->irq_registered = false; 143 } 144 145 sp->ccp_irq_handler = NULL; 146 sp->ccp_irq_data = NULL; 147 } else { 148 /* Each sub-device can manage it's own interrupt */ 149 free_irq(sp->ccp_irq, data); 150 } 151 } 152 153 void sp_free_psp_irq(struct sp_device *sp, void *data) 154 { 155 if ((sp->psp_irq == sp->ccp_irq) && sp->dev_vdata->ccp_vdata) { 156 /* Using common routine to manage all interrupts */ 157 if (!sp->ccp_irq_handler) { 158 /* Nothing else using it, so free it */ 159 free_irq(sp->psp_irq, sp); 160 161 sp->irq_registered = false; 162 } 163 164 sp->psp_irq_handler = NULL; 165 sp->psp_irq_data = NULL; 166 } else { 167 /* Each sub-device can manage it's own interrupt */ 168 free_irq(sp->psp_irq, data); 169 } 170 } 171 172 /** 173 * sp_alloc_struct - allocate and initialize the sp_device struct 174 * 175 * @dev: device struct of the SP 176 */ 177 struct sp_device *sp_alloc_struct(struct device *dev) 178 { 179 struct sp_device *sp; 180 181 sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL); 182 if (!sp) 183 return NULL; 184 185 sp->dev = dev; 186 sp->ord = atomic_inc_return(&sp_ordinal); 187 snprintf(sp->name, SP_MAX_NAME_LEN, "sp-%u", sp->ord); 188 189 return sp; 190 } 191 192 int sp_init(struct sp_device *sp) 193 { 194 sp_add_device(sp); 195 196 if (sp->dev_vdata->ccp_vdata) 197 ccp_dev_init(sp); 198 199 if (sp->dev_vdata->psp_vdata) 200 psp_dev_init(sp); 201 return 0; 202 } 203 204 void sp_destroy(struct sp_device *sp) 205 { 206 if (sp->dev_vdata->ccp_vdata) 207 ccp_dev_destroy(sp); 208 209 if (sp->dev_vdata->psp_vdata) 210 psp_dev_destroy(sp); 211 212 sp_del_device(sp); 213 } 214 215 int sp_suspend(struct sp_device *sp) 216 { 217 if (sp->dev_vdata->ccp_vdata) { 218 ccp_dev_suspend(sp); 219 } 220 221 return 0; 222 } 223 224 int sp_resume(struct sp_device *sp) 225 { 226 if (sp->dev_vdata->ccp_vdata) { 227 ccp_dev_resume(sp); 228 } 229 230 return 0; 231 } 232 233 struct sp_device *sp_get_psp_master_device(void) 234 { 235 struct sp_device *i, *ret = NULL; 236 unsigned long flags; 237 238 write_lock_irqsave(&sp_unit_lock, flags); 239 if (list_empty(&sp_units)) 240 goto unlock; 241 242 list_for_each_entry(i, &sp_units, entry) { 243 if (i->psp_data && i->get_psp_master_device) { 244 ret = i->get_psp_master_device(); 245 break; 246 } 247 } 248 249 unlock: 250 write_unlock_irqrestore(&sp_unit_lock, flags); 251 return ret; 252 } 253 254 static int __init sp_mod_init(void) 255 { 256 #ifdef CONFIG_X86 257 static bool initialized; 258 int ret; 259 260 if (initialized) 261 return 0; 262 263 ret = sp_pci_init(); 264 if (ret) 265 return ret; 266 267 #ifdef CONFIG_CRYPTO_DEV_SP_PSP 268 psp_pci_init(); 269 #endif 270 271 initialized = true; 272 273 return 0; 274 #endif 275 276 #ifdef CONFIG_ARM64 277 int ret; 278 279 ret = sp_platform_init(); 280 if (ret) 281 return ret; 282 283 return 0; 284 #endif 285 286 return -ENODEV; 287 } 288 289 #if IS_BUILTIN(CONFIG_KVM_AMD) && IS_ENABLED(CONFIG_KVM_AMD_SEV) 290 int __init sev_module_init(void) 291 { 292 return sp_mod_init(); 293 } 294 #endif 295 296 static void __exit sp_mod_exit(void) 297 { 298 #ifdef CONFIG_X86 299 300 #ifdef CONFIG_CRYPTO_DEV_SP_PSP 301 psp_pci_exit(); 302 #endif 303 304 sp_pci_exit(); 305 #endif 306 307 #ifdef CONFIG_ARM64 308 sp_platform_exit(); 309 #endif 310 } 311 312 module_init(sp_mod_init); 313 module_exit(sp_mod_exit); 314