aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2023-03-01 15:02:13 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2023-03-01 15:02:13 +0100
commit526947e496e4447d74b8d42415e2847481c5043d (patch)
tree99749e89dea2a252f6a1d721a8d7cf1e3658f405 /hw/intc
parentd31d2404795e254517e513503d14a7991d61dbe6 (diff)
parent79807f3e6bf1186c684312d4e7fb426b2643bade (diff)
downloadqemu-526947e496e4447d74b8d42415e2847481c5043d.zip
qemu-526947e496e4447d74b8d42415e2847481c5043d.tar.gz
qemu-526947e496e4447d74b8d42415e2847481c5043d.tar.bz2
Merge branch 'xenfv-kvm-15' of git://git.infradead.org/users/dwmw2/qemu into HEAD
This adds support for emulating Xen under Linux/KVM, based on kernel patches which have been present since Linux v5.12. As with the kernel support, it's derived from work started by João Martins of Oracle in 2018. This series just adds the basic platform support — CPUID, hypercalls, event channels, a stub of XenStore. A full single-tenant internal implementation of XenStore, and patches to make QEMU's Xen PV drivers work with this Xen emulation, are waiting in the wings to be submitted in a follow-on patch series. As noted in the documentation, it's enabled by setting the xen-version property on the KVM accelerator, e.g.: qemu-system-x86_64 -serial mon:stdio -M q35 -display none -m 1G -smp 2 \ -accel kvm,xen-version=0x4000e,kernel-irqchip=split \ -kernel vmlinuz-6.0.7-301.fc37.x86_64 \ -append "console=ttyS0 root=/dev/sda1" \ -drive file=/var/lib/libvirt/images/fedora28.qcow2,if=none,id=disk \ -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 Even before this was merged, we've already been using it to find and fix bugs in the Linux kernel Xen guest support: https://lore.kernel.org/all/4bffa69a949bfdc92c4a18e5a1c3cbb3b94a0d32.camel@infradead.org/ https://lore.kernel.org/all/871qnunycr.ffs@tglx/ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/apic.c2
-rw-r--r--hw/intc/i8259.c4
-rw-r--r--hw/intc/ioapic.c4
-rw-r--r--hw/intc/ioapic_common.c4
-rw-r--r--hw/intc/ioapic_internal.h118
5 files changed, 125 insertions, 7 deletions
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 2d3e55f..0ff060f 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -20,7 +20,7 @@
#include "qemu/thread.h"
#include "hw/i386/apic_internal.h"
#include "hw/i386/apic.h"
-#include "hw/i386/ioapic.h"
+#include "hw/intc/ioapic.h"
#include "hw/intc/i8259.h"
#include "hw/intc/kvm_irqcount.h"
#include "hw/pci/msi.h"
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index 0261f08..17910f3 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -406,7 +406,7 @@ static void pic_realize(DeviceState *dev, Error **errp)
pc->parent_realize(dev, errp);
}
-qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
+qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq_in)
{
qemu_irq *irq_set;
DeviceState *dev;
@@ -418,7 +418,7 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
isadev = i8259_init_chip(TYPE_I8259, bus, true);
dev = DEVICE(isadev);
- qdev_connect_gpio_out(dev, 0, parent_irq);
+ qdev_connect_gpio_out(dev, 0, parent_irq_in);
for (i = 0 ; i < 8; i++) {
irq_set[i] = qdev_get_gpio_in(dev, i);
}
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 2642629..6364eca 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -24,10 +24,10 @@
#include "qapi/error.h"
#include "monitor/monitor.h"
#include "hw/i386/apic.h"
-#include "hw/i386/ioapic.h"
-#include "hw/i386/ioapic_internal.h"
#include "hw/i386/x86.h"
#include "hw/intc/i8259.h"
+#include "hw/intc/ioapic.h"
+#include "hw/intc/ioapic_internal.h"
#include "hw/pci/msi.h"
#include "hw/qdev-properties.h"
#include "sysemu/kvm.h"
diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
index aa5f760..b05f436 100644
--- a/hw/intc/ioapic_common.c
+++ b/hw/intc/ioapic_common.c
@@ -24,9 +24,9 @@
#include "qemu/module.h"
#include "migration/vmstate.h"
#include "monitor/monitor.h"
-#include "hw/i386/ioapic.h"
-#include "hw/i386/ioapic_internal.h"
#include "hw/intc/intc.h"
+#include "hw/intc/ioapic.h"
+#include "hw/intc/ioapic_internal.h"
#include "hw/sysbus.h"
/* ioapic_no count start from 0 to MAX_IOAPICS,
diff --git a/hw/intc/ioapic_internal.h b/hw/intc/ioapic_internal.h
new file mode 100644
index 0000000..37b8565
--- /dev/null
+++ b/hw/intc/ioapic_internal.h
@@ -0,0 +1,118 @@
+/*
+ * IOAPIC emulation logic - internal interfaces
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ * Copyright (c) 2009 Xiantao Zhang, Intel
+ * Copyright (c) 2011 Jan Kiszka, Siemens AG
+ *
+ * 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/>.
+ */
+
+#ifndef HW_INTC_IOAPIC_INTERNAL_H
+#define HW_INTC_IOAPIC_INTERNAL_H
+
+#include "exec/memory.h"
+#include "hw/intc/ioapic.h"
+#include "hw/sysbus.h"
+#include "qemu/notify.h"
+#include "qom/object.h"
+
+#define MAX_IOAPICS 2
+
+#define IOAPIC_LVT_DEST_SHIFT 56
+#define IOAPIC_LVT_DEST_IDX_SHIFT 48
+#define IOAPIC_LVT_MASKED_SHIFT 16
+#define IOAPIC_LVT_TRIGGER_MODE_SHIFT 15
+#define IOAPIC_LVT_REMOTE_IRR_SHIFT 14
+#define IOAPIC_LVT_POLARITY_SHIFT 13
+#define IOAPIC_LVT_DELIV_STATUS_SHIFT 12
+#define IOAPIC_LVT_DEST_MODE_SHIFT 11
+#define IOAPIC_LVT_DELIV_MODE_SHIFT 8
+
+#define IOAPIC_LVT_MASKED (1 << IOAPIC_LVT_MASKED_SHIFT)
+#define IOAPIC_LVT_TRIGGER_MODE (1 << IOAPIC_LVT_TRIGGER_MODE_SHIFT)
+#define IOAPIC_LVT_REMOTE_IRR (1 << IOAPIC_LVT_REMOTE_IRR_SHIFT)
+#define IOAPIC_LVT_POLARITY (1 << IOAPIC_LVT_POLARITY_SHIFT)
+#define IOAPIC_LVT_DELIV_STATUS (1 << IOAPIC_LVT_DELIV_STATUS_SHIFT)
+#define IOAPIC_LVT_DEST_MODE (1 << IOAPIC_LVT_DEST_MODE_SHIFT)
+#define IOAPIC_LVT_DELIV_MODE (7 << IOAPIC_LVT_DELIV_MODE_SHIFT)
+
+/* Bits that are read-only for IOAPIC entry */
+#define IOAPIC_RO_BITS (IOAPIC_LVT_REMOTE_IRR | \
+ IOAPIC_LVT_DELIV_STATUS)
+#define IOAPIC_RW_BITS (~(uint64_t)IOAPIC_RO_BITS)
+
+#define IOAPIC_TRIGGER_EDGE 0
+#define IOAPIC_TRIGGER_LEVEL 1
+
+/*io{apic,sapic} delivery mode*/
+#define IOAPIC_DM_FIXED 0x0
+#define IOAPIC_DM_LOWEST_PRIORITY 0x1
+#define IOAPIC_DM_PMI 0x2
+#define IOAPIC_DM_NMI 0x4
+#define IOAPIC_DM_INIT 0x5
+#define IOAPIC_DM_SIPI 0x6
+#define IOAPIC_DM_EXTINT 0x7
+#define IOAPIC_DM_MASK 0x7
+
+#define IOAPIC_VECTOR_MASK 0xff
+
+#define IOAPIC_IOREGSEL 0x00
+#define IOAPIC_IOWIN 0x10
+#define IOAPIC_EOI 0x40
+
+#define IOAPIC_REG_ID 0x00
+#define IOAPIC_REG_VER 0x01
+#define IOAPIC_REG_ARB 0x02
+#define IOAPIC_REG_REDTBL_BASE 0x10
+#define IOAPIC_ID 0x00
+
+#define IOAPIC_ID_SHIFT 24
+#define IOAPIC_ID_MASK 0xf
+
+#define IOAPIC_VER_ENTRIES_SHIFT 16
+
+
+#define TYPE_IOAPIC_COMMON "ioapic-common"
+OBJECT_DECLARE_TYPE(IOAPICCommonState, IOAPICCommonClass, IOAPIC_COMMON)
+
+struct IOAPICCommonClass {
+ SysBusDeviceClass parent_class;
+
+ DeviceRealize realize;
+ DeviceUnrealize unrealize;
+ void (*pre_save)(IOAPICCommonState *s);
+ void (*post_load)(IOAPICCommonState *s);
+};
+
+struct IOAPICCommonState {
+ SysBusDevice busdev;
+ MemoryRegion io_memory;
+ uint8_t id;
+ uint8_t ioregsel;
+ uint32_t irr;
+ uint64_t ioredtbl[IOAPIC_NUM_PINS];
+ Notifier machine_done;
+ uint8_t version;
+ uint64_t irq_count[IOAPIC_NUM_PINS];
+ int irq_level[IOAPIC_NUM_PINS];
+ int irq_eoi[IOAPIC_NUM_PINS];
+ QEMUTimer *delayed_ioapic_service_timer;
+};
+
+void ioapic_reset_common(DeviceState *dev);
+
+void ioapic_stat_update_irq(IOAPICCommonState *s, int irq, int level);
+
+#endif /* HW_INTC_IOAPIC_INTERNAL_H */