aboutsummaryrefslogtreecommitdiff
path: root/hw/i386/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'hw/i386/kvm')
-rw-r--r--hw/i386/kvm/apic.c13
-rw-r--r--hw/i386/kvm/clock.c16
-rw-r--r--hw/i386/kvm/i8254.c11
-rw-r--r--hw/i386/kvm/i8259.c6
-rw-r--r--hw/i386/kvm/ioapic.c9
-rw-r--r--hw/i386/kvm/xen-stubs.c13
-rw-r--r--hw/i386/kvm/xen_evtchn.c72
-rw-r--r--hw/i386/kvm/xen_evtchn.h2
-rw-r--r--hw/i386/kvm/xen_gnttab.c8
-rw-r--r--hw/i386/kvm/xen_overlay.c10
-rw-r--r--hw/i386/kvm/xen_primary_console.c6
-rw-r--r--hw/i386/kvm/xen_xenstore.c14
12 files changed, 102 insertions, 78 deletions
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index a72c28e..1be9bfe 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -14,9 +14,10 @@
#include "qemu/module.h"
#include "hw/i386/apic_internal.h"
#include "hw/pci/msi.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/kvm.h"
+#include "system/hw_accel.h"
+#include "system/kvm.h"
#include "kvm/kvm_i386.h"
+#include "kvm/tdx.h"
static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic,
int reg_id, uint32_t val)
@@ -141,6 +142,10 @@ static void kvm_apic_put(CPUState *cs, run_on_cpu_data data)
struct kvm_lapic_state kapic;
int ret;
+ if (is_tdx_vm()) {
+ return;
+ }
+
kvm_put_apicbase(s->cpu, s->apicbase);
kvm_put_apic_state(s, &kapic);
@@ -214,7 +219,7 @@ static void kvm_apic_mem_write(void *opaque, hwaddr addr,
static const MemoryRegionOps kvm_apic_io_ops = {
.read = kvm_apic_mem_read,
.write = kvm_apic_mem_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static void kvm_apic_reset(APICCommonState *s)
@@ -240,7 +245,7 @@ static void kvm_apic_unrealize(DeviceState *dev)
{
}
-static void kvm_apic_class_init(ObjectClass *klass, void *data)
+static void kvm_apic_class_init(ObjectClass *klass, const void *data)
{
APICCommonClass *k = APIC_COMMON_CLASS(klass);
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 40aa9a3..f563827 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -16,9 +16,9 @@
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
-#include "sysemu/hw_accel.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
+#include "system/hw_accel.h"
#include "kvm/kvm_i386.h"
#include "migration/vmstate.h"
#include "hw/sysbus.h"
@@ -27,7 +27,6 @@
#include "qapi/error.h"
#include <linux/kvm.h>
-#include "standard-headers/asm-x86/kvm_para.h"
#include "qom/object.h"
#define TYPE_KVM_CLOCK "kvmclock"
@@ -305,13 +304,12 @@ static const VMStateDescription kvmclock_vmsd = {
}
};
-static Property kvmclock_properties[] = {
+static const Property kvmclock_properties[] = {
DEFINE_PROP_BOOL("x-mach-use-reliable-get-clock", KVMClockState,
mach_use_reliable_get_clock, true),
- DEFINE_PROP_END_OF_LIST(),
};
-static void kvmclock_class_init(ObjectClass *klass, void *data)
+static void kvmclock_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -334,8 +332,8 @@ void kvmclock_create(bool create_always)
assert(kvm_enabled());
if (create_always ||
- cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
- (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
+ cpu->env.features[FEAT_KVM] & (CPUID_KVM_CLOCK |
+ CPUID_KVM_CLOCK2)) {
sysbus_create_simple(TYPE_KVM_CLOCK, -1, NULL);
}
}
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index e49b9c4..14b78f3 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -29,11 +29,11 @@
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/timer/i8254.h"
#include "hw/timer/i8254_internal.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "target/i386/kvm/kvm_i386.h"
#include "qom/object.h"
@@ -287,13 +287,12 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
kpc->parent_realize(dev, errp);
}
-static Property kvm_pit_properties[] = {
+static const Property kvm_pit_properties[] = {
DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
lost_tick_policy, LOST_TICK_POLICY_DELAY),
- DEFINE_PROP_END_OF_LIST(),
};
-static void kvm_pit_class_init(ObjectClass *klass, void *data)
+static void kvm_pit_class_init(ObjectClass *klass, const void *data)
{
KVMPITClass *kpc = KVM_PIT_CLASS(klass);
PITCommonClass *k = PIT_COMMON_CLASS(klass);
@@ -303,7 +302,7 @@ static void kvm_pit_class_init(ObjectClass *klass, void *data)
&kpc->parent_realize);
k->set_channel_gate = kvm_pit_set_gate;
k->get_channel_info = kvm_pit_get_channel_info;
- dc->reset = kvm_pit_reset;
+ device_class_set_legacy_reset(dc, kvm_pit_reset);
device_class_set_props(dc, kvm_pit_properties);
}
diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c
index 3ca0e1f..8a72d6e 100644
--- a/hw/i386/kvm/i8259.c
+++ b/hw/i386/kvm/i8259.c
@@ -16,7 +16,7 @@
#include "qemu/module.h"
#include "hw/intc/kvm_irqcount.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qom/object.h"
#define TYPE_KVM_I8259 "kvm-i8259"
@@ -139,13 +139,13 @@ qemu_irq *kvm_i8259_init(ISABus *bus)
return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS);
}
-static void kvm_i8259_class_init(ObjectClass *klass, void *data)
+static void kvm_i8259_class_init(ObjectClass *klass, const void *data)
{
KVMPICClass *kpc = KVM_PIC_CLASS(klass);
PICCommonClass *k = PIC_COMMON_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->reset = kvm_pic_reset;
+ device_class_set_legacy_reset(dc, kvm_pic_reset);
device_class_set_parent_realize(dc, kvm_pic_realize, &kpc->parent_realize);
k->pre_save = kvm_pic_get;
k->post_load = kvm_pic_put;
diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
index b96fe84..693ee97 100644
--- a/hw/i386/kvm/ioapic.c
+++ b/hw/i386/kvm/ioapic.c
@@ -15,7 +15,7 @@
#include "hw/qdev-properties.h"
#include "hw/intc/ioapic_internal.h"
#include "hw/intc/kvm_irqcount.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm/kvm_i386.h"
/* PC Utility function */
@@ -133,12 +133,11 @@ static void kvm_ioapic_realize(DeviceState *dev, Error **errp)
qdev_init_gpio_in(dev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
}
-static Property kvm_ioapic_properties[] = {
+static const Property kvm_ioapic_properties[] = {
DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
- DEFINE_PROP_END_OF_LIST()
};
-static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
+static void kvm_ioapic_class_init(ObjectClass *klass, const void *data)
{
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -146,7 +145,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
k->realize = kvm_ioapic_realize;
k->pre_save = kvm_ioapic_get;
k->post_load = kvm_ioapic_put;
- dc->reset = kvm_ioapic_reset;
+ device_class_set_legacy_reset(dc, kvm_ioapic_reset);
device_class_set_props(dc, kvm_ioapic_properties);
}
diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c
index d03131e..ce73119 100644
--- a/hw/i386/kvm/xen-stubs.c
+++ b/hw/i386/kvm/xen-stubs.c
@@ -12,7 +12,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc-target.h"
#include "xen_evtchn.h"
#include "xen_primary_console.h"
@@ -38,15 +37,3 @@ void xen_primary_console_create(void)
void xen_primary_console_set_be_port(uint16_t port)
{
}
-#ifdef TARGET_I386
-EvtchnInfoList *qmp_xen_event_list(Error **errp)
-{
- error_setg(errp, "Xen event channel emulation not enabled");
- return NULL;
-}
-
-void qmp_xen_event_inject(uint32_t port, Error **errp)
-{
- error_setg(errp, "Xen event channel emulation not enabled");
-}
-#endif
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 07bd0c9..dd566c4 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -19,11 +19,11 @@
#include "monitor/monitor.h"
#include "monitor/hmp.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc-target.h"
-#include "qapi/qmp/qdict.h"
+#include "qapi/qapi-commands-misc-i386.h"
+#include "qobject/qdict.h"
#include "qom/object.h"
#include "exec/target_page.h"
-#include "exec/address-spaces.h"
+#include "system/address-spaces.h"
#include "migration/vmstate.h"
#include "trace.h"
@@ -41,8 +41,8 @@
#include "xen_overlay.h"
#include "xen_xenstore.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include <linux/kvm.h>
#include <sys/eventfd.h>
@@ -140,6 +140,8 @@ struct XenEvtchnState {
uint64_t callback_param;
bool evtchn_in_kernel;
+ bool setting_callback_gsi;
+ int extern_gsi_level;
uint32_t callback_gsi;
QEMUBH *gsi_bh;
@@ -269,7 +271,7 @@ static const VMStateDescription xen_evtchn_vmstate = {
}
};
-static void xen_evtchn_class_init(ObjectClass *klass, void *data)
+static void xen_evtchn_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -431,9 +433,22 @@ void xen_evtchn_set_callback_level(int level)
}
if (s->callback_gsi && s->callback_gsi < s->nr_callback_gsis) {
- qemu_set_irq(s->callback_gsis[s->callback_gsi], level);
- if (level) {
- /* Ensure the vCPU polls for deassertion */
+ /*
+ * Ugly, but since we hold the BQL we can set this flag so that
+ * xen_evtchn_set_gsi() can tell the difference between this code
+ * setting the GSI, and an external device (PCI INTx) doing so.
+ */
+ s->setting_callback_gsi = true;
+ /* Do not deassert the line if an external device is asserting it. */
+ qemu_set_irq(s->callback_gsis[s->callback_gsi],
+ level || s->extern_gsi_level);
+ s->setting_callback_gsi = false;
+
+ /*
+ * If the callback GSI is the only one asserted, ensure the status
+ * is polled for deassertion in kvm_arch_post_run().
+ */
+ if (level && !s->extern_gsi_level) {
kvm_xen_set_callback_asserted();
}
}
@@ -1596,7 +1611,7 @@ static int allocate_pirq(XenEvtchnState *s, int type, int gsi)
return pirq;
}
-bool xen_evtchn_set_gsi(int gsi, int level)
+bool xen_evtchn_set_gsi(int gsi, int *level)
{
XenEvtchnState *s = xen_evtchn_singleton;
int pirq;
@@ -1608,16 +1623,35 @@ bool xen_evtchn_set_gsi(int gsi, int level)
}
/*
- * Check that that it *isn't* the event channel GSI, and thus
- * that we are not recursing and it's safe to take s->port_lock.
- *
- * Locking aside, it's perfectly sane to bail out early for that
- * special case, as it would make no sense for the event channel
- * GSI to be routed back to event channels, when the delivery
- * method is to raise the GSI... that recursion wouldn't *just*
- * be a locking issue.
+ * For the callback_gsi we need to implement a logical OR of the event
+ * channel GSI and the external input (e.g. from PCI INTx), because
+ * QEMU itself doesn't support shared level interrupts via demux or
+ * resamplers.
*/
if (gsi && gsi == s->callback_gsi) {
+ /* Remember the external state of the GSI pin (e.g. from PCI INTx) */
+ if (!s->setting_callback_gsi) {
+ s->extern_gsi_level = *level;
+
+ /*
+ * Don't allow the external device to deassert the line if the
+ * eveht channel GSI should still be asserted.
+ */
+ if (!s->extern_gsi_level) {
+ struct vcpu_info *vi = kvm_xen_get_vcpu_info_hva(0);
+ if (vi && vi->evtchn_upcall_pending) {
+ /* Need to poll for deassertion */
+ kvm_xen_set_callback_asserted();
+ *level = 1;
+ }
+ }
+ }
+
+ /*
+ * The event channel GSI cannot be routed to PIRQ, as that would make
+ * no sense. It could also deadlock on s->port_lock, if we proceed.
+ * So bail out now.
+ */
return false;
}
@@ -1628,7 +1662,7 @@ bool xen_evtchn_set_gsi(int gsi, int level)
return false;
}
- if (level) {
+ if (*level) {
int port = s->pirq[pirq].port;
s->pirq_gsi_set |= (1U << gsi);
diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h
index b740acf..0521ebc 100644
--- a/hw/i386/kvm/xen_evtchn.h
+++ b/hw/i386/kvm/xen_evtchn.h
@@ -23,7 +23,7 @@ void xen_evtchn_set_callback_level(int level);
int xen_evtchn_set_port(uint16_t port);
-bool xen_evtchn_set_gsi(int gsi, int level);
+bool xen_evtchn_set_gsi(int gsi, int *level);
void xen_evtchn_snoop_msi(PCIDevice *dev, bool is_msix, unsigned int vector,
uint64_t addr, uint32_t data, bool is_masked);
void xen_evtchn_remove_pci_device(PCIDevice *dev);
diff --git a/hw/i386/kvm/xen_gnttab.c b/hw/i386/kvm/xen_gnttab.c
index 245e4b1..4b9e272 100644
--- a/hw/i386/kvm/xen_gnttab.c
+++ b/hw/i386/kvm/xen_gnttab.c
@@ -17,7 +17,7 @@
#include "qapi/error.h"
#include "qom/object.h"
#include "exec/target_page.h"
-#include "exec/address-spaces.h"
+#include "system/address-spaces.h"
#include "migration/vmstate.h"
#include "hw/sysbus.h"
@@ -27,8 +27,8 @@
#include "xen_gnttab.h"
#include "xen_primary_console.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include "hw/xen/interface/memory.h"
#include "hw/xen/interface/grant_table.h"
@@ -135,7 +135,7 @@ static const VMStateDescription xen_gnttab_vmstate = {
}
};
-static void xen_gnttab_class_init(ObjectClass *klass, void *data)
+static void xen_gnttab_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/i386/kvm/xen_overlay.c b/hw/i386/kvm/xen_overlay.c
index c68e78a..3cb7361 100644
--- a/hw/i386/kvm/xen_overlay.c
+++ b/hw/i386/kvm/xen_overlay.c
@@ -16,15 +16,15 @@
#include "qapi/error.h"
#include "qom/object.h"
#include "exec/target_page.h"
-#include "exec/address-spaces.h"
+#include "system/address-spaces.h"
#include "migration/vmstate.h"
#include "hw/sysbus.h"
#include "hw/xen/xen.h"
#include "xen_overlay.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include <linux/kvm.h>
#include "hw/xen/interface/memory.h"
@@ -151,11 +151,11 @@ static void xen_overlay_reset(DeviceState *dev)
kvm_xen_soft_reset();
}
-static void xen_overlay_class_init(ObjectClass *klass, void *data)
+static void xen_overlay_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->reset = xen_overlay_reset;
+ device_class_set_legacy_reset(dc, xen_overlay_reset);
dc->realize = xen_overlay_realize;
dc->vmsd = &xen_overlay_vmstate;
}
diff --git a/hw/i386/kvm/xen_primary_console.c b/hw/i386/kvm/xen_primary_console.c
index abe79f5..6e9d641 100644
--- a/hw/i386/kvm/xen_primary_console.c
+++ b/hw/i386/kvm/xen_primary_console.c
@@ -20,8 +20,8 @@
#include "xen_overlay.h"
#include "xen_primary_console.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include "trace.h"
@@ -67,7 +67,7 @@ static void xen_primary_console_realize(DeviceState *dev, Error **errp)
xen_primary_console_singleton = s;
}
-static void xen_primary_console_class_init(ObjectClass *klass, void *data)
+static void xen_primary_console_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/i386/kvm/xen_xenstore.c b/hw/i386/kvm/xen_xenstore.c
index 1a9bc34..42955cc 100644
--- a/hw/i386/kvm/xen_xenstore.c
+++ b/hw/i386/kvm/xen_xenstore.c
@@ -28,8 +28,8 @@
#include "xen_primary_console.h"
#include "xen_xenstore.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include "trace.h"
@@ -209,7 +209,6 @@ static int xen_xenstore_post_load(void *opaque, int ver)
{
XenXenstoreState *s = opaque;
GByteArray *save;
- int ret;
/*
* As qemu/dom0, rebind to the guest's port. The Windows drivers may
@@ -231,8 +230,7 @@ static int xen_xenstore_post_load(void *opaque, int ver)
s->impl_state = NULL;
s->impl_state_size = 0;
- ret = xs_impl_deserialize(s->impl, save, xen_domid, fire_watch_cb, s);
- return ret;
+ return xs_impl_deserialize(s->impl, save, xen_domid, fire_watch_cb, s);
}
static const VMStateDescription xen_xenstore_vmstate = {
@@ -261,7 +259,7 @@ static const VMStateDescription xen_xenstore_vmstate = {
}
};
-static void xen_xenstore_class_init(ObjectClass *klass, void *data)
+static void xen_xenstore_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -532,6 +530,10 @@ static void xs_read(XenXenstoreState *s, unsigned int req_id,
return;
}
+ if (!len) {
+ return;
+ }
+
memcpy(&rsp_data[rsp->len], data->data, len);
rsp->len += len;
}