Merge tag 'x86_urgent_for_v6.2_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

- Start checking for -mindirect-branch-cs-prefix clang support too now
that LLVM 16 will support it

- Fix a NULL ptr deref when suspending with Xen PV

- Have a SEV-SNP guest check explicitly for features enabled by the
hypervisor and fail gracefully if some are unsupported by the guest
instead of failing in a non-obvious and hard-to-debug way

- Fix a MSI descriptor leakage under Xen

- Mark Xen's MSI domain as supporting MSI-X

- Prevent legacy PIC interrupts from being resent in software by
marking them level triggered, as they should be, which lead to a NULL
ptr deref

* tag 'x86_urgent_for_v6.2_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/build: Move '-mindirect-branch-cs-prefix' out of GCC-only block
acpi: Fix suspend with Xen PV
x86/sev: Add SEV-SNP guest feature negotiation support
x86/pci/xen: Fixup fallout from the PCI/MSI overhaul
x86/pci/xen: Set MSI_FLAG_PCI_MSIX support in Xen MSI domain
x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL

+160 -3
+36
Documentation/x86/amd-memory-encryption.rst
··· 95 not enable SME, then Linux will not be able to activate memory encryption, even 96 if configured to do so by default or the mem_encrypt=on command line parameter 97 is specified.
··· 95 not enable SME, then Linux will not be able to activate memory encryption, even 96 if configured to do so by default or the mem_encrypt=on command line parameter 97 is specified. 98 + 99 + Secure Nested Paging (SNP) 100 + ========================== 101 + 102 + SEV-SNP introduces new features (SEV_FEATURES[1:63]) which can be enabled 103 + by the hypervisor for security enhancements. Some of these features need 104 + guest side implementation to function correctly. The below table lists the 105 + expected guest behavior with various possible scenarios of guest/hypervisor 106 + SNP feature support. 107 + 108 + +-----------------+---------------+---------------+------------------+ 109 + | Feature Enabled | Guest needs | Guest has | Guest boot | 110 + | by the HV | implementation| implementation| behaviour | 111 + +=================+===============+===============+==================+ 112 + | No | No | No | Boot | 113 + | | | | | 114 + +-----------------+---------------+---------------+------------------+ 115 + | No | Yes | No | Boot | 116 + | | | | | 117 + +-----------------+---------------+---------------+------------------+ 118 + | No | Yes | Yes | Boot | 119 + | | | | | 120 + +-----------------+---------------+---------------+------------------+ 121 + | Yes | No | No | Boot with | 122 + | | | | feature enabled | 123 + +-----------------+---------------+---------------+------------------+ 124 + | Yes | Yes | No | Graceful boot | 125 + | | | | failure | 126 + +-----------------+---------------+---------------+------------------+ 127 + | Yes | Yes | Yes | Boot with | 128 + | | | | feature enabled | 129 + +-----------------+---------------+---------------+------------------+ 130 + 131 + More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR 132 + 133 + [1] https://www.amd.com/system/files/TechDocs/40332.pdf
+1 -1
arch/x86/Makefile
··· 14 15 ifdef CONFIG_CC_IS_GCC 16 RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) 17 - RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix) 18 RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register) 19 endif 20 ifdef CONFIG_CC_IS_CLANG 21 RETPOLINE_CFLAGS := -mretpoline-external-thunk 22 RETPOLINE_VDSO_CFLAGS := -mretpoline 23 endif 24 25 ifdef CONFIG_RETHUNK 26 RETHUNK_CFLAGS := -mfunction-return=thunk-extern
··· 14 15 ifdef CONFIG_CC_IS_GCC 16 RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) 17 RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register) 18 endif 19 ifdef CONFIG_CC_IS_CLANG 20 RETPOLINE_CFLAGS := -mretpoline-external-thunk 21 RETPOLINE_VDSO_CFLAGS := -mretpoline 22 endif 23 + RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix) 24 25 ifdef CONFIG_RETHUNK 26 RETHUNK_CFLAGS := -mfunction-return=thunk-extern
+6
arch/x86/boot/compressed/ident_map_64.c
··· 180 181 /* Load the new page-table. */ 182 write_cr3(top_level_pgt); 183 } 184 185 static pte_t *split_large_pmd(struct x86_mapping_info *info,
··· 180 181 /* Load the new page-table. */ 182 write_cr3(top_level_pgt); 183 + 184 + /* 185 + * Now that the required page table mappings are established and a 186 + * GHCB can be used, check for SNP guest/HV feature compatibility. 187 + */ 188 + snp_check_features(); 189 } 190 191 static pte_t *split_large_pmd(struct x86_mapping_info *info,
+2
arch/x86/boot/compressed/misc.h
··· 126 127 #ifdef CONFIG_AMD_MEM_ENCRYPT 128 void sev_enable(struct boot_params *bp); 129 void sev_es_shutdown_ghcb(void); 130 extern bool sev_es_check_ghcb_fault(unsigned long address); 131 void snp_set_page_private(unsigned long paddr); ··· 144 if (bp) 145 bp->cc_blob_address = 0; 146 } 147 static inline void sev_es_shutdown_ghcb(void) { } 148 static inline bool sev_es_check_ghcb_fault(unsigned long address) 149 {
··· 126 127 #ifdef CONFIG_AMD_MEM_ENCRYPT 128 void sev_enable(struct boot_params *bp); 129 + void snp_check_features(void); 130 void sev_es_shutdown_ghcb(void); 131 extern bool sev_es_check_ghcb_fault(unsigned long address); 132 void snp_set_page_private(unsigned long paddr); ··· 143 if (bp) 144 bp->cc_blob_address = 0; 145 } 146 + static inline void snp_check_features(void) { } 147 static inline void sev_es_shutdown_ghcb(void) { } 148 static inline bool sev_es_check_ghcb_fault(unsigned long address) 149 {
+70
arch/x86/boot/compressed/sev.c
··· 208 error("Can't unmap GHCB page"); 209 } 210 211 bool sev_es_check_ghcb_fault(unsigned long address) 212 { 213 /* Check whether the fault was on the GHCB page */ ··· 285 attrs = 1; 286 if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, attrs)) 287 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); 288 } 289 290 void sev_enable(struct boot_params *bp)
··· 208 error("Can't unmap GHCB page"); 209 } 210 211 + static void __noreturn sev_es_ghcb_terminate(struct ghcb *ghcb, unsigned int set, 212 + unsigned int reason, u64 exit_info_2) 213 + { 214 + u64 exit_info_1 = SVM_VMGEXIT_TERM_REASON(set, reason); 215 + 216 + vc_ghcb_invalidate(ghcb); 217 + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_TERM_REQUEST); 218 + ghcb_set_sw_exit_info_1(ghcb, exit_info_1); 219 + ghcb_set_sw_exit_info_2(ghcb, exit_info_2); 220 + 221 + sev_es_wr_ghcb_msr(__pa(ghcb)); 222 + VMGEXIT(); 223 + 224 + while (true) 225 + asm volatile("hlt\n" : : : "memory"); 226 + } 227 + 228 bool sev_es_check_ghcb_fault(unsigned long address) 229 { 230 /* Check whether the fault was on the GHCB page */ ··· 268 attrs = 1; 269 if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, attrs)) 270 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); 271 + } 272 + 273 + /* 274 + * SNP_FEATURES_IMPL_REQ is the mask of SNP features that will need 275 + * guest side implementation for proper functioning of the guest. If any 276 + * of these features are enabled in the hypervisor but are lacking guest 277 + * side implementation, the behavior of the guest will be undefined. The 278 + * guest could fail in non-obvious way making it difficult to debug. 279 + * 280 + * As the behavior of reserved feature bits is unknown to be on the 281 + * safe side add them to the required features mask. 282 + */ 283 + #define SNP_FEATURES_IMPL_REQ (MSR_AMD64_SNP_VTOM | \ 284 + MSR_AMD64_SNP_REFLECT_VC | \ 285 + MSR_AMD64_SNP_RESTRICTED_INJ | \ 286 + MSR_AMD64_SNP_ALT_INJ | \ 287 + MSR_AMD64_SNP_DEBUG_SWAP | \ 288 + MSR_AMD64_SNP_VMPL_SSS | \ 289 + MSR_AMD64_SNP_SECURE_TSC | \ 290 + MSR_AMD64_SNP_VMGEXIT_PARAM | \ 291 + MSR_AMD64_SNP_VMSA_REG_PROTECTION | \ 292 + MSR_AMD64_SNP_RESERVED_BIT13 | \ 293 + MSR_AMD64_SNP_RESERVED_BIT15 | \ 294 + MSR_AMD64_SNP_RESERVED_MASK) 295 + 296 + /* 297 + * SNP_FEATURES_PRESENT is the mask of SNP features that are implemented 298 + * by the guest kernel. As and when a new feature is implemented in the 299 + * guest kernel, a corresponding bit should be added to the mask. 300 + */ 301 + #define SNP_FEATURES_PRESENT (0) 302 + 303 + void snp_check_features(void) 304 + { 305 + u64 unsupported; 306 + 307 + if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) 308 + return; 309 + 310 + /* 311 + * Terminate the boot if hypervisor has enabled any feature lacking 312 + * guest side implementation. Pass on the unsupported features mask through 313 + * EXIT_INFO_2 of the GHCB protocol so that those features can be reported 314 + * as part of the guest boot failure. 315 + */ 316 + unsupported = sev_status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT; 317 + if (unsupported) { 318 + if (ghcb_version < 2 || (!boot_ghcb && !early_setup_ghcb())) 319 + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); 320 + 321 + sev_es_ghcb_terminate(boot_ghcb, SEV_TERM_SET_GEN, 322 + GHCB_SNP_UNSUPPORTED, unsupported); 323 + } 324 } 325 326 void sev_enable(struct boot_params *bp)
+8
arch/x86/include/asm/acpi.h
··· 14 #include <asm/mmu.h> 15 #include <asm/mpspec.h> 16 #include <asm/x86_init.h> 17 18 #ifdef CONFIG_ACPI_APEI 19 # include <asm/pgtable_types.h> ··· 63 64 /* Physical address to resume after wakeup */ 65 unsigned long acpi_get_wakeup_address(void); 66 67 /* 68 * Check if the CPU can handle C2 and deeper
··· 14 #include <asm/mmu.h> 15 #include <asm/mpspec.h> 16 #include <asm/x86_init.h> 17 + #include <asm/cpufeature.h> 18 19 #ifdef CONFIG_ACPI_APEI 20 # include <asm/pgtable_types.h> ··· 62 63 /* Physical address to resume after wakeup */ 64 unsigned long acpi_get_wakeup_address(void); 65 + 66 + static inline bool acpi_skip_set_wakeup_address(void) 67 + { 68 + return cpu_feature_enabled(X86_FEATURE_XENPV); 69 + } 70 + 71 + #define acpi_skip_set_wakeup_address acpi_skip_set_wakeup_address 72 73 /* 74 * Check if the CPU can handle C2 and deeper
+20
arch/x86/include/asm/msr-index.h
··· 566 #define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) 567 #define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) 568 569 #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f 570 571 /* AMD Collaborative Processor Performance Control MSRs */
··· 566 #define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) 567 #define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) 568 569 + /* SNP feature bits enabled by the hypervisor */ 570 + #define MSR_AMD64_SNP_VTOM BIT_ULL(3) 571 + #define MSR_AMD64_SNP_REFLECT_VC BIT_ULL(4) 572 + #define MSR_AMD64_SNP_RESTRICTED_INJ BIT_ULL(5) 573 + #define MSR_AMD64_SNP_ALT_INJ BIT_ULL(6) 574 + #define MSR_AMD64_SNP_DEBUG_SWAP BIT_ULL(7) 575 + #define MSR_AMD64_SNP_PREVENT_HOST_IBS BIT_ULL(8) 576 + #define MSR_AMD64_SNP_BTB_ISOLATION BIT_ULL(9) 577 + #define MSR_AMD64_SNP_VMPL_SSS BIT_ULL(10) 578 + #define MSR_AMD64_SNP_SECURE_TSC BIT_ULL(11) 579 + #define MSR_AMD64_SNP_VMGEXIT_PARAM BIT_ULL(12) 580 + #define MSR_AMD64_SNP_IBS_VIRT BIT_ULL(14) 581 + #define MSR_AMD64_SNP_VMSA_REG_PROTECTION BIT_ULL(16) 582 + #define MSR_AMD64_SNP_SMT_PROTECTION BIT_ULL(17) 583 + 584 + /* SNP feature bits reserved for future use. */ 585 + #define MSR_AMD64_SNP_RESERVED_BIT13 BIT_ULL(13) 586 + #define MSR_AMD64_SNP_RESERVED_BIT15 BIT_ULL(15) 587 + #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, 18) 588 + 589 #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f 590 591 /* AMD Collaborative Processor Performance Control MSRs */
+6
arch/x86/include/uapi/asm/svm.h
··· 116 #define SVM_VMGEXIT_AP_CREATE 1 117 #define SVM_VMGEXIT_AP_DESTROY 2 118 #define SVM_VMGEXIT_HV_FEATURES 0x8000fffd 119 #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff 120 121 /* Exit code reserved for hypervisor/software use */
··· 116 #define SVM_VMGEXIT_AP_CREATE 1 117 #define SVM_VMGEXIT_AP_DESTROY 2 118 #define SVM_VMGEXIT_HV_FEATURES 0x8000fffd 119 + #define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe 120 + #define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code) \ 121 + /* SW_EXITINFO1[3:0] */ \ 122 + (((((u64)reason_set) & 0xf)) | \ 123 + /* SW_EXITINFO1[11:4] */ \ 124 + ((((u64)reason_code) & 0xff) << 4)) 125 #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff 126 127 /* Exit code reserved for hypervisor/software use */
+1
arch/x86/kernel/i8259.c
··· 114 disable_irq_nosync(irq); 115 io_apic_irqs &= ~(1<<irq); 116 irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); 117 enable_irq(irq); 118 lapic_assign_legacy_vector(irq, true); 119 }
··· 114 disable_irq_nosync(irq); 115 io_apic_irqs &= ~(1<<irq); 116 irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); 117 + irq_set_status_flags(irq, IRQ_LEVEL); 118 enable_irq(irq); 119 lapic_assign_legacy_vector(irq, true); 120 }
+3 -1
arch/x86/kernel/irqinit.c
··· 65 66 legacy_pic->init(0); 67 68 - for (i = 0; i < nr_legacy_irqs(); i++) 69 irq_set_chip_and_handler(i, chip, handle_level_irq); 70 } 71 72 void __init init_IRQ(void)
··· 65 66 legacy_pic->init(0); 67 68 + for (i = 0; i < nr_legacy_irqs(); i++) { 69 irq_set_chip_and_handler(i, chip, handle_level_irq); 70 + irq_set_status_flags(i, IRQ_LEVEL); 71 + } 72 } 73 74 void __init init_IRQ(void)
+2
arch/x86/pci/xen.c
··· 392 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) { 393 for (i = 0; i < msidesc->nvec_used; i++) 394 xen_destroy_irq(msidesc->irq + i); 395 } 396 } 397 ··· 434 }; 435 436 static struct msi_domain_info xen_pci_msi_domain_info = { 437 .ops = &xen_pci_msi_domain_ops, 438 }; 439
··· 392 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) { 393 for (i = 0; i < msidesc->nvec_used; i++) 394 xen_destroy_irq(msidesc->irq + i); 395 + msidesc->irq = 0; 396 } 397 } 398 ··· 433 }; 434 435 static struct msi_domain_info xen_pci_msi_domain_info = { 436 + .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS, 437 .ops = &xen_pci_msi_domain_ops, 438 }; 439
+5 -1
drivers/acpi/sleep.c
··· 60 .priority = 0, 61 }; 62 63 static int acpi_sleep_prepare(u32 acpi_state) 64 { 65 #ifdef CONFIG_ACPI_SLEEP 66 unsigned long acpi_wakeup_address; 67 68 /* do we have a wakeup address for S2 and S3? */ 69 - if (acpi_state == ACPI_STATE_S3) { 70 acpi_wakeup_address = acpi_get_wakeup_address(); 71 if (!acpi_wakeup_address) 72 return -EFAULT;
··· 60 .priority = 0, 61 }; 62 63 + #ifndef acpi_skip_set_wakeup_address 64 + #define acpi_skip_set_wakeup_address() false 65 + #endif 66 + 67 static int acpi_sleep_prepare(u32 acpi_state) 68 { 69 #ifdef CONFIG_ACPI_SLEEP 70 unsigned long acpi_wakeup_address; 71 72 /* do we have a wakeup address for S2 and S3? */ 73 + if (acpi_state == ACPI_STATE_S3 && !acpi_skip_set_wakeup_address()) { 74 acpi_wakeup_address = acpi_get_wakeup_address(); 75 if (!acpi_wakeup_address) 76 return -EFAULT;