Skip to content

Commit 2b4b5a4

Browse files
committed
Force vcpu thread back to user space at least every second.
This is to avoid dead loop in vcpu thread when user space is killed forcefully.
1 parent 8c40c3f commit 2b4b5a4

3 files changed

Lines changed: 21 additions & 0 deletions

File tree

arch/x86/kvm/x86.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4760,6 +4760,7 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
47604760
break;
47614761
}
47624762
if (test_and_clear_bit(0, (size_t *)&vcpu->run->user_event_pending)) {
4763+
r = 0;
47634764
vcpu->run->exit_reason = GVM_EXIT_INTR;
47644765
break;
47654766
}

include/linux/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ struct kvm_vcpu {
184184
u64 blocked;
185185
PETHREAD thread;
186186
KAPC apc;
187+
KTIMER run_timer;
188+
KDPC run_timer_dpc;
187189
struct kvm_vcpu_stat stat;
188190
bool valid_wakeup;
189191

virt/kvm/kvm_main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,12 @@ void kvm_reload_remote_mmus(struct kvm *kvm)
246246
kvm_make_all_cpus_request(kvm, GVM_REQ_MMU_RELOAD);
247247
}
248248

249+
void kvm_vcpu_run_timer_func(KDPC *dpc, void* context, void *arg1, void *arg2)
250+
{
251+
struct kvm_vcpu *vcpu = (struct kvm_vcpu *)context;
252+
vcpu->run->user_event_pending = 1;
253+
}
254+
249255
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
250256
{
251257
int r;
@@ -274,6 +280,8 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
274280
vcpu->preempted = false;
275281

276282
KeInitializeEvent(&vcpu->kick_event, SynchronizationEvent, FALSE);
283+
KeInitializeTimer(&vcpu->run_timer);
284+
KeInitializeDpc(&vcpu->run_timer_dpc, kvm_vcpu_run_timer_func, vcpu);
277285

278286
r = kvm_arch_vcpu_init(vcpu);
279287
if (r < 0)
@@ -2039,6 +2047,8 @@ NTSTATUS kvm_vcpu_ioctl(PDEVICE_OBJECT pDevObj, PIRP pIrp,
20392047
int r;
20402048
struct kvm_fpu *fpu = NULL;
20412049
struct kvm_sregs *kvm_sregs = NULL;
2050+
LARGE_INTEGER expire;
2051+
expire.QuadPart = (u64)-10000000;
20422052

20432053
if (vcpu->kvm->process != IoGetCurrentProcess())
20442054
return -EIO;
@@ -2056,7 +2066,15 @@ NTSTATUS kvm_vcpu_ioctl(PDEVICE_OBJECT pDevObj, PIRP pIrp,
20562066
KernelMode,
20572067
NULL);
20582068
}
2069+
/* vcpu_run has to return to user space periodically otherwise
2070+
* vcpu thread could hang when process terminates.
2071+
*/
2072+
KeSetTimer(&vcpu->run_timer, expire, &vcpu->run_timer_dpc);
2073+
20592074
r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
2075+
2076+
KeCancelTimer(&vcpu->run_timer);
2077+
KeInitializeTimer(&vcpu->run_timer);
20602078
break;
20612079
case GVM_VCPU_MMAP:
20622080
r = -EINVAL;

0 commit comments

Comments
 (0)