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 int sp_restore(struct sp_device *sp) 234 { 235 if (sp->psp_data) { 236 int ret = psp_restore(sp); 237 238 if (ret) 239 return ret; 240 } 241 242 return sp_resume(sp); 243 } 244 245 struct sp_device *sp_get_psp_master_device(void) 246 { 247 struct sp_device *i, *ret = NULL; 248 unsigned long flags; 249 250 write_lock_irqsave(&sp_unit_lock, flags); 251 if (list_empty(&sp_units)) 252 goto unlock; 253 254 list_for_each_entry(i, &sp_units, entry) { 255 if (i->psp_data && i->get_psp_master_device) { 256 ret = i->get_psp_master_device(); 257 break; 258 } 259 } 260 261 unlock: 262 write_unlock_irqrestore(&sp_unit_lock, flags); 263 return ret; 264 } 265 266 static int __init sp_mod_init(void) 267 { 268 #ifdef CONFIG_X86 269 static bool initialized; 270 int ret; 271 272 if (initialized) 273 return 0; 274 275 ret = sp_pci_init(); 276 if (ret) 277 return ret; 278 279 #ifdef CONFIG_CRYPTO_DEV_SP_PSP 280 psp_pci_init(); 281 #endif 282 283 initialized = true; 284 285 return 0; 286 #endif 287 288 #ifdef CONFIG_ARM64 289 int ret; 290 291 ret = sp_platform_init(); 292 if (ret) 293 return ret; 294 295 return 0; 296 #endif 297 298 return -ENODEV; 299 } 300 301 #if IS_BUILTIN(CONFIG_KVM_AMD) && IS_ENABLED(CONFIG_KVM_AMD_SEV) 302 int __init sev_module_init(void) 303 { 304 return sp_mod_init(); 305 } 306 #endif 307 308 static void __exit sp_mod_exit(void) 309 { 310 #ifdef CONFIG_X86 311 312 #ifdef CONFIG_CRYPTO_DEV_SP_PSP 313 psp_pci_exit(); 314 #endif 315 316 sp_pci_exit(); 317 #endif 318 319 #ifdef CONFIG_ARM64 320 sp_platform_exit(); 321 #endif 322 } 323 324 module_init(sp_mod_init); 325 module_exit(sp_mod_exit); 326