-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkernel.patch
More file actions
192 lines (179 loc) · 7.34 KB
/
Copy pathkernel.patch
File metadata and controls
192 lines (179 loc) · 7.34 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 282c91c6aa33..99eaf8c50117 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1291,6 +1291,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); //added line AICodo
if (!kvm_mwait_in_guest(vcpu->kvm)) {
svm_set_intercept(svm, INTERCEPT_MONITOR);
@@ -3300,6 +3301,29 @@ 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(KERN_ALERT "[handle_rdtsc] svm.c fake rdtsc svm function is working diff 20 AICodo \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,
@@ -3371,6 +3395,7 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[SVM_EXIT_RSM] = rsm_interception,
[SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception,
[SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception,
+ [SVM_EXIT_RDTSC] = handle_rdtsc_interception, //added line AICodo
#ifdef CONFIG_KVM_AMD_SEV
[SVM_EXIT_VMGEXIT] = sev_handle_vmgexit,
#endif
@@ -5500,6 +5525,7 @@ static int __init svm_init(void)
{
int r;
+ printk(KERN_ALERT "kvm-amd.ko AICodo v2.0 Start,ok!!!\n");//added line AICodo
__unused_size_checks();
if (!kvm_is_svm_supported())
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 3b92f893b239..092ecac438dc 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -247,6 +247,13 @@ static const struct {
#define L1D_CACHE_ORDER 4
static void *vmx_l1d_flush_pages;
+static __always_inline u64 mul_u64_u64_shr0(u64 a, u64 mul, unsigned int shift){ return (u64)(((unsigned __int128)a * mul) >> shift); }
+static inline u64 __scale_tsc0(u64 ratio, u64 tsc){ return mul_u64_u64_shr0(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits); }
+static inline u64 kvm_scale_tsc0(u64 tsc, u64 ratio){
+ u64 _tsc = tsc;
+ if (ratio != kvm_caps.default_tsc_scaling_ratio){_tsc = __scale_tsc0(ratio, tsc);}
+ return _tsc;
+}
static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
{
struct page *page;
@@ -4492,11 +4499,12 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx)
* Not used by KVM, but fully supported for nesting, i.e. are allowed in
* vmcs12 and propagated to vmcs02 when set in vmcs12.
*/
- exec_control &= ~(CPU_BASED_RDTSC_EXITING |
+ exec_control &= ~(
CPU_BASED_USE_IO_BITMAPS |
CPU_BASED_MONITOR_TRAP_FLAG |
CPU_BASED_PAUSE_EXITING);
+ exec_control |= CPU_BASED_RDTSC_EXITING; //Ensure handle_rdtsc() is used.added line AICodo
/* INTR_WINDOW_EXITING and NMI_WINDOW_EXITING are toggled dynamically */
exec_control &= ~(CPU_BASED_INTR_WINDOW_EXITING |
CPU_BASED_NMI_WINDOW_EXITING);
@@ -6087,6 +6095,33 @@ static int handle_bus_lock_vmexit(struct kvm_vcpu *vcpu)
return 1;
}
+static u32 print_once_rdtsc = 1;
+static int handle_rdtsc(struct kvm_vcpu *vcpu) {
+ u64 offset = vcpu->arch.tsc_offset;
+ u64 ratio = vcpu->arch.tsc_scaling_ratio;
+ u64 rdtsc_fake;
+ if(print_once_rdtsc){
+ printk(KERN_ALERT "[handle_rdtsc] vmx.c fake rdtsc vmx function is working AICodo\n");
+ print_once_rdtsc = 0;
+ }
+ if (vmx_get_cpl(vcpu) != 0 || !is_protmode(vcpu)){ratio /= 4;}
+ rdtsc_fake = kvm_scale_tsc0(rdtsc(), ratio) + offset;
+ vcpu->arch.regs[VCPU_REGS_RAX] = rdtsc_fake & -1u;
+ vcpu->arch.regs[VCPU_REGS_RDX] = (rdtsc_fake >> 32) & -1u;
+ return skip_emulated_instruction(vcpu);
+}
+static u32 print_once_rdtscp = 1;
+static int handle_rdtscp(struct kvm_vcpu *vcpu) {
+ if(print_once_rdtscp){
+ printk(KERN_ALERT "[handle_rdtscp] vmx.c fake rdtscp vmx function is working AICodo\n");
+ print_once_rdtscp = 0;
+ }
+ vcpu->arch.regs[VCPU_REGS_RCX] = vmcs_read16(VIRTUAL_PROCESSOR_ID);
+ return handle_rdtsc(vcpu);
+}
+
+static int handle_umwait(struct kvm_vcpu *vcpu){return skip_emulated_instruction(vcpu);}
+static int handle_tpause(struct kvm_vcpu *vcpu){return skip_emulated_instruction(vcpu);}
static int handle_notify(struct kvm_vcpu *vcpu)
{
unsigned long exit_qual = vmx_get_exit_qual(vcpu);
@@ -6171,6 +6206,10 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_ENCLS] = handle_encls,
[EXIT_REASON_BUS_LOCK] = handle_bus_lock_vmexit,
[EXIT_REASON_NOTIFY] = handle_notify,
+ [EXIT_REASON_RDTSC] = handle_rdtsc, //added line AICodo
+ [EXIT_REASON_RDTSCP] = handle_rdtscp, //added line AICodo
+ [EXIT_REASON_UMWAIT] = handle_umwait, //added line AICodo
+ [EXIT_REASON_TPAUSE] = handle_tpause, //added line AICodo
};
static const int kvm_vmx_max_exit_handlers =
@@ -8613,6 +8652,7 @@ module_exit(vmx_exit);
static int __init vmx_init(void)
{
int r, cpu;
+ printk(KERN_ALERT "kvm-intel.ko AICodo v2.0 Start,ok!!!\n");//added line AICodo
if (!kvm_is_vmx_supported())
return -EOPNOTSUPP;
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 951e44dc9d0e..ced0ca3ef380 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -529,6 +529,7 @@ static inline u8 vmx_get_rvi(void)
CPU_BASED_MONITOR_EXITING | \
CPU_BASED_INVLPG_EXITING | \
CPU_BASED_RDPMC_EXITING | \
+ CPU_BASED_RDTSC_EXITING | \
CPU_BASED_INTR_WINDOW_EXITING)
#ifdef CONFIG_X86_64
@@ -542,8 +543,7 @@ static inline u8 vmx_get_rvi(void)
#endif
#define KVM_OPTIONAL_VMX_CPU_BASED_VM_EXEC_CONTROL \
- (CPU_BASED_RDTSC_EXITING | \
- CPU_BASED_TPR_SHADOW | \
+ (CPU_BASED_TPR_SHADOW | \
CPU_BASED_USE_IO_BITMAPS | \
CPU_BASED_MONITOR_TRAP_FLAG | \
CPU_BASED_USE_MSR_BITMAPS | \
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9e57dd990a26..5e567c10be35 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8928,6 +8928,14 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu)
kvm_run->exit_reason = KVM_EXIT_DEBUG;
return 0;
}
+ if (KVM_GUESTDBG_SINGLESTEP ) {
+ printk(KERN_ALERT "kvm_vcpu_do_singlestep if (KVM_GUESTDBG_SINGLESTEP) AICodo return 0\n");
+ kvm_run->debug.arch.dr6 = DR6_BS | DR6_ACTIVE_LOW | 1;
+ kvm_run->debug.arch.pc = kvm_get_linear_rip(vcpu);
+ kvm_run->debug.arch.exception = DB_VECTOR;
+ kvm_run->exit_reason = KVM_EXIT_DEBUG;
+ return 0;
+ }
kvm_queue_exception_p(vcpu, DB_VECTOR, DR6_BS);
return 1;
}
@@ -14046,6 +14054,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_rmp_fault);
static int __init kvm_x86_init(void)
{
+ printk(KERN_ALERT "kvm.ko AICodo v2.0 Start,ok!!!\n");
kvm_init_xstate_sizes();
kvm_mmu_x86_module_init();