Skip to content

Commit 73cdc91

Browse files
committed
Pinning vcpu to cpu to work around a hang issue on Intel.
1 parent 2f2fb77 commit 73cdc91

4 files changed

Lines changed: 42 additions & 35 deletions

File tree

gvm-main.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static PCALLBACK_OBJECT power_callback;
2929
static PVOID power_callback_handle;
3030
static int suspend;
3131
static atomic_t suspend_wait;
32+
char CPUString[13];
3233

3334
DRIVER_INITIALIZE DriverEntry;
3435

@@ -82,7 +83,6 @@ VOID gvmDriverUnload(PDRIVER_OBJECT pDrvObj)
8283
//XXX: Clean up other devices?
8384
PDEVICE_OBJECT pDevObj = pDrvObj->DeviceObject;
8485
UNICODE_STRING DosDeviceName;
85-
char CPUString[13];
8686
unsigned int eax = 0;
8787

8888
if (power_callback_handle)
@@ -379,8 +379,6 @@ NTSTATUS _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
379379
struct gvm_device_extension *pDevExt;
380380
NTSTATUS rc;
381381
int r;
382-
char CPUString[13];
383-
unsigned int eax = 0;
384382

385383
rc = NtKrUtilsInit();
386384
if (!NT_SUCCESS(rc))
@@ -393,14 +391,9 @@ NTSTATUS _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
393391
return STATUS_NO_MEMORY;
394392
RtlZeroBytes(pZeroPage, PAGE_SIZE);
395393

396-
RtlZeroBytes(CPUString, 13);
397-
cpuid(0, &eax,
398-
(unsigned int *)&CPUString[0],
399-
(unsigned int *)&CPUString[8],
400-
(unsigned int *)&CPUString[4]);
401-
if (strcmp("GenuineIntel", CPUString) == 0)
394+
if (is_Intel())
402395
r = vmx_init();
403-
else if (strcmp("AuthenticAMD", CPUString) == 0)
396+
else if (is_AMD())
404397
r = svm_init();
405398
else {
406399
DbgPrint("Processor %s is not supported\n", CPUString);

ntkrutils.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct cpumask __cpu_online_mask;
4848
struct cpumask *cpu_online_mask = &__cpu_online_mask;
4949
unsigned int cpu_online_count;
5050
u64 max_pagen;
51+
char CPUString[13];
5152

5253
DEFINE_PER_CPU(struct cpu_getput_cxt, cpu_getput_cxt);
5354

@@ -536,6 +537,13 @@ NTSTATUS NtKrUtilsInit(void)
536537
NTSTATUS rc;
537538
int cpu;
538539
PROCESSOR_NUMBER cpu_number;
540+
unsigned int eax;
541+
542+
RtlZeroBytes(CPUString, 13);
543+
cpuid(0, &eax,
544+
(unsigned int *)&CPUString[0],
545+
(unsigned int *)&CPUString[8],
546+
(unsigned int *)&CPUString[4]);
539547

540548
cpu_features_init();
541549

ntkrutils.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,5 +1287,20 @@ static inline void xsetbv(u32 index, u64 value)
12871287
_xsetbv(index, value);
12881288
}
12891289

1290+
/*
1291+
* host cpu vendor
1292+
*/
1293+
extern char CPUString[13];
1294+
1295+
static __inline bool is_Intel()
1296+
{
1297+
return !strcmp("GenuineIntel", CPUString);
1298+
}
1299+
1300+
static __inline bool is_AMD()
1301+
{
1302+
return !strcmp("AuthenticAMD", CPUString);
1303+
}
1304+
12901305
extern NTSTATUS NtKrUtilsInit(void);
12911306
extern void NtKrUtilsExit(void);

virt/kvm/kvm_main.c

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,11 +1871,13 @@ static int kvm_vm_ioctl_create_vcpu(PDEVICE_OBJECT pDevObj, PIRP pIrp, void *arg
18711871
mutex_unlock(&kvm->lock);
18721872
kvm_arch_vcpu_postcreate(vcpu);
18731873

1874-
Affinity = (KAFFINITY)1 << (
1875-
cpu_online_count - 1
1876-
- 2 * vcpu->vcpu_id / cpu_online_count % 2
1877-
- vcpu->vcpu_id * 2 % cpu_online_count);
1878-
KeSetSystemAffinityThread(Affinity);
1874+
if (is_Intel()) {
1875+
Affinity = (KAFFINITY)1 << (
1876+
cpu_online_count - 1
1877+
- 2 * vcpu->vcpu_id / cpu_online_count % 2
1878+
- vcpu->vcpu_id * 2 % cpu_online_count);
1879+
KeSetSystemAffinityThread(Affinity);
1880+
}
18791881
return r;
18801882

18811883
unlock_vcpu_destroy:
@@ -1914,6 +1916,7 @@ NTSTATUS kvm_vcpu_fast_ioctl_run(PDEVICE_OBJECT pDevObj)
19141916
struct kvm_vcpu *vcpu = devext->PrivData;
19151917
LARGE_INTEGER expire;
19161918
expire.QuadPart = (u64)-10000000;
1919+
KAFFINITY Affinity;
19171920
int r = -EINVAL;
19181921

19191922
if (vcpu->kvm->process != IoGetCurrentProcess())
@@ -1928,6 +1931,13 @@ NTSTATUS kvm_vcpu_fast_ioctl_run(PDEVICE_OBJECT pDevObj)
19281931
NULL,
19291932
KernelMode,
19301933
NULL);
1934+
if (is_Intel()) {
1935+
Affinity = (KAFFINITY)1 << (
1936+
cpu_online_count - 1
1937+
- 2 * vcpu->vcpu_id / cpu_online_count % 2
1938+
- vcpu->vcpu_id * 2 % cpu_online_count);
1939+
KeSetSystemAffinityThread(Affinity);
1940+
}
19311941
}
19321942
/* vcpu_run has to return to user space periodically otherwise
19331943
* vcpu thread could hang when process terminates.
@@ -1959,26 +1969,7 @@ NTSTATUS kvm_vcpu_ioctl(PDEVICE_OBJECT pDevObj, PIRP pIrp,
19591969

19601970
switch (ioctl) {
19611971
case GVM_RUN:
1962-
r = -EINVAL;
1963-
if (vcpu->thread != PsGetCurrentThread()) {
1964-
vcpu->thread = PsGetCurrentThread();
1965-
KeInitializeApc(&vcpu->apc, vcpu->thread,
1966-
OriginalApcEnvironment,
1967-
gvmWaitSuspend,
1968-
NULL,
1969-
NULL,
1970-
KernelMode,
1971-
NULL);
1972-
}
1973-
/* vcpu_run has to return to user space periodically otherwise
1974-
* vcpu thread could hang when process terminates.
1975-
*/
1976-
KeSetTimer(&vcpu->run_timer, expire, &vcpu->run_timer_dpc);
1977-
1978-
r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
1979-
1980-
KeCancelTimer(&vcpu->run_timer);
1981-
KeInitializeTimer(&vcpu->run_timer);
1972+
r = kvm_vcpu_fast_ioctl_run(pDevObj);
19821973
break;
19831974
case GVM_VCPU_MMAP:
19841975
r = -EINVAL;

0 commit comments

Comments
 (0)