diff mbox series

[v5,17/20] hw/intc: properly model IOAPIC MSI messages

Message ID 20221111182535.64844-18-alex.bennee@linaro.org
State New
Headers show
Series use MemTxAttrs to avoid current_cpu in hw/ | expand

Commit Message

Alex Bennée Nov. 11, 2022, 6:25 p.m. UTC
On the real HW the IOAPIC is wired directly to the APIC and doesn't
really generate memory accesses on the main bus of the system. To
model this we can use the MTRT_MACHINE requester type and set the id
as a magic number to represent the IOAPIC as the source.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
---
 include/hw/i386/ioapic_internal.h |  2 ++
 hw/intc/ioapic.c                  | 35 ++++++++++++++++++++++++-------
 2 files changed, 30 insertions(+), 7 deletions(-)

Comments

Richard Henderson Nov. 12, 2022, 5:57 a.m. UTC | #1
On 11/12/22 04:25, Alex Bennée wrote:
> On the real HW the IOAPIC is wired directly to the APIC and doesn't
> really generate memory accesses on the main bus of the system. To
> model this we can use the MTRT_MACHINE requester type and set the id
> as a magic number to represent the IOAPIC as the source.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Peter Xu <peterx@redhat.com>
> ---
>   include/hw/i386/ioapic_internal.h |  2 ++
>   hw/intc/ioapic.c                  | 35 ++++++++++++++++++++++++-------
>   2 files changed, 30 insertions(+), 7 deletions(-)
> 
> diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
> index 9880443cc7..a8c7a1418a 100644
> --- a/include/hw/i386/ioapic_internal.h
> +++ b/include/hw/i386/ioapic_internal.h
> @@ -82,6 +82,8 @@
>   
>   #define IOAPIC_VER_ENTRIES_SHIFT        16
>   
> +/* Magic number to identify IOAPIC memory transactions */
> +#define MEMTX_IOAPIC                    0xA71C

Closing in on 1337 5p34k -- sure you didn't want a '4' there to start?  ;-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index 9880443cc7..a8c7a1418a 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -82,6 +82,8 @@ 
 
 #define IOAPIC_VER_ENTRIES_SHIFT        16
 
+/* Magic number to identify IOAPIC memory transactions */
+#define MEMTX_IOAPIC                    0xA71C
 
 #define TYPE_IOAPIC_COMMON "ioapic-common"
 OBJECT_DECLARE_TYPE(IOAPICCommonState, IOAPICCommonClass, IOAPIC_COMMON)
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 264262959d..8a5418002b 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -21,6 +21,7 @@ 
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "qapi/error.h"
 #include "monitor/monitor.h"
 #include "hw/i386/apic.h"
@@ -88,9 +89,33 @@  static void ioapic_entry_parse(uint64_t entry, struct ioapic_entry_info *info)
         (info->delivery_mode << MSI_DATA_DELIVERY_MODE_SHIFT);
 }
 
-static void ioapic_service(IOAPICCommonState *s)
+/*
+ * No matter whether IR is enabled, we translate the IOAPIC message
+ * into a MSI one, and its address space will decide whether we need a
+ * translation.
+ *
+ * As the IOPIC is directly wired to the APIC writes to it are not the
+ * same as writes coming from the main bus of the machine. To model
+ * this we set its source as machine specific with the MEMTX_IOPIC
+ * id.
+ */
+static void send_ioapic_msi(struct ioapic_entry_info info)
 {
     AddressSpace *ioapic_as = X86_MACHINE(qdev_get_machine())->ioapic_as;
+    MemTxAttrs attrs = MEMTXATTRS_MACHINE(MEMTX_IOAPIC);
+    MemTxResult res;
+
+    address_space_stl_le(ioapic_as, info.addr, info.data,
+                                         attrs, &res);
+    if (res != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: couldn't write to %"PRIx32"\n", __func__, info.addr);
+    }
+}
+
+
+static void ioapic_service(IOAPICCommonState *s)
+{
     struct ioapic_entry_info info;
     uint8_t i;
     uint32_t mask;
@@ -130,12 +155,8 @@  static void ioapic_service(IOAPICCommonState *s)
                     continue;
                 }
 #endif
-
-                /* No matter whether IR is enabled, we translate
-                 * the IOAPIC message into a MSI one, and its
-                 * address space will decide whether we need a
-                 * translation. */
-                stl_le_phys(ioapic_as, info.addr, info.data);
+                /* If not handled by KVM we now send it ourselves */
+                send_ioapic_msi(info);
             }
         }
     }