- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmPWdaAACgkQEsHwGGHe VUrHUBAAvRh7cDVKvr2wPNJ+9RFjPFubcLq/+4yTe4Bu14wnYn8+gb2S7P2bPJWl TxbZhJGV2IeYyB+aJybjGwX96AzE5lWD6epQLRLI/BOVmqLA8Eyw9te0NEQDd9Wq hgY1/hhUmLdpXubq09YjIht5nlxVZ+JFfppouTR7LVtZl7MFvQbAOU8rWzpcbm7l UlA4GLakFeOYpbI5g+zzsZ1a1M0cSz8wQ43plD5aAtNy2wKbWiA4QDXJo9J7+ZQg 1FmOHZ3ChPjEhf9k/N2uAZ6RUHVEDIJ7hDfsM3j/qsKGzCV4cho2Ify+0PFWo4pt FO2bRh1yDFqdz4m6ulhnmuMnoRnEuswwrTzrG+HYu1ntpUt72dULmmRBpJ0s6C7W BHpCThNWIlcfHbLNY+VAOJ2hiOqfU/8ld+8R0sn7xmomjgCRYHh9kDGOeuvh1hJl jfITDuL2gjcj3Ph6+xh6KvOga41ff3EcxkfvqolZ/emRllPiDWsKYXVgUIl22FHt 23xH7gutPCp27MdoXM1EaWs5s/PQfctvm4LrW6XS8IjWURLo4RrkU6y7YD5VKVy8 KCKcpF+JMdE1Ao1WpMFfjDG4ObyMYyqnD790nQVM1e5kIhOpeWaa7WzkGFRyIo6Q 5BU3GGDyMT8SHy7NFhQL62YJe0P2ZctNIDjiTQlYDnWWhjmvk8I= =4QMN -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
bc6bc34b10
@ -95,3 +95,39 @@ by supplying mem_encrypt=on on the kernel command line. However, if BIOS does
|
||||
not enable SME, then Linux will not be able to activate memory encryption, even
|
||||
if configured to do so by default or the mem_encrypt=on command line parameter
|
||||
is specified.
|
||||
|
||||
Secure Nested Paging (SNP)
|
||||
==========================
|
||||
|
||||
SEV-SNP introduces new features (SEV_FEATURES[1:63]) which can be enabled
|
||||
by the hypervisor for security enhancements. Some of these features need
|
||||
guest side implementation to function correctly. The below table lists the
|
||||
expected guest behavior with various possible scenarios of guest/hypervisor
|
||||
SNP feature support.
|
||||
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
| Feature Enabled | Guest needs | Guest has | Guest boot |
|
||||
| by the HV | implementation| implementation| behaviour |
|
||||
+=================+===============+===============+==================+
|
||||
| No | No | No | Boot |
|
||||
| | | | |
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
| No | Yes | No | Boot |
|
||||
| | | | |
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
| No | Yes | Yes | Boot |
|
||||
| | | | |
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
| Yes | No | No | Boot with |
|
||||
| | | | feature enabled |
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
| Yes | Yes | No | Graceful boot |
|
||||
| | | | failure |
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
| Yes | Yes | Yes | Boot with |
|
||||
| | | | feature enabled |
|
||||
+-----------------+---------------+---------------+------------------+
|
||||
|
||||
More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR
|
||||
|
||||
[1] https://www.amd.com/system/files/TechDocs/40332.pdf
|
||||
|
@ -14,13 +14,13 @@ endif
|
||||
|
||||
ifdef CONFIG_CC_IS_GCC
|
||||
RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
|
||||
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
|
||||
RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register)
|
||||
endif
|
||||
ifdef CONFIG_CC_IS_CLANG
|
||||
RETPOLINE_CFLAGS := -mretpoline-external-thunk
|
||||
RETPOLINE_VDSO_CFLAGS := -mretpoline
|
||||
endif
|
||||
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
|
||||
|
||||
ifdef CONFIG_RETHUNK
|
||||
RETHUNK_CFLAGS := -mfunction-return=thunk-extern
|
||||
|
@ -180,6 +180,12 @@ void initialize_identity_maps(void *rmode)
|
||||
|
||||
/* Load the new page-table. */
|
||||
write_cr3(top_level_pgt);
|
||||
|
||||
/*
|
||||
* Now that the required page table mappings are established and a
|
||||
* GHCB can be used, check for SNP guest/HV feature compatibility.
|
||||
*/
|
||||
snp_check_features();
|
||||
}
|
||||
|
||||
static pte_t *split_large_pmd(struct x86_mapping_info *info,
|
||||
|
@ -126,6 +126,7 @@ static inline void console_init(void)
|
||||
|
||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||
void sev_enable(struct boot_params *bp);
|
||||
void snp_check_features(void);
|
||||
void sev_es_shutdown_ghcb(void);
|
||||
extern bool sev_es_check_ghcb_fault(unsigned long address);
|
||||
void snp_set_page_private(unsigned long paddr);
|
||||
@ -143,6 +144,7 @@ static inline void sev_enable(struct boot_params *bp)
|
||||
if (bp)
|
||||
bp->cc_blob_address = 0;
|
||||
}
|
||||
static inline void snp_check_features(void) { }
|
||||
static inline void sev_es_shutdown_ghcb(void) { }
|
||||
static inline bool sev_es_check_ghcb_fault(unsigned long address)
|
||||
{
|
||||
|
@ -208,6 +208,23 @@ void sev_es_shutdown_ghcb(void)
|
||||
error("Can't unmap GHCB page");
|
||||
}
|
||||
|
||||
static void __noreturn sev_es_ghcb_terminate(struct ghcb *ghcb, unsigned int set,
|
||||
unsigned int reason, u64 exit_info_2)
|
||||
{
|
||||
u64 exit_info_1 = SVM_VMGEXIT_TERM_REASON(set, reason);
|
||||
|
||||
vc_ghcb_invalidate(ghcb);
|
||||
ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_TERM_REQUEST);
|
||||
ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
|
||||
ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
|
||||
|
||||
sev_es_wr_ghcb_msr(__pa(ghcb));
|
||||
VMGEXIT();
|
||||
|
||||
while (true)
|
||||
asm volatile("hlt\n" : : : "memory");
|
||||
}
|
||||
|
||||
bool sev_es_check_ghcb_fault(unsigned long address)
|
||||
{
|
||||
/* Check whether the fault was on the GHCB page */
|
||||
@ -270,6 +287,59 @@ static void enforce_vmpl0(void)
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SNP_FEATURES_IMPL_REQ is the mask of SNP features that will need
|
||||
* guest side implementation for proper functioning of the guest. If any
|
||||
* of these features are enabled in the hypervisor but are lacking guest
|
||||
* side implementation, the behavior of the guest will be undefined. The
|
||||
* guest could fail in non-obvious way making it difficult to debug.
|
||||
*
|
||||
* As the behavior of reserved feature bits is unknown to be on the
|
||||
* safe side add them to the required features mask.
|
||||
*/
|
||||
#define SNP_FEATURES_IMPL_REQ (MSR_AMD64_SNP_VTOM | \
|
||||
MSR_AMD64_SNP_REFLECT_VC | \
|
||||
MSR_AMD64_SNP_RESTRICTED_INJ | \
|
||||
MSR_AMD64_SNP_ALT_INJ | \
|
||||
MSR_AMD64_SNP_DEBUG_SWAP | \
|
||||
MSR_AMD64_SNP_VMPL_SSS | \
|
||||
MSR_AMD64_SNP_SECURE_TSC | \
|
||||
MSR_AMD64_SNP_VMGEXIT_PARAM | \
|
||||
MSR_AMD64_SNP_VMSA_REG_PROTECTION | \
|
||||
MSR_AMD64_SNP_RESERVED_BIT13 | \
|
||||
MSR_AMD64_SNP_RESERVED_BIT15 | \
|
||||
MSR_AMD64_SNP_RESERVED_MASK)
|
||||
|
||||
/*
|
||||
* SNP_FEATURES_PRESENT is the mask of SNP features that are implemented
|
||||
* by the guest kernel. As and when a new feature is implemented in the
|
||||
* guest kernel, a corresponding bit should be added to the mask.
|
||||
*/
|
||||
#define SNP_FEATURES_PRESENT (0)
|
||||
|
||||
void snp_check_features(void)
|
||||
{
|
||||
u64 unsupported;
|
||||
|
||||
if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Terminate the boot if hypervisor has enabled any feature lacking
|
||||
* guest side implementation. Pass on the unsupported features mask through
|
||||
* EXIT_INFO_2 of the GHCB protocol so that those features can be reported
|
||||
* as part of the guest boot failure.
|
||||
*/
|
||||
unsupported = sev_status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT;
|
||||
if (unsupported) {
|
||||
if (ghcb_version < 2 || (!boot_ghcb && !early_setup_ghcb()))
|
||||
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
|
||||
|
||||
sev_es_ghcb_terminate(boot_ghcb, SEV_TERM_SET_GEN,
|
||||
GHCB_SNP_UNSUPPORTED, unsupported);
|
||||
}
|
||||
}
|
||||
|
||||
void sev_enable(struct boot_params *bp)
|
||||
{
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/x86_init.h>
|
||||
#include <asm/cpufeature.h>
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI
|
||||
# include <asm/pgtable_types.h>
|
||||
@ -63,6 +64,13 @@ extern int (*acpi_suspend_lowlevel)(void);
|
||||
/* Physical address to resume after wakeup */
|
||||
unsigned long acpi_get_wakeup_address(void);
|
||||
|
||||
static inline bool acpi_skip_set_wakeup_address(void)
|
||||
{
|
||||
return cpu_feature_enabled(X86_FEATURE_XENPV);
|
||||
}
|
||||
|
||||
#define acpi_skip_set_wakeup_address acpi_skip_set_wakeup_address
|
||||
|
||||
/*
|
||||
* Check if the CPU can handle C2 and deeper
|
||||
*/
|
||||
|
@ -566,6 +566,26 @@
|
||||
#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)
|
||||
#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT)
|
||||
|
||||
/* SNP feature bits enabled by the hypervisor */
|
||||
#define MSR_AMD64_SNP_VTOM BIT_ULL(3)
|
||||
#define MSR_AMD64_SNP_REFLECT_VC BIT_ULL(4)
|
||||
#define MSR_AMD64_SNP_RESTRICTED_INJ BIT_ULL(5)
|
||||
#define MSR_AMD64_SNP_ALT_INJ BIT_ULL(6)
|
||||
#define MSR_AMD64_SNP_DEBUG_SWAP BIT_ULL(7)
|
||||
#define MSR_AMD64_SNP_PREVENT_HOST_IBS BIT_ULL(8)
|
||||
#define MSR_AMD64_SNP_BTB_ISOLATION BIT_ULL(9)
|
||||
#define MSR_AMD64_SNP_VMPL_SSS BIT_ULL(10)
|
||||
#define MSR_AMD64_SNP_SECURE_TSC BIT_ULL(11)
|
||||
#define MSR_AMD64_SNP_VMGEXIT_PARAM BIT_ULL(12)
|
||||
#define MSR_AMD64_SNP_IBS_VIRT BIT_ULL(14)
|
||||
#define MSR_AMD64_SNP_VMSA_REG_PROTECTION BIT_ULL(16)
|
||||
#define MSR_AMD64_SNP_SMT_PROTECTION BIT_ULL(17)
|
||||
|
||||
/* SNP feature bits reserved for future use. */
|
||||
#define MSR_AMD64_SNP_RESERVED_BIT13 BIT_ULL(13)
|
||||
#define MSR_AMD64_SNP_RESERVED_BIT15 BIT_ULL(15)
|
||||
#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, 18)
|
||||
|
||||
#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
|
||||
|
||||
/* AMD Collaborative Processor Performance Control MSRs */
|
||||
|
@ -116,6 +116,12 @@
|
||||
#define SVM_VMGEXIT_AP_CREATE 1
|
||||
#define SVM_VMGEXIT_AP_DESTROY 2
|
||||
#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
|
||||
#define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe
|
||||
#define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code) \
|
||||
/* SW_EXITINFO1[3:0] */ \
|
||||
(((((u64)reason_set) & 0xf)) | \
|
||||
/* SW_EXITINFO1[11:4] */ \
|
||||
((((u64)reason_code) & 0xff) << 4))
|
||||
#define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff
|
||||
|
||||
/* Exit code reserved for hypervisor/software use */
|
||||
|
@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int irq)
|
||||
disable_irq_nosync(irq);
|
||||
io_apic_irqs &= ~(1<<irq);
|
||||
irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
|
||||
irq_set_status_flags(irq, IRQ_LEVEL);
|
||||
enable_irq(irq);
|
||||
lapic_assign_legacy_vector(irq, true);
|
||||
}
|
||||
|
@ -65,8 +65,10 @@ void __init init_ISA_irqs(void)
|
||||
|
||||
legacy_pic->init(0);
|
||||
|
||||
for (i = 0; i < nr_legacy_irqs(); i++)
|
||||
for (i = 0; i < nr_legacy_irqs(); i++) {
|
||||
irq_set_chip_and_handler(i, chip, handle_level_irq);
|
||||
irq_set_status_flags(i, IRQ_LEVEL);
|
||||
}
|
||||
}
|
||||
|
||||
void __init init_IRQ(void)
|
||||
|
@ -392,6 +392,7 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
|
||||
msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) {
|
||||
for (i = 0; i < msidesc->nvec_used; i++)
|
||||
xen_destroy_irq(msidesc->irq + i);
|
||||
msidesc->irq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,6 +434,7 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = {
|
||||
};
|
||||
|
||||
static struct msi_domain_info xen_pci_msi_domain_info = {
|
||||
.flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS,
|
||||
.ops = &xen_pci_msi_domain_ops,
|
||||
};
|
||||
|
||||
|
@ -60,13 +60,17 @@ static struct notifier_block tts_notifier = {
|
||||
.priority = 0,
|
||||
};
|
||||
|
||||
#ifndef acpi_skip_set_wakeup_address
|
||||
#define acpi_skip_set_wakeup_address() false
|
||||
#endif
|
||||
|
||||
static int acpi_sleep_prepare(u32 acpi_state)
|
||||
{
|
||||
#ifdef CONFIG_ACPI_SLEEP
|
||||
unsigned long acpi_wakeup_address;
|
||||
|
||||
/* do we have a wakeup address for S2 and S3? */
|
||||
if (acpi_state == ACPI_STATE_S3) {
|
||||
if (acpi_state == ACPI_STATE_S3 && !acpi_skip_set_wakeup_address()) {
|
||||
acpi_wakeup_address = acpi_get_wakeup_address();
|
||||
if (!acpi_wakeup_address)
|
||||
return -EFAULT;
|
||||
|
Loading…
Reference in New Issue
Block a user