linux/drivers/crypto/ccp/psp-dev.c
<<
>>
Prefs
   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}
 793