Skip to content

Commit 0ecaefb

Browse files
committed
x86/CPU/AMD: Track SNP host status with cc_platform_*()
The host SNP worthiness can determined later, after alternatives have been patched, in snp_rmptable_init() depending on cmdline options like iommu=pt which is incompatible with SNP, for example. Which means that one cannot use X86_FEATURE_SEV_SNP and will need to have a special flag for that control. Use that newly added CC_ATTR_HOST_SEV_SNP in the appropriate places. Move kdump_sev_callback() to its rightful place, while at it. Fixes: 216d106 ("x86/sev: Add SEV-SNP host initialization support") Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Tested-by: Srikanth Aithal <sraithal@amd.com> Link: https://lore.kernel.org/r/20240327154317.29909-6-bp@alien8.de
1 parent bc6f707 commit 0ecaefb

File tree

8 files changed

+49
-39
lines changed

8 files changed

+49
-39
lines changed

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/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/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/svm/sev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3174,7 +3174,7 @@ struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
31743174
unsigned long pfn;
31753175
struct page *p;
31763176

3177-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
3177+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
31783178
return alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
31793179

31803180
/*

arch/x86/virt/svm/sev.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static int __mfd_enable(unsigned int cpu)
7777
{
7878
u64 val;
7979

80-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
80+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
8181
return 0;
8282

8383
rdmsrl(MSR_AMD64_SYSCFG, val);
@@ -98,7 +98,7 @@ static int __snp_enable(unsigned int cpu)
9898
{
9999
u64 val;
100100

101-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
101+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
102102
return 0;
103103

104104
rdmsrl(MSR_AMD64_SYSCFG, val);
@@ -174,11 +174,11 @@ static int __init snp_rmptable_init(void)
174174
u64 rmptable_size;
175175
u64 val;
176176

177-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
177+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
178178
return 0;
179179

180180
if (!amd_iommu_snp_en)
181-
return 0;
181+
goto nosnp;
182182

183183
if (!probed_rmp_size)
184184
goto nosnp;
@@ -225,7 +225,7 @@ static int __init snp_rmptable_init(void)
225225
return 0;
226226

227227
nosnp:
228-
setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
228+
cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
229229
return -ENOSYS;
230230
}
231231

@@ -246,7 +246,7 @@ static struct rmpentry *__snp_lookup_rmpentry(u64 pfn, int *level)
246246
{
247247
struct rmpentry *large_entry, *entry;
248248

249-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
249+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
250250
return ERR_PTR(-ENODEV);
251251

252252
entry = get_rmpentry(pfn);
@@ -363,7 +363,7 @@ int psmash(u64 pfn)
363363
unsigned long paddr = pfn << PAGE_SHIFT;
364364
int ret;
365365

366-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
366+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
367367
return -ENODEV;
368368

369369
if (!pfn_valid(pfn))
@@ -472,7 +472,7 @@ static int rmpupdate(u64 pfn, struct rmp_state *state)
472472
unsigned long paddr = pfn << PAGE_SHIFT;
473473
int ret, level;
474474

475-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
475+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
476476
return -ENODEV;
477477

478478
level = RMP_TO_PG_LEVEL(state->pagesize);
@@ -558,3 +558,13 @@ void snp_leak_pages(u64 pfn, unsigned int npages)
558558
spin_unlock(&snp_leaked_pages_list_lock);
559559
}
560560
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+
}

drivers/crypto/ccp/sev-dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ static int __sev_snp_init_locked(int *error)
10901090
void *arg = &data;
10911091
int cmd, rc = 0;
10921092

1093-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
1093+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
10941094
return -ENODEV;
10951095

10961096
sev = psp->sev_data;

drivers/iommu/amd/init.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3228,20 +3228,22 @@ static bool __init detect_ivrs(void)
32283228
static void iommu_snp_enable(void)
32293229
{
32303230
#ifdef CONFIG_KVM_AMD_SEV
3231-
if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP))
3231+
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
32323232
return;
32333233
/*
32343234
* The SNP support requires that IOMMU must be enabled, and is
32353235
* not configured in the passthrough mode.
32363236
*/
32373237
if (no_iommu || iommu_default_passthrough()) {
32383238
pr_err("SNP: IOMMU disabled or configured in passthrough mode, SNP cannot be supported.\n");
3239+
cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
32393240
return;
32403241
}
32413242

32423243
amd_iommu_snp_en = check_feature(FEATURE_SNP);
32433244
if (!amd_iommu_snp_en) {
32443245
pr_err("SNP: IOMMU SNP feature not enabled, SNP cannot be supported.\n");
3246+
cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
32453247
return;
32463248
}
32473249

0 commit comments

Comments
 (0)