Skip to content

Commit 82f7720

Browse files
peterfangwenlingz
authored andcommitted
dm: vhpet: clean up asserts
Remove the use of assert() in vHPET. Tracked-On: #3252 Signed-off-by: Peter Fang <peter.fang@intel.com> Reviewed-by: <yonghua.huang@intel.com> Acked-by: Yin, Fengwei <fengwei.yin@intel.com>
1 parent aac8275 commit 82f7720

File tree

2 files changed

+122
-72
lines changed

2 files changed

+122
-72
lines changed

devicemodel/core/timer.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ int32_t
115115
acrn_timer_settime(struct acrn_timer *timer, const struct itimerspec *new_value)
116116
{
117117
if (timer == NULL) {
118+
errno = EINVAL;
118119
return -1;
119120
}
120121

@@ -126,6 +127,7 @@ acrn_timer_settime_abs(struct acrn_timer *timer,
126127
const struct itimerspec *new_value)
127128
{
128129
if (timer == NULL) {
130+
errno = EINVAL;
129131
return -1;
130132
}
131133

@@ -136,6 +138,7 @@ int32_t
136138
acrn_timer_gettime(struct acrn_timer *timer, struct itimerspec *cur_value)
137139
{
138140
if (timer == NULL) {
141+
errno = EINVAL;
139142
return -1;
140143
}
141144

devicemodel/hw/platform/hpet.c

Lines changed: 119 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@
3131
*/
3232

3333
#include <pthread.h>
34-
#include <assert.h>
3534
#include <errno.h>
3635
#include <stdbool.h>
3736
#include <stdio.h>
37+
#include <err.h>
38+
#include <sysexits.h>
3839
#include <string.h>
3940
#include <unistd.h>
4041

@@ -58,18 +59,22 @@
5859
*/
5960
#define VHPET_NUM_TIMERS (8)
6061

61-
#define VHPET_LOCK() \
62-
do { \
63-
int err; \
64-
err = pthread_mutex_lock(&vhpet_mtx); \
65-
assert(err == 0); \
62+
#define VHPET_LOCK() \
63+
do { \
64+
int err; \
65+
err = pthread_mutex_lock(&vhpet_mtx); \
66+
if (err) \
67+
errx(EX_SOFTWARE, "pthread_mutex_lock returned %s", \
68+
strerror(err)); \
6669
} while (0)
6770

68-
#define VHPET_UNLOCK() \
69-
do { \
70-
int err; \
71-
err = pthread_mutex_unlock(&vhpet_mtx); \
72-
assert(err == 0); \
71+
#define VHPET_UNLOCK() \
72+
do { \
73+
int err; \
74+
err = pthread_mutex_unlock(&vhpet_mtx); \
75+
if (err) \
76+
errx(EX_SOFTWARE, "pthread_mutex_unlock returned %s", \
77+
strerror(err)); \
7378
} while (0)
7479

7580
#define vhpet_ts_to_ticks(ts) ts_to_ticks(HPET_FREQ, ts)
@@ -196,13 +201,15 @@ vhpet_counter(struct vhpet *vhpet, struct timespec *nowptr)
196201
val = vhpet->countbase;
197202

198203
if (vhpet_counter_enabled(vhpet)) {
199-
if (clock_gettime(CLOCK_REALTIME, &now)) {
200-
perror("clock_gettime failed");
201-
assert(0);
202-
}
204+
if (clock_gettime(CLOCK_REALTIME, &now))
205+
errx(EX_SOFTWARE, "clock_gettime returned: %s", strerror(errno));
203206

204207
/* delta = now - countbase_ts */
205-
assert(timespeccmp(&now, &vhpet->countbase_ts, >=));
208+
if (timespeccmp(&now, &vhpet->countbase_ts, <)) {
209+
warnx("vhpet counter going backwards");
210+
vhpet->countbase_ts = now;
211+
}
212+
206213
delta = now;
207214
timespecsub(&delta, &vhpet->countbase_ts);
208215
val += vhpet_ts_to_ticks(&delta);
@@ -212,10 +219,15 @@ vhpet_counter(struct vhpet *vhpet, struct timespec *nowptr)
212219
} else {
213220
/*
214221
* The timespec corresponding to the 'countbase' is
215-
* meaningless when the counter is disabled. Make sure
216-
* that the caller doesn't want to use it.
222+
* meaningless when the counter is disabled. Warn if
223+
* the caller wants to use it.
217224
*/
218-
assert(nowptr == NULL);
225+
if (nowptr) {
226+
warnx("vhpet unexpected nowptr");
227+
if (clock_gettime(CLOCK_REALTIME, nowptr))
228+
errx(EX_SOFTWARE, "clock_gettime returned: %s",
229+
strerror(errno));
230+
}
219231
}
220232

221233
return val;
@@ -228,8 +240,12 @@ vhpet_timer_clear_isr(struct vhpet *vhpet, int n)
228240

229241
if (vhpet->isr & (1 << n)) {
230242
pin = vhpet_timer_ioapic_pin(vhpet, n);
231-
assert(pin != 0);
232-
vm_set_gsi_irq(vhpet->vm, pin, GSI_SET_LOW);
243+
244+
if (pin)
245+
vm_set_gsi_irq(vhpet->vm, pin, GSI_SET_LOW);
246+
else
247+
warnx("vhpet t%d intr asserted without a valid intr route", n);
248+
233249
vhpet->isr &= ~(1 << n);
234250
}
235251
}
@@ -263,8 +279,8 @@ vhpet_timer_running(struct vhpet *vhpet, int n)
263279
static inline bool
264280
vhpet_timer_edge_trig(struct vhpet *vhpet, int n)
265281
{
266-
assert(!vhpet_timer_msi_enabled(vhpet, n));
267-
return ((vhpet->timer[n].cap_config & HPET_TCNF_INT_TYPE) == 0);
282+
return (!vhpet_timer_msi_enabled(vhpet, n) &&
283+
(vhpet->timer[n].cap_config & HPET_TCNF_INT_TYPE) == 0);
268284
}
269285

270286
static void
@@ -279,10 +295,17 @@ vhpet_timer_interrupt(struct vhpet *vhpet, int n)
279295
/*
280296
* If a level triggered interrupt is already asserted then just return.
281297
*/
282-
if ((vhpet->isr & (1 << n)) != 0) {
283-
assert(!vhpet_timer_edge_trig(vhpet, n));
284-
DPRINTF(("hpet t%d intr is already asserted\n", n));
285-
return;
298+
if (vhpet->isr & (1 << n)) {
299+
if (!vhpet_timer_msi_enabled(vhpet, n) &&
300+
!vhpet_timer_edge_trig(vhpet, n)) {
301+
DPRINTF(("hpet t%d intr is already asserted\n", n));
302+
return;
303+
} else {
304+
warnx("vhpet t%d intr asserted in %s mode", n,
305+
vhpet_timer_msi_enabled(vhpet, n) ?
306+
"msi" : "edge-triggered");
307+
vhpet->isr &= ~(1 << n);
308+
}
286309
}
287310

288311
if (vhpet_timer_msi_enabled(vhpet, n)) {
@@ -331,23 +354,27 @@ vhpet_timer_handler(void *a, uint64_t nexp)
331354
/* Bail if timer was stopped */
332355
if (!arg->running) {
333356
DPRINTF(("hpet t%d(%p) already stopped\n", n, arg));
334-
assert(ts_is_zero(&vhpet->timer[n].expts));
357+
if (!ts_is_zero(&vhpet->timer[n].expts)) {
358+
warnx("vhpet t%d stopped with an expiration time", n);
359+
ts_set_zero(&vhpet->timer[n].expts);
360+
}
361+
goto done;
362+
} else if (arg != vhpet_tmrarg(vhpet, n)) {
363+
warnx("vhpet t%d observes a stale timer arg", n);
335364
goto done;
336-
} else
337-
assert(arg == vhpet_tmrarg(vhpet, n));
365+
}
338366

339367
vhpet_timer_interrupt(vhpet, n);
340368

341-
if (clock_gettime(CLOCK_REALTIME, &now)) {
342-
perror("clock_gettime failed");
343-
assert(0);
344-
}
369+
if (clock_gettime(CLOCK_REALTIME, &now))
370+
errx(EX_SOFTWARE, "clock_gettime returned: %s", strerror(errno));
345371

346372
if (acrn_timer_gettime(vhpet_tmr(vhpet, n), &tmrts))
347-
assert(0);
373+
errx(EX_SOFTWARE, "acrn_timer_gettime returned: %s", strerror(errno));
348374

349375
/* One-shot mode has a periodicity of 2^32 ticks */
350-
assert(!ts_is_zero(&tmrts.it_interval));
376+
if (ts_is_zero(&tmrts.it_interval))
377+
warnx("vhpet t%d has no periodicity", n);
351378

352379
/*
353380
* The actual expiration time will be slightly later than expts.
@@ -386,8 +413,8 @@ vhpet_adjust_compval(struct vhpet *vhpet, int n, const struct timespec *now)
386413
compval = vhpet->timer[n].compval;
387414
comprate = vhpet->timer[n].comprate;
388415

389-
assert(comprate != 0);
390-
assert(timespeccmp(&vhpet->timer[n].expts, now, <));
416+
if (!comprate || timespeccmp(&vhpet->timer[n].expts, now, >=))
417+
return;
391418

392419
/* delta = now - expts */
393420
delta = *now;
@@ -420,8 +447,11 @@ vhpet_stop_timer(struct vhpet *vhpet, int n, const struct timespec *now,
420447
{
421448
struct vhpet_timer_arg *arg;
422449

423-
assert(vhpet_timer_running(vhpet, n));
424-
assert(!ts_is_zero(&vhpet->timer[n].expts));
450+
if (!vhpet_timer_running(vhpet, n))
451+
return;
452+
453+
if (ts_is_zero(&vhpet->timer[n].expts))
454+
warnx("vhpet t%d is running without an expiration time", n);
425455

426456
DPRINTF(("hpet t%d stopped\n", n));
427457

@@ -430,12 +460,16 @@ vhpet_stop_timer(struct vhpet *vhpet, int n, const struct timespec *now,
430460

431461
/* Cancel the existing timer */
432462
if (acrn_timer_settime(vhpet_tmr(vhpet, n), &zero_ts))
433-
assert(0);
463+
errx(EX_SOFTWARE, "acrn_timer_settime returned: %s", strerror(errno));
434464

435465
if (++vhpet->timer[n].tmridx == nitems(vhpet->timer[n].tmrlst))
436466
vhpet->timer[n].tmridx = 0;
437467

438-
assert(!vhpet_timer_running(vhpet, n));
468+
if (vhpet_timer_running(vhpet, n)) {
469+
warnx("vhpet t%d timer %d is still running",
470+
n, vhpet->timer[n].tmridx);
471+
vhpet_stop_timer(vhpet, n, &zero_ts.it_value, false);
472+
}
439473

440474
/*
441475
* If the timer was scheduled to expire in the past but hasn't
@@ -444,15 +478,17 @@ vhpet_stop_timer(struct vhpet *vhpet, int n, const struct timespec *now,
444478
* in the guest. This is especially bad in one-shot mode because
445479
* the next interrupt has to wait for the counter to wrap around.
446480
*/
447-
if (timespeccmp(&vhpet->timer[n].expts, now, <)) {
448-
DPRINTF(("hpet t%d interrupt triggered after "
449-
"stopping timer\n", n));
450-
if (adj_compval && vhpet->timer[n].comprate != 0)
451-
vhpet_adjust_compval(vhpet, n, now);
452-
vhpet_timer_interrupt(vhpet, n);
453-
}
481+
if (!ts_is_zero(&vhpet->timer[n].expts)) {
482+
if (timespeccmp(&vhpet->timer[n].expts, now, <)) {
483+
DPRINTF(("hpet t%d interrupt triggered after "
484+
"stopping timer\n", n));
485+
if (adj_compval)
486+
vhpet_adjust_compval(vhpet, n, now);
487+
vhpet_timer_interrupt(vhpet, n);
488+
}
454489

455-
ts_set_zero(&vhpet->timer[n].expts);
490+
ts_set_zero(&vhpet->timer[n].expts);
491+
}
456492
}
457493

458494
static void
@@ -463,8 +499,7 @@ vhpet_start_timer(struct vhpet *vhpet, int n, uint32_t counter,
463499
uint32_t delta;
464500
struct vhpet_timer_arg *arg;
465501

466-
if (vhpet_timer_running(vhpet, n))
467-
vhpet_stop_timer(vhpet, n, now, adj_compval);
502+
vhpet_stop_timer(vhpet, n, now, adj_compval);
468503

469504
DPRINTF(("hpet t%d started\n", n));
470505

@@ -484,14 +519,13 @@ vhpet_start_timer(struct vhpet *vhpet, int n, uint32_t counter,
484519
vhpet_ticks_to_ts(1ULL << 32, &ts.it_interval);
485520

486521
arg = vhpet_tmrarg(vhpet, n);
487-
assert(!arg->running);
488522
arg->running = true;
489523

490524
/* Arm the new timer */
491525
if (acrn_timer_settime_abs(vhpet_tmr(vhpet, n), &ts))
492-
assert(0);
526+
errx(EX_SOFTWARE, "acrn_timer_settime_abs returned: %s",
527+
strerror(errno));
493528

494-
assert(ts_is_zero(&vhpet->timer[n].expts));
495529
vhpet->timer[n].expts = ts.it_value;
496530
}
497531

@@ -514,18 +548,18 @@ vhpet_start_counting(struct vhpet *vhpet)
514548
{
515549
int i;
516550

517-
if (clock_gettime(CLOCK_REALTIME, &vhpet->countbase_ts)) {
518-
perror("clock_gettime failed");
519-
assert(0);
520-
}
551+
if (clock_gettime(CLOCK_REALTIME, &vhpet->countbase_ts))
552+
errx(EX_SOFTWARE, "clock_gettime returned: %s", strerror(errno));
521553

522554
/* Restart the timers based on the main counter base value */
523555
for (i = 0; i < VHPET_NUM_TIMERS; i++) {
524556
if (vhpet_timer_enabled(vhpet, i))
525557
vhpet_start_timer(vhpet, i, vhpet->countbase,
526558
&vhpet->countbase_ts, true);
527-
else
528-
assert(!vhpet_timer_running(vhpet, i));
559+
else if (vhpet_timer_running(vhpet, i)) {
560+
warnx("vhpet t%d's timer is disabled but running", i);
561+
vhpet_stop_timer(vhpet, i, &zero_ts.it_value, false);
562+
}
529563
}
530564
}
531565

@@ -541,8 +575,10 @@ vhpet_stop_counting(struct vhpet *vhpet, uint32_t counter,
541575
for (i = 0; i < VHPET_NUM_TIMERS; i++) {
542576
if (vhpet_timer_enabled(vhpet, i))
543577
vhpet_stop_timer(vhpet, i, now, true);
544-
else
545-
assert(!vhpet_timer_running(vhpet, i));
578+
else if (vhpet_timer_running(vhpet, i)) {
579+
warnx("vhpet t%d's timer is disabled but running", i);
580+
vhpet_stop_timer(vhpet, i, &zero_ts.it_value, false);
581+
}
546582
}
547583
}
548584

@@ -564,8 +600,14 @@ vhpet_timer_update_config(struct vhpet *vhpet, int n, uint64_t data,
564600
struct timespec now;
565601

566602
if (vhpet_timer_msi_enabled(vhpet, n) ||
567-
vhpet_timer_edge_trig(vhpet, n))
568-
assert(!(vhpet->isr & (1 << n)));
603+
vhpet_timer_edge_trig(vhpet, n)) {
604+
if (vhpet->isr & (1 << n)) {
605+
warnx("vhpet t%d intr asserted in %s mode", n,
606+
vhpet_timer_msi_enabled(vhpet, n) ?
607+
"msi" : "edge-triggered");
608+
vhpet->isr &= ~(1 << n);
609+
}
610+
}
569611

570612
old_pin = vhpet_timer_ioapic_pin(vhpet, n);
571613
oldval = vhpet->timer[n].cap_config;
@@ -597,10 +639,9 @@ vhpet_timer_update_config(struct vhpet *vhpet, int n, uint64_t data,
597639
* - Timer remains in periodic mode
598640
*/
599641
if (!vhpet_timer_enabled(vhpet, n)) {
600-
if (clock_gettime(CLOCK_REALTIME, &now)) {
601-
perror("clock_gettime failed");
602-
assert(0);
603-
}
642+
if (clock_gettime(CLOCK_REALTIME, &now))
643+
errx(EX_SOFTWARE, "clock_gettime returned: %s",
644+
strerror(errno));
604645
vhpet_stop_timer(vhpet, n, &now, true);
605646
} else if (!(oldval & (HPET_TCNF_TYPE | HPET_TCNF_INT_ENB)) ||
606647
((oldval ^ newval) & HPET_TCNF_TYPE))
@@ -633,8 +674,10 @@ vhpet_timer_update_config(struct vhpet *vhpet, int n, uint64_t data,
633674
* not remain asserted forever.
634675
*/
635676
if (vhpet->isr & (1 << n)) {
636-
assert(old_pin != 0);
637-
if (!vhpet_timer_interrupt_enabled(vhpet, n) ||
677+
if (!old_pin) {
678+
warnx("vhpet t%d intr asserted without a valid intr route", n);
679+
vhpet->isr &= ~(1 << n);
680+
} else if (!vhpet_timer_interrupt_enabled(vhpet, n) ||
638681
vhpet_timer_msi_enabled(vhpet, n) ||
639682
vhpet_timer_edge_trig(vhpet, n) ||
640683
new_pin != old_pin) {
@@ -763,7 +806,11 @@ vhpet_mmio_write(struct vhpet *vhpet, int vcpuid, uint64_t gpa, uint64_t *wval,
763806
HPET_TCNF_VAL_SET) != 0)
764807
vhpet->timer[i].compval = val64;
765808
} else {
766-
assert(vhpet->timer[i].comprate == 0);
809+
if (vhpet->timer[i].comprate) {
810+
warnx("vhpet t%d's comprate is %u in non-periodic mode"
811+
" - should be 0", i, vhpet->timer[i].comprate);
812+
vhpet->timer[i].comprate = 0;
813+
}
767814
val64 = vhpet->timer[i].compval;
768815
update_register(&val64, data, mask);
769816
vhpet->timer[i].compval = val64;

0 commit comments

Comments
 (0)