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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86-urgent-2023-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 fixes from Ingo Molnar:

- Fix SEV-SNP guest crashes that may happen on NMIs

- Fix a potential SEV platform memory setup overflow

* tag 'x86-urgent-2023-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/sev: Change npages to unsigned long in snp_accept_memory()
x86/sev: Use the GHCB protocol when available for SNP CPUID requests

+56 -16
+55 -14
arch/x86/kernel/sev-shared.c
··· 256 256 return 0; 257 257 } 258 258 259 - static int sev_cpuid_hv(struct cpuid_leaf *leaf) 259 + static int __sev_cpuid_hv_msr(struct cpuid_leaf *leaf) 260 260 { 261 261 int ret; 262 262 ··· 277 277 ret = ret ? : __sev_cpuid_hv(leaf->fn, GHCB_CPUID_REQ_EDX, &leaf->edx); 278 278 279 279 return ret; 280 + } 281 + 282 + static int __sev_cpuid_hv_ghcb(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) 283 + { 284 + u32 cr4 = native_read_cr4(); 285 + int ret; 286 + 287 + ghcb_set_rax(ghcb, leaf->fn); 288 + ghcb_set_rcx(ghcb, leaf->subfn); 289 + 290 + if (cr4 & X86_CR4_OSXSAVE) 291 + /* Safe to read xcr0 */ 292 + ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK)); 293 + else 294 + /* xgetbv will cause #UD - use reset value for xcr0 */ 295 + ghcb_set_xcr0(ghcb, 1); 296 + 297 + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0); 298 + if (ret != ES_OK) 299 + return ret; 300 + 301 + if (!(ghcb_rax_is_valid(ghcb) && 302 + ghcb_rbx_is_valid(ghcb) && 303 + ghcb_rcx_is_valid(ghcb) && 304 + ghcb_rdx_is_valid(ghcb))) 305 + return ES_VMM_ERROR; 306 + 307 + leaf->eax = ghcb->save.rax; 308 + leaf->ebx = ghcb->save.rbx; 309 + leaf->ecx = ghcb->save.rcx; 310 + leaf->edx = ghcb->save.rdx; 311 + 312 + return ES_OK; 313 + } 314 + 315 + static int sev_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) 316 + { 317 + return ghcb ? __sev_cpuid_hv_ghcb(ghcb, ctxt, leaf) 318 + : __sev_cpuid_hv_msr(leaf); 280 319 } 281 320 282 321 /* ··· 427 388 return false; 428 389 } 429 390 430 - static void snp_cpuid_hv(struct cpuid_leaf *leaf) 391 + static void snp_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) 431 392 { 432 - if (sev_cpuid_hv(leaf)) 393 + if (sev_cpuid_hv(ghcb, ctxt, leaf)) 433 394 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV); 434 395 } 435 396 436 - static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) 397 + static int snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt, 398 + struct cpuid_leaf *leaf) 437 399 { 438 400 struct cpuid_leaf leaf_hv = *leaf; 439 401 440 402 switch (leaf->fn) { 441 403 case 0x1: 442 - snp_cpuid_hv(&leaf_hv); 404 + snp_cpuid_hv(ghcb, ctxt, &leaf_hv); 443 405 444 406 /* initial APIC ID */ 445 407 leaf->ebx = (leaf_hv.ebx & GENMASK(31, 24)) | (leaf->ebx & GENMASK(23, 0)); ··· 459 419 break; 460 420 case 0xB: 461 421 leaf_hv.subfn = 0; 462 - snp_cpuid_hv(&leaf_hv); 422 + snp_cpuid_hv(ghcb, ctxt, &leaf_hv); 463 423 464 424 /* extended APIC ID */ 465 425 leaf->edx = leaf_hv.edx; ··· 507 467 } 508 468 break; 509 469 case 0x8000001E: 510 - snp_cpuid_hv(&leaf_hv); 470 + snp_cpuid_hv(ghcb, ctxt, &leaf_hv); 511 471 512 472 /* extended APIC ID */ 513 473 leaf->eax = leaf_hv.eax; ··· 528 488 * Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value 529 489 * should be treated as fatal by caller. 530 490 */ 531 - static int snp_cpuid(struct cpuid_leaf *leaf) 491 + static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) 532 492 { 533 493 const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); 534 494 ··· 562 522 return 0; 563 523 } 564 524 565 - return snp_cpuid_postprocess(leaf); 525 + return snp_cpuid_postprocess(ghcb, ctxt, leaf); 566 526 } 567 527 568 528 /* ··· 584 544 leaf.fn = fn; 585 545 leaf.subfn = subfn; 586 546 587 - ret = snp_cpuid(&leaf); 547 + ret = snp_cpuid(NULL, NULL, &leaf); 588 548 if (!ret) 589 549 goto cpuid_done; 590 550 591 551 if (ret != -EOPNOTSUPP) 592 552 goto fail; 593 553 594 - if (sev_cpuid_hv(&leaf)) 554 + if (__sev_cpuid_hv_msr(&leaf)) 595 555 goto fail; 596 556 597 557 cpuid_done: ··· 888 848 return ret; 889 849 } 890 850 891 - static int vc_handle_cpuid_snp(struct pt_regs *regs) 851 + static int vc_handle_cpuid_snp(struct ghcb *ghcb, struct es_em_ctxt *ctxt) 892 852 { 853 + struct pt_regs *regs = ctxt->regs; 893 854 struct cpuid_leaf leaf; 894 855 int ret; 895 856 896 857 leaf.fn = regs->ax; 897 858 leaf.subfn = regs->cx; 898 - ret = snp_cpuid(&leaf); 859 + ret = snp_cpuid(ghcb, ctxt, &leaf); 899 860 if (!ret) { 900 861 regs->ax = leaf.eax; 901 862 regs->bx = leaf.ebx; ··· 915 874 enum es_result ret; 916 875 int snp_cpuid_ret; 917 876 918 - snp_cpuid_ret = vc_handle_cpuid_snp(regs); 877 + snp_cpuid_ret = vc_handle_cpuid_snp(ghcb, ctxt); 919 878 if (!snp_cpuid_ret) 920 879 return ES_OK; 921 880 if (snp_cpuid_ret != -EOPNOTSUPP)
+1 -2
arch/x86/kernel/sev.c
··· 868 868 869 869 void snp_accept_memory(phys_addr_t start, phys_addr_t end) 870 870 { 871 - unsigned long vaddr; 872 - unsigned int npages; 871 + unsigned long vaddr, npages; 873 872 874 873 if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) 875 874 return;