@@ -9180,6 +9180,7 @@ static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
9180
9180
likely (!pic_in_kernel (vcpu -> kvm ));
9181
9181
}
9182
9182
9183
+ /* Called within kvm->srcu read side. */
9183
9184
static void post_kvm_run_save (struct kvm_vcpu * vcpu )
9184
9185
{
9185
9186
struct kvm_run * kvm_run = vcpu -> run ;
@@ -9188,16 +9189,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
9188
9189
kvm_run -> cr8 = kvm_get_cr8 (vcpu );
9189
9190
kvm_run -> apic_base = kvm_get_apic_base (vcpu );
9190
9191
9191
- /*
9192
- * The call to kvm_ready_for_interrupt_injection() may end up in
9193
- * kvm_xen_has_interrupt() which may require the srcu lock to be
9194
- * held, to protect against changes in the vcpu_info address.
9195
- */
9196
- vcpu -> srcu_idx = srcu_read_lock (& vcpu -> kvm -> srcu );
9197
9192
kvm_run -> ready_for_interrupt_injection =
9198
9193
pic_in_kernel (vcpu -> kvm ) ||
9199
9194
kvm_vcpu_ready_for_interrupt_injection (vcpu );
9200
- srcu_read_unlock (& vcpu -> kvm -> srcu , vcpu -> srcu_idx );
9201
9195
9202
9196
if (is_smm (vcpu ))
9203
9197
kvm_run -> flags |= KVM_RUN_X86_SMM ;
@@ -9815,6 +9809,7 @@ void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
9815
9809
EXPORT_SYMBOL_GPL (__kvm_request_immediate_exit );
9816
9810
9817
9811
/*
9812
+ * Called within kvm->srcu read side.
9818
9813
* Returns 1 to let vcpu_run() continue the guest execution loop without
9819
9814
* exiting to the userspace. Otherwise, the value will be returned to the
9820
9815
* userspace.
@@ -10193,6 +10188,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
10193
10188
return r ;
10194
10189
}
10195
10190
10191
+ /* Called within kvm->srcu read side. */
10196
10192
static inline int vcpu_block (struct kvm * kvm , struct kvm_vcpu * vcpu )
10197
10193
{
10198
10194
bool hv_timer ;
@@ -10252,12 +10248,12 @@ static inline bool kvm_vcpu_running(struct kvm_vcpu *vcpu)
10252
10248
!vcpu -> arch .apf .halted );
10253
10249
}
10254
10250
10251
+ /* Called within kvm->srcu read side. */
10255
10252
static int vcpu_run (struct kvm_vcpu * vcpu )
10256
10253
{
10257
10254
int r ;
10258
10255
struct kvm * kvm = vcpu -> kvm ;
10259
10256
10260
- vcpu -> srcu_idx = srcu_read_lock (& kvm -> srcu );
10261
10257
vcpu -> arch .l1tf_flush_l1d = true;
10262
10258
10263
10259
for (;;) {
@@ -10285,14 +10281,12 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
10285
10281
if (__xfer_to_guest_mode_work_pending ()) {
10286
10282
srcu_read_unlock (& kvm -> srcu , vcpu -> srcu_idx );
10287
10283
r = xfer_to_guest_mode_handle_work (vcpu );
10284
+ vcpu -> srcu_idx = srcu_read_lock (& kvm -> srcu );
10288
10285
if (r )
10289
10286
return r ;
10290
- vcpu -> srcu_idx = srcu_read_lock (& kvm -> srcu );
10291
10287
}
10292
10288
}
10293
10289
10294
- srcu_read_unlock (& kvm -> srcu , vcpu -> srcu_idx );
10295
-
10296
10290
return r ;
10297
10291
}
10298
10292
@@ -10398,13 +10392,15 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
10398
10392
int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu * vcpu )
10399
10393
{
10400
10394
struct kvm_run * kvm_run = vcpu -> run ;
10395
+ struct kvm * kvm = vcpu -> kvm ;
10401
10396
int r ;
10402
10397
10403
10398
vcpu_load (vcpu );
10404
10399
kvm_sigset_activate (vcpu );
10405
10400
kvm_run -> flags = 0 ;
10406
10401
kvm_load_guest_fpu (vcpu );
10407
10402
10403
+ vcpu -> srcu_idx = srcu_read_lock (& vcpu -> kvm -> srcu );
10408
10404
if (unlikely (vcpu -> arch .mp_state == KVM_MP_STATE_UNINITIALIZED )) {
10409
10405
if (kvm_run -> immediate_exit ) {
10410
10406
r = - EINTR ;
@@ -10415,7 +10411,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
10415
10411
* use before KVM has ever run the vCPU.
10416
10412
*/
10417
10413
WARN_ON_ONCE (kvm_lapic_hv_timer_in_use (vcpu ));
10414
+
10415
+ srcu_read_unlock (& kvm -> srcu , vcpu -> srcu_idx );
10418
10416
kvm_vcpu_block (vcpu );
10417
+ vcpu -> srcu_idx = srcu_read_lock (& kvm -> srcu );
10418
+
10419
10419
if (kvm_apic_accept_events (vcpu ) < 0 ) {
10420
10420
r = 0 ;
10421
10421
goto out ;
@@ -10475,8 +10475,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
10475
10475
if (kvm_run -> kvm_valid_regs )
10476
10476
store_regs (vcpu );
10477
10477
post_kvm_run_save (vcpu );
10478
- kvm_sigset_deactivate ( vcpu );
10478
+ srcu_read_unlock ( & kvm -> srcu , vcpu -> srcu_idx );
10479
10479
10480
+ kvm_sigset_deactivate (vcpu );
10480
10481
vcpu_put (vcpu );
10481
10482
return r ;
10482
10483
}
0 commit comments