On Mon, 11 Aug 2025 12:31:27 -0400
Peter Xu <pet...@redhat.com> wrote:

> On Fri, Aug 08, 2025 at 02:01:33PM +0200, Igor Mammedov wrote:
> > the helper forms load-acquire/store-release pair with
> > tcg_handle_interrupt/generic_handle_interrupt and can be used
> > for checking interrupts outside of BQL
> > 
> > Signed-off-by: Igor Mammedov <imamm...@redhat.com>
> > ---
> >  include/hw/core/cpu.h     | 12 ++++++++++++
> >  accel/tcg/tcg-accel-ops.c |  3 ++-
> >  system/cpus.c             |  3 ++-
> >  3 files changed, 16 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> > index 5eaf41a566..d0460c01cf 100644
> > --- a/include/hw/core/cpu.h
> > +++ b/include/hw/core/cpu.h
> > @@ -942,6 +942,18 @@ 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.
> > + *
> > + * 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;
> > +}
> > +
> >  /**
> >   * cpu_set_pc:
> >   * @cpu: The CPU to set the program counter for.
> > diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
> > index 3b0d7d298e..02c7600bb7 100644
> > --- a/accel/tcg/tcg-accel-ops.c
> > +++ b/accel/tcg/tcg-accel-ops.c
> > @@ -97,7 +97,8 @@ static void tcg_cpu_reset_hold(CPUState *cpu)
> >  /* mask must never be zero, except for A20 change call */
> >  void tcg_handle_interrupt(CPUState *cpu, int mask)
> >  {
> > -    cpu->interrupt_request |= mask;
> > +    qatomic_store_release(&cpu->interrupt_request,
> > +        cpu->interrupt_request | mask);
> >  
> >      /*
> >       * If called from iothread context, wake the target cpu in
> > diff --git a/system/cpus.c b/system/cpus.c
> > index 256723558d..8e543488c3 100644
> > --- a/system/cpus.c
> > +++ b/system/cpus.c
> > @@ -256,7 +256,8 @@ int64_t cpus_get_elapsed_ticks(void)
> >  
> >  void generic_handle_interrupt(CPUState *cpu, int mask)
> >  {
> > -    cpu->interrupt_request |= mask;
> > +    qatomic_store_release(&cpu->interrupt_request,
> > +        cpu->interrupt_request | mask);
> >  
> >      if (!qemu_cpu_is_self(cpu)) {
> >          qemu_cpu_kick(cpu);
> > -- 
> > 2.47.1
> >   
> 
> Besides the two writters mentioned above, I still see some more:
> 
> *** accel/tcg/user-exec.c:
> cpu_interrupt[52]              cpu->interrupt_request |= mask;

I don't know if external interrupts can happen in user mode,
for same thread(self) exceptions we don't really need it.

> *** hw/intc/s390_flic.c:
> qemu_s390_flic_notify[193]     cs->interrupt_request |= CPU_INTERRUPT_HARD;

later on the function, for cpus it deemed not to ignore,
explicitly calls cpu_interrupt() which will do store_release.
I'd tentatively would say we don't need explicit store_release here

Anyways CCing David, perhaps he would recall why it's setting interrupt for all
but ignores to actually rise it for some.

> *** hw/openrisc/cputimer.c:
> openrisc_timer_cb[108]         cs->interrupt_request |= CPU_INTERRUPT_TIMER;

this one seems to be similar to generic_handle_interrupt(),
interrupt request from external thread, so I'd add store_release here.

Arguably, it should be calling cpu_interrupt() instead of opencoding it.
(the questionable part is that it set interrupt conditionally but
kicks vccpu always - is this really necessary?)


> *** target/arm/helper.c:
> arm_cpu_do_interrupt[9150]     cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
on kvm it can be reached via main thread or vcpu(self) thread.
so tentatively we need it here.

(ps: kvm_arch_on_sigbus_vcpu()->arm_cpu_do_interrupt() is called under BQL
while kvm_on_sigbus() is called without one from signal handler,
which theoretically might trample on the thread running the 1st vcpu)

> *** target/i386/tcg/system/svm_helper.c:
> helper_vmrun[406]              cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
this one seems to be self targeted (i.e. same thread),
perhaps TCG experts can comment on it.

CCing TCG folks as series touches a few TCG bits anyway


> Do they better as well be converted to use store_release too?

alternatively, for consistency sake we can add a helper to set interrupt
with store_release included and do a blanket tree wide change like with
cpu_test_interrupt().
 
> The other nitpick is this patch introduces the reader helper but without
> using it.
> 
> It can be squashed into the other patch where the reader helper will be
> applied tree-wide.  IMHO that would be better explaining the helper on its
> own.

I can merge it with 7/10 that adds 1st user for the helper in kvm/i386 code.
That has less chances for the store/acquire change to be drowned in
tree wide patch (9/10)

> 
> Thanks,
> 


Reply via email to