amd_pmu_enable_virt();
 
+       /*
+        * If TSC_AUX virtualization is supported, TSC_AUX becomes a swap type
+        * "B" field (see sev_es_prepare_switch_to_guest()) for SEV-ES guests.
+        * Since Linux does not change the value of TSC_AUX once set, prime the
+        * TSC_AUX field now to avoid a RDMSR on every vCPU run.
+        */
+       if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) {
+               struct sev_es_save_area *hostsa;
+               u32 msr_hi;
+
+               hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400);
+
+               rdmsr(MSR_TSC_AUX, hostsa->tsc_aux, msr_hi);
+       }
+
        return 0;
 }
 
        if (tsc_scaling)
                __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
 
-       if (likely(tsc_aux_uret_slot >= 0))
+       /*
+        * TSC_AUX is always virtualized for SEV-ES guests when the feature is
+        * available. The user return MSR support is not required in this case
+        * because TSC_AUX is restored on #VMEXIT from the host save area
+        * (which has been initialized in svm_hardware_enable()).
+        */
+       if (likely(tsc_aux_uret_slot >= 0) &&
+           (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm)))
                kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull);
 
        svm->guest_state_loaded = true;
                svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0;
                break;
        case MSR_TSC_AUX:
+               /*
+                * TSC_AUX is always virtualized for SEV-ES guests when the
+                * feature is available. The user return MSR support is not
+                * required in this case because TSC_AUX is restored on #VMEXIT
+                * from the host save area (which has been initialized in
+                * svm_hardware_enable()).
+                */
+               if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && sev_es_guest(vcpu->kvm))
+                       break;
+
                /*
                 * TSC_AUX is usually changed only during boot and never read
                 * directly.  Intercept TSC_AUX instead of exposing it to the