On Tue, Jan 3, 2023 at 9:48 AM Thomas Huth <th...@redhat.com> wrote:

> These IRQ counting functions will soon be required in binaries that
> do not include the APIC code, too, so let's extract them into a
> separate file that can be linked independently of the APIC code.
>
> While we're at it, change the apic_* prefix into kvm_* since the
> functions are used from the i8259 PIC (i.e. not the APIC), too.
>
> Signed-off-by: Thomas Huth <th...@redhat.com>
> ---
>  include/hw/i386/apic.h          |  2 --
>  include/hw/i386/apic_internal.h |  1 -
>  include/hw/intc/kvm_irqcount.h  | 10 +++++++
>  hw/i386/kvm/i8259.c             |  4 +--
>  hw/i386/kvm/ioapic.c            |  4 +--
>  hw/intc/apic.c                  |  3 +-
>  hw/intc/apic_common.c           | 30 ++------------------
>  hw/intc/kvm_irqcount.c          | 49 +++++++++++++++++++++++++++++++++
>  hw/rtc/mc146818rtc.c            |  6 ++--
>  hw/intc/meson.build             |  6 ++++
>  hw/intc/trace-events            |  9 +++---
>  11 files changed, 81 insertions(+), 43 deletions(-)
>  create mode 100644 include/hw/intc/kvm_irqcount.h
>  create mode 100644 hw/intc/kvm_irqcount.c
>
> diff --git a/include/hw/i386/apic.h b/include/hw/i386/apic.h
> index da1d2fe155..bdc15a7a73 100644
> --- a/include/hw/i386/apic.h
> +++ b/include/hw/i386/apic.h
> @@ -9,8 +9,6 @@ int apic_accept_pic_intr(DeviceState *s);
>  void apic_deliver_pic_intr(DeviceState *s, int level);
>  void apic_deliver_nmi(DeviceState *d);
>  int apic_get_interrupt(DeviceState *s);
> -void apic_reset_irq_delivered(void);
> -int apic_get_irq_delivered(void);
>  void cpu_set_apic_base(DeviceState *s, uint64_t val);
>  uint64_t cpu_get_apic_base(DeviceState *s);
>  void cpu_set_apic_tpr(DeviceState *s, uint8_t val);
> diff --git a/include/hw/i386/apic_internal.h
> b/include/hw/i386/apic_internal.h
> index c175e7e718..e61ad04769 100644
> --- a/include/hw/i386/apic_internal.h
> +++ b/include/hw/i386/apic_internal.h
> @@ -199,7 +199,6 @@ typedef struct VAPICState {
>
>  extern bool apic_report_tpr_access;
>
> -void apic_report_irq_delivered(int delivered);
>  bool apic_next_timer(APICCommonState *s, int64_t current_time);
>  void apic_enable_tpr_access_reporting(DeviceState *d, bool enable);
>  void apic_enable_vapic(DeviceState *d, hwaddr paddr);
> diff --git a/include/hw/intc/kvm_irqcount.h
> b/include/hw/intc/kvm_irqcount.h
> new file mode 100644
> index 0000000000..0ed5999e49
> --- /dev/null
> +++ b/include/hw/intc/kvm_irqcount.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +
> +#ifndef KVM_IRQCOUNT_H
> +#define KVM_IRQCOUNT_H
> +
> +void kvm_report_irq_delivered(int delivered);
> +void kvm_reset_irq_delivered(void);
> +int kvm_get_irq_delivered(void);
> +
> +#endif
> diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c
> index d61bae4dc3..3ca0e1ff03 100644
> --- a/hw/i386/kvm/i8259.c
> +++ b/hw/i386/kvm/i8259.c
> @@ -14,7 +14,7 @@
>  #include "hw/isa/i8259_internal.h"
>  #include "hw/intc/i8259.h"
>  #include "qemu/module.h"
> -#include "hw/i386/apic_internal.h"
> +#include "hw/intc/kvm_irqcount.h"
>  #include "hw/irq.h"
>  #include "sysemu/kvm.h"
>  #include "qom/object.h"
> @@ -117,7 +117,7 @@ static void kvm_pic_set_irq(void *opaque, int irq, int
> level)
>
>      pic_stat_update_irq(irq, level);
>      delivered = kvm_set_irq(kvm_state, irq, level);
> -    apic_report_irq_delivered(delivered);
> +    kvm_report_irq_delivered(delivered);
>  }
>
>  static void kvm_pic_realize(DeviceState *dev, Error **errp)
> diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
> index ee7c8ef68b..272e26b4a2 100644
> --- a/hw/i386/kvm/ioapic.c
> +++ b/hw/i386/kvm/ioapic.c
> @@ -15,7 +15,7 @@
>  #include "hw/i386/x86.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/i386/ioapic_internal.h"
> -#include "hw/i386/apic_internal.h"
> +#include "hw/intc/kvm_irqcount.h"
>  #include "sysemu/kvm.h"
>
>  /* PC Utility function */
> @@ -116,7 +116,7 @@ static void kvm_ioapic_set_irq(void *opaque, int irq,
> int level)
>
>      ioapic_stat_update_irq(common, irq, level);
>      delivered = kvm_set_irq(kvm_state, s->kvm_gsi_base + irq, level);
> -    apic_report_irq_delivered(delivered);
> +    kvm_report_irq_delivered(delivered);
>  }
>
>  static void kvm_ioapic_realize(DeviceState *dev, Error **errp)
> diff --git a/hw/intc/apic.c b/hw/intc/apic.c
> index 3df11c34d6..2d3e55f4e2 100644
> --- a/hw/intc/apic.c
> +++ b/hw/intc/apic.c
> @@ -22,6 +22,7 @@
>  #include "hw/i386/apic.h"
>  #include "hw/i386/ioapic.h"
>  #include "hw/intc/i8259.h"
> +#include "hw/intc/kvm_irqcount.h"
>  #include "hw/pci/msi.h"
>  #include "qemu/host-utils.h"
>  #include "sysemu/kvm.h"
> @@ -399,7 +400,7 @@ void apic_poll_irq(DeviceState *dev)
>
>  static void apic_set_irq(APICCommonState *s, int vector_num, int
> trigger_mode)
>  {
> -    apic_report_irq_delivered(!apic_get_bit(s->irr, vector_num));
> +    kvm_report_irq_delivered(!apic_get_bit(s->irr, vector_num));
>
>      apic_set_bit(s->irr, vector_num);
>      if (trigger_mode)
> diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
> index 2a20982066..4a34f03047 100644
> --- a/hw/intc/apic_common.c
> +++ b/hw/intc/apic_common.c
> @@ -25,6 +25,7 @@
>  #include "qapi/visitor.h"
>  #include "hw/i386/apic.h"
>  #include "hw/i386/apic_internal.h"
> +#include "hw/intc/kvm_irqcount.h"
>  #include "trace.h"
>  #include "hw/boards.h"
>  #include "sysemu/hax.h"
> @@ -33,7 +34,6 @@
>  #include "hw/sysbus.h"
>  #include "migration/vmstate.h"
>
> -static int apic_irq_delivered;
>  bool apic_report_tpr_access;
>
>  void cpu_set_apic_base(DeviceState *dev, uint64_t val)
> @@ -122,32 +122,6 @@ void apic_handle_tpr_access_report(DeviceState *dev,
> target_ulong ip,
>      vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access);
>  }
>
> -void apic_report_irq_delivered(int delivered)
> -{
> -    apic_irq_delivered += delivered;
> -
> -    trace_apic_report_irq_delivered(apic_irq_delivered);
> -}
> -
> -void apic_reset_irq_delivered(void)
> -{
> -    /* Copy this into a local variable to encourage gcc to emit a plain
> -     * register for a sys/sdt.h marker.  For details on this workaround,
> see:
> -     * https://sourceware.org/bugzilla/show_bug.cgi?id=13296
> -     */
> -    volatile int a_i_d = apic_irq_delivered;
> -    trace_apic_reset_irq_delivered(a_i_d);
> -
> -    apic_irq_delivered = 0;
> -}
> -
> -int apic_get_irq_delivered(void)
> -{
> -    trace_apic_get_irq_delivered(apic_irq_delivered);
> -
> -    return apic_irq_delivered;
> -}
> -
>  void apic_deliver_nmi(DeviceState *dev)
>  {
>      APICCommonState *s = APIC_COMMON(dev);
> @@ -272,7 +246,7 @@ static void apic_reset_common(DeviceState *dev)
>      s->apicbase = APIC_DEFAULT_ADDRESS | bsp | MSR_IA32_APICBASE_ENABLE;
>      s->id = s->initial_apic_id;
>
> -    apic_reset_irq_delivered();
> +    kvm_reset_irq_delivered();
>
>      s->vapic_paddr = 0;
>      info->vapic_base_update(s);
> diff --git a/hw/intc/kvm_irqcount.c b/hw/intc/kvm_irqcount.c
> new file mode 100644
> index 0000000000..2ef8a83a7a
> --- /dev/null
> +++ b/hw/intc/kvm_irqcount.c
> @@ -0,0 +1,49 @@
> +/*
> + * KVM PIC functions for counting the delivered IRQs.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <
> http://www.gnu.org/licenses/>
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/intc/kvm_irqcount.h"
> +#include "trace.h"
> +
> +static int kvm_irq_delivered;
> +
> +void kvm_report_irq_delivered(int delivered)
> +{
> +    kvm_irq_delivered += delivered;
> +
> +    trace_kvm_report_irq_delivered(kvm_irq_delivered);
> +}
> +
> +void kvm_reset_irq_delivered(void)
> +{
> +    /*
> +     * Copy this into a local variable to encourage gcc to emit a plain
> +     * register for a sys/sdt.h marker.  For details on this workaround,
> see:
> +     * https://sourceware.org/bugzilla/show_bug.cgi?id=13296
> +     */
> +    volatile int k_i_d = kvm_irq_delivered;
> +    trace_kvm_reset_irq_delivered(k_i_d);
> +
> +    kvm_irq_delivered = 0;
> +}
> +
> +int kvm_get_irq_delivered(void)
> +{
> +    trace_kvm_get_irq_delivered(kvm_irq_delivered);
> +
> +    return kvm_irq_delivered;
> +}
> diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
> index 1ebb412479..947d68c257 100644
> --- a/hw/rtc/mc146818rtc.c
> +++ b/hw/rtc/mc146818rtc.c
> @@ -27,6 +27,7 @@
>  #include "qemu/module.h"
>  #include "qemu/bcd.h"
>  #include "hw/acpi/acpi_aml_interface.h"
> +#include "hw/intc/kvm_irqcount.h"
>  #include "hw/irq.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/qdev-properties-system.h"
> @@ -46,7 +47,6 @@
>
>  #ifdef TARGET_I386
>  #include "qapi/qapi-commands-misc-target.h"
> -#include "hw/i386/apic.h"
>  #endif
>
>  //#define DEBUG_CMOS
> @@ -124,9 +124,9 @@ void qmp_rtc_reset_reinjection(Error **errp)
>
>  static bool rtc_policy_slew_deliver_irq(RTCState *s)
>  {
> -    apic_reset_irq_delivered();
> +    kvm_reset_irq_delivered();
>      qemu_irq_raise(s->irq);
> -    return apic_get_irq_delivered();
> +    return kvm_get_irq_delivered();
>  }
>
>  static void rtc_coalesced_timer(void *opaque)
> diff --git a/hw/intc/meson.build b/hw/intc/meson.build
> index bcbf22ff51..cd9f1ee888 100644
> --- a/hw/intc/meson.build
> +++ b/hw/intc/meson.build
> @@ -25,6 +25,12 @@ softmmu_ss.add(when: 'CONFIG_XILINX', if_true:
> files('xilinx_intc.c'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true:
> files('xlnx-zynqmp-ipi.c'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true:
> files('xlnx-pmu-iomod-intc.c'))
>
> +if config_all_devices.has_key('CONFIG_APIC') or \
> +   config_all_devices.has_key('CONFIG_I8259') or \
> +   config_all_devices.has_key('CONFIG_MC146818RTC')
> +    softmmu_ss.add(files('kvm_irqcount.c'))
> +endif
>

I'd slightly prefer to track these dependencies via KConfig since its
declarative nature seems to lend itself better for tooling. Anyway:

Reviewed-by: Bernhard Beschow <shen...@gmail.com>

+
>  specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true:
> files('allwinner-a10-pic.c'))
>  specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c',
> 'apic_common.c'))
>  specific_ss.add(when: 'CONFIG_ARM_GIC', if_true:
> files('arm_gicv3_cpuif_common.c'))
> diff --git a/hw/intc/trace-events b/hw/intc/trace-events
> index 6fbc2045e6..50cadfb996 100644
> --- a/hw/intc/trace-events
> +++ b/hw/intc/trace-events
> @@ -10,10 +10,6 @@ pic_ioport_read(bool master, uint64_t addr, int val)
> "master %d addr 0x%"PRIx64"
>  # apic_common.c
>  cpu_set_apic_base(uint64_t val) "0x%016"PRIx64
>  cpu_get_apic_base(uint64_t val) "0x%016"PRIx64
> -# coalescing
> -apic_report_irq_delivered(int apic_irq_delivered) "coalescing %d"
> -apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
> -apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
>
>  # apic.c
>  apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
> @@ -30,6 +26,11 @@ ioapic_mem_read(uint8_t addr, uint8_t regsel, uint8_t
> size, uint32_t val) "ioapi
>  ioapic_mem_write(uint8_t addr, uint8_t regsel, uint8_t size, uint32_t
> val) "ioapic mem write addr 0x%"PRIx8" regsel: 0x%"PRIx8" size 0x%"PRIx8"
> val 0x%"PRIx32
>  ioapic_set_irq(int vector, int level) "vector: %d level: %d"
>
> +# kvm_irqcount.c
> +kvm_report_irq_delivered(int irq_delivered) "coalescing %d"
> +kvm_reset_irq_delivered(int irq_delivered) "old coalescing %d"
> +kvm_get_irq_delivered(int irq_delivered) "returning coalescing %d"
> +
>  # slavio_intctl.c
>  slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read
> cpu %d reg 0x%"PRIx64" = 0x%x"
>  slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val)
> "write cpu %d reg 0x%"PRIx64" = 0x%x"
> --
> 2.31.1
>
>

Reply via email to