History

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

Linus Torvalds committed 3 years ago

Commit bc6bc342 parents 80826e9 27b5de612 files · +160 −3Browse files

Unified · Split

12 files
  1. Documentation/x86/amd-memory-encryption.rst +36 −0
  2. arch/x86/Makefile +1 −1
  3. arch/x86/boot/compressed/ident_map_64.c +6 −0
  4. arch/x86/boot/compressed/misc.h +2 −0
  5. arch/x86/boot/compressed/sev.c +70 −0
  6. arch/x86/include/asm/acpi.h +8 −0
  7. arch/x86/include/asm/msr-index.h +20 −0
  8. arch/x86/include/uapi/asm/svm.h +6 −0
  9. arch/x86/kernel/i8259.c +1 −0
  10. arch/x86/kernel/irqinit.c +3 −1
  11. arch/x86/pci/xen.c +2 −0
  12. drivers/acpi/sleep.c +5 −1
Documentation/x86/amd-memory-encryption.rst+36−0
@@ -95,3 +95,39 @@ by supplying mem_encrypt=on on the kernel command line. However, if BIOS does · 94 unmodified lines
9595 not enable SME, then Linux will not be able to activate memory encryption, even
9696 if configured to do so by default or the mem_encrypt=on command line parameter
9797 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
arch/x86/Makefile+1−1
@@ -14,13 +14,13 @@ endif · 13 unmodified lines
1414
1515 ifdef CONFIG_CC_IS_GCC
1616 RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
17−RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
1817 RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register)
1918 endif
2019 ifdef CONFIG_CC_IS_CLANG
2120 RETPOLINE_CFLAGS := -mretpoline-external-thunk
2221 RETPOLINE_VDSO_CFLAGS := -mretpoline
2322 endif
23+RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
2424
2525 ifdef CONFIG_RETHUNK
2626 RETHUNK_CFLAGS := -mfunction-return=thunk-extern
arch/x86/boot/compressed/ident_map_64.c+6−0
@@ -180,6 +180,12 @@ void initialize_identity_maps(void *rmode) · 179 unmodified lines
180180
181181 /* Load the new page-table. */
182182 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();
183189 }
184190
185191 static pte_t *split_large_pmd(struct x86_mapping_info *info,
arch/x86/boot/compressed/misc.h+2−0
@@ -126,6 +126,7 @@ static inline void console_init(void) · 125 unmodified lines
126126
127127 #ifdef CONFIG_AMD_MEM_ENCRYPT
128128 void sev_enable(struct boot_params *bp);
129+void snp_check_features(void);
129130 void sev_es_shutdown_ghcb(void);
130131 extern bool sev_es_check_ghcb_fault(unsigned long address);
131132 void snp_set_page_private(unsigned long paddr);
@@ -143,6 +144,7 @@ static inline void sev_enable(struct boot_params *bp) · 11 unmodified lines
143144 if (bp)
144145 bp->cc_blob_address = 0;
145146 }
147+static inline void snp_check_features(void) { }
146148 static inline void sev_es_shutdown_ghcb(void) { }
147149 static inline bool sev_es_check_ghcb_fault(unsigned long address)
148150 {
arch/x86/boot/compressed/sev.c+70−0
@@ -208,6 +208,23 @@ void sev_es_shutdown_ghcb(void) · 207 unmodified lines
208208 error("Can't unmap GHCB page");
209209 }
210210
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+
211228 bool sev_es_check_ghcb_fault(unsigned long address)
212229 {
213230 /* Check whether the fault was on the GHCB page */
@@ -270,6 +287,59 @@ static void enforce_vmpl0(void) · 56 unmodified lines
270287 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
271288 }
272289
290+/*
291+ * SNP_FEATURES_IMPL_REQ is the mask of SNP features that will need
292+ * guest side implementation for proper functioning of the guest. If any
293+ * of these features are enabled in the hypervisor but are lacking guest
294+ * side implementation, the behavior of the guest will be undefined. The
295+ * guest could fail in non-obvious way making it difficult to debug.
296+ *
297+ * As the behavior of reserved feature bits is unknown to be on the
298+ * safe side add them to the required features mask.
299+ */
300+#define SNP_FEATURES_IMPL_REQ (MSR_AMD64_SNP_VTOM | \
301+ MSR_AMD64_SNP_REFLECT_VC | \
302+ MSR_AMD64_SNP_RESTRICTED_INJ | \
303+ MSR_AMD64_SNP_ALT_INJ | \
304+ MSR_AMD64_SNP_DEBUG_SWAP | \
305+ MSR_AMD64_SNP_VMPL_SSS | \
306+ MSR_AMD64_SNP_SECURE_TSC | \
307+ MSR_AMD64_SNP_VMGEXIT_PARAM | \
308+ MSR_AMD64_SNP_VMSA_REG_PROTECTION | \
309+ MSR_AMD64_SNP_RESERVED_BIT13 | \
310+ MSR_AMD64_SNP_RESERVED_BIT15 | \
311+ MSR_AMD64_SNP_RESERVED_MASK)
312+
313+/*
314+ * SNP_FEATURES_PRESENT is the mask of SNP features that are implemented
315+ * by the guest kernel. As and when a new feature is implemented in the
316+ * guest kernel, a corresponding bit should be added to the mask.
317+ */
318+#define SNP_FEATURES_PRESENT (0)
319+
320+void snp_check_features(void)
321+{
322+ u64 unsupported;
323+
324+ if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
325+ return;
326+
327+ /*
328+ * Terminate the boot if hypervisor has enabled any feature lacking
329+ * guest side implementation. Pass on the unsupported features mask through
330+ * EXIT_INFO_2 of the GHCB protocol so that those features can be reported
331+ * as part of the guest boot failure.
332+ */
333+ unsupported = sev_status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT;
334+ if (unsupported) {
335+ if (ghcb_version < 2 || (!boot_ghcb && !early_setup_ghcb()))
336+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
337+
338+ sev_es_ghcb_terminate(boot_ghcb, SEV_TERM_SET_GEN,
339+ GHCB_SNP_UNSUPPORTED, unsupported);
340+ }
341+}
342+
273343 void sev_enable(struct boot_params *bp)
274344 {
275345 unsigned int eax, ebx, ecx, edx;
arch/x86/include/asm/acpi.h+8−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <asm/mmu.h>
1515 #include <asm/mpspec.h>
1616 #include <asm/x86_init.h>
17+#include <asm/cpufeature.h>
1718
1819 #ifdef CONFIG_ACPI_APEI
1920 # include <asm/pgtable_types.h>
@@ -63,6 +64,13 @@ extern int (*acpi_suspend_lowlevel)(void); · 43 unmodified lines
6364 /* Physical address to resume after wakeup */
6465 unsigned long acpi_get_wakeup_address(void);
6566
67+static inline bool acpi_skip_set_wakeup_address(void)
68+{
69+ return cpu_feature_enabled(X86_FEATURE_XENPV);
70+}
71+
72+#define acpi_skip_set_wakeup_address acpi_skip_set_wakeup_address
73+
6674 /*
6775 * Check if the CPU can handle C2 and deeper
6876 */
arch/x86/include/asm/msr-index.h+20−0
@@ -566,6 +566,26 @@ · 565 unmodified lines
566566 #define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)
567567 #define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT)
568568
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+
569589 #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
570590
571591 /* AMD Collaborative Processor Performance Control MSRs */
arch/x86/include/uapi/asm/svm.h+6−0
@@ -116,6 +116,12 @@ · 115 unmodified lines
116116 #define SVM_VMGEXIT_AP_CREATE 1
117117 #define SVM_VMGEXIT_AP_DESTROY 2
118118 #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))
119125 #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff
120126
121127 /* Exit code reserved for hypervisor/software use */
arch/x86/kernel/i8259.c+1−0
@@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int irq) · 113 unmodified lines
114114 disable_irq_nosync(irq);
115115 io_apic_irqs &= ~(1<<irq);
116116 irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
117+ irq_set_status_flags(irq, IRQ_LEVEL);
117118 enable_irq(irq);
118119 lapic_assign_legacy_vector(irq, true);
119120 }
arch/x86/kernel/irqinit.c+3−1
@@ -65,8 +65,10 @@ void __init init_ISA_irqs(void) · 64 unmodified lines
6565
6666 legacy_pic->init(0);
6767
68− for (i = 0; i < nr_legacy_irqs(); i++)
68+ for (i = 0; i < nr_legacy_irqs(); i++) {
6969 irq_set_chip_and_handler(i, chip, handle_level_irq);
70+ irq_set_status_flags(i, IRQ_LEVEL);
71+ }
7072 }
7173
7274 void __init init_IRQ(void)
arch/x86/pci/xen.c+2−0
@@ -392,6 +392,7 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev) · 391 unmodified lines
392392 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) {
393393 for (i = 0; i < msidesc->nvec_used; i++)
394394 xen_destroy_irq(msidesc->irq + i);
395+ msidesc->irq = 0;
395396 }
396397 }
397398
@@ -433,6 +434,7 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = { · 35 unmodified lines
433434 };
434435
435436 static struct msi_domain_info xen_pci_msi_domain_info = {
437+ .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS,
436438 .ops = &xen_pci_msi_domain_ops,
437439 };
438440
drivers/acpi/sleep.c+5−1
@@ -60,13 +60,17 @@ static struct notifier_block tts_notifier = { · 59 unmodified lines
6060 .priority = 0,
6161 };
6262
63+#ifndef acpi_skip_set_wakeup_address
64+#define acpi_skip_set_wakeup_address() false
65+#endif
66+
6367 static int acpi_sleep_prepare(u32 acpi_state)
6468 {
6569 #ifdef CONFIG_ACPI_SLEEP
6670 unsigned long acpi_wakeup_address;
6771
6872 /* do we have a wakeup address for S2 and S3? */
69− if (acpi_state == ACPI_STATE_S3) {
73+ if (acpi_state == ACPI_STATE_S3 && !acpi_skip_set_wakeup_address()) {
7074 acpi_wakeup_address = acpi_get_wakeup_address();
7175 if (!acpi_wakeup_address)
7276 return -EFAULT;