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
95not enable SME, then Linux will not be able to activate memory encryption, even95not enable SME, then Linux will not be able to activate memory encryption, even
96if configured to do so by default or the mem_encrypt=on command line parameter96if configured to do so by default or the mem_encrypt=on command line parameter
97is specified.97is specified.
98
99Secure Nested Paging (SNP)
100==========================
101
102SEV-SNP introduces new features (SEV_FEATURES[1:63]) which can be enabled
103by the hypervisor for security enhancements. Some of these features need
104guest side implementation to function correctly. The below table lists the
105expected guest behavior with various possible scenarios of guest/hypervisor
106SNP 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
131More 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
14 14
15ifdef CONFIG_CC_IS_GCC15ifdef CONFIG_CC_IS_GCC
16RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)16RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
17RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
18RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register)17RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register)
19endif18endif
20ifdef CONFIG_CC_IS_CLANG19ifdef CONFIG_CC_IS_CLANG
21RETPOLINE_CFLAGS := -mretpoline-external-thunk20RETPOLINE_CFLAGS := -mretpoline-external-thunk
22RETPOLINE_VDSO_CFLAGS := -mretpoline21RETPOLINE_VDSO_CFLAGS := -mretpoline
23endif22endif
23RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
24 24
25ifdef CONFIG_RETHUNK25ifdef CONFIG_RETHUNK
26RETHUNK_CFLAGS := -mfunction-return=thunk-extern26RETHUNK_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
180 180
181 /* Load the new page-table. */181 /* Load the new page-table. */
182 write_cr3(top_level_pgt);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();
183}189}
184 190
185static pte_t *split_large_pmd(struct x86_mapping_info *info,191static 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
126 126
127#ifdef CONFIG_AMD_MEM_ENCRYPT127#ifdef CONFIG_AMD_MEM_ENCRYPT
128void sev_enable(struct boot_params *bp);128void sev_enable(struct boot_params *bp);
129void snp_check_features(void);
129void sev_es_shutdown_ghcb(void);130void sev_es_shutdown_ghcb(void);
130extern bool sev_es_check_ghcb_fault(unsigned long address);131extern bool sev_es_check_ghcb_fault(unsigned long address);
131void snp_set_page_private(unsigned long paddr);132void snp_set_page_private(unsigned long paddr);
@@ -143,6 +144,7 @@ static inline void sev_enable(struct boot_params *bp) · 11 unmodified lines
143 if (bp)144 if (bp)
144 bp->cc_blob_address = 0;145 bp->cc_blob_address = 0;
145}146}
147static inline void snp_check_features(void) { }
146static inline void sev_es_shutdown_ghcb(void) { }148static inline void sev_es_shutdown_ghcb(void) { }
147static inline bool sev_es_check_ghcb_fault(unsigned long address)149static inline bool sev_es_check_ghcb_fault(unsigned long address)
148{150{
arch/x86/boot/compressed/sev.c+70−0
@@ -208,6 +208,23 @@ void sev_es_shutdown_ghcb(void) · 207 unmodified lines
208 error("Can't unmap GHCB page");208 error("Can't unmap GHCB page");
209}209}
210 210
211static 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
211bool sev_es_check_ghcb_fault(unsigned long address)228bool sev_es_check_ghcb_fault(unsigned long address)
212{229{
213 /* Check whether the fault was on the GHCB page */230 /* Check whether the fault was on the GHCB page */
@@ -270,6 +287,59 @@ static void enforce_vmpl0(void) · 56 unmodified lines
270 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);287 sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
271}288}
272 289
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
320void 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
273void sev_enable(struct boot_params *bp)343void sev_enable(struct boot_params *bp)
274{344{
275 unsigned int eax, ebx, ecx, edx;345 unsigned int eax, ebx, ecx, edx;
arch/x86/include/asm/acpi.h+8−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <asm/mmu.h>14#include <asm/mmu.h>
15#include <asm/mpspec.h>15#include <asm/mpspec.h>
16#include <asm/x86_init.h>16#include <asm/x86_init.h>
17#include <asm/cpufeature.h>
17 18
18#ifdef CONFIG_ACPI_APEI19#ifdef CONFIG_ACPI_APEI
19# include <asm/pgtable_types.h>20# include <asm/pgtable_types.h>
@@ -63,6 +64,13 @@ extern int (*acpi_suspend_lowlevel)(void); · 43 unmodified lines
63/* Physical address to resume after wakeup */64/* Physical address to resume after wakeup */
64unsigned long acpi_get_wakeup_address(void);65unsigned long acpi_get_wakeup_address(void);
65 66
67static 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
66/*74/*
67 * Check if the CPU can handle C2 and deeper75 * Check if the CPU can handle C2 and deeper
68 */76 */
arch/x86/include/asm/msr-index.h+20−0
@@ -566,6 +566,26 @@ · 565 unmodified lines
566#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)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)567#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT)
568 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
569#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f589#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
570 590
571/* AMD Collaborative Processor Performance Control MSRs */591/* AMD Collaborative Processor Performance Control MSRs */
arch/x86/include/uapi/asm/svm.h+6−0
@@ -116,6 +116,12 @@ · 115 unmodified lines
116#define SVM_VMGEXIT_AP_CREATE 1116#define SVM_VMGEXIT_AP_CREATE 1
117#define SVM_VMGEXIT_AP_DESTROY 2117#define SVM_VMGEXIT_AP_DESTROY 2
118#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd118#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))
119#define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff125#define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff
120 126
121/* Exit code reserved for hypervisor/software use */127/* 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
114 disable_irq_nosync(irq);114 disable_irq_nosync(irq);
115 io_apic_irqs &= ~(1<<irq);115 io_apic_irqs &= ~(1<<irq);
116 irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);116 irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
117 irq_set_status_flags(irq, IRQ_LEVEL);
117 enable_irq(irq);118 enable_irq(irq);
118 lapic_assign_legacy_vector(irq, true);119 lapic_assign_legacy_vector(irq, true);
119}120}
arch/x86/kernel/irqinit.c+3−1
@@ -65,8 +65,10 @@ void __init init_ISA_irqs(void) · 64 unmodified lines
65 65
66 legacy_pic->init(0);66 legacy_pic->init(0);
67 67
68 for (i = 0; i < nr_legacy_irqs(); i++)68 for (i = 0; i < nr_legacy_irqs(); i++) {
69 irq_set_chip_and_handler(i, chip, handle_level_irq);69 irq_set_chip_and_handler(i, chip, handle_level_irq);
70 irq_set_status_flags(i, IRQ_LEVEL);
71 }
70}72}
71 73
72void __init init_IRQ(void)74void __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
392 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) {392 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) {
393 for (i = 0; i < msidesc->nvec_used; i++)393 for (i = 0; i < msidesc->nvec_used; i++)
394 xen_destroy_irq(msidesc->irq + i);394 xen_destroy_irq(msidesc->irq + i);
395 msidesc->irq = 0;
395 }396 }
396}397}
397 398
@@ -433,6 +434,7 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = { · 35 unmodified lines
433};434};
434 435
435static struct msi_domain_info xen_pci_msi_domain_info = {436static struct msi_domain_info xen_pci_msi_domain_info = {
437 .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS,
436 .ops = &xen_pci_msi_domain_ops,438 .ops = &xen_pci_msi_domain_ops,
437};439};
438 440
drivers/acpi/sleep.c+5−1
@@ -60,13 +60,17 @@ static struct notifier_block tts_notifier = { · 59 unmodified lines
60 .priority = 0,60 .priority = 0,
61};61};
62 62
63#ifndef acpi_skip_set_wakeup_address
64#define acpi_skip_set_wakeup_address() false
65#endif
66
63static int acpi_sleep_prepare(u32 acpi_state)67static int acpi_sleep_prepare(u32 acpi_state)
64{68{
65#ifdef CONFIG_ACPI_SLEEP69#ifdef CONFIG_ACPI_SLEEP
66 unsigned long acpi_wakeup_address;70 unsigned long acpi_wakeup_address;
67 71
68 /* do we have a wakeup address for S2 and S3? */72 /* 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()) {
70 acpi_wakeup_address = acpi_get_wakeup_address();74 acpi_wakeup_address = acpi_get_wakeup_address();
71 if (!acpi_wakeup_address)75 if (!acpi_wakeup_address)
72 return -EFAULT;76 return -EFAULT;