0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "misc.h"
0014
0015 #include <asm/pgtable_types.h>
0016 #include <asm/sev.h>
0017 #include <asm/trapnr.h>
0018 #include <asm/trap_pf.h>
0019 #include <asm/msr-index.h>
0020 #include <asm/fpu/xcr.h>
0021 #include <asm/ptrace.h>
0022 #include <asm/svm.h>
0023 #include <asm/cpuid.h>
0024
0025 #include "error.h"
0026 #include "../msr.h"
0027
0028 struct ghcb boot_ghcb_page __aligned(PAGE_SIZE);
0029 struct ghcb *boot_ghcb;
0030
0031
0032
0033
0034
0035 static bool insn_has_rep_prefix(struct insn *insn)
0036 {
0037 insn_byte_t p;
0038 int i;
0039
0040 insn_get_prefixes(insn);
0041
0042 for_each_insn_prefix(insn, i, p) {
0043 if (p == 0xf2 || p == 0xf3)
0044 return true;
0045 }
0046
0047 return false;
0048 }
0049
0050
0051
0052
0053
0054 static unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)
0055 {
0056 return 0UL;
0057 }
0058
0059 static inline u64 sev_es_rd_ghcb_msr(void)
0060 {
0061 struct msr m;
0062
0063 boot_rdmsr(MSR_AMD64_SEV_ES_GHCB, &m);
0064
0065 return m.q;
0066 }
0067
0068 static inline void sev_es_wr_ghcb_msr(u64 val)
0069 {
0070 struct msr m;
0071
0072 m.q = val;
0073 boot_wrmsr(MSR_AMD64_SEV_ES_GHCB, &m);
0074 }
0075
0076 static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt)
0077 {
0078 char buffer[MAX_INSN_SIZE];
0079 int ret;
0080
0081 memcpy(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE);
0082
0083 ret = insn_decode(&ctxt->insn, buffer, MAX_INSN_SIZE, INSN_MODE_64);
0084 if (ret < 0)
0085 return ES_DECODE_FAILED;
0086
0087 return ES_OK;
0088 }
0089
0090 static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
0091 void *dst, char *buf, size_t size)
0092 {
0093 memcpy(dst, buf, size);
0094
0095 return ES_OK;
0096 }
0097
0098 static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
0099 void *src, char *buf, size_t size)
0100 {
0101 memcpy(buf, src, size);
0102
0103 return ES_OK;
0104 }
0105
0106 #undef __init
0107 #undef __pa
0108 #define __init
0109 #define __pa(x) ((unsigned long)(x))
0110
0111 #define __BOOT_COMPRESSED
0112
0113
0114 #include "../../lib/inat.c"
0115 #include "../../lib/insn.c"
0116
0117
0118 #include "../../kernel/sev-shared.c"
0119
0120 static inline bool sev_snp_enabled(void)
0121 {
0122 return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
0123 }
0124
0125 static void __page_state_change(unsigned long paddr, enum psc_op op)
0126 {
0127 u64 val;
0128
0129 if (!sev_snp_enabled())
0130 return;
0131
0132
0133
0134
0135
0136 if (op == SNP_PAGE_STATE_SHARED && pvalidate(paddr, RMP_PG_SIZE_4K, 0))
0137 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
0138
0139
0140 sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op));
0141 VMGEXIT();
0142
0143
0144 val = sev_es_rd_ghcb_msr();
0145 if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val))
0146 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
0147
0148
0149
0150
0151
0152 if (op == SNP_PAGE_STATE_PRIVATE && pvalidate(paddr, RMP_PG_SIZE_4K, 1))
0153 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
0154 }
0155
0156 void snp_set_page_private(unsigned long paddr)
0157 {
0158 __page_state_change(paddr, SNP_PAGE_STATE_PRIVATE);
0159 }
0160
0161 void snp_set_page_shared(unsigned long paddr)
0162 {
0163 __page_state_change(paddr, SNP_PAGE_STATE_SHARED);
0164 }
0165
0166 static bool early_setup_ghcb(void)
0167 {
0168 if (set_page_decrypted((unsigned long)&boot_ghcb_page))
0169 return false;
0170
0171
0172 memset(&boot_ghcb_page, 0, sizeof(boot_ghcb_page));
0173
0174 boot_ghcb = &boot_ghcb_page;
0175
0176
0177 inat_init_tables();
0178
0179
0180 if (sev_snp_enabled())
0181 snp_register_ghcb_early(__pa(&boot_ghcb_page));
0182
0183 return true;
0184 }
0185
0186 void sev_es_shutdown_ghcb(void)
0187 {
0188 if (!boot_ghcb)
0189 return;
0190
0191 if (!sev_es_check_cpu_features())
0192 error("SEV-ES CPU Features missing.");
0193
0194
0195
0196
0197
0198
0199 if (set_page_encrypted((unsigned long)&boot_ghcb_page))
0200 error("Can't map GHCB page encrypted");
0201
0202
0203
0204
0205
0206
0207 if (set_page_non_present((unsigned long)&boot_ghcb_page))
0208 error("Can't unmap GHCB page");
0209 }
0210
0211 bool sev_es_check_ghcb_fault(unsigned long address)
0212 {
0213
0214 return ((address & PAGE_MASK) == (unsigned long)&boot_ghcb_page);
0215 }
0216
0217 void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)
0218 {
0219 struct es_em_ctxt ctxt;
0220 enum es_result result;
0221
0222 if (!boot_ghcb && !early_setup_ghcb())
0223 sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
0224
0225 vc_ghcb_invalidate(boot_ghcb);
0226 result = vc_init_em_ctxt(&ctxt, regs, exit_code);
0227 if (result != ES_OK)
0228 goto finish;
0229
0230 switch (exit_code) {
0231 case SVM_EXIT_RDTSC:
0232 case SVM_EXIT_RDTSCP:
0233 result = vc_handle_rdtsc(boot_ghcb, &ctxt, exit_code);
0234 break;
0235 case SVM_EXIT_IOIO:
0236 result = vc_handle_ioio(boot_ghcb, &ctxt);
0237 break;
0238 case SVM_EXIT_CPUID:
0239 result = vc_handle_cpuid(boot_ghcb, &ctxt);
0240 break;
0241 default:
0242 result = ES_UNSUPPORTED;
0243 break;
0244 }
0245
0246 finish:
0247 if (result == ES_OK)
0248 vc_finish_insn(&ctxt);
0249 else if (result != ES_RETRY)
0250 sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
0251 }
0252
0253 static void enforce_vmpl0(void)
0254 {
0255 u64 attrs;
0256 int err;
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 attrs = 1;
0269 if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, attrs))
0270 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
0271 }
0272
0273 void sev_enable(struct boot_params *bp)
0274 {
0275 unsigned int eax, ebx, ecx, edx;
0276 struct msr m;
0277 bool snp;
0278
0279
0280
0281
0282
0283
0284 if (bp)
0285 bp->cc_blob_address = 0;
0286
0287
0288
0289
0290
0291 snp = snp_init(bp);
0292
0293
0294 eax = 0x80000000;
0295 ecx = 0;
0296 native_cpuid(&eax, &ebx, &ecx, &edx);
0297 if (eax < 0x8000001f)
0298 return;
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 eax = 0x8000001f;
0309 ecx = 0;
0310 native_cpuid(&eax, &ebx, &ecx, &edx);
0311
0312 if (!(eax & BIT(1))) {
0313 if (snp)
0314 error("SEV-SNP support indicated by CC blob, but not CPUID.");
0315 return;
0316 }
0317
0318
0319 boot_rdmsr(MSR_AMD64_SEV, &m);
0320 sev_status = m.q;
0321 if (!(sev_status & MSR_AMD64_SEV_ENABLED))
0322 return;
0323
0324
0325 if (sev_status & MSR_AMD64_SEV_ES_ENABLED) {
0326 if (!sev_es_negotiate_protocol())
0327 sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_PROT_UNSUPPORTED);
0328 }
0329
0330
0331
0332
0333
0334 if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) {
0335 if (!(get_hv_features() & GHCB_HV_FT_SNP))
0336 sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
0337
0338 enforce_vmpl0();
0339 }
0340
0341 if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
0342 error("SEV-SNP supported indicated by CC blob, but not SEV status MSR.");
0343
0344 sme_me_mask = BIT_ULL(ebx & 0x3f);
0345 }
0346
0347
0348 static struct cc_blob_sev_info *find_cc_blob_efi(struct boot_params *bp)
0349 {
0350 unsigned long cfg_table_pa;
0351 unsigned int cfg_table_len;
0352 int ret;
0353
0354 ret = efi_get_conf_table(bp, &cfg_table_pa, &cfg_table_len);
0355 if (ret)
0356 return NULL;
0357
0358 return (struct cc_blob_sev_info *)efi_find_vendor_table(bp, cfg_table_pa,
0359 cfg_table_len,
0360 EFI_CC_BLOB_GUID);
0361 }
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 static struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
0374 {
0375 struct cc_blob_sev_info *cc_info;
0376
0377 cc_info = find_cc_blob_efi(bp);
0378 if (cc_info)
0379 goto found_cc_info;
0380
0381 cc_info = find_cc_blob_setup_data(bp);
0382 if (!cc_info)
0383 return NULL;
0384
0385 found_cc_info:
0386 if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC)
0387 sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
0388
0389 return cc_info;
0390 }
0391
0392
0393
0394
0395
0396 bool snp_init(struct boot_params *bp)
0397 {
0398 struct cc_blob_sev_info *cc_info;
0399
0400 if (!bp)
0401 return false;
0402
0403 cc_info = find_cc_blob(bp);
0404 if (!cc_info)
0405 return false;
0406
0407
0408
0409
0410
0411
0412
0413
0414 setup_cpuid_table(cc_info);
0415
0416
0417
0418
0419
0420
0421 bp->cc_blob_address = (u32)(unsigned long)cc_info;
0422
0423 return true;
0424 }
0425
0426 void sev_prep_identity_maps(unsigned long top_level_pgt)
0427 {
0428
0429
0430
0431
0432
0433
0434 if (sev_snp_enabled()) {
0435 unsigned long cc_info_pa = boot_params->cc_blob_address;
0436 struct cc_blob_sev_info *cc_info;
0437
0438 kernel_add_identity_map(cc_info_pa, cc_info_pa + sizeof(*cc_info));
0439
0440 cc_info = (struct cc_blob_sev_info *)cc_info_pa;
0441 kernel_add_identity_map(cc_info->cpuid_phys, cc_info->cpuid_phys + cc_info->cpuid_len);
0442 }
0443
0444 sev_verify_cbit(top_level_pgt);
0445 }