Skip to content

Commit 5fc2e89

Browse files
committed
Merge tag 'x86_urgent_for_v6.16_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fix from Borislav Petkov: - Make sure AMD SEV guests using secure TSC, include a TSC_FACTOR which prevents their TSCs from going skewed from the hypervisor's * tag 'x86_urgent_for_v6.16_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/sev: Use TSC_FACTOR for Secure TSC frequency calculation
2 parents 463b1b2 + 52e1a03 commit 5fc2e89

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

arch/x86/coco/sev/core.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static const char * const sev_status_feat_names[] = {
8888
*/
8989
static u64 snp_tsc_scale __ro_after_init;
9090
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;
9292

9393
DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data);
9494
DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
@@ -2167,15 +2167,31 @@ static unsigned long securetsc_get_tsc_khz(void)
21672167

21682168
void __init snp_secure_tsc_init(void)
21692169
{
2170-
unsigned long long tsc_freq_mhz;
2170+
struct snp_secrets_page *secrets;
2171+
unsigned long tsc_freq_mhz;
2172+
void *mem;
21712173

21722174
if (!cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC))
21732175
return;
21742176

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+
21752185
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
21762186
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);
21782192

21792193
x86_platform.calibrate_cpu = securetsc_get_tsc_khz;
21802194
x86_platform.calibrate_tsc = securetsc_get_tsc_khz;
2195+
2196+
early_memunmap(mem, PAGE_SIZE);
21812197
}

arch/x86/include/asm/sev.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,18 @@ struct snp_tsc_info_resp {
223223
u8 rsvd2[100];
224224
} __packed;
225225

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+
226238
struct snp_guest_req {
227239
void *req_buf;
228240
size_t req_sz;
@@ -282,8 +294,11 @@ struct snp_secrets_page {
282294
u8 svsm_guest_vmpl;
283295
u8 rsvd3[3];
284296

297+
/* The percentage decrease from nominal to mean TSC frequency. */
298+
u32 tsc_factor;
299+
285300
/* Remainder of page */
286-
u8 rsvd4[3744];
301+
u8 rsvd4[3740];
287302
} __packed;
288303

289304
struct snp_msg_desc {

0 commit comments

Comments
 (0)