Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/io/vlapic.c
Show First 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* APIC timer frequency: | * APIC timer frequency: | ||||
* - arbitrary but chosen to be in the ballpark of contemporary hardware. | * - arbitrary but chosen to be in the ballpark of contemporary hardware. | ||||
* - power-of-two to avoid loss of precision when converted to a bintime. | * - power-of-two to avoid loss of precision when converted to a bintime. | ||||
*/ | */ | ||||
#define VLAPIC_BUS_FREQ (128 * 1024 * 1024) | #define VLAPIC_BUS_FREQ (128 * 1024 * 1024) | ||||
static void vlapic_set_error(struct vlapic *, uint32_t, bool); | static void vlapic_set_error(struct vlapic *, uint32_t, bool); | ||||
static void vlapic_callout_handler(void *arg); | |||||
static __inline uint32_t | static __inline uint32_t | ||||
vlapic_get_id(struct vlapic *vlapic) | vlapic_get_id(struct vlapic *vlapic) | ||||
{ | { | ||||
if (x2apic(vlapic)) | if (x2apic(vlapic)) | ||||
return (vlapic->vcpuid); | return (vlapic->vcpuid); | ||||
else | else | ||||
▲ Show 20 Lines • Show All 612 Lines • ▼ Show 20 Lines | case APIC_LVT_CMCI: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
vlapic_callout_reset(struct vlapic *vlapic, sbintime_t t) | |||||
{ | |||||
callout_reset_sbt_curcpu(&vlapic->callout, t, 0, | |||||
vlapic_callout_handler, vlapic, 0); | |||||
} | |||||
static void | |||||
vlapic_callout_handler(void *arg) | vlapic_callout_handler(void *arg) | ||||
{ | { | ||||
struct vlapic *vlapic; | struct vlapic *vlapic; | ||||
struct bintime bt, btnow; | struct bintime bt, btnow; | ||||
sbintime_t rem_sbt; | sbintime_t rem_sbt; | ||||
vlapic = arg; | vlapic = arg; | ||||
Show All 38 Lines | if (bintime_cmp(&bt, &vlapic->timer_period_bt, <)) { | ||||
vlapic->timer_fire_bt = btnow; | vlapic->timer_fire_bt = btnow; | ||||
VLAPIC_CTR2(vlapic, "vlapic timer lagging by %lu " | VLAPIC_CTR2(vlapic, "vlapic timer lagging by %lu " | ||||
"usecs, period is %lu usecs - resetting time base", | "usecs, period is %lu usecs - resetting time base", | ||||
bttosbt(bt) / SBT_1US, | bttosbt(bt) / SBT_1US, | ||||
bttosbt(vlapic->timer_period_bt) / SBT_1US); | bttosbt(vlapic->timer_period_bt) / SBT_1US); | ||||
} | } | ||||
bintime_add(&vlapic->timer_fire_bt, &vlapic->timer_period_bt); | bintime_add(&vlapic->timer_fire_bt, &vlapic->timer_period_bt); | ||||
callout_reset_sbt(&vlapic->callout, rem_sbt, 0, | vlapic_callout_reset(vlapic, rem_sbt); | ||||
vlapic_callout_handler, vlapic, 0); | |||||
} | } | ||||
done: | done: | ||||
VLAPIC_TIMER_UNLOCK(vlapic); | VLAPIC_TIMER_UNLOCK(vlapic); | ||||
} | } | ||||
void | void | ||||
vlapic_icrtmr_write_handler(struct vlapic *vlapic) | vlapic_icrtmr_write_handler(struct vlapic *vlapic) | ||||
{ | { | ||||
Show All 9 Lines | vlapic_icrtmr_write_handler(struct vlapic *vlapic) | ||||
vlapic->timer_period_bt = vlapic->timer_freq_bt; | vlapic->timer_period_bt = vlapic->timer_freq_bt; | ||||
bintime_mul(&vlapic->timer_period_bt, icr_timer); | bintime_mul(&vlapic->timer_period_bt, icr_timer); | ||||
if (icr_timer != 0) { | if (icr_timer != 0) { | ||||
binuptime(&vlapic->timer_fire_bt); | binuptime(&vlapic->timer_fire_bt); | ||||
bintime_add(&vlapic->timer_fire_bt, &vlapic->timer_period_bt); | bintime_add(&vlapic->timer_fire_bt, &vlapic->timer_period_bt); | ||||
sbt = bttosbt(vlapic->timer_period_bt); | sbt = bttosbt(vlapic->timer_period_bt); | ||||
callout_reset_sbt(&vlapic->callout, sbt, 0, | vlapic_callout_reset(vlapic, sbt); | ||||
vlapic_callout_handler, vlapic, 0); | |||||
} else | } else | ||||
callout_stop(&vlapic->callout); | callout_stop(&vlapic->callout); | ||||
VLAPIC_TIMER_UNLOCK(vlapic); | VLAPIC_TIMER_UNLOCK(vlapic); | ||||
} | } | ||||
/* | /* | ||||
* This function populates 'dmask' with the set of vcpus that match the | * This function populates 'dmask' with the set of vcpus that match the | ||||
▲ Show 20 Lines • Show All 857 Lines • ▼ Show 20 Lines | vlapic_reset_callout(struct vlapic *vlapic, uint32_t ccr) | ||||
bt = vlapic->timer_freq_bt; | bt = vlapic->timer_freq_bt; | ||||
bintime_mul(&bt, ccr); | bintime_mul(&bt, ccr); | ||||
if (ccr != 0) { | if (ccr != 0) { | ||||
binuptime(&vlapic->timer_fire_bt); | binuptime(&vlapic->timer_fire_bt); | ||||
bintime_add(&vlapic->timer_fire_bt, &bt); | bintime_add(&vlapic->timer_fire_bt, &bt); | ||||
sbt = bttosbt(bt); | sbt = bttosbt(bt); | ||||
callout_reset_sbt(&vlapic->callout, sbt, 0, | vlapic_callout_reset(vlapic, sbt); | ||||
vlapic_callout_handler, vlapic, 0); | |||||
} else { | } else { | ||||
/* even if the CCR was 0, periodic timers should be reset */ | /* even if the CCR was 0, periodic timers should be reset */ | ||||
if (vlapic_periodic_timer(vlapic)) { | if (vlapic_periodic_timer(vlapic)) { | ||||
binuptime(&vlapic->timer_fire_bt); | binuptime(&vlapic->timer_fire_bt); | ||||
bintime_add(&vlapic->timer_fire_bt, | bintime_add(&vlapic->timer_fire_bt, | ||||
&vlapic->timer_period_bt); | &vlapic->timer_period_bt); | ||||
sbt = bttosbt(vlapic->timer_period_bt); | sbt = bttosbt(vlapic->timer_period_bt); | ||||
callout_stop(&vlapic->callout); | callout_stop(&vlapic->callout); | ||||
callout_reset_sbt(&vlapic->callout, sbt, 0, | vlapic_callout_reset(vlapic, sbt); | ||||
vlapic_callout_handler, vlapic, 0); | |||||
} | } | ||||
} | } | ||||
VLAPIC_TIMER_UNLOCK(vlapic); | VLAPIC_TIMER_UNLOCK(vlapic); | ||||
} | } | ||||
int | int | ||||
vlapic_snapshot(struct vm *vm, struct vm_snapshot_meta *meta) | vlapic_snapshot(struct vm *vm, struct vm_snapshot_meta *meta) | ||||
▲ Show 20 Lines • Show All 61 Lines • Show Last 20 Lines |