Skip to content

Commit eab0637

Browse files
committed
Use high resolution timer API (ExXXXTimer) to implement LAPIC timer.
This is to replace the regular Windows KeXXXTimer API, which suffered from insufficient timer resolution and led to LAPIC timer calibration failure when calibrating against the legacy IRQ0 timer. However, according to Microfost online documentation here: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/high-resolution-timers Using newer timer APIs does make the AEHD driver not compatible with Windows 7 any more. But Microsoft has already removed signing support for Windows 7 anyway. Change-Id: If58dc6b984d6eb3c8c330dd66522c9481de55ca7
1 parent 77af915 commit eab0637

4 files changed

Lines changed: 44 additions & 21 deletions

File tree

aehd/aehd.vcxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,24 @@
2222
</PropertyGroup>
2323
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2424
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
25-
<TargetVersion>Windows7</TargetVersion>
25+
<TargetVersion>WindowsV6.3</TargetVersion>
2626
<UseDebugLibraries>true</UseDebugLibraries>
2727
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
2828
<ConfigurationType>Driver</ConfigurationType>
2929
<DriverType>WDM</DriverType>
3030
<SpectreMitigation>false</SpectreMitigation>
3131
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
32-
<_NT_TARGET_VERSION>0x0601</_NT_TARGET_VERSION>
32+
<_NT_TARGET_VERSION>0x0603</_NT_TARGET_VERSION>
3333
</PropertyGroup>
3434
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
35-
<TargetVersion>Windows7</TargetVersion>
35+
<TargetVersion>WindowsV6.3</TargetVersion>
3636
<UseDebugLibraries>false</UseDebugLibraries>
3737
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
3838
<ConfigurationType>Driver</ConfigurationType>
3939
<DriverType>WDM</DriverType>
4040
<SpectreMitigation>false</SpectreMitigation>
4141
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
42-
<_NT_TARGET_VERSION>0x0601</_NT_TARGET_VERSION>
42+
<_NT_TARGET_VERSION>0x0603</_NT_TARGET_VERSION>
4343
</PropertyGroup>
4444
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
4545
<ImportGroup Label="PropertySheets">

arch/x86/kvm/lapic.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,7 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu)
14501450
return;
14511451

14521452
hrtimer_cancel(&apic->lapic_timer.timer);
1453+
hrtimer_delete(&apic->lapic_timer.timer);
14531454

14541455
if (apic->regs)
14551456
free_page((size_t)apic->regs);
@@ -1670,8 +1671,9 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
16701671
}
16711672
apic->vcpu = vcpu;
16721673

1673-
hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
1674-
HRTIMER_MODE_ABS_PINNED);
1674+
if (hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
1675+
HRTIMER_MODE_ABS_PINNED))
1676+
goto nomem_free_apic;
16751677
apic->lapic_timer.timer.function = apic_timer_fn;
16761678

16771679
/*

ntkrutils.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,54 +129,74 @@ NTSTATUS aehdGetCpuOnlineMap(void)
129129
/*
130130
Timer Stuffs
131131
*/
132-
void timer_dpc_fn(struct _KDPC *Dpc,
133-
PVOID DeferredContext,
134-
PVOID SystemArgument1,
135-
PVOID SystemArgument2)
132+
void timer_callback_fn(PEX_TIMER ex_timer, PVOID ex_timer_context)
136133
{
137-
struct hrtimer *timer = (struct hrtimer*)DeferredContext;
134+
struct hrtimer *timer = (struct hrtimer*)ex_timer_context;
138135
enum hrtimer_restart ret = timer->function(timer);
139136
if(ret == HRTIMER_RESTART)
140137
hrtimer_restart(timer);
141138
}
142139

143-
void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode)
140+
int hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode)
144141
{
145-
KeInitializeTimerEx(&timer->ktimer, SynchronizationTimer);
142+
timer->ex_timer = ExAllocateTimer(timer_callback_fn, timer, EX_TIMER_HIGH_RESOLUTION);
143+
if (!timer->ex_timer)
144+
return 1;
145+
ExInitializeSetTimerParameters(&timer->ext_set_parameters);
146146
timer->base = &timer->base_hack;
147147
timer->base->get_time = ktime_get;
148-
KeInitializeThreadedDpc(&timer->kdpc, (PKDEFERRED_ROUTINE)timer_dpc_fn, timer);
148+
return 0;
149149
}
150150

151151
int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
152152
{
153153
int r;
154+
LARGE_INTEGER time;
155+
LONGLONG duetime;
154156
// We only emulate hrtimer mode that KVM uses
155157
ASSERTMSG("Unsupported hrtimer mode", mode == HRTIMER_MODE_ABS_PINNED);
156158
timer->due_time.QuadPart = ktime_to_ns(tim);
157159
timer->node.expires = tim;
158160
do_div(&(u64)timer->due_time.QuadPart, 100);
159-
r = (int)KeSetTimer(&timer->ktimer, timer->due_time, &timer->kdpc);
161+
KeQuerySystemTime(&time);
162+
duetime = timer->due_time.QuadPart - time.QuadPart;
163+
if (duetime < 0)
164+
duetime = 0;
165+
r = (int)ExSetTimer(timer->ex_timer, -duetime, 0, &timer->ext_set_parameters);
160166
return r;
161167
}
162168

163169
int hrtimer_cancel(struct hrtimer *timer)
164170
{
165171
int r;
166-
r = KeCancelTimer(&timer->ktimer);
172+
r = ExCancelTimer(timer->ex_timer, NULL);
167173
return r;
168174
}
169175

170176
int hrtimer_restart(struct hrtimer* timer)
171177
{
172178
int r;
173-
//timer->due_time.QuadPart = (ktime_to_ns(ktime_get()) - ktime_to_ns(timer->node.expires)) / 100;
179+
LARGE_INTEGER time;
180+
LONGLONG duetime;
181+
174182
timer->due_time.QuadPart = ktime_to_ns(timer->node.expires);
175183
do_div(&(u64)timer->due_time.QuadPart, 100);
176-
r = (int)KeSetTimer(&timer->ktimer, timer->due_time, &timer->kdpc);
184+
KeQuerySystemTime(&time);
185+
duetime = timer->due_time.QuadPart - time.QuadPart;
186+
if (duetime < 0)
187+
duetime = 0;
188+
r = (int)ExSetTimer(timer->ex_timer, -duetime, 0, &timer->ext_set_parameters);
177189
return r;
178190
}
179191

192+
void hrtimer_delete(struct hrtimer* timer)
193+
{
194+
EXT_DELETE_PARAMETERS ext_delete_parameters;
195+
196+
ExInitializeDeleteTimerParameters(&ext_delete_parameters);
197+
ExDeleteTimer(timer->ex_timer, TRUE, TRUE, &ext_delete_parameters);
198+
}
199+
180200
struct list_head aehd_mmap_list;
181201
DEFINE_RAW_SPINLOCK(aehd_mmap_lock);
182202

ntkrutils.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,16 +596,17 @@ struct hrtimer
596596
enum hrtimer_restart (*function)(struct hrtimer *);
597597
struct hrtimer_clock_base *base;
598598
size_t state;
599-
KTIMER ktimer;
600-
KDPC kdpc;
599+
PEX_TIMER ex_timer;
600+
EXT_SET_PARAMETERS ext_set_parameters;
601601
LARGE_INTEGER due_time;
602602
struct hrtimer_clock_base base_hack;
603603
};
604604

605-
void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode);
605+
int hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode);
606606
int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);
607607
int hrtimer_cancel(struct hrtimer *timer);
608608
int hrtimer_restart(struct hrtimer* timer);
609+
void hrtimer_delete(struct hrtimer* timer);
609610

610611
static __forceinline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 delta)
611612
{

0 commit comments

Comments
 (0)