diff mbox series

[v15,07/13] x86/sev: Mark Secure TSC as reliable clocksource

Message ID 20241203090045.942078-8-nikunj@amd.com (mailing list archive)
State New
Headers show
Series Add Secure TSC support for SNP guests | expand

Commit Message

Nikunj A. Dadhania Dec. 3, 2024, 9 a.m. UTC
In SNP guest environment with Secure TSC enabled, unlike other clock
sources (such as HPET, ACPI timer, APIC, etc.), the RDTSC instruction is
handled without causing a VM exit, resulting in minimal overhead and
jitters. Hence, mark Secure TSC as the only reliable clock source,
bypassing unstable calibration.

Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
Tested-by: Peter Gonda <pgonda@google.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 arch/x86/mm/mem_encrypt_amd.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Borislav Petkov Dec. 11, 2024, 8:32 p.m. UTC | #1
On Tue, Dec 03, 2024 at 02:30:39PM +0530, Nikunj A Dadhania wrote:
> diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
> index 774f9677458f..fa0bc52ef707 100644
> --- a/arch/x86/mm/mem_encrypt_amd.c
> +++ b/arch/x86/mm/mem_encrypt_amd.c
> @@ -541,6 +541,10 @@ void __init sme_early_init(void)
>  	 * kernel mapped.
>  	 */
>  	snp_update_svsm_ca();
> +
> +	/* Mark the TSC as reliable when Secure TSC is enabled */
> +	if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
> +		setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);

What happens if someone writes MSR 0x10 on some CPU and thus makes the TSCs on
the host unsynchronized and that CPU runs a SecureTSC guest?

That guest would use RDTSC and get wrong values and turn the guest into
a mess, right?
Nikunj A. Dadhania Dec. 12, 2024, 5:07 a.m. UTC | #2
On 12/12/2024 2:02 AM, Borislav Petkov wrote:
> On Tue, Dec 03, 2024 at 02:30:39PM +0530, Nikunj A Dadhania wrote:
>> diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
>> index 774f9677458f..fa0bc52ef707 100644
>> --- a/arch/x86/mm/mem_encrypt_amd.c
>> +++ b/arch/x86/mm/mem_encrypt_amd.c
>> @@ -541,6 +541,10 @@ void __init sme_early_init(void)
>>  	 * kernel mapped.
>>  	 */
>>  	snp_update_svsm_ca();
>> +
>> +	/* Mark the TSC as reliable when Secure TSC is enabled */
>> +	if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
>> +		setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
> 
> What happens if someone writes MSR 0x10 on some CPU and thus makes the TSCs on
> the host unsynchronized and that CPU runs a SecureTSC guest?
> 
> That guest would use RDTSC and get wrong values and turn the guest into
> a mess, right?

No, SecureTSC guest keeps on ticking forward even when the HV has written to 
MSR 0x10 on the CPU where the SecureTSC guest is running.

I performed following experiment to confirm the behavior:

1) Started the SecureTSC guest pinned to CPU10

host $ taskset -c 10 ./bootg_sectsc.sh

2) Read TSC MSR on guest

guest $ sudo rdmsr 0x10
8005a5b2d634c

3) Set TSC MSR to 0 on CPU10 on host.

host $ sudo wrmsr -p 10 0x10 0
host $ sudo rdmsr -p 10 0x10
4846ad0

4) Read TSC MSR on guest again

guest $ sudo rdmsr 0x10
8005d18a7144f

Regards,
Nikunj
diff mbox series

Patch

diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 774f9677458f..fa0bc52ef707 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -541,6 +541,10 @@  void __init sme_early_init(void)
 	 * kernel mapped.
 	 */
 	snp_update_svsm_ca();
+
+	/* Mark the TSC as reliable when Secure TSC is enabled */
+	if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
+		setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)