[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v3 29/35] spapr/xive, xics: use the CPU_INTC handlers
From: |
Cédric Le Goater |
Subject: |
[Qemu-ppc] [PATCH v3 29/35] spapr/xive, xics: use the CPU_INTC handlers to reset KVM |
Date: |
Thu, 19 Apr 2018 14:43:25 +0200 |
The vCPUs are disconnected from the KVM device using a 'disable=1' as
last argument of the KVM_ENABLE_CAP ioctl. This is a bit hacky, we
should probably introduce a KVM_DISABLE_CAP ioctl.
Signed-off-by: Cédric Le Goater <address@hidden>
---
hw/intc/spapr_xive_kvm.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--
hw/intc/xics.c | 4 ++++
hw/intc/xics_kvm.c | 48 ++++++++++++++++++++++++++++++++++++++++--
hw/intc/xive.c | 5 +++++
hw/ppc/spapr_cpu_core.c | 8 +++++++
5 files changed, 116 insertions(+), 4 deletions(-)
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index ec5613fc2804..e3851991653e 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -15,6 +15,7 @@
#include "sysemu/cpus.h"
#include "sysemu/kvm.h"
#include "monitor/monitor.h"
+#include "hw/intc/intc.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_xive.h"
#include "hw/ppc/xive.h"
@@ -47,6 +48,25 @@ static bool xive_nvt_kvm_cpu_is_enabled(CPUState *cs)
return false;
}
+static void xive_nvt_kvm_cpu_disable(CPUState *cs, Error **errp)
+{
+ KVMEnabledCPU *enabled_cpu;
+ unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
+
+ QLIST_FOREACH(enabled_cpu, &kvm_enabled_cpus, node) {
+ if (enabled_cpu->vcpu_id == vcpu_id) {
+ break;
+ }
+ }
+
+ if (enabled_cpu->vcpu_id == vcpu_id) {
+ QLIST_REMOVE(enabled_cpu, node);
+ g_free(enabled_cpu);
+ } else {
+ error_setg(errp, "Can not find enabled CPU%ld", vcpu_id);
+ }
+}
+
static void xive_nvt_kvm_cpu_enable(CPUState *cs)
{
KVMEnabledCPU *enabled_cpu;
@@ -183,8 +203,36 @@ static void xive_nvt_kvm_reset(XiveNVT *nvt)
xive_nvt_kvm_set_state(nvt, 1);
}
-static void xive_nvt_kvm_realize(XiveNVT *nvt, Error **errp)
+static void xive_nvt_kvm_disconnect(CPUIntc *intc, Error **errp)
{
+ XiveNVT *nvt = XIVE_NVT_KVM(intc);
+ CPUState *cs = nvt->cs;
+ unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
+ int ret;
+
+ if (kernel_xive_fd == -1) {
+ return;
+ }
+
+ /* Disable IRQ capability with a 'disable=1' as last argument.
+ *
+ * This is a bit hacky, we should introduce a KVM_DISABLE_CAP
+ * iotcl
+ */
+ ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_IRQ_XIVE, 0, kernel_xive_fd,
+ vcpu_id, 1);
+ if (ret < 0) {
+ error_setg(errp, "Unable to disconnect CPU%ld from KVM XIVE device:
%s",
+ vcpu_id, strerror(errno));
+ return;
+ }
+
+ xive_nvt_kvm_cpu_disable(cs, errp);
+}
+
+static void xive_nvt_kvm_connect(CPUIntc *intc, Error **errp)
+{
+ XiveNVT *nvt = XIVE_NVT_KVM(intc);
CPUState *cs = nvt->cs;
unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
int ret;
@@ -209,14 +257,17 @@ static void xive_nvt_kvm_class_init(ObjectClass *klass,
void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
XiveNVTClass *xnc = XIVE_NVT_CLASS(klass);
+ CPUIntcClass *cic = CPU_INTC_CLASS(klass);
dc->desc = "XIVE KVM Interrupt Presenter";
- xnc->realize = xive_nvt_kvm_realize;
xnc->synchronize_state = xive_nvt_kvm_synchronize_state;
xnc->reset = xive_nvt_kvm_reset;
xnc->pre_save = xive_nvt_kvm_get_state;
xnc->post_load = xive_nvt_kvm_set_state;
+
+ cic->connect = xive_nvt_kvm_connect;
+ cic->disconnect = xive_nvt_kvm_disconnect;
}
static const TypeInfo xive_nvt_kvm_info = {
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index e73e623e3b53..48fed2731fd2 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -381,6 +381,10 @@ static const TypeInfo icp_info = {
.instance_size = sizeof(ICPState),
.class_init = icp_class_init,
.class_size = sizeof(ICPStateClass),
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_CPU_INTC },
+ { }
+ }
};
Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index e727397c4a4d..62ea4ea150f2 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -32,6 +32,7 @@
#include "hw/hw.h"
#include "trace.h"
#include "sysemu/kvm.h"
+#include "hw/intc/intc.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/xics.h"
#include "kvm_ppc.h"
@@ -137,8 +138,48 @@ static void icp_kvm_reset(ICPState *icp)
icp_set_kvm_state(icp, 1);
}
-static void icp_kvm_realize(ICPState *icp, Error **errp)
+static void icp_kvm_disconnect(CPUIntc *intc, Error **errp)
{
+ ICPState *icp = ICP(intc);
+ CPUState *cs = icp->cs;
+ KVMEnabledICP *enabled_icp;
+ unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
+ int ret;
+
+ if (kernel_xics_fd == -1) {
+ return;
+ }
+
+ /* Disable IRQ capability with a 'disable=1' as last argument.
+ *
+ * This is a bit hacky, we should introduce a KVM_DISABLE_CAP
+ * iotcl
+ */
+ ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd,
+ vcpu_id, 1);
+ if (ret < 0) {
+ error_setg(errp, "Unable to disconnect CPU%ld to kernel XICS: %s",
+ vcpu_id, strerror(errno));
+ return;
+ }
+
+ QLIST_FOREACH(enabled_icp, &kvm_enabled_icps, node) {
+ if (enabled_icp->vcpu_id == vcpu_id) {
+ break;
+ }
+ }
+
+ if (enabled_icp->vcpu_id == vcpu_id) {
+ QLIST_REMOVE(enabled_icp, node);
+ g_free(enabled_icp);
+ } else {
+ error_setg(errp, "Can not find enabled CPU%ld", vcpu_id);
+ }
+ }
+
+static void icp_kvm_connect(CPUIntc *intc, Error **errp)
+{
+ ICPState *icp = ICP(intc);
CPUState *cs = icp->cs;
KVMEnabledICP *enabled_icp;
unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
@@ -173,12 +214,15 @@ static void icp_kvm_realize(ICPState *icp, Error **errp)
static void icp_kvm_class_init(ObjectClass *klass, void *data)
{
ICPStateClass *icpc = ICP_CLASS(klass);
+ CPUIntcClass *cic = CPU_INTC_CLASS(klass);
icpc->pre_save = icp_get_kvm_state;
icpc->post_load = icp_set_kvm_state;
- icpc->realize = icp_kvm_realize;
icpc->reset = icp_kvm_reset;
icpc->synchronize_state = icp_synchronize_state;
+
+ cic->connect = icp_kvm_connect;
+ cic->disconnect = icp_kvm_disconnect;
}
static const TypeInfo icp_kvm_info = {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index d96732cfe6be..4a9b09e3d819 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -14,6 +14,7 @@
#include "sysemu/cpus.h"
#include "sysemu/dma.h"
#include "monitor/monitor.h"
+#include "hw/intc/intc.h"
#include "hw/ppc/xics.h" /* for ICP_PROP_CPU */
#include "hw/ppc/xive.h"
#include "hw/ppc/xive_regs.h"
@@ -513,6 +514,10 @@ static const TypeInfo xive_nvt_info = {
.instance_init = xive_nvt_init,
.class_init = xive_nvt_class_init,
.class_size = sizeof(XiveNVTClass),
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_CPU_INTC },
+ { }
+ }
};
/*
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 3df2bda53f50..aa612cb1c9f6 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -16,6 +16,7 @@
#include "sysemu/cpus.h"
#include "sysemu/kvm.h"
#include "target/ppc/kvm_ppc.h"
+#include "hw/intc/intc.h"
#include "hw/ppc/ppc.h"
#include "target/ppc/mmu-hash64.h"
#include "sysemu/numa.h"
@@ -105,6 +106,7 @@ static void spapr_cpu_core_unrealizefn(DeviceState *dev,
Error **errp)
PowerPCCPU *cpu = POWERPC_CPU(cs);
spapr_cpu_destroy(cpu);
+ cpu_intc_disconnect(CPU_INTC(cpu->intc), NULL);
object_unparent(cpu->intc);
cpu_remove_sync(cs);
object_unparent(obj);
@@ -134,6 +136,10 @@ static void spapr_cpu_core_realize_child(Object *child,
goto error;
}
+ cpu_intc_connect(CPU_INTC(cpu->intc), &local_err);
+ if (local_err) {
+ goto error;
+ }
return;
error:
@@ -263,6 +269,7 @@ void spapr_cpu_core_reset_icp(Error **errp)
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
+ cpu_intc_disconnect(CPU_INTC(cpu->intc), errp);
cpu->intc = NULL;
}
}
@@ -298,5 +305,6 @@ void spapr_cpu_core_set_icp(const char *icp_type, Error
**errp)
}
cpu->intc = args.icp;
+ cpu_intc_connect(CPU_INTC(cpu->intc), errp);
}
}
--
2.13.6
- [Qemu-ppc] [PATCH v3 19/35] spapr: toggle the ICP depending on the selected interrupt mode, (continued)
- [Qemu-ppc] [PATCH v3 19/35] spapr: toggle the ICP depending on the selected interrupt mode, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 20/35] spapr: add support to dump XIVE information, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 21/35] spapr: advertise XIVE exploitation mode in CAS, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 22/35] spapr: add classes for the XIVE models, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 23/35] target/ppc/kvm: add Linux KVM definitions for XIVE, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 24/35] spapr/xive: add common realize routine for KVM, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 25/35] spapr/xive: add KVM support, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 26/35] spapr/xive: add a XIVE KVM device to the machine, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 27/35] migration: discard non-migratable RAMBlocks, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 28/35] intc: introduce a CPUIntc interface, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 29/35] spapr/xive, xics: use the CPU_INTC handlers to reset KVM,
Cédric Le Goater <=
- [Qemu-ppc] [PATCH v3 30/35] spapr/xive, xics: reset KVM at machine reset, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 31/35] spapr/xive: raise migration priority of the machine, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 32/35] ppc/pnv: introduce a pnv_icp_create() helper, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 33/35] ppc: externalize ppc_get_vcpu_by_pir(), Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 34/35] ppc/pnv: add XIVE support, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 35/35] ppc/pnv: add a PSI bridge model for POWER9 processor, Cédric Le Goater, 2018/04/19
- Re: [Qemu-ppc] [Qemu-devel] [PATCH v3 00/35] ppc: support for the XIVE interrupt controller (POWER9), no-reply, 2018/04/21