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

Changed files
+35 -4
arch
x86
coco
sev
include
asm
+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
··· 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 {