[PATCH 1/3] target/s390x: Fix missing interrupts for small CKC values

Ilya Leoshkevich posted 3 patches 1 month ago
Maintainers: Thomas Huth <thuth@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, David Hildenbrand <david@redhat.com>, Ilya Leoshkevich <iii@linux.ibm.com>, Halil Pasic <pasic@linux.ibm.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, Eric Farman <farman@linux.ibm.com>, Matthew Rosato <mjrosato@linux.ibm.com>
There is a newer version of this series
[PATCH 1/3] target/s390x: Fix missing interrupts for small CKC values
Posted by Ilya Leoshkevich 1 month ago
Suppose TOD clock value is 0x1111111111111111 and clock-comparator
value is 0, in which case clock-comparator interruption should occur
immediately.

With the current code, tod2time(env->ckc - td->base.low) ends up being
a very large number, so this interruption never happens.

Fix by firing the timer immediately if env->ckc < td->base.low.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 target/s390x/tcg/misc_helper.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c
index 6d9d601d29a..afcf7688eda 100644
--- a/target/s390x/tcg/misc_helper.c
+++ b/target/s390x/tcg/misc_helper.c
@@ -199,11 +199,15 @@ static void update_ckc_timer(CPUS390XState *env)
         return;
     }
 
-    /* difference between origins */
-    time = env->ckc - td->base.low;
+    if (env->ckc < td->base.low) {
+	time = 0;
+    } else {
+	/* difference between origins */
+	time = env->ckc - td->base.low;
 
-    /* nanoseconds */
-    time = tod2time(time);
+	/* nanoseconds */
+	time = tod2time(time);
+    }
 
     timer_mod(env->tod_timer, time);
 }
-- 
2.51.0
Re: [PATCH 1/3] target/s390x: Fix missing interrupts for small CKC values
Posted by Thomas Huth 1 month ago
On 14/10/2025 18.05, Ilya Leoshkevich wrote:
> Suppose TOD clock value is 0x1111111111111111 and clock-comparator
> value is 0, in which case clock-comparator interruption should occur
> immediately.
> 
> With the current code, tod2time(env->ckc - td->base.low) ends up being
> a very large number, so this interruption never happens.
> 
> Fix by firing the timer immediately if env->ckc < td->base.low.
> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   target/s390x/tcg/misc_helper.c | 12 ++++++++----
>   1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c
> index 6d9d601d29a..afcf7688eda 100644
> --- a/target/s390x/tcg/misc_helper.c
> +++ b/target/s390x/tcg/misc_helper.c
> @@ -199,11 +199,15 @@ static void update_ckc_timer(CPUS390XState *env)
>           return;
>       }
>   
> -    /* difference between origins */
> -    time = env->ckc - td->base.low;
> +    if (env->ckc < td->base.low) {
> +	time = 0;
> +    } else {
> +	/* difference between origins */
> +	time = env->ckc - td->base.low;
>   
> -    /* nanoseconds */
> -    time = tod2time(time);
> +	/* nanoseconds */
> +	time = tod2time(time);
> +    }
>   
>       timer_mod(env->tod_timer, time);
>   }

Yes, this looks right.

Reviewed-by: Thomas Huth <thuth@redhat.com>