All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] target/s390x: Fix missing clock-comparator interrupts
@ 2025-10-16 12:06 Ilya Leoshkevich
  2025-10-16 12:06 ` [PATCH v3 1/3] target/s390x: Fix missing interrupts for small CKC values Ilya Leoshkevich
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2025-10-16 12:06 UTC (permalink / raw)
  To: Thomas Huth, Richard Henderson, David Hildenbrand
  Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich

v2: https://lore.kernel.org/qemu-devel/20251015142141.3238-1-iii@linux.ibm.com/
v2 -> v3: Rearm the timer on control register load (Thomas).
          Add Thomas' R-b to the test.

v1: https://lore.kernel.org/qemu-devel/20251014160743.398093-1-iii@linux.ibm.com/
v1 -> v2: Add Thomas' R-b.
          Cc: stable (Michael).
          Improve formatting, commit messages, and test (Ilya).

Hi,

While trying to (so far unsuccessfully) reproduce [1], I found two bugs
in the clock comparator handling. This series fixes both and adds a
test.

[1] https://lore.kernel.org/lkml/ab3131a2-c42a-47ff-bf03-e9f68ac053c0@t-8ch.de/

Best regards,
Ilya

Ilya Leoshkevich (3):
  target/s390x: Fix missing interrupts for small CKC values
  target/s390x: Fix missing clock-comparator interrupts after reset
  tests/tcg/s390x: Test SET CLOCK COMPARATOR

 target/s390x/tcg/mem_helper.c           | 11 ++++-
 target/s390x/tcg/misc_helper.c          | 12 ++++--
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/sckc.S                  | 55 +++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 5 deletions(-)
 create mode 100644 tests/tcg/s390x/sckc.S

-- 
2.51.0



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/3] target/s390x: Fix missing interrupts for small CKC values
  2025-10-16 12:06 [PATCH v3 0/3] target/s390x: Fix missing clock-comparator interrupts Ilya Leoshkevich
@ 2025-10-16 12:06 ` Ilya Leoshkevich
  2025-10-16 12:07 ` [PATCH v3 2/3] target/s390x: Fix missing clock-comparator interrupts after reset Ilya Leoshkevich
  2025-10-16 12:07 ` [PATCH v3 3/3] tests/tcg/s390x: Test SET CLOCK COMPARATOR Ilya Leoshkevich
  2 siblings, 0 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2025-10-16 12:06 UTC (permalink / raw)
  To: Thomas Huth, Richard Henderson, David Hildenbrand
  Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich, qemu-stable

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.

Cc: qemu-stable@nongnu.org
Reviewed-by: Thomas Huth <thuth@redhat.com>
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..215b5b9d933 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



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/3] target/s390x: Fix missing clock-comparator interrupts after reset
  2025-10-16 12:06 [PATCH v3 0/3] target/s390x: Fix missing clock-comparator interrupts Ilya Leoshkevich
  2025-10-16 12:06 ` [PATCH v3 1/3] target/s390x: Fix missing interrupts for small CKC values Ilya Leoshkevich
@ 2025-10-16 12:07 ` Ilya Leoshkevich
  2025-10-16 13:29   ` Thomas Huth
  2025-10-16 12:07 ` [PATCH v3 3/3] tests/tcg/s390x: Test SET CLOCK COMPARATOR Ilya Leoshkevich
  2 siblings, 1 reply; 5+ messages in thread
From: Ilya Leoshkevich @ 2025-10-16 12:07 UTC (permalink / raw)
  To: Thomas Huth, Richard Henderson, David Hildenbrand
  Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich, qemu-stable

After reset, CKC value is set to 0, so if clock-comparator interrupts
are enabled, one should occur very shortly thereafter.

Currently the code that loads the respective control register does not
set tod_timer, so this does not happen.

Fix by adding a tcg_s390_tod_updated() call to LCTL and LCTLG.

Cc: qemu-stable@nongnu.org
Suggested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 target/s390x/tcg/mem_helper.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index f1acb1618f7..24675fc818d 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -1959,6 +1959,10 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
         if (env->cregs[i] != val && i >= 9 && i <= 11) {
             PERchanged = true;
         }
+        if (i == 0 && !(env->cregs[i] & CR0_CKC_SC) && (val & CR0_CKC_SC)) {
+            BQL_LOCK_GUARD();
+            tcg_s390_tod_updated(env_cpu(env), RUN_ON_CPU_NULL);
+        }
         env->cregs[i] = val;
         HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
                    i, src, val);
@@ -1989,10 +1993,15 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
 
     for (i = r1;; i = (i + 1) % 16) {
         uint32_t val = cpu_ldl_data_ra(env, src, ra);
+        uint64_t val64 = deposit64(env->cregs[i], 0, 32, val);
         if ((uint32_t)env->cregs[i] != val && i >= 9 && i <= 11) {
             PERchanged = true;
         }
-        env->cregs[i] = deposit64(env->cregs[i], 0, 32, val);
+        if (i == 0 && !(env->cregs[i] & CR0_CKC_SC) && (val64 & CR0_CKC_SC)) {
+            BQL_LOCK_GUARD();
+            tcg_s390_tod_updated(env_cpu(env), RUN_ON_CPU_NULL);
+        }
+        env->cregs[i] = val64;
         HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%x\n", i, src, val);
         src += sizeof(uint32_t);
 
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 3/3] tests/tcg/s390x: Test SET CLOCK COMPARATOR
  2025-10-16 12:06 [PATCH v3 0/3] target/s390x: Fix missing clock-comparator interrupts Ilya Leoshkevich
  2025-10-16 12:06 ` [PATCH v3 1/3] target/s390x: Fix missing interrupts for small CKC values Ilya Leoshkevich
  2025-10-16 12:07 ` [PATCH v3 2/3] target/s390x: Fix missing clock-comparator interrupts after reset Ilya Leoshkevich
@ 2025-10-16 12:07 ` Ilya Leoshkevich
  2 siblings, 0 replies; 5+ messages in thread
From: Ilya Leoshkevich @ 2025-10-16 12:07 UTC (permalink / raw)
  To: Thomas Huth, Richard Henderson, David Hildenbrand
  Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich, qemu-stable

Add a small test to prevent regressions.

Cc: qemu-stable@nongnu.org
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/sckc.S                  | 55 +++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 tests/tcg/s390x/sckc.S

diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target
index 8cd4667c63b..a4425d3184a 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -28,6 +28,7 @@ ASM_TESTS =                                                                    \
     mc                                                                         \
     per                                                                        \
     precise-smc-softmmu                                                        \
+    sckc                                                                       \
     ssm-early                                                                  \
     stosm-early                                                                \
     stpq                                                                       \
diff --git a/tests/tcg/s390x/sckc.S b/tests/tcg/s390x/sckc.S
new file mode 100644
index 00000000000..66e8733f45c
--- /dev/null
+++ b/tests/tcg/s390x/sckc.S
@@ -0,0 +1,55 @@
+/*
+ * Test clock comparator.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .org 0x130
+ext_old_psw:
+    .org 0x1b0
+ext_new_psw:
+    .quad 0x180000000, _ext            /* 64-bit mode */
+    .org 0x200                         /* lowcore padding */
+
+    .globl _start
+_start:
+    lpswe start31_psw
+_start31:
+    stctg %c0,%c0,c0
+    oi c0+6,8                          /* set clock-comparator subclass mask */
+    lctlg %c0,%c0,c0
+    jg .
+
+_ext:
+    stg %r0,ext_saved_r0
+
+    lg %r0,ext_counter
+    aghi %r0,1
+    stg %r0,ext_counter
+
+    cgfi %r0,0x1000
+    jnz 0f
+    lpswe success_psw
+0:
+
+    stck clock
+    lg %r0,clock
+    agfi %r0,0x40000                   /* 64us * 0x1000 =~ 0.25s */
+    stg %r0,clock
+    sckc clock
+
+    lg %r0,ext_saved_r0
+    lpswe ext_old_psw
+
+    .align 8
+start31_psw:
+    .quad 0x100000080000000,_start31   /* EX, 31-bit mode */
+success_psw:
+    .quad 0x2000000000000,0xfff        /* see is_special_wait_psw() */
+c0:
+    .skip 8
+clock:
+    .quad 0
+ext_counter:
+    .quad 0
+ext_saved_r0:
+    .skip 8
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 2/3] target/s390x: Fix missing clock-comparator interrupts after reset
  2025-10-16 12:07 ` [PATCH v3 2/3] target/s390x: Fix missing clock-comparator interrupts after reset Ilya Leoshkevich
@ 2025-10-16 13:29   ` Thomas Huth
  0 siblings, 0 replies; 5+ messages in thread
From: Thomas Huth @ 2025-10-16 13:29 UTC (permalink / raw)
  To: Ilya Leoshkevich, Richard Henderson, David Hildenbrand
  Cc: qemu-s390x, qemu-devel, qemu-stable

On 16/10/2025 14.07, Ilya Leoshkevich wrote:
> After reset, CKC value is set to 0, so if clock-comparator interrupts
> are enabled, one should occur very shortly thereafter.
> 
> Currently the code that loads the respective control register does not
> set tod_timer, so this does not happen.
> 
> Fix by adding a tcg_s390_tod_updated() call to LCTL and LCTLG.

(I just realized that I mixed up store and load in my previous mail to this 
patch in v2, sorry for the confusion)

> Cc: qemu-stable@nongnu.org
> Suggested-by: Thomas Huth <thuth@redhat.com>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   target/s390x/tcg/mem_helper.c | 11 ++++++++++-
>   1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
> index f1acb1618f7..24675fc818d 100644
> --- a/target/s390x/tcg/mem_helper.c
> +++ b/target/s390x/tcg/mem_helper.c
> @@ -1959,6 +1959,10 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>           if (env->cregs[i] != val && i >= 9 && i <= 11) {
>               PERchanged = true;
>           }
> +        if (i == 0 && !(env->cregs[i] & CR0_CKC_SC) && (val & CR0_CKC_SC)) {
> +            BQL_LOCK_GUARD();
> +            tcg_s390_tod_updated(env_cpu(env), RUN_ON_CPU_NULL);
> +        }
>           env->cregs[i] = val;
>           HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
>                      i, src, val);
> @@ -1989,10 +1993,15 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>   
>       for (i = r1;; i = (i + 1) % 16) {
>           uint32_t val = cpu_ldl_data_ra(env, src, ra);
> +        uint64_t val64 = deposit64(env->cregs[i], 0, 32, val);
>           if ((uint32_t)env->cregs[i] != val && i >= 9 && i <= 11) {
>               PERchanged = true;
>           }
> -        env->cregs[i] = deposit64(env->cregs[i], 0, 32, val);
> +        if (i == 0 && !(env->cregs[i] & CR0_CKC_SC) && (val64 & CR0_CKC_SC)) {
> +            BQL_LOCK_GUARD();
> +            tcg_s390_tod_updated(env_cpu(env), RUN_ON_CPU_NULL);
> +        }
> +        env->cregs[i] = val64;

That looks nicer to me, indeed, thanks!

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



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-10-16 13:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-16 12:06 [PATCH v3 0/3] target/s390x: Fix missing clock-comparator interrupts Ilya Leoshkevich
2025-10-16 12:06 ` [PATCH v3 1/3] target/s390x: Fix missing interrupts for small CKC values Ilya Leoshkevich
2025-10-16 12:07 ` [PATCH v3 2/3] target/s390x: Fix missing clock-comparator interrupts after reset Ilya Leoshkevich
2025-10-16 13:29   ` Thomas Huth
2025-10-16 12:07 ` [PATCH v3 3/3] tests/tcg/s390x: Test SET CLOCK COMPARATOR Ilya Leoshkevich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.