summary refs log tree commit diff stats
path: root/hw/intc/ioapic.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-08-04 10:24:27 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-08-04 10:24:27 +0100
commit09704e6ded83fa0bec14baf32f800f6512156ca0 (patch)
tree72647b9a6c3b35984749926c21a9d2c17e86b3ee /hw/intc/ioapic.c
parent29b2517ac79ecd42c169248668e4007dee90dc5a (diff)
parente911765cbb9e9ddf5d952c88bb52180a62c6cea0 (diff)
downloadfocaccia-qemu-09704e6ded83fa0bec14baf32f800f6512156ca0.tar.gz
focaccia-qemu-09704e6ded83fa0bec14baf32f800f6512156ca0.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* xsetbv fix (x86 targets TCG)
* remove unused functions
* qht segfault and memory leak fixes
* NBD fixes
* Fix for non-power-of-2 discard granularity
* Memory hotplug fixes
* Migration regressions
* IOAPIC fixes and (disabled by default) EOI register support
* Various other small fixes

# gpg: Signature made Wed 03 Aug 2016 18:01:05 BST
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (25 commits)
  util: Fix assertion in iov_copy() upon zero 'bytes' and non-zero 'offset'
  qdev: Fix use after free in qdev_init_nofail error path
  Reorganize help output of '-display' option
  x86: ioapic: add support for explicit EOI
  x86: ioapic: ignore level irq during processing
  apic: fix broken migration for kvm-apic
  fw_cfg: Make base type "fw_cfg" abstract
  block: Cater to iscsi with non-power-of-2 discard
  osdep: Document differences in rounding macros
  nbd: Limit nbdflags to 16 bits
  nbd: Fix bad flag detection on server
  i2c: fix migration regression introduced by broadcast support
  mptsas: really fix migration compatibility
  qdist: return "(empty)" instead of NULL when printing an empty dist
  qdist: use g_renew and g_new instead of g_realloc and g_malloc.
  qdist: fix memory leak during binning
  target-i386: fix typo in xsetbv implementation
  qht: do not segfault when gathering stats from an uninitialized qht
  util: Drop inet_listen()
  util: drop unix_nonblocking_connect()
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc/ioapic.c')
-rw-r--r--hw/intc/ioapic.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 2d3282a864..31791b0986 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -21,6 +21,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "monitor/monitor.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
@@ -117,21 +118,25 @@ static void ioapic_service(IOAPICCommonState *s)
                     s->ioredtbl[i] |= IOAPIC_LVT_REMOTE_IRR;
                 }
 
+                if (coalesce) {
+                    /* We are level triggered interrupts, and the
+                     * guest should be still working on previous one,
+                     * so skip it. */
+                    continue;
+                }
+
 #ifdef CONFIG_KVM
                 if (kvm_irqchip_is_split()) {
                     if (info.trig_mode == IOAPIC_TRIGGER_EDGE) {
                         kvm_set_irq(kvm_state, i, 1);
                         kvm_set_irq(kvm_state, i, 0);
                     } else {
-                        if (!coalesce) {
-                            kvm_set_irq(kvm_state, i, 1);
-                        }
+                        kvm_set_irq(kvm_state, i, 1);
                     }
                     continue;
                 }
-#else
-                (void)coalesce;
 #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
@@ -265,7 +270,7 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
             val = s->id << IOAPIC_ID_SHIFT;
             break;
         case IOAPIC_REG_VER:
-            val = IOAPIC_VERSION |
+            val = s->version |
                 ((IOAPIC_NUM_PINS - 1) << IOAPIC_VER_ENTRIES_SHIFT);
             break;
         default:
@@ -354,6 +359,13 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
             }
         }
         break;
+    case IOAPIC_EOI:
+        /* Explicit EOI is only supported for IOAPIC version 0x20 */
+        if (size != 4 || s->version != 0x20) {
+            break;
+        }
+        ioapic_eoi_broadcast(val);
+        break;
     }
 
     ioapic_update_kvm_routes(s);
@@ -387,6 +399,12 @@ static void ioapic_realize(DeviceState *dev, Error **errp)
 {
     IOAPICCommonState *s = IOAPIC_COMMON(dev);
 
+    if (s->version != 0x11 && s->version != 0x20) {
+        error_report("IOAPIC only supports version 0x11 or 0x20 "
+                     "(default: 0x11).");
+        exit(1);
+    }
+
     memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s,
                           "ioapic", 0x1000);
 
@@ -397,6 +415,11 @@ static void ioapic_realize(DeviceState *dev, Error **errp)
     qemu_add_machine_init_done_notifier(&s->machine_done);
 }
 
+static Property ioapic_properties[] = {
+    DEFINE_PROP_UINT8("version", IOAPICCommonState, version, 0x11),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ioapic_class_init(ObjectClass *klass, void *data)
 {
     IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
@@ -404,6 +427,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
 
     k->realize = ioapic_realize;
     dc->reset = ioapic_reset_common;
+    dc->props = ioapic_properties;
 }
 
 static const TypeInfo ioapic_info = {