mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
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:
@@ -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
|
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
|
if configured to do so by default or the mem_encrypt=on command line parameter
|
||||||
is specified.
|
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
|
ifdef CONFIG_CC_IS_GCC
|
||||||
RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
|
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)
|
RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register)
|
||||||
endif
|
endif
|
||||||
ifdef CONFIG_CC_IS_CLANG
|
ifdef CONFIG_CC_IS_CLANG
|
||||||
RETPOLINE_CFLAGS := -mretpoline-external-thunk
|
RETPOLINE_CFLAGS := -mretpoline-external-thunk
|
||||||
RETPOLINE_VDSO_CFLAGS := -mretpoline
|
RETPOLINE_VDSO_CFLAGS := -mretpoline
|
||||||
endif
|
endif
|
||||||
|
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
|
||||||
|
|
||||||
ifdef CONFIG_RETHUNK
|
ifdef CONFIG_RETHUNK
|
||||||
RETHUNK_CFLAGS := -mfunction-return=thunk-extern
|
RETHUNK_CFLAGS := -mfunction-return=thunk-extern
|
||||||
|
@@ -180,6 +180,12 @@ void initialize_identity_maps(void *rmode)
|
|||||||
|
|
||||||
/* Load the new page-table. */
|
/* Load the new page-table. */
|
||||||
write_cr3(top_level_pgt);
|
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,
|
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
|
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||||
void sev_enable(struct boot_params *bp);
|
void sev_enable(struct boot_params *bp);
|
||||||
|
void snp_check_features(void);
|
||||||
void sev_es_shutdown_ghcb(void);
|
void sev_es_shutdown_ghcb(void);
|
||||||
extern bool sev_es_check_ghcb_fault(unsigned long address);
|
extern bool sev_es_check_ghcb_fault(unsigned long address);
|
||||||
void snp_set_page_private(unsigned long paddr);
|
void snp_set_page_private(unsigned long paddr);
|
||||||
@@ -143,6 +144,7 @@ static inline void sev_enable(struct boot_params *bp)
|
|||||||
if (bp)
|
if (bp)
|
||||||
bp->cc_blob_address = 0;
|
bp->cc_blob_address = 0;
|
||||||
}
|
}
|
||||||
|
static inline void snp_check_features(void) { }
|
||||||
static inline void sev_es_shutdown_ghcb(void) { }
|
static inline void sev_es_shutdown_ghcb(void) { }
|
||||||
static inline bool sev_es_check_ghcb_fault(unsigned long address)
|
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");
|
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)
|
bool sev_es_check_ghcb_fault(unsigned long address)
|
||||||
{
|
{
|
||||||
/* Check whether the fault was on the GHCB page */
|
/* 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);
|
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)
|
void sev_enable(struct boot_params *bp)
|
||||||
{
|
{
|
||||||
unsigned int eax, ebx, ecx, edx;
|
unsigned int eax, ebx, ecx, edx;
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/x86_init.h>
|
#include <asm/x86_init.h>
|
||||||
|
#include <asm/cpufeature.h>
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_APEI
|
#ifdef CONFIG_ACPI_APEI
|
||||||
# include <asm/pgtable_types.h>
|
# include <asm/pgtable_types.h>
|
||||||
@@ -63,6 +64,13 @@ extern int (*acpi_suspend_lowlevel)(void);
|
|||||||
/* Physical address to resume after wakeup */
|
/* Physical address to resume after wakeup */
|
||||||
unsigned long acpi_get_wakeup_address(void);
|
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
|
* 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_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)
|
||||||
#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_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
|
#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
|
||||||
|
|
||||||
/* AMD Collaborative Processor Performance Control MSRs */
|
/* AMD Collaborative Processor Performance Control MSRs */
|
||||||
|
@@ -116,6 +116,12 @@
|
|||||||
#define SVM_VMGEXIT_AP_CREATE 1
|
#define SVM_VMGEXIT_AP_CREATE 1
|
||||||
#define SVM_VMGEXIT_AP_DESTROY 2
|
#define SVM_VMGEXIT_AP_DESTROY 2
|
||||||
#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
|
#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
|
#define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff
|
||||||
|
|
||||||
/* Exit code reserved for hypervisor/software use */
|
/* Exit code reserved for hypervisor/software use */
|
||||||
|
@@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int irq)
|
|||||||
disable_irq_nosync(irq);
|
disable_irq_nosync(irq);
|
||||||
io_apic_irqs &= ~(1<<irq);
|
io_apic_irqs &= ~(1<<irq);
|
||||||
irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
|
irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
|
||||||
|
irq_set_status_flags(irq, IRQ_LEVEL);
|
||||||
enable_irq(irq);
|
enable_irq(irq);
|
||||||
lapic_assign_legacy_vector(irq, true);
|
lapic_assign_legacy_vector(irq, true);
|
||||||
}
|
}
|
||||||
|
@@ -65,8 +65,10 @@ void __init init_ISA_irqs(void)
|
|||||||
|
|
||||||
legacy_pic->init(0);
|
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_chip_and_handler(i, chip, handle_level_irq);
|
||||||
|
irq_set_status_flags(i, IRQ_LEVEL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init init_IRQ(void)
|
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) {
|
msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) {
|
||||||
for (i = 0; i < msidesc->nvec_used; i++)
|
for (i = 0; i < msidesc->nvec_used; i++)
|
||||||
xen_destroy_irq(msidesc->irq + 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 = {
|
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,
|
.ops = &xen_pci_msi_domain_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -60,13 +60,17 @@ static struct notifier_block tts_notifier = {
|
|||||||
.priority = 0,
|
.priority = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef acpi_skip_set_wakeup_address
|
||||||
|
#define acpi_skip_set_wakeup_address() false
|
||||||
|
#endif
|
||||||
|
|
||||||
static int acpi_sleep_prepare(u32 acpi_state)
|
static int acpi_sleep_prepare(u32 acpi_state)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ACPI_SLEEP
|
#ifdef CONFIG_ACPI_SLEEP
|
||||||
unsigned long acpi_wakeup_address;
|
unsigned long acpi_wakeup_address;
|
||||||
|
|
||||||
/* do we have a wakeup address for S2 and S3? */
|
/* 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();
|
acpi_wakeup_address = acpi_get_wakeup_address();
|
||||||
if (!acpi_wakeup_address)
|
if (!acpi_wakeup_address)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
Reference in New Issue
Block a user