+19
-3
arch/x86/coco/sev/core.c
+19
-3
arch/x86/coco/sev/core.c
···
88
88
*/
89
89
static u64 snp_tsc_scale __ro_after_init;
90
90
static u64 snp_tsc_offset __ro_after_init;
91
-
static u64 snp_tsc_freq_khz __ro_after_init;
91
+
static unsigned long snp_tsc_freq_khz __ro_after_init;
92
92
93
93
DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data);
94
94
DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
···
2167
2167
2168
2168
void __init snp_secure_tsc_init(void)
2169
2169
{
2170
-
unsigned long long tsc_freq_mhz;
2170
+
struct snp_secrets_page *secrets;
2171
+
unsigned long tsc_freq_mhz;
2172
+
void *mem;
2171
2173
2172
2174
if (!cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC))
2173
2175
return;
2174
2176
2177
+
mem = early_memremap_encrypted(sev_secrets_pa, PAGE_SIZE);
2178
+
if (!mem) {
2179
+
pr_err("Unable to get TSC_FACTOR: failed to map the SNP secrets page.\n");
2180
+
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SECURE_TSC);
2181
+
}
2182
+
2183
+
secrets = (__force struct snp_secrets_page *)mem;
2184
+
2175
2185
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
2176
2186
rdmsrq(MSR_AMD64_GUEST_TSC_FREQ, tsc_freq_mhz);
2177
-
snp_tsc_freq_khz = (unsigned long)(tsc_freq_mhz * 1000);
2187
+
2188
+
/* Extract the GUEST TSC MHZ from BIT[17:0], rest is reserved space */
2189
+
tsc_freq_mhz &= GENMASK_ULL(17, 0);
2190
+
2191
+
snp_tsc_freq_khz = SNP_SCALE_TSC_FREQ(tsc_freq_mhz * 1000, secrets->tsc_factor);
2178
2192
2179
2193
x86_platform.calibrate_cpu = securetsc_get_tsc_khz;
2180
2194
x86_platform.calibrate_tsc = securetsc_get_tsc_khz;
2195
+
2196
+
early_memunmap(mem, PAGE_SIZE);
2181
2197
}
+16
-1
arch/x86/include/asm/sev.h
+16
-1
arch/x86/include/asm/sev.h
···
223
223
u8 rsvd2[100];
224
224
} __packed;
225
225
226
+
/*
227
+
* Obtain the mean TSC frequency by decreasing the nominal TSC frequency with
228
+
* TSC_FACTOR as documented in the SNP Firmware ABI specification:
229
+
*
230
+
* GUEST_TSC_FREQ * (1 - (TSC_FACTOR * 0.00001))
231
+
*
232
+
* which is equivalent to:
233
+
*
234
+
* GUEST_TSC_FREQ -= (GUEST_TSC_FREQ * TSC_FACTOR) / 100000;
235
+
*/
236
+
#define SNP_SCALE_TSC_FREQ(freq, factor) ((freq) - (freq) * (factor) / 100000)
237
+
226
238
struct snp_guest_req {
227
239
void *req_buf;
228
240
size_t req_sz;
···
294
282
u8 svsm_guest_vmpl;
295
283
u8 rsvd3[3];
296
284
285
+
/* The percentage decrease from nominal to mean TSC frequency. */
286
+
u32 tsc_factor;
287
+
297
288
/* Remainder of page */
298
-
u8 rsvd4[3744];
289
+
u8 rsvd4[3740];
299
290
} __packed;
300
291
301
292
struct snp_msg_desc {