diff -Naur --no-dereference a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c --- a/arch/x86/kvm/vmx/vmx.c 2024-07-01 21:03:34.000000000 +0300 +++ b/arch/x86/kvm/vmx/vmx.c 2024-07-01 20:24:05.000000000 +0300 @@ -6128,6 +6128,7 @@ [EXIT_REASON_ENCLS] = handle_encls, [EXIT_REASON_BUS_LOCK] = handle_bus_lock_vmexit, [EXIT_REASON_NOTIFY] = handle_notify, + [EXIT_REASON_RDTSC] = handle_rdtsc, }; static const int kvm_vmx_max_exit_handlers = diff -Naur --no-dereference a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c --- a/arch/x86/kvm/vmx/vmx.c 2024-07-01 21:03:34.000000000 +0300 +++ b/arch/x86/kvm/vmx/vmx.c 2024-07-01 20:24:05.000000000 +0300 @@ -6070,6 +6070,34 @@ return 1; } +static int handle_rdtsc(struct kvm_vcpu *vcpu) +{ + static u64 rdtsc_cur = 0; + static u64 rdtsc_prev = 0; + u64 _rdtsc = rdtsc(); + + printk_once("[HookEntry] fake rdtsc vmx function is working\n"); + + if (rdtsc_prev == 0) + { + rdtsc_cur = _rdtsc; + } + else if (_rdtsc > rdtsc_prev) + { + rdtsc_cur += (_rdtsc - rdtsc_prev) / 16; + } + + if (rdtsc_cur > _rdtsc) + { + rdtsc_cur = _rdtsc; + } + + rdtsc_prev = rdtsc_cur; + vcpu->arch.regs[VCPU_REGS_RAX] = rdtsc_cur & -1u; + vcpu->arch.regs[VCPU_REGS_RDX] = (rdtsc_cur >> 32) & -1u; + return skip_emulated_instruction(vcpu); +} + /* * The exit handlers return 1 if the exit was handled fully and guest execution * may resume. Otherwise they set the kvm_run parameter to indicate what needs