@@ -10080,26 +10080,15 @@ static int complete_hypercall_exit(struct kvm_vcpu *vcpu)
10080
10080
return kvm_skip_emulated_instruction (vcpu );
10081
10081
}
10082
10082
10083
- int kvm_emulate_hypercall (struct kvm_vcpu * vcpu )
10083
+ unsigned long __kvm_emulate_hypercall (struct kvm_vcpu * vcpu , unsigned long nr ,
10084
+ unsigned long a0 , unsigned long a1 ,
10085
+ unsigned long a2 , unsigned long a3 ,
10086
+ int op_64_bit , int cpl )
10084
10087
{
10085
- unsigned long nr , a0 , a1 , a2 , a3 , ret ;
10086
- int op_64_bit ;
10087
-
10088
- if (kvm_xen_hypercall_enabled (vcpu -> kvm ))
10089
- return kvm_xen_hypercall (vcpu );
10090
-
10091
- if (kvm_hv_hypercall_enabled (vcpu ))
10092
- return kvm_hv_hypercall (vcpu );
10093
-
10094
- nr = kvm_rax_read (vcpu );
10095
- a0 = kvm_rbx_read (vcpu );
10096
- a1 = kvm_rcx_read (vcpu );
10097
- a2 = kvm_rdx_read (vcpu );
10098
- a3 = kvm_rsi_read (vcpu );
10088
+ unsigned long ret ;
10099
10089
10100
10090
trace_kvm_hypercall (nr , a0 , a1 , a2 , a3 );
10101
10091
10102
- op_64_bit = is_64_bit_hypercall (vcpu );
10103
10092
if (!op_64_bit ) {
10104
10093
nr &= 0xFFFFFFFF ;
10105
10094
a0 &= 0xFFFFFFFF ;
@@ -10108,7 +10097,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
10108
10097
a3 &= 0xFFFFFFFF ;
10109
10098
}
10110
10099
10111
- if (static_call ( kvm_x86_get_cpl )( vcpu ) != 0 ) {
10100
+ if (cpl ) {
10112
10101
ret = - KVM_EPERM ;
10113
10102
goto out ;
10114
10103
}
@@ -10169,18 +10158,49 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
10169
10158
10170
10159
WARN_ON_ONCE (vcpu -> run -> hypercall .flags & KVM_EXIT_HYPERCALL_MBZ );
10171
10160
vcpu -> arch .complete_userspace_io = complete_hypercall_exit ;
10161
+ /* stat is incremented on completion. */
10172
10162
return 0 ;
10173
10163
}
10174
10164
default :
10175
10165
ret = - KVM_ENOSYS ;
10176
10166
break ;
10177
10167
}
10168
+
10178
10169
out :
10170
+ ++ vcpu -> stat .hypercalls ;
10171
+ return ret ;
10172
+ }
10173
+ EXPORT_SYMBOL_GPL (__kvm_emulate_hypercall );
10174
+
10175
+ int kvm_emulate_hypercall (struct kvm_vcpu * vcpu )
10176
+ {
10177
+ unsigned long nr , a0 , a1 , a2 , a3 , ret ;
10178
+ int op_64_bit ;
10179
+ int cpl ;
10180
+
10181
+ if (kvm_xen_hypercall_enabled (vcpu -> kvm ))
10182
+ return kvm_xen_hypercall (vcpu );
10183
+
10184
+ if (kvm_hv_hypercall_enabled (vcpu ))
10185
+ return kvm_hv_hypercall (vcpu );
10186
+
10187
+ nr = kvm_rax_read (vcpu );
10188
+ a0 = kvm_rbx_read (vcpu );
10189
+ a1 = kvm_rcx_read (vcpu );
10190
+ a2 = kvm_rdx_read (vcpu );
10191
+ a3 = kvm_rsi_read (vcpu );
10192
+ op_64_bit = is_64_bit_hypercall (vcpu );
10193
+ cpl = static_call (kvm_x86_get_cpl )(vcpu );
10194
+
10195
+ ret = __kvm_emulate_hypercall (vcpu , nr , a0 , a1 , a2 , a3 , op_64_bit , cpl );
10196
+ if (nr == KVM_HC_MAP_GPA_RANGE && !ret )
10197
+ /* MAP_GPA tosses the request to the user space. */
10198
+ return 0 ;
10199
+
10179
10200
if (!op_64_bit )
10180
10201
ret = (u32 )ret ;
10181
10202
kvm_rax_write (vcpu , ret );
10182
10203
10183
- ++ vcpu -> stat .hypercalls ;
10184
10204
return kvm_skip_emulated_instruction (vcpu );
10185
10205
}
10186
10206
EXPORT_SYMBOL_GPL (kvm_emulate_hypercall );
0 commit comments