#!/bin/bash sed -i '/\[SVM_EXIT_VMGEXIT\] = sev_handle_vmgexit,/a\ [SVM_EXIT_RDTSC] = handle_rdtsc_interception,' arch/x86/kvm/svm/svm.c sed -i '/ svm_set_intercept(svm, INTERCEPT_RSM);/a\ svm_set_intercept(svm, INTERCEPT_RDTSC);' arch/x86/kvm/svm/svm.c sed -i '/static int (\*const svm_exit_handlers\[\])(struct kvm/e cat << '\''EOF'\'' static u32 print_once = 1; static int handle_rdtsc_interception(struct kvm_vcpu *vcpu) { static u64 rdtsc_fake = 0; static u64 rdtsc_prev = 0; u64 rdtsc_real = rdtsc(); if(print_once) { printk("[handle_rdtsc] fake rdtsc svm function is working\n"); print_once = 0; rdtsc_fake = rdtsc_real; } if(rdtsc_prev != 0) { if(rdtsc_real > rdtsc_prev) { u64 diff = rdtsc_real - rdtsc_prev; u64 fake_diff = diff / 20; // if you have 3.2Ghz on your vm, change 20 to 16 rdtsc_fake += fake_diff; } } if(rdtsc_fake > rdtsc_real) { rdtsc_fake = rdtsc_real; } rdtsc_prev = rdtsc_real; vcpu->arch.regs[VCPU_REGS_RAX] = rdtsc_fake & -1u; vcpu->arch.regs[VCPU_REGS_RDX] = (rdtsc_fake >> 32) & -1u; return svm_skip_emulated_instruction(vcpu); } EOF ' arch/x86/kvm/svm/svm.c