fix common code duplication by introducing new method get_Virtual_TSC()

it computes TSC as needed for RDTSC(P) and RDMSR TSC taking into account VMX and SVM adjustments
replaces previous get_TSC_VMXAdjust(Bit64u0
This commit is contained in:
Stanislav Shwartsman 2023-11-25 15:00:39 +02:00
parent 1ae23ad935
commit c1c391a9c6
4 changed files with 11 additions and 20 deletions

View File

@ -4679,9 +4679,7 @@ public: // for now...
#if BX_CPU_LEVEL >= 5
BX_SMF Bit64u get_TSC();
BX_SMF void set_TSC(Bit64u tsc);
#if BX_SUPPORT_VMX || BX_SUPPORT_SVM
BX_SMF Bit64u get_TSC_VMXAdjust(Bit64u tsc);
#endif
BX_SMF Bit64u get_Virtual_TSC(); // takes into account VMX or SVM adjustments
#endif
#if BX_SUPPORT_PKEYS

View File

@ -155,10 +155,7 @@ bool BX_CPP_AttrRegparmN(2) BX_CPU_C::rdmsr(Bit32u index, Bit64u *msr)
#endif
case BX_MSR_TSC:
val64 = BX_CPU_THIS_PTR get_TSC();
#if BX_SUPPORT_SVM || BX_SUPPORT_VMX
val64 = BX_CPU_THIS_PTR get_TSC_VMXAdjust(val64);
#endif
val64 = BX_CPU_THIS_PTR get_Virtual_TSC();
break;
case BX_MSR_TSC_ADJUST:

View File

@ -646,11 +646,15 @@ Bit64u BX_CPU_C::get_TSC(void)
}
#if BX_SUPPORT_VMX || BX_SUPPORT_SVM
Bit64u BX_CPU_C::get_TSC_VMXAdjust(Bit64u tsc)
Bit64u BX_CPU_C::get_Virtual_TSC()
{
Bit64u tsc = BX_CPU_THIS_PTR get_TSC();
#if BX_SUPPORT_VMX
if (BX_CPU_THIS_PTR in_vmx_guest) {
if (VMEXIT(VMX_VM_EXEC_CTRL1_TSC_OFFSET) && SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_TSC_SCALING)) {
// RDTSC first computes the product of the value of the IA32_TIME_STAMP_COUNTER MSR and
// the value of the TSC multiplier. It then shifts the value of the product right 48 bits and loads
// EAX:EDX with <the sum of that shifted value and the value of the TSC offset>.
Bit128u product_128;
long_mul(&product_128,tsc,BX_CPU_THIS_PTR vmcs.tsc_multiplier);
tsc = (product_128.lo >> 48) | (product_128.hi << 16); // tsc = (uint64) (long128(tsc_value * tsc_multiplier) >> 48);
@ -694,11 +698,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSC(bxInstruction_c *i)
if (SVM_INTERCEPT(SVM_INTERCEPT0_RDTSC)) Svm_Vmexit(SVM_VMEXIT_RDTSC);
#endif
// return ticks
Bit64u ticks = BX_CPU_THIS_PTR get_TSC();
#if BX_SUPPORT_SVM || BX_SUPPORT_VMX
ticks = BX_CPU_THIS_PTR get_TSC_VMXAdjust(ticks);
#endif
Bit64u ticks = BX_CPU_THIS_PTR get_Virtual_TSC();
RAX = GET32L(ticks);
RDX = GET32H(ticks);
@ -741,11 +741,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSCP(bxInstruction_c *i)
if (SVM_INTERCEPT(SVM_INTERCEPT1_RDTSCP)) Svm_Vmexit(SVM_VMEXIT_RDTSCP);
#endif
// return ticks
Bit64u ticks = BX_CPU_THIS_PTR get_TSC();
#if BX_SUPPORT_SVM || BX_SUPPORT_VMX
ticks = BX_CPU_THIS_PTR get_TSC_VMXAdjust(ticks);
#endif
Bit64u ticks = BX_CPU_THIS_PTR get_Virtual_TSC();
RAX = GET32L(ticks);
RDX = GET32H(ticks);

View File

@ -122,8 +122,8 @@ public:
int register_timer_ticks(void* this_ptr, bx_timer_handler_t, Bit64u ticks,
bool continuous, bool active, const char *id);
void activate_timer_ticks(unsigned index, Bit64u instructions,
bool continuous);
void activate_timer_ticks(unsigned index, Bit64u instructions, bool continuous);
Bit64u time_usec();
Bit64u time_nsec();
Bit64u time_usec_sequential();