-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpatch.sh
95 lines (89 loc) · 3.22 KB
/
patch.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/bin/bash
linux_git_repo="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
linux_git_branch="linux-rolling-lts"
cpu_brand=$(grep -m 1 'vendor_id' /proc/cpuinfo | cut -c13-)
git clone --branch $linux_git_branch $linux_git_repo
if [ $cpu_brand = "AuthenticAMD" ] && [ -z $(grep -r "EDITED BY SED" "$(pwd)/linux/arch/x86/kvm/svm/svm.c") ]; then
line_1=$(( $(grep -n "kvm_handle_invpcid(vcpu, type, gva);" linux/arch/x86/kvm/svm/svm.c | awk '{print $1;}' | cut -f1 -d ':')+2))
sed -i "${line_1}a\
\
/* EDITED BY SED */\n\
u32 print_once = 1;\n\
static int handle_rdtsc_interception(struct kvm_vcpu *vcpu)\n\
{\n\
static u64 rdtsc_fake = 0;\n\
static u64 rdtsc_prev = 0;\n\
u64 rdtsc_real = rdtsc();\n\
if(print_once)\n\
{\n\
printk(\"[handle_rdtsc] fake rdtsc svm function is working\\n\");\n\
print_once = 0;\n\
rdtsc_fake = rdtsc_real;\n\
}\n\
\n\
if(rdtsc_prev != 0)\n\
{\n\
if(rdtsc_real > rdtsc_prev)\n\
{\n\
u64 diff = rdtsc_real - rdtsc_prev;\n\
u64 fake_diff = diff / 20; // if you have 3.2Ghz on your vm, change 20 to 16\n\
rdtsc_fake += fake_diff;\n\
}\n\
}\n\
if(rdtsc_fake > rdtsc_real)\n\
{\n\
rdtsc_fake = rdtsc_real;\n\
}\n\
rdtsc_prev = rdtsc_real;\n\
\n\
vcpu->arch.regs[VCPU_REGS_RAX] = rdtsc_fake & -1u;\n\
vcpu->arch.regs[VCPU_REGS_RDX] = (rdtsc_fake >> 32) & -1u;\n\
\n\
return svm_skip_emulated_instruction(vcpu);\n\
}" "$(pwd)/linux/arch/x86/kvm/svm/svm.c"
line_2=$(( $(grep -n "svm_set_intercept(svm, INTERCEPT_RSM);" linux/arch/x86/kvm/svm/svm.c | awk '{print $1;}' | cut -f1 -d ':')+0))
sed -i "${line_2}a\
svm_set_intercept(svm, INTERCEPT_RDTSC);" "$(pwd)/linux/arch/x86/kvm/svm/svm.c"
line_3=$(( $(grep -n "SVM_EXIT_VMGEXIT" linux/arch/x86/kvm/svm/svm.c | awk '{print $1;}' | cut -f1 -d ':')+0))
sed -i "${line_3}a\
[SVM_EXIT_RDTSC] = handle_rdtsc_interception" "$(pwd)/linux/arch/x86/kvm/svm/svm.c"
elif [ $cpu_brand = "GenuineIntel" ] && [ -z $(grep -r "EDITED BY SED" "$(pwd)linux/arch/x86/kvm/vmx/vmx.c") ]; then
sed -i '5984a\
\
/* EDITED BY SED */ \
static u32 print_once = 1; \
static int handle_rdtsc(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 vmx 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 / 16; // if you have 4.2Ghz on your vm, change 16 to 20 \
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 skip_emulated_instruction(vcpu); \
}' "$(pwd)/linux/arch/x86/kvm/vmx/vmx.c"
sed -i '6076a\
[EXIT_REASON_RDTSC] = handle_rdtsc,' "$(pwd)/linux/arch/x86/kvm/vmx/vmx.c"
fi