Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+166 -41
+93
arch/x86/coco/core.c
··· 3 3 * Confidential Computing Platform Capability checks 4 4 * 5 5 * Copyright (C) 2021 Advanced Micro Devices, Inc. 6 + * Copyright (C) 2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 6 7 * 7 8 * Author: Tom Lendacky <thomas.lendacky@amd.com> 8 9 */ 9 10 10 11 #include <linux/export.h> 11 12 #include <linux/cc_platform.h> 13 + #include <linux/string.h> 14 + #include <linux/random.h> 12 15 16 + #include <asm/archrandom.h> 13 17 #include <asm/coco.h> 14 18 #include <asm/processor.h> 15 19 16 20 enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE; 17 21 u64 cc_mask __ro_after_init; 22 + 23 + static struct cc_attr_flags { 24 + __u64 host_sev_snp : 1, 25 + __resv : 63; 26 + } cc_flags; 18 27 19 28 static bool noinstr intel_cc_platform_has(enum cc_attr attr) 20 29 { ··· 98 89 case CC_ATTR_GUEST_SEV_SNP: 99 90 return sev_status & MSR_AMD64_SEV_SNP_ENABLED; 100 91 92 + case CC_ATTR_HOST_SEV_SNP: 93 + return cc_flags.host_sev_snp; 94 + 101 95 default: 102 96 return false; 103 97 } ··· 160 148 } 161 149 } 162 150 EXPORT_SYMBOL_GPL(cc_mkdec); 151 + 152 + static void amd_cc_platform_clear(enum cc_attr attr) 153 + { 154 + switch (attr) { 155 + case CC_ATTR_HOST_SEV_SNP: 156 + cc_flags.host_sev_snp = 0; 157 + break; 158 + default: 159 + break; 160 + } 161 + } 162 + 163 + void cc_platform_clear(enum cc_attr attr) 164 + { 165 + switch (cc_vendor) { 166 + case CC_VENDOR_AMD: 167 + amd_cc_platform_clear(attr); 168 + break; 169 + default: 170 + break; 171 + } 172 + } 173 + 174 + static void amd_cc_platform_set(enum cc_attr attr) 175 + { 176 + switch (attr) { 177 + case CC_ATTR_HOST_SEV_SNP: 178 + cc_flags.host_sev_snp = 1; 179 + break; 180 + default: 181 + break; 182 + } 183 + } 184 + 185 + void cc_platform_set(enum cc_attr attr) 186 + { 187 + switch (cc_vendor) { 188 + case CC_VENDOR_AMD: 189 + amd_cc_platform_set(attr); 190 + break; 191 + default: 192 + break; 193 + } 194 + } 195 + 196 + __init void cc_random_init(void) 197 + { 198 + /* 199 + * The seed is 32 bytes (in units of longs), which is 256 bits, which 200 + * is the security level that the RNG is targeting. 201 + */ 202 + unsigned long rng_seed[32 / sizeof(long)]; 203 + size_t i, longs; 204 + 205 + if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) 206 + return; 207 + 208 + /* 209 + * Since the CoCo threat model includes the host, the only reliable 210 + * source of entropy that can be neither observed nor manipulated is 211 + * RDRAND. Usually, RDRAND failure is considered tolerable, but since 212 + * CoCo guests have no other unobservable source of entropy, it's 213 + * important to at least ensure the RNG gets some initial random seeds. 214 + */ 215 + for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) { 216 + longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i); 217 + 218 + /* 219 + * A zero return value means that the guest doesn't have RDRAND 220 + * or the CPU is physically broken, and in both cases that 221 + * means most crypto inside of the CoCo instance will be 222 + * broken, defeating the purpose of CoCo in the first place. So 223 + * just panic here because it's absolutely unsafe to continue 224 + * executing. 225 + */ 226 + if (longs == 0) 227 + panic("RDRAND is defective."); 228 + } 229 + add_device_randomness(rng_seed, sizeof(rng_seed)); 230 + memzero_explicit(rng_seed, sizeof(rng_seed)); 231 + }
+2
arch/x86/include/asm/coco.h
··· 22 22 23 23 u64 cc_mkenc(u64 val); 24 24 u64 cc_mkdec(u64 val); 25 + void cc_random_init(void); 25 26 #else 26 27 #define cc_vendor (CC_VENDOR_NONE) 27 28 ··· 35 34 { 36 35 return val; 37 36 } 37 + static inline void cc_random_init(void) { } 38 38 #endif 39 39 40 40 #endif /* _ASM_X86_COCO_H */
+2 -2
arch/x86/include/asm/sev.h
··· 228 228 void snp_accept_memory(phys_addr_t start, phys_addr_t end); 229 229 u64 snp_get_unsupported_features(u64 status); 230 230 u64 sev_get_status(void); 231 - void kdump_sev_callback(void); 232 231 void sev_show_status(void); 233 232 #else 234 233 static inline void sev_es_ist_enter(struct pt_regs *regs) { } ··· 257 258 static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { } 258 259 static inline u64 snp_get_unsupported_features(u64 status) { return 0; } 259 260 static inline u64 sev_get_status(void) { return 0; } 260 - static inline void kdump_sev_callback(void) { } 261 261 static inline void sev_show_status(void) { } 262 262 #endif 263 263 ··· 268 270 int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid, bool immutable); 269 271 int rmp_make_shared(u64 pfn, enum pg_level level); 270 272 void snp_leak_pages(u64 pfn, unsigned int npages); 273 + void kdump_sev_callback(void); 271 274 #else 272 275 static inline bool snp_probe_rmptable_info(void) { return false; } 273 276 static inline int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level) { return -ENODEV; } ··· 281 282 } 282 283 static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV; } 283 284 static inline void snp_leak_pages(u64 pfn, unsigned int npages) {} 285 + static inline void kdump_sev_callback(void) { } 284 286 #endif 285 287 286 288 #endif
+23 -15
arch/x86/kernel/cpu/amd.c
··· 345 345 #endif 346 346 } 347 347 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 + 348 370 static void bsp_init_amd(struct cpuinfo_x86 *c) 349 371 { 350 372 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { ··· 474 452 break; 475 453 } 476 454 477 - if (cpu_has(c, X86_FEATURE_SEV_SNP)) { 478 - /* 479 - * RMP table entry format is not architectural and it can vary by processor 480 - * and is defined by the per-processor PPR. Restrict SNP support on the 481 - * known CPU model and family for which the RMP table entry format is 482 - * currently defined for. 483 - */ 484 - if (!boot_cpu_has(X86_FEATURE_ZEN3) && 485 - !boot_cpu_has(X86_FEATURE_ZEN4) && 486 - !boot_cpu_has(X86_FEATURE_ZEN5)) 487 - setup_clear_cpu_cap(X86_FEATURE_SEV_SNP); 488 - else if (!snp_probe_rmptable_info()) 489 - setup_clear_cpu_cap(X86_FEATURE_SEV_SNP); 490 - } 491 - 455 + bsp_determine_snp(c); 492 456 return; 493 457 494 458 warn:
+3 -1
arch/x86/kernel/cpu/mce/core.c
··· 2500 2500 return -EINVAL; 2501 2501 2502 2502 b = &per_cpu(mce_banks_array, s->id)[bank]; 2503 - 2504 2503 if (!b->init) 2505 2504 return -ENODEV; 2506 2505 2507 2506 b->ctl = new; 2507 + 2508 + mutex_lock(&mce_sysfs_mutex); 2508 2509 mce_restart(); 2510 + mutex_unlock(&mce_sysfs_mutex); 2509 2511 2510 2512 return size; 2511 2513 }
+1 -1
arch/x86/kernel/cpu/mtrr/generic.c
··· 108 108 (boot_cpu_data.x86 >= 0x0f))) 109 109 return; 110 110 111 - if (cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 111 + if (cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 112 112 return; 113 113 114 114 rdmsr(MSR_AMD64_SYSCFG, lo, hi);
+2 -1
arch/x86/kernel/cpu/resctrl/internal.h
··· 78 78 else 79 79 cpu = cpumask_any_but(mask, exclude_cpu); 80 80 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()) 82 83 return cpu; 83 84 84 85 /* If the CPU picked isn't marked nohz_full nothing more needs doing. */
+2
arch/x86/kernel/setup.c
··· 35 35 #include <asm/bios_ebda.h> 36 36 #include <asm/bugs.h> 37 37 #include <asm/cacheinfo.h> 38 + #include <asm/coco.h> 38 39 #include <asm/cpu.h> 39 40 #include <asm/efi.h> 40 41 #include <asm/gart.h> ··· 992 991 * memory size. 993 992 */ 994 993 mem_encrypt_setup_arch(); 994 + cc_random_init(); 995 995 996 996 efi_fake_memmap(); 997 997 efi_find_mirror();
-10
arch/x86/kernel/sev.c
··· 2284 2284 } 2285 2285 device_initcall(snp_init_platform_device); 2286 2286 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 - 2297 2287 void sev_show_status(void) 2298 2288 { 2299 2289 int i;
+1
arch/x86/kvm/Kconfig
··· 122 122 default y 123 123 depends on KVM_AMD && X86_64 124 124 depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m) 125 + select ARCH_HAS_CC_PLATFORM 125 126 help 126 127 Provides support for launching Encrypted VMs (SEV) and Encrypted VMs 127 128 with Encrypted State (SEV-ES) on AMD processors.
+1 -1
arch/x86/kvm/svm/sev.c
··· 3184 3184 unsigned long pfn; 3185 3185 struct page *p; 3186 3186 3187 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 3187 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 3188 3188 return alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); 3189 3189 3190 3190 /*
+1
arch/x86/lib/retpoline.S
··· 229 229 /* Dummy for the alternative in CALL_UNTRAIN_RET. */ 230 230 SYM_CODE_START(srso_alias_untrain_ret) 231 231 ANNOTATE_UNRET_SAFE 232 + ANNOTATE_NOENDBR 232 233 ret 233 234 int3 234 235 SYM_FUNC_END(srso_alias_untrain_ret)
+1
arch/x86/mm/numa_32.c
··· 24 24 25 25 #include <linux/memblock.h> 26 26 #include <linux/init.h> 27 + #include <asm/pgtable_areas.h> 27 28 28 29 #include "numa_internal.h" 29 30
+18 -8
arch/x86/virt/svm/sev.c
··· 77 77 { 78 78 u64 val; 79 79 80 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 80 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 81 81 return 0; 82 82 83 83 rdmsrl(MSR_AMD64_SYSCFG, val); ··· 98 98 { 99 99 u64 val; 100 100 101 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 101 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 102 102 return 0; 103 103 104 104 rdmsrl(MSR_AMD64_SYSCFG, val); ··· 174 174 u64 rmptable_size; 175 175 u64 val; 176 176 177 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 177 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 178 178 return 0; 179 179 180 180 if (!amd_iommu_snp_en) 181 - return 0; 181 + goto nosnp; 182 182 183 183 if (!probed_rmp_size) 184 184 goto nosnp; ··· 225 225 return 0; 226 226 227 227 nosnp: 228 - setup_clear_cpu_cap(X86_FEATURE_SEV_SNP); 228 + cc_platform_clear(CC_ATTR_HOST_SEV_SNP); 229 229 return -ENOSYS; 230 230 } 231 231 ··· 246 246 { 247 247 struct rmpentry *large_entry, *entry; 248 248 249 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 249 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 250 250 return ERR_PTR(-ENODEV); 251 251 252 252 entry = get_rmpentry(pfn); ··· 363 363 unsigned long paddr = pfn << PAGE_SHIFT; 364 364 int ret; 365 365 366 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 366 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 367 367 return -ENODEV; 368 368 369 369 if (!pfn_valid(pfn)) ··· 472 472 unsigned long paddr = pfn << PAGE_SHIFT; 473 473 int ret, level; 474 474 475 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 475 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 476 476 return -ENODEV; 477 477 478 478 level = RMP_TO_PG_LEVEL(state->pagesize); ··· 558 558 spin_unlock(&snp_leaked_pages_list_lock); 559 559 } 560 560 EXPORT_SYMBOL_GPL(snp_leak_pages); 561 + 562 + void kdump_sev_callback(void) 563 + { 564 + /* 565 + * Do wbinvd() on remote CPUs when SNP is enabled in order to 566 + * safely do SNP_SHUTDOWN on the local CPU. 567 + */ 568 + if (cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 569 + wbinvd(); 570 + }
+1 -1
drivers/crypto/ccp/sev-dev.c
··· 1090 1090 void *arg = &data; 1091 1091 int cmd, rc = 0; 1092 1092 1093 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 1093 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 1094 1094 return -ENODEV; 1095 1095 1096 1096 sev = psp->sev_data;
+3 -1
drivers/iommu/amd/init.c
··· 3228 3228 static void iommu_snp_enable(void) 3229 3229 { 3230 3230 #ifdef CONFIG_KVM_AMD_SEV 3231 - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 3231 + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) 3232 3232 return; 3233 3233 /* 3234 3234 * The SNP support requires that IOMMU must be enabled, and is ··· 3236 3236 */ 3237 3237 if (no_iommu || iommu_default_passthrough()) { 3238 3238 pr_err("SNP: IOMMU disabled or configured in passthrough mode, SNP cannot be supported.\n"); 3239 + cc_platform_clear(CC_ATTR_HOST_SEV_SNP); 3239 3240 return; 3240 3241 } 3241 3242 3242 3243 amd_iommu_snp_en = check_feature(FEATURE_SNP); 3243 3244 if (!amd_iommu_snp_en) { 3244 3245 pr_err("SNP: IOMMU SNP feature not enabled, SNP cannot be supported.\n"); 3246 + cc_platform_clear(CC_ATTR_HOST_SEV_SNP); 3245 3247 return; 3246 3248 } 3247 3249
+12
include/linux/cc_platform.h
··· 90 90 * Examples include TDX Guest. 91 91 */ 92 92 CC_ATTR_HOTPLUG_DISABLED, 93 + 94 + /** 95 + * @CC_ATTR_HOST_SEV_SNP: AMD SNP enabled on the host. 96 + * 97 + * The host kernel is running with the necessary features 98 + * enabled to run SEV-SNP guests. 99 + */ 100 + CC_ATTR_HOST_SEV_SNP, 93 101 }; 94 102 95 103 #ifdef CONFIG_ARCH_HAS_CC_PLATFORM ··· 115 107 * * FALSE - Specified Confidential Computing attribute is not active 116 108 */ 117 109 bool cc_platform_has(enum cc_attr attr); 110 + void cc_platform_set(enum cc_attr attr); 111 + void cc_platform_clear(enum cc_attr attr); 118 112 119 113 #else /* !CONFIG_ARCH_HAS_CC_PLATFORM */ 120 114 121 115 static inline bool cc_platform_has(enum cc_attr attr) { return false; } 116 + static inline void cc_platform_set(enum cc_attr attr) { } 117 + static inline void cc_platform_clear(enum cc_attr attr) { } 122 118 123 119 #endif /* CONFIG_ARCH_HAS_CC_PLATFORM */ 124 120