Lines Matching full:timer
3 * arch_timer_edge_cases.c - Tests the aarch64 timer IRQ functionality.
5 * The test validates some edge cases related to the arch-timer:
11 * - masking/unmasking using the timer control mask.
52 /* Virtual or physical timer and counter tests. */
53 enum arch_timer timer; member
54 /* Delay used for most timer tests. */
60 /* Whether to test the physical timer. */
62 /* Whether to test the virtual timer. */
84 typedef void (*sleep_method_t)(enum arch_timer timer, uint64_t usec);
86 static void sleep_poll(enum arch_timer timer, uint64_t usec);
87 static void sleep_sched_poll(enum arch_timer timer, uint64_t usec);
88 static void sleep_in_userspace(enum arch_timer timer, uint64_t usec);
89 static void sleep_migrate(enum arch_timer timer, uint64_t usec);
139 static void set_counter(enum arch_timer timer, uint64_t counter) in set_counter() argument
141 GUEST_SYNC_ARGS(SET_COUNTER_VALUE, counter, timer, 0, 0); in set_counter()
147 enum arch_timer timer; in guest_irq_handler() local
158 timer = PHYSICAL; in guest_irq_handler()
160 timer = VIRTUAL; in guest_irq_handler()
164 ctl = timer_get_ctl(timer); in guest_irq_handler()
165 cval = timer_get_cval(timer); in guest_irq_handler()
166 cnt = timer_get_cntct(timer); in guest_irq_handler()
171 /* Disable and mask the timer. */ in guest_irq_handler()
172 timer_set_ctl(timer, CTL_IMASK); in guest_irq_handler()
180 static void set_cval_irq(enum arch_timer timer, uint64_t cval_cycles, in set_cval_irq() argument
185 timer_set_cval(timer, cval_cycles); in set_cval_irq()
186 timer_set_ctl(timer, ctl); in set_cval_irq()
189 static void set_tval_irq(enum arch_timer timer, uint64_t tval_cycles, in set_tval_irq() argument
194 timer_set_ctl(timer, ctl); in set_tval_irq()
195 timer_set_tval(timer, tval_cycles); in set_tval_irq()
198 static void set_xval_irq(enum arch_timer timer, uint64_t xval, uint32_t ctl, in set_xval_irq() argument
203 set_cval_irq(timer, xval, ctl); in set_xval_irq()
206 set_tval_irq(timer, xval, ctl); in set_xval_irq()
209 GUEST_FAIL("Could not get timer %d", timer); in set_xval_irq()
281 /* Whichever timer we are testing with, sleep with the other. */ in guest_poll()
293 static void sleep_poll(enum arch_timer timer, uint64_t usec) in sleep_poll() argument
295 guest_poll(timer, usec, NO_USERSPACE_CMD); in sleep_poll()
298 static void sleep_sched_poll(enum arch_timer timer, uint64_t usec) in sleep_sched_poll() argument
300 guest_poll(timer, usec, USERSPACE_SCHED_YIELD); in sleep_sched_poll()
303 static void sleep_migrate(enum arch_timer timer, uint64_t usec) in sleep_migrate() argument
305 guest_poll(timer, usec, USERSPACE_MIGRATE_SELF); in sleep_migrate()
308 static void sleep_in_userspace(enum arch_timer timer, uint64_t usec) in sleep_in_userspace() argument
314 * Reset the timer state to some nice values like the counter not being close
317 static void reset_timer_state(enum arch_timer timer, uint64_t cnt) in reset_timer_state() argument
319 set_counter(timer, cnt); in reset_timer_state()
320 timer_set_ctl(timer, CTL_IMASK); in reset_timer_state()
323 static void test_timer_xval(enum arch_timer timer, uint64_t xval, in test_timer_xval() argument
330 reset_timer_state(timer, reset_cnt); in test_timer_xval()
332 set_xval_irq(timer, xval, CTL_ENABLE, tv); in test_timer_xval()
342 * The test_timer_* functions will program the timer, wait for it, and assert
350 static void test_timer_cval(enum arch_timer timer, uint64_t cval, in test_timer_cval() argument
354 test_timer_xval(timer, cval, TIMER_CVAL, wm, reset_state, reset_cnt); in test_timer_cval()
357 static void test_timer_tval(enum arch_timer timer, int32_t tval, in test_timer_tval() argument
361 test_timer_xval(timer, (uint64_t) tval, TIMER_TVAL, wm, reset_state, in test_timer_tval()
365 static void test_xval_check_no_irq(enum arch_timer timer, uint64_t xval, in test_xval_check_no_irq() argument
371 set_xval_irq(timer, xval, CTL_ENABLE | CTL_IMASK, timer_view); in test_xval_check_no_irq()
372 guest_sleep(timer, usec); in test_xval_check_no_irq()
381 static void test_cval_no_irq(enum arch_timer timer, uint64_t cval, in test_cval_no_irq() argument
384 test_xval_check_no_irq(timer, cval, usec, TIMER_CVAL, wm); in test_cval_no_irq()
387 static void test_tval_no_irq(enum arch_timer timer, int32_t tval, uint64_t usec, in test_tval_no_irq() argument
391 test_xval_check_no_irq(timer, (uint64_t) tval, usec, TIMER_TVAL, wm); in test_tval_no_irq()
394 /* Test masking/unmasking a timer using the timer mask (not the IRQ mask). */
395 static void test_timer_control_mask_then_unmask(enum arch_timer timer) in test_timer_control_mask_then_unmask() argument
397 reset_timer_state(timer, DEF_CNT); in test_timer_control_mask_then_unmask()
398 set_tval_irq(timer, -1, CTL_ENABLE | CTL_IMASK); in test_timer_control_mask_then_unmask()
400 /* Unmask the timer, and then get an IRQ. */ in test_timer_control_mask_then_unmask()
402 timer_set_ctl(timer, CTL_ENABLE); in test_timer_control_mask_then_unmask()
410 /* Check that timer control masks actually mask a timer being fired. */
411 static void test_timer_control_masks(enum arch_timer timer) in test_timer_control_masks() argument
413 reset_timer_state(timer, DEF_CNT); in test_timer_control_masks()
417 set_tval_irq(timer, -1, CTL_ENABLE | CTL_IMASK); in test_timer_control_masks()
420 sleep_poll(timer, TIMEOUT_NO_IRQ_US); in test_timer_control_masks()
423 timer_set_ctl(timer, CTL_IMASK); in test_timer_control_masks()
426 static void test_fire_a_timer_multiple_times(enum arch_timer timer, in test_fire_a_timer_multiple_times() argument
432 reset_timer_state(timer, DEF_CNT); in test_fire_a_timer_multiple_times()
434 set_tval_irq(timer, 0, CTL_ENABLE); in test_fire_a_timer_multiple_times()
440 /* The IRQ handler masked and disabled the timer. in test_fire_a_timer_multiple_times()
443 timer_set_ctl(timer, CTL_ENABLE); in test_fire_a_timer_multiple_times()
451 static void test_timers_fired_multiple_times(enum arch_timer timer) in test_timers_fired_multiple_times() argument
456 test_fire_a_timer_multiple_times(timer, irq_wait_method[i], 10); in test_timers_fired_multiple_times()
460 * Set a timer for tval=delta_1_ms then reprogram it to
461 * tval=delta_2_ms. Check that we get the timer fired. There is no
464 static void test_reprogramming_timer(enum arch_timer timer, irq_wait_method_t wm, in test_reprogramming_timer() argument
468 reset_timer_state(timer, DEF_CNT); in test_reprogramming_timer()
470 /* Program the timer to DEF_CNT + delta_1_ms. */ in test_reprogramming_timer()
471 set_tval_irq(timer, msec_to_cycles(delta_1_ms), CTL_ENABLE); in test_reprogramming_timer()
473 /* Reprogram the timer to DEF_CNT + delta_2_ms. */ in test_reprogramming_timer()
474 timer_set_tval(timer, msec_to_cycles(delta_2_ms)); in test_reprogramming_timer()
480 GUEST_ASSERT(timer_get_cntct(timer) >= in test_reprogramming_timer()
487 static void test_reprogram_timers(enum arch_timer timer) in test_reprogram_timers() argument
497 test_reprogramming_timer(timer, irq_wait_method[i], 2 * base_wait, in test_reprogram_timers()
499 test_reprogramming_timer(timer, irq_wait_method[i], base_wait, in test_reprogram_timers()
504 static void test_basic_functionality(enum arch_timer timer) in test_basic_functionality() argument
513 test_timer_cval(timer, cval, wm, true, DEF_CNT); in test_basic_functionality()
514 test_timer_tval(timer, tval, wm, true, DEF_CNT); in test_basic_functionality()
519 * This test checks basic timer behavior without actually firing timers, things
522 static void timers_sanity_checks(enum arch_timer timer, bool use_sched) in timers_sanity_checks() argument
524 reset_timer_state(timer, DEF_CNT); in timers_sanity_checks()
529 timer_set_cval(timer, in timers_sanity_checks()
530 timer_get_cntct(timer) - in timers_sanity_checks()
534 GUEST_ASSERT(timer_get_tval(timer) < 0); in timers_sanity_checks()
537 timer_set_tval(timer, -1); in timers_sanity_checks()
540 GUEST_ASSERT(timer_get_cval(timer) < timer_get_cntct(timer)); in timers_sanity_checks()
545 timer_set_cval(timer, in timers_sanity_checks()
546 timer_get_cntct(timer) + TVAL_MAX + in timers_sanity_checks()
550 GUEST_ASSERT(timer_get_tval(timer) <= 0); in timers_sanity_checks()
556 timer_set_cval(timer, in timers_sanity_checks()
557 timer_get_cntct(timer) + 2ULL * TVAL_MAX + in timers_sanity_checks()
561 GUEST_ASSERT(timer_get_tval(timer) <= in timers_sanity_checks()
565 set_counter(timer, msec_to_cycles(1)); in timers_sanity_checks()
566 timer_set_tval(timer, -1 * msec_to_cycles(test_args.wait_ms)); in timers_sanity_checks()
569 GUEST_ASSERT(timer_get_cval(timer) >= (CVAL_MAX - msec_to_cycles(test_args.wait_ms))); in timers_sanity_checks()
572 timer_set_tval(timer, 0); in timers_sanity_checks()
573 sleep_poll(timer, 1); in timers_sanity_checks()
574 GUEST_ASSERT(timer_get_tval(timer) < 0); in timers_sanity_checks()
578 /* Mask and disable any pending timer. */ in timers_sanity_checks()
579 timer_set_ctl(timer, CTL_IMASK); in timers_sanity_checks()
582 static void test_timers_sanity_checks(enum arch_timer timer) in test_timers_sanity_checks() argument
584 timers_sanity_checks(timer, false); in test_timers_sanity_checks()
586 timers_sanity_checks(timer, true); in test_timers_sanity_checks()
589 static void test_set_cnt_after_tval_max(enum arch_timer timer, irq_wait_method_t wm) in test_set_cnt_after_tval_max() argument
592 reset_timer_state(timer, DEF_CNT); in test_set_cnt_after_tval_max()
594 set_cval_irq(timer, in test_set_cnt_after_tval_max()
598 set_counter(timer, TVAL_MAX); in test_set_cnt_after_tval_max()
608 static void test_timers_above_tval_max(enum arch_timer timer) in test_timers_above_tval_max() argument
617 * wait_ms", and the timer would fire immediately. Test that it in test_timers_above_tval_max()
621 reset_timer_state(timer, DEF_CNT); in test_timers_above_tval_max()
622 cval = timer_get_cntct(timer) + TVAL_MAX + in test_timers_above_tval_max()
624 test_cval_no_irq(timer, cval, in test_timers_above_tval_max()
631 test_set_cnt_after_tval_max(timer, irq_wait_method[i]); in test_timers_above_tval_max()
640 static void test_set_cnt_after_xval(enum arch_timer timer, uint64_t cnt_1, in test_set_cnt_after_xval() argument
646 set_counter(timer, cnt_1); in test_set_cnt_after_xval()
647 timer_set_ctl(timer, CTL_IMASK); in test_set_cnt_after_xval()
649 set_xval_irq(timer, xval, CTL_ENABLE, tv); in test_set_cnt_after_xval()
650 set_counter(timer, cnt_2); in test_set_cnt_after_xval()
663 static void test_set_cnt_after_xval_no_irq(enum arch_timer timer, in test_set_cnt_after_xval_no_irq() argument
671 set_counter(timer, cnt_1); in test_set_cnt_after_xval_no_irq()
672 timer_set_ctl(timer, CTL_IMASK); in test_set_cnt_after_xval_no_irq()
674 set_xval_irq(timer, xval, CTL_ENABLE, tv); in test_set_cnt_after_xval_no_irq()
675 set_counter(timer, cnt_2); in test_set_cnt_after_xval_no_irq()
676 guest_sleep(timer, TIMEOUT_NO_IRQ_US); in test_set_cnt_after_xval_no_irq()
683 timer_set_ctl(timer, CTL_IMASK); in test_set_cnt_after_xval_no_irq()
686 static void test_set_cnt_after_tval(enum arch_timer timer, uint64_t cnt_1, in test_set_cnt_after_tval() argument
690 test_set_cnt_after_xval(timer, cnt_1, tval, cnt_2, wm, TIMER_TVAL); in test_set_cnt_after_tval()
693 static void test_set_cnt_after_cval(enum arch_timer timer, uint64_t cnt_1, in test_set_cnt_after_cval() argument
697 test_set_cnt_after_xval(timer, cnt_1, cval, cnt_2, wm, TIMER_CVAL); in test_set_cnt_after_cval()
700 static void test_set_cnt_after_tval_no_irq(enum arch_timer timer, in test_set_cnt_after_tval_no_irq() argument
704 test_set_cnt_after_xval_no_irq(timer, cnt_1, tval, cnt_2, wm, in test_set_cnt_after_tval_no_irq()
708 static void test_set_cnt_after_cval_no_irq(enum arch_timer timer, in test_set_cnt_after_cval_no_irq() argument
712 test_set_cnt_after_xval_no_irq(timer, cnt_1, cval, cnt_2, wm, in test_set_cnt_after_cval_no_irq()
716 /* Set a timer and then move the counter ahead of it. */
717 static void test_move_counters_ahead_of_timers(enum arch_timer timer) in test_move_counters_ahead_of_timers() argument
725 test_set_cnt_after_cval(timer, 0, DEF_CNT, DEF_CNT + 1, wm); in test_move_counters_ahead_of_timers()
726 test_set_cnt_after_cval(timer, CVAL_MAX, 1, 2, wm); in test_move_counters_ahead_of_timers()
729 test_set_cnt_after_tval(timer, 0, -1, DEF_CNT + 1, wm); in test_move_counters_ahead_of_timers()
730 test_set_cnt_after_tval(timer, 0, -1, TVAL_MAX, wm); in test_move_counters_ahead_of_timers()
732 test_set_cnt_after_tval(timer, 0, tval, (uint64_t) tval + 1, in test_move_counters_ahead_of_timers()
739 test_set_cnt_after_cval_no_irq(timer, 0, DEF_CNT, CVAL_MAX, sm); in test_move_counters_ahead_of_timers()
744 * Program a timer, mask it, and then change the tval or counter to cancel it.
747 static void test_move_counters_behind_timers(enum arch_timer timer) in test_move_counters_behind_timers() argument
754 test_set_cnt_after_cval_no_irq(timer, DEF_CNT, DEF_CNT - 1, 0, in test_move_counters_behind_timers()
756 test_set_cnt_after_tval_no_irq(timer, DEF_CNT, -1, 0, sm); in test_move_counters_behind_timers()
760 static void test_timers_in_the_past(enum arch_timer timer) in test_timers_in_the_past() argument
769 /* set a timer wait_ms the past. */ in test_timers_in_the_past()
771 test_timer_cval(timer, cval, wm, true, DEF_CNT); in test_timers_in_the_past()
772 test_timer_tval(timer, tval, wm, true, DEF_CNT); in test_timers_in_the_past()
774 /* Set a timer to counter=0 (in the past) */ in test_timers_in_the_past()
775 test_timer_cval(timer, 0, wm, true, DEF_CNT); in test_timers_in_the_past()
778 test_timer_tval(timer, 0, wm, true, DEF_CNT); in test_timers_in_the_past()
780 /* Set a timer to as far in the past as possible */ in test_timers_in_the_past()
781 test_timer_tval(timer, TVAL_MIN, wm, true, DEF_CNT); in test_timers_in_the_past()
791 set_counter(timer, msec_to_cycles(test_args.wait_ms)); in test_timers_in_the_past()
792 test_tval_no_irq(timer, tval, TIMEOUT_NO_IRQ_US, sm); in test_timers_in_the_past()
796 static void test_long_timer_delays(enum arch_timer timer) in test_long_timer_delays() argument
805 test_timer_cval(timer, cval, wm, true, DEF_CNT); in test_long_timer_delays()
806 test_timer_tval(timer, tval, wm, true, DEF_CNT); in test_long_timer_delays()
810 static void guest_run_iteration(enum arch_timer timer) in guest_run_iteration() argument
812 test_basic_functionality(timer); in guest_run_iteration()
813 test_timers_sanity_checks(timer); in guest_run_iteration()
815 test_timers_above_tval_max(timer); in guest_run_iteration()
816 test_timers_in_the_past(timer); in guest_run_iteration()
818 test_move_counters_ahead_of_timers(timer); in guest_run_iteration()
819 test_move_counters_behind_timers(timer); in guest_run_iteration()
820 test_reprogram_timers(timer); in guest_run_iteration()
822 test_timers_fired_multiple_times(timer); in guest_run_iteration()
824 test_timer_control_mask_then_unmask(timer); in guest_run_iteration()
825 test_timer_control_masks(timer); in guest_run_iteration()
828 static void guest_code(enum arch_timer timer) in guest_code() argument
845 guest_run_iteration(timer); in guest_code()
848 test_long_timer_delays(timer); in guest_code()
890 enum arch_timer timer) in kvm_set_cntxct() argument
892 if (timer == PHYSICAL) in kvm_set_cntxct()
902 enum arch_timer timer = uc->args[3]; in handle_sync() local
906 kvm_set_cntxct(vcpu, val, timer); in handle_sync()
963 enum arch_timer timer) in test_vm_create() argument
973 vcpu_args_set(*vcpu, 1, timer); in test_vm_create()
991 pr_info("\t-p: Test physical timer (default: true)\n"); in test_print_help()
992 pr_info("\t-v: Test virtual timer (default: true)\n"); in test_print_help()