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
This commit is contained in:
@@ -88,7 +88,7 @@ static const char * const sev_status_feat_names[] = {
|
||||
*/
|
||||
static u64 snp_tsc_scale __ro_after_init;
|
||||
static u64 snp_tsc_offset __ro_after_init;
|
||||
static u64 snp_tsc_freq_khz __ro_after_init;
|
||||
static unsigned long snp_tsc_freq_khz __ro_after_init;
|
||||
|
||||
DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data);
|
||||
DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
|
||||
@@ -2167,15 +2167,31 @@ static unsigned long securetsc_get_tsc_khz(void)
|
||||
|
||||
void __init snp_secure_tsc_init(void)
|
||||
{
|
||||
unsigned long long tsc_freq_mhz;
|
||||
struct snp_secrets_page *secrets;
|
||||
unsigned long tsc_freq_mhz;
|
||||
void *mem;
|
||||
|
||||
if (!cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC))
|
||||
return;
|
||||
|
||||
mem = early_memremap_encrypted(sev_secrets_pa, PAGE_SIZE);
|
||||
if (!mem) {
|
||||
pr_err("Unable to get TSC_FACTOR: failed to map the SNP secrets page.\n");
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SECURE_TSC);
|
||||
}
|
||||
|
||||
secrets = (__force struct snp_secrets_page *)mem;
|
||||
|
||||
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
|
||||
rdmsrq(MSR_AMD64_GUEST_TSC_FREQ, tsc_freq_mhz);
|
||||
snp_tsc_freq_khz = (unsigned long)(tsc_freq_mhz * 1000);
|
||||
|
||||
/* Extract the GUEST TSC MHZ from BIT[17:0], rest is reserved space */
|
||||
tsc_freq_mhz &= GENMASK_ULL(17, 0);
|
||||
|
||||
snp_tsc_freq_khz = SNP_SCALE_TSC_FREQ(tsc_freq_mhz * 1000, secrets->tsc_factor);
|
||||
|
||||
x86_platform.calibrate_cpu = securetsc_get_tsc_khz;
|
||||
x86_platform.calibrate_tsc = securetsc_get_tsc_khz;
|
||||
|
||||
early_memunmap(mem, PAGE_SIZE);
|
||||
}
|
||||
|
||||
@@ -223,6 +223,18 @@ struct snp_tsc_info_resp {
|
||||
u8 rsvd2[100];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Obtain the mean TSC frequency by decreasing the nominal TSC frequency with
|
||||
* TSC_FACTOR as documented in the SNP Firmware ABI specification:
|
||||
*
|
||||
* GUEST_TSC_FREQ * (1 - (TSC_FACTOR * 0.00001))
|
||||
*
|
||||
* which is equivalent to:
|
||||
*
|
||||
* GUEST_TSC_FREQ -= (GUEST_TSC_FREQ * TSC_FACTOR) / 100000;
|
||||
*/
|
||||
#define SNP_SCALE_TSC_FREQ(freq, factor) ((freq) - (freq) * (factor) / 100000)
|
||||
|
||||
struct snp_guest_req {
|
||||
void *req_buf;
|
||||
size_t req_sz;
|
||||
@@ -282,8 +294,11 @@ struct snp_secrets_page {
|
||||
u8 svsm_guest_vmpl;
|
||||
u8 rsvd3[3];
|
||||
|
||||
/* The percentage decrease from nominal to mean TSC frequency. */
|
||||
u32 tsc_factor;
|
||||
|
||||
/* Remainder of page */
|
||||
u8 rsvd4[3744];
|
||||
u8 rsvd4[3740];
|
||||
} __packed;
|
||||
|
||||
struct snp_msg_desc {
|
||||
|
||||
Reference in New Issue
Block a user