Lines Matching +full:panic +full:- +full:indicator
1 // SPDX-License-Identifier: GPL-2.0-only
30 #include <linux/amd-iommu.h>
39 #include "psp-dev.h"
40 #include "sev-dev.h"
46 /* Minimum firmware version required for the SEV-SNP support */
51 * Maximum number of firmware-writable buffers that might be specified
56 /* Leave room in the descriptor array for an end-of-list indicator. */
114 * When SEV-SNP is enabled the TMR needs to be 2MB aligned and 2MB sized.
130 static void __sev_firmware_shutdown(struct sev_device *sev, bool panic);
141 struct sev_device *sev = psp_master->sev_data; in sev_version_greater_or_equal()
143 if (sev->api_major > maj) in sev_version_greater_or_equal()
146 if (sev->api_major == maj && sev->api_minor >= min) in sev_version_greater_or_equal()
162 reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg); in sev_irq_handler()
164 sev->int_rcvd = 1; in sev_irq_handler()
165 wake_up(&sev->int_queue); in sev_irq_handler()
175 * If invoked during panic handling, local interrupts are disabled, in sev_wait_cmd_ioc()
183 while (timeout_usecs--) { in sev_wait_cmd_ioc()
184 *reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg); in sev_wait_cmd_ioc()
190 return -ETIMEDOUT; in sev_wait_cmd_ioc()
193 ret = wait_event_timeout(sev->int_queue, in sev_wait_cmd_ioc()
194 sev->int_rcvd, timeout * HZ); in sev_wait_cmd_ioc()
196 return -ETIMEDOUT; in sev_wait_cmd_ioc()
198 *reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg); in sev_wait_cmd_ioc()
271 return ERR_PTR(-ENOMEM); in open_file_as_root()
273 cred->fsuid = GLOBAL_ROOT_UID; in open_file_as_root()
281 struct sev_device *sev = psp_master->sev_data; in sev_read_init_ex_file()
288 return -EOPNOTSUPP; in sev_read_init_ex_file()
294 if (ret == -ENOENT) { in sev_read_init_ex_file()
295 dev_info(sev->dev, in sev_read_init_ex_file()
300 dev_err(sev->dev, in sev_read_init_ex_file()
309 dev_info(sev->dev, in sev_read_init_ex_file()
314 dev_dbg(sev->dev, "SEV: read %ld bytes from NV file\n", nread); in sev_read_init_ex_file()
322 struct sev_device *sev = psp_master->sev_data; in sev_write_init_ex_file()
336 dev_err(sev->dev, in sev_write_init_ex_file()
347 dev_err(sev->dev, in sev_write_init_ex_file()
350 return -EIO; in sev_write_init_ex_file()
353 dev_dbg(sev->dev, "SEV: write successful to NV file\n"); in sev_write_init_ex_file()
367 * non-platform commands do. Only INIT(_EX), PLATFORM_RESET, PEK_GEN, in sev_write_init_ex_file_if_required()
415 snp_leak_pages(__phys_to_pfn(paddr), npages - i); in snp_reclaim_pages()
450 if (!psp_master || !psp_master->sev_data) in __snp_alloc_firmware_pages()
457 /* If SEV-SNP is initialized then add the page in RMP table. */ in __snp_alloc_firmware_pages()
458 sev = psp_master->sev_data; in __snp_alloc_firmware_pages()
459 if (!sev->snp_initialized) in __snp_alloc_firmware_pages()
481 struct sev_device *sev = psp_master->sev_data; in __snp_free_firmware_pages()
488 if (sev->snp_initialized && in __snp_free_firmware_pages()
516 * struct cmd_buf_desc - descriptors for managing legacy SEV command address
524 * be NULL if this descriptor is only an end-of-list indicator.
532 * @guest_owned: true if the address corresponds to guest-owned pages, in which
544 * turn need to be transitioned to/from firmware-owned before/after
547 * Additionally, in cases where those pages are not guest-owned, a bounce
560 desc_list[0].paddr_ptr = &data->pdh_cert_address; in snp_populate_cmd_buf_desc_list()
561 desc_list[0].len = data->pdh_cert_len; in snp_populate_cmd_buf_desc_list()
562 desc_list[1].paddr_ptr = &data->cert_chain_address; in snp_populate_cmd_buf_desc_list()
563 desc_list[1].len = data->cert_chain_len; in snp_populate_cmd_buf_desc_list()
569 desc_list[0].paddr_ptr = &data->address; in snp_populate_cmd_buf_desc_list()
570 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
576 desc_list[0].paddr_ptr = &data->address; in snp_populate_cmd_buf_desc_list()
577 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
583 desc_list[0].paddr_ptr = &data->address; in snp_populate_cmd_buf_desc_list()
584 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
591 desc_list[0].paddr_ptr = &data->address; in snp_populate_cmd_buf_desc_list()
592 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
599 desc_list[0].paddr_ptr = &data->address; in snp_populate_cmd_buf_desc_list()
600 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
606 desc_list[0].paddr_ptr = &data->guest_address; in snp_populate_cmd_buf_desc_list()
607 desc_list[0].len = data->guest_len; in snp_populate_cmd_buf_desc_list()
614 desc_list[0].paddr_ptr = &data->dst_addr; in snp_populate_cmd_buf_desc_list()
615 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
622 desc_list[0].paddr_ptr = &data->dst_addr; in snp_populate_cmd_buf_desc_list()
623 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
630 desc_list[0].paddr_ptr = &data->address; in snp_populate_cmd_buf_desc_list()
631 desc_list[0].len = data->len; in snp_populate_cmd_buf_desc_list()
637 desc_list[0].paddr_ptr = &data->session_address; in snp_populate_cmd_buf_desc_list()
638 desc_list[0].len = data->session_len; in snp_populate_cmd_buf_desc_list()
644 desc_list[0].paddr_ptr = &data->hdr_address; in snp_populate_cmd_buf_desc_list()
645 desc_list[0].len = data->hdr_len; in snp_populate_cmd_buf_desc_list()
646 desc_list[1].paddr_ptr = &data->trans_address; in snp_populate_cmd_buf_desc_list()
647 desc_list[1].len = data->trans_len; in snp_populate_cmd_buf_desc_list()
653 desc_list[0].paddr_ptr = &data->hdr_address; in snp_populate_cmd_buf_desc_list()
654 desc_list[0].len = data->hdr_len; in snp_populate_cmd_buf_desc_list()
655 desc_list[1].paddr_ptr = &data->trans_address; in snp_populate_cmd_buf_desc_list()
656 desc_list[1].len = data->trans_len; in snp_populate_cmd_buf_desc_list()
662 desc_list[0].paddr_ptr = &data->guest_address; in snp_populate_cmd_buf_desc_list()
663 desc_list[0].len = data->guest_len; in snp_populate_cmd_buf_desc_list()
670 desc_list[0].paddr_ptr = &data->guest_address; in snp_populate_cmd_buf_desc_list()
671 desc_list[0].len = data->guest_len; in snp_populate_cmd_buf_desc_list()
684 if (!desc->len) in snp_map_cmd_buf_desc()
688 if (!desc->guest_owned) { in snp_map_cmd_buf_desc()
691 page = alloc_pages(GFP_KERNEL_ACCOUNT, get_order(desc->len)); in snp_map_cmd_buf_desc()
694 return -ENOMEM; in snp_map_cmd_buf_desc()
697 desc->paddr_orig = *desc->paddr_ptr; in snp_map_cmd_buf_desc()
698 *desc->paddr_ptr = __psp_pa(page_to_virt(page)); in snp_map_cmd_buf_desc()
701 npages = PAGE_ALIGN(desc->len) >> PAGE_SHIFT; in snp_map_cmd_buf_desc()
703 /* Transition the buffer to firmware-owned. */ in snp_map_cmd_buf_desc()
704 if (rmp_mark_pages_firmware(*desc->paddr_ptr, npages, true)) { in snp_map_cmd_buf_desc()
705 pr_warn("Error moving pages to firmware-owned state for SEV legacy command.\n"); in snp_map_cmd_buf_desc()
706 return -EFAULT; in snp_map_cmd_buf_desc()
716 if (!desc->len) in snp_unmap_cmd_buf_desc()
719 npages = PAGE_ALIGN(desc->len) >> PAGE_SHIFT; in snp_unmap_cmd_buf_desc()
721 /* Transition the buffers back to hypervisor-owned. */ in snp_unmap_cmd_buf_desc()
722 if (snp_reclaim_pages(*desc->paddr_ptr, npages, true)) { in snp_unmap_cmd_buf_desc()
723 pr_warn("Failed to reclaim firmware-owned pages while issuing SEV legacy command.\n"); in snp_unmap_cmd_buf_desc()
724 return -EFAULT; in snp_unmap_cmd_buf_desc()
728 if (!desc->guest_owned) { in snp_unmap_cmd_buf_desc()
729 void *bounce_buf = __va(__sme_clr(*desc->paddr_ptr)); in snp_unmap_cmd_buf_desc()
730 void *dst_buf = __va(__sme_clr(desc->paddr_orig)); in snp_unmap_cmd_buf_desc()
732 memcpy(dst_buf, bounce_buf, desc->len); in snp_unmap_cmd_buf_desc()
733 __free_pages(virt_to_page(bounce_buf), get_order(desc->len)); in snp_unmap_cmd_buf_desc()
736 *desc->paddr_ptr = desc->paddr_orig; in snp_unmap_cmd_buf_desc()
751 if (!desc->paddr_ptr) in snp_map_cmd_buf_desc_list()
761 for (i--; i >= 0; i--) in snp_map_cmd_buf_desc_list()
764 return -EFAULT; in snp_map_cmd_buf_desc_list()
774 if (!desc->paddr_ptr) in snp_unmap_cmd_buf_desc_list()
778 ret = -EFAULT; in snp_unmap_cmd_buf_desc_list()
808 struct sev_device *sev = psp_master->sev_data; in snp_legacy_handling_needed()
810 return cmd < SEV_CMD_SNP_INIT && sev->snp_initialized; in snp_legacy_handling_needed()
819 return -EFAULT; in snp_prep_cmd_buf()
823 * the firmware-owned state. in snp_prep_cmd_buf()
827 return -EFAULT; in snp_prep_cmd_buf()
840 * into the hypervisor-owned state. in snp_reclaim_cmd_buf()
844 return -EFAULT; in snp_reclaim_cmd_buf()
861 if (!psp || !psp->sev_data) in __sev_do_cmd_locked()
862 return -ENODEV; in __sev_do_cmd_locked()
865 return -EBUSY; in __sev_do_cmd_locked()
867 sev = psp->sev_data; in __sev_do_cmd_locked()
871 return -EINVAL; in __sev_do_cmd_locked()
887 if (!sev->cmd_buf_active) { in __sev_do_cmd_locked()
888 cmd_buf = sev->cmd_buf; in __sev_do_cmd_locked()
889 sev->cmd_buf_active = true; in __sev_do_cmd_locked()
890 } else if (!sev->cmd_buf_backup_active) { in __sev_do_cmd_locked()
891 cmd_buf = sev->cmd_buf_backup; in __sev_do_cmd_locked()
892 sev->cmd_buf_backup_active = true; in __sev_do_cmd_locked()
894 dev_err(sev->dev, in __sev_do_cmd_locked()
896 return -EBUSY; in __sev_do_cmd_locked()
902 * The behavior of the SEV-legacy commands is altered when the in __sev_do_cmd_locked()
907 dev_err(sev->dev, in __sev_do_cmd_locked()
913 cmd_buf = sev->cmd_buf; in __sev_do_cmd_locked()
920 dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n", in __sev_do_cmd_locked()
926 iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg); in __sev_do_cmd_locked()
927 iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg); in __sev_do_cmd_locked()
929 sev->int_rcvd = 0; in __sev_do_cmd_locked()
934 * If invoked during panic handling, local interrupts are disabled so in __sev_do_cmd_locked()
943 iowrite32(reg, sev->io_regs + sev->vdata->cmdresp_reg); in __sev_do_cmd_locked()
951 dev_err(sev->dev, "sev command %#x timed out, disabling PSP\n", cmd); in __sev_do_cmd_locked()
963 dev_dbg(sev->dev, "sev command %#x failed (%#010lx)\n", in __sev_do_cmd_locked()
971 cmdbuff_hi = ioread32(sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg); in __sev_do_cmd_locked()
972 cmdbuff_lo = ioread32(sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg); in __sev_do_cmd_locked()
974 dev_dbg(sev->dev, "Additional error information reported in cmdbuff:"); in __sev_do_cmd_locked()
975 dev_dbg(sev->dev, " cmdbuff hi: %#010x\n", cmdbuff_hi); in __sev_do_cmd_locked()
976 dev_dbg(sev->dev, " cmdbuff lo: %#010x\n", cmdbuff_lo); in __sev_do_cmd_locked()
978 ret = -EIO; in __sev_do_cmd_locked()
994 dev_err(sev->dev, in __sev_do_cmd_locked()
1002 if (sev->cmd_buf_backup_active) in __sev_do_cmd_locked()
1003 sev->cmd_buf_backup_active = false; in __sev_do_cmd_locked()
1005 sev->cmd_buf_active = false; in __sev_do_cmd_locked()
1008 return -EFAULT; in __sev_do_cmd_locked()
1092 entry->page_state = page_state; in snp_hv_fixed_pages_state_update()
1121 if (psp_master->sev_data && in snp_alloc_hv_fixed_pages()
1122 ((struct sev_device *)psp_master->sev_data)->snp_initialized) in snp_alloc_hv_fixed_pages()
1125 /* Re-use freed pages that match the request */ in snp_alloc_hv_fixed_pages()
1128 if (entry->order == order && entry->free) { in snp_alloc_hv_fixed_pages()
1129 entry->free = false; in snp_alloc_hv_fixed_pages()
1130 memset(page_address(entry->page), 0, in snp_alloc_hv_fixed_pages()
1131 (1 << entry->order) * PAGE_SIZE); in snp_alloc_hv_fixed_pages()
1132 return entry->page; in snp_alloc_hv_fixed_pages()
1146 entry->page = page; in snp_alloc_hv_fixed_pages()
1147 entry->order = order; in snp_alloc_hv_fixed_pages()
1148 list_add_tail(&entry->list, &snp_hv_fixed_pages); in snp_alloc_hv_fixed_pages()
1168 if (entry->page != page) in snp_free_hv_fixed_pages()
1175 * Mark the pages as free internally to allow possible re-use. in snp_free_hv_fixed_pages()
1177 if (entry->page_state == HV_FIXED) { in snp_free_hv_fixed_pages()
1178 entry->free = true; in snp_free_hv_fixed_pages()
1180 __free_pages(page, entry->order); in snp_free_hv_fixed_pages()
1181 list_del(&entry->list); in snp_free_hv_fixed_pages()
1200 range_list->num_elements; in snp_add_hv_fixed_pages()
1204 * do not exceed the page-sized argument buffer. in snp_add_hv_fixed_pages()
1207 dev_warn(sev->dev, "Additional HV_Fixed pages cannot be accommodated, omitting\n"); in snp_add_hv_fixed_pages()
1211 range = &range_list->ranges[range_list->num_elements]; in snp_add_hv_fixed_pages()
1213 range->base = page_to_pfn(entry->page) << PAGE_SHIFT; in snp_add_hv_fixed_pages()
1214 range->page_count = 1 << entry->order; in snp_add_hv_fixed_pages()
1217 range_list->num_elements = num_elements; in snp_add_hv_fixed_pages()
1231 if (entry->free && entry->page_state != HV_FIXED) in snp_leak_hv_fixed_pages()
1232 __free_pages(entry->page, entry->order); in snp_leak_hv_fixed_pages()
1234 __snp_leak_pages(page_to_pfn(entry->page), in snp_leak_hv_fixed_pages()
1235 1 << entry->order, false); in snp_leak_hv_fixed_pages()
1237 list_del(&entry->list); in snp_leak_hv_fixed_pages()
1247 if (!psp || !psp->sev_data) in sev_is_snp_ciphertext_hiding_supported()
1250 sev = psp->sev_data; in sev_is_snp_ciphertext_hiding_supported()
1258 return ((sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED) && in sev_is_snp_ciphertext_hiding_supported()
1259 sev->snp_plat_status.ciphertext_hiding_cap); in sev_is_snp_ciphertext_hiding_supported()
1275 if (sev->snp_initialized) in snp_get_platform_data()
1276 return -EINVAL; in snp_get_platform_data()
1278 buf.address = __psp_pa(&sev->snp_plat_status); in snp_get_platform_data()
1281 dev_err(sev->dev, "SNP PLATFORM_STATUS command failed, ret = %d, error = %#x\n", in snp_get_platform_data()
1286 sev->api_major = sev->snp_plat_status.api_major; in snp_get_platform_data()
1287 sev->api_minor = sev->snp_plat_status.api_minor; in snp_get_platform_data()
1288 sev->build = sev->snp_plat_status.build_id; in snp_get_platform_data()
1293 * sub-function 0. in snp_get_platform_data()
1295 if (!sev->snp_plat_status.feature_info) in snp_get_platform_data()
1300 * command to ensure structure is 8-byte aligned, and does not in snp_get_platform_data()
1305 return -ENOMEM; in snp_get_platform_data()
1314 sev->snp_feat_info_0 = *feat_info; in snp_get_platform_data()
1316 dev_err(sev->dev, "SNP FEATURE_INFO command failed, ret = %d, error = %#x\n", in snp_get_platform_data()
1327 struct sev_data_range *range = &range_list->ranges[range_list->num_elements]; in snp_filter_reserved_mem_regions()
1332 * do not exceed the page-sized argument buffer. in snp_filter_reserved_mem_regions()
1334 if ((range_list->num_elements * sizeof(struct sev_data_range) + in snp_filter_reserved_mem_regions()
1336 return -E2BIG; in snp_filter_reserved_mem_regions()
1338 switch (rs->desc) { in snp_filter_reserved_mem_regions()
1342 range->base = rs->start & PAGE_MASK; in snp_filter_reserved_mem_regions()
1343 size = PAGE_ALIGN((rs->end + 1) - rs->start); in snp_filter_reserved_mem_regions()
1344 range->page_count = size >> PAGE_SHIFT; in snp_filter_reserved_mem_regions()
1345 range_list->num_elements++; in snp_filter_reserved_mem_regions()
1364 return -ENODEV; in __sev_snp_init_locked()
1366 sev = psp->sev_data; in __sev_snp_init_locked()
1368 if (sev->snp_initialized) in __sev_snp_init_locked()
1372 dev_dbg(sev->dev, "SEV-SNP support requires firmware version >= %d:%d\n", in __sev_snp_init_locked()
1374 return -EOPNOTSUPP; in __sev_snp_init_locked()
1381 * of system physical address ranges to convert into HV-fixed page in __sev_snp_init_locked()
1390 bool tio_supp = !!(sev->snp_feat_info_0.ebx & SNP_SEV_TIO_SUPPORTED); in __sev_snp_init_locked()
1399 dev_err(sev->dev, in __sev_snp_init_locked()
1401 return -ENOMEM; in __sev_snp_init_locked()
1406 * to be setup as HV-fixed pages. in __sev_snp_init_locked()
1411 dev_err(sev->dev, in __sev_snp_init_locked()
1417 * Add HV_Fixed pages from other PSP sub-devices, such as SFS to the in __sev_snp_init_locked()
1437 * SEV ioctl can inadvertently shut down SNP and SEV-TIO causing in __sev_snp_init_locked()
1441 dev_warn(sev->dev, "SEV-TIO as incompatible with psp_init_on_probe=0\n"); in __sev_snp_init_locked()
1454 * - WBINVD on all running CPUs in __sev_snp_init_locked()
1455 * - SEV_CMD_SNP_INIT[_EX] firmware command in __sev_snp_init_locked()
1456 * - WBINVD on all running CPUs in __sev_snp_init_locked()
1457 * - SEV_CMD_SNP_DF_FLUSH firmware command in __sev_snp_init_locked()
1463 dev_err(sev->dev, "SEV-SNP: %s failed rc %d, error %#x\n", in __sev_snp_init_locked()
1473 dev_err(sev->dev, "SEV-SNP: SNP_DF_FLUSH failed rc %d, error %#x\n", in __sev_snp_init_locked()
1479 sev->snp_initialized = true; in __sev_snp_init_locked()
1480 dev_dbg(sev->dev, "SEV-SNP firmware initialized, SEV-TIO is %s\n", in __sev_snp_init_locked()
1483 dev_info(sev->dev, "SEV-SNP API:%d.%d build:%d\n", sev->api_major, in __sev_snp_init_locked()
1484 sev->api_minor, sev->build); in __sev_snp_init_locked()
1516 /* Obtain the TMR memory area for SEV-ES use */ in __sev_platform_init_handle_tmr()
1520 if (!sev->snp_initialized) in __sev_platform_init_handle_tmr()
1523 dev_warn(sev->dev, "SEV: TMR allocation failed, SEV-ES support unavailable\n"); in __sev_platform_init_handle_tmr()
1545 dev_err(sev->dev, "SEV: INIT_EX NV memory allocation failed\n"); in __sev_platform_init_handle_init_ex_path()
1546 return -ENOMEM; in __sev_platform_init_handle_init_ex_path()
1555 /* If SEV-SNP is initialized, transition to firmware page. */ in __sev_platform_init_handle_init_ex_path()
1556 if (sev->snp_initialized) { in __sev_platform_init_handle_init_ex_path()
1561 dev_err(sev->dev, "SEV: INIT_EX NV memory page state change failed.\n"); in __sev_platform_init_handle_init_ex_path()
1562 return -ENOMEM; in __sev_platform_init_handle_init_ex_path()
1576 if (!psp_master || !psp_master->sev_data) in __sev_platform_init_locked()
1577 return -ENODEV; in __sev_platform_init_locked()
1579 sev = psp_master->sev_data; in __sev_platform_init_locked()
1581 if (sev->sev_plat_status.state == SEV_STATE_INIT) in __sev_platform_init_locked()
1599 dev_err(sev->dev, in __sev_platform_init_locked()
1608 dev_err(sev->dev, "SEV: %s failed %#x, rc %d\n", in __sev_platform_init_locked()
1613 sev->sev_plat_status.state = SEV_STATE_INIT; in __sev_platform_init_locked()
1619 dev_err(sev->dev, "SEV: DF_FLUSH failed %#x, rc %d\n", in __sev_platform_init_locked()
1624 dev_dbg(sev->dev, "SEV firmware initialized\n"); in __sev_platform_init_locked()
1626 dev_info(sev->dev, "SEV API:%d.%d build:%d\n", sev->api_major, in __sev_platform_init_locked()
1627 sev->api_minor, sev->build); in __sev_platform_init_locked()
1637 if (!psp_master || !psp_master->sev_data) in _sev_platform_init_locked()
1638 return -ENODEV; in _sev_platform_init_locked()
1649 sev = psp_master->sev_data; in _sev_platform_init_locked()
1651 if (sev->sev_plat_status.state == SEV_STATE_INIT) in _sev_platform_init_locked()
1654 rc = __sev_snp_init_locked(&args->error, args->max_snp_asid); in _sev_platform_init_locked()
1655 if (rc && rc != -ENODEV) in _sev_platform_init_locked()
1658 /* Defer legacy SEV/SEV-ES support if allowed by caller/module. */ in _sev_platform_init_locked()
1659 if (args->probe && !psp_init_on_probe) in _sev_platform_init_locked()
1662 return __sev_platform_init_locked(&args->error); in _sev_platform_init_locked()
1683 if (!psp || !psp->sev_data) in __sev_platform_shutdown_locked()
1686 sev = psp->sev_data; in __sev_platform_shutdown_locked()
1688 if (sev->sev_plat_status.state == SEV_STATE_UNINIT) in __sev_platform_shutdown_locked()
1693 dev_err(sev->dev, "SEV: failed to SHUTDOWN error %#x, rc %d\n", in __sev_platform_shutdown_locked()
1698 sev->sev_plat_status.state = SEV_STATE_UNINIT; in __sev_platform_shutdown_locked()
1699 dev_dbg(sev->dev, "SEV firmware shutdown\n"); in __sev_platform_shutdown_locked()
1724 argp->error = SEV_RET_INVALID_PLATFORM_STATE; in sev_move_to_init_state()
1739 argp->error = SEV_RET_INVALID_PLATFORM_STATE; in snp_move_to_init_state()
1753 return -EPERM; in sev_ioctl_do_reset()
1761 * SHUTDOWN command do INIT -> UNINIT before issuing the FACTORY_RESET. in sev_ioctl_do_reset()
1764 rc = sev_get_platform_state(&state, &argp->error); in sev_ioctl_do_reset()
1769 return -EBUSY; in sev_ioctl_do_reset()
1772 rc = __sev_platform_shutdown_locked(&argp->error); in sev_ioctl_do_reset()
1777 return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, NULL, &argp->error); in sev_ioctl_do_reset()
1787 ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error); in sev_ioctl_do_platform_status()
1791 if (copy_to_user((void __user *)argp->data, &data, sizeof(data))) in sev_ioctl_do_platform_status()
1792 ret = -EFAULT; in sev_ioctl_do_platform_status()
1799 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_pek_pdh_gen()
1804 return -EPERM; in sev_ioctl_do_pek_pdh_gen()
1806 if (sev->sev_plat_status.state == SEV_STATE_UNINIT) { in sev_ioctl_do_pek_pdh_gen()
1812 rc = __sev_do_cmd_locked(cmd, NULL, &argp->error); in sev_ioctl_do_pek_pdh_gen()
1822 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_pek_csr()
1831 return -EPERM; in sev_ioctl_do_pek_csr()
1833 if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) in sev_ioctl_do_pek_csr()
1834 return -EFAULT; in sev_ioctl_do_pek_csr()
1845 return -EFAULT; in sev_ioctl_do_pek_csr()
1849 return -ENOMEM; in sev_ioctl_do_pek_csr()
1855 if (sev->sev_plat_status.state == SEV_STATE_UNINIT) { in sev_ioctl_do_pek_csr()
1861 ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, &data, &argp->error); in sev_ioctl_do_pek_csr()
1869 if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { in sev_ioctl_do_pek_csr()
1870 ret = -EFAULT; in sev_ioctl_do_pek_csr()
1874 if (ret || WARN_ON_ONCE(argp->error)) in sev_ioctl_do_pek_csr()
1879 ret = -EFAULT; in sev_ioctl_do_pek_csr()
1893 return ERR_PTR(-EINVAL); in psp_copy_user_blob()
1897 return ERR_PTR(-EINVAL); in psp_copy_user_blob()
1905 struct sev_device *sev = psp_master->sev_data; in sev_get_api_version()
1921 dev_err(sev->dev, in sev_get_api_version()
1927 sev->sev_plat_status = status; in sev_get_api_version()
1929 sev->api_major = status.api_major; in sev_get_api_version()
1930 sev->api_minor = status.api_minor; in sev_get_api_version()
1931 sev->build = status.build; in sev_get_api_version()
1957 * Family 17h Model 00h -- Family 17h Model 0Fh in sev_get_firmware()
1961 * Fall-back to using generic name: sev.fw in sev_get_firmware()
1968 return -ENOENT; in sev_get_firmware()
1982 return -1; in sev_update_firmware()
1985 if (sev_get_firmware(dev, &firmware) == -ENOENT) { in sev_update_firmware()
1987 return -1; in sev_update_firmware()
1990 order = get_order(firmware->size); in sev_update_firmware()
1993 ret = -1; in sev_update_firmware()
2002 memcpy(fw_blob, firmware->data, firmware->size); in sev_update_firmware()
2005 data.len = firmware->size; in sev_update_firmware()
2027 static int __sev_snp_shutdown_locked(int *error, bool panic) in __sev_snp_shutdown_locked() argument
2034 if (!psp || !psp->sev_data) in __sev_snp_shutdown_locked()
2037 sev = psp->sev_data; in __sev_snp_shutdown_locked()
2039 if (!sev->snp_initialized) in __sev_snp_shutdown_locked()
2045 if (sev->snp_feat_info_0.ecx & SNP_X86_SHUTDOWN_SUPPORTED) in __sev_snp_shutdown_locked()
2049 * If invoked during panic handling, local interrupts are disabled in __sev_snp_shutdown_locked()
2054 if (!panic) in __sev_snp_shutdown_locked()
2066 dev_err(sev->dev, "SEV-SNP DF_FLUSH failed, ret = %d, error = %#x\n", in __sev_snp_shutdown_locked()
2075 dev_err(sev->dev, "SEV-SNP firmware shutdown failed, rc %d, error %#x\n", in __sev_snp_shutdown_locked()
2081 if (!panic) in __sev_snp_shutdown_locked()
2100 dev_err(sev->dev, "SNP IOMMU shutdown failed\n"); in __sev_snp_shutdown_locked()
2106 sev->snp_initialized = false; in __sev_snp_shutdown_locked()
2107 dev_dbg(sev->dev, "SEV-SNP firmware shutdown\n"); in __sev_snp_shutdown_locked()
2111 * itself during panic as the panic notifier is called with RCU read in __sev_snp_shutdown_locked()
2114 if (!panic) in __sev_snp_shutdown_locked()
2126 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_pek_import()
2134 return -EPERM; in sev_ioctl_do_pek_import()
2136 if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) in sev_ioctl_do_pek_import()
2137 return -EFAULT; in sev_ioctl_do_pek_import()
2159 if (sev->sev_plat_status.state != SEV_STATE_INIT) { in sev_ioctl_do_pek_import()
2165 ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error); in sev_ioctl_do_pek_import()
2187 return -ENOTSUPP; in sev_ioctl_do_get_id2()
2189 if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) in sev_ioctl_do_get_id2()
2190 return -EFAULT; in sev_ioctl_do_get_id2()
2204 return -ENOMEM; in sev_ioctl_do_get_id2()
2213 ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, &data, &argp->error); in sev_ioctl_do_get_id2()
2221 if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { in sev_ioctl_do_get_id2()
2222 ret = -EFAULT; in sev_ioctl_do_get_id2()
2226 if (ret || WARN_ON_ONCE(argp->error)) in sev_ioctl_do_get_id2()
2231 ret = -EFAULT; in sev_ioctl_do_get_id2()
2251 return -ENOTSUPP; in sev_ioctl_do_get_id()
2254 * 8-byte aligned. Memory allocated should be enough to in sev_ioctl_do_get_id()
2263 return -ENOMEM; in sev_ioctl_do_get_id()
2268 data->address = __psp_pa(id_blob); in sev_ioctl_do_get_id()
2269 data->len = user_size; in sev_ioctl_do_get_id()
2271 ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error); in sev_ioctl_do_get_id()
2273 if (copy_to_user((void __user *)argp->data, id_blob, data->len)) in sev_ioctl_do_get_id()
2274 ret = -EFAULT; in sev_ioctl_do_get_id()
2284 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_pdh_export()
2293 if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) in sev_ioctl_do_pdh_export()
2294 return -EFAULT; in sev_ioctl_do_pdh_export()
2309 return -EFAULT; in sev_ioctl_do_pdh_export()
2313 return -EFAULT; in sev_ioctl_do_pdh_export()
2317 return -ENOMEM; in sev_ioctl_do_pdh_export()
2324 ret = -ENOMEM; in sev_ioctl_do_pdh_export()
2333 if (sev->sev_plat_status.state != SEV_STATE_INIT) { in sev_ioctl_do_pdh_export()
2335 ret = -EPERM; in sev_ioctl_do_pdh_export()
2343 ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error); in sev_ioctl_do_pdh_export()
2352 if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { in sev_ioctl_do_pdh_export()
2353 ret = -EFAULT; in sev_ioctl_do_pdh_export()
2357 if (ret || WARN_ON_ONCE(argp->error)) in sev_ioctl_do_pdh_export()
2363 ret = -EFAULT; in sev_ioctl_do_pdh_export()
2371 ret = -EFAULT; in sev_ioctl_do_pdh_export()
2386 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_snp_platform_status()
2392 if (!argp->data) in sev_ioctl_do_snp_platform_status()
2393 return -EINVAL; in sev_ioctl_do_snp_platform_status()
2397 return -ENOMEM; in sev_ioctl_do_snp_platform_status()
2403 * when SNP has been initialized, the status page must be firmware-owned. in sev_ioctl_do_snp_platform_status()
2405 if (sev->snp_initialized) { in sev_ioctl_do_snp_platform_status()
2411 ret = -EFAULT; in sev_ioctl_do_snp_platform_status()
2417 ret = __sev_do_cmd_locked(SEV_CMD_SNP_PLATFORM_STATUS, &buf, &argp->error); in sev_ioctl_do_snp_platform_status()
2419 if (sev->snp_initialized) { in sev_ioctl_do_snp_platform_status()
2423 * transition either case back to Hypervisor-owned state. in sev_ioctl_do_snp_platform_status()
2426 return -EFAULT; in sev_ioctl_do_snp_platform_status()
2432 if (copy_to_user((void __user *)argp->data, data, in sev_ioctl_do_snp_platform_status()
2434 ret = -EFAULT; in sev_ioctl_do_snp_platform_status()
2443 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_snp_commit()
2448 if (!sev->snp_initialized) { in sev_ioctl_do_snp_commit()
2456 ret = __sev_do_cmd_locked(SEV_CMD_SNP_COMMIT, &buf, &argp->error); in sev_ioctl_do_snp_commit()
2466 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_snp_set_config()
2471 if (!argp->data) in sev_ioctl_do_snp_set_config()
2472 return -EINVAL; in sev_ioctl_do_snp_set_config()
2475 return -EPERM; in sev_ioctl_do_snp_set_config()
2477 if (copy_from_user(&config, (void __user *)argp->data, sizeof(config))) in sev_ioctl_do_snp_set_config()
2478 return -EFAULT; in sev_ioctl_do_snp_set_config()
2480 if (!sev->snp_initialized) { in sev_ioctl_do_snp_set_config()
2486 ret = __sev_do_cmd_locked(SEV_CMD_SNP_CONFIG, &config, &argp->error); in sev_ioctl_do_snp_set_config()
2496 struct sev_device *sev = psp_master->sev_data; in sev_ioctl_do_snp_vlek_load()
2502 if (!argp->data) in sev_ioctl_do_snp_vlek_load()
2503 return -EINVAL; in sev_ioctl_do_snp_vlek_load()
2506 return -EPERM; in sev_ioctl_do_snp_vlek_load()
2508 if (copy_from_user(&input, u64_to_user_ptr(argp->data), sizeof(input))) in sev_ioctl_do_snp_vlek_load()
2509 return -EFAULT; in sev_ioctl_do_snp_vlek_load()
2512 return -EINVAL; in sev_ioctl_do_snp_vlek_load()
2521 if (!sev->snp_initialized) { in sev_ioctl_do_snp_vlek_load()
2527 ret = __sev_do_cmd_locked(SEV_CMD_SNP_VLEK_LOAD, &input, &argp->error); in sev_ioctl_do_snp_vlek_load()
2542 int ret = -EFAULT; in sev_ioctl()
2543 bool writable = file->f_mode & FMODE_WRITE; in sev_ioctl()
2545 if (!psp_master || !psp_master->sev_data) in sev_ioctl()
2546 return -ENODEV; in sev_ioctl()
2549 return -EINVAL; in sev_ioctl()
2552 return -EFAULT; in sev_ioctl()
2555 return -EINVAL; in sev_ioctl()
2602 ret = -EINVAL; in sev_ioctl()
2607 ret = -EFAULT; in sev_ioctl()
2651 misc_deregister(&misc_dev->misc); in sev_exit()
2658 struct device *dev = sev->dev; in sev_misc_init()
2673 return -ENOMEM; in sev_misc_init()
2675 misc = &misc_dev->misc; in sev_misc_init()
2676 misc->minor = MISC_DYNAMIC_MINOR; in sev_misc_init()
2677 misc->name = DEVICE_NAME; in sev_misc_init()
2678 misc->fops = &sev_fops; in sev_misc_init()
2684 kref_init(&misc_dev->refcount); in sev_misc_init()
2686 kref_get(&misc_dev->refcount); in sev_misc_init()
2689 init_waitqueue_head(&sev->int_queue); in sev_misc_init()
2690 sev->misc = misc_dev; in sev_misc_init()
2698 struct device *dev = psp->dev; in sev_dev_init()
2700 int ret = -ENOMEM; in sev_dev_init()
2711 sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 1); in sev_dev_init()
2712 if (!sev->cmd_buf) in sev_dev_init()
2715 sev->cmd_buf_backup = (uint8_t *)sev->cmd_buf + PAGE_SIZE; in sev_dev_init()
2717 psp->sev_data = sev; in sev_dev_init()
2719 sev->dev = dev; in sev_dev_init()
2720 sev->psp = psp; in sev_dev_init()
2722 sev->io_regs = psp->io_regs; in sev_dev_init()
2724 sev->vdata = (struct sev_vdata *)psp->vdata->sev; in sev_dev_init()
2725 if (!sev->vdata) { in sev_dev_init()
2726 ret = -ENODEV; in sev_dev_init()
2744 devm_free_pages(dev, (unsigned long)sev->cmd_buf); in sev_dev_init()
2748 psp->sev_data = NULL; in sev_dev_init()
2755 static void __sev_firmware_shutdown(struct sev_device *sev, bool panic) in __sev_firmware_shutdown() argument
2765 * If invoked during panic handling, local interrupts are in __sev_firmware_shutdown()
2771 if (!panic) in __sev_firmware_shutdown()
2787 __sev_snp_shutdown_locked(&error, panic); in __sev_firmware_shutdown()
2796 if (sev->tio_status) in sev_firmware_shutdown()
2803 kfree(sev->tio_status); in sev_firmware_shutdown()
2804 sev->tio_status = NULL; in sev_firmware_shutdown()
2811 if (!psp_master || !psp_master->sev_data) in sev_platform_shutdown()
2814 sev_firmware_shutdown(psp_master->sev_data); in sev_platform_shutdown()
2827 if (!psp || !psp->sev_data) in sev_get_snp_policy_bits()
2830 sev = psp->sev_data; in sev_get_snp_policy_bits()
2834 if (sev->snp_plat_status.feature_info) { in sev_get_snp_policy_bits()
2835 if (sev->snp_feat_info_0.ecx & SNP_RAPL_DISABLE_SUPPORTED) in sev_get_snp_policy_bits()
2838 if (sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED) in sev_get_snp_policy_bits()
2841 if (sev->snp_feat_info_0.ecx & SNP_AES_256_XTS_POLICY_SUPPORTED) in sev_get_snp_policy_bits()
2844 if (sev->snp_feat_info_0.ecx & SNP_CXL_ALLOW_POLICY_SUPPORTED) in sev_get_snp_policy_bits()
2857 struct sev_device *sev = psp->sev_data; in sev_dev_destroy()
2864 if (sev->misc) in sev_dev_destroy()
2865 kref_put(&misc_dev->refcount, sev_exit); in sev_dev_destroy()
2873 struct sev_device *sev = psp_master->sev_data; in snp_shutdown_on_panic()
2879 * more confusion during a panic, just bail out here. in snp_shutdown_on_panic()
2892 if (!filep || filep->f_op != &sev_fops) in sev_issue_cmd_external_user()
2893 return -EBADF; in sev_issue_cmd_external_user()
2901 struct sev_device *sev = psp_master->sev_data; in sev_pci_init()
2912 api_major = sev->api_major; in sev_pci_init()
2913 api_minor = sev->api_minor; in sev_pci_init()
2914 build = sev->build; in sev_pci_init()
2916 if (sev_update_firmware(sev->dev) == 0) in sev_pci_init()
2919 if (api_major != sev->api_major || api_minor != sev->api_minor || in sev_pci_init()
2920 build != sev->build) in sev_pci_init()
2921 dev_info(sev->dev, "SEV firmware updated from %d.%d.%d to %d.%d.%d\n", in sev_pci_init()
2923 sev->api_major, sev->api_minor, sev->build); in sev_pci_init()
2930 psp_master->sev_data = NULL; in sev_pci_init()
2935 struct sev_device *sev = psp_master->sev_data; in sev_pci_exit()