From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553179951497915.2955706442224; Thu, 21 Mar 2019 07:52:31 -0700 (PDT) Received: from localhost ([127.0.0.1]:38840 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z3T-0004y4-AC for importer@patchew.org; Thu, 21 Mar 2019 10:52:27 -0400 Received: from eggs.gnu.org ([209.51.188.92]:43866) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z17-0003S6-3L for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z13-0000LM-TA for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:00 -0400 Received: from 19.mo4.mail-out.ovh.net ([87.98.179.66]:40002) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z0u-0008HQ-RD for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:49:50 -0400 Received: from player788.ha.ovh.net (unknown [10.109.143.183]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id 5F79B1DFC70 for ; Thu, 21 Mar 2019 15:49:33 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 617353E6B2AA; Thu, 21 Mar 2019 14:49:27 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:00 +0100 Message-Id: <20190321144914.19934-2-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11852629796677061606 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 87.98.179.66 Subject: [Qemu-devel] [PATCH v3 01/15] linux-headers: update to 5.1-rc1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" These changes provide the interface with the KVM device implementing the XIVE native exploitation interrupt mode. Also used to retrieve the state of the KVM device for the monitor usage and for migration. Available from : https://github.com/legoater/linux/commits/xive-5.1 Signed-off-by: C=C3=A9dric Le Goater --- linux-headers/asm-powerpc/kvm.h | 46 +++++++++++++++++++++++++++++++++ linux-headers/linux/kvm.h | 11 ++++++++ 2 files changed, 57 insertions(+) diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kv= m.h index 8c876c166ef2..07daf7bf6fe4 100644 --- a/linux-headers/asm-powerpc/kvm.h +++ b/linux-headers/asm-powerpc/kvm.h @@ -480,6 +480,8 @@ struct kvm_ppc_cpu_char { #define KVM_REG_PPC_ICP_PPRI_SHIFT 16 /* pending irq priority */ #define KVM_REG_PPC_ICP_PPRI_MASK 0xff =20 +#define KVM_REG_PPC_VP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x8d) + /* Device control API: PPC-specific devices */ #define KVM_DEV_MPIC_GRP_MISC 1 #define KVM_DEV_MPIC_BASE_ADDR 0 /* 64-bit */ @@ -675,4 +677,48 @@ struct kvm_ppc_cpu_char { #define KVM_XICS_PRESENTED (1ULL << 43) #define KVM_XICS_QUEUED (1ULL << 44) =20 +/* POWER9 XIVE Native Interrupt Controller */ +#define KVM_DEV_XIVE_GRP_CTRL 1 +#define KVM_DEV_XIVE_RESET 1 +#define KVM_DEV_XIVE_EQ_SYNC 2 +#define KVM_DEV_XIVE_GRP_SOURCE 2 /* 64-bit source identifier */ +#define KVM_DEV_XIVE_GRP_SOURCE_CONFIG 3 /* 64-bit source identifier */ +#define KVM_DEV_XIVE_GRP_EQ_CONFIG 4 /* 64-bit EQ identifier */ +#define KVM_DEV_XIVE_GRP_SOURCE_SYNC 5 /* 64-bit source identifier */ + +/* Layout of 64-bit XIVE source attribute values */ +#define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0) +#define KVM_XIVE_LEVEL_ASSERTED (1ULL << 1) + +/* Layout of 64-bit XIVE source configuration attribute values */ +#define KVM_XIVE_SOURCE_PRIORITY_SHIFT 0 +#define KVM_XIVE_SOURCE_PRIORITY_MASK 0x7 +#define KVM_XIVE_SOURCE_SERVER_SHIFT 3 +#define KVM_XIVE_SOURCE_SERVER_MASK 0xfffffff8ULL +#define KVM_XIVE_SOURCE_MASKED_SHIFT 32 +#define KVM_XIVE_SOURCE_MASKED_MASK 0x100000000ULL +#define KVM_XIVE_SOURCE_EISN_SHIFT 33 +#define KVM_XIVE_SOURCE_EISN_MASK 0xfffffffe00000000ULL + +/* Layout of 64-bit EQ identifier */ +#define KVM_XIVE_EQ_PRIORITY_SHIFT 0 +#define KVM_XIVE_EQ_PRIORITY_MASK 0x7 +#define KVM_XIVE_EQ_SERVER_SHIFT 3 +#define KVM_XIVE_EQ_SERVER_MASK 0xfffffff8ULL + +/* Layout of EQ configuration values (64 bytes) */ +struct kvm_ppc_xive_eq { + __u32 flags; + __u32 qshift; + __u64 qaddr; + __u32 qtoggle; + __u32 qindex; + __u8 pad[40]; +}; + +#define KVM_XIVE_EQ_ALWAYS_NOTIFY 0x00000001 + +#define KVM_XIVE_TIMA_PAGE_OFFSET 0 +#define KVM_XIVE_ESB_PAGE_OFFSET 4 + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index b53ee5974802..49ff307fa094 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1,3 +1,4 @@ + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __LINUX_KVM_H #define __LINUX_KVM_H @@ -988,6 +989,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_VM_IPA_SIZE 165 #define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166 #define KVM_CAP_HYPERV_CPUID 167 +#define KVM_CAP_PPC_IRQ_XIVE 168 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 @@ -1182,6 +1184,11 @@ struct kvm_create_device { __u32 flags; /* in: KVM_CREATE_DEVICE_xxx */ }; =20 +struct kvm_destroy_device { + __u32 fd; /* in: device handle */ + __u32 flags; /* in: unused */ +}; + struct kvm_device_attr { __u32 flags; /* no flags currently defined */ __u32 group; /* device-defined */ @@ -1211,6 +1218,8 @@ enum kvm_device_type { #define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_ITS, #define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS + KVM_DEV_TYPE_XIVE, +#define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_MAX, }; =20 @@ -1328,6 +1337,8 @@ struct kvm_s390_ucas_mapping { #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) =20 +#define KVM_DESTROY_DEVICE _IOWR(KVMIO, 0xf0, struct kvm_destroy_device) + /* * ioctls for vcpu fds */ --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180150805976.888348155213; Thu, 21 Mar 2019 07:55:50 -0700 (PDT) Received: from localhost ([127.0.0.1]:38906 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z6h-0008OX-HY for importer@patchew.org; Thu, 21 Mar 2019 10:55:47 -0400 Received: from eggs.gnu.org ([209.51.188.92]:43865) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z17-0003S5-3N for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z12-0000K7-OB for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:00 -0400 Received: from 16.mo1.mail-out.ovh.net ([178.33.104.224]:44906) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z0p-0008P2-Jv for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:49:46 -0400 Received: from player788.ha.ovh.net (unknown [10.109.160.40]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id 2B7F9165C8C for ; Thu, 21 Mar 2019 15:49:39 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 5A0183E6B36A; Thu, 21 Mar 2019 14:49:33 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:01 +0100 Message-Id: <20190321144914.19934-3-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11854037170440473574 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 178.33.104.224 Subject: [Qemu-devel] [PATCH v3 02/15] spapr/xive: add KVM support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This introduces a set of helpers when KVM is in use, which create the KVM XIVE device, initialize the interrupt sources at a KVM level and connect the interrupt presenters to the vCPU. They also handle the initialization of the TIMA and the source ESB memory regions of the controller. These have a different type under KVM. They are 'ram device' memory mappings, similarly to VFIO, exposed to the guest and the associated VMAs on the host are populated dynamically with the appropriate pages using a fault handler. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- Changes since v2: - rebased on new naming scheme - rebased on new configuration system - replaced error_report_err() by warn_report_err() =20 include/hw/ppc/spapr_xive.h | 10 ++ include/hw/ppc/xive.h | 13 ++ target/ppc/kvm_ppc.h | 6 + hw/intc/spapr_xive.c | 48 +++++++- hw/intc/spapr_xive_kvm.c | 237 ++++++++++++++++++++++++++++++++++++ hw/intc/xive.c | 21 +++- hw/ppc/spapr_irq.c | 6 +- target/ppc/kvm.c | 7 ++ hw/intc/Makefile.objs | 1 + hw/ppc/Kconfig | 5 + 10 files changed, 344 insertions(+), 10 deletions(-) create mode 100644 hw/intc/spapr_xive_kvm.c diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index fc3e9652f99a..0edcc762dedd 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -38,6 +38,10 @@ typedef struct SpaprXive { /* TIMA mapping address */ hwaddr tm_base; MemoryRegion tm_mmio; + + /* KVM support */ + int fd; + void *tm_mmap; } SpaprXive; =20 bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi); @@ -49,5 +53,11 @@ void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr= _servers, void *fdt, uint32_t phandle); void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx); void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable); +void spapr_xive_map_mmio(SpaprXive *xive); + +/* + * KVM XIVE device helpers + */ +void kvmppc_xive_connect(SpaprXive *xive, Error **errp); =20 #endif /* PPC_SPAPR_XIVE_H */ diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index c4f27742ca09..dd115da30ebc 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -140,6 +140,7 @@ #ifndef PPC_XIVE_H #define PPC_XIVE_H =20 +#include "sysemu/kvm.h" #include "hw/qdev-core.h" #include "hw/sysbus.h" #include "hw/ppc/xive_regs.h" @@ -194,6 +195,9 @@ typedef struct XiveSource { uint32_t esb_shift; MemoryRegion esb_mmio; =20 + /* KVM support */ + void *esb_mmap; + XiveNotifier *xive; } XiveSource; =20 @@ -423,4 +427,13 @@ static inline uint32_t xive_nvt_cam_line(uint8_t nvt_b= lk, uint32_t nvt_idx) return (nvt_blk << 19) | nvt_idx; } =20 +/* + * KVM XIVE device helpers + */ + +void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **err= p); +void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp); +void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val); +void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp); + #endif /* PPC_XIVE_H */ diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 2c2ea30e87f3..7d2b8becd2b9 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -60,6 +60,7 @@ bool kvmppc_has_cap_fixup_hcalls(void); bool kvmppc_has_cap_htm(void); bool kvmppc_has_cap_mmu_radix(void); bool kvmppc_has_cap_mmu_hash_v3(void); +bool kvmppc_has_cap_xive(void); int kvmppc_get_cap_safe_cache(void); int kvmppc_get_cap_safe_bounds_check(void); int kvmppc_get_cap_safe_indirect_branch(void); @@ -315,6 +316,11 @@ static inline bool kvmppc_has_cap_mmu_hash_v3(void) return false; } =20 +static inline bool kvmppc_has_cap_xive(void) +{ + return false; +} + static inline int kvmppc_get_cap_safe_cache(void) { return 0; diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 097f88d4608d..84ecbf3adf24 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -173,7 +173,7 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor= *mon) } } =20 -static void spapr_xive_map_mmio(SpaprXive *xive) +void spapr_xive_map_mmio(SpaprXive *xive) { sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base); sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base); @@ -250,6 +250,9 @@ static void spapr_xive_instance_init(Object *obj) object_initialize_child(obj, "end_source", &xive->end_source, sizeof(xive->end_source), TYPE_XIVE_END_SOURCE, &error_abort, NULL); + + /* Not connected to the KVM XIVE device */ + xive->fd =3D -1; } =20 static void spapr_xive_realize(DeviceState *dev, Error **errp) @@ -258,6 +261,7 @@ static void spapr_xive_realize(DeviceState *dev, Error = **errp) XiveSource *xsrc =3D &xive->source; XiveENDSource *end_xsrc =3D &xive->end_source; Error *local_err =3D NULL; + MachineState *machine =3D MACHINE(qdev_get_machine()); =20 if (!xive->nr_irqs) { error_setg(errp, "Number of interrupt needs to be greater 0"); @@ -304,6 +308,32 @@ static void spapr_xive_realize(DeviceState *dev, Error= **errp) xive->eat =3D g_new0(XiveEAS, xive->nr_irqs); xive->endt =3D g_new0(XiveEND, xive->nr_ends); =20 + xive->nodename =3D g_strdup_printf("interrupt-controller@%" PRIx64, + xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SH= IFT)); + + qemu_register_reset(spapr_xive_reset, dev); + + if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) { + kvmppc_xive_connect(xive, &local_err); + if (local_err && machine_kernel_irqchip_required(machine)) { + error_prepend(&local_err, + "kernel_irqchip requested but unavailable: "); + error_propagate(errp, local_err); + return; + } + + if (!local_err) { + return; + } + + /* + * We failed to initialize the XIVE KVM device, fallback to + * emulated mode + */ + error_prepend(&local_err, "kernel_irqchip allowed but unavailable:= "); + warn_report_err(local_err); + } + /* TIMA initialization */ memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive, "xive.tima", 4ull << TM_SHIFT); @@ -315,11 +345,6 @@ static void spapr_xive_realize(DeviceState *dev, Error= **errp) =20 /* Map all regions */ spapr_xive_map_mmio(xive); - - xive->nodename =3D g_strdup_printf("interrupt-controller@%" PRIx64, - xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SH= IFT)); - - qemu_register_reset(spapr_xive_reset, dev); } =20 static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk, @@ -494,6 +519,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t li= sn, bool lsi) if (lsi) { xive_source_irq_set_lsi(xsrc, lisn); } + + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_source_reset_one(xsrc, lisn, &local_err); + if (local_err) { + error_report_err(local_err); + return false; + } + } + return true; } =20 diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c new file mode 100644 index 000000000000..7d9e771e8a91 --- /dev/null +++ b/hw/intc/spapr_xive_kvm.c @@ -0,0 +1,237 @@ +/* + * QEMU PowerPC sPAPR XIVE interrupt controller model + * + * Copyright (c) 2017-2019, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "target/ppc/cpu.h" +#include "sysemu/cpus.h" +#include "sysemu/kvm.h" +#include "hw/ppc/spapr.h" +#include "hw/ppc/spapr_xive.h" +#include "hw/ppc/xive.h" +#include "kvm_ppc.h" + +#include + +/* + * Helpers for CPU hotplug + * + * TODO: make a common KVMEnabledCPU layer for XICS and XIVE + */ +typedef struct KVMEnabledCPU { + unsigned long vcpu_id; + QLIST_ENTRY(KVMEnabledCPU) node; +} KVMEnabledCPU; + +static QLIST_HEAD(, KVMEnabledCPU) + kvm_enabled_cpus =3D QLIST_HEAD_INITIALIZER(&kvm_enabled_cpus); + +static bool kvm_cpu_is_enabled(CPUState *cs) +{ + KVMEnabledCPU *enabled_cpu; + unsigned long vcpu_id =3D kvm_arch_vcpu_id(cs); + + QLIST_FOREACH(enabled_cpu, &kvm_enabled_cpus, node) { + if (enabled_cpu->vcpu_id =3D=3D vcpu_id) { + return true; + } + } + return false; +} + +static void kvm_cpu_enable(CPUState *cs) +{ + KVMEnabledCPU *enabled_cpu; + unsigned long vcpu_id =3D kvm_arch_vcpu_id(cs); + + enabled_cpu =3D g_malloc(sizeof(*enabled_cpu)); + enabled_cpu->vcpu_id =3D vcpu_id; + QLIST_INSERT_HEAD(&kvm_enabled_cpus, enabled_cpu, node); +} + +/* + * XIVE Thread Interrupt Management context (KVM) + */ + +void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp) +{ + SpaprXive *xive =3D SPAPR_MACHINE(qdev_get_machine())->xive; + unsigned long vcpu_id; + int ret; + + /* Check if CPU was hot unplugged and replugged. */ + if (kvm_cpu_is_enabled(tctx->cs)) { + return; + } + + vcpu_id =3D kvm_arch_vcpu_id(tctx->cs); + + ret =3D kvm_vcpu_enable_cap(tctx->cs, KVM_CAP_PPC_IRQ_XIVE, 0, xive->f= d, + vcpu_id, 0); + if (ret < 0) { + error_setg(errp, "XIVE: unable to connect CPU%ld to KVM device: %s= ", + vcpu_id, strerror(errno)); + return; + } + + kvm_cpu_enable(tctx->cs); +} + +/* + * XIVE Interrupt Source (KVM) + */ + +/* + * At reset, the interrupt sources are simply created and MASKED. We + * only need to inform the KVM XIVE device about their type: LSI or + * MSI. + */ +void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **err= p) +{ + SpaprXive *xive =3D SPAPR_XIVE(xsrc->xive); + uint64_t state =3D 0; + + if (xive_source_irq_is_lsi(xsrc, srcno)) { + state |=3D KVM_XIVE_LEVEL_SENSITIVE; + if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) { + state |=3D KVM_XIVE_LEVEL_ASSERTED; + } + } + + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state, + true, errp); +} + +void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp) +{ + int i; + + for (i =3D 0; i < xsrc->nr_irqs; i++) { + Error *local_err =3D NULL; + + kvmppc_xive_source_reset_one(xsrc, i, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } +} + +void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val) +{ + XiveSource *xsrc =3D opaque; + struct kvm_irq_level args; + int rc; + + args.irq =3D srcno; + if (!xive_source_irq_is_lsi(xsrc, srcno)) { + if (!val) { + return; + } + args.level =3D KVM_INTERRUPT_SET; + } else { + if (val) { + xsrc->status[srcno] |=3D XIVE_STATUS_ASSERTED; + args.level =3D KVM_INTERRUPT_SET_LEVEL; + } else { + xsrc->status[srcno] &=3D ~XIVE_STATUS_ASSERTED; + args.level =3D KVM_INTERRUPT_UNSET; + } + } + rc =3D kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args); + if (rc < 0) { + error_report("XIVE: kvm_irq_line() failed : %s", strerror(errno)); + } +} + +/* + * sPAPR XIVE interrupt controller (KVM) + */ + +static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len, + Error **errp) +{ + void *addr; + uint32_t page_shift =3D 16; /* TODO: fix page_shift */ + + addr =3D mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, xive->fd, + pgoff << page_shift); + if (addr =3D=3D MAP_FAILED) { + error_setg_errno(errp, errno, "XIVE: unable to set memory mapping"= ); + return NULL; + } + + return addr; +} + +/* + * All the XIVE memory regions are now backed by mappings from the KVM + * XIVE device. + */ +void kvmppc_xive_connect(SpaprXive *xive, Error **errp) +{ + XiveSource *xsrc =3D &xive->source; + XiveENDSource *end_xsrc =3D &xive->end_source; + Error *local_err =3D NULL; + size_t esb_len =3D (1ull << xsrc->esb_shift) * xsrc->nr_irqs; + size_t tima_len =3D 4ull << TM_SHIFT; + + if (!kvmppc_has_cap_xive()) { + error_setg(errp, "IRQ_XIVE capability must be present for KVM"); + return; + } + + /* First, create the KVM XIVE device */ + xive->fd =3D kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false); + if (xive->fd < 0) { + error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device= "); + return; + } + + /* + * 1. Source ESB pages - KVM mapping + */ + xsrc->esb_mmap =3D kvmppc_xive_mmap(xive, KVM_XIVE_ESB_PAGE_OFFSET, es= b_len, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + memory_region_init_ram_device_ptr(&xsrc->esb_mmio, OBJECT(xsrc), + "xive.esb", esb_len, xsrc->esb_mmap); + sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio); + + /* + * 2. END ESB pages (No KVM support yet) + */ + sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio); + + /* + * 3. TIMA pages - KVM mapping + */ + xive->tm_mmap =3D kvmppc_xive_mmap(xive, KVM_XIVE_TIMA_PAGE_OFFSET, ti= ma_len, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + memory_region_init_ram_device_ptr(&xive->tm_mmio, OBJECT(xive), + "xive.tima", tima_len, xive->tm_mmap= ); + sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio); + + kvm_kernel_irqchip =3D true; + kvm_msi_via_irqfd_allowed =3D true; + kvm_gsi_direct_mapping =3D true; + + /* Map all regions */ + spapr_xive_map_mmio(xive); +} diff --git a/hw/intc/xive.c b/hw/intc/xive.c index a0b87001da25..a0662fd33174 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -555,6 +555,15 @@ static void xive_tctx_realize(DeviceState *dev, Error = **errp) return; } =20 + /* Connect the presenter to the VCPU (required for CPU hotplug) */ + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_cpu_connect(tctx, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } + qemu_register_reset(xive_tctx_reset, dev); } =20 @@ -957,6 +966,10 @@ static void xive_source_reset(void *dev) =20 /* PQs are initialized to 0b01 (Q=3D1) which corresponds to "ints off"= */ memset(xsrc->status, XIVE_ESB_OFF, xsrc->nr_irqs); + + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_source_reset(xsrc, &error_fatal); + } } =20 static void xive_source_realize(DeviceState *dev, Error **errp) @@ -990,9 +1003,11 @@ static void xive_source_realize(DeviceState *dev, Err= or **errp) xsrc->status =3D g_malloc0(xsrc->nr_irqs); xsrc->lsi_map =3D bitmap_new(xsrc->nr_irqs); =20 - memory_region_init_io(&xsrc->esb_mmio, OBJECT(xsrc), - &xive_source_esb_ops, xsrc, "xive.esb", - (1ull << xsrc->esb_shift) * xsrc->nr_irqs); + if (!kvm_irqchip_in_kernel()) { + memory_region_init_io(&xsrc->esb_mmio, OBJECT(xsrc), + &xive_source_esb_ops, xsrc, "xive.esb", + (1ull << xsrc->esb_shift) * xsrc->nr_irqs); + } =20 qemu_register_reset(xive_source_reset, dev); } diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 253e4de7fd7d..ec60d0a5ef74 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -387,7 +387,11 @@ static void spapr_irq_set_irq_xive(void *opaque, int s= rcno, int val) { SpaprMachineState *spapr =3D opaque; =20 - xive_source_set_irq(&spapr->xive->source, srcno, val); + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_source_set_irq(&spapr->xive->source, srcno, val); + } else { + xive_source_set_irq(&spapr->xive->source, srcno, val); + } } =20 static const char *spapr_irq_get_nodename_xive(SpaprMachineState *spapr) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 2427c8ee13ae..820ac24f6a66 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -85,6 +85,7 @@ static int cap_fixup_hcalls; static int cap_htm; /* Hardware transactional memory support */ static int cap_mmu_radix; static int cap_mmu_hash_v3; +static int cap_xive; static int cap_resize_hpt; static int cap_ppc_pvr_compat; static int cap_ppc_safe_cache; @@ -151,6 +152,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_htm =3D kvm_vm_check_extension(s, KVM_CAP_PPC_HTM); cap_mmu_radix =3D kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX); cap_mmu_hash_v3 =3D kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3); + cap_xive =3D kvm_vm_check_extension(s, KVM_CAP_PPC_IRQ_XIVE); cap_resize_hpt =3D kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT); kvmppc_get_cpu_characteristics(s); cap_ppc_nested_kvm_hv =3D kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED= _HV); @@ -2444,6 +2446,11 @@ static int parse_cap_ppc_count_cache_flush_assist(st= ruct kvm_ppc_cpu_char c) return 0; } =20 +bool kvmppc_has_cap_xive(void) +{ + return cap_xive; +} + static void kvmppc_get_cpu_characteristics(KVMState *s) { struct kvm_ppc_cpu_char c; diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index df712c3e6c93..03019b9a0343 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -39,6 +39,7 @@ obj-$(CONFIG_XICS_SPAPR) +=3D xics_spapr.o obj-$(CONFIG_XICS_KVM) +=3D xics_kvm.o obj-$(CONFIG_XIVE) +=3D xive.o obj-$(CONFIG_XIVE_SPAPR) +=3D spapr_xive.o +obj-$(CONFIG_XIVE_KVM) +=3D spapr_xive_kvm.o obj-$(CONFIG_POWERNV) +=3D xics_pnv.o pnv_xive.o obj-$(CONFIG_ALLWINNER_A10_PIC) +=3D allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) +=3D s390_flic.o diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 2b83637511ec..810c35d27a80 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -119,3 +119,8 @@ config XIVE_SPAPR default y depends on PSERIES select XIVE + +config XIVE_KVM + bool + default y + depends on XIVE_SPAPR && KVM --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180662993707.229148182799; Thu, 21 Mar 2019 08:04:22 -0700 (PDT) Received: from localhost ([127.0.0.1]:39097 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6zEu-0006i4-FE for importer@patchew.org; Thu, 21 Mar 2019 11:04:16 -0400 Received: from eggs.gnu.org ([209.51.188.92]:43991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1D-0003Vc-KW for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1A-0000X4-Fv for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:07 -0400 Received: from 8.mo178.mail-out.ovh.net ([46.105.74.227]:46232) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z16-00009T-PX for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:01 -0400 Received: from player788.ha.ovh.net (unknown [10.109.159.7]) by mo178.mail-out.ovh.net (Postfix) with ESMTP id 3494D57C66 for ; Thu, 21 Mar 2019 15:49:45 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 1D9F03E6B3DE; Thu, 21 Mar 2019 14:49:39 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:02 +0100 Message-Id: <20190321144914.19934-4-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11855726020701424614 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.74.227 Subject: [Qemu-devel] [PATCH v3 03/15] spapr/xive: add hcall support when under KVM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" XIVE hcalls are all redirected to QEMU as none are on a fast path. When necessary, QEMU invokes KVM through specific ioctls to perform host operations. QEMU should have done the necessary checks before calling KVM and, in case of failure, H_HARDWARE is simply returned. H_INT_ESB is a special case that could have been handled under KVM but the impact on performance was low when under QEMU. Here are some figures : kernel irqchip OFF ON H_INT_ESB KVM QEMU rtl8139 (LSI ) 1.19 1.24 1.23 Gbits/sec virtio 31.80 42.30 -- Gbits/sec Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- What has not changed : - Memory barriers have not been included. Only loads are performed on the ESB management page (no stores for now) and stores are done only on the trigger page. We should be fine as for the load ordering on the management page. Changes since v2: - added an assert() in spapr_xive_end_to_target() - moved xive_end_is_valid() check out of kvmppc_xive_set_queue_config() - dealt with MASKED EAS - reworked ESB memory operations - improved KVM_XIVE_EQ_ALWAYS_NOTIFY handling =20 include/hw/ppc/spapr_xive.h | 15 +++ hw/intc/spapr_xive.c | 90 ++++++++++++++-- hw/intc/spapr_xive_kvm.c | 198 ++++++++++++++++++++++++++++++++++++ 3 files changed, 295 insertions(+), 8 deletions(-) diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 0edcc762dedd..03685910e76b 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -55,9 +55,24 @@ void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx); void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable); void spapr_xive_map_mmio(SpaprXive *xive); =20 +int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx, + uint32_t *out_server, uint8_t *out_prio); + /* * KVM XIVE device helpers */ void kvmppc_xive_connect(SpaprXive *xive, Error **errp); +void kvmppc_xive_reset(SpaprXive *xive, Error **errp); +void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS= *eas, + Error **errp); +void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t lisn, Error **errp); +uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcno, uint32_t offset, + uint64_t data, bool write); +void kvmppc_xive_set_queue_config(SpaprXive *xive, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + Error **errp); +void kvmppc_xive_get_queue_config(SpaprXive *xive, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + Error **errp); =20 #endif /* PPC_SPAPR_XIVE_H */ diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 84ecbf3adf24..cde2fd7c8997 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -86,6 +86,22 @@ static int spapr_xive_target_to_nvt(uint32_t target, * sPAPR END indexing uses a simple mapping of the CPU vcpu_id, 8 * priorities per CPU */ +int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx, + uint32_t *out_server, uint8_t *out_prio) +{ + + assert(end_blk =3D=3D SPAPR_XIVE_BLOCK_ID); + + if (out_server) { + *out_server =3D end_idx >> 3; + } + + if (out_prio) { + *out_prio =3D end_idx & 0x7; + } + return 0; +} + static void spapr_xive_cpu_to_end(PowerPCCPU *cpu, uint8_t prio, uint8_t *out_end_blk, uint32_t *out_end_= idx) { @@ -791,6 +807,16 @@ static target_ulong h_int_set_source_config(PowerPCCPU= *cpu, new_eas.w =3D xive_set_field64(EAS_END_DATA, new_eas.w, eisn); } =20 + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_set_source_config(xive, lisn, &new_eas, &local_err); + if (local_err) { + error_report_err(local_err); + return H_HARDWARE; + } + } + out: xive->eat[lisn] =3D new_eas; return H_SUCCESS; @@ -1096,6 +1122,16 @@ static target_ulong h_int_set_queue_config(PowerPCCP= U *cpu, */ =20 out: + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_set_queue_config(xive, end_blk, end_idx, &end, &local_= err); + if (local_err) { + error_report_err(local_err); + return H_HARDWARE; + } + } + /* Update END */ memcpy(&xive->endt[end_idx], &end, sizeof(XiveEND)); return H_SUCCESS; @@ -1188,6 +1224,16 @@ static target_ulong h_int_get_queue_config(PowerPCCP= U *cpu, args[2] =3D 0; } =20 + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_get_queue_config(xive, end_blk, end_idx, end, &local_e= rr); + if (local_err) { + error_report_err(local_err); + return H_HARDWARE; + } + } + /* TODO: do we need any locking on the END ? */ if (flags & SPAPR_XIVE_END_DEBUG) { /* Load the event queue generation number into the return flags */ @@ -1340,15 +1386,20 @@ static target_ulong h_int_esb(PowerPCCPU *cpu, return H_P3; } =20 - mmio_addr =3D xive->vc_base + xive_source_esb_mgmt(xsrc, lisn) + offse= t; + if (kvm_irqchip_in_kernel()) { + args[0] =3D kvmppc_xive_esb_rw(xsrc, lisn, offset, data, + flags & SPAPR_XIVE_ESB_STORE); + } else { + mmio_addr =3D xive->vc_base + xive_source_esb_mgmt(xsrc, lisn) + o= ffset; =20 - if (dma_memory_rw(&address_space_memory, mmio_addr, &data, 8, - (flags & SPAPR_XIVE_ESB_STORE))) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x%" - HWADDR_PRIx "\n", mmio_addr); - return H_HARDWARE; + if (dma_memory_rw(&address_space_memory, mmio_addr, &data, 8, + (flags & SPAPR_XIVE_ESB_STORE))) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x= %" + HWADDR_PRIx "\n", mmio_addr); + return H_HARDWARE; + } + args[0] =3D (flags & SPAPR_XIVE_ESB_STORE) ? -1 : data; } - args[0] =3D (flags & SPAPR_XIVE_ESB_STORE) ? -1 : data; return H_SUCCESS; } =20 @@ -1405,7 +1456,20 @@ static target_ulong h_int_sync(PowerPCCPU *cpu, * This is not needed when running the emulation under QEMU */ =20 - /* This is not real hardware. Nothing to be done */ + /* + * This is not real hardware. Nothing to be done unless when + * under KVM + */ + + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_sync_source(xive, lisn, &local_err); + if (local_err) { + error_report_err(local_err); + return H_HARDWARE; + } + } return H_SUCCESS; } =20 @@ -1440,6 +1504,16 @@ static target_ulong h_int_reset(PowerPCCPU *cpu, } =20 device_reset(DEVICE(xive)); + + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_reset(xive, &local_err); + if (local_err) { + error_report_err(local_err); + return H_HARDWARE; + } + } return H_SUCCESS; } =20 diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 7d9e771e8a91..2714f8e4702e 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -89,6 +89,50 @@ void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **err= p) * XIVE Interrupt Source (KVM) */ =20 +void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS= *eas, + Error **errp) +{ + uint32_t end_idx; + uint32_t end_blk; + uint8_t priority; + uint32_t server; + bool masked; + uint32_t eisn; + uint64_t kvm_src; + Error *local_err =3D NULL; + + assert(xive_eas_is_valid(eas)); + + end_idx =3D xive_get_field64(EAS_END_INDEX, eas->w); + end_blk =3D xive_get_field64(EAS_END_BLOCK, eas->w); + eisn =3D xive_get_field64(EAS_END_DATA, eas->w); + masked =3D xive_eas_is_masked(eas); + + spapr_xive_end_to_target(end_blk, end_idx, &server, &priority); + + kvm_src =3D priority << KVM_XIVE_SOURCE_PRIORITY_SHIFT & + KVM_XIVE_SOURCE_PRIORITY_MASK; + kvm_src |=3D server << KVM_XIVE_SOURCE_SERVER_SHIFT & + KVM_XIVE_SOURCE_SERVER_MASK; + kvm_src |=3D ((uint64_t) masked << KVM_XIVE_SOURCE_MASKED_SHIFT) & + KVM_XIVE_SOURCE_MASKED_MASK; + kvm_src |=3D ((uint64_t)eisn << KVM_XIVE_SOURCE_EISN_SHIFT) & + KVM_XIVE_SOURCE_EISN_MASK; + + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE_CONFIG, lisn, + &kvm_src, true, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } +} + +void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t lisn, Error **errp) +{ + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE_SYNC, lisn, + NULL, true, errp); +} + /* * At reset, the interrupt sources are simply created and MASKED. We * only need to inform the KVM XIVE device about their type: LSI or @@ -125,6 +169,64 @@ void kvmppc_xive_source_reset(XiveSource *xsrc, Error = **errp) } } =20 +/* + * This is used to perform the magic loads on the ESB pages, described + * in xive.h. + * + * Memory barriers should not be needed for loads (no store for now). + */ +static uint64_t xive_esb_rw(XiveSource *xsrc, int srcno, uint32_t offset, + uint64_t data, bool write) +{ + uint64_t *addr =3D xsrc->esb_mmap + xive_source_esb_mgmt(xsrc, srcno) + + offset; + + if (write) { + *addr =3D cpu_to_be64(data); + return -1; + } else { + /* Prevent the compiler from optimizing away the load */ + volatile uint64_t value =3D be64_to_cpu(*addr); + return value; + } +} + +static uint8_t xive_esb_read(XiveSource *xsrc, int srcno, uint32_t offset) +{ + return xive_esb_rw(xsrc, srcno, offset, 0, 0) & 0x3; +} + +static void xive_esb_trigger(XiveSource *xsrc, int srcno) +{ + uint64_t *addr =3D xsrc->esb_mmap + xive_source_esb_page(xsrc, srcno); + + *addr =3D 0x0; +} + +uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcno, uint32_t offset, + uint64_t data, bool write) +{ + if (write) { + return xive_esb_rw(xsrc, srcno, offset, data, 1); + } + + /* + * Special Load EOI handling for LSI sources. Q bit is never set + * and the interrupt should be re-triggered if the level is still + * asserted. + */ + if (xive_source_irq_is_lsi(xsrc, srcno) && + offset =3D=3D XIVE_ESB_LOAD_EOI) { + xive_esb_read(xsrc, srcno, XIVE_ESB_SET_PQ_00); + if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) { + xive_esb_trigger(xsrc, srcno); + } + return 0; + } else { + return xive_esb_rw(xsrc, srcno, offset, 0, 0); + } +} + void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val) { XiveSource *xsrc =3D opaque; @@ -155,6 +257,102 @@ void kvmppc_xive_source_set_irq(void *opaque, int src= no, int val) /* * sPAPR XIVE interrupt controller (KVM) */ +void kvmppc_xive_get_queue_config(SpaprXive *xive, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + Error **errp) +{ + struct kvm_ppc_xive_eq kvm_eq =3D { 0 }; + uint64_t kvm_eq_idx; + uint8_t priority; + uint32_t server; + Error *local_err =3D NULL; + + assert(xive_end_is_valid(end)); + + /* Encode the tuple (server, prio) as a KVM EQ index */ + spapr_xive_end_to_target(end_blk, end_idx, &server, &priority); + + kvm_eq_idx =3D priority << KVM_XIVE_EQ_PRIORITY_SHIFT & + KVM_XIVE_EQ_PRIORITY_MASK; + kvm_eq_idx |=3D server << KVM_XIVE_EQ_SERVER_SHIFT & + KVM_XIVE_EQ_SERVER_MASK; + + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_EQ_CONFIG, kvm_eq_idx, + &kvm_eq, false, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + /* + * The EQ index and toggle bit are updated by HW. These are the + * only fields from KVM we want to update QEMU with. The other END + * fields should already be in the QEMU END table. + */ + end->w1 =3D xive_set_field32(END_W1_GENERATION, 0ul, kvm_eq.qtoggle) | + xive_set_field32(END_W1_PAGE_OFF, 0ul, kvm_eq.qindex); +} + +void kvmppc_xive_set_queue_config(SpaprXive *xive, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + Error **errp) +{ + struct kvm_ppc_xive_eq kvm_eq =3D { 0 }; + uint64_t kvm_eq_idx; + uint8_t priority; + uint32_t server; + Error *local_err =3D NULL; + + /* + * Build the KVM state from the local END structure. + */ + + kvm_eq.flags =3D 0; + if (xive_get_field32(END_W0_UCOND_NOTIFY, end->w0)) { + kvm_eq.flags |=3D KVM_XIVE_EQ_ALWAYS_NOTIFY; + } + + /* + * If the hcall is disabling the EQ, set the size and page address + * to zero. When migrating, only valid ENDs are taken into + * account. + */ + if (xive_end_is_valid(end)) { + kvm_eq.qshift =3D xive_get_field32(END_W0_QSIZE, end->w0) + 12; + kvm_eq.qaddr =3D (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << = 32 | + be32_to_cpu(end->w3); + /* + * The EQ toggle bit and index should only be relevant when + * restoring the EQ state + */ + kvm_eq.qtoggle =3D xive_get_field32(END_W1_GENERATION, end->w1); + kvm_eq.qindex =3D xive_get_field32(END_W1_PAGE_OFF, end->w1); + } else { + kvm_eq.qshift =3D 0; + kvm_eq.qaddr =3D 0; + } + + /* Encode the tuple (server, prio) as a KVM EQ index */ + spapr_xive_end_to_target(end_blk, end_idx, &server, &priority); + + kvm_eq_idx =3D priority << KVM_XIVE_EQ_PRIORITY_SHIFT & + KVM_XIVE_EQ_PRIORITY_MASK; + kvm_eq_idx |=3D server << KVM_XIVE_EQ_SERVER_SHIFT & + KVM_XIVE_EQ_SERVER_MASK; + + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_EQ_CONFIG, kvm_eq_idx, + &kvm_eq, true, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } +} + +void kvmppc_xive_reset(SpaprXive *xive, Error **errp) +{ + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_CTRL, KVM_DEV_XIVE_RESET, + NULL, true, errp); +} =20 static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len, Error **errp) --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180315298982.7823960163956; Thu, 21 Mar 2019 07:58:35 -0700 (PDT) Received: from localhost ([127.0.0.1]:38967 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z9K-0002E5-3W for importer@patchew.org; Thu, 21 Mar 2019 10:58:30 -0400 Received: from eggs.gnu.org ([209.51.188.92]:43987) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1D-0003VZ-JG for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1B-0000Yg-55 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:07 -0400 Received: from 17.mo6.mail-out.ovh.net ([46.105.36.150]:58963) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1A-0000EI-Kv for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:05 -0400 Received: from player788.ha.ovh.net (unknown [10.109.146.106]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 8C1A51B9996 for ; Thu, 21 Mar 2019 15:49:50 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 0E9E03E6B426; Thu, 21 Mar 2019 14:49:45 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:03 +0100 Message-Id: <20190321144914.19934-5-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11857414872120658918 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.36.150 Subject: [Qemu-devel] [PATCH v3 04/15] spapr/xive: add state synchronization with KVM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This extends the KVM XIVE device backend with 'synchronize_state' methods used to retrieve the state from KVM. The HW state of the sources, the KVM device and the thread interrupt contexts are collected for the monitor usage and also migration. These get operations rely on their KVM counterpart in the host kernel which acts as a proxy for OPAL, the host firmware. The set operations will be added for migration support later. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v2: - removed the capture of the OS CAM line value from KVM - added xive_end_is_valid() check include/hw/ppc/spapr_xive.h | 8 ++++ include/hw/ppc/xive.h | 1 + hw/intc/spapr_xive.c | 17 +++++--- hw/intc/spapr_xive_kvm.c | 87 +++++++++++++++++++++++++++++++++++++ hw/intc/xive.c | 10 +++++ 5 files changed, 116 insertions(+), 7 deletions(-) diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 03685910e76b..7e49badd8c9a 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -44,6 +44,13 @@ typedef struct SpaprXive { void *tm_mmap; } SpaprXive; =20 +/* + * The sPAPR machine has a unique XIVE IC device. Assign a fixed value + * to the controller block id value. It can nevertheless be changed + * for testing purpose. + */ +#define SPAPR_XIVE_BLOCK_ID 0x0 + bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon); @@ -74,5 +81,6 @@ void kvmppc_xive_set_queue_config(SpaprXive *xive, uint8_= t end_blk, void kvmppc_xive_get_queue_config(SpaprXive *xive, uint8_t end_blk, uint32_t end_idx, XiveEND *end, Error **errp); +void kvmppc_xive_synchronize_state(SpaprXive *xive, Error **errp); =20 #endif /* PPC_SPAPR_XIVE_H */ diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index dd115da30ebc..78c919c4a590 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -435,5 +435,6 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int= srcno, Error **errp); void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp); void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val); void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp); +void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp); =20 #endif /* PPC_XIVE_H */ diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index cde2fd7c8997..4d07140f1078 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -40,13 +40,6 @@ =20 #define SPAPR_XIVE_NVT_BASE 0x400 =20 -/* - * The sPAPR machine has a unique XIVE IC device. Assign a fixed value - * to the controller block id value. It can nevertheless be changed - * for testing purpose. - */ -#define SPAPR_XIVE_BLOCK_ID 0x0 - /* * sPAPR NVT and END indexing helpers */ @@ -156,6 +149,16 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monito= r *mon) XiveSource *xsrc =3D &xive->source; int i; =20 + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_synchronize_state(xive, &local_err); + if (local_err) { + error_report_err(local_err); + return; + } + } + monitor_printf(mon, " LSIN PQ EISN CPU/PRIO EQ\n"); =20 for (i =3D 0; i < xive->nr_irqs; i++) { diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 2714f8e4702e..2e46661cb3ad 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -60,6 +60,51 @@ static void kvm_cpu_enable(CPUState *cs) /* * XIVE Thread Interrupt Management context (KVM) */ +static void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp) +{ + uint64_t state[2] =3D { 0 }; + int ret; + + ret =3D kvm_get_one_reg(tctx->cs, KVM_REG_PPC_VP_STATE, state); + if (ret !=3D 0) { + error_setg_errno(errp, errno, + "XIVE: could not capture KVM state of CPU %ld", + kvm_arch_vcpu_id(tctx->cs)); + return; + } + + /* word0 and word1 of the OS ring. */ + *((uint64_t *) &tctx->regs[TM_QW1_OS]) =3D state[0]; +} + +typedef struct { + XiveTCTX *tctx; + Error *err; +} XiveCpuGetState; + +static void kvmppc_xive_cpu_do_synchronize_state(CPUState *cpu, + run_on_cpu_data arg) +{ + XiveCpuGetState *s =3D arg.host_ptr; + + kvmppc_xive_cpu_get_state(s->tctx, &s->err); +} + +void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp) +{ + XiveCpuGetState s =3D { + .tctx =3D tctx, + .err =3D NULL, + }; + + run_on_cpu(tctx->cs, kvmppc_xive_cpu_do_synchronize_state, + RUN_ON_CPU_HOST_PTR(&s)); + + if (s.err) { + error_propagate(errp, s.err); + return; + } +} =20 void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp) { @@ -227,6 +272,19 @@ uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcn= o, uint32_t offset, } } =20 +static void kvmppc_xive_source_get_state(XiveSource *xsrc) +{ + int i; + + for (i =3D 0; i < xsrc->nr_irqs; i++) { + /* Perform a load without side effect to retrieve the PQ bits */ + uint8_t pq =3D xive_esb_read(xsrc, i, XIVE_ESB_GET); + + /* and save PQ locally */ + xive_source_esb_set(xsrc, i, pq); + } +} + void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val) { XiveSource *xsrc =3D opaque; @@ -354,6 +412,35 @@ void kvmppc_xive_reset(SpaprXive *xive, Error **errp) NULL, true, errp); } =20 +static void kvmppc_xive_get_queues(SpaprXive *xive, Error **errp) +{ + Error *local_err =3D NULL; + int i; + + for (i =3D 0; i < xive->nr_ends; i++) { + if (!xive_end_is_valid(&xive->endt[i])) { + continue; + } + + kvmppc_xive_get_queue_config(xive, SPAPR_XIVE_BLOCK_ID, i, + &xive->endt[i], &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } +} + +void kvmppc_xive_synchronize_state(SpaprXive *xive, Error **errp) +{ + kvmppc_xive_source_get_state(&xive->source); + + /* EAT: there is no extra state to query from KVM */ + + /* ENDT */ + kvmppc_xive_get_queues(xive, errp); +} + static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len, Error **errp) { diff --git a/hw/intc/xive.c b/hw/intc/xive.c index a0662fd33174..65cb772676a5 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -493,6 +493,16 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor = *mon) int cpu_index =3D tctx->cs ? tctx->cs->cpu_index : -1; int i; =20 + if (kvm_irqchip_in_kernel()) { + Error *local_err =3D NULL; + + kvmppc_xive_cpu_synchronize_state(tctx, &local_err); + if (local_err) { + error_report_err(local_err); + return; + } + } + monitor_printf(mon, "CPU[%04x]: QW NSR CPPR IPB LSMFB ACK# INC AGE= PIPR" " W2\n", cpu_index); =20 --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180136801272.62302870745816; Thu, 21 Mar 2019 07:55:36 -0700 (PDT) Received: from localhost ([127.0.0.1]:38882 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z6T-0008B0-K6 for importer@patchew.org; Thu, 21 Mar 2019 10:55:33 -0400 Received: from eggs.gnu.org ([209.51.188.92]:43966) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1C-0003VR-T0 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1A-0000Wy-Gd for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:06 -0400 Received: from 14.mo4.mail-out.ovh.net ([46.105.40.29]:33531) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z17-0000KE-1F for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:01 -0400 Received: from player788.ha.ovh.net (unknown [10.109.143.220]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id 5CD8C1DFCBB for ; Thu, 21 Mar 2019 15:49:56 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 8C1C23E6B4C8; Thu, 21 Mar 2019 14:49:50 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:04 +0100 Message-Id: <20190321144914.19934-6-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11859103721785428966 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.40.29 Subject: [Qemu-devel] [PATCH v3 05/15] spapr/xive: introduce a VM state change handler X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This handler is in charge of stabilizing the flow of event notifications in the XIVE controller before migrating a guest. This is a requirement before transferring the guest EQ pages to a destination. When the VM is stopped, the handler sets the source PQs to PENDING to stop the flow of events and to possibly catch a triggered interrupt occuring while the VM is stopped. Their previous state is saved. The XIVE controller is then synced through KVM to flush any in-flight event notification and to stabilize the EQs. At this stage, the EQ pages are marked dirty to make sure the EQ pages are transferred if a migration sequence is in progress. The previous configuration of the sources is restored when the VM resumes, after a migration or a stop. If an interrupt was queued while the VM was stopped, the handler simply generates the missing trigger. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- Changes since v2: - merged in handling of pending interrupts while the VM is stopped. include/hw/ppc/spapr_xive.h | 1 + hw/intc/spapr_xive_kvm.c | 96 ++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 7e49badd8c9a..734662c12a10 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -42,6 +42,7 @@ typedef struct SpaprXive { /* KVM support */ int fd; void *tm_mmap; + VMChangeStateEntry *change; } SpaprXive; =20 /* diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 2e46661cb3ad..a011d415ee51 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -431,9 +431,100 @@ static void kvmppc_xive_get_queues(SpaprXive *xive, E= rror **errp) } } =20 +/* + * The primary goal of the XIVE VM change handler is to mark the EQ + * pages dirty when all XIVE event notifications have stopped. + * + * Whenever the VM is stopped, the VM change handler sets the source + * PQs to PENDING to stop the flow of events and to possibly catch a + * triggered interrupt occuring while the VM is stopped. The previous + * state is saved in anticipation of a migration. The XIVE controller + * is then synced through KVM to flush any in-flight event + * notification and stabilize the EQs. + * + * At this stage, we can mark the EQ page dirty and let a migration + * sequence transfer the EQ pages to the destination, which is done + * just after the stop state. + * + * The previous configuration of the sources is restored when the VM + * runs again. If an interrupt was queued while the VM was stopped, + * simply generate a trigger. + */ +static void kvmppc_xive_change_state_handler(void *opaque, int running, + RunState state) +{ + SpaprXive *xive =3D opaque; + XiveSource *xsrc =3D &xive->source; + Error *local_err =3D NULL; + int i; + + /* + * Restore the sources to their initial state. This is called when + * the VM resumes after a stop or a migration. + */ + if (running) { + for (i =3D 0; i < xsrc->nr_irqs; i++) { + uint8_t pq =3D xive_source_esb_get(xsrc, i); + uint8_t old_pq; + + old_pq =3D xive_esb_read(xsrc, i, XIVE_ESB_SET_PQ_00 + (pq << = 8)); + + /* + * An interrupt was queued while the VM was stopped, + * generate a trigger. + */ + if (pq =3D=3D XIVE_ESB_RESET && old_pq =3D=3D XIVE_ESB_QUEUED)= { + xive_esb_trigger(xsrc, i); + } + } + + return; + } + + /* + * Mask the sources, to stop the flow of event notifications, and + * save the PQs locally in the XiveSource object. The XiveSource + * state will be collected later on by its vmstate handler if a + * migration is in progress. + */ + for (i =3D 0; i < xsrc->nr_irqs; i++) { + uint8_t pq =3D xive_esb_read(xsrc, i, XIVE_ESB_GET); + + /* + * PQ is set to PENDING to possibly catch a triggered + * interrupt occuring while the VM is stopped (hotplug event + * for instance) . + */ + if (pq !=3D XIVE_ESB_OFF) { + pq =3D xive_esb_read(xsrc, i, XIVE_ESB_SET_PQ_10); + } + xive_source_esb_set(xsrc, i, pq); + } + + /* + * Sync the XIVE controller in KVM, to flush in-flight event + * notification that should be enqueued in the EQs and mark the + * XIVE EQ pages dirty to collect all updates. + */ + kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_CTRL, + KVM_DEV_XIVE_EQ_SYNC, NULL, true, &local_err); + if (local_err) { + error_report_err(local_err); + return; + } +} + void kvmppc_xive_synchronize_state(SpaprXive *xive, Error **errp) { - kvmppc_xive_source_get_state(&xive->source); + /* + * When the VM is stopped, the sources are masked and the previous + * state is saved in anticipation of a migration. We should not + * synchronize the source state in that case else we will override + * the saved state. + */ + if (runstate_is_running()) { + kvmppc_xive_source_get_state(&xive->source); + } =20 /* EAT: there is no extra state to query from KVM */ =20 @@ -513,6 +604,9 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp) "xive.tima", tima_len, xive->tm_mmap= ); sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio); =20 + xive->change =3D qemu_add_vm_change_state_handler( + kvmppc_xive_change_state_handler, xive); + kvm_kernel_irqchip =3D true; kvm_msi_via_irqfd_allowed =3D true; kvm_gsi_direct_mapping =3D true; --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180489912295.61029104455963; Thu, 21 Mar 2019 08:01:29 -0700 (PDT) Received: from localhost ([127.0.0.1]:39052 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6zC7-0004Vj-Qq for importer@patchew.org; Thu, 21 Mar 2019 11:01:23 -0400 Received: from eggs.gnu.org ([209.51.188.92]:43995) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1D-0003W0-N2 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1B-0000ZG-G7 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:07 -0400 Received: from 14.mo4.mail-out.ovh.net ([46.105.40.29]:41033) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1A-0000U6-Ki for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:05 -0400 Received: from player788.ha.ovh.net (unknown [10.109.160.54]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id F208E1DD5C5 for ; Thu, 21 Mar 2019 15:50:01 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 605583E6B4D3; Thu, 21 Mar 2019 14:49:56 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:05 +0100 Message-Id: <20190321144914.19934-7-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11860511094959737830 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.40.29 Subject: [Qemu-devel] [PATCH v3 06/15] spapr/xive: add migration support for KVM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" When the VM is stopped, the VM state handler stabilizes the XIVE IC and marks the EQ pages dirty. These are then transferred to destination before the transfer of the device vmstates starts. The SpaprXive interrupt controller model captures the XIVE internal tables, EAT and ENDT and the XiveTCTX model does the same for the thread interrupt context registers. At restart, the SpaprXive 'post_load' method restores all the XIVE states. It is called by the sPAPR machine 'post_load' method, when all XIVE states have been transferred and loaded. Finally, the source states are restored in the VM change state handler when the machine reaches the running state. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- Changes since v2: - added xive_end_is_valid() check include/hw/ppc/spapr_xive.h | 3 ++ include/hw/ppc/xive.h | 1 + hw/intc/spapr_xive.c | 24 ++++++++++ hw/intc/spapr_xive_kvm.c | 95 ++++++++++++++++++++++++++++++++++++- hw/intc/xive.c | 17 +++++++ hw/ppc/spapr_irq.c | 2 +- 6 files changed, 140 insertions(+), 2 deletions(-) diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 734662c12a10..04294b0ca266 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -55,6 +55,7 @@ typedef struct SpaprXive { bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon); +int spapr_xive_post_load(SpaprXive *xive, int version_id); =20 void spapr_xive_hcall_init(SpaprMachineState *spapr); void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fd= t, @@ -83,5 +84,7 @@ void kvmppc_xive_get_queue_config(SpaprXive *xive, uint8_= t end_blk, uint32_t end_idx, XiveEND *end, Error **errp); void kvmppc_xive_synchronize_state(SpaprXive *xive, Error **errp); +int kvmppc_xive_pre_save(SpaprXive *xive); +int kvmppc_xive_post_load(SpaprXive *xive, int version_id); =20 #endif /* PPC_SPAPR_XIVE_H */ diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 78c919c4a590..edb8937f17fb 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -436,5 +436,6 @@ void kvmppc_xive_source_reset(XiveSource *xsrc, Error *= *errp); void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val); void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp); void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp); +void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp); =20 #endif /* PPC_XIVE_H */ diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 4d07140f1078..a3cbbdf7aff0 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -471,10 +471,34 @@ static const VMStateDescription vmstate_spapr_xive_ea= s =3D { }, }; =20 +static int vmstate_spapr_xive_pre_save(void *opaque) +{ + if (kvm_irqchip_in_kernel()) { + return kvmppc_xive_pre_save(SPAPR_XIVE(opaque)); + } + + return 0; +} + +/* + * Called by the sPAPR IRQ backend 'post_load' method at the machine + * level. + */ +int spapr_xive_post_load(SpaprXive *xive, int version_id) +{ + if (kvm_irqchip_in_kernel()) { + return kvmppc_xive_post_load(xive, version_id); + } + + return 0; +} + static const VMStateDescription vmstate_spapr_xive =3D { .name =3D TYPE_SPAPR_XIVE, .version_id =3D 1, .minimum_version_id =3D 1, + .pre_save =3D vmstate_spapr_xive_pre_save, + .post_load =3D NULL, /* handled at the machine level */ .fields =3D (VMStateField[]) { VMSTATE_UINT32_EQUAL(nr_irqs, SpaprXive, NULL), VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, SpaprXive, nr_irqs, diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index a011d415ee51..2fe0106f82a8 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 "hw/ppc/spapr.h" +#include "hw/ppc/spapr_cpu_core.h" #include "hw/ppc/spapr_xive.h" #include "hw/ppc/xive.h" #include "kvm_ppc.h" @@ -60,7 +61,24 @@ static void kvm_cpu_enable(CPUState *cs) /* * XIVE Thread Interrupt Management context (KVM) */ -static void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp) + +static void kvmppc_xive_cpu_set_state(XiveTCTX *tctx, Error **errp) +{ + uint64_t state[2]; + int ret; + + /* word0 and word1 of the OS ring. */ + state[0] =3D *((uint64_t *) &tctx->regs[TM_QW1_OS]); + + ret =3D kvm_set_one_reg(tctx->cs, KVM_REG_PPC_VP_STATE, state); + if (ret !=3D 0) { + error_setg_errno(errp, errno, + "XIVE: could not restore KVM state of CPU %ld", + kvm_arch_vcpu_id(tctx->cs)); + } +} + +void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp) { uint64_t state[2] =3D { 0 }; int ret; @@ -532,6 +550,81 @@ void kvmppc_xive_synchronize_state(SpaprXive *xive, Er= ror **errp) kvmppc_xive_get_queues(xive, errp); } =20 +/* + * The SpaprXive 'pre_save' method is called by the vmstate handler of + * the SpaprXive model, after the XIVE controller is synced in the VM + * change handler. + */ +int kvmppc_xive_pre_save(SpaprXive *xive) +{ + Error *local_err =3D NULL; + + /* EAT: there is no extra state to query from KVM */ + + /* ENDT */ + kvmppc_xive_get_queues(xive, &local_err); + if (local_err) { + error_report_err(local_err); + return -1; + } + + return 0; +} + +/* + * The SpaprXive 'post_load' method is not called by a vmstate + * handler. It is called at the sPAPR machine level at the end of the + * migration sequence by the sPAPR IRQ backend 'post_load' method, + * when all XIVE states have been transferred and loaded. + */ +int kvmppc_xive_post_load(SpaprXive *xive, int version_id) +{ + Error *local_err =3D NULL; + CPUState *cs; + int i; + + /* Restore the ENDT first. The targetting depends on it. */ + for (i =3D 0; i < xive->nr_ends; i++) { + if (!xive_end_is_valid(&xive->endt[i])) { + continue; + } + + kvmppc_xive_set_queue_config(xive, SPAPR_XIVE_BLOCK_ID, i, + &xive->endt[i], &local_err); + if (local_err) { + error_report_err(local_err); + return -1; + } + } + + /* Restore the EAT */ + for (i =3D 0; i < xive->nr_irqs; i++) { + if (!xive_eas_is_valid(&xive->eat[i])) { + continue; + } + + kvmppc_xive_set_source_config(xive, i, &xive->eat[i], &local_err); + if (local_err) { + error_report_err(local_err); + return -1; + } + } + + /* Restore the thread interrupt contexts */ + CPU_FOREACH(cs) { + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + + kvmppc_xive_cpu_set_state(spapr_cpu_state(cpu)->tctx, &local_err); + if (local_err) { + error_report_err(local_err); + return -1; + } + } + + /* The source states will be restored when the machine starts running = */ + return 0; +} + static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len, Error **errp) { diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 65cb772676a5..901689b0f015 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -582,10 +582,27 @@ static void xive_tctx_unrealize(DeviceState *dev, Err= or **errp) qemu_unregister_reset(xive_tctx_reset, dev); } =20 +static int vmstate_xive_tctx_pre_save(void *opaque) +{ + Error *local_err =3D NULL; + + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_cpu_get_state(XIVE_TCTX(opaque), &local_err); + if (local_err) { + error_report_err(local_err); + return -1; + } + } + + return 0; +} + static const VMStateDescription vmstate_xive_tctx =3D { .name =3D TYPE_XIVE_TCTX, .version_id =3D 1, .minimum_version_id =3D 1, + .pre_save =3D vmstate_xive_tctx_pre_save, + .post_load =3D NULL, /* handled by the sPAPRxive model */ .fields =3D (VMStateField[]) { VMSTATE_BUFFER(regs, XiveTCTX), VMSTATE_END_OF_LIST() diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index ec60d0a5ef74..f6db48b4da79 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -365,7 +365,7 @@ static void spapr_irq_cpu_intc_create_xive(SpaprMachine= State *spapr, =20 static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_= id) { - return 0; + return spapr_xive_post_load(spapr->xive, version_id); } =20 static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180320758282.7896817333519; Thu, 21 Mar 2019 07:58:40 -0700 (PDT) Received: from localhost ([127.0.0.1]:38971 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z9M-0002GN-Bx for importer@patchew.org; Thu, 21 Mar 2019 10:58:32 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44132) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1Y-0003uP-AV for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1X-000123-8t for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:28 -0400 Received: from 2.mo3.mail-out.ovh.net ([46.105.75.36]:52589) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1T-0000dP-PV for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:25 -0400 Received: from player788.ha.ovh.net (unknown [10.109.159.139]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id CE9CD205045 for ; Thu, 21 Mar 2019 15:50:07 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id DF2533E6B4DA; Thu, 21 Mar 2019 14:50:01 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:06 +0100 Message-Id: <20190321144914.19934-8-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11862199944048249830 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.75.36 Subject: [Qemu-devel] [PATCH v3 07/15] spapr/xive: activate KVM support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" All is in place for KVM now. State synchronization and migration will come next. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- hw/ppc/spapr_irq.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index f6db48b4da79..b4e3128b7f06 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -263,19 +263,10 @@ SpaprIrq spapr_irq_xics =3D { static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs, Error **errp) { - MachineState *machine =3D MACHINE(spapr); uint32_t nr_servers =3D spapr_max_server_number(spapr); DeviceState *dev; int i; =20 - /* KVM XIVE device not yet available */ - if (kvm_enabled()) { - if (machine_kernel_irqchip_required(machine)) { - error_setg(errp, "kernel_irqchip requested. no KVM XIVE suppor= t"); - return; - } - } - dev =3D qdev_create(NULL, TYPE_SPAPR_XIVE); qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs); /* --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180151439707.9144502510488; Thu, 21 Mar 2019 07:55:51 -0700 (PDT) Received: from localhost ([127.0.0.1]:38917 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z6i-0008S5-ED for importer@patchew.org; Thu, 21 Mar 2019 10:55:48 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44101) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1X-0003tk-MJ for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1V-0000zw-OF for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:27 -0400 Received: from 10.mo1.mail-out.ovh.net ([178.32.96.102]:45148) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1T-0000nq-42 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:23 -0400 Received: from player788.ha.ovh.net (unknown [10.109.146.53]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id 6398D165B61 for ; Thu, 21 Mar 2019 15:50:13 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id D912E3E6B55A; Thu, 21 Mar 2019 14:50:07 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:07 +0100 Message-Id: <20190321144914.19934-9-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11863888796326202342 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 178.32.96.102 Subject: [Qemu-devel] [PATCH v3 08/15] spapr/rtas: modify spapr_rtas_register() to remove RTAS handlers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Removing RTAS handlers will become necessary when the new pseries machine supporting multiple interrupt mode is introduced. Signed-off-by: C=C3=A9dric Le Goater --- include/hw/ppc/spapr.h | 4 ++++ hw/ppc/spapr_rtas.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 2b4c05a2ec33..6a067db04351 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -671,6 +671,10 @@ typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, SpaprMa= chineState *sm, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets); void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn); +static inline void spapr_rtas_unregister(int token) +{ + spapr_rtas_register(token, NULL, NULL); +} target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm, uint32_t token, uint32_t nargs, target_ulong = args, uint32_t nret, target_ulong rets); diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 24c45b12d46b..ee24212765be 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -404,7 +404,7 @@ void spapr_rtas_register(int token, const char *name, s= papr_rtas_fn fn) =20 token -=3D RTAS_TOKEN_BASE; =20 - assert(!rtas_table[token].name); + assert(!name || !rtas_table[token].name); =20 rtas_table[token].name =3D name; rtas_table[token].fn =3D fn; --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180000369789.9065957978883; Thu, 21 Mar 2019 07:53:20 -0700 (PDT) Received: from localhost ([127.0.0.1]:38856 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z4F-0005ge-AJ for importer@patchew.org; Thu, 21 Mar 2019 10:53:15 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44174) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1Z-0003vS-8r for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1Y-00013f-66 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:29 -0400 Received: from 8.mo69.mail-out.ovh.net ([46.105.56.233]:51840) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1X-0000u4-Se for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:28 -0400 Received: from player788.ha.ovh.net (unknown [10.109.146.86]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id 6F2414BDFD for ; Thu, 21 Mar 2019 15:50:19 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id D41733E6B668; Thu, 21 Mar 2019 14:50:13 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:08 +0100 Message-Id: <20190321144914.19934-10-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11865577645149883366 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.56.233 Subject: [Qemu-devel] [PATCH v3 09/15] sysbus: add a sysbus_mmio_unmap() helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This will be used to remove the MMIO regions of the POWER9 XIVE interrupt controller when the sPAPR machine is reseted. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- include/hw/sysbus.h | 1 + hw/core/sysbus.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index 1aedcf05c92b..4c668fbbdc60 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -89,6 +89,7 @@ qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int = n); void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr); void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr, int priority); +void sysbus_mmio_unmap(SysBusDevice *dev, int n); void sysbus_add_io(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem); MemoryRegion *sysbus_address_space(SysBusDevice *dev); diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 307cf90a5196..689a867a2274 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -153,6 +153,16 @@ static void sysbus_mmio_map_common(SysBusDevice *dev, = int n, hwaddr addr, } } =20 +void sysbus_mmio_unmap(SysBusDevice *dev, int n) +{ + assert(n >=3D 0 && n < dev->num_mmio); + + if (dev->mmio[n].addr !=3D (hwaddr)-1) { + memory_region_del_subregion(get_system_memory(), dev->mmio[n].memo= ry); + dev->mmio[n].addr =3D (hwaddr)-1; + } +} + void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr) { sysbus_mmio_map_common(dev, n, addr, false, 0); --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180177638514.5858395024181; Thu, 21 Mar 2019 07:56:17 -0700 (PDT) Received: from localhost ([127.0.0.1]:38919 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z78-0000O0-IM for importer@patchew.org; Thu, 21 Mar 2019 10:56:14 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44193) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1Z-0003vv-Po for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1Y-000144-9g for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:29 -0400 Received: from 8.mo179.mail-out.ovh.net ([46.105.75.26]:46091) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1X-0000zL-QC for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:28 -0400 Received: from player788.ha.ovh.net (unknown [10.109.143.232]) by mo179.mail-out.ovh.net (Postfix) with ESMTP id E35AD1229CC for ; Thu, 21 Mar 2019 15:50:24 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 6AA7E3E6B701; Thu, 21 Mar 2019 14:50:19 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:09 +0100 Message-Id: <20190321144914.19934-11-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11866985021052324838 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.75.26 Subject: [Qemu-devel] [PATCH v3 10/15] spapr: introduce routines to delete the KVM IRQ device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" If a new interrupt mode is chosen by CAS, the machine generates a reset to reconfigure. At this point, the connection with the previous KVM device needs to be closed and a new connection needs to opened with the KVM device operating the chosen interrupt mode. New routines are introduced to destroy the XICS and the XIVE KVM devices. They make use of a new KVM device ioctl which destroys the device and also disconnects the IRQ presenters from the vCPUs. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- include/hw/ppc/spapr_xive.h | 1 + include/hw/ppc/xics_spapr.h | 1 + hw/intc/spapr_xive_kvm.c | 60 +++++++++++++++++++++++++++++++++++++ hw/intc/xics_kvm.c | 56 ++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 04294b0ca266..0b5e972d52c8 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -71,6 +71,7 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t en= d_idx, * KVM XIVE device helpers */ void kvmppc_xive_connect(SpaprXive *xive, Error **errp); +void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp); void kvmppc_xive_reset(SpaprXive *xive, Error **errp); void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS= *eas, Error **errp); diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h index 15a8dcff66fc..111e0d235cef 100644 --- a/include/hw/ppc/xics_spapr.h +++ b/include/hw/ppc/xics_spapr.h @@ -34,6 +34,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fd= t, uint32_t phandle); int xics_kvm_init(SpaprMachineState *spapr, Error **errp); +int xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp); void xics_spapr_init(SpaprMachineState *spapr); =20 #endif /* XICS_SPAPR_H */ diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 2fe0106f82a8..e8a4784f5326 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -58,6 +58,16 @@ static void kvm_cpu_enable(CPUState *cs) QLIST_INSERT_HEAD(&kvm_enabled_cpus, enabled_cpu, node); } =20 +static void kvm_cpu_disable_all(void) +{ + KVMEnabledCPU *enabled_cpu, *next; + + QLIST_FOREACH_SAFE(enabled_cpu, &kvm_enabled_cpus, node, next) { + QLIST_REMOVE(enabled_cpu, node); + g_free(enabled_cpu); + } +} + /* * XIVE Thread Interrupt Management context (KVM) */ @@ -707,3 +717,53 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp) /* Map all regions */ spapr_xive_map_mmio(xive); } + +void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp) +{ + XiveSource *xsrc; + struct kvm_destroy_device xive_destroy_device; + size_t esb_len; + int rc; + + /* The KVM XIVE device is not in use */ + if (!xive || xive->fd =3D=3D -1) { + return; + } + + if (!kvmppc_has_cap_xive()) { + error_setg(errp, "IRQ_XIVE capability must be present for KVM"); + return; + } + + /* Clear the KVM mapping */ + xsrc =3D &xive->source; + esb_len =3D (1ull << xsrc->esb_shift) * xsrc->nr_irqs; + + sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 0); + munmap(xsrc->esb_mmap, esb_len); + + sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 1); + + sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 2); + munmap(xive->tm_mmap, 4ull << TM_SHIFT); + + /* Destroy the KVM device. This also clears the VCPU presenters */ + xive_destroy_device.fd =3D xive->fd; + xive_destroy_device.flags =3D 0; + rc =3D kvm_vm_ioctl(kvm_state, KVM_DESTROY_DEVICE, &xive_destroy_devic= e); + if (rc < 0) { + error_setg_errno(errp, -rc, "Error on KVM_DESTROY_DEVICE for XIVE"= ); + } + close(xive->fd); + xive->fd =3D -1; + + kvm_kernel_irqchip =3D false; + kvm_msi_via_irqfd_allowed =3D false; + kvm_gsi_direct_mapping =3D false; + + /* Clear the local list of presenter (hotplug) */ + kvm_cpu_disable_all(); + + /* VM Change state handler is not needed anymore */ + qemu_del_vm_change_state_handler(xive->change); +} diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 78a252e6dfd4..0e3b5f5fbfcd 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -51,6 +51,16 @@ typedef struct KVMEnabledICP { static QLIST_HEAD(, KVMEnabledICP) kvm_enabled_icps =3D QLIST_HEAD_INITIALIZER(&kvm_enabled_icps); =20 +static void kvm_disable_icps(void) +{ + KVMEnabledICP *enabled_icp, *next; + + QLIST_FOREACH_SAFE(enabled_icp, &kvm_enabled_icps, node, next) { + QLIST_REMOVE(enabled_icp, node); + g_free(enabled_icp); + } +} + /* * ICP-KVM */ @@ -360,3 +370,49 @@ fail: kvmppc_define_rtas_kernel_token(0, "ibm,int-off"); return -1; } + +int xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp) +{ + int rc; + struct kvm_destroy_device xics_destroy_device =3D { + .fd =3D kernel_xics_fd, + .flags =3D 0, + }; + + /* The KVM XICS device is not in use */ + if (kernel_xics_fd =3D=3D -1) { + return 0; + } + + if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS= )) { + error_setg(errp, + "KVM and IRQ_XICS capability must be present for KVM XI= CS device"); + return -1; + } + + rc =3D kvm_vm_ioctl(kvm_state, KVM_DESTROY_DEVICE, &xics_destroy_devic= e); + if (rc < 0) { + error_setg_errno(errp, -rc, "Error on KVM_DESTROY_DEVICE for XICS"= ); + } + close(kernel_xics_fd); + kernel_xics_fd =3D -1; + + spapr_rtas_unregister(RTAS_IBM_SET_XIVE); + spapr_rtas_unregister(RTAS_IBM_GET_XIVE); + spapr_rtas_unregister(RTAS_IBM_INT_OFF); + spapr_rtas_unregister(RTAS_IBM_INT_ON); + + kvmppc_define_rtas_kernel_token(0, "ibm,set-xive"); + kvmppc_define_rtas_kernel_token(0, "ibm,get-xive"); + kvmppc_define_rtas_kernel_token(0, "ibm,int-on"); + kvmppc_define_rtas_kernel_token(0, "ibm,int-off"); + + kvm_kernel_irqchip =3D false; + kvm_msi_via_irqfd_allowed =3D false; + kvm_gsi_direct_mapping =3D false; + + /* Clear the presenter from the VCPUs */ + kvm_disable_icps(); + + return rc; +} --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180336687980.2344772165873; Thu, 21 Mar 2019 07:58:56 -0700 (PDT) Received: from localhost ([127.0.0.1]:38975 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z9b-0002Ru-Gh for importer@patchew.org; Thu, 21 Mar 2019 10:58:47 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44246) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1h-00042M-6A for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1d-0001Bk-0e for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:35 -0400 Received: from 10.mo5.mail-out.ovh.net ([46.105.52.148]:53890) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1c-00019g-PI for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:32 -0400 Received: from player788.ha.ovh.net (unknown [10.109.146.163]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id 7A0DF225FEB for ; Thu, 21 Mar 2019 15:50:30 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id EC7B13E6B734; Thu, 21 Mar 2019 14:50:24 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:10 +0100 Message-Id: <20190321144914.19934-12-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11868673870759955430 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.52.148 Subject: [Qemu-devel] [PATCH v3 11/15] spapr: check for the activation of the KVM IRQ device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The activation of the KVM IRQ device depends on the interrupt mode chosen at CAS time by the machine and some methods used at reset or by the migration need to be protected. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- Changes since v2: - did an update in ics_set_kvm_state_one() =20 hw/intc/spapr_xive_kvm.c | 28 ++++++++++++++++++++++++++++ hw/intc/xics_kvm.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index e8a4784f5326..78d2ea433c98 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -90,9 +90,15 @@ static void kvmppc_xive_cpu_set_state(XiveTCTX *tctx, Er= ror **errp) =20 void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp) { + SpaprXive *xive =3D SPAPR_MACHINE(qdev_get_machine())->xive; uint64_t state[2] =3D { 0 }; int ret; =20 + /* The KVM XIVE device is not in use */ + if (xive->fd =3D=3D -1) { + return; + } + ret =3D kvm_get_one_reg(tctx->cs, KVM_REG_PPC_VP_STATE, state); if (ret !=3D 0) { error_setg_errno(errp, errno, @@ -140,6 +146,11 @@ void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **e= rrp) unsigned long vcpu_id; int ret; =20 + /* The KVM XIVE device is not in use */ + if (xive->fd =3D=3D -1) { + return; + } + /* Check if CPU was hot unplugged and replugged. */ if (kvm_cpu_is_enabled(tctx->cs)) { return; @@ -316,9 +327,13 @@ static void kvmppc_xive_source_get_state(XiveSource *x= src) void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val) { XiveSource *xsrc =3D opaque; + SpaprXive *xive =3D SPAPR_XIVE(xsrc->xive); struct kvm_irq_level args; int rc; =20 + /* The KVM XIVE device should be in use */ + assert(xive->fd !=3D -1); + args.irq =3D srcno; if (!xive_source_irq_is_lsi(xsrc, srcno)) { if (!val) { @@ -544,6 +559,11 @@ static void kvmppc_xive_change_state_handler(void *opa= que, int running, =20 void kvmppc_xive_synchronize_state(SpaprXive *xive, Error **errp) { + /* The KVM XIVE device is not in use */ + if (xive->fd =3D=3D -1) { + return; + } + /* * When the VM is stopped, the sources are masked and the previous * state is saved in anticipation of a migration. We should not @@ -569,6 +589,11 @@ int kvmppc_xive_pre_save(SpaprXive *xive) { Error *local_err =3D NULL; =20 + /* The KVM XIVE device is not in use */ + if (xive->fd =3D=3D -1) { + return 0; + } + /* EAT: there is no extra state to query from KVM */ =20 /* ENDT */ @@ -593,6 +618,9 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_= id) CPUState *cs; int i; =20 + /* The KVM XIVE device should be in use */ + assert(xive->fd !=3D -1); + /* Restore the ENDT first. The targetting depends on it. */ for (i =3D 0; i < xive->nr_ends; i++) { if (!xive_end_is_valid(&xive->endt[i])) { diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 0e3b5f5fbfcd..b3a01326d261 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -69,6 +69,11 @@ void icp_get_kvm_state(ICPState *icp) uint64_t state; int ret; =20 + /* The KVM XICS device is not in use */ + if (kernel_xics_fd =3D=3D -1) { + return; + } + /* ICP for this CPU thread is not in use, exiting */ if (!icp->cs) { return; @@ -105,6 +110,11 @@ int icp_set_kvm_state(ICPState *icp) uint64_t state; int ret; =20 + /* The KVM XICS device is not in use */ + if (kernel_xics_fd =3D=3D -1) { + return 0; + } + /* ICP for this CPU thread is not in use, exiting */ if (!icp->cs) { return 0; @@ -133,8 +143,9 @@ void icp_kvm_realize(DeviceState *dev, Error **errp) unsigned long vcpu_id; int ret; =20 + /* The KVM XICS device is not in use */ if (kernel_xics_fd =3D=3D -1) { - abort(); + return; } =20 cs =3D icp->cs; @@ -170,6 +181,11 @@ void ics_get_kvm_state(ICSState *ics) uint64_t state; int i; =20 + /* The KVM XICS device is not in use */ + if (kernel_xics_fd =3D=3D -1) { + return; + } + for (i =3D 0; i < ics->nr_irqs; i++) { ICSIRQState *irq =3D &ics->irqs[i]; =20 @@ -230,6 +246,11 @@ int ics_set_kvm_state_one(ICSState *ics, int srcno) ICSIRQState *irq =3D &ics->irqs[srcno]; int ret; =20 + /* The KVM XICS device is not in use */ + if (kernel_xics_fd =3D=3D -1) { + return 0; + } + state =3D irq->server; state |=3D (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK) << KVM_XICS_PRIORITY_SHIFT; @@ -269,6 +290,11 @@ int ics_set_kvm_state(ICSState *ics) { int i; =20 + /* The KVM XICS device is not in use */ + if (kernel_xics_fd =3D=3D -1) { + return 0; + } + for (i =3D 0; i < ics->nr_irqs; i++) { int ret; =20 @@ -286,6 +312,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val) struct kvm_irq_level args; int rc; =20 + /* The KVM XICS device should be in use */ + assert(kernel_xics_fd !=3D -1); + args.irq =3D srcno + ics->offset; if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MSI) { if (!val) { --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180886099205.29364492604043; Thu, 21 Mar 2019 08:08:06 -0700 (PDT) Received: from localhost ([127.0.0.1]:39172 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6zIZ-0000vV-2C for importer@patchew.org; Thu, 21 Mar 2019 11:08:03 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44304) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1p-000484-2K for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1n-0001Qn-6y for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:44 -0400 Received: from 4.mo4.mail-out.ovh.net ([178.32.98.131]:48814) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1j-0001Fc-4u for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:41 -0400 Received: from player788.ha.ovh.net (unknown [10.109.146.143]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id 059881DFCD6 for ; Thu, 21 Mar 2019 15:50:35 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 717723E6B757; Thu, 21 Mar 2019 14:50:30 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:11 +0100 Message-Id: <20190321144914.19934-13-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11870081243285523430 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 178.32.98.131 Subject: [Qemu-devel] [PATCH v3 12/15] spapr/irq: remove spapr_ics_create() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" spapr_ics_create() is only called once. Merge it in spapr_irq_init_xics() and simplify a bit the error handling by using 'error_fatal' . Signed-off-by: C=C3=A9dric Le Goater --- hw/ppc/spapr_irq.c | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index b4e3128b7f06..d7130f66dbaa 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -66,36 +66,11 @@ void spapr_irq_msi_reset(SpaprMachineState *spapr) * XICS IRQ backend. */ =20 -static ICSState *spapr_ics_create(SpaprMachineState *spapr, - int nr_irqs, Error **errp) -{ - Error *local_err =3D NULL; - Object *obj; - - obj =3D object_new(TYPE_ICS_SIMPLE); - object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort); - object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr), - &error_abort); - object_property_set_int(obj, nr_irqs, "nr-irqs", &local_err); - if (local_err) { - goto error; - } - object_property_set_bool(obj, true, "realized", &local_err); - if (local_err) { - goto error; - } - - return ICS_BASE(obj); - -error: - error_propagate(errp, local_err); - return NULL; -} - static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs, Error **errp) { MachineState *machine =3D MACHINE(spapr); + Object *obj; Error *local_err =3D NULL; bool xics_kvm =3D false; =20 @@ -107,7 +82,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr= , int nr_irqs, if (machine_kernel_irqchip_required(machine) && !xics_kvm) { error_prepend(&local_err, "kernel_irqchip requested but unavailable: "); - goto error; + error_propagate(errp, local_err); + return; } error_free(local_err); local_err =3D NULL; @@ -117,10 +93,18 @@ static void spapr_irq_init_xics(SpaprMachineState *spa= pr, int nr_irqs, xics_spapr_init(spapr); } =20 - spapr->ics =3D spapr_ics_create(spapr, nr_irqs, &local_err); + obj =3D object_new(TYPE_ICS_SIMPLE); + object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort); + object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr), + &error_fatal); + object_property_set_int(obj, nr_irqs, "nr-irqs", &error_fatal); + object_property_set_bool(obj, true, "realized", &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } =20 -error: - error_propagate(errp, local_err); + spapr->ics =3D ICS_BASE(obj); } =20 #define ICS_IRQ_FREE(ics, srcno) \ --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553180542069684.2645955412822; Thu, 21 Mar 2019 08:02:22 -0700 (PDT) Received: from localhost ([127.0.0.1]:39060 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6zCw-00059e-Bt for importer@patchew.org; Thu, 21 Mar 2019 11:02:14 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44350) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1u-0004Df-Lc for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1q-0001W1-SE for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:49 -0400 Received: from 2.mo2.mail-out.ovh.net ([188.165.53.149]:35031) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1o-0001Oy-Vd for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:46 -0400 Received: from player788.ha.ovh.net (unknown [10.109.159.136]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 990A918C0B3 for ; Thu, 21 Mar 2019 15:50:41 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 0F4063E6B796; Thu, 21 Mar 2019 14:50:36 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:12 +0100 Message-Id: <20190321144914.19934-14-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11871770096308358118 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 188.165.53.149 Subject: [Qemu-devel] [PATCH v3 13/15] spapr/irq: introduce a spapr_irq_init_device() helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The way the XICS and the XIVE devices are initialized follows the same pattern. First, try to connect to the KVM device and if not possible fallback on the emulated device, unless a kernel_irqchip is required. The spapr_irq_init_device() routine implements this sequence in generic way using new sPAPR IRQ handlers ->init_emu() and ->init_kvm(). The XIVE init sequence is moved under the associated sPAPR IRQ ->init() handler. This will change again when KVM support is added for the dual interrupt mode. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- include/hw/ppc/spapr_irq.h | 2 + include/hw/ppc/spapr_xive.h | 1 + hw/intc/spapr_xive.c | 26 +++-------- hw/ppc/spapr_irq.c | 89 +++++++++++++++++++++++++++++-------- 4 files changed, 78 insertions(+), 40 deletions(-) diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index b855f74e4428..14cab73c9c07 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -48,6 +48,8 @@ typedef struct SpaprIrq { void (*reset)(SpaprMachineState *spapr, Error **errp); void (*set_irq)(void *opaque, int srcno, int val); const char *(*get_nodename)(SpaprMachineState *spapr); + void (*init_emu)(SpaprMachineState *spapr, Error **errp); + void (*init_kvm)(SpaprMachineState *spapr, Error **errp); } SpaprIrq; =20 extern SpaprIrq spapr_irq_xics; diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 0b5e972d52c8..b26befcf6b56 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -66,6 +66,7 @@ void spapr_xive_map_mmio(SpaprXive *xive); =20 int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx, uint32_t *out_server, uint8_t *out_prio); +void spapr_xive_init(SpaprXive *xive, Error **errp); =20 /* * KVM XIVE device helpers diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a3cbbdf7aff0..f889c89dc2e9 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -280,7 +280,6 @@ static void spapr_xive_realize(DeviceState *dev, Error = **errp) XiveSource *xsrc =3D &xive->source; XiveENDSource *end_xsrc =3D &xive->end_source; Error *local_err =3D NULL; - MachineState *machine =3D MACHINE(qdev_get_machine()); =20 if (!xive->nr_irqs) { error_setg(errp, "Number of interrupt needs to be greater 0"); @@ -331,27 +330,12 @@ static void spapr_xive_realize(DeviceState *dev, Erro= r **errp) xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SH= IFT)); =20 qemu_register_reset(spapr_xive_reset, dev); +} =20 - if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) { - kvmppc_xive_connect(xive, &local_err); - if (local_err && machine_kernel_irqchip_required(machine)) { - error_prepend(&local_err, - "kernel_irqchip requested but unavailable: "); - error_propagate(errp, local_err); - return; - } - - if (!local_err) { - return; - } - - /* - * We failed to initialize the XIVE KVM device, fallback to - * emulated mode - */ - error_prepend(&local_err, "kernel_irqchip allowed but unavailable:= "); - warn_report_err(local_err); - } +void spapr_xive_init(SpaprXive *xive, Error **errp) +{ + XiveSource *xsrc =3D &xive->source; + XiveENDSource *end_xsrc =3D &xive->end_source; =20 /* TIMA initialization */ memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive, diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index d7130f66dbaa..0c65de35f52a 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -61,36 +61,50 @@ void spapr_irq_msi_reset(SpaprMachineState *spapr) bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr); } =20 - -/* - * XICS IRQ backend. - */ - -static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs, - Error **errp) +static void spapr_irq_init_device(SpaprMachineState *spapr, + SpaprIrq *irq, Error **errp) { MachineState *machine =3D MACHINE(spapr); - Object *obj; Error *local_err =3D NULL; - bool xics_kvm =3D false; =20 - if (kvm_enabled()) { - if (machine_kernel_irqchip_allowed(machine) && - !xics_kvm_init(spapr, &local_err)) { - xics_kvm =3D true; - } - if (machine_kernel_irqchip_required(machine) && !xics_kvm) { + if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) { + irq->init_kvm(spapr, &local_err); + if (local_err && machine_kernel_irqchip_required(machine)) { error_prepend(&local_err, "kernel_irqchip requested but unavailable: "); error_propagate(errp, local_err); return; } - error_free(local_err); - local_err =3D NULL; + + if (!local_err) { + return; + } + + /* + * We failed to initialize the KVM device, fallback to + * emulated mode + */ + error_prepend(&local_err, "kernel_irqchip allowed but unavailable:= "); + warn_report_err(local_err); } =20 - if (!xics_kvm) { - xics_spapr_init(spapr); + irq->init_emu(spapr, errp); +} + +/* + * XICS IRQ backend. + */ + +static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs, + Error **errp) +{ + Object *obj; + Error *local_err =3D NULL; + + spapr_irq_init_device(spapr, &spapr_irq_xics, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; } =20 obj =3D object_new(TYPE_ICS_SIMPLE); @@ -219,6 +233,18 @@ static const char *spapr_irq_get_nodename_xics(SpaprMa= chineState *spapr) return XICS_NODENAME; } =20 +static void spapr_irq_init_emu_xics(SpaprMachineState *spapr, Error **errp) +{ + xics_spapr_init(spapr); +} + +static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp) +{ + if (kvm_enabled()) { + xics_kvm_init(spapr, errp); + } +} + #define SPAPR_IRQ_XICS_NR_IRQS 0x1000 #define SPAPR_IRQ_XICS_NR_MSIS \ (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI) @@ -239,6 +265,8 @@ SpaprIrq spapr_irq_xics =3D { .reset =3D spapr_irq_reset_xics, .set_irq =3D spapr_irq_set_irq_xics, .get_nodename =3D spapr_irq_get_nodename_xics, + .init_emu =3D spapr_irq_init_emu_xics, + .init_kvm =3D spapr_irq_init_kvm_xics, }; =20 /* @@ -250,6 +278,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spap= r, int nr_irqs, uint32_t nr_servers =3D spapr_max_server_number(spapr); DeviceState *dev; int i; + Error *local_err =3D NULL; =20 dev =3D qdev_create(NULL, TYPE_SPAPR_XIVE); qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs); @@ -267,6 +296,12 @@ static void spapr_irq_init_xive(SpaprMachineState *spa= pr, int nr_irqs, } =20 spapr_xive_hcall_init(spapr); + + spapr_irq_init_device(spapr, &spapr_irq_xive, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } } =20 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool ls= i, @@ -374,6 +409,18 @@ static const char *spapr_irq_get_nodename_xive(SpaprMa= chineState *spapr) return spapr->xive->nodename; } =20 +static void spapr_irq_init_emu_xive(SpaprMachineState *spapr, Error **errp) +{ + spapr_xive_init(spapr->xive, errp); +} + +static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp) +{ + if (kvm_enabled()) { + kvmppc_xive_connect(spapr->xive, errp); + } +} + /* * XIVE uses the full IRQ number space. Set it to 8K to be compatible * with XICS. @@ -398,6 +445,8 @@ SpaprIrq spapr_irq_xive =3D { .reset =3D spapr_irq_reset_xive, .set_irq =3D spapr_irq_set_irq_xive, .get_nodename =3D spapr_irq_get_nodename_xive, + .init_emu =3D spapr_irq_init_emu_xive, + .init_kvm =3D spapr_irq_init_kvm_xive, }; =20 /* @@ -559,6 +608,8 @@ SpaprIrq spapr_irq_dual =3D { .reset =3D spapr_irq_reset_dual, .set_irq =3D spapr_irq_set_irq_dual, .get_nodename =3D spapr_irq_get_nodename_dual, + .init_emu =3D NULL, /* should not be used */ + .init_kvm =3D NULL, /* should not be used */ }; =20 /* --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15531806953755.272569045747332; Thu, 21 Mar 2019 08:04:55 -0700 (PDT) Received: from localhost ([127.0.0.1]:39103 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6zFT-00074S-8C for importer@patchew.org; Thu, 21 Mar 2019 11:04:51 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44392) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z1w-0004Et-5V for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1v-0001a9-2A for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:52 -0400 Received: from 7.mo177.mail-out.ovh.net ([46.105.61.149]:59577) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1u-0001XS-KC for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:50 -0400 Received: from player788.ha.ovh.net (unknown [10.109.143.109]) by mo177.mail-out.ovh.net (Postfix) with ESMTP id B5E5BEC26C for ; Thu, 21 Mar 2019 15:50:47 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 9FBA53E6B80E; Thu, 21 Mar 2019 14:50:41 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:13 +0100 Message-Id: <20190321144914.19934-15-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11873458945262717926 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.61.149 Subject: [Qemu-devel] [PATCH v3 14/15] spapr/irq: initialize the IRQ device only once X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add a check to make sure that the routine initializing the emulated IRQ device is called once. We don't have much to test on the XICS side, so we introduce a 'static bool'. Not very elegant but works well enough. Signed-off-by: C=C3=A9dric Le Goater --- hw/intc/spapr_xive.c | 9 +++++++++ hw/intc/xics_spapr.c | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index f889c89dc2e9..15d41d9cd36d 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -337,6 +337,15 @@ void spapr_xive_init(SpaprXive *xive, Error **errp) XiveSource *xsrc =3D &xive->source; XiveENDSource *end_xsrc =3D &xive->end_source; =20 + /* + * The emulated XIVE device can only be initialized once. If the + * ESB memory region has been already mapped, it means we have been + * through there. + */ + if (memory_region_is_mapped(&xsrc->esb_mmio)) { + return; + } + /* TIMA initialization */ memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive, "xive.tima", 4ull << TM_SHIFT); diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 9d2b8adef7c5..67e82f3720b0 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -239,6 +239,16 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineS= tate *spapr, =20 void xics_spapr_init(SpaprMachineState *spapr) { + static bool init_done; + + /* + * Emulated mode can only be initialized once. + */ + if (init_done) { + return; + } + init_done =3D true; + /* Registration of global state belongs into realize */ spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive); spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive); --=20 2.20.1 From nobody Fri May 17 13:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553181012868971.8995889696298; Thu, 21 Mar 2019 08:10:12 -0700 (PDT) Received: from localhost ([127.0.0.1]:39210 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6zKU-0002Mj-Cb for importer@patchew.org; Thu, 21 Mar 2019 11:10:02 -0400 Received: from eggs.gnu.org ([209.51.188.92]:44425) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h6z20-0004GV-LD for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h6z1y-0001gD-TS for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:56 -0400 Received: from 6.mo173.mail-out.ovh.net ([46.105.43.93]:55499) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h6z1y-0001e5-H2 for qemu-devel@nongnu.org; Thu, 21 Mar 2019 10:50:54 -0400 Received: from player788.ha.ovh.net (unknown [10.109.146.19]) by mo173.mail-out.ovh.net (Postfix) with ESMTP id 379B1FADAD for ; Thu, 21 Mar 2019 15:50:53 +0100 (CET) Received: from kaod.org (deibp9eh1--blueice1n0.emea.ibm.com [195.212.29.162]) (Authenticated sender: clg@kaod.org) by player788.ha.ovh.net (Postfix) with ESMTPSA id 9B31D3E6B919; Thu, 21 Mar 2019 14:50:47 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 21 Mar 2019 15:49:14 +0100 Message-Id: <20190321144914.19934-16-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321144914.19934-1-clg@kaod.org> References: <20190321144914.19934-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11875147795785026534 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrieelgdehhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.43.93 Subject: [Qemu-devel] [PATCH v3 15/15] spapr/irq: add KVM support to the 'dual' machine X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-ppc@nongnu.org, Greg Kurz , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The interrupt mode is chosen by the CAS negotiation process and activated after a reset to take into account the required changes in the machine. This brings new constraints on how the associated KVM IRQ device is initialized. Currently, each model takes care of the initialization of the KVM device in their realize method but this is not possible anymore as the initialization needs to be done globaly when the interrupt mode is known, i.e. when machine is reseted. It also means that we need a way to delete a KVM device when another mode is chosen. Also, to support migration, the QEMU objects holding the state to transfer should always be available but not necessarily activated. The overall approach of this proposal is to initialize both interrupt mode at the QEMU level to keep the IRQ number space in sync and to allow switching from one mode to another. For the KVM side of things, the whole initialization of the KVM device, sources and presenters, is grouped in a single routine. The XICS and XIVE sPAPR IRQ reset handlers are modified accordingly to handle the init and the delete sequences of the KVM device. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson --- Changes since v2: - introduced the use of spapr_irq_init_device()=20 include/hw/ppc/xive.h | 1 - hw/intc/spapr_xive_kvm.c | 29 ++++++++++++++++++++++- hw/intc/xics_kvm.c | 26 ++++++++++++++++++++ hw/intc/xive.c | 4 ---- hw/ppc/spapr_irq.c | 51 ++++++++++++++++++++++++++++++---------- 5 files changed, 92 insertions(+), 19 deletions(-) diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index edb8937f17fb..d872f96d1a1b 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -432,7 +432,6 @@ static inline uint32_t xive_nvt_cam_line(uint8_t nvt_bl= k, uint32_t nvt_idx) */ =20 void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **err= p); -void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp); void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val); void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp); void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp); diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 78d2ea433c98..5577a88bf10f 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -238,7 +238,7 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int= srcno, Error **errp) true, errp); } =20 -void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp) +static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp) { int i; =20 @@ -690,6 +690,15 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp) Error *local_err =3D NULL; size_t esb_len =3D (1ull << xsrc->esb_shift) * xsrc->nr_irqs; size_t tima_len =3D 4ull << TM_SHIFT; + CPUState *cs; + + /* + * The KVM XIVE device already in use. This is the case when + * rebooting under the XIVE-only interrupt mode. + */ + if (xive->fd !=3D -1) { + return; + } =20 if (!kvmppc_has_cap_xive()) { error_setg(errp, "IRQ_XIVE capability must be present for KVM"); @@ -738,6 +747,24 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp) xive->change =3D qemu_add_vm_change_state_handler( kvmppc_xive_change_state_handler, xive); =20 + /* Connect the presenters to the initial VCPUs of the machine */ + CPU_FOREACH(cs) { + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + + kvmppc_xive_cpu_connect(spapr_cpu_state(cpu)->tctx, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } + + /* Update the KVM sources */ + kvmppc_xive_source_reset(xsrc, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + kvm_kernel_irqchip =3D true; kvm_msi_via_irqfd_allowed =3D true; kvm_gsi_direct_mapping =3D true; diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index b3a01326d261..b33d1f2f789e 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -33,6 +33,7 @@ #include "trace.h" #include "sysemu/kvm.h" #include "hw/ppc/spapr.h" +#include "hw/ppc/spapr_cpu_core.h" #include "hw/ppc/xics.h" #include "hw/ppc/xics_spapr.h" #include "kvm_ppc.h" @@ -342,6 +343,16 @@ static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineSt= ate *spapr, int xics_kvm_init(SpaprMachineState *spapr, Error **errp) { int rc; + CPUState *cs; + Error *local_err =3D NULL; + + /* + * The KVM XICS device already in use. This is the case when + * rebooting under the XICS-only interrupt mode. + */ + if (kernel_xics_fd !=3D -1) { + return 0; + } =20 if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS= )) { error_setg(errp, @@ -390,6 +401,21 @@ int xics_kvm_init(SpaprMachineState *spapr, Error **er= rp) kvm_msi_via_irqfd_allowed =3D true; kvm_gsi_direct_mapping =3D true; =20 + /* Connect the presenters to the initial VCPUs of the machine */ + CPU_FOREACH(cs) { + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + + icp_kvm_realize(DEVICE(spapr_cpu_state(cpu)->icp), &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto fail; + } + icp_set_kvm_state(spapr_cpu_state(cpu)->icp); + } + + /* Update the KVM sources */ + ics_set_kvm_state(spapr->ics); + return 0; =20 fail: diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 901689b0f015..1909c0dec5b2 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -993,10 +993,6 @@ static void xive_source_reset(void *dev) =20 /* PQs are initialized to 0b01 (Q=3D1) which corresponds to "ints off"= */ memset(xsrc->status, XIVE_ESB_OFF, xsrc->nr_irqs); - - if (kvm_irqchip_in_kernel()) { - kvmppc_xive_source_reset(xsrc, &error_fatal); - } } =20 static void xive_source_realize(DeviceState *dev, Error **errp) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 0c65de35f52a..170c0bbb025e 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -101,12 +101,6 @@ static void spapr_irq_init_xics(SpaprMachineState *spa= pr, int nr_irqs, Object *obj; Error *local_err =3D NULL; =20 - spapr_irq_init_device(spapr, &spapr_irq_xics, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - obj =3D object_new(TYPE_ICS_SIMPLE); object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort); object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr), @@ -225,7 +219,13 @@ static void spapr_irq_set_irq_xics(void *opaque, int s= rcno, int val) =20 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp) { - /* TODO: create the KVM XICS device */ + Error *local_err =3D NULL; + + spapr_irq_init_device(spapr, &spapr_irq_xics, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } } =20 static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr) @@ -381,6 +381,7 @@ static int spapr_irq_post_load_xive(SpaprMachineState *= spapr, int version_id) static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) { CPUState *cs; + Error *local_err =3D NULL; =20 CPU_FOREACH(cs) { PowerPCCPU *cpu =3D POWERPC_CPU(cs); @@ -389,6 +390,12 @@ static void spapr_irq_reset_xive(SpaprMachineState *sp= apr, Error **errp) spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); } =20 + spapr_irq_init_device(spapr, &spapr_irq_xive, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + /* Activate the XIVE MMIOs */ spapr_xive_mmio_set_enabled(spapr->xive, true); } @@ -471,14 +478,8 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *= spapr) static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs, Error **errp) { - MachineState *machine =3D MACHINE(spapr); Error *local_err =3D NULL; =20 - if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) { - error_setg(errp, "No KVM support for the 'dual' machine"); - return; - } - spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -557,6 +558,9 @@ static int spapr_irq_post_load_dual(SpaprMachineState *= spapr, int version_id) * defaults to XICS at startup. */ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + if (kvm_irqchip_in_kernel()) { + xics_kvm_disconnect(spapr, &error_fatal); + } spapr_irq_xive.reset(spapr, &error_fatal); } =20 @@ -565,12 +569,30 @@ static int spapr_irq_post_load_dual(SpaprMachineState= *spapr, int version_id) =20 static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp) { + Error *local_err =3D NULL; + /* * Deactivate the XIVE MMIOs. The XIVE backend will reenable them * if selected. */ spapr_xive_mmio_set_enabled(spapr->xive, false); =20 + /* Destroy all KVM devices */ + if (kvm_irqchip_in_kernel()) { + xics_kvm_disconnect(spapr, &local_err); + if (local_err) { + error_propagate(errp, local_err); + error_prepend(errp, "KVM XICS disconnect failed: "); + return; + } + kvmppc_xive_disconnect(spapr->xive, &local_err); + if (local_err) { + error_propagate(errp, local_err); + error_prepend(errp, "KVM XIVE disconnect failed: "); + return; + } + } + spapr_irq_current(spapr)->reset(spapr, errp); } =20 @@ -759,6 +781,9 @@ SpaprIrq spapr_irq_xics_legacy =3D { .dt_populate =3D spapr_dt_xics, .cpu_intc_create =3D spapr_irq_cpu_intc_create_xics, .post_load =3D spapr_irq_post_load_xics, + .reset =3D spapr_irq_reset_xics, .set_irq =3D spapr_irq_set_irq_xics, .get_nodename =3D spapr_irq_get_nodename_xics, + .init_emu =3D spapr_irq_init_emu_xics, + .init_kvm =3D spapr_irq_init_kvm_xics, }; --=20 2.20.1