Skip to content

Commit bc6bc34

Browse files
committed
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
2 parents 80826e9 + 27b5de6 commit bc6bc34

File tree

12 files changed

+160
-3
lines changed

12 files changed

+160
-3
lines changed

Documentation/x86/amd-memory-encryption.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,39 @@ by supplying mem_encrypt=on on the kernel command line. However, if BIOS does
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ endif
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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,12 @@ void initialize_identity_maps(void *rmode)
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ static inline void console_init(void)
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)
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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,23 @@ void sev_es_shutdown_ghcb(void)
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)
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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
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);
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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,26 @@
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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int irq)
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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ void __init init_ISA_irqs(void)
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)

0 commit comments

Comments
 (0)