Skip to content

Commit

Permalink
Merge tag 'x86-urgent-2024-04-07' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:

 - Fix MCE timer reinit locking

 - Fix/improve CoCo guest random entropy pool init

 - Fix SEV-SNP late disable bugs

 - Fix false positive objtool build warning

 - Fix header dependency bug

 - Fix resctrl CPU offlining bug

* tag 'x86-urgent-2024-04-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/retpoline: Add NOENDBR annotation to the SRSO dummy return thunk
  x86/mce: Make sure to grab mce_sysfs_mutex in set_bank()
  x86/CPU/AMD: Track SNP host status with cc_platform_*()
  x86/cc: Add cc_platform_set/_clear() helpers
  x86/kvm/Kconfig: Have KVM_AMD_SEV select ARCH_HAS_CC_PLATFORM
  x86/coco: Require seeding RNG with RDRAND on CoCo systems
  x86/numa/32: Include missing <asm/pgtable_areas.h>
  x86/resctrl: Fix uninitialized memory read when last CPU of domain goes offline
  • Loading branch information
Linus Torvalds committed Apr 7, 2024
2 parents 3520c35 + b377c66 commit 9fe3084
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 41 deletions.
93 changes: 93 additions & 0 deletions arch/x86/coco/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@
* Confidential Computing Platform Capability checks
*
* Copyright (C) 2021 Advanced Micro Devices, Inc.
* Copyright (C) 2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*
* Author: Tom Lendacky <thomas.lendacky@amd.com>
*/

#include <linux/export.h>
#include <linux/cc_platform.h>
#include <linux/string.h>
#include <linux/random.h>

#include <asm/archrandom.h>
#include <asm/coco.h>
#include <asm/processor.h>

enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE;
u64 cc_mask __ro_after_init;

static struct cc_attr_flags {
__u64 host_sev_snp : 1,
__resv : 63;
} cc_flags;

static bool noinstr intel_cc_platform_has(enum cc_attr attr)
{
switch (attr) {
Expand Down Expand Up @@ -89,6 +98,9 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
case CC_ATTR_GUEST_SEV_SNP:
return sev_status & MSR_AMD64_SEV_SNP_ENABLED;

case CC_ATTR_HOST_SEV_SNP:
return cc_flags.host_sev_snp;

default:
return false;
}
Expand Down Expand Up @@ -148,3 +160,84 @@ u64 cc_mkdec(u64 val)
}
}
EXPORT_SYMBOL_GPL(cc_mkdec);

static void amd_cc_platform_clear(enum cc_attr attr)
{
switch (attr) {
case CC_ATTR_HOST_SEV_SNP:
cc_flags.host_sev_snp = 0;
break;
default:
break;
}
}

void cc_platform_clear(enum cc_attr attr)
{
switch (cc_vendor) {
case CC_VENDOR_AMD:
amd_cc_platform_clear(attr);
break;
default:
break;
}
}

static void amd_cc_platform_set(enum cc_attr attr)
{
switch (attr) {
case CC_ATTR_HOST_SEV_SNP:
cc_flags.host_sev_snp = 1;
break;
default:
break;
}
}

void cc_platform_set(enum cc_attr attr)
{
switch (cc_vendor) {
case CC_VENDOR_AMD:
amd_cc_platform_set(attr);
break;
default:
break;
}
}

__init void cc_random_init(void)
{
/*
* The seed is 32 bytes (in units of longs), which is 256 bits, which
* is the security level that the RNG is targeting.
*/
unsigned long rng_seed[32 / sizeof(long)];
size_t i, longs;

if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
return;

/*
* Since the CoCo threat model includes the host, the only reliable
* source of entropy that can be neither observed nor manipulated is
* RDRAND. Usually, RDRAND failure is considered tolerable, but since
* CoCo guests have no other unobservable source of entropy, it's
* important to at least ensure the RNG gets some initial random seeds.
*/
for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) {
longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i);

/*
* A zero return value means that the guest doesn't have RDRAND
* or the CPU is physically broken, and in both cases that
* means most crypto inside of the CoCo instance will be
* broken, defeating the purpose of CoCo in the first place. So
* just panic here because it's absolutely unsafe to continue
* executing.
*/
if (longs == 0)
panic("RDRAND is defective.");
}
add_device_randomness(rng_seed, sizeof(rng_seed));
memzero_explicit(rng_seed, sizeof(rng_seed));
}
2 changes: 2 additions & 0 deletions arch/x86/include/asm/coco.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static inline void cc_set_mask(u64 mask)

u64 cc_mkenc(u64 val);
u64 cc_mkdec(u64 val);
void cc_random_init(void);
#else
#define cc_vendor (CC_VENDOR_NONE)

Expand All @@ -34,6 +35,7 @@ static inline u64 cc_mkdec(u64 val)
{
return val;
}
static inline void cc_random_init(void) { }
#endif

#endif /* _ASM_X86_COCO_H */
4 changes: 2 additions & 2 deletions arch/x86/include/asm/sev.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct sn
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
u64 snp_get_unsupported_features(u64 status);
u64 sev_get_status(void);
void kdump_sev_callback(void);
void sev_show_status(void);
#else
static inline void sev_es_ist_enter(struct pt_regs *regs) { }
Expand Down Expand Up @@ -258,7 +257,6 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
static inline u64 sev_get_status(void) { return 0; }
static inline void kdump_sev_callback(void) { }
static inline void sev_show_status(void) { }
#endif

Expand All @@ -270,6 +268,7 @@ int psmash(u64 pfn);
int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid, bool immutable);
int rmp_make_shared(u64 pfn, enum pg_level level);
void snp_leak_pages(u64 pfn, unsigned int npages);
void kdump_sev_callback(void);
#else
static inline bool snp_probe_rmptable_info(void) { return false; }
static inline int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level) { return -ENODEV; }
Expand All @@ -282,6 +281,7 @@ static inline int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 as
}
static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV; }
static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
static inline void kdump_sev_callback(void) { }
#endif

#endif
38 changes: 23 additions & 15 deletions arch/x86/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,28 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
#endif
}

static void bsp_determine_snp(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
cc_vendor = CC_VENDOR_AMD;

if (cpu_has(c, X86_FEATURE_SEV_SNP)) {
/*
* RMP table entry format is not architectural and is defined by the
* per-processor PPR. Restrict SNP support on the known CPU models
* for which the RMP table entry format is currently defined for.
*/
if (!cpu_has(c, X86_FEATURE_HYPERVISOR) &&
c->x86 >= 0x19 && snp_probe_rmptable_info()) {
cc_platform_set(CC_ATTR_HOST_SEV_SNP);
} else {
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
}
}
#endif
}

static void bsp_init_amd(struct cpuinfo_x86 *c)
{
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
Expand Down Expand Up @@ -452,21 +474,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
break;
}

if (cpu_has(c, X86_FEATURE_SEV_SNP)) {
/*
* RMP table entry format is not architectural and it can vary by processor
* and is defined by the per-processor PPR. Restrict SNP support on the
* known CPU model and family for which the RMP table entry format is
* currently defined for.
*/
if (!boot_cpu_has(X86_FEATURE_ZEN3) &&
!boot_cpu_has(X86_FEATURE_ZEN4) &&
!boot_cpu_has(X86_FEATURE_ZEN5))
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
else if (!snp_probe_rmptable_info())
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
}

bsp_determine_snp(c);
return;

warn:
Expand Down
4 changes: 3 additions & 1 deletion arch/x86/kernel/cpu/mce/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2500,12 +2500,14 @@ static ssize_t set_bank(struct device *s, struct device_attribute *attr,
return -EINVAL;

b = &per_cpu(mce_banks_array, s->id)[bank];

if (!b->init)
return -ENODEV;

b->ctl = new;

mutex_lock(&mce_sysfs_mutex);
mce_restart();
mutex_unlock(&mce_sysfs_mutex);

return size;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/mtrr/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static inline void k8_check_syscfg_dram_mod_en(void)
(boot_cpu_data.x86 >= 0x0f)))
return;

if (cpu_feature_enabled(X86_FEATURE_SEV_SNP))
if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
return;

rdmsr(MSR_AMD64_SYSCFG, lo, hi);
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/kernel/cpu/resctrl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
else
cpu = cpumask_any_but(mask, exclude_cpu);

if (!IS_ENABLED(CONFIG_NO_HZ_FULL))
/* Only continue if tick_nohz_full_mask has been initialized. */
if (!tick_nohz_full_enabled())
return cpu;

/* If the CPU picked isn't marked nohz_full nothing more needs doing. */
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <asm/bios_ebda.h>
#include <asm/bugs.h>
#include <asm/cacheinfo.h>
#include <asm/coco.h>
#include <asm/cpu.h>
#include <asm/efi.h>
#include <asm/gart.h>
Expand Down Expand Up @@ -991,6 +992,7 @@ void __init setup_arch(char **cmdline_p)
* memory size.
*/
mem_encrypt_setup_arch();
cc_random_init();

efi_fake_memmap();
efi_find_mirror();
Expand Down
10 changes: 0 additions & 10 deletions arch/x86/kernel/sev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2284,16 +2284,6 @@ static int __init snp_init_platform_device(void)
}
device_initcall(snp_init_platform_device);

void kdump_sev_callback(void)
{
/*
* Do wbinvd() on remote CPUs when SNP is enabled in order to
* safely do SNP_SHUTDOWN on the local CPU.
*/
if (cpu_feature_enabled(X86_FEATURE_SEV_SNP))
wbinvd();
}

void sev_show_status(void)
{
int i;
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kvm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ config KVM_AMD_SEV
default y
depends on KVM_AMD && X86_64
depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m)
select ARCH_HAS_CC_PLATFORM
help
Provides support for launching Encrypted VMs (SEV) and Encrypted VMs
with Encrypted State (SEV-ES) on AMD processors.
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kvm/svm/sev.c
Original file line number Diff line number Diff line change
Expand Up @@ -3184,7 +3184,7 @@ struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
unsigned long pfn;
struct page *p;

if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
return alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);

/*
Expand Down
1 change: 1 addition & 0 deletions arch/x86/lib/retpoline.S
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ SYM_CODE_END(srso_return_thunk)
/* Dummy for the alternative in CALL_UNTRAIN_RET. */
SYM_CODE_START(srso_alias_untrain_ret)
ANNOTATE_UNRET_SAFE
ANNOTATE_NOENDBR
ret
int3
SYM_FUNC_END(srso_alias_untrain_ret)
Expand Down
1 change: 1 addition & 0 deletions arch/x86/mm/numa_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <linux/memblock.h>
#include <linux/init.h>
#include <asm/pgtable_areas.h>

#include "numa_internal.h"

Expand Down
Loading

0 comments on commit 9fe3084

Please sign in to comment.