Page MenuHomeFreeBSD

D20335.diff
No OneTemporary

D20335.diff

Index: head/sys/amd64/vmm/io/vatpit.c
===================================================================
--- head/sys/amd64/vmm/io/vatpit.c
+++ head/sys/amd64/vmm/io/vatpit.c
@@ -2,6 +2,7 @@
* Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
* Copyright (c) 2011 NetApp, Inc.
* All rights reserved.
+ * Copyright (c) 2018 Joyent, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -78,7 +79,7 @@
struct channel {
int mode;
uint16_t initial; /* initial counter value */
- sbintime_t now_sbt; /* uptime when counter was loaded */
+ struct bintime now_bt; /* uptime when counter was loaded */
uint8_t cr[2];
uint8_t ol[2];
bool slatched; /* status latched */
@@ -87,7 +88,7 @@
int olbyte;
int frbyte;
struct callout callout;
- sbintime_t callout_sbt; /* target time */
+ struct bintime callout_bt; /* target time */
struct vatpit_callout_arg callout_arg;
};
@@ -95,26 +96,41 @@
struct vm *vm;
struct mtx mtx;
- sbintime_t freq_sbt;
+ struct bintime freq_bt;
struct channel channel[3];
};
static void pit_timer_start_cntr0(struct vatpit *vatpit);
+static uint64_t
+vatpit_delta_ticks(struct vatpit *vatpit, struct channel *c)
+{
+ struct bintime delta;
+ uint64_t result;
+
+ binuptime(&delta);
+ bintime_sub(&delta, &c->now_bt);
+
+ result = delta.sec * PIT_8254_FREQ;
+ result += delta.frac / vatpit->freq_bt.frac;
+
+ return (result);
+}
+
static int
vatpit_get_out(struct vatpit *vatpit, int channel)
{
struct channel *c;
- sbintime_t delta_ticks;
+ uint64_t delta_ticks;
int out;
c = &vatpit->channel[channel];
switch (c->mode) {
case TIMER_INTTC:
- delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt;
- out = ((c->initial - delta_ticks) <= 0);
+ delta_ticks = vatpit_delta_ticks(vatpit, c);
+ out = (delta_ticks >= c->initial);
break;
default:
out = 0;
@@ -164,24 +180,28 @@
pit_timer_start_cntr0(struct vatpit *vatpit)
{
struct channel *c;
- sbintime_t now, delta, precision;
+ struct bintime now, delta;
+ sbintime_t precision;
c = &vatpit->channel[0];
if (c->initial != 0) {
- delta = c->initial * vatpit->freq_sbt;
- precision = delta >> tc_precexp;
- c->callout_sbt = c->callout_sbt + delta;
+ delta.sec = 0;
+ delta.frac = vatpit->freq_bt.frac * c->initial;
+ bintime_add(&c->callout_bt, &delta);
+ precision = bttosbt(delta) >> tc_precexp;
/*
- * Reset 'callout_sbt' if the time that the callout
+ * Reset 'callout_bt' if the time that the callout
* was supposed to fire is more than 'c->initial'
* ticks in the past.
*/
- now = sbinuptime();
- if (c->callout_sbt < now)
- c->callout_sbt = now + delta;
+ binuptime(&now);
+ if (bintime_cmp(&c->callout_bt, &now, <)) {
+ c->callout_bt = now;
+ bintime_add(&c->callout_bt, &delta);
+ }
- callout_reset_sbt(&c->callout, c->callout_sbt,
+ callout_reset_sbt(&c->callout, bttosbt(c->callout_bt),
precision, vatpit_callout_handler, &c->callout_arg,
C_ABSOLUTE);
}
@@ -191,7 +211,7 @@
pit_update_counter(struct vatpit *vatpit, struct channel *c, bool latch)
{
uint16_t lval;
- sbintime_t delta_ticks;
+ uint64_t delta_ticks;
/* cannot latch a new value until the old one has been consumed */
if (latch && c->olbyte != 0)
@@ -207,12 +227,11 @@
* here.
*/
c->initial = TIMER_DIV(PIT_8254_FREQ, 100);
- c->now_sbt = sbinuptime();
+ binuptime(&c->now_bt);
c->status &= ~TIMER_STS_NULLCNT;
}
- delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt;
-
+ delta_ticks = vatpit_delta_ticks(vatpit, c);
lval = c->initial - delta_ticks % c->initial;
if (latch) {
@@ -383,10 +402,10 @@
c->frbyte = 0;
c->crbyte = 0;
c->initial = c->cr[0] | (uint16_t)c->cr[1] << 8;
- c->now_sbt = sbinuptime();
+ binuptime(&c->now_bt);
/* Start an interval timer for channel 0 */
if (port == TIMER_CNTR0) {
- c->callout_sbt = c->now_sbt;
+ c->callout_bt = c->now_bt;
pit_timer_start_cntr0(vatpit);
}
if (c->initial == 0)
@@ -423,7 +442,6 @@
vatpit_init(struct vm *vm)
{
struct vatpit *vatpit;
- struct bintime bt;
struct vatpit_callout_arg *arg;
int i;
@@ -432,8 +450,7 @@
mtx_init(&vatpit->mtx, "vatpit lock", NULL, MTX_SPIN);
- FREQ2BT(PIT_8254_FREQ, &bt);
- vatpit->freq_sbt = bttosbt(bt);
+ FREQ2BT(PIT_8254_FREQ, &vatpit->freq_bt);
for (i = 0; i < 3; i++) {
callout_init(&vatpit->channel[i].callout, 1);

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 26, 11:32 PM (12 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15608981
Default Alt Text
D20335.diff (4 KB)

Event Timeline