Hi Igor,
On 21/8/25 17:56, Igor Mammedov wrote:
the helpers form load-acquire/store-release pair and use them to replace
open-coded checkers/setters consistently across the code, which
ensures that appropriate barriers are in place in case checks happen
outside of BQL.
I don't understand the beginning of this sentence (even prepending
the patch subject).
Signed-off-by: Igor Mammedov <imamm...@redhat.com>
Reviewed-by: Peter Xu <pet...@redhat.com>
Reviewed-by: Jason J. Herne <jjhe...@linux.ibm.com>
---
v5: fix copy/paste error in doc comment of cpu_set_interrupt()
"Jason J. Herne" <jjhe...@linux.ibm.com>
v4:
add cpu_set_interrupt() and merge helpers patch with
patches that use them (v3 6-7,9/10).
Peter Xu <pet...@redhat.com>
---
include/hw/core/cpu.h | 25 +++++++++++++++++++++
accel/tcg/cpu-exec.c | 10 ++++-----
accel/tcg/tcg-accel-ops.c | 2 +-
accel/tcg/user-exec.c | 2 +-
hw/intc/s390_flic.c | 2 +-
hw/openrisc/cputimer.c | 2 +-
system/cpus.c | 2 +-
target/alpha/cpu.c | 8 +++----
target/arm/cpu.c | 20 ++++++++---------
target/arm/helper.c | 18 +++++++--------
target/arm/hvf/hvf.c | 6 ++---
target/avr/cpu.c | 2 +-
target/hppa/cpu.c | 2 +-
target/i386/hvf/hvf.c | 4 ++--
target/i386/hvf/x86hvf.c | 21 +++++++++---------
target/i386/kvm/kvm.c | 34 ++++++++++++++---------------
target/i386/nvmm/nvmm-all.c | 24 ++++++++++----------
target/i386/tcg/system/seg_helper.c | 2 +-
target/i386/tcg/system/svm_helper.c | 2 +-
target/i386/whpx/whpx-all.c | 34 ++++++++++++++---------------
target/loongarch/cpu.c | 2 +-
target/m68k/cpu.c | 2 +-
target/microblaze/cpu.c | 2 +-
target/mips/cpu.c | 6 ++---
target/mips/kvm.c | 2 +-
target/openrisc/cpu.c | 3 +--
target/ppc/cpu_init.c | 2 +-
target/ppc/kvm.c | 2 +-
target/rx/cpu.c | 3 +--
target/rx/helper.c | 2 +-
target/s390x/cpu-system.c | 2 +-
target/sh4/cpu.c | 2 +-
target/sh4/helper.c | 2 +-
target/sparc/cpu.c | 2 +-
target/sparc/int64_helper.c | 4 ++--
35 files changed, 141 insertions(+), 119 deletions(-)
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 5eaf41a566..1dee9d4c76 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -942,6 +942,31 @@ CPUState *cpu_by_arch_id(int64_t id);
void cpu_interrupt(CPUState *cpu, int mask);
+/**
+ * cpu_test_interrupt:
> + * @cpu: The CPU to check interrupt(s) on.> + * @mask: The
interrupts to check.
Can we use plural form to express we might test for more
than one interrupt in the mask?
-> cpu_test_interrupts()
otherwise cpu_test_interrupt_mask().
+ *
+ * Checks if any of interrupts in @mask are pending on @cpu.
+ */
+static inline bool cpu_test_interrupt(CPUState *cpu, int mask)
+{
+ return qatomic_load_acquire(&cpu->interrupt_request) & mask;
How missing "qemu/atomic.h" header.
+}
+
+/**
+ * cpu_set_interrupt:
+ * @cpu: The CPU to set pending interrupt(s) on.
+ * @mask: The interrupts to set.
Rename plural: cpu_set_interrupts() or _mask().
+ *
+ * Sets interrupts in @mask as pending on @cpu.
+ */
+static inline void cpu_set_interrupt(CPUState *cpu, int mask)
+{
+ qatomic_store_release(&cpu->interrupt_request,
+ cpu->interrupt_request | mask);
(indent is off)
+}
+
The field is described in CPUState as:
@interrupt_request: Indicates a pending interrupt request.
Can we update the description, mentioning its access should be
via the proper cpu_test_interrupts/cpu_set_interrupts/... helpers?
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 713bdb2056..1269c2c6ba 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -778,7 +778,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
*/
qatomic_set_mb(&cpu->neg.icount_decr.u16.high, 0);
- if (unlikely(qatomic_read(&cpu->interrupt_request))) {
+ if (unlikely(cpu_test_interrupt(cpu, ~0))) {
Maybe nitpicking, but I'd introduce the API and use it first only where
we already use atomic accesses. Then convert the rest of the code base
to this API in a distinct patch.
int interrupt_request;
bql_lock();
interrupt_request = cpu->interrupt_request;
@@ -786,7 +786,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
/* Mask out external interrupts for this step. */
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
}> - if (interrupt_request & CPU_INTERRUPT_DEBUG) {
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_DEBUG)) {
cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
cpu->exception_index = EXCP_DEBUG;
bql_unlock();
@@ -795,7 +795,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
#if !defined(CONFIG_USER_ONLY)
if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) {
/* Do nothing */
- } else if (interrupt_request & CPU_INTERRUPT_HALT) {
+ } else if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HALT)) {
replay_interrupt();
cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
Can we have a cpu_clear_interrupts() helper for completion? Likely we
need the same BQL-safe access.
cpu->halted = 1;
@@ -805,7 +805,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
} else {
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
- if (interrupt_request & CPU_INTERRUPT_RESET) {
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_RESET)) {
replay_interrupt();
tcg_ops->cpu_exec_reset(cpu);
bql_unlock();
@@ -841,7 +841,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
interrupt_request = cpu->interrupt_request;
}
#endif /* !CONFIG_USER_ONLY */
- if (interrupt_request & CPU_INTERRUPT_EXITTB) {
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_EXITTB)) {
cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
/* ensure that no TB jump will be modified as
the program flow was changed */
Looking at v4 applied on top of v10.1.0-rc4 reconstructing patch
#6 with v5:
$ git grep -F -- '->interrupt_request'
* Missing cpu_test_interrupts()
target/arm/machine.c:968: env->irq_line_state =
cs->interrupt_request &
target/i386/helper.c:600: int sipi = cs->interrupt_request &
CPU_INTERRUPT_SIPI;
target/i386/kvm/kvm.c:5067: events.smi.pending =
cs->interrupt_request & CPU_INTERRUPT_SMI;
target/i386/kvm/kvm.c:5068: events.smi.latched_init =
cs->interrupt_request & CPU_INTERRUPT_INIT;
* Possible uses of qatomic_load_acquire()?
accel/tcg/cpu-exec.c:801: int interrupt_request =
cpu->interrupt_request;
accel/tcg/tcg-accel-ops-icount.c:152: int old_mask =
cpu->interrupt_request;
* Candidates for cpu_clear_interrupts()
accel/tcg/cpu-exec.c:784: cpu->interrupt_request &=
~CPU_INTERRUPT_DEBUG;
accel/tcg/cpu-exec.c:794: cpu->interrupt_request &=
~CPU_INTERRUPT_HALT;
accel/tcg/cpu-exec.c:842: cpu->interrupt_request &=
~CPU_INTERRUPT_EXITTB;
hw/core/cpu-common.c:79: cpu->interrupt_request &= ~mask;
hw/core/cpu-system.c:207: cpu->interrupt_request &= ~0x01;
target/avr/helper.c:50: cs->interrupt_request &=
~CPU_INTERRUPT_RESET;
target/avr/helper.c:62: cs->interrupt_request &=
~CPU_INTERRUPT_HARD;
target/i386/helper.c:605: cs->interrupt_request = sipi;
target/i386/hvf/x86hvf.c:400: cs->interrupt_request &=
~CPU_INTERRUPT_NMI;
target/i386/hvf/x86hvf.c:412: cs->interrupt_request &=
~CPU_INTERRUPT_HARD;
target/i386/hvf/x86hvf.c:440: cs->interrupt_request &=
~CPU_INTERRUPT_POLL;
target/i386/hvf/x86hvf.c:453: cs->interrupt_request &=
~CPU_INTERRUPT_TPR;
target/i386/kvm/kvm.c:5069: cs->interrupt_request &=
~(CPU_INTERRUPT_INIT | CPU_INTERRUPT_SMI);
target/i386/kvm/kvm.c:5459: cpu->interrupt_request &=
~CPU_INTERRUPT_NMI;
target/i386/kvm/kvm.c:5470: cpu->interrupt_request &=
~CPU_INTERRUPT_SMI;
target/i386/kvm/kvm.c:5505: cpu->interrupt_request &=
~CPU_INTERRUPT_HARD;
target/i386/kvm/kvm.c:5600: cs->interrupt_request &=
~CPU_INTERRUPT_MCE;
target/i386/kvm/kvm.c:5630: cs->interrupt_request &=
~CPU_INTERRUPT_POLL;
target/i386/kvm/kvm.c:5643: cs->interrupt_request &=
~CPU_INTERRUPT_TPR;
target/i386/nvmm/nvmm-all.c:422: cpu->interrupt_request &=
~CPU_INTERRUPT_NMI;
target/i386/nvmm/nvmm-all.c:431: cpu->interrupt_request &=
~CPU_INTERRUPT_HARD;
target/i386/nvmm/nvmm-all.c:440: cpu->interrupt_request &=
~CPU_INTERRUPT_SMI;
target/i386/nvmm/nvmm-all.c:700: cpu->interrupt_request &=
~CPU_INTERRUPT_POLL;
target/i386/nvmm/nvmm-all.c:713: cpu->interrupt_request &=
~CPU_INTERRUPT_TPR;
target/i386/tcg/system/seg_helper.c:181: cs->interrupt_request &=
~CPU_INTERRUPT_POLL;
target/i386/tcg/system/seg_helper.c:189: cs->interrupt_request &=
~CPU_INTERRUPT_SMI;
target/i386/tcg/system/seg_helper.c:194: cs->interrupt_request &=
~CPU_INTERRUPT_NMI;
target/i386/tcg/system/seg_helper.c:199: cs->interrupt_request &=
~CPU_INTERRUPT_MCE;
target/i386/tcg/system/seg_helper.c:204: cs->interrupt_request &=
~(CPU_INTERRUPT_HARD |
target/i386/tcg/system/seg_helper.c:218: cs->interrupt_request &=
~CPU_INTERRUPT_VIRQ;
target/i386/tcg/system/svm_helper.c:827: cs->interrupt_request &=
~CPU_INTERRUPT_VIRQ;
target/i386/whpx/whpx-all.c:1474: cpu->interrupt_request &=
~CPU_INTERRUPT_NMI;
target/i386/whpx/whpx-all.c:1481: cpu->interrupt_request &=
~CPU_INTERRUPT_SMI;
target/i386/whpx/whpx-all.c:1505: cpu->interrupt_request
&= ~CPU_INTERRUPT_HARD;
target/i386/whpx/whpx-all.c:1523: cpu->interrupt_request &=
~CPU_INTERRUPT_HARD;
target/i386/whpx/whpx-all.c:1610: cpu->interrupt_request &=
~CPU_INTERRUPT_POLL;
target/i386/whpx/whpx-all.c:1626: cpu->interrupt_request &=
~CPU_INTERRUPT_TPR;
target/openrisc/sys_helper.c:199: cs->interrupt_request
&= ~CPU_INTERRUPT_TIMER;
target/rx/helper.c:66: cs->interrupt_request &=
~CPU_INTERRUPT_FIR;
target/rx/helper.c:76: cs->interrupt_request &=
~CPU_INTERRUPT_HARD;
target/s390x/tcg/excp_helper.c:562: cs->interrupt_request &=
~CPU_INTERRUPT_HARD;