Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working anymore with kernel 6.5 #16

Open
scoony opened this issue Sep 15, 2023 · 5 comments
Open

Not working anymore with kernel 6.5 #16

scoony opened this issue Sep 15, 2023 · 5 comments

Comments

@scoony
Copy link

scoony commented Sep 15, 2023

I was trying to make a script to compile automatically the kernel for my gaming VM but now with the new kernels the compilation failed.

Something has probably changed in the svm.h file.

I've got a compilation error everytime I try to patch the files.

Anyone got a solution?

@Samuil1337
Copy link

I assume your are on AMD, so you can copy and paste everything like explained in the README, but append "svm_" to the method that is returned from the function you paste in. Basically you write a new patch that works with the changed code.

@YungBinary
Copy link

@scoony If you’re on Intel, I forked this repo and updated the patch for Linux kernel 6.8.0-45 (latest for Ubuntu). See my repo here -> https://github.com/YungBinary/RDTSC-KVM-Handler-v2

@scoony
Copy link
Author

scoony commented Sep 26, 2024

@scoony If you’re on Intel, I forked this repo and updated the patch for Linux kernel 6.8.0-45 (latest for Ubuntu). See my repo here -> https://github.com/YungBinary/RDTSC-KVM-Handler-v2

Hi @YungBinary , i'm on AMD, i gave up :(

@Samuil1337
Copy link

What, why? On amd the code literally works but you have to add it manually. Again, the only thing that changed is the kvm_skip_emulated_instruction function call. You have to prepend "svm_" and it will work. Although a heads-up, this isn't really a good implementation

@Username404-59
Copy link

Patch for AMD (no idea if it works, haven't tested it yet)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 9df3e1e5ae81..a91aa30f498e 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1292,6 +1292,7 @@ static void init_vmcb(struct kvm_vcpu *vcpu)
 	svm_set_intercept(svm, INTERCEPT_XSETBV);
 	svm_set_intercept(svm, INTERCEPT_RDPRU);
 	svm_set_intercept(svm, INTERCEPT_RSM);
+	svm_set_intercept(svm, INTERCEPT_RDTSC);
 
 	if (!kvm_mwait_in_guest(vcpu->kvm)) {
 		svm_set_intercept(svm, INTERCEPT_MONITOR);
@@ -3286,6 +3287,42 @@ static int invpcid_interception(struct kvm_vcpu *vcpu)
 	return kvm_handle_invpcid(vcpu, type, gva);
 }
 
+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);
+}
+
 static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[SVM_EXIT_READ_CR0]			= cr_interception,
 	[SVM_EXIT_READ_CR3]			= cr_interception,
@@ -3360,6 +3397,7 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 #ifdef CONFIG_KVM_AMD_SEV
 	[SVM_EXIT_VMGEXIT]			= sev_handle_vmgexit,
 #endif
+	[SVM_EXIT_RDTSC]			= handle_rdtsc_interception,
 };
 
 static void dump_vmcb(struct kvm_vcpu *vcpu)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants