Skip to content

Commit 7d7f7da

Browse files
Wanpeng Libonzini
authored andcommitted
KVM: LAPIC: extract start_sw_period() to handle periodic/oneshot mode
Extract start_sw_period() to handle periodic/oneshot mode, it will be used by later patch. Cc: Paolo Bonzini <[email protected]> Cc: Radim Krčmář <[email protected]> Cc: Yunhong Jiang <[email protected]> Signed-off-by: Wanpeng Li <[email protected]> Signed-off-by: Radim Krčmář <[email protected]>
1 parent ce35ef2 commit 7d7f7da

File tree

1 file changed

+47
-42
lines changed

1 file changed

+47
-42
lines changed

arch/x86/kvm/lapic.c

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,50 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic)
13471347
local_irq_restore(flags);
13481348
}
13491349

1350+
static void start_sw_period(struct kvm_lapic *apic)
1351+
{
1352+
ktime_t now;
1353+
1354+
/* lapic timer in oneshot or periodic mode */
1355+
now = apic->lapic_timer.timer.base->get_time();
1356+
apic->lapic_timer.period = (u64)kvm_lapic_get_reg(apic, APIC_TMICT)
1357+
* APIC_BUS_CYCLE_NS * apic->divide_count;
1358+
1359+
if (!apic->lapic_timer.period)
1360+
return;
1361+
/*
1362+
* Do not allow the guest to program periodic timers with small
1363+
* interval, since the hrtimers are not throttled by the host
1364+
* scheduler.
1365+
*/
1366+
if (apic_lvtt_period(apic)) {
1367+
s64 min_period = min_timer_period_us * 1000LL;
1368+
1369+
if (apic->lapic_timer.period < min_period) {
1370+
pr_info_ratelimited(
1371+
"kvm: vcpu %i: requested %lld ns "
1372+
"lapic timer period limited to %lld ns\n",
1373+
apic->vcpu->vcpu_id,
1374+
apic->lapic_timer.period, min_period);
1375+
apic->lapic_timer.period = min_period;
1376+
}
1377+
}
1378+
1379+
hrtimer_start(&apic->lapic_timer.timer,
1380+
ktime_add_ns(now, apic->lapic_timer.period),
1381+
HRTIMER_MODE_ABS_PINNED);
1382+
1383+
apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
1384+
PRIx64 ", "
1385+
"timer initial count 0x%x, period %lldns, "
1386+
"expire @ 0x%016" PRIx64 ".\n", __func__,
1387+
APIC_BUS_CYCLE_NS, ktime_to_ns(now),
1388+
kvm_lapic_get_reg(apic, APIC_TMICT),
1389+
apic->lapic_timer.period,
1390+
ktime_to_ns(ktime_add_ns(now,
1391+
apic->lapic_timer.period)));
1392+
}
1393+
13501394
bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu)
13511395
{
13521396
if (!lapic_in_kernel(vcpu))
@@ -1424,50 +1468,11 @@ EXPORT_SYMBOL_GPL(kvm_lapic_switch_to_sw_timer);
14241468

14251469
static void start_apic_timer(struct kvm_lapic *apic)
14261470
{
1427-
ktime_t now;
1428-
14291471
atomic_set(&apic->lapic_timer.pending, 0);
14301472

1431-
if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) {
1432-
/* lapic timer in oneshot or periodic mode */
1433-
now = apic->lapic_timer.timer.base->get_time();
1434-
apic->lapic_timer.period = (u64)kvm_lapic_get_reg(apic, APIC_TMICT)
1435-
* APIC_BUS_CYCLE_NS * apic->divide_count;
1436-
1437-
if (!apic->lapic_timer.period)
1438-
return;
1439-
/*
1440-
* Do not allow the guest to program periodic timers with small
1441-
* interval, since the hrtimers are not throttled by the host
1442-
* scheduler.
1443-
*/
1444-
if (apic_lvtt_period(apic)) {
1445-
s64 min_period = min_timer_period_us * 1000LL;
1446-
1447-
if (apic->lapic_timer.period < min_period) {
1448-
pr_info_ratelimited(
1449-
"kvm: vcpu %i: requested %lld ns "
1450-
"lapic timer period limited to %lld ns\n",
1451-
apic->vcpu->vcpu_id,
1452-
apic->lapic_timer.period, min_period);
1453-
apic->lapic_timer.period = min_period;
1454-
}
1455-
}
1456-
1457-
hrtimer_start(&apic->lapic_timer.timer,
1458-
ktime_add_ns(now, apic->lapic_timer.period),
1459-
HRTIMER_MODE_ABS_PINNED);
1460-
1461-
apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
1462-
PRIx64 ", "
1463-
"timer initial count 0x%x, period %lldns, "
1464-
"expire @ 0x%016" PRIx64 ".\n", __func__,
1465-
APIC_BUS_CYCLE_NS, ktime_to_ns(now),
1466-
kvm_lapic_get_reg(apic, APIC_TMICT),
1467-
apic->lapic_timer.period,
1468-
ktime_to_ns(ktime_add_ns(now,
1469-
apic->lapic_timer.period)));
1470-
} else if (apic_lvtt_tscdeadline(apic)) {
1473+
if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic))
1474+
start_sw_period(apic);
1475+
else if (apic_lvtt_tscdeadline(apic)) {
14711476
if (!(kvm_x86_ops->set_hv_timer && start_hv_tscdeadline(apic)))
14721477
start_sw_tscdeadline(apic);
14731478
}

0 commit comments

Comments
 (0)