^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AMD Secure Encrypted Virtualization (SEV) interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016,2019 Advanced Micro Devices, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Brijesh Singh <brijesh.singh@amd.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/hw_random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/ccp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "psp-dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "sev-dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DEVICE_NAME "sev"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SEV_FW_FILE "amd/sev.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SEV_FW_NAME_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static DEFINE_MUTEX(sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static struct sev_misc_dev *misc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int psp_cmd_timeout = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) module_param(psp_cmd_timeout, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODULE_PARM_DESC(psp_cmd_timeout, " default timeout value, in seconds, for PSP commands");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int psp_probe_timeout = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) module_param(psp_probe_timeout, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static bool psp_dead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int psp_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Trusted Memory Region (TMR):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * The TMR is a 1MB area that must be 1MB aligned. Use the page allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * to allocate the memory, which will return aligned memory for the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * allocation order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SEV_ES_TMR_SIZE (1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void *sev_es_tmr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (sev->api_major > maj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (sev->api_major == maj && sev->api_minor >= min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static void sev_irq_handler(int irq, void *data, unsigned int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct sev_device *sev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Check if it is command completion: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!(status & SEV_CMD_COMPLETE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Check if it is SEV command completion: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (reg & PSP_CMDRESP_RESP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) sev->int_rcvd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) wake_up(&sev->int_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static int sev_wait_cmd_ioc(struct sev_device *sev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int *reg, unsigned int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ret = wait_event_timeout(sev->int_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) sev->int_rcvd, timeout * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int sev_cmd_buffer_len(int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case SEV_CMD_INIT: return sizeof(struct sev_data_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case SEV_CMD_PLATFORM_STATUS: return sizeof(struct sev_user_data_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case SEV_CMD_PEK_CSR: return sizeof(struct sev_data_pek_csr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case SEV_CMD_PEK_CERT_IMPORT: return sizeof(struct sev_data_pek_cert_import);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case SEV_CMD_PDH_CERT_EXPORT: return sizeof(struct sev_data_pdh_cert_export);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case SEV_CMD_LAUNCH_START: return sizeof(struct sev_data_launch_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case SEV_CMD_LAUNCH_UPDATE_DATA: return sizeof(struct sev_data_launch_update_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case SEV_CMD_LAUNCH_UPDATE_VMSA: return sizeof(struct sev_data_launch_update_vmsa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case SEV_CMD_LAUNCH_FINISH: return sizeof(struct sev_data_launch_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) case SEV_CMD_LAUNCH_MEASURE: return sizeof(struct sev_data_launch_measure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case SEV_CMD_ACTIVATE: return sizeof(struct sev_data_activate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case SEV_CMD_DEACTIVATE: return sizeof(struct sev_data_deactivate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case SEV_CMD_DECOMMISSION: return sizeof(struct sev_data_decommission);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case SEV_CMD_GUEST_STATUS: return sizeof(struct sev_data_guest_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) case SEV_CMD_DBG_DECRYPT: return sizeof(struct sev_data_dbg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case SEV_CMD_DBG_ENCRYPT: return sizeof(struct sev_data_dbg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case SEV_CMD_SEND_START: return sizeof(struct sev_data_send_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) case SEV_CMD_SEND_UPDATE_DATA: return sizeof(struct sev_data_send_update_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) case SEV_CMD_SEND_UPDATE_VMSA: return sizeof(struct sev_data_send_update_vmsa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case SEV_CMD_SEND_FINISH: return sizeof(struct sev_data_send_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case SEV_CMD_RECEIVE_START: return sizeof(struct sev_data_receive_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) case SEV_CMD_RECEIVE_FINISH: return sizeof(struct sev_data_receive_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) case SEV_CMD_RECEIVE_UPDATE_DATA: return sizeof(struct sev_data_receive_update_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case SEV_CMD_RECEIVE_UPDATE_VMSA: return sizeof(struct sev_data_receive_update_vmsa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) case SEV_CMD_LAUNCH_UPDATE_SECRET: return sizeof(struct sev_data_launch_secret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case SEV_CMD_DOWNLOAD_FIRMWARE: return sizeof(struct sev_data_download_firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case SEV_CMD_GET_ID: return sizeof(struct sev_data_get_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) default: return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct psp_device *psp = psp_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct sev_device *sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int phys_lsb, phys_msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int reg, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!psp || !psp->sev_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (psp_dead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) sev = psp->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (data && WARN_ON_ONCE(!virt_addr_valid(data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Get the physical address of the command buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) cmd, phys_msb, phys_lsb, psp_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) sev_cmd_buffer_len(cmd), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) sev->int_rcvd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) reg = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) reg <<= SEV_CMDRESP_CMD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) reg |= SEV_CMDRESP_IOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) iowrite32(reg, sev->io_regs + sev->vdata->cmdresp_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* wait for command completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = sev_wait_cmd_ioc(sev, ®, psp_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (psp_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *psp_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dev_err(sev->dev, "sev command %#x timed out, disabling PSP\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) psp_dead = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) psp_timeout = psp_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (psp_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *psp_ret = reg & PSP_CMDRESP_ERR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (reg & PSP_CMDRESP_ERR_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev_dbg(sev->dev, "sev command %#x failed (%#010x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cmd, reg & PSP_CMDRESP_ERR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sev_cmd_buffer_len(cmd), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int sev_do_cmd(int cmd, void *data, int *psp_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) mutex_lock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) rc = __sev_do_cmd_locked(cmd, data, psp_ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mutex_unlock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int __sev_platform_init_locked(int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct psp_device *psp = psp_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct sev_device *sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!psp || !psp->sev_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sev = psp->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (sev->state == SEV_STATE_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (sev_es_tmr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u64 tmr_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Do not include the encryption mask on the physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * address of the TMR (firmware should clear it anyway).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) tmr_pa = __pa(sev_es_tmr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) sev->init_cmd_buf.flags |= SEV_INIT_FLAGS_SEV_ES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) sev->init_cmd_buf.tmr_address = tmr_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) sev->init_cmd_buf.tmr_len = SEV_ES_TMR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rc = __sev_do_cmd_locked(SEV_CMD_INIT, &sev->init_cmd_buf, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sev->state = SEV_STATE_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* Prepare for first SEV guest launch after INIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) wbinvd_on_all_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_dbg(sev->dev, "SEV firmware initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int sev_platform_init(int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mutex_lock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) rc = __sev_platform_init_locked(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mutex_unlock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) EXPORT_SYMBOL_GPL(sev_platform_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int __sev_platform_shutdown_locked(int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (sev->state == SEV_STATE_UNINIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) sev->state = SEV_STATE_UNINIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_dbg(sev->dev, "SEV firmware shutdown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int sev_platform_shutdown(int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) mutex_lock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) rc = __sev_platform_shutdown_locked(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mutex_unlock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int sev_get_platform_state(int *state, int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) &sev->status_cmd_buf, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *state = sev->status_cmd_buf.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int state, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (!writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * The SEV spec requires that FACTORY_RESET must be issued in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * UNINIT state. Before we go further lets check if any guest is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * If FW is in WORKING state then deny the request otherwise issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * SHUTDOWN command do INIT -> UNINIT before issuing the FACTORY_RESET.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) rc = sev_get_platform_state(&state, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (state == SEV_STATE_WORKING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (state == SEV_STATE_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) rc = __sev_platform_shutdown_locked(&argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, NULL, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct sev_user_data_status *data = &sev->status_cmd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (copy_to_user((void __user *)argp->data, data, sizeof(*data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp, bool writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (sev->state == SEV_STATE_UNINIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rc = __sev_platform_init_locked(&argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return __sev_do_cmd_locked(cmd, NULL, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct sev_user_data_pek_csr input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct sev_data_pek_csr *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) void __user *input_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) void *blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* userspace wants to query CSR length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!input.address || !input.length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* allocate a physically contiguous buffer to store the CSR blob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) input_address = (void __user *)input.address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (input.length > SEV_FW_BLOB_MAX_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) blob = kmalloc(input.length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) data->address = __psp_pa(blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) data->len = input.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) cmd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (sev->state == SEV_STATE_UNINIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret = __sev_platform_init_locked(&argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto e_free_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* If we query the CSR length, FW responded with expected data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) input.length = data->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) goto e_free_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (copy_to_user(input_address, blob, input.length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) e_free_blob:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) kfree(blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) e_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) void *psp_copy_user_blob(u64 uaddr, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!uaddr || !len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* verify that blob length does not exceed our limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (len > SEV_FW_BLOB_MAX_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return memdup_user((void __user *)uaddr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) EXPORT_SYMBOL_GPL(psp_copy_user_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int sev_get_api_version(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct sev_user_data_status *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int error = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) status = &sev->status_cmd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = sev_platform_status(status, &error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dev_err(sev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) "SEV: failed to get status. Error: %#x\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) sev->api_major = status->api_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) sev->api_minor = status->api_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) sev->build = status->build;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) sev->state = status->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int sev_get_firmware(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) const struct firmware **firmware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) char fw_name_specific[SEV_FW_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) char fw_name_subset[SEV_FW_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) snprintf(fw_name_specific, sizeof(fw_name_specific),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) "amd/amd_sev_fam%.2xh_model%.2xh.sbin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) boot_cpu_data.x86, boot_cpu_data.x86_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) snprintf(fw_name_subset, sizeof(fw_name_subset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) "amd/amd_sev_fam%.2xh_model%.1xxh.sbin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) boot_cpu_data.x86, (boot_cpu_data.x86_model & 0xf0) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Check for SEV FW for a particular model.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * Ex. amd_sev_fam17h_model00h.sbin for Family 17h Model 00h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * Check for SEV FW common to a subset of models.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * Ex. amd_sev_fam17h_model0xh.sbin for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * Family 17h Model 00h -- Family 17h Model 0Fh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * Fall-back to using generic name: sev.fw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if ((firmware_request_nowarn(firmware, fw_name_specific, dev) >= 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) (firmware_request_nowarn(firmware, fw_name_subset, dev) >= 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) (firmware_request_nowarn(firmware, SEV_FW_FILE, dev) >= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* Don't fail if SEV FW couldn't be updated. Continue with existing SEV FW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int sev_update_firmware(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct sev_data_download_firmware *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int ret, error, order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct page *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) u64 data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (sev_get_firmware(dev, &firmware) == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dev_dbg(dev, "No SEV firmware file present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * SEV FW expects the physical address given to it to be 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * byte aligned. Memory allocated has structure placed at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * beginning followed by the firmware being passed to the SEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * FW. Allocate enough memory for data structure + alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * padding + SEV FW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) data_size = ALIGN(sizeof(struct sev_data_download_firmware), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) order = get_order(firmware->size + data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) p = alloc_pages(GFP_KERNEL, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) goto fw_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * Copy firmware data to a kernel allocated contiguous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * memory region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) data = page_address(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) memcpy(page_address(p) + data_size, firmware->data, firmware->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) data->address = __psp_pa(page_address(p) + data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) data->len = firmware->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dev_dbg(dev, "Failed to update SEV firmware: %#x\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dev_info(dev, "SEV firmware update successful\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) __free_pages(p, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) fw_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct sev_user_data_pek_cert_import input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct sev_data_pek_cert_import *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) void *pek_blob, *oca_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (!writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* copy PEK certificate blobs from userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (IS_ERR(pek_blob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ret = PTR_ERR(pek_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) data->pek_cert_address = __psp_pa(pek_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) data->pek_cert_len = input.pek_cert_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* copy PEK certificate blobs from userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (IS_ERR(oca_blob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = PTR_ERR(oca_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) goto e_free_pek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) data->oca_cert_address = __psp_pa(oca_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) data->oca_cert_len = input.oca_cert_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* If platform is not in INIT state then transition it to INIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (sev->state != SEV_STATE_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ret = __sev_platform_init_locked(&argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) goto e_free_oca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, data, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) e_free_oca:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) kfree(oca_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) e_free_pek:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) kfree(pek_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) e_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct sev_user_data_get_id2 input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct sev_data_get_id *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) void __user *input_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) void *id_blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* SEV GET_ID is available from SEV API v0.16 and up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!sev_version_greater_or_equal(0, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) input_address = (void __user *)input.address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (input.address && input.length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) id_blob = kmalloc(input.length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (!id_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) data->address = __psp_pa(id_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) data->len = input.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Firmware will return the length of the ID value (either the minimum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * required length or the actual length written), return it to the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) input.length = data->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (id_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (copy_to_user(input_address, id_blob, data->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) e_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) kfree(id_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int sev_ioctl_do_get_id(struct sev_issue_cmd *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct sev_data_get_id *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) u64 data_size, user_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) void *id_blob, *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /* SEV GET_ID available from SEV API v0.16 and up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!sev_version_greater_or_equal(0, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* SEV FW expects the buffer it fills with the ID to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * 8-byte aligned. Memory allocated should be enough to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * hold data structure + alignment padding + memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * where SEV FW writes the ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) data_size = ALIGN(sizeof(struct sev_data_get_id), 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) user_size = sizeof(struct sev_user_data_get_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) mem = kzalloc(data_size + user_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (!mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) data = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) id_blob = mem + data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) data->address = __psp_pa(id_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) data->len = user_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (copy_to_user((void __user *)argp->data, id_blob, data->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) kfree(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct sev_user_data_pdh_cert_export input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) void *pdh_blob = NULL, *cert_blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct sev_data_pdh_cert_export *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) void __user *input_cert_chain_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) void __user *input_pdh_cert_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* If platform is not in INIT state then transition it to INIT. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (sev->state != SEV_STATE_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ret = __sev_platform_init_locked(&argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* Userspace wants to query the certificate length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!input.pdh_cert_address ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) !input.pdh_cert_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) !input.cert_chain_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) goto cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) input_pdh_cert_address = (void __user *)input.pdh_cert_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) input_cert_chain_address = (void __user *)input.cert_chain_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* Allocate a physically contiguous buffer to store the PDH blob. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* Allocate a physically contiguous buffer to store the cert chain blob. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!pdh_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) goto e_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) data->pdh_cert_address = __psp_pa(pdh_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) data->pdh_cert_len = input.pdh_cert_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (!cert_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) goto e_free_pdh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) data->cert_chain_address = __psp_pa(cert_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) data->cert_chain_len = input.cert_chain_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) cmd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, data, &argp->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* If we query the length, FW responded with expected data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) input.cert_chain_len = data->cert_chain_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) input.pdh_cert_len = data->pdh_cert_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) goto e_free_cert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (pdh_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (copy_to_user(input_pdh_cert_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) pdh_blob, input.pdh_cert_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto e_free_cert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (cert_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (copy_to_user(input_cert_chain_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) cert_blob, input.cert_chain_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) e_free_cert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) kfree(cert_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) e_free_pdh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) kfree(pdh_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) e_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct sev_issue_cmd input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) bool writable = file->f_mode & FMODE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (!psp_master || !psp_master->sev_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (ioctl != SEV_ISSUE_CMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (copy_from_user(&input, argp, sizeof(struct sev_issue_cmd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (input.cmd > SEV_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) mutex_lock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) switch (input.cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) case SEV_FACTORY_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) ret = sev_ioctl_do_reset(&input, writable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case SEV_PLATFORM_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) ret = sev_ioctl_do_platform_status(&input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case SEV_PEK_GEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PEK_GEN, &input, writable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) case SEV_PDH_GEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PDH_GEN, &input, writable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) case SEV_PEK_CSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ret = sev_ioctl_do_pek_csr(&input, writable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case SEV_PEK_CERT_IMPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ret = sev_ioctl_do_pek_import(&input, writable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case SEV_PDH_CERT_EXPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ret = sev_ioctl_do_pdh_export(&input, writable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case SEV_GET_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) pr_warn_once("SEV_GET_ID command is deprecated, use SEV_GET_ID2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ret = sev_ioctl_do_get_id(&input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) case SEV_GET_ID2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ret = sev_ioctl_do_get_id2(&input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (copy_to_user(argp, &input, sizeof(struct sev_issue_cmd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) mutex_unlock(&sev_cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static const struct file_operations sev_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .unlocked_ioctl = sev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int sev_platform_status(struct sev_user_data_status *data, int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return sev_do_cmd(SEV_CMD_PLATFORM_STATUS, data, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) EXPORT_SYMBOL_GPL(sev_platform_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int sev_guest_deactivate(struct sev_data_deactivate *data, int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return sev_do_cmd(SEV_CMD_DEACTIVATE, data, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) EXPORT_SYMBOL_GPL(sev_guest_deactivate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) int sev_guest_activate(struct sev_data_activate *data, int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return sev_do_cmd(SEV_CMD_ACTIVATE, data, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) EXPORT_SYMBOL_GPL(sev_guest_activate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int sev_guest_decommission(struct sev_data_decommission *data, int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return sev_do_cmd(SEV_CMD_DECOMMISSION, data, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) EXPORT_SYMBOL_GPL(sev_guest_decommission);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) int sev_guest_df_flush(int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return sev_do_cmd(SEV_CMD_DF_FLUSH, NULL, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) EXPORT_SYMBOL_GPL(sev_guest_df_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static void sev_exit(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) misc_deregister(&misc_dev->misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) kfree(misc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) misc_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) static int sev_misc_init(struct sev_device *sev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct device *dev = sev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * SEV feature support can be detected on multiple devices but the SEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * FW commands must be issued on the master. During probe, we do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * know the master hence we create /dev/sev on the first device probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * sev_do_cmd() finds the right master device to which to issue the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * command to the firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!misc_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct miscdevice *misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) misc_dev = kzalloc(sizeof(*misc_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (!misc_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) misc = &misc_dev->misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) misc->minor = MISC_DYNAMIC_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) misc->name = DEVICE_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) misc->fops = &sev_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) ret = misc_register(misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) kref_init(&misc_dev->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) kref_get(&misc_dev->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) init_waitqueue_head(&sev->int_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) sev->misc = misc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) dev_dbg(dev, "registered SEV device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) int sev_dev_init(struct psp_device *psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct device *dev = psp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct sev_device *sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) sev = devm_kzalloc(dev, sizeof(*sev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!sev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) goto e_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) psp->sev_data = sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) sev->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) sev->psp = psp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) sev->io_regs = psp->io_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) sev->vdata = (struct sev_vdata *)psp->vdata->sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!sev->vdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) dev_err(dev, "sev: missing driver data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto e_sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) psp_set_sev_irq_handler(psp, sev_irq_handler, sev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ret = sev_misc_init(sev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) goto e_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) dev_notice(dev, "sev enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) e_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) psp_clear_sev_irq_handler(psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) e_sev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) devm_kfree(dev, sev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) e_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) psp->sev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) dev_notice(dev, "sev initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static void sev_firmware_shutdown(struct sev_device *sev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) sev_platform_shutdown(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (sev_es_tmr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* The TMR area was encrypted, flush it from the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) wbinvd_on_all_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) free_pages((unsigned long)sev_es_tmr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) get_order(SEV_ES_TMR_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) sev_es_tmr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) void sev_dev_destroy(struct psp_device *psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct sev_device *sev = psp->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (!sev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) sev_firmware_shutdown(sev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (sev->misc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) kref_put(&misc_dev->refcount, sev_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) psp_clear_sev_irq_handler(psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) int sev_issue_cmd_external_user(struct file *filep, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) void *data, int *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (!filep || filep->f_op != &sev_fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return sev_do_cmd(cmd, data, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) void sev_pci_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct page *tmr_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int error, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (!sev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) psp_timeout = psp_probe_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (sev_get_api_version())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (sev_version_greater_or_equal(0, 15) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) sev_update_firmware(sev->dev) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) sev_get_api_version();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* Obtain the TMR memory area for SEV-ES use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (tmr_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) sev_es_tmr = page_address(tmr_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) sev_es_tmr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) dev_warn(sev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) "SEV: TMR allocation failed, SEV-ES support unavailable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /* Initialize the platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) rc = sev_platform_init(&error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (rc && (error == SEV_RET_SECURE_DATA_INVALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * INIT command returned an integrity check failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * status code, meaning that firmware load and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * validation of SEV related persistent data has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * failed and persistent state has been erased.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * Retrying INIT command here should succeed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) dev_dbg(sev->dev, "SEV: retrying INIT command");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) rc = sev_platform_init(&error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) dev_err(sev->dev, "SEV: failed to INIT error %#x\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) dev_info(sev->dev, "SEV API:%d.%d build:%d\n", sev->api_major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) sev->api_minor, sev->build);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) psp_master->sev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) void sev_pci_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct sev_device *sev = psp_master->sev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (!sev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) sev_firmware_shutdown(sev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }