Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lv2: Fix overflows of periodic timers #10287

Merged
merged 1 commit into from May 17, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 15 additions & 8 deletions rpcs3/Emu/Cell/lv2/sys_timer.cpp
Expand Up @@ -42,7 +42,8 @@ void lv2_timer_context::operator()()
if (period)
{
// Set next expiration time and check again
expire += period;
const u64 _next = next + period;
expire.release(_next > next ? _next : UINT64_MAX);
continue;
}

Expand Down Expand Up @@ -135,12 +136,6 @@ error_code _sys_timer_start(ppu_thread& ppu, u32 timer_id, u64 base_time, u64 pe

const u64 start_time = get_guest_system_time();

if (!period && start_time >= base_time)
{
// Invalid oneshot (TODO: what will happen if both args are 0?)
return not_an_error(CELL_ETIMEDOUT);
}

if (period && period < 100)
{
// Invalid periodic timer
Expand All @@ -161,8 +156,15 @@ error_code _sys_timer_start(ppu_thread& ppu, u32 timer_id, u64 base_time, u64 pe
return CELL_EBUSY;
}

if (!period && start_time >= base_time)
{
// Invalid oneshot
return CELL_ETIMEDOUT;
}

// sys_timer_start_periodic() will use current time (TODO: is it correct?)
timer.expire = base_time ? base_time : start_time + period;
const u64 expire = base_time ? base_time : start_time + period;
timer.expire = expire > start_time ? expire : UINT64_MAX;
timer.period = period;
timer.state = SYS_TIMER_STATE_RUN;

Expand All @@ -178,6 +180,11 @@ error_code _sys_timer_start(ppu_thread& ppu, u32 timer_id, u64 base_time, u64 pe

if (timer.ret)
{
if (timer.ret == CELL_ETIMEDOUT)
{
return not_an_error(timer.ret);
}

return timer.ret;
}

Expand Down