1*51f3fe70SGabriele Monaco // SPDX-License-Identifier: GPL-2.0 2*51f3fe70SGabriele Monaco #include <linux/kernel.h> 3*51f3fe70SGabriele Monaco #include <linux/rv.h> 4*51f3fe70SGabriele Monaco #include <rv/kunit.h> 5*51f3fe70SGabriele Monaco #include <trace/events/syscalls.h> 6*51f3fe70SGabriele Monaco #include <trace/events/sched.h> 7*51f3fe70SGabriele Monaco #include <uapi/linux/futex.h> 8*51f3fe70SGabriele Monaco #include "sleep_kunit.h" 9*51f3fe70SGabriele Monaco 10*51f3fe70SGabriele Monaco #if IS_REACHABLE(CONFIG_RV_MON_SLEEP) 11*51f3fe70SGabriele Monaco 12*51f3fe70SGabriele Monaco static void rv_test_sleep(struct kunit *test) 13*51f3fe70SGabriele Monaco { 14*51f3fe70SGabriele Monaco struct task_struct *target = rv_kunit_alloc_mock_task(test); 15*51f3fe70SGabriele Monaco struct task_struct *other = rv_kunit_alloc_mock_task(test); 16*51f3fe70SGabriele Monaco struct rv_kunit_ctx *ctx = test->priv; 17*51f3fe70SGabriele Monaco unsigned long args[6] = {0}; 18*51f3fe70SGabriele Monaco struct pt_regs regs = {0}; 19*51f3fe70SGabriele Monaco 20*51f3fe70SGabriele Monaco prepare_test(test, &rv_sleep_ops.mon); 21*51f3fe70SGabriele Monaco target->policy = SCHED_FIFO; 22*51f3fe70SGabriele Monaco target->prio = MAX_RT_PRIO - 2; 23*51f3fe70SGabriele Monaco other->policy = SCHED_FIFO; 24*51f3fe70SGabriele Monaco other->prio = MAX_RT_PRIO - 1; 25*51f3fe70SGabriele Monaco rv_sleep_ops.handle_task_newtask(NULL, target, 0); 26*51f3fe70SGabriele Monaco 27*51f3fe70SGabriele Monaco /* RT task sleeps on a non RT-friendly nanosleep */ 28*51f3fe70SGabriele Monaco rv_mock_current(target); 29*51f3fe70SGabriele Monaco args[0] = CLOCK_REALTIME; 30*51f3fe70SGabriele Monaco syscall_set_arguments(target, ®s, args); 31*51f3fe70SGabriele Monaco #ifdef __NR_clock_nanosleep 32*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sys_enter(NULL, ®s, __NR_clock_nanosleep); 33*51f3fe70SGabriele Monaco #elif defined(__NR_clock_nanosleep_time64) 34*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sys_enter(NULL, ®s, __NR_clock_nanosleep_time64); 35*51f3fe70SGabriele Monaco #endif 36*51f3fe70SGabriele Monaco RV_KUNIT_EXPECT_REACTION_HERE(test, ctx) 37*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sched_set_state(NULL, target, TASK_INTERRUPTIBLE); 38*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sys_exit(NULL, NULL, 0); 39*51f3fe70SGabriele Monaco 40*51f3fe70SGabriele Monaco /* RT task woken up by lower priority task */ 41*51f3fe70SGabriele Monaco args[1] = FUTEX_WAIT; 42*51f3fe70SGabriele Monaco syscall_set_arguments(target, ®s, args); 43*51f3fe70SGabriele Monaco rv_mock_current(target); 44*51f3fe70SGabriele Monaco #ifdef __NR_futex 45*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sys_enter(NULL, ®s, __NR_futex); 46*51f3fe70SGabriele Monaco #elif defined(__NR_futex_time64) 47*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sys_enter(NULL, ®s, __NR_futex_time64); 48*51f3fe70SGabriele Monaco #endif 49*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sched_set_state(NULL, target, TASK_INTERRUPTIBLE); 50*51f3fe70SGabriele Monaco rv_mock_current(other); 51*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sched_waking(NULL, target); 52*51f3fe70SGabriele Monaco rv_mock_current(target); 53*51f3fe70SGabriele Monaco RV_KUNIT_EXPECT_REACTION_HERE(test, ctx) 54*51f3fe70SGabriele Monaco rv_sleep_ops.handle_sched_exit(NULL, true); 55*51f3fe70SGabriele Monaco } 56*51f3fe70SGabriele Monaco 57*51f3fe70SGabriele Monaco #else 58*51f3fe70SGabriele Monaco #define rv_test_sleep rv_test_stub 59*51f3fe70SGabriele Monaco #endif 60