Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'kvm-x86-ciphertext-6.18' of https://github.com/kvm-x86/linux into HEAD

KVM SEV-SNP CipherText Hiding support for 6.18

Add support for SEV-SNP's CipherText Hiding, an opt-in feature that prevents
unauthorized CPU accesses from reading the ciphertext of SNP guest private
memory, e.g. to attempt an offline attack. Instead of ciphertext, the CPU
will always read back all FFs when CipherText Hiding is enabled.

Add new module parameter to the KVM module to enable CipherText Hiding and
control the number of ASIDs that can be used for VMs with CipherText Hiding,
which is in effect the number of SNP VMs. When CipherText Hiding is enabled,
the shared SEV-ES/SEV-SNP ASID space is split into separate ranges for SEV-ES
and SEV-SNP guests, i.e. ASIDs that can be used for CipherText Hiding cannot
be used to run SEV-ES guests.

+249 -27
+21
Documentation/admin-guide/kernel-parameters.txt
··· 2957 2957 (enabled). Disable by KVM if hardware lacks support 2958 2958 for NPT. 2959 2959 2960 + kvm-amd.ciphertext_hiding_asids= 2961 + [KVM,AMD] Ciphertext hiding prevents disallowed accesses 2962 + to SNP private memory from reading ciphertext. Instead, 2963 + reads will see constant default values (0xff). 2964 + 2965 + If ciphertext hiding is enabled, the joint SEV-ES and 2966 + SEV-SNP ASID space is partitioned into separate SEV-ES 2967 + and SEV-SNP ASID ranges, with the SEV-SNP range being 2968 + [1..max_snp_asid] and the SEV-ES range being 2969 + (max_snp_asid..min_sev_asid), where min_sev_asid is 2970 + enumerated by CPUID.0x.8000_001F[EDX]. 2971 + 2972 + A non-zero value enables SEV-SNP ciphertext hiding and 2973 + adjusts the ASID ranges for SEV-ES and SEV-SNP guests. 2974 + KVM caps the number of SEV-SNP ASIDs at the maximum 2975 + possible value, e.g. specifying -1u will assign all 2976 + joint SEV-ES and SEV-SNP ASIDs to SEV-SNP. Note, 2977 + assigning all joint ASIDs to SEV-SNP, i.e. configuring 2978 + max_snp_asid == min_sev_asid-1, will effectively make 2979 + SEV-ES unusable. 2980 + 2960 2981 kvm-arm.mode= 2961 2982 [KVM,ARM,EARLY] Select one of KVM/arm64's modes of 2962 2983 operation.
+58 -10
arch/x86/kvm/svm/sev.c
··· 58 58 module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444); 59 59 static u64 sev_supported_vmsa_features; 60 60 61 + static unsigned int nr_ciphertext_hiding_asids; 62 + module_param_named(ciphertext_hiding_asids, nr_ciphertext_hiding_asids, uint, 0444); 63 + 61 64 #define AP_RESET_HOLD_NONE 0 62 65 #define AP_RESET_HOLD_NAE_EVENT 1 63 66 #define AP_RESET_HOLD_MSR_PROTO 2 ··· 87 84 static DEFINE_MUTEX(sev_bitmap_lock); 88 85 unsigned int max_sev_asid; 89 86 static unsigned int min_sev_asid; 87 + static unsigned int max_sev_es_asid; 88 + static unsigned int min_sev_es_asid; 89 + static unsigned int max_snp_asid; 90 + static unsigned int min_snp_asid; 90 91 static unsigned long sev_me_mask; 91 92 static unsigned int nr_asids; 92 93 static unsigned long *sev_asid_bitmap; ··· 187 180 misc_cg_uncharge(type, sev->misc_cg, 1); 188 181 } 189 182 190 - static int sev_asid_new(struct kvm_sev_info *sev) 183 + static int sev_asid_new(struct kvm_sev_info *sev, unsigned long vm_type) 191 184 { 192 185 /* 193 186 * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid. 194 187 * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1. 195 - * Note: min ASID can end up larger than the max if basic SEV support is 196 - * effectively disabled by disallowing use of ASIDs for SEV guests. 197 188 */ 198 - unsigned int min_asid = sev->es_active ? 1 : min_sev_asid; 199 - unsigned int max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid; 200 - unsigned int asid; 189 + unsigned int min_asid, max_asid, asid; 201 190 bool retry = true; 202 191 int ret; 203 192 193 + if (vm_type == KVM_X86_SNP_VM) { 194 + min_asid = min_snp_asid; 195 + max_asid = max_snp_asid; 196 + } else if (sev->es_active) { 197 + min_asid = min_sev_es_asid; 198 + max_asid = max_sev_es_asid; 199 + } else { 200 + min_asid = min_sev_asid; 201 + max_asid = max_sev_asid; 202 + } 203 + 204 + /* 205 + * The min ASID can end up larger than the max if basic SEV support is 206 + * effectively disabled by disallowing use of ASIDs for SEV guests. 207 + * Similarly for SEV-ES guests the min ASID can end up larger than the 208 + * max when ciphertext hiding is enabled, effectively disabling SEV-ES 209 + * support. 210 + */ 204 211 if (min_asid > max_asid) 205 212 return -ENOTTY; 206 213 ··· 475 454 if (snp_active) 476 455 sev->vmsa_features |= SVM_SEV_FEAT_SNP_ACTIVE; 477 456 478 - ret = sev_asid_new(sev); 457 + ret = sev_asid_new(sev, vm_type); 479 458 if (ret) 480 459 goto e_no_asid; 481 460 ··· 3079 3058 if (min_sev_asid == 1) 3080 3059 goto out; 3081 3060 3061 + min_sev_es_asid = min_snp_asid = 1; 3062 + max_sev_es_asid = max_snp_asid = min_sev_asid - 1; 3063 + 3082 3064 sev_es_asid_count = min_sev_asid - 1; 3083 3065 WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV_ES, sev_es_asid_count)); 3084 3066 sev_es_supported = true; ··· 3090 3066 out: 3091 3067 if (sev_enabled) { 3092 3068 init_args.probe = true; 3069 + 3070 + if (sev_is_snp_ciphertext_hiding_supported()) 3071 + init_args.max_snp_asid = min(nr_ciphertext_hiding_asids, 3072 + min_sev_asid - 1); 3073 + 3093 3074 if (sev_platform_init(&init_args)) 3094 3075 sev_supported = sev_es_supported = sev_snp_supported = false; 3095 3076 else if (sev_snp_supported) 3096 3077 sev_snp_supported = is_sev_snp_initialized(); 3078 + 3079 + if (sev_snp_supported) 3080 + nr_ciphertext_hiding_asids = init_args.max_snp_asid; 3081 + 3082 + /* 3083 + * If ciphertext hiding is enabled, the joint SEV-ES/SEV-SNP 3084 + * ASID range is partitioned into separate SEV-ES and SEV-SNP 3085 + * ASID ranges, with the SEV-SNP range being [1..max_snp_asid] 3086 + * and the SEV-ES range being (max_snp_asid..max_sev_es_asid]. 3087 + * Note, SEV-ES may effectively be disabled if all ASIDs from 3088 + * the joint range are assigned to SEV-SNP. 3089 + */ 3090 + if (nr_ciphertext_hiding_asids) { 3091 + max_snp_asid = nr_ciphertext_hiding_asids; 3092 + min_sev_es_asid = max_snp_asid + 1; 3093 + pr_info("SEV-SNP ciphertext hiding enabled\n"); 3094 + } 3097 3095 } 3098 3096 3099 3097 if (boot_cpu_has(X86_FEATURE_SEV)) ··· 3126 3080 min_sev_asid, max_sev_asid); 3127 3081 if (boot_cpu_has(X86_FEATURE_SEV_ES)) 3128 3082 pr_info("SEV-ES %s (ASIDs %u - %u)\n", 3129 - str_enabled_disabled(sev_es_supported), 3130 - min_sev_asid > 1 ? 1 : 0, min_sev_asid - 1); 3083 + sev_es_supported ? min_sev_es_asid <= max_sev_es_asid ? "enabled" : 3084 + "unusable" : 3085 + "disabled", 3086 + min_sev_es_asid, max_sev_es_asid); 3131 3087 if (boot_cpu_has(X86_FEATURE_SEV_SNP)) 3132 3088 pr_info("SEV-SNP %s (ASIDs %u - %u)\n", 3133 3089 str_enabled_disabled(sev_snp_supported), 3134 - min_sev_asid > 1 ? 1 : 0, min_sev_asid - 1); 3090 + min_snp_asid, max_snp_asid); 3135 3091 3136 3092 sev_enabled = sev_supported; 3137 3093 sev_es_enabled = sev_es_supported;
+114 -13
drivers/crypto/ccp/sev-dev.c
··· 233 233 case SEV_CMD_SNP_GUEST_REQUEST: return sizeof(struct sev_data_snp_guest_request); 234 234 case SEV_CMD_SNP_CONFIG: return sizeof(struct sev_user_data_snp_config); 235 235 case SEV_CMD_SNP_COMMIT: return sizeof(struct sev_data_snp_commit); 236 + case SEV_CMD_SNP_FEATURE_INFO: return sizeof(struct sev_data_snp_feature_info); 236 237 default: return 0; 237 238 } 238 239 ··· 1074 1073 wrmsrq(MSR_VM_HSAVE_PA, 0); 1075 1074 } 1076 1075 1076 + bool sev_is_snp_ciphertext_hiding_supported(void) 1077 + { 1078 + struct psp_device *psp = psp_master; 1079 + struct sev_device *sev; 1080 + 1081 + if (!psp || !psp->sev_data) 1082 + return false; 1083 + 1084 + sev = psp->sev_data; 1085 + 1086 + /* 1087 + * Feature information indicates if CipherTextHiding feature is 1088 + * supported by the SEV firmware and additionally platform status 1089 + * indicates if CipherTextHiding feature is enabled in the 1090 + * Platform BIOS. 1091 + */ 1092 + return ((sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED) && 1093 + sev->snp_plat_status.ciphertext_hiding_cap); 1094 + } 1095 + EXPORT_SYMBOL_GPL(sev_is_snp_ciphertext_hiding_supported); 1096 + 1097 + static int snp_get_platform_data(struct sev_device *sev, int *error) 1098 + { 1099 + struct sev_data_snp_feature_info snp_feat_info; 1100 + struct snp_feature_info *feat_info; 1101 + struct sev_data_snp_addr buf; 1102 + struct page *page; 1103 + int rc; 1104 + 1105 + /* 1106 + * This function is expected to be called before SNP is 1107 + * initialized. 1108 + */ 1109 + if (sev->snp_initialized) 1110 + return -EINVAL; 1111 + 1112 + buf.address = __psp_pa(&sev->snp_plat_status); 1113 + rc = sev_do_cmd(SEV_CMD_SNP_PLATFORM_STATUS, &buf, error); 1114 + if (rc) { 1115 + dev_err(sev->dev, "SNP PLATFORM_STATUS command failed, ret = %d, error = %#x\n", 1116 + rc, *error); 1117 + return rc; 1118 + } 1119 + 1120 + sev->api_major = sev->snp_plat_status.api_major; 1121 + sev->api_minor = sev->snp_plat_status.api_minor; 1122 + sev->build = sev->snp_plat_status.build_id; 1123 + 1124 + /* 1125 + * Do feature discovery of the currently loaded firmware, 1126 + * and cache feature information from CPUID 0x8000_0024, 1127 + * sub-function 0. 1128 + */ 1129 + if (!sev->snp_plat_status.feature_info) 1130 + return 0; 1131 + 1132 + /* 1133 + * Use dynamically allocated structure for the SNP_FEATURE_INFO 1134 + * command to ensure structure is 8-byte aligned, and does not 1135 + * cross a page boundary. 1136 + */ 1137 + page = alloc_page(GFP_KERNEL); 1138 + if (!page) 1139 + return -ENOMEM; 1140 + 1141 + feat_info = page_address(page); 1142 + snp_feat_info.length = sizeof(snp_feat_info); 1143 + snp_feat_info.ecx_in = 0; 1144 + snp_feat_info.feature_info_paddr = __psp_pa(feat_info); 1145 + 1146 + rc = sev_do_cmd(SEV_CMD_SNP_FEATURE_INFO, &snp_feat_info, error); 1147 + if (!rc) 1148 + sev->snp_feat_info_0 = *feat_info; 1149 + else 1150 + dev_err(sev->dev, "SNP FEATURE_INFO command failed, ret = %d, error = %#x\n", 1151 + rc, *error); 1152 + 1153 + __free_page(page); 1154 + 1155 + return rc; 1156 + } 1157 + 1077 1158 static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg) 1078 1159 { 1079 1160 struct sev_data_range_list *range_list = arg; ··· 1186 1103 return 0; 1187 1104 } 1188 1105 1189 - static int __sev_snp_init_locked(int *error) 1106 + static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid) 1190 1107 { 1191 1108 struct psp_device *psp = psp_master; 1192 1109 struct sev_data_snp_init_ex data; ··· 1247 1164 } 1248 1165 1249 1166 memset(&data, 0, sizeof(data)); 1167 + 1168 + if (max_snp_asid) { 1169 + data.ciphertext_hiding_en = 1; 1170 + data.max_snp_asid = max_snp_asid; 1171 + } 1172 + 1250 1173 data.init_rmp = 1; 1251 1174 data.list_paddr_en = 1; 1252 1175 data.list_paddr = __psp_pa(snp_range_list); ··· 1375 1286 1376 1287 sev = psp_master->sev_data; 1377 1288 1378 - if (sev->state == SEV_STATE_INIT) 1289 + if (sev->sev_plat_status.state == SEV_STATE_INIT) 1379 1290 return 0; 1380 1291 1381 1292 __sev_platform_init_handle_tmr(sev); ··· 1407 1318 return rc; 1408 1319 } 1409 1320 1410 - sev->state = SEV_STATE_INIT; 1321 + sev->sev_plat_status.state = SEV_STATE_INIT; 1411 1322 1412 1323 /* Prepare for first SEV guest launch after INIT */ 1413 1324 wbinvd_on_all_cpus(); ··· 1436 1347 1437 1348 sev = psp_master->sev_data; 1438 1349 1439 - if (sev->state == SEV_STATE_INIT) 1350 + if (sev->sev_plat_status.state == SEV_STATE_INIT) 1440 1351 return 0; 1441 1352 1442 - rc = __sev_snp_init_locked(&args->error); 1353 + rc = __sev_snp_init_locked(&args->error, args->max_snp_asid); 1443 1354 if (rc && rc != -ENODEV) 1444 1355 return rc; 1445 1356 ··· 1473 1384 1474 1385 sev = psp->sev_data; 1475 1386 1476 - if (sev->state == SEV_STATE_UNINIT) 1387 + if (sev->sev_plat_status.state == SEV_STATE_UNINIT) 1477 1388 return 0; 1478 1389 1479 1390 ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error); ··· 1483 1394 return ret; 1484 1395 } 1485 1396 1486 - sev->state = SEV_STATE_UNINIT; 1397 + sev->sev_plat_status.state = SEV_STATE_UNINIT; 1487 1398 dev_dbg(sev->dev, "SEV firmware shutdown\n"); 1488 1399 1489 1400 return ret; ··· 1522 1433 { 1523 1434 int error, rc; 1524 1435 1525 - rc = __sev_snp_init_locked(&error); 1436 + rc = __sev_snp_init_locked(&error, 0); 1526 1437 if (rc) { 1527 1438 argp->error = SEV_RET_INVALID_PLATFORM_STATE; 1528 1439 return rc; ··· 1591 1502 if (!writable) 1592 1503 return -EPERM; 1593 1504 1594 - if (sev->state == SEV_STATE_UNINIT) { 1505 + if (sev->sev_plat_status.state == SEV_STATE_UNINIT) { 1595 1506 rc = sev_move_to_init_state(argp, &shutdown_required); 1596 1507 if (rc) 1597 1508 return rc; ··· 1640 1551 data.len = input.length; 1641 1552 1642 1553 cmd: 1643 - if (sev->state == SEV_STATE_UNINIT) { 1554 + if (sev->sev_plat_status.state == SEV_STATE_UNINIT) { 1644 1555 ret = sev_move_to_init_state(argp, &shutdown_required); 1645 1556 if (ret) 1646 1557 goto e_free_blob; ··· 1688 1599 struct sev_user_data_status status; 1689 1600 int error = 0, ret; 1690 1601 1602 + /* 1603 + * Cache SNP platform status and SNP feature information 1604 + * if SNP is available. 1605 + */ 1606 + if (cc_platform_has(CC_ATTR_HOST_SEV_SNP)) { 1607 + ret = snp_get_platform_data(sev, &error); 1608 + if (ret) 1609 + return 1; 1610 + } 1611 + 1691 1612 ret = sev_platform_status(&status, &error); 1692 1613 if (ret) { 1693 1614 dev_err(sev->dev, ··· 1705 1606 return 1; 1706 1607 } 1707 1608 1609 + /* Cache SEV platform status */ 1610 + sev->sev_plat_status = status; 1611 + 1708 1612 sev->api_major = status.api_major; 1709 1613 sev->api_minor = status.api_minor; 1710 1614 sev->build = status.build; 1711 - sev->state = status.state; 1712 1615 1713 1616 return 0; 1714 1617 } ··· 1938 1837 data.oca_cert_len = input.oca_cert_len; 1939 1838 1940 1839 /* If platform is not in INIT state then transition it to INIT */ 1941 - if (sev->state != SEV_STATE_INIT) { 1840 + if (sev->sev_plat_status.state != SEV_STATE_INIT) { 1942 1841 ret = sev_move_to_init_state(argp, &shutdown_required); 1943 1842 if (ret) 1944 1843 goto e_free_oca; ··· 2109 2008 2110 2009 cmd: 2111 2010 /* If platform is not in INIT state then transition it to INIT. */ 2112 - if (sev->state != SEV_STATE_INIT) { 2011 + if (sev->sev_plat_status.state != SEV_STATE_INIT) { 2113 2012 if (!writable) { 2114 2013 ret = -EPERM; 2115 2014 goto e_free_cert;
+5 -1
drivers/crypto/ccp/sev-dev.h
··· 42 42 43 43 struct sev_vdata *vdata; 44 44 45 - int state; 46 45 unsigned int int_rcvd; 47 46 wait_queue_head_t int_queue; 48 47 struct sev_misc_dev *misc; ··· 56 57 bool cmd_buf_backup_active; 57 58 58 59 bool snp_initialized; 60 + 61 + struct sev_user_data_status sev_plat_status; 62 + 63 + struct sev_user_data_snp_status snp_plat_status; 64 + struct snp_feature_info snp_feat_info_0; 59 65 }; 60 66 61 67 int sev_dev_init(struct psp_device *psp);
+42 -2
include/linux/psp-sev.h
··· 107 107 SEV_CMD_SNP_DOWNLOAD_FIRMWARE_EX = 0x0CA, 108 108 SEV_CMD_SNP_COMMIT = 0x0CB, 109 109 SEV_CMD_SNP_VLEK_LOAD = 0x0CD, 110 + SEV_CMD_SNP_FEATURE_INFO = 0x0CE, 110 111 111 112 SEV_CMD_MAX, 112 113 }; ··· 748 747 struct sev_data_snp_init_ex { 749 748 u32 init_rmp:1; 750 749 u32 list_paddr_en:1; 751 - u32 rsvd:30; 750 + u32 rapl_dis:1; 751 + u32 ciphertext_hiding_en:1; 752 + u32 rsvd:28; 752 753 u32 rsvd1; 753 754 u64 list_paddr; 754 - u8 rsvd2[48]; 755 + u16 max_snp_asid; 756 + u8 rsvd2[46]; 755 757 } __packed; 756 758 757 759 /** ··· 803 799 * @probe: True if this is being called as part of CCP module probe, which 804 800 * will defer SEV_INIT/SEV_INIT_EX firmware initialization until needed 805 801 * unless psp_init_on_probe module param is set 802 + * @max_snp_asid: When non-zero, enable ciphertext hiding and specify the 803 + * maximum ASID that can be used for an SEV-SNP guest. 806 804 */ 807 805 struct sev_platform_init_args { 808 806 int error; 809 807 bool probe; 808 + unsigned int max_snp_asid; 810 809 }; 811 810 812 811 /** ··· 820 813 struct sev_data_snp_commit { 821 814 u32 len; 822 815 } __packed; 816 + 817 + /** 818 + * struct sev_data_snp_feature_info - SEV_SNP_FEATURE_INFO structure 819 + * 820 + * @length: len of the command buffer read by the PSP 821 + * @ecx_in: subfunction index 822 + * @feature_info_paddr : System Physical Address of the FEATURE_INFO structure 823 + */ 824 + struct sev_data_snp_feature_info { 825 + u32 length; 826 + u32 ecx_in; 827 + u64 feature_info_paddr; 828 + } __packed; 829 + 830 + /** 831 + * struct feature_info - FEATURE_INFO structure 832 + * 833 + * @eax: output of SNP_FEATURE_INFO command 834 + * @ebx: output of SNP_FEATURE_INFO command 835 + * @ecx: output of SNP_FEATURE_INFO command 836 + * #edx: output of SNP_FEATURE_INFO command 837 + */ 838 + struct snp_feature_info { 839 + u32 eax; 840 + u32 ebx; 841 + u32 ecx; 842 + u32 edx; 843 + } __packed; 844 + 845 + #define SNP_CIPHER_TEXT_HIDING_SUPPORTED BIT(3) 823 846 824 847 #ifdef CONFIG_CRYPTO_DEV_SP_PSP 825 848 ··· 994 957 void *snp_alloc_firmware_page(gfp_t mask); 995 958 void snp_free_firmware_page(void *addr); 996 959 void sev_platform_shutdown(void); 960 + bool sev_is_snp_ciphertext_hiding_supported(void); 997 961 998 962 #else /* !CONFIG_CRYPTO_DEV_SP_PSP */ 999 963 ··· 1030 992 static inline void snp_free_firmware_page(void *addr) { } 1031 993 1032 994 static inline void sev_platform_shutdown(void) { } 995 + 996 + static inline bool sev_is_snp_ciphertext_hiding_supported(void) { return false; } 1033 997 1034 998 #endif /* CONFIG_CRYPTO_DEV_SP_PSP */ 1035 999
+9 -1
include/uapi/linux/psp-sev.h
··· 185 185 * @mask_chip_id: whether chip id is present in attestation reports or not 186 186 * @mask_chip_key: whether attestation reports are signed or not 187 187 * @vlek_en: VLEK (Version Loaded Endorsement Key) hashstick is loaded 188 + * @feature_info: whether SNP_FEATURE_INFO command is available 189 + * @rapl_dis: whether RAPL is disabled 190 + * @ciphertext_hiding_cap: whether platform has ciphertext hiding capability 191 + * @ciphertext_hiding_en: whether ciphertext hiding is enabled 188 192 * @rsvd1: reserved 189 193 * @guest_count: the number of guest currently managed by the firmware 190 194 * @current_tcb_version: current TCB version ··· 204 200 __u32 mask_chip_id:1; /* Out */ 205 201 __u32 mask_chip_key:1; /* Out */ 206 202 __u32 vlek_en:1; /* Out */ 207 - __u32 rsvd1:29; 203 + __u32 feature_info:1; /* Out */ 204 + __u32 rapl_dis:1; /* Out */ 205 + __u32 ciphertext_hiding_cap:1; /* Out */ 206 + __u32 ciphertext_hiding_en:1; /* Out */ 207 + __u32 rsvd1:25; 208 208 __u32 guest_count; /* Out */ 209 209 __u64 current_tcb_version; /* Out */ 210 210 __u64 reported_tcb_version; /* Out */