Skip to content

Commit 9fe3084

Browse files
committed
Merge tag 'x86-urgent-2024-04-07' of git://git.kernel.org/pub/scm/linux/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
2 parents 3520c35 + b377c66 commit 9fe3084

File tree

17 files changed

+166
-41
lines changed

17 files changed

+166
-41
lines changed

arch/x86/coco/core.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,28 @@
33
* Confidential Computing Platform Capability checks
44
*
55
* Copyright (C) 2021 Advanced Micro Devices, Inc.
6+
* Copyright (C) 2024 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
67
*
78
* Author: Tom Lendacky <[email protected]>
89
*/
910

1011
#include <linux/export.h>
1112
#include <linux/cc_platform.h>
13+
#include <linux/string.h>
14+
#include <linux/random.h>
1215

16+
#include <asm/archrandom.h>
1317
#include <asm/coco.h>
1418
#include <asm/processor.h>
1519

1620
enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE;
1721
u64 cc_mask __ro_after_init;
1822

23+
static struct cc_attr_flags {
24+
__u64 host_sev_snp : 1,
25+
__resv : 63;
26+
} cc_flags;
27+
1928
static bool noinstr intel_cc_platform_has(enum cc_attr attr)
2029
{
2130
switch (attr) {
@@ -89,6 +98,9 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
8998
case CC_ATTR_GUEST_SEV_SNP:
9099
return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
91100

101+
case CC_ATTR_HOST_SEV_SNP:
102+
return cc_flags.host_sev_snp;
103+
92104
default:
93105
return false;
94106
}
@@ -148,3 +160,84 @@ u64 cc_mkdec(u64 val)
148160
}
149161
}
150162
EXPORT_SYMBOL_GPL(cc_mkdec);
163+
164+
static void amd_cc_platform_clear(enum cc_attr attr)
165+
{
166+
switch (attr) {
167+
case CC_ATTR_HOST_SEV_SNP:
168+
cc_flags.host_sev_snp = 0;
169+
break;
170+
default:
171+
break;
172+
}
173+
}
174+
175+
void cc_platform_clear(enum cc_attr attr)
176+
{
177+
switch (cc_vendor) {
178+
case CC_VENDOR_AMD:
179+
amd_cc_platform_clear(attr);
180+
break;
181+
default:
182+
break;
183+
}
184+
}
185+
186+
static void amd_cc_platform_set(enum cc_attr attr)
187+
{
188+
switch (attr) {
189+
case CC_ATTR_HOST_SEV_SNP:
190+
cc_flags.host_sev_snp = 1;
191+
break;
192+
default:
193+
break;
194+
}
195+
}
196+
197+
void cc_platform_set(enum cc_attr attr)
198+
{
199+
switch (cc_vendor) {
200+
case CC_VENDOR_AMD:
201+
amd_cc_platform_set(attr);
202+
break;
203+
default:
204+
break;
205+
}
206+
}
207+
208+
__init void cc_random_init(void)
209+
{
210+
/*
211+
* The seed is 32 bytes (in units of longs), which is 256 bits, which
212+
* is the security level that the RNG is targeting.
213+
*/
214+
unsigned long rng_seed[32 / sizeof(long)];
215+
size_t i, longs;
216+
217+
if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
218+
return;
219+
220+
/*
221+
* Since the CoCo threat model includes the host, the only reliable
222+
* source of entropy that can be neither observed nor manipulated is
223+
* RDRAND. Usually, RDRAND failure is considered tolerable, but since
224+
* CoCo guests have no other unobservable source of entropy, it's
225+
* important to at least ensure the RNG gets some initial random seeds.
226+
*/
227+
for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) {
228+
longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i);
229+
230+
/*
231+
* A zero return value means that the guest doesn't have RDRAND
232+
* or the CPU is physically broken, and in both cases that
233+
* means most crypto inside of the CoCo instance will be
234+
* broken, defeating the purpose of CoCo in the first place. So
235+
* just panic here because it's absolutely unsafe to continue
236+
* executing.
237+
*/
238+
if (longs == 0)
239+
panic("RDRAND is defective.");
240+
}
241+
add_device_randomness(rng_seed, sizeof(rng_seed));
242+
memzero_explicit(rng_seed, sizeof(rng_seed));
243+
}

arch/x86/include/asm/coco.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static inline void cc_set_mask(u64 mask)
2222

2323
u64 cc_mkenc(u64 val);
2424
u64 cc_mkdec(u64 val);
25+
void cc_random_init(void);
2526
#else
2627
#define cc_vendor (CC_VENDOR_NONE)
2728

@@ -34,6 +35,7 @@ static inline u64 cc_mkdec(u64 val)
3435
{
3536
return val;
3637
}
38+
static inline void cc_random_init(void) { }
3739
#endif
3840

3941
#endif /* _ASM_X86_COCO_H */

arch/x86/include/asm/sev.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct sn
228228
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
229229
u64 snp_get_unsupported_features(u64 status);
230230
u64 sev_get_status(void);
231-
void kdump_sev_callback(void);
232231
void sev_show_status(void);
233232
#else
234233
static inline void sev_es_ist_enter(struct pt_regs *regs) { }
@@ -258,7 +257,6 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
258257
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
259258
static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
260259
static inline u64 sev_get_status(void) { return 0; }
261-
static inline void kdump_sev_callback(void) { }
262260
static inline void sev_show_status(void) { }
263261
#endif
264262

@@ -270,6 +268,7 @@ int psmash(u64 pfn);
270268
int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid, bool immutable);
271269
int rmp_make_shared(u64 pfn, enum pg_level level);
272270
void snp_leak_pages(u64 pfn, unsigned int npages);
271+
void kdump_sev_callback(void);
273272
#else
274273
static inline bool snp_probe_rmptable_info(void) { return false; }
275274
static inline int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level) { return -ENODEV; }
@@ -282,6 +281,7 @@ static inline int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 as
282281
}
283282
static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV; }
284283
static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
284+
static inline void kdump_sev_callback(void) { }
285285
#endif
286286

287287
#endif

arch/x86/kernel/cpu/amd.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,28 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
345345
#endif
346346
}
347347

348+
static void bsp_determine_snp(struct cpuinfo_x86 *c)
349+
{
350+
#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
351+
cc_vendor = CC_VENDOR_AMD;
352+
353+
if (cpu_has(c, X86_FEATURE_SEV_SNP)) {
354+
/*
355+
* RMP table entry format is not architectural and is defined by the
356+
* per-processor PPR. Restrict SNP support on the known CPU models
357+
* for which the RMP table entry format is currently defined for.
358+
*/
359+
if (!cpu_has(c, X86_FEATURE_HYPERVISOR) &&
360+
c->x86 >= 0x19 && snp_probe_rmptable_info()) {
361+
cc_platform_set(CC_ATTR_HOST_SEV_SNP);
362+
} else {
363+
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
364+
cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
365+
}
366+
}
367+
#endif
368+
}
369+
348370
static void bsp_init_amd(struct cpuinfo_x86 *c)
349371
{
350372
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
@@ -452,21 +474,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
452474
break;
453475
}
454476

455-
if (cpu_has(c, X86_FEATURE_SEV_SNP)) {
456-
/*
457-
* RMP table entry format is not architectural and it can vary by processor
458-
* and is defined by the per-processor PPR. Restrict SNP support on the
459-
* known CPU model and family for which the RMP table entry format is
460-
* currently defined for.
461-
*/
462-
if (!boot_cpu_has(X86_FEATURE_ZEN3) &&
463-
!boot_cpu_has(X86_FEATURE_ZEN4) &&
464-
!boot_cpu_has(X86_FEATURE_ZEN5))
465-
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
466-
else if (!snp_probe_rmptable_info())
467-
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
468-
}
469-
477+
bsp_determine_snp(c);
470478
return;
471479

472480
warn:

arch/x86/kernel/cpu/mce/core.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2500,12 +2500,14 @@ static ssize_t set_bank(struct device *s, struct device_attribute *attr,
25002500
return -EINVAL;
25012501

25022502
b = &per_cpu(mce_banks_array, s->id)[bank];
2503-
25042503
if (!b->init)
25052504
return -ENODEV;
25062505

25072506
b->ctl = new;
2507+
2508+
mutex_lock(&mce_sysfs_mutex);
25082509
mce_restart();
2510+
mutex_unlock(&mce_sysfs_mutex);
25092511

25102512
return size;
25112513
}

arch/x86/kernel/cpu/mtrr/generic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static inline void k8_check_syscfg_dram_mod_en(void)
108108
(boot_cpu_data.x86 >= 0x0f)))
109109
return;
110110

111-
if (cpu_feature_enabled(X86_FEATURE_SEV_SNP))
111+
if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
112112
return;
113113

114114
rdmsr(MSR_AMD64_SYSCFG, lo, hi);

arch/x86/kernel/cpu/resctrl/internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
7878
else
7979
cpu = cpumask_any_but(mask, exclude_cpu);
8080

81-
if (!IS_ENABLED(CONFIG_NO_HZ_FULL))
81+
/* Only continue if tick_nohz_full_mask has been initialized. */
82+
if (!tick_nohz_full_enabled())
8283
return cpu;
8384

8485
/* If the CPU picked isn't marked nohz_full nothing more needs doing. */

arch/x86/kernel/setup.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <asm/bios_ebda.h>
3636
#include <asm/bugs.h>
3737
#include <asm/cacheinfo.h>
38+
#include <asm/coco.h>
3839
#include <asm/cpu.h>
3940
#include <asm/efi.h>
4041
#include <asm/gart.h>
@@ -991,6 +992,7 @@ void __init setup_arch(char **cmdline_p)
991992
* memory size.
992993
*/
993994
mem_encrypt_setup_arch();
995+
cc_random_init();
994996

995997
efi_fake_memmap();
996998
efi_find_mirror();

arch/x86/kernel/sev.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,16 +2284,6 @@ static int __init snp_init_platform_device(void)
22842284
}
22852285
device_initcall(snp_init_platform_device);
22862286

2287-
void kdump_sev_callback(void)
2288-
{
2289-
/*
2290-
* Do wbinvd() on remote CPUs when SNP is enabled in order to
2291-
* safely do SNP_SHUTDOWN on the local CPU.
2292-
*/
2293-
if (cpu_feature_enabled(X86_FEATURE_SEV_SNP))
2294-
wbinvd();
2295-
}
2296-
22972287
void sev_show_status(void)
22982288
{
22992289
int i;

arch/x86/kvm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ config KVM_AMD_SEV
122122
default y
123123
depends on KVM_AMD && X86_64
124124
depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m)
125+
select ARCH_HAS_CC_PLATFORM
125126
help
126127
Provides support for launching Encrypted VMs (SEV) and Encrypted VMs
127128
with Encrypted State (SEV-ES) on AMD processors.

arch/x86/kvm/svm/sev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3184,7 +3184,7 @@ struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
31843184
unsigned long pfn;
31853185
struct page *p;
31863186

3187-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
3187+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
31883188
return alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
31893189

31903190
/*

arch/x86/lib/retpoline.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ SYM_CODE_END(srso_return_thunk)
229229
/* Dummy for the alternative in CALL_UNTRAIN_RET. */
230230
SYM_CODE_START(srso_alias_untrain_ret)
231231
ANNOTATE_UNRET_SAFE
232+
ANNOTATE_NOENDBR
232233
ret
233234
int3
234235
SYM_FUNC_END(srso_alias_untrain_ret)

arch/x86/mm/numa_32.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <linux/memblock.h>
2626
#include <linux/init.h>
27+
#include <asm/pgtable_areas.h>
2728

2829
#include "numa_internal.h"
2930

0 commit comments

Comments
 (0)