From patchwork Mon Jan 7 18:43:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751119 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ABA626C5 for ; Mon, 7 Jan 2019 19:02:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E3AB289B2 for ; Mon, 7 Jan 2019 19:02:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92A96289B4; Mon, 7 Jan 2019 19:02:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 18752289B2 for ; Mon, 7 Jan 2019 19:02:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727730AbfAGTCf (ORCPT ); Mon, 7 Jan 2019 14:02:35 -0500 Received: from 9.mo69.mail-out.ovh.net ([46.105.56.78]:48133 "EHLO 9.mo69.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726638AbfAGTCe (ORCPT ); Mon, 7 Jan 2019 14:02:34 -0500 X-Greylist: delayed 1107 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:02:33 EST Received: from player737.ha.ovh.net (unknown [10.109.143.223]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id AA1A437904 for ; Mon, 7 Jan 2019 19:44:04 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 4920B186630A; Mon, 7 Jan 2019 18:43:53 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 01/19] powerpc/xive: export flags for the XIVE native exploitation mode hcalls Date: Mon, 7 Jan 2019 19:43:13 +0100 Message-Id: <20190107184331.8429-2-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11381722159073364951 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP These flags are shared between Linux/KVM implementing the hypervisor calls for the XIVE native exploitation mode and the driver for the sPAPR guests. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson --- arch/powerpc/include/asm/xive.h | 23 +++++++++++++++++++++++ arch/powerpc/sysdev/xive/spapr.c | 28 ++++++++-------------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index 3c704f5dd3ae..32f033bfbf42 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -93,6 +93,29 @@ extern void xive_flush_interrupt(void); /* xmon hook */ extern void xmon_xive_do_dump(int cpu); +/* + * Hcall flags shared by the sPAPR backend and KVM + */ + +/* H_INT_GET_SOURCE_INFO */ +#define XIVE_SPAPR_SRC_H_INT_ESB PPC_BIT(60) +#define XIVE_SPAPR_SRC_LSI PPC_BIT(61) +#define XIVE_SPAPR_SRC_TRIGGER PPC_BIT(62) +#define XIVE_SPAPR_SRC_STORE_EOI PPC_BIT(63) + +/* H_INT_SET_SOURCE_CONFIG */ +#define XIVE_SPAPR_SRC_SET_EISN PPC_BIT(62) +#define XIVE_SPAPR_SRC_MASK PPC_BIT(63) /* unused */ + +/* H_INT_SET_QUEUE_CONFIG */ +#define XIVE_SPAPR_EQ_ALWAYS_NOTIFY PPC_BIT(63) + +/* H_INT_SET_QUEUE_CONFIG */ +#define XIVE_SPAPR_EQ_DEBUG PPC_BIT(63) + +/* H_INT_ESB */ +#define XIVE_SPAPR_ESB_STORE PPC_BIT(63) + /* APIs used by KVM */ extern u32 xive_native_default_eq_shift(void); extern u32 xive_native_alloc_vp_block(u32 max_vcpus); diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 575db3b06a6b..730284f838c8 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -184,9 +184,6 @@ static long plpar_int_get_source_info(unsigned long flags, return 0; } -#define XIVE_SRC_SET_EISN (1ull << (63 - 62)) -#define XIVE_SRC_MASK (1ull << (63 - 63)) /* unused */ - static long plpar_int_set_source_config(unsigned long flags, unsigned long lisn, unsigned long target, @@ -243,8 +240,6 @@ static long plpar_int_get_queue_info(unsigned long flags, return 0; } -#define XIVE_EQ_ALWAYS_NOTIFY (1ull << (63 - 63)) - static long plpar_int_set_queue_config(unsigned long flags, unsigned long target, unsigned long priority, @@ -286,8 +281,6 @@ static long plpar_int_sync(unsigned long flags, unsigned long lisn) return 0; } -#define XIVE_ESB_FLAG_STORE (1ull << (63 - 63)) - static long plpar_int_esb(unsigned long flags, unsigned long lisn, unsigned long offset, @@ -321,7 +314,7 @@ static u64 xive_spapr_esb_rw(u32 lisn, u32 offset, u64 data, bool write) unsigned long read_data; long rc; - rc = plpar_int_esb(write ? XIVE_ESB_FLAG_STORE : 0, + rc = plpar_int_esb(write ? XIVE_SPAPR_ESB_STORE : 0, lisn, offset, data, &read_data); if (rc) return -1; @@ -329,11 +322,6 @@ static u64 xive_spapr_esb_rw(u32 lisn, u32 offset, u64 data, bool write) return write ? 0 : read_data; } -#define XIVE_SRC_H_INT_ESB (1ull << (63 - 60)) -#define XIVE_SRC_LSI (1ull << (63 - 61)) -#define XIVE_SRC_TRIGGER (1ull << (63 - 62)) -#define XIVE_SRC_STORE_EOI (1ull << (63 - 63)) - static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) { long rc; @@ -349,11 +337,11 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) if (rc) return -EINVAL; - if (flags & XIVE_SRC_H_INT_ESB) + if (flags & XIVE_SPAPR_SRC_H_INT_ESB) data->flags |= XIVE_IRQ_FLAG_H_INT_ESB; - if (flags & XIVE_SRC_STORE_EOI) + if (flags & XIVE_SPAPR_SRC_STORE_EOI) data->flags |= XIVE_IRQ_FLAG_STORE_EOI; - if (flags & XIVE_SRC_LSI) + if (flags & XIVE_SPAPR_SRC_LSI) data->flags |= XIVE_IRQ_FLAG_LSI; data->eoi_page = eoi_page; data->esb_shift = esb_shift; @@ -374,7 +362,7 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) data->hw_irq = hw_irq; /* Full function page supports trigger */ - if (flags & XIVE_SRC_TRIGGER) { + if (flags & XIVE_SPAPR_SRC_TRIGGER) { data->trig_mmio = data->eoi_mmio; return 0; } @@ -391,8 +379,8 @@ static int xive_spapr_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq) { long rc; - rc = plpar_int_set_source_config(XIVE_SRC_SET_EISN, hw_irq, target, - prio, sw_irq); + rc = plpar_int_set_source_config(XIVE_SPAPR_SRC_SET_EISN, hw_irq, + target, prio, sw_irq); return rc == 0 ? 0 : -ENXIO; } @@ -432,7 +420,7 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio, q->eoi_phys = esn_page; /* Default is to always notify */ - flags = XIVE_EQ_ALWAYS_NOTIFY; + flags = XIVE_SPAPR_EQ_ALWAYS_NOTIFY; /* Configure and enable the queue in HW */ rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); From patchwork Mon Jan 7 18:43:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751111 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DDA066C5 for ; Mon, 7 Jan 2019 19:01:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CEE6D289B2 for ; Mon, 7 Jan 2019 19:01:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BFFDA289B1; Mon, 7 Jan 2019 19:01:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F054289B1 for ; Mon, 7 Jan 2019 19:01:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727875AbfAGTBn (ORCPT ); Mon, 7 Jan 2019 14:01:43 -0500 Received: from 20.mo7.mail-out.ovh.net ([46.105.49.208]:39896 "EHLO 20.mo7.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727286AbfAGTBn (ORCPT ); Mon, 7 Jan 2019 14:01:43 -0500 X-Greylist: delayed 1067 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:01:41 EST Received: from player737.ha.ovh.net (unknown [10.109.160.226]) by mo7.mail-out.ovh.net (Postfix) with ESMTP id 1CE04F2A13 for ; Mon, 7 Jan 2019 19:44:15 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 72FA01866325; Mon, 7 Jan 2019 18:44:04 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 02/19] powerpc/xive: add OPAL extensions for the XIVE native exploitation support Date: Mon, 7 Jan 2019 19:43:14 +0100 Message-Id: <20190107184331.8429-3-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11384818386161732567 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The support for XIVE native exploitation mode in Linux/KVM needs a couple more OPAL calls to configure the sPAPR guest and to get/set the state of the XIVE internal structures. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson --- arch/powerpc/include/asm/opal-api.h | 11 ++- arch/powerpc/include/asm/opal.h | 7 ++ arch/powerpc/include/asm/xive.h | 14 +++ arch/powerpc/sysdev/xive/native.c | 99 +++++++++++++++++++ .../powerpc/platforms/powernv/opal-wrappers.S | 3 + 5 files changed, 130 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 870fb7b239ea..cdfc54f78101 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -186,8 +186,8 @@ #define OPAL_XIVE_FREE_IRQ 140 #define OPAL_XIVE_SYNC 141 #define OPAL_XIVE_DUMP 142 -#define OPAL_XIVE_RESERVED3 143 -#define OPAL_XIVE_RESERVED4 144 +#define OPAL_XIVE_GET_QUEUE_STATE 143 +#define OPAL_XIVE_SET_QUEUE_STATE 144 #define OPAL_SIGNAL_SYSTEM_RESET 145 #define OPAL_NPU_INIT_CONTEXT 146 #define OPAL_NPU_DESTROY_CONTEXT 147 @@ -209,8 +209,11 @@ #define OPAL_SENSOR_GROUP_ENABLE 163 #define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164 #define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165 -#define OPAL_NX_COPROC_INIT 167 -#define OPAL_LAST 167 +#define OPAL_HANDLE_HMI2 166 +#define OPAL_NX_COPROC_INIT 167 +#define OPAL_NPU_SET_RELAXED_ORDER 168 +#define OPAL_NPU_GET_RELAXED_ORDER 169 +#define OPAL_XIVE_GET_VP_STATE 170 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a55b01c90bb1..4e978d4dea5c 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -279,6 +279,13 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id); int64_t opal_xive_free_irq(uint32_t girq); int64_t opal_xive_sync(uint32_t type, uint32_t id); int64_t opal_xive_dump(uint32_t type, uint32_t id); +int64_t opal_xive_get_queue_state(uint64_t vp, uint32_t prio, + __be32 *out_qtoggle, + __be32 *out_qindex); +int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio, + uint32_t qtoggle, + uint32_t qindex); +int64_t opal_xive_get_vp_state(uint64_t vp, __be64 *out_w01); int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target, uint64_t desc, uint16_t pe_number); diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index 32f033bfbf42..d6be3e4d9fa4 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -132,12 +132,26 @@ extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio, extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio); extern void xive_native_sync_source(u32 hw_irq); +extern void xive_native_sync_queue(u32 hw_irq); extern bool is_xive_irq(struct irq_chip *chip); extern int xive_native_enable_vp(u32 vp_id, bool single_escalation); extern int xive_native_disable_vp(u32 vp_id); extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id); extern bool xive_native_has_single_escalation(void); +extern int xive_native_get_queue_info(u32 vp_id, uint32_t prio, + u64 *out_qpage, + u64 *out_qsize, + u64 *out_qeoi_page, + u32 *out_escalate_irq, + u64 *out_qflags); + +extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle, + u32 *qindex); +extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle, + u32 qindex); +extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state); + #else static inline bool xive_enabled(void) { return false; } diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 1ca127d052a6..0c037e933e55 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -437,6 +437,12 @@ void xive_native_sync_source(u32 hw_irq) } EXPORT_SYMBOL_GPL(xive_native_sync_source); +void xive_native_sync_queue(u32 hw_irq) +{ + opal_xive_sync(XIVE_SYNC_QUEUE, hw_irq); +} +EXPORT_SYMBOL_GPL(xive_native_sync_queue); + static const struct xive_ops xive_native_ops = { .populate_irq_data = xive_native_populate_irq_data, .configure_irq = xive_native_configure_irq, @@ -711,3 +717,96 @@ bool xive_native_has_single_escalation(void) return xive_has_single_esc; } EXPORT_SYMBOL_GPL(xive_native_has_single_escalation); + +int xive_native_get_queue_info(u32 vp_id, u32 prio, + u64 *out_qpage, + u64 *out_qsize, + u64 *out_qeoi_page, + u32 *out_escalate_irq, + u64 *out_qflags) +{ + __be64 qpage; + __be64 qsize; + __be64 qeoi_page; + __be32 escalate_irq; + __be64 qflags; + s64 rc; + + rc = opal_xive_get_queue_info(vp_id, prio, &qpage, &qsize, + &qeoi_page, &escalate_irq, &qflags); + if (rc) { + pr_err("OPAL failed to get queue info for VCPU %d/%d : %lld\n", + vp_id, prio, rc); + return -EIO; + } + + if (out_qpage) + *out_qpage = be64_to_cpu(qpage); + if (out_qsize) + *out_qsize = be32_to_cpu(qsize); + if (out_qeoi_page) + *out_qeoi_page = be64_to_cpu(qeoi_page); + if (out_escalate_irq) + *out_escalate_irq = be32_to_cpu(escalate_irq); + if (out_qflags) + *out_qflags = be64_to_cpu(qflags); + + return 0; +} +EXPORT_SYMBOL_GPL(xive_native_get_queue_info); + +int xive_native_get_queue_state(u32 vp_id, u32 prio, u32 *qtoggle, u32 *qindex) +{ + __be32 opal_qtoggle; + __be32 opal_qindex; + s64 rc; + + rc = opal_xive_get_queue_state(vp_id, prio, &opal_qtoggle, + &opal_qindex); + if (rc) { + pr_err("OPAL failed to get queue state for VCPU %d/%d : %lld\n", + vp_id, prio, rc); + return -EIO; + } + + if (qtoggle) + *qtoggle = be32_to_cpu(opal_qtoggle); + if (qindex) + *qindex = be32_to_cpu(opal_qindex); + + return 0; +} +EXPORT_SYMBOL_GPL(xive_native_get_queue_state); + +int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex) +{ + s64 rc; + + rc = opal_xive_set_queue_state(vp_id, prio, qtoggle, qindex); + if (rc) { + pr_err("OPAL failed to set queue state for VCPU %d/%d : %lld\n", + vp_id, prio, rc); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(xive_native_set_queue_state); + +int xive_native_get_vp_state(u32 vp_id, u64 *out_state) +{ + __be64 state; + s64 rc; + + rc = opal_xive_get_vp_state(vp_id, &state); + if (rc) { + pr_err("OPAL failed to get vp state for VCPU %d : %lld\n", + vp_id, rc); + return -EIO; + } + + if (out_state) + *out_state = be64_to_cpu(state); + return 0; +} +EXPORT_SYMBOL_GPL(xive_native_get_vp_state); diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index f4875fe3f8ff..3179953d6b56 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -309,6 +309,9 @@ OPAL_CALL(opal_xive_get_vp_info, OPAL_XIVE_GET_VP_INFO); OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO); OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC); OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); +OPAL_CALL(opal_xive_get_queue_state, OPAL_XIVE_GET_QUEUE_STATE); +OPAL_CALL(opal_xive_set_queue_state, OPAL_XIVE_SET_QUEUE_STATE); +OPAL_CALL(opal_xive_get_vp_state, OPAL_XIVE_GET_VP_STATE); OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET); OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT); From patchwork Mon Jan 7 18:43:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751139 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 04DAB1399 for ; Mon, 7 Jan 2019 19:22:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9AA1289AB for ; Mon, 7 Jan 2019 19:22:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DC134289BF; Mon, 7 Jan 2019 19:22:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86351289AB for ; Mon, 7 Jan 2019 19:22:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727572AbfAGTWI (ORCPT ); Mon, 7 Jan 2019 14:22:08 -0500 Received: from 14.mo4.mail-out.ovh.net ([46.105.40.29]:60025 "EHLO 14.mo4.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727369AbfAGTWI (ORCPT ); Mon, 7 Jan 2019 14:22:08 -0500 X-Greylist: delayed 2227 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:22:07 EST Received: from player737.ha.ovh.net (unknown [10.109.146.1]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id E21C81C7F84 for ; Mon, 7 Jan 2019 19:44:24 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id ED14C1866364; Mon, 7 Jan 2019 18:44:15 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 03/19] KVM: PPC: Book3S HV: check the IRQ controller type Date: Mon, 7 Jan 2019 19:43:15 +0100 Message-Id: <20190107184331.8429-4-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11387351660839013335 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We will have different KVM devices for interrupts, one for the XICS-over-XIVE mode and one for the XIVE native exploitation mode. Let's add some checks to make sure we are not mixing the interfaces in KVM. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson --- arch/powerpc/kvm/book3s_xive.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index f78d002f0fe0..8a4fa45f07f8 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -819,6 +819,9 @@ u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + if (!kvmppc_xics_enabled(vcpu)) + return -EPERM; + if (!xc) return 0; @@ -835,6 +838,9 @@ int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) u8 cppr, mfrr; u32 xisr; + if (!kvmppc_xics_enabled(vcpu)) + return -EPERM; + if (!xc || !xive) return -ENOENT; From patchwork Mon Jan 7 18:43:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751121 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 412006C5 for ; Mon, 7 Jan 2019 19:02:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3218B289B2 for ; Mon, 7 Jan 2019 19:02:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2689E289B4; Mon, 7 Jan 2019 19:02:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BD99289B2 for ; Mon, 7 Jan 2019 19:02:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728312AbfAGTCj (ORCPT ); Mon, 7 Jan 2019 14:02:39 -0500 Received: from 2.mo69.mail-out.ovh.net ([178.33.251.80]:52172 "EHLO 2.mo69.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727734AbfAGTCg (ORCPT ); Mon, 7 Jan 2019 14:02:36 -0500 X-Greylist: delayed 603 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:02:35 EST Received: from player737.ha.ovh.net (unknown [10.109.160.244]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id E036038C32 for ; Mon, 7 Jan 2019 19:44:35 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id E73291866383; Mon, 7 Jan 2019 18:44:24 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 04/19] KVM: PPC: Book3S HV: export services for the XIVE native exploitation device Date: Mon, 7 Jan 2019 19:43:16 +0100 Message-Id: <20190107184331.8429-5-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11390447883591388119 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The KVM device for the XIVE native exploitation mode will reuse the structures of the XICS-over-XIVE glue implementation. Some code will also be shared : source block creation and destruction, target selection and escalation attachment. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson --- arch/powerpc/kvm/book3s_xive.h | 11 +++++ arch/powerpc/kvm/book3s_xive.c | 89 +++++++++++++++++++--------------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index a08ae6fd4c51..10c4aa5cd010 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -248,5 +248,16 @@ extern int (*__xive_vm_h_ipi)(struct kvm_vcpu *vcpu, unsigned long server, extern int (*__xive_vm_h_cppr)(struct kvm_vcpu *vcpu, unsigned long cppr); extern int (*__xive_vm_h_eoi)(struct kvm_vcpu *vcpu, unsigned long xirr); +/* + * Common Xive routines for XICS-over-XIVE and XIVE native + */ +struct kvmppc_xive_src_block *kvmppc_xive_create_src_block( + struct kvmppc_xive *xive, int irq); +void kvmppc_xive_free_sources(struct kvmppc_xive_src_block *sb); +int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio); +void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu); +int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio); +int kvmppc_xive_debug_show_queues(struct seq_file *m, struct kvm_vcpu *vcpu); + #endif /* CONFIG_KVM_XICS */ #endif /* _KVM_PPC_BOOK3S_XICS_H */ diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 8a4fa45f07f8..bb5d32f7e4e6 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -166,7 +166,7 @@ static irqreturn_t xive_esc_irq(int irq, void *data) return IRQ_HANDLED; } -static int xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio) +int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; struct xive_q *q = &xc->queues[prio]; @@ -291,7 +291,7 @@ static int xive_check_provisioning(struct kvm *kvm, u8 prio) continue; rc = xive_provision_queue(vcpu, prio); if (rc == 0 && !xive->single_escalation) - xive_attach_escalation(vcpu, prio); + kvmppc_xive_attach_escalation(vcpu, prio); if (rc) return rc; } @@ -342,7 +342,7 @@ static int xive_try_pick_queue(struct kvm_vcpu *vcpu, u8 prio) return atomic_add_unless(&q->count, 1, max) ? 0 : -EBUSY; } -static int xive_select_target(struct kvm *kvm, u32 *server, u8 prio) +int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio) { struct kvm_vcpu *vcpu; int i, rc; @@ -535,7 +535,7 @@ static int xive_target_interrupt(struct kvm *kvm, * priority. The count for that new target will have * already been incremented. */ - rc = xive_select_target(kvm, &server, prio); + rc = kvmppc_xive_select_target(kvm, &server, prio); /* * We failed to find a target ? Not much we can do @@ -1055,7 +1055,7 @@ int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq, } EXPORT_SYMBOL_GPL(kvmppc_xive_clr_mapped); -static void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu) +void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; struct kvm *kvm = vcpu->kvm; @@ -1225,7 +1225,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, if (xive->qmap & (1 << i)) { r = xive_provision_queue(vcpu, i); if (r == 0 && !xive->single_escalation) - xive_attach_escalation(vcpu, i); + kvmppc_xive_attach_escalation(vcpu, i); if (r) goto bail; } else { @@ -1240,7 +1240,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, } /* If not done above, attach priority 0 escalation */ - r = xive_attach_escalation(vcpu, 0); + r = kvmppc_xive_attach_escalation(vcpu, 0); if (r) goto bail; @@ -1491,8 +1491,8 @@ static int xive_get_source(struct kvmppc_xive *xive, long irq, u64 addr) return 0; } -static struct kvmppc_xive_src_block *xive_create_src_block(struct kvmppc_xive *xive, - int irq) +struct kvmppc_xive_src_block *kvmppc_xive_create_src_block( + struct kvmppc_xive *xive, int irq) { struct kvm *kvm = xive->kvm; struct kvmppc_xive_src_block *sb; @@ -1571,7 +1571,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) sb = kvmppc_xive_find_source(xive, irq, &idx); if (!sb) { pr_devel("No source, creating source block...\n"); - sb = xive_create_src_block(xive, irq); + sb = kvmppc_xive_create_src_block(xive, irq); if (!sb) { pr_devel("Failed to create block...\n"); return -ENOMEM; @@ -1795,7 +1795,7 @@ static void kvmppc_xive_cleanup_irq(u32 hw_num, struct xive_irq_data *xd) xive_cleanup_irq_data(xd); } -static void kvmppc_xive_free_sources(struct kvmppc_xive_src_block *sb) +void kvmppc_xive_free_sources(struct kvmppc_xive_src_block *sb) { int i; @@ -1824,6 +1824,8 @@ static void kvmppc_xive_free(struct kvm_device *dev) debugfs_remove(xive->dentry); + pr_devel("Destroying xive for partition\n"); + if (kvm) kvm->arch.xive = NULL; @@ -1889,6 +1891,43 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type) return 0; } +int kvmppc_xive_debug_show_queues(struct seq_file *m, struct kvm_vcpu *vcpu) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + unsigned int i; + + for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) { + struct xive_q *q = &xc->queues[i]; + u32 i0, i1, idx; + + if (!q->qpage && !xc->esc_virq[i]) + continue; + + seq_printf(m, " [q%d]: ", i); + + if (q->qpage) { + idx = q->idx; + i0 = be32_to_cpup(q->qpage + idx); + idx = (idx + 1) & q->msk; + i1 = be32_to_cpup(q->qpage + idx); + seq_printf(m, "T=%d %08x %08x...\n", q->toggle, + i0, i1); + } + if (xc->esc_virq[i]) { + struct irq_data *d = irq_get_irq_data(xc->esc_virq[i]); + struct xive_irq_data *xd = + irq_data_get_irq_handler_data(d); + u64 pq = xive_vm_esb_load(xd, XIVE_ESB_GET); + + seq_printf(m, "E:%c%c I(%d:%llx:%llx)", + (pq & XIVE_ESB_VAL_P) ? 'P' : 'p', + (pq & XIVE_ESB_VAL_Q) ? 'Q' : 'q', + xc->esc_virq[i], pq, xd->eoi_page); + seq_puts(m, "\n"); + } + } + return 0; +} static int xive_debug_show(struct seq_file *m, void *private) { @@ -1914,7 +1953,6 @@ static int xive_debug_show(struct seq_file *m, void *private) kvm_for_each_vcpu(i, vcpu, kvm) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; - unsigned int i; if (!xc) continue; @@ -1924,33 +1962,8 @@ static int xive_debug_show(struct seq_file *m, void *private) xc->server_num, xc->cppr, xc->hw_cppr, xc->mfrr, xc->pending, xc->stat_rm_h_xirr, xc->stat_vm_h_xirr); - for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) { - struct xive_q *q = &xc->queues[i]; - u32 i0, i1, idx; - if (!q->qpage && !xc->esc_virq[i]) - continue; - - seq_printf(m, " [q%d]: ", i); - - if (q->qpage) { - idx = q->idx; - i0 = be32_to_cpup(q->qpage + idx); - idx = (idx + 1) & q->msk; - i1 = be32_to_cpup(q->qpage + idx); - seq_printf(m, "T=%d %08x %08x... \n", q->toggle, i0, i1); - } - if (xc->esc_virq[i]) { - struct irq_data *d = irq_get_irq_data(xc->esc_virq[i]); - struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); - u64 pq = xive_vm_esb_load(xd, XIVE_ESB_GET); - seq_printf(m, "E:%c%c I(%d:%llx:%llx)", - (pq & XIVE_ESB_VAL_P) ? 'P' : 'p', - (pq & XIVE_ESB_VAL_Q) ? 'Q' : 'q', - xc->esc_virq[i], pq, xd->eoi_page); - seq_printf(m, "\n"); - } - } + kvmppc_xive_debug_show_queues(m, vcpu); t_rm_h_xirr += xc->stat_rm_h_xirr; t_rm_h_ipoll += xc->stat_rm_h_ipoll; From patchwork Mon Jan 7 18:43:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751077 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D24646C5 for ; Mon, 7 Jan 2019 18:51:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C28F4289AA for ; Mon, 7 Jan 2019 18:51:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B6CC9289B0; Mon, 7 Jan 2019 18:51:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF0E6289AA for ; Mon, 7 Jan 2019 18:51:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727361AbfAGSvy (ORCPT ); Mon, 7 Jan 2019 13:51:54 -0500 Received: from 2.mo177.mail-out.ovh.net ([178.33.109.80]:39713 "EHLO 2.mo177.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726858AbfAGSvy (ORCPT ); Mon, 7 Jan 2019 13:51:54 -0500 Received: from player737.ha.ovh.net (unknown [10.109.159.35]) by mo177.mail-out.ovh.net (Postfix) with ESMTP id D07E9D8C1E for ; Mon, 7 Jan 2019 19:44:46 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id E799518663AC; Mon, 7 Jan 2019 18:44:35 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 05/19] KVM: PPC: Book3S HV: add a new KVM device for the XIVE native exploitation mode Date: Mon, 7 Jan 2019 19:43:17 +0100 Message-Id: <20190107184331.8429-6-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11393544111332821975 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This is the basic framework for the new KVM device supporting the XIVE native exploitation mode. The user interface exposes a new capability and a new KVM device to be used by QEMU. Internally, the interface to the new KVM device is protected with a new interrupt mode: KVMPPC_IRQ_XIVE. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/asm/kvm_host.h | 2 + arch/powerpc/include/asm/kvm_ppc.h | 21 ++ arch/powerpc/kvm/book3s_xive.h | 3 + include/uapi/linux/kvm.h | 3 + arch/powerpc/kvm/book3s.c | 7 +- arch/powerpc/kvm/book3s_xive_native.c | 332 ++++++++++++++++++++++++++ arch/powerpc/kvm/powerpc.c | 30 +++ arch/powerpc/kvm/Makefile | 2 +- 8 files changed, 398 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/kvm/book3s_xive_native.c diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0f98f00da2ea..c522e8274ad9 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -220,6 +220,7 @@ extern struct kvm_device_ops kvm_xics_ops; struct kvmppc_xive; struct kvmppc_xive_vcpu; extern struct kvm_device_ops kvm_xive_ops; +extern struct kvm_device_ops kvm_xive_native_ops; struct kvmppc_passthru_irqmap; @@ -446,6 +447,7 @@ struct kvmppc_passthru_irqmap { #define KVMPPC_IRQ_DEFAULT 0 #define KVMPPC_IRQ_MPIC 1 #define KVMPPC_IRQ_XICS 2 /* Includes a XIVE option */ +#define KVMPPC_IRQ_XIVE 3 /* XIVE native exploitation mode */ #define MMIO_HPTE_CACHE_SIZE 4 diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index eb0d79f0ca45..1bb313f238fe 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -591,6 +591,18 @@ extern int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval); extern int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, bool line_status); extern void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu); + +static inline int kvmppc_xive_enabled(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.irq_type == KVMPPC_IRQ_XIVE; +} + +extern int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, + struct kvm_vcpu *vcpu, u32 cpu); +extern void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu); +extern void kvmppc_xive_native_init_module(void); +extern void kvmppc_xive_native_exit_module(void); + #else static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, u32 priority) { return -1; } @@ -614,6 +626,15 @@ static inline int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) { retur static inline int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, bool line_status) { return -ENODEV; } static inline void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu) { } + +static inline int kvmppc_xive_enabled(struct kvm_vcpu *vcpu) + { return 0; } +static inline int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, + struct kvm_vcpu *vcpu, u32 cpu) { return -EBUSY; } +static inline void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu) { } +static inline void kvmppc_xive_native_init_module(void) { } +static inline void kvmppc_xive_native_exit_module(void) { } + #endif /* CONFIG_KVM_XIVE */ /* diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 10c4aa5cd010..5f22415520b4 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -12,6 +12,9 @@ #ifdef CONFIG_KVM_XICS #include "book3s_xics.h" +#define KVMPPC_XIVE_FIRST_IRQ 0 +#define KVMPPC_XIVE_NR_IRQS KVMPPC_XICS_NR_IRQS + /* * State for one guest irq source. * diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 6d4ea4b6c922..52bf74a1616e 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -988,6 +988,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 #ifdef KVM_CAP_IRQ_ROUTING @@ -1211,6 +1212,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, }; diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index bd1a677dd9e4..de7eed191107 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1039,7 +1039,10 @@ static int kvmppc_book3s_init(void) #ifdef CONFIG_KVM_XIVE if (xive_enabled()) { kvmppc_xive_init_module(); + kvmppc_xive_native_init_module(); kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS); + kvm_register_device_ops(&kvm_xive_native_ops, + KVM_DEV_TYPE_XIVE); } else #endif kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS); @@ -1050,8 +1053,10 @@ static int kvmppc_book3s_init(void) static void kvmppc_book3s_exit(void) { #ifdef CONFIG_KVM_XICS - if (xive_enabled()) + if (xive_enabled()) { kvmppc_xive_exit_module(); + kvmppc_xive_native_exit_module(); + } #endif #ifdef CONFIG_KVM_BOOK3S_32_HANDLER kvmppc_book3s_exit_pr(); diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c new file mode 100644 index 000000000000..115143e76c45 --- /dev/null +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017-2019, IBM Corporation. + */ + +#define pr_fmt(fmt) "xive-kvm: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "book3s_xive.h" + +static void xive_native_cleanup_queue(struct kvm_vcpu *vcpu, int prio) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + struct xive_q *q = &xc->queues[prio]; + + xive_native_disable_queue(xc->vp_id, q, prio); + if (q->qpage) { + put_page(virt_to_page(q->qpage)); + q->qpage = NULL; + } +} + +void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + int i; + + if (!kvmppc_xive_enabled(vcpu)) + return; + + if (!xc) + return; + + pr_devel("native_cleanup_vcpu(cpu=%d)\n", xc->server_num); + + /* Ensure no interrupt is still routed to that VP */ + xc->valid = false; + kvmppc_xive_disable_vcpu_interrupts(vcpu); + + /* Disable the VP */ + xive_native_disable_vp(xc->vp_id); + + /* Free the queues & associated interrupts */ + for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) { + /* Free the escalation irq */ + if (xc->esc_virq[i]) { + free_irq(xc->esc_virq[i], vcpu); + irq_dispose_mapping(xc->esc_virq[i]); + kfree(xc->esc_virq_names[i]); + xc->esc_virq[i] = 0; + } + + /* Free the queue */ + xive_native_cleanup_queue(vcpu, i); + } + + /* Free the VP */ + kfree(xc); + + /* Cleanup the vcpu */ + vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; + vcpu->arch.xive_vcpu = NULL; +} + +int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, + struct kvm_vcpu *vcpu, u32 cpu) +{ + struct kvmppc_xive *xive = dev->private; + struct kvmppc_xive_vcpu *xc; + int rc; + + pr_devel("native_connect_vcpu(cpu=%d)\n", cpu); + + if (dev->ops != &kvm_xive_native_ops) { + pr_devel("Wrong ops !\n"); + return -EPERM; + } + if (xive->kvm != vcpu->kvm) + return -EPERM; + if (vcpu->arch.irq_type) + return -EBUSY; + if (kvmppc_xive_find_server(vcpu->kvm, cpu)) { + pr_devel("Duplicate !\n"); + return -EEXIST; + } + if (cpu >= KVM_MAX_VCPUS) { + pr_devel("Out of bounds !\n"); + return -EINVAL; + } + xc = kzalloc(sizeof(*xc), GFP_KERNEL); + if (!xc) + return -ENOMEM; + + mutex_lock(&vcpu->kvm->lock); + vcpu->arch.xive_vcpu = xc; + xc->xive = xive; + xc->vcpu = vcpu; + xc->server_num = cpu; + xc->vp_id = xive->vp_base + cpu; + xc->valid = true; + + rc = xive_native_get_vp_info(xc->vp_id, &xc->vp_cam, &xc->vp_chip_id); + if (rc) { + pr_err("Failed to get VP info from OPAL: %d\n", rc); + goto bail; + } + + /* + * Enable the VP first as the single escalation mode will + * affect escalation interrupts numbering + */ + rc = xive_native_enable_vp(xc->vp_id, xive->single_escalation); + if (rc) { + pr_err("Failed to enable VP in OPAL: %d\n", rc); + goto bail; + } + + /* Configure VCPU fields for use by assembly push/pull */ + vcpu->arch.xive_saved_state.w01 = cpu_to_be64(0xff000000); + vcpu->arch.xive_cam_word = cpu_to_be32(xc->vp_cam | TM_QW1W2_VO); + + /* TODO: initialize queues ? */ + +bail: + vcpu->arch.irq_type = KVMPPC_IRQ_XIVE; + mutex_unlock(&vcpu->kvm->lock); + if (rc) + kvmppc_xive_native_cleanup_vcpu(vcpu); + + return rc; +} + +static int kvmppc_xive_native_set_attr(struct kvm_device *dev, + struct kvm_device_attr *attr) +{ + return -ENXIO; +} + +static int kvmppc_xive_native_get_attr(struct kvm_device *dev, + struct kvm_device_attr *attr) +{ + return -ENXIO; +} + +static int kvmppc_xive_native_has_attr(struct kvm_device *dev, + struct kvm_device_attr *attr) +{ + return -ENXIO; +} + +static void kvmppc_xive_native_free(struct kvm_device *dev) +{ + struct kvmppc_xive *xive = dev->private; + struct kvm *kvm = xive->kvm; + int i; + + debugfs_remove(xive->dentry); + + pr_devel("Destroying xive native for partition\n"); + + if (kvm) + kvm->arch.xive = NULL; + + /* Mask and free interrupts */ + for (i = 0; i <= xive->max_sbid; i++) { + if (xive->src_blocks[i]) + kvmppc_xive_free_sources(xive->src_blocks[i]); + kfree(xive->src_blocks[i]); + xive->src_blocks[i] = NULL; + } + + if (xive->vp_base != XIVE_INVALID_VP) + xive_native_free_vp_block(xive->vp_base); + + kfree(xive); + kfree(dev); +} + +static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) +{ + struct kvmppc_xive *xive; + struct kvm *kvm = dev->kvm; + int ret = 0; + + pr_devel("Creating xive native for partition\n"); + + if (kvm->arch.xive) + return -EEXIST; + + xive = kzalloc(sizeof(*xive), GFP_KERNEL); + if (!xive) + return -ENOMEM; + + dev->private = xive; + xive->dev = dev; + xive->kvm = kvm; + kvm->arch.xive = xive; + + /* We use the default queue size set by the host */ + xive->q_order = xive_native_default_eq_shift(); + if (xive->q_order < PAGE_SHIFT) + xive->q_page_order = 0; + else + xive->q_page_order = xive->q_order - PAGE_SHIFT; + + /* Allocate a bunch of VPs */ + xive->vp_base = xive_native_alloc_vp_block(KVM_MAX_VCPUS); + pr_devel("VP_Base=%x\n", xive->vp_base); + + if (xive->vp_base == XIVE_INVALID_VP) + ret = -ENOMEM; + + xive->single_escalation = xive_native_has_single_escalation(); + + if (ret) + kfree(xive); + + return ret; +} + +static int xive_native_debug_show(struct seq_file *m, void *private) +{ + struct kvmppc_xive *xive = m->private; + struct kvm *kvm = xive->kvm; + struct kvm_vcpu *vcpu; + unsigned int i; + + if (!kvm) + return 0; + + seq_puts(m, "=========\nVCPU state\n=========\n"); + + kvm_for_each_vcpu(i, vcpu, kvm) { + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + + if (!xc) + continue; + + seq_printf(m, "cpu server %#x NSR=%02x CPPR=%02x IBP=%02x PIPR=%02x w01=%016llx w2=%08x\n", + xc->server_num, + vcpu->arch.xive_saved_state.nsr, + vcpu->arch.xive_saved_state.cppr, + vcpu->arch.xive_saved_state.ipb, + vcpu->arch.xive_saved_state.pipr, + vcpu->arch.xive_saved_state.w01, + (u32) vcpu->arch.xive_cam_word); + + kvmppc_xive_debug_show_queues(m, vcpu); + } + + return 0; +} + +static int xive_native_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, xive_native_debug_show, inode->i_private); +} + +static const struct file_operations xive_native_debug_fops = { + .open = xive_native_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void xive_native_debugfs_init(struct kvmppc_xive *xive) +{ + char *name; + + name = kasprintf(GFP_KERNEL, "kvm-xive-%p", xive); + if (!name) { + pr_err("%s: no memory for name\n", __func__); + return; + } + + xive->dentry = debugfs_create_file(name, 0444, powerpc_debugfs_root, + xive, &xive_native_debug_fops); + + pr_debug("%s: created %s\n", __func__, name); + kfree(name); +} + +static void kvmppc_xive_native_init(struct kvm_device *dev) +{ + struct kvmppc_xive *xive = (struct kvmppc_xive *)dev->private; + + /* Register some debug interfaces */ + xive_native_debugfs_init(xive); +} + +struct kvm_device_ops kvm_xive_native_ops = { + .name = "kvm-xive-native", + .create = kvmppc_xive_native_create, + .init = kvmppc_xive_native_init, + .destroy = kvmppc_xive_native_free, + .set_attr = kvmppc_xive_native_set_attr, + .get_attr = kvmppc_xive_native_get_attr, + .has_attr = kvmppc_xive_native_has_attr, +}; + +void kvmppc_xive_native_init_module(void) +{ + ; +} + +void kvmppc_xive_native_exit_module(void) +{ + ; +} diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index b90a7d154180..01d526e15e9d 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -566,6 +566,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_PPC_ENABLE_HCALL: #ifdef CONFIG_KVM_XICS case KVM_CAP_IRQ_XICS: +#endif +#ifdef CONFIG_KVM_XIVE + case KVM_CAP_PPC_IRQ_XIVE: #endif case KVM_CAP_PPC_GET_CPU_CHAR: r = 1; @@ -753,6 +756,9 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) else kvmppc_xics_free_icp(vcpu); break; + case KVMPPC_IRQ_XIVE: + kvmppc_xive_native_cleanup_vcpu(vcpu); + break; } kvmppc_core_vcpu_free(vcpu); @@ -1941,6 +1947,30 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, break; } #endif /* CONFIG_KVM_XICS */ +#ifdef CONFIG_KVM_XIVE + case KVM_CAP_PPC_IRQ_XIVE: { + struct fd f; + struct kvm_device *dev; + + r = -EBADF; + f = fdget(cap->args[0]); + if (!f.file) + break; + + r = -ENXIO; + if (!xive_enabled()) + break; + + r = -EPERM; + dev = kvm_device_from_filp(f.file); + if (dev) + r = kvmppc_xive_native_connect_vcpu(dev, vcpu, + cap->args[1]); + + fdput(f); + break; + } +#endif /* CONFIG_KVM_XIVE */ #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE case KVM_CAP_PPC_FWNMI: r = -EINVAL; diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 64f1135e7732..806cbe488410 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -99,7 +99,7 @@ endif kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ book3s_xics.o -kvm-book3s_64-objs-$(CONFIG_KVM_XIVE) += book3s_xive.o +kvm-book3s_64-objs-$(CONFIG_KVM_XIVE) += book3s_xive.o book3s_xive_native.o kvm-book3s_64-objs-$(CONFIG_SPAPR_TCE_IOMMU) += book3s_64_vio.o kvm-book3s_64-module-objs := \ From patchwork Mon Jan 7 18:43:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751115 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AF39E6C5 for ; Mon, 7 Jan 2019 19:02:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FABA289B1 for ; Mon, 7 Jan 2019 19:02:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9309A289B3; Mon, 7 Jan 2019 19:02:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2351A289B1 for ; Mon, 7 Jan 2019 19:02:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728233AbfAGTCI (ORCPT ); Mon, 7 Jan 2019 14:02:08 -0500 Received: from 12.mo4.mail-out.ovh.net ([178.33.104.253]:43302 "EHLO 12.mo4.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728399AbfAGTCG (ORCPT ); Mon, 7 Jan 2019 14:02:06 -0500 X-Greylist: delayed 925 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:02:04 EST Received: from player737.ha.ovh.net (unknown [10.109.143.220]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id F14CF1C8226 for ; Mon, 7 Jan 2019 19:44:58 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id D15B618663E7; Mon, 7 Jan 2019 18:44:46 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 06/19] KVM: PPC: Book3S HV: add a GET_ESB_FD control to the XIVE native device Date: Mon, 7 Jan 2019 19:43:18 +0100 Message-Id: <20190107184331.8429-7-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11396921810366532567 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This will let the guest create a memory mapping to expose the ESB MMIO regions used to control the interrupt sources, to trigger events, to EOI or to turn off the sources. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 4 ++ arch/powerpc/kvm/book3s_xive_native.c | 97 +++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 8c876c166ef2..6bb61ba141c2 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -675,4 +675,8 @@ struct kvm_ppc_cpu_char { #define KVM_XICS_PRESENTED (1ULL << 43) #define KVM_XICS_QUEUED (1ULL << 44) +/* POWER9 XIVE Native Interrupt Controller */ +#define KVM_DEV_XIVE_GRP_CTRL 1 +#define KVM_DEV_XIVE_GET_ESB_FD 1 + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 115143e76c45..e20081f0c8d4 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -153,6 +153,85 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, return rc; } +static int xive_native_esb_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct kvmppc_xive *xive = vma->vm_file->private_data; + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + struct xive_irq_data *xd; + u32 hw_num; + u16 src; + u64 page; + unsigned long irq; + + /* + * Linux/KVM uses a two pages ESB setting, one for trigger and + * one for EOI + */ + irq = vmf->pgoff / 2; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) { + pr_err("%s: source %lx not found !\n", __func__, irq); + return VM_FAULT_SIGBUS; + } + + state = &sb->irq_state[src]; + kvmppc_xive_select_irq(state, &hw_num, &xd); + + arch_spin_lock(&sb->lock); + + /* + * first/even page is for trigger + * second/odd page is for EOI and management. + */ + page = vmf->pgoff % 2 ? xd->eoi_page : xd->trig_page; + arch_spin_unlock(&sb->lock); + + if (!page) { + pr_err("%s: acessing invalid ESB page for source %lx !\n", + __func__, irq); + return VM_FAULT_SIGBUS; + } + + vmf_insert_pfn(vma, vmf->address, page >> PAGE_SHIFT); + return VM_FAULT_NOPAGE; +} + +static const struct vm_operations_struct xive_native_esb_vmops = { + .fault = xive_native_esb_fault, +}; + +static int xive_native_esb_mmap(struct file *file, struct vm_area_struct *vma) +{ + /* There are two ESB pages (trigger and EOI) per IRQ */ + if (vma_pages(vma) + vma->vm_pgoff > KVMPPC_XIVE_NR_IRQS * 2) + return -EINVAL; + + vma->vm_flags |= VM_IO | VM_PFNMAP; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_ops = &xive_native_esb_vmops; + return 0; +} + +static const struct file_operations xive_native_esb_fops = { + .mmap = xive_native_esb_mmap, +}; + +static int kvmppc_xive_native_get_esb_fd(struct kvmppc_xive *xive, u64 addr) +{ + u64 __user *ubufp = (u64 __user *) addr; + int ret; + + ret = anon_inode_getfd("[xive-esb]", &xive_native_esb_fops, xive, + O_RDWR | O_CLOEXEC); + if (ret < 0) + return ret; + + return put_user(ret, ubufp); +} + static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -162,12 +241,30 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev, static int kvmppc_xive_native_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { + struct kvmppc_xive *xive = dev->private; + + switch (attr->group) { + case KVM_DEV_XIVE_GRP_CTRL: + switch (attr->attr) { + case KVM_DEV_XIVE_GET_ESB_FD: + return kvmppc_xive_native_get_esb_fd(xive, attr->addr); + } + break; + } return -ENXIO; } static int kvmppc_xive_native_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { + switch (attr->group) { + case KVM_DEV_XIVE_GRP_CTRL: + switch (attr->attr) { + case KVM_DEV_XIVE_GET_ESB_FD: + return 0; + } + break; + } return -ENXIO; } From patchwork Mon Jan 7 18:43:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751083 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A04946C5 for ; Mon, 7 Jan 2019 18:52:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8DD50289AA for ; Mon, 7 Jan 2019 18:52:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C9FD289B0; Mon, 7 Jan 2019 18:52:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0514E289AA for ; Mon, 7 Jan 2019 18:52:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727274AbfAGSwU (ORCPT ); Mon, 7 Jan 2019 13:52:20 -0500 Received: from 9.mo179.mail-out.ovh.net ([46.105.76.148]:40017 "EHLO 9.mo179.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726813AbfAGSwT (ORCPT ); Mon, 7 Jan 2019 13:52:19 -0500 Received: from player737.ha.ovh.net (unknown [10.109.146.76]) by mo179.mail-out.ovh.net (Postfix) with ESMTP id D233C10F21C for ; Mon, 7 Jan 2019 19:45:09 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 08A4F1866417; Mon, 7 Jan 2019 18:44:58 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 07/19] KVM: PPC: Book3S HV: add a GET_TIMA_FD control to XIVE native device Date: Mon, 7 Jan 2019 19:43:19 +0100 Message-Id: <20190107184331.8429-8-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11400018033937255383 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This will let the guest create a memory mapping to expose the XIVE MMIO region (TIMA) used for interrupt management at the CPU level. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/asm/xive.h | 1 + arch/powerpc/include/uapi/asm/kvm.h | 1 + arch/powerpc/kvm/book3s_xive_native.c | 57 +++++++++++++++++++++++++++ arch/powerpc/sysdev/xive/native.c | 11 ++++++ 4 files changed, 70 insertions(+) diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index d6be3e4d9fa4..7a7aa22d8258 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -23,6 +23,7 @@ * same offset regardless of where the code is executing */ extern void __iomem *xive_tima; +extern unsigned long xive_tima_os; /* * Offset in the TM area of our current execution level (provided by diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 6bb61ba141c2..89c140cb9e79 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -678,5 +678,6 @@ struct kvm_ppc_cpu_char { /* POWER9 XIVE Native Interrupt Controller */ #define KVM_DEV_XIVE_GRP_CTRL 1 #define KVM_DEV_XIVE_GET_ESB_FD 1 +#define KVM_DEV_XIVE_GET_TIMA_FD 2 #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index e20081f0c8d4..ee9d12bf2dae 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -232,6 +232,60 @@ static int kvmppc_xive_native_get_esb_fd(struct kvmppc_xive *xive, u64 addr) return put_user(ret, ubufp); } +static int xive_native_tima_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + + switch (vmf->pgoff) { + case 0: /* HW - forbid access */ + case 1: /* HV - forbid access */ + return VM_FAULT_SIGBUS; + case 2: /* OS */ + vmf_insert_pfn(vma, vmf->address, xive_tima_os >> PAGE_SHIFT); + return VM_FAULT_NOPAGE; + case 3: /* USER - TODO */ + default: + return VM_FAULT_SIGBUS; + } +} + +static const struct vm_operations_struct xive_native_tima_vmops = { + .fault = xive_native_tima_fault, +}; + +static int xive_native_tima_mmap(struct file *file, struct vm_area_struct *vma) +{ + /* + * The TIMA is four pages wide but only the last two pages (OS + * and User view) are accessible to the guest. The page fault + * handler will handle the permissions. + */ + if (vma_pages(vma) + vma->vm_pgoff > 4) + return -EINVAL; + + vma->vm_flags |= VM_IO | VM_PFNMAP; + vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot); + vma->vm_ops = &xive_native_tima_vmops; + return 0; +} + +static const struct file_operations xive_native_tima_fops = { + .mmap = xive_native_tima_mmap, +}; + +static int kvmppc_xive_native_get_tima_fd(struct kvmppc_xive *xive, u64 addr) +{ + u64 __user *ubufp = (u64 __user *) addr; + int ret; + + ret = anon_inode_getfd("[xive-tima]", &xive_native_tima_fops, xive, + O_RDWR | O_CLOEXEC); + if (ret < 0) + return ret; + + return put_user(ret, ubufp); +} + static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -248,6 +302,8 @@ static int kvmppc_xive_native_get_attr(struct kvm_device *dev, switch (attr->attr) { case KVM_DEV_XIVE_GET_ESB_FD: return kvmppc_xive_native_get_esb_fd(xive, attr->addr); + case KVM_DEV_XIVE_GET_TIMA_FD: + return kvmppc_xive_native_get_tima_fd(xive, attr->addr); } break; } @@ -261,6 +317,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, case KVM_DEV_XIVE_GRP_CTRL: switch (attr->attr) { case KVM_DEV_XIVE_GET_ESB_FD: + case KVM_DEV_XIVE_GET_TIMA_FD: return 0; } break; diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 0c037e933e55..7782201e5fe8 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -521,6 +521,9 @@ u32 xive_native_default_eq_shift(void) } EXPORT_SYMBOL_GPL(xive_native_default_eq_shift); +unsigned long xive_tima_os; +EXPORT_SYMBOL_GPL(xive_tima_os); + bool __init xive_native_init(void) { struct device_node *np; @@ -573,6 +576,14 @@ bool __init xive_native_init(void) for_each_possible_cpu(cpu) kvmppc_set_xive_tima(cpu, r.start, tima); + /* Resource 2 is OS window */ + if (of_address_to_resource(np, 2, &r)) { + pr_err("Failed to get thread mgmnt area resource\n"); + return false; + } + + xive_tima_os = r.start; + /* Grab size of provisionning pages */ xive_parse_provisioning(np); From patchwork Mon Jan 7 18:43:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4CF5D13BF for ; Mon, 7 Jan 2019 19:01:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B6C0289B1 for ; Mon, 7 Jan 2019 19:01:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2D674289B2; Mon, 7 Jan 2019 19:01:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BAF3A289B3 for ; Mon, 7 Jan 2019 19:01:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727622AbfAGTBt (ORCPT ); Mon, 7 Jan 2019 14:01:49 -0500 Received: from 4.mo7.mail-out.ovh.net ([178.32.122.254]:57957 "EHLO 4.mo7.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727589AbfAGTBo (ORCPT ); Mon, 7 Jan 2019 14:01:44 -0500 X-Greylist: delayed 981 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:01:43 EST Received: from player737.ha.ovh.net (unknown [10.109.159.35]) by mo7.mail-out.ovh.net (Postfix) with ESMTP id 65E0AF2CC0 for ; Mon, 7 Jan 2019 19:45:21 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id D962C186643B; Mon, 7 Jan 2019 18:45:09 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 08/19] KVM: PPC: Book3S HV: add a VC_BASE control to the XIVE native device Date: Mon, 7 Jan 2019 19:43:20 +0100 Message-Id: <20190107184331.8429-9-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11403395734415510487 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The ESB MMIO region controls the interrupt sources of the guest. QEMU will query an fd (GET_ESB_FD ioctl) and map this region at a specific address for the guest to use. The guest will obtain this information using the H_INT_GET_SOURCE_INFO hcall. To inform KVM of the address setting used by QEMU, add a VC_BASE control to the KVM XIVE device Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 1 + arch/powerpc/kvm/book3s_xive.h | 3 +++ arch/powerpc/kvm/book3s_xive_native.c | 39 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 89c140cb9e79..8b78b12aa118 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -679,5 +679,6 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_GRP_CTRL 1 #define KVM_DEV_XIVE_GET_ESB_FD 1 #define KVM_DEV_XIVE_GET_TIMA_FD 2 +#define KVM_DEV_XIVE_VC_BASE 3 #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 5f22415520b4..ae4a670eea63 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -125,6 +125,9 @@ struct kvmppc_xive { /* Flags */ u8 single_escalation; + + /* VC base address for ESBs */ + u64 vc_base; }; #define KVMPPC_XIVE_Q_COUNT 8 diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index ee9d12bf2dae..29a62914de55 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -153,6 +153,25 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, return rc; } +static int kvmppc_xive_native_set_vc_base(struct kvmppc_xive *xive, u64 addr) +{ + u64 __user *ubufp = (u64 __user *) addr; + + if (get_user(xive->vc_base, ubufp)) + return -EFAULT; + return 0; +} + +static int kvmppc_xive_native_get_vc_base(struct kvmppc_xive *xive, u64 addr) +{ + u64 __user *ubufp = (u64 __user *) addr; + + if (put_user(xive->vc_base, ubufp)) + return -EFAULT; + + return 0; +} + static int xive_native_esb_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; @@ -289,6 +308,16 @@ static int kvmppc_xive_native_get_tima_fd(struct kvmppc_xive *xive, u64 addr) static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { + struct kvmppc_xive *xive = dev->private; + + switch (attr->group) { + case KVM_DEV_XIVE_GRP_CTRL: + switch (attr->attr) { + case KVM_DEV_XIVE_VC_BASE: + return kvmppc_xive_native_set_vc_base(xive, attr->addr); + } + break; + } return -ENXIO; } @@ -304,6 +333,8 @@ static int kvmppc_xive_native_get_attr(struct kvm_device *dev, return kvmppc_xive_native_get_esb_fd(xive, attr->addr); case KVM_DEV_XIVE_GET_TIMA_FD: return kvmppc_xive_native_get_tima_fd(xive, attr->addr); + case KVM_DEV_XIVE_VC_BASE: + return kvmppc_xive_native_get_vc_base(xive, attr->addr); } break; } @@ -318,6 +349,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, switch (attr->attr) { case KVM_DEV_XIVE_GET_ESB_FD: case KVM_DEV_XIVE_GET_TIMA_FD: + case KVM_DEV_XIVE_VC_BASE: return 0; } break; @@ -353,6 +385,11 @@ static void kvmppc_xive_native_free(struct kvm_device *dev) kfree(dev); } +/* + * ESB MMIO address of chip 0 + */ +#define XIVE_VC_BASE 0x0006010000000000ull + static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) { struct kvmppc_xive *xive; @@ -387,6 +424,8 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) if (xive->vp_base == XIVE_INVALID_VP) ret = -ENOMEM; + xive->vc_base = XIVE_VC_BASE; + xive->single_escalation = xive_native_has_single_escalation(); if (ret) From patchwork Mon Jan 7 18:43:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751137 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 048E091E for ; Mon, 7 Jan 2019 19:21:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8396289AB for ; Mon, 7 Jan 2019 19:21:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB772289BF; Mon, 7 Jan 2019 19:21:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5B0EC289AB for ; Mon, 7 Jan 2019 19:21:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727569AbfAGTVq (ORCPT ); Mon, 7 Jan 2019 14:21:46 -0500 Received: from 15.mo7.mail-out.ovh.net ([87.98.180.21]:43547 "EHLO 15.mo7.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727317AbfAGTVq (ORCPT ); Mon, 7 Jan 2019 14:21:46 -0500 X-Greylist: delayed 1200 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:21:42 EST Received: from player737.ha.ovh.net (unknown [10.109.160.244]) by mo7.mail-out.ovh.net (Postfix) with ESMTP id 479ADF294B for ; Mon, 7 Jan 2019 19:45:32 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 6A97B1866453; Mon, 7 Jan 2019 18:45:21 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 09/19] KVM: PPC: Book3S HV: add a SET_SOURCE control to the XIVE native device Date: Mon, 7 Jan 2019 19:43:21 +0100 Message-Id: <20190107184331.8429-10-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11406491959938485207 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Interrupt sources are simply created at the OPAL level and then MASKED. KVM only needs to know about their type: LSI or MSI. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 5 + arch/powerpc/kvm/book3s_xive_native.c | 98 +++++++++++++++++++ .../powerpc/kvm/book3s_xive_native_template.c | 27 +++++ 3 files changed, 130 insertions(+) create mode 100644 arch/powerpc/kvm/book3s_xive_native_template.c diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 8b78b12aa118..6fc9660c5aec 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -680,5 +680,10 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_GET_ESB_FD 1 #define KVM_DEV_XIVE_GET_TIMA_FD 2 #define KVM_DEV_XIVE_VC_BASE 3 +#define KVM_DEV_XIVE_GRP_SOURCES 2 /* 64-bit source attributes */ + +/* Layout of 64-bit XIVE source attribute values */ +#define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0) +#define KVM_XIVE_LEVEL_ASSERTED (1ULL << 1) #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 29a62914de55..2518640d4a58 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -31,6 +31,24 @@ #include "book3s_xive.h" +/* + * We still instantiate them here because we use some of the + * generated utility functions as well in this file. + */ +#define XIVE_RUNTIME_CHECKS +#define X_PFX xive_vm_ +#define X_STATIC static +#define X_STAT_PFX stat_vm_ +#define __x_tima xive_tima +#define __x_eoi_page(xd) ((void __iomem *)((xd)->eoi_mmio)) +#define __x_trig_page(xd) ((void __iomem *)((xd)->trig_mmio)) +#define __x_writeb __raw_writeb +#define __x_readw __raw_readw +#define __x_readq __raw_readq +#define __x_writeq __raw_writeq + +#include "book3s_xive_native_template.c" + static void xive_native_cleanup_queue(struct kvm_vcpu *vcpu, int prio) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; @@ -305,6 +323,78 @@ static int kvmppc_xive_native_get_tima_fd(struct kvmppc_xive *xive, u64 addr) return put_user(ret, ubufp); } +static int kvmppc_xive_native_set_source(struct kvmppc_xive *xive, long irq, + u64 addr) +{ + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + u64 __user *ubufp = (u64 __user *) addr; + u64 val; + u16 idx; + + pr_devel("%s irq=0x%lx\n", __func__, irq); + + if (irq < KVMPPC_XIVE_FIRST_IRQ || irq >= KVMPPC_XIVE_NR_IRQS) + return -ENOENT; + + sb = kvmppc_xive_find_source(xive, irq, &idx); + if (!sb) { + pr_debug("No source, creating source block...\n"); + sb = kvmppc_xive_create_src_block(xive, irq); + if (!sb) { + pr_err("Failed to create block...\n"); + return -ENOMEM; + } + } + state = &sb->irq_state[idx]; + + if (get_user(val, ubufp)) { + pr_err("fault getting user info !\n"); + return -EFAULT; + } + + /* + * If the source doesn't already have an IPI, allocate + * one and get the corresponding data + */ + if (!state->ipi_number) { + state->ipi_number = xive_native_alloc_irq(); + if (state->ipi_number == 0) { + pr_err("Failed to allocate IRQ !\n"); + return -ENOMEM; + } + xive_native_populate_irq_data(state->ipi_number, + &state->ipi_data); + pr_debug("%s allocated hw_irq=0x%x for irq=0x%lx\n", __func__, + state->ipi_number, irq); + } + + arch_spin_lock(&sb->lock); + + /* Restore LSI state */ + if (val & KVM_XIVE_LEVEL_SENSITIVE) { + state->lsi = true; + if (val & KVM_XIVE_LEVEL_ASSERTED) + state->asserted = true; + pr_devel(" LSI ! Asserted=%d\n", state->asserted); + } + + /* Mask IRQ to start with */ + state->act_server = 0; + state->act_priority = MASKED; + xive_vm_esb_load(&state->ipi_data, XIVE_ESB_SET_PQ_01); + xive_native_configure_irq(state->ipi_number, 0, MASKED, 0); + + /* Increment the number of valid sources and mark this one valid */ + if (!state->valid) + xive->src_count++; + state->valid = true; + + arch_spin_unlock(&sb->lock); + + return 0; +} + static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -317,6 +407,9 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev, return kvmppc_xive_native_set_vc_base(xive, attr->addr); } break; + case KVM_DEV_XIVE_GRP_SOURCES: + return kvmppc_xive_native_set_source(xive, attr->attr, + attr->addr); } return -ENXIO; } @@ -353,6 +446,11 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, return 0; } break; + case KVM_DEV_XIVE_GRP_SOURCES: + if (attr->attr >= KVMPPC_XIVE_FIRST_IRQ && + attr->attr < KVMPPC_XIVE_NR_IRQS) + return 0; + break; } return -ENXIO; } diff --git a/arch/powerpc/kvm/book3s_xive_native_template.c b/arch/powerpc/kvm/book3s_xive_native_template.c new file mode 100644 index 000000000000..e7260da4a596 --- /dev/null +++ b/arch/powerpc/kvm/book3s_xive_native_template.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017-2019, IBM Corporation. + */ + +/* File to be included by other .c files */ + +#define XGLUE(a, b) a##b +#define GLUE(a, b) XGLUE(a, b) + +/* + * TODO: introduce a common template file with the XIVE native layer + * and the XICS-on-XIVE glue for the utility functions + */ +static u8 GLUE(X_PFX, esb_load)(struct xive_irq_data *xd, u32 offset) +{ + u64 val; + + if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) + offset |= offset << 4; + + val = __x_readq(__x_eoi_page(xd) + offset); +#ifdef __LITTLE_ENDIAN__ + val >>= 64-8; +#endif + return (u8)val; +} From patchwork Mon Jan 7 18:43:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751181 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6F41413B5 for ; Mon, 7 Jan 2019 20:01:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F344289AF for ; Mon, 7 Jan 2019 20:01:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 52613289C0; Mon, 7 Jan 2019 20:01:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 35830289AF for ; Mon, 7 Jan 2019 20:01:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726540AbfAGUBt (ORCPT ); Mon, 7 Jan 2019 15:01:49 -0500 Received: from 16.mo1.mail-out.ovh.net ([178.33.104.224]:60725 "EHLO 16.mo1.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726718AbfAGUBs (ORCPT ); Mon, 7 Jan 2019 15:01:48 -0500 Received: from player737.ha.ovh.net (unknown [10.109.160.54]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id 2FCAC14CE6C for ; Mon, 7 Jan 2019 19:45:44 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 528AD186647E; Mon, 7 Jan 2019 18:45:32 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 10/19] KVM: PPC: Book3S HV: add a EISN attribute to kvmppc_xive_irq_state Date: Mon, 7 Jan 2019 19:43:22 +0100 Message-Id: <20190107184331.8429-11-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11409869656920001495 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The Effective IRQ Source Number is the interrupt number pushed in the event queue that the guest OS will use to dispatch events internally. Signed-off-by: Cédric Le Goater --- arch/powerpc/kvm/book3s_xive.h | 3 +++ arch/powerpc/kvm/book3s_xive.c | 1 + 2 files changed, 4 insertions(+) diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index ae4a670eea63..67e07b41061d 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -57,6 +57,9 @@ struct kvmppc_xive_irq_state { bool saved_p; bool saved_q; u8 saved_scan_prio; + + /* Xive native */ + u32 eisn; /* Guest Effective IRQ number */ }; /* Select the "right" interrupt (IPI vs. passthrough) */ diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index bb5d32f7e4e6..e9f05d9c9ad5 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1515,6 +1515,7 @@ struct kvmppc_xive_src_block *kvmppc_xive_create_src_block( for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) { sb->irq_state[i].number = (bid << KVMPPC_XICS_ICS_SHIFT) | i; + sb->irq_state[i].eisn = 0; sb->irq_state[i].guest_priority = MASKED; sb->irq_state[i].saved_priority = MASKED; sb->irq_state[i].act_priority = MASKED; From patchwork Mon Jan 7 18:43:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751079 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 18C7F1399 for ; Mon, 7 Jan 2019 18:52:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 07172289AA for ; Mon, 7 Jan 2019 18:52:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF230289B1; Mon, 7 Jan 2019 18:52:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF173289AA for ; Mon, 7 Jan 2019 18:52:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727681AbfAGSv7 (ORCPT ); Mon, 7 Jan 2019 13:51:59 -0500 Received: from 15.mo1.mail-out.ovh.net ([188.165.38.232]:51221 "EHLO 15.mo1.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726989AbfAGSv7 (ORCPT ); Mon, 7 Jan 2019 13:51:59 -0500 X-Greylist: delayed 354 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 13:51:50 EST Received: from player737.ha.ovh.net (unknown [10.109.159.68]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id 5232A14CEAD for ; Mon, 7 Jan 2019 19:45:55 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 2A13818664BD; Mon, 7 Jan 2019 18:45:44 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 11/19] KVM: PPC: Book3S HV: add support for the XIVE native exploitation mode hcalls Date: Mon, 7 Jan 2019 19:43:23 +0100 Message-Id: <20190107184331.8429-12-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11412965884339522519 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The XIVE native exploitation mode specs define a set of Hypervisor calls to configure the sources and the event queues : - H_INT_GET_SOURCE_INFO used to obtain the address of the MMIO page of the Event State Buffer (PQ bits) entry associated with the source. - H_INT_SET_SOURCE_CONFIG assigns a source to a "target". - H_INT_GET_SOURCE_CONFIG determines which "target" and "priority" is assigned to a source - H_INT_GET_QUEUE_INFO returns the address of the notification management page associated with the specified "target" and "priority". - H_INT_SET_QUEUE_CONFIG sets or resets the event queue for a given "target" and "priority". It is also used to set the notification configuration associated with the queue, only unconditional notification is supported for the moment. Reset is performed with a queue size of 0 and queueing is disabled in that case. - H_INT_GET_QUEUE_CONFIG returns the queue settings for a given "target" and "priority". - H_INT_RESET resets all of the guest's internal interrupt structures to their initial state, losing all configuration set via the hcalls H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG. - H_INT_SYNC issue a synchronisation on a source to make sure all notifications have reached their queue. Calls that still need to be addressed : H_INT_SET_OS_REPORTING_LINE H_INT_GET_OS_REPORTING_LINE Signed-off-by: Cédric Le Goater --- arch/powerpc/include/asm/kvm_ppc.h | 43 ++ arch/powerpc/kvm/book3s_xive.h | 54 +++ arch/powerpc/kvm/book3s_hv.c | 29 ++ arch/powerpc/kvm/book3s_hv_builtin.c | 196 +++++++++ arch/powerpc/kvm/book3s_hv_rm_xive_native.c | 47 +++ arch/powerpc/kvm/book3s_xive_native.c | 326 ++++++++++++++- .../powerpc/kvm/book3s_xive_native_template.c | 371 ++++++++++++++++++ arch/powerpc/kvm/Makefile | 2 + arch/powerpc/kvm/book3s_hv_rmhandlers.S | 52 +++ 9 files changed, 1118 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/kvm/book3s_hv_rm_xive_native.c diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 1bb313f238fe..4cc897039485 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -602,6 +602,7 @@ extern int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, extern void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu); extern void kvmppc_xive_native_init_module(void); extern void kvmppc_xive_native_exit_module(void); +extern int kvmppc_xive_native_hcall(struct kvm_vcpu *vcpu, u32 cmd); #else static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, @@ -634,6 +635,8 @@ static inline int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, static inline void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu) { } static inline void kvmppc_xive_native_init_module(void) { } static inline void kvmppc_xive_native_exit_module(void) { } +static inline int kvmppc_xive_native_hcall(struct kvm_vcpu *vcpu, u32 cmd) + { return 0; } #endif /* CONFIG_KVM_XIVE */ @@ -682,6 +685,46 @@ int kvmppc_rm_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr); int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr); void kvmppc_guest_entry_inject_int(struct kvm_vcpu *vcpu); +int kvmppc_rm_h_int_get_source_info(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +int kvmppc_rm_h_int_set_source_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn, + unsigned long target, + unsigned long priority, + unsigned long eisn); +int kvmppc_rm_h_int_get_source_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +int kvmppc_rm_h_int_get_queue_info(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +int kvmppc_rm_h_int_set_queue_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority, + unsigned long qpage, + unsigned long qsize); +int kvmppc_rm_h_int_get_queue_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +int kvmppc_rm_h_int_set_os_reporting_line(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long reportingline); +int kvmppc_rm_h_int_get_os_reporting_line(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long reportingline); +int kvmppc_rm_h_int_esb(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn, unsigned long offset, + unsigned long data); +int kvmppc_rm_h_int_sync(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn); +int kvmppc_rm_h_int_reset(struct kvm_vcpu *vcpu, unsigned long flag); + /* * Host-side operations we want to set up while running in real * mode in the guest operating on the xics. diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 67e07b41061d..31e598e62589 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -268,5 +268,59 @@ void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu); int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio); int kvmppc_xive_debug_show_queues(struct seq_file *m, struct kvm_vcpu *vcpu); +int xive_rm_h_int_get_source_info(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +int xive_rm_h_int_get_source_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +int xive_rm_h_int_get_queue_info(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +int xive_rm_h_int_get_queue_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +int xive_rm_h_int_set_os_reporting_line(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long reportingline); +int xive_rm_h_int_get_os_reporting_line(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long reportingline); +int xive_rm_h_int_esb(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn, unsigned long offset, + unsigned long data); +int xive_rm_h_int_sync(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn); + +extern int (*__xive_vm_h_int_get_source_info)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +extern int (*__xive_vm_h_int_get_source_config)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +extern int (*__xive_vm_h_int_get_queue_info)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +extern int (*__xive_vm_h_int_get_queue_config)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +extern int (*__xive_vm_h_int_set_os_reporting_line)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long reportingline); +extern int (*__xive_vm_h_int_get_os_reporting_line)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long reportingline); +extern int (*__xive_vm_h_int_esb)(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn, unsigned long offset, + unsigned long data); +extern int (*__xive_vm_h_int_sync)(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn); + #endif /* CONFIG_KVM_XICS */ #endif /* _KVM_PPC_BOOK3S_XICS_H */ diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 5a066fc299e1..1fb17d529a88 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -930,6 +930,22 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) break; } return RESUME_HOST; + case H_INT_GET_SOURCE_INFO: + case H_INT_SET_SOURCE_CONFIG: + case H_INT_GET_SOURCE_CONFIG: + case H_INT_GET_QUEUE_INFO: + case H_INT_SET_QUEUE_CONFIG: + case H_INT_GET_QUEUE_CONFIG: + case H_INT_SET_OS_REPORTING_LINE: + case H_INT_GET_OS_REPORTING_LINE: + case H_INT_ESB: + case H_INT_SYNC: + case H_INT_RESET: + if (kvmppc_xive_enabled(vcpu)) { + ret = kvmppc_xive_native_hcall(vcpu, req); + break; + } + return RESUME_HOST; case H_SET_DABR: ret = kvmppc_h_set_dabr(vcpu, kvmppc_get_gpr(vcpu, 4)); break; @@ -5153,6 +5169,19 @@ static unsigned int default_hcall_list[] = { H_IPOLL, H_XIRR, H_XIRR_X, +#endif +#ifdef CONFIG_KVM_XIVE + H_INT_GET_SOURCE_INFO, + H_INT_SET_SOURCE_CONFIG, + H_INT_GET_SOURCE_CONFIG, + H_INT_GET_QUEUE_INFO, + H_INT_SET_QUEUE_CONFIG, + H_INT_GET_QUEUE_CONFIG, + H_INT_SET_OS_REPORTING_LINE, + H_INT_GET_OS_REPORTING_LINE, + H_INT_ESB, + H_INT_SYNC, + H_INT_RESET, #endif 0 }; diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index a71e2fc00a4e..db690f914d78 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -51,6 +51,42 @@ EXPORT_SYMBOL_GPL(__xive_vm_h_ipi); EXPORT_SYMBOL_GPL(__xive_vm_h_cppr); EXPORT_SYMBOL_GPL(__xive_vm_h_eoi); +int (*__xive_vm_h_int_get_source_info)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +int (*__xive_vm_h_int_get_source_config)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn); +int (*__xive_vm_h_int_get_queue_info)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +int (*__xive_vm_h_int_get_queue_config)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority); +int (*__xive_vm_h_int_set_os_reporting_line)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long line); +int (*__xive_vm_h_int_get_os_reporting_line)(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long line); +int (*__xive_vm_h_int_esb)(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn, unsigned long offset, + unsigned long data); +int (*__xive_vm_h_int_sync)(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn); + +EXPORT_SYMBOL_GPL(__xive_vm_h_int_get_source_info); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_get_source_config); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_get_queue_info); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_get_queue_config); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_set_os_reporting_line); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_get_os_reporting_line); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_esb); +EXPORT_SYMBOL_GPL(__xive_vm_h_int_sync); + /* * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) * should be power of 2. @@ -660,6 +696,166 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) } #endif /* CONFIG_KVM_XICS */ +#ifdef CONFIG_KVM_XIVE +int kvmppc_rm_h_int_get_source_info(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_get_source_info(vcpu, flag, lisn); + if (unlikely(!__xive_vm_h_int_get_source_info)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_get_source_info(vcpu, flag, lisn); +} + +int kvmppc_rm_h_int_set_source_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn, + unsigned long target, + unsigned long priority, + unsigned long eisn) +{ + return H_TOO_HARD; +} + +int kvmppc_rm_h_int_get_source_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long lisn) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_get_source_config(vcpu, flag, lisn); + if (unlikely(!__xive_vm_h_int_get_source_config)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_get_source_config(vcpu, flag, lisn); +} + +int kvmppc_rm_h_int_get_queue_info(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_get_queue_info(vcpu, flag, target, + priority); + if (unlikely(!__xive_vm_h_int_get_queue_info)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_get_queue_info(vcpu, flag, target, priority); +} + +int kvmppc_rm_h_int_set_queue_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority, + unsigned long qpage, + unsigned long qsize) +{ + return H_TOO_HARD; +} + +int kvmppc_rm_h_int_get_queue_config(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long priority) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_get_queue_config(vcpu, flag, target, + priority); + if (unlikely(!__xive_vm_h_int_get_queue_config)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_get_queue_config(vcpu, flag, target, priority); +} + +int kvmppc_rm_h_int_set_os_reporting_line(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long line) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_set_os_reporting_line(vcpu, flag, line); + if (unlikely(!__xive_vm_h_int_set_os_reporting_line)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_set_os_reporting_line(vcpu, flag, line); +} + +int kvmppc_rm_h_int_get_os_reporting_line(struct kvm_vcpu *vcpu, + unsigned long flag, + unsigned long target, + unsigned long line) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_get_os_reporting_line(vcpu, + flag, target, line); + if (unlikely(!__xive_vm_h_int_get_os_reporting_line)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_get_os_reporting_line(vcpu, flag, target, line); +} + +int kvmppc_rm_h_int_esb(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn, unsigned long offset, + unsigned long data) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_esb(vcpu, flag, lisn, offset, data); + if (unlikely(!__xive_vm_h_int_esb)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_esb(vcpu, flag, lisn, offset, data); +} + +int kvmppc_rm_h_int_sync(struct kvm_vcpu *vcpu, unsigned long flag, + unsigned long lisn) +{ + if (!kvmppc_xive_enabled(vcpu)) + return H_TOO_HARD; + if (!xive_enabled()) + return H_TOO_HARD; + + if (is_rm()) + return xive_rm_h_int_sync(vcpu, flag, lisn); + if (unlikely(!__xive_vm_h_int_sync)) + return H_NOT_AVAILABLE; + return __xive_vm_h_int_sync(vcpu, flag, lisn); +} + +int kvmppc_rm_h_int_reset(struct kvm_vcpu *vcpu, unsigned long flag) +{ + return H_TOO_HARD; +} +#endif /* CONFIG_KVM_XIVE */ + void kvmppc_bad_interrupt(struct pt_regs *regs) { /* diff --git a/arch/powerpc/kvm/book3s_hv_rm_xive_native.c b/arch/powerpc/kvm/book3s_hv_rm_xive_native.c new file mode 100644 index 000000000000..0e72a6ae0f07 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_rm_xive_native.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "book3s_xive.h" + +/* XXX */ +#include +//#define DBG(fmt...) udbg_printf(fmt) +#define DBG(fmt...) do { } while (0) + +static inline void __iomem *get_tima_phys(void) +{ + return local_paca->kvm_hstate.xive_tima_phys; +} + +#undef XIVE_RUNTIME_CHECKS +#define X_PFX xive_rm_ +#define X_STATIC +#define X_STAT_PFX stat_rm_ +#define __x_tima get_tima_phys() +#define __x_eoi_page(xd) ((void __iomem *)((xd)->eoi_page)) +#define __x_trig_page(xd) ((void __iomem *)((xd)->trig_page)) +#define __x_writeb __raw_rm_writeb +#define __x_readw __raw_rm_readw +#define __x_readq __raw_rm_readq +#define __x_writeq __raw_rm_writeq + +#include "book3s_xive_native_template.c" diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 2518640d4a58..35d806740c3a 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -171,6 +171,56 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, return rc; } +static int kvmppc_xive_native_set_source_config(struct kvmppc_xive *xive, + struct kvmppc_xive_src_block *sb, + struct kvmppc_xive_irq_state *state, + u32 server, + u8 priority, + u32 eisn) +{ + struct kvm *kvm = xive->kvm; + u32 hw_num; + int rc = 0; + + /* + * TODO: Do we need to safely mask and unmask a source ? can + * we just let the guest handle the possible races ? + */ + arch_spin_lock(&sb->lock); + + if (state->act_server == server && state->act_priority == priority && + state->eisn == eisn) + goto unlock; + + pr_devel("new_act_prio=%d new_act_server=%d act_server=%d act_prio=%d\n", + priority, server, state->act_server, state->act_priority); + + kvmppc_xive_select_irq(state, &hw_num, NULL); + + if (priority != MASKED) { + rc = kvmppc_xive_select_target(kvm, &server, priority); + if (rc) + goto unlock; + + state->act_priority = priority; + state->act_server = server; + state->eisn = eisn; + + rc = xive_native_configure_irq(hw_num, xive->vp_base + server, + priority, eisn); + } else { + state->act_priority = MASKED; + state->act_server = 0; + state->eisn = 0; + + rc = xive_native_configure_irq(hw_num, 0, MASKED, 0); + } + +unlock: + arch_spin_unlock(&sb->lock); + return rc; +} + static int kvmppc_xive_native_set_vc_base(struct kvmppc_xive *xive, u64 addr) { u64 __user *ubufp = (u64 __user *) addr; @@ -323,6 +373,20 @@ static int kvmppc_xive_native_get_tima_fd(struct kvmppc_xive *xive, u64 addr) return put_user(ret, ubufp); } +static int xive_native_validate_queue_size(u32 qsize) +{ + switch (qsize) { + case 12: + case 16: + case 21: + case 24: + case 0: + return 0; + default: + return -EINVAL; + } +} + static int kvmppc_xive_native_set_source(struct kvmppc_xive *xive, long irq, u64 addr) { @@ -532,6 +596,248 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) return ret; } +static int kvmppc_h_int_set_source_config(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long irq, + unsigned long server, + unsigned long priority, + unsigned long eisn) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + int rc = 0; + u16 idx; + + pr_devel("H_INT_SET_SOURCE_CONFIG flags=%08lx irq=%lx server=%ld priority=%ld eisn=%lx\n", + flags, irq, server, priority, eisn); + + if (flags & ~(XIVE_SPAPR_SRC_SET_EISN | XIVE_SPAPR_SRC_MASK)) + return H_PARAMETER; + + sb = kvmppc_xive_find_source(xive, irq, &idx); + if (!sb) + return H_P2; + state = &sb->irq_state[idx]; + + if (!(flags & XIVE_SPAPR_SRC_SET_EISN)) + eisn = state->eisn; + + if (priority != xive_prio_from_guest(priority)) { + pr_err("invalid priority for queue %ld for VCPU %ld\n", + priority, server); + return H_P3; + } + + /* TODO: handle XIVE_SPAPR_SRC_MASK */ + + rc = kvmppc_xive_native_set_source_config(xive, sb, state, server, + priority, eisn); + if (!rc) + return H_SUCCESS; + else if (rc == -EINVAL) + return H_P4; /* no server found */ + else + return H_HARDWARE; +} + +static int kvmppc_h_int_set_queue_config(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long server, + unsigned long priority, + unsigned long qpage, + unsigned long qsize) +{ + struct kvm *kvm = vcpu->kvm; + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + struct xive_q *q; + int rc; + __be32 *qaddr = 0; + struct page *page; + + pr_devel("H_INT_SET_QUEUE_CONFIG flags=%08lx server=%ld priority=%ld qpage=%08lx qsize=%ld\n", + flags, server, priority, qpage, qsize); + + if (flags & ~XIVE_SPAPR_EQ_ALWAYS_NOTIFY) + return H_PARAMETER; + + if (xc->server_num != server) { + vcpu = kvmppc_xive_find_server(kvm, server); + if (!vcpu) { + pr_debug("Can't find server %ld\n", server); + return H_P2; + } + xc = vcpu->arch.xive_vcpu; + } + + if (priority != xive_prio_from_guest(priority) || priority == MASKED) { + pr_err("invalid priority for queue %ld for VCPU %d\n", + priority, xc->server_num); + return H_P3; + } + q = &xc->queues[priority]; + + rc = xive_native_validate_queue_size(qsize); + if (rc) { + pr_err("invalid queue size %ld\n", qsize); + return H_P5; + } + + /* reset queue and disable queueing */ + if (!qsize) { + rc = xive_native_configure_queue(xc->vp_id, q, priority, + NULL, 0, true); + if (rc) { + pr_err("Failed to reset queue %ld for VCPU %d: %d\n", + priority, xc->server_num, rc); + return H_HARDWARE; + } + + if (q->qpage) { + put_page(virt_to_page(q->qpage)); + q->qpage = NULL; + } + + return H_SUCCESS; + } + + page = gfn_to_page(kvm, gpa_to_gfn(qpage)); + if (is_error_page(page)) { + pr_warn("Couldn't get guest page for %lx!\n", qpage); + return H_P4; + } + qaddr = page_to_virt(page) + (qpage & ~PAGE_MASK); + + rc = xive_native_configure_queue(xc->vp_id, q, priority, + (__be32 *) qaddr, qsize, true); + if (rc) { + pr_err("Failed to configure queue %ld for VCPU %d: %d\n", + priority, xc->server_num, rc); + put_page(page); + return H_HARDWARE; + } + + rc = kvmppc_xive_attach_escalation(vcpu, priority); + if (rc) { + xive_native_cleanup_queue(vcpu, priority); + return H_HARDWARE; + } + + return H_SUCCESS; +} + +static void kvmppc_xive_reset_sources(struct kvmppc_xive_src_block *sb) +{ + int i; + + for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) { + struct kvmppc_xive_irq_state *state = &sb->irq_state[i]; + + if (!state->valid) + continue; + + if (state->act_priority == MASKED) + continue; + + arch_spin_lock(&sb->lock); + state->eisn = 0; + state->act_server = 0; + state->act_priority = MASKED; + xive_vm_esb_load(&state->ipi_data, XIVE_ESB_SET_PQ_01); + xive_native_configure_irq(state->ipi_number, 0, MASKED, 0); + if (state->pt_number) { + xive_vm_esb_load(state->pt_data, XIVE_ESB_SET_PQ_01); + xive_native_configure_irq(state->pt_number, + 0, MASKED, 0); + } + arch_spin_unlock(&sb->lock); + } +} + +static int kvmppc_h_int_reset(struct kvmppc_xive *xive, unsigned long flags) +{ + struct kvm *kvm = xive->kvm; + struct kvm_vcpu *vcpu; + unsigned int i; + + pr_devel("H_INT_RESET flags=%08lx\n", flags); + + if (flags) + return H_PARAMETER; + + mutex_lock(&kvm->lock); + + kvm_for_each_vcpu(i, vcpu, kvm) { + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + unsigned int prio; + + if (!xc) + continue; + + kvmppc_xive_disable_vcpu_interrupts(vcpu); + + for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) { + + if (xc->esc_virq[prio]) { + free_irq(xc->esc_virq[prio], vcpu); + irq_dispose_mapping(xc->esc_virq[prio]); + kfree(xc->esc_virq_names[prio]); + xc->esc_virq[prio] = 0; + } + + xive_native_cleanup_queue(vcpu, prio); + } + } + + for (i = 0; i <= xive->max_sbid; i++) { + if (xive->src_blocks[i]) + kvmppc_xive_reset_sources(xive->src_blocks[i]); + } + + mutex_unlock(&kvm->lock); + + return H_SUCCESS; +} + +int kvmppc_xive_native_hcall(struct kvm_vcpu *vcpu, u32 req) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + int rc; + + if (!xive || !vcpu->arch.xive_vcpu) + return H_FUNCTION; + + switch (req) { + case H_INT_SET_QUEUE_CONFIG: + rc = kvmppc_h_int_set_queue_config(vcpu, + kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5), + kvmppc_get_gpr(vcpu, 6), + kvmppc_get_gpr(vcpu, 7), + kvmppc_get_gpr(vcpu, 8)); + break; + + case H_INT_SET_SOURCE_CONFIG: + rc = kvmppc_h_int_set_source_config(vcpu, + kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5), + kvmppc_get_gpr(vcpu, 6), + kvmppc_get_gpr(vcpu, 7), + kvmppc_get_gpr(vcpu, 8)); + break; + + case H_INT_RESET: + rc = kvmppc_h_int_reset(xive, kvmppc_get_gpr(vcpu, 4)); + break; + + default: + rc = H_NOT_AVAILABLE; + } + + return rc; +} +EXPORT_SYMBOL_GPL(kvmppc_xive_native_hcall); + static int xive_native_debug_show(struct seq_file *m, void *private) { struct kvmppc_xive *xive = m->private; @@ -614,10 +920,26 @@ struct kvm_device_ops kvm_xive_native_ops = { void kvmppc_xive_native_init_module(void) { - ; + __xive_vm_h_int_get_source_info = xive_vm_h_int_get_source_info; + __xive_vm_h_int_get_source_config = xive_vm_h_int_get_source_config; + __xive_vm_h_int_get_queue_info = xive_vm_h_int_get_queue_info; + __xive_vm_h_int_get_queue_config = xive_vm_h_int_get_queue_config; + __xive_vm_h_int_set_os_reporting_line = + xive_vm_h_int_set_os_reporting_line; + __xive_vm_h_int_get_os_reporting_line = + xive_vm_h_int_get_os_reporting_line; + __xive_vm_h_int_esb = xive_vm_h_int_esb; + __xive_vm_h_int_sync = xive_vm_h_int_sync; } void kvmppc_xive_native_exit_module(void) { - ; + __xive_vm_h_int_get_source_info = NULL; + __xive_vm_h_int_get_source_config = NULL; + __xive_vm_h_int_get_queue_info = NULL; + __xive_vm_h_int_get_queue_config = NULL; + __xive_vm_h_int_set_os_reporting_line = NULL; + __xive_vm_h_int_get_os_reporting_line = NULL; + __xive_vm_h_int_esb = NULL; + __xive_vm_h_int_sync = NULL; } diff --git a/arch/powerpc/kvm/book3s_xive_native_template.c b/arch/powerpc/kvm/book3s_xive_native_template.c index e7260da4a596..ccde2786d203 100644 --- a/arch/powerpc/kvm/book3s_xive_native_template.c +++ b/arch/powerpc/kvm/book3s_xive_native_template.c @@ -8,6 +8,279 @@ #define XGLUE(a, b) a##b #define GLUE(a, b) XGLUE(a, b) +X_STATIC int GLUE(X_PFX, h_int_get_source_info)(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long irq) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + struct xive_irq_data *xd; + u32 hw_num; + u16 src; + unsigned long esb_addr; + + pr_devel("H_INT_GET_SOURCE_INFO flags=%08lx irq=%lx\n", flags, irq); + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) { + pr_debug("source %lx not found !\n", irq); + return H_P2; + } + state = &sb->irq_state[src]; + + arch_spin_lock(&sb->lock); + kvmppc_xive_select_irq(state, &hw_num, &xd); + + vcpu->arch.regs.gpr[4] = 0; + if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) + vcpu->arch.regs.gpr[4] |= XIVE_SPAPR_SRC_STORE_EOI; + + /* + * Force the use of the H_INT_ESB hcall in case of a Virtual + * LSI interrupt. This is necessary under KVM to re-trigger + * the interrupt if the level is still asserted + */ + if (state->lsi) { + vcpu->arch.regs.gpr[4] |= XIVE_SPAPR_SRC_LSI; + vcpu->arch.regs.gpr[4] |= XIVE_SPAPR_SRC_H_INT_ESB; + } + + /* + * Linux/KVM uses a two pages ESB setting, one for trigger and + * one for EOI + */ + esb_addr = xive->vc_base + (irq << (PAGE_SHIFT + 1)); + + /* EOI/management page is the second/odd page */ + if (xd->eoi_page && + !(vcpu->arch.regs.gpr[4] & XIVE_SPAPR_SRC_H_INT_ESB)) + vcpu->arch.regs.gpr[5] = esb_addr + (1ull << PAGE_SHIFT); + else + vcpu->arch.regs.gpr[5] = -1; + + /* Trigger page is always the first/even page */ + if (xd->trig_page) + vcpu->arch.regs.gpr[6] = esb_addr; + else + vcpu->arch.regs.gpr[6] = -1; + + vcpu->arch.regs.gpr[7] = PAGE_SHIFT; + arch_spin_unlock(&sb->lock); + return H_SUCCESS; +} + +X_STATIC int GLUE(X_PFX, h_int_get_source_config)(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long irq) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + u16 src; + + pr_devel("H_INT_GET_SOURCE_CONFIG flags=%08lx irq=%lx\n", flags, irq); + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) { + pr_debug("source %lx not found !\n", irq); + return H_P2; + } + state = &sb->irq_state[src]; + + arch_spin_lock(&sb->lock); + vcpu->arch.regs.gpr[4] = state->act_server; + vcpu->arch.regs.gpr[5] = state->act_priority; + vcpu->arch.regs.gpr[6] = state->number; + arch_spin_unlock(&sb->lock); + + return H_SUCCESS; +} + +X_STATIC int GLUE(X_PFX, h_int_get_queue_info)(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long server, + unsigned long priority) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + struct xive_q *q; + + pr_devel("H_INT_GET_QUEUE_INFO flags=%08lx server=%ld priority=%ld\n", + flags, server, priority); + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + if (xc->server_num != server) { + struct kvm_vcpu *vc; + + vc = kvmppc_xive_find_server(vcpu->kvm, server); + if (!vc) { + pr_debug("server %ld not found\n", server); + return H_P2; + } + xc = vc->arch.xive_vcpu; + } + + if (priority != xive_prio_from_guest(priority) || priority == MASKED) { + pr_debug("invalid priority for queue %ld for VCPU %ld\n", + priority, server); + return H_P3; + } + q = &xc->queues[priority]; + + vcpu->arch.regs.gpr[4] = q->eoi_phys; + /* TODO: Power of 2 page size of the notification page */ + vcpu->arch.regs.gpr[5] = 0; + return H_SUCCESS; +} + +X_STATIC int GLUE(X_PFX, get_queue_state)(struct kvm_vcpu *vcpu, + struct kvmppc_xive_vcpu *xc, + unsigned long prio) +{ + int rc; + u32 qtoggle; + u32 qindex; + + rc = xive_native_get_queue_state(xc->vp_id, prio, &qtoggle, &qindex); + if (rc) + return rc; + + vcpu->arch.regs.gpr[4] |= ((unsigned long) qtoggle) << 62; + vcpu->arch.regs.gpr[7] = qindex; + return 0; +} + +X_STATIC int GLUE(X_PFX, h_int_get_queue_config)(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long server, + unsigned long priority) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + struct xive_q *q; + u64 qpage; + u64 qsize; + u64 qeoi_page; + u32 escalate_irq; + u64 qflags; + int rc; + + pr_devel("H_INT_GET_QUEUE_CONFIG flags=%08lx server=%ld priority=%ld\n", + flags, server, priority); + + if (!xive) + return H_FUNCTION; + + if (flags & ~XIVE_SPAPR_EQ_DEBUG) + return H_PARAMETER; + + if (xc->server_num != server) { + struct kvm_vcpu *vc; + + vc = kvmppc_xive_find_server(vcpu->kvm, server); + if (!vc) { + pr_debug("server %ld not found\n", server); + return H_P2; + } + xc = vc->arch.xive_vcpu; + } + + if (priority != xive_prio_from_guest(priority) || priority == MASKED) { + pr_debug("invalid priority for queue %ld for VCPU %ld\n", + priority, server); + return H_P3; + } + q = &xc->queues[priority]; + + rc = xive_native_get_queue_info(xc->vp_id, priority, &qpage, &qsize, + &qeoi_page, &escalate_irq, &qflags); + if (rc) + return H_HARDWARE; + + vcpu->arch.regs.gpr[4] = 0; + if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY) + vcpu->arch.regs.gpr[4] |= XIVE_SPAPR_EQ_ALWAYS_NOTIFY; + + vcpu->arch.regs.gpr[5] = qpage; + vcpu->arch.regs.gpr[6] = qsize; + if (flags & XIVE_SPAPR_EQ_DEBUG) { + rc = GLUE(X_PFX, get_queue_state)(vcpu, xc, priority); + if (rc) + return H_HARDWARE; + } + return H_SUCCESS; +} + +/* TODO H_INT_SET_OS_REPORTING_LINE */ +X_STATIC int GLUE(X_PFX, h_int_set_os_reporting_line)(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long line) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + + pr_devel("H_INT_SET_OS_REPORTING_LINE flags=%08lx line=%ld\n", + flags, line); + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + return H_FUNCTION; +} + +/* TODO H_INT_GET_OS_REPORTING_LINE*/ +X_STATIC int GLUE(X_PFX, h_int_get_os_reporting_line)(struct kvm_vcpu *vcpu, + unsigned long flags, + unsigned long server, + unsigned long line) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + + pr_devel("H_INT_GET_OS_REPORTING_LINE flags=%08lx server=%ld line=%ld\n", + flags, server, line); + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + if (xc->server_num != server) { + struct kvm_vcpu *vc; + + vc = kvmppc_xive_find_server(vcpu->kvm, server); + if (!vc) { + pr_debug("server %ld not found\n", server); + return H_P2; + } + xc = vc->arch.xive_vcpu; + } + + return H_FUNCTION; + +} + /* * TODO: introduce a common template file with the XIVE native layer * and the XICS-on-XIVE glue for the utility functions @@ -25,3 +298,101 @@ static u8 GLUE(X_PFX, esb_load)(struct xive_irq_data *xd, u32 offset) #endif return (u8)val; } + +static u8 GLUE(X_PFX, esb_store)(struct xive_irq_data *xd, u32 offset, u64 data) +{ + u64 val; + + if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) + offset |= offset << 4; + + val = __x_readq(__x_eoi_page(xd) + offset); +#ifdef __LITTLE_ENDIAN__ + val >>= 64-8; +#endif + return (u8)val; +} + +X_STATIC int GLUE(X_PFX, h_int_esb)(struct kvm_vcpu *vcpu, unsigned long flags, + unsigned long irq, unsigned long offset, + unsigned long data) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + struct xive_irq_data *xd; + u32 hw_num; + u16 src; + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) { + pr_debug("source %lx not found !\n", irq); + return H_P2; + } + state = &sb->irq_state[src]; + + if (offset > (1ull << PAGE_SHIFT)) + return H_P3; + + arch_spin_lock(&sb->lock); + kvmppc_xive_select_irq(state, &hw_num, &xd); + + if (flags & XIVE_SPAPR_ESB_STORE) { + GLUE(X_PFX, esb_store)(xd, offset, data); + vcpu->arch.regs.gpr[4] = -1; + } else { + /* Virtual LSI EOI handling */ + if (state->lsi && offset == XIVE_ESB_LOAD_EOI) { + GLUE(X_PFX, esb_load)(xd, XIVE_ESB_SET_PQ_00); + if (state->asserted && __x_trig_page(xd)) + __x_writeq(0, __x_trig_page(xd)); + vcpu->arch.regs.gpr[4] = 0; + } else { + vcpu->arch.regs.gpr[4] = + GLUE(X_PFX, esb_load)(xd, offset); + } + } + arch_spin_unlock(&sb->lock); + + return H_SUCCESS; +} + +X_STATIC int GLUE(X_PFX, h_int_sync)(struct kvm_vcpu *vcpu, unsigned long flags, + unsigned long irq) +{ + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + struct xive_irq_data *xd; + u32 hw_num; + u16 src; + + pr_devel("H_INT_SYNC flags=%08lx irq=%lx\n", flags, irq); + + if (!xive) + return H_FUNCTION; + + if (flags) + return H_PARAMETER; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) { + pr_debug("source %lx not found !\n", irq); + return H_P2; + } + state = &sb->irq_state[src]; + + arch_spin_lock(&sb->lock); + + kvmppc_xive_select_irq(state, &hw_num, &xd); + xive_native_sync_source(hw_num); + + arch_spin_unlock(&sb->lock); + return H_SUCCESS; +} diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 806cbe488410..1a5c65c59b13 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -81,6 +81,8 @@ kvm-hv-$(CONFIG_PPC_TRANSACTIONAL_MEM) += \ kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XICS) := \ book3s_hv_rm_xics.o book3s_hv_rm_xive.o +kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XIVE) += \ + book3s_hv_rm_xive_native.o kvm-book3s_64-builtin-tm-objs-$(CONFIG_PPC_TRANSACTIONAL_MEM) += \ book3s_hv_tm_builtin.o diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 9b8d50a7cbaf..25b9489de249 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2462,6 +2462,58 @@ hcall_real_table: .long 0 /* 0x2fc - H_XIRR_X*/ #endif .long DOTSYM(kvmppc_h_random) - hcall_real_table + .long 0 /* 0x304 */ + .long 0 /* 0x308 */ + .long 0 /* 0x30c */ + .long 0 /* 0x310 */ + .long 0 /* 0x314 */ + .long 0 /* 0x318 */ + .long 0 /* 0x31c */ + .long 0 /* 0x320 */ + .long 0 /* 0x324 */ + .long 0 /* 0x328 */ + .long 0 /* 0x32c */ + .long 0 /* 0x330 */ + .long 0 /* 0x334 */ + .long 0 /* 0x338 */ + .long 0 /* 0x33c */ + .long 0 /* 0x340 */ + .long 0 /* 0x344 */ + .long 0 /* 0x348 */ + .long 0 /* 0x34c */ + .long 0 /* 0x350 */ + .long 0 /* 0x354 */ + .long 0 /* 0x358 */ + .long 0 /* 0x35c */ + .long 0 /* 0x360 */ + .long 0 /* 0x364 */ + .long 0 /* 0x368 */ + .long 0 /* 0x36c */ + .long 0 /* 0x370 */ + .long 0 /* 0x374 */ + .long 0 /* 0x378 */ + .long 0 /* 0x37c */ + .long 0 /* 0x380 */ + .long 0 /* 0x384 */ + .long 0 /* 0x388 */ + .long 0 /* 0x38c */ + .long 0 /* 0x390 */ + .long 0 /* 0x394 */ + .long 0 /* 0x398 */ + .long 0 /* 0x39c */ + .long 0 /* 0x3a0 */ + .long 0 /* 0x3a4 */ + .long DOTSYM(kvmppc_rm_h_int_get_source_info) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_set_source_config) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_get_source_config) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_get_queue_info) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_set_queue_config) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_get_queue_config) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_set_os_reporting_line) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_get_os_reporting_line) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_esb) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_sync) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_int_reset) - hcall_real_table .globl hcall_real_table_end hcall_real_table_end: From patchwork Mon Jan 7 18:43:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751285 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE63C91E for ; Mon, 7 Jan 2019 23:31:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B062928AD6 for ; Mon, 7 Jan 2019 23:31:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A0A6728ADC; Mon, 7 Jan 2019 23:31:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A08228AD6 for ; Mon, 7 Jan 2019 23:31:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727057AbfAGXbz (ORCPT ); Mon, 7 Jan 2019 18:31:55 -0500 Received: from 13.mo1.mail-out.ovh.net ([178.33.253.128]:41828 "EHLO 13.mo1.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726668AbfAGXbz (ORCPT ); Mon, 7 Jan 2019 18:31:55 -0500 X-Greylist: delayed 16788 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 18:31:54 EST Received: from player737.ha.ovh.net (unknown [10.109.160.93]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id BA94A14CED7 for ; Mon, 7 Jan 2019 19:46:04 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 4FF9F18664E9; Mon, 7 Jan 2019 18:45:55 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 12/19] KVM: PPC: Book3S HV: record guest queue page address Date: Mon, 7 Jan 2019 19:43:24 +0100 Message-Id: <20190107184331.8429-13-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11415499157494402007 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The guest physical address of the event queue will be part of the state to transfer in the migration. Cache its value when the queue is configured, it will save us an OPAL call. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/asm/xive.h | 2 ++ arch/powerpc/kvm/book3s_xive_native.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index 7a7aa22d8258..e90c3c5d9533 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -74,6 +74,8 @@ struct xive_q { u32 esc_irq; atomic_t count; atomic_t pending_count; + u64 guest_qpage; + u32 guest_qsize; }; /* Global enable flags for the XIVE support */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 35d806740c3a..4ca75aade069 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -708,6 +708,10 @@ static int kvmppc_h_int_set_queue_config(struct kvm_vcpu *vcpu, } qaddr = page_to_virt(page) + (qpage & ~PAGE_MASK); + /* Backup queue page address and size for migration */ + q->guest_qpage = qpage; + q->guest_qsize = qsize; + rc = xive_native_configure_queue(xc->vp_id, q, priority, (__be32 *) qaddr, qsize, true); if (rc) { From patchwork Mon Jan 7 18:43:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751217 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9A5DA91E for ; Mon, 7 Jan 2019 21:13:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8817228A3D for ; Mon, 7 Jan 2019 21:13:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 764AC28A4E; Mon, 7 Jan 2019 21:13:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E09C028A3D for ; Mon, 7 Jan 2019 21:13:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726816AbfAGVNA (ORCPT ); Mon, 7 Jan 2019 16:13:00 -0500 Received: from 5.mo3.mail-out.ovh.net ([87.98.178.36]:34307 "EHLO 5.mo3.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726721AbfAGVNA (ORCPT ); Mon, 7 Jan 2019 16:13:00 -0500 X-Greylist: delayed 6599 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 16:12:59 EST Received: from player737.ha.ovh.net (unknown [10.109.159.248]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 60C071EF48E for ; Mon, 7 Jan 2019 19:46:15 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id B6A0D1866519; Mon, 7 Jan 2019 18:46:04 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 13/19] KVM: PPC: Book3S HV: add a SYNC control for the XIVE native migration Date: Mon, 7 Jan 2019 19:43:25 +0100 Message-Id: <20190107184331.8429-14-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11418595380442598359 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When migration of a VM is initiated, a first copy of the RAM is transferred to the destination before the VM is stopped. At that time, QEMU needs to perform a XIVE quiesce sequence to stop the flow of event notifications and stabilize the EQs. The sources are masked and the XIVE IC is synced with the KVM ioctl KVM_DEV_XIVE_GRP_SYNC. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 1 + arch/powerpc/kvm/book3s_xive_native.c | 32 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 6fc9660c5aec..f3b859223b80 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -681,6 +681,7 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_GET_TIMA_FD 2 #define KVM_DEV_XIVE_VC_BASE 3 #define KVM_DEV_XIVE_GRP_SOURCES 2 /* 64-bit source attributes */ +#define KVM_DEV_XIVE_GRP_SYNC 3 /* 64-bit source attributes */ /* Layout of 64-bit XIVE source attribute values */ #define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0) diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 4ca75aade069..a8052867afc1 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -459,6 +459,35 @@ static int kvmppc_xive_native_set_source(struct kvmppc_xive *xive, long irq, return 0; } +static int kvmppc_xive_native_sync(struct kvmppc_xive *xive, long irq, u64 addr) +{ + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + struct xive_irq_data *xd; + u32 hw_num; + u16 src; + + pr_devel("%s irq=0x%lx\n", __func__, irq); + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) + return -ENOENT; + + state = &sb->irq_state[src]; + + if (!state->valid) + return -ENOENT; + + arch_spin_lock(&sb->lock); + + kvmppc_xive_select_irq(state, &hw_num, &xd); + xive_native_sync_source(hw_num); + xive_native_sync_queue(hw_num); + + arch_spin_unlock(&sb->lock); + return 0; +} + static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -474,6 +503,8 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev, case KVM_DEV_XIVE_GRP_SOURCES: return kvmppc_xive_native_set_source(xive, attr->attr, attr->addr); + case KVM_DEV_XIVE_GRP_SYNC: + return kvmppc_xive_native_sync(xive, attr->attr, attr->addr); } return -ENXIO; } @@ -511,6 +542,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, } break; case KVM_DEV_XIVE_GRP_SOURCES: + case KVM_DEV_XIVE_GRP_SYNC: if (attr->attr >= KVMPPC_XIVE_FIRST_IRQ && attr->attr < KVMPPC_XIVE_NR_IRQS) return 0; From patchwork Mon Jan 7 18:43:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751109 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 766E7746 for ; Mon, 7 Jan 2019 19:01:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 671CC289B1 for ; Mon, 7 Jan 2019 19:01:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58856289B3; Mon, 7 Jan 2019 19:01:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C702D289B1 for ; Mon, 7 Jan 2019 19:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727987AbfAGTBr (ORCPT ); Mon, 7 Jan 2019 14:01:47 -0500 Received: from 12.mo7.mail-out.ovh.net ([178.33.107.167]:37102 "EHLO 12.mo7.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727637AbfAGTBp (ORCPT ); Mon, 7 Jan 2019 14:01:45 -0500 X-Greylist: delayed 915 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 14:01:44 EST Received: from player737.ha.ovh.net (unknown [10.109.143.201]) by mo7.mail-out.ovh.net (Postfix) with ESMTP id 826CCF2C1B for ; Mon, 7 Jan 2019 19:46:26 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 62C961866544; Mon, 7 Jan 2019 18:46:15 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 14/19] KVM: PPC: Book3S HV: add a control to make the XIVE EQ pages dirty Date: Mon, 7 Jan 2019 19:43:26 +0100 Message-Id: <20190107184331.8429-15-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11421691606781299671 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When the VM is stopped in a migration sequence, the sources are masked and the XIVE IC is synced to stabilize the EQs. When done, the KVM ioctl KVM_DEV_XIVE_SAVE_EQ_PAGES is called to mark dirty the EQ pages. The migration can then transfer the remaining dirty pages to the destination and start collecting the state of the devices. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 1 + arch/powerpc/kvm/book3s_xive_native.c | 40 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index f3b859223b80..1a8740629acf 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -680,6 +680,7 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_GET_ESB_FD 1 #define KVM_DEV_XIVE_GET_TIMA_FD 2 #define KVM_DEV_XIVE_VC_BASE 3 +#define KVM_DEV_XIVE_SAVE_EQ_PAGES 4 #define KVM_DEV_XIVE_GRP_SOURCES 2 /* 64-bit source attributes */ #define KVM_DEV_XIVE_GRP_SYNC 3 /* 64-bit source attributes */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index a8052867afc1..f2de1bcf3b35 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -373,6 +373,43 @@ static int kvmppc_xive_native_get_tima_fd(struct kvmppc_xive *xive, u64 addr) return put_user(ret, ubufp); } +static int kvmppc_xive_native_vcpu_save_eq_pages(struct kvm_vcpu *vcpu) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + unsigned int prio; + + if (!xc) + return -ENOENT; + + for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) { + struct xive_q *q = &xc->queues[prio]; + + if (!q->qpage) + continue; + + /* Mark EQ page dirty for migration */ + mark_page_dirty(vcpu->kvm, gpa_to_gfn(q->guest_qpage)); + } + return 0; +} + +static int kvmppc_xive_native_save_eq_pages(struct kvmppc_xive *xive) +{ + struct kvm *kvm = xive->kvm; + struct kvm_vcpu *vcpu; + unsigned int i; + + pr_devel("%s\n", __func__); + + mutex_lock(&kvm->lock); + kvm_for_each_vcpu(i, vcpu, kvm) { + kvmppc_xive_native_vcpu_save_eq_pages(vcpu); + } + mutex_unlock(&kvm->lock); + + return 0; +} + static int xive_native_validate_queue_size(u32 qsize) { switch (qsize) { @@ -498,6 +535,8 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev, switch (attr->attr) { case KVM_DEV_XIVE_VC_BASE: return kvmppc_xive_native_set_vc_base(xive, attr->addr); + case KVM_DEV_XIVE_SAVE_EQ_PAGES: + return kvmppc_xive_native_save_eq_pages(xive); } break; case KVM_DEV_XIVE_GRP_SOURCES: @@ -538,6 +577,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, case KVM_DEV_XIVE_GET_ESB_FD: case KVM_DEV_XIVE_GET_TIMA_FD: case KVM_DEV_XIVE_VC_BASE: + case KVM_DEV_XIVE_SAVE_EQ_PAGES: return 0; } break; From patchwork Mon Jan 7 18:43:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751075 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6F7A6C5 for ; Mon, 7 Jan 2019 18:51:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B7D94289AA for ; Mon, 7 Jan 2019 18:51:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AC5CC289B0; Mon, 7 Jan 2019 18:51:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2E920289AA for ; Mon, 7 Jan 2019 18:51:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727316AbfAGSvv (ORCPT ); Mon, 7 Jan 2019 13:51:51 -0500 Received: from 4.mo1.mail-out.ovh.net ([46.105.76.26]:42103 "EHLO 4.mo1.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726907AbfAGSvu (ORCPT ); Mon, 7 Jan 2019 13:51:50 -0500 X-Greylist: delayed 399 seconds by postgrey-1.27 at vger.kernel.org; Mon, 07 Jan 2019 13:51:49 EST Received: from player737.ha.ovh.net (unknown [10.109.146.5]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id 3CDAE14CE40 for ; Mon, 7 Jan 2019 19:46:38 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 89F9A1866589; Mon, 7 Jan 2019 18:46:26 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 15/19] KVM: PPC: Book3S HV: add get/set accessors for the source configuration Date: Mon, 7 Jan 2019 19:43:27 +0100 Message-Id: <20190107184331.8429-16-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11425069306851462103 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Theses are use to capure the XIVE EAS table of the KVM device, the configuration of the source targets. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 11 ++++ arch/powerpc/kvm/book3s_xive_native.c | 87 +++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 1a8740629acf..faf024f39858 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -683,9 +683,20 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_SAVE_EQ_PAGES 4 #define KVM_DEV_XIVE_GRP_SOURCES 2 /* 64-bit source attributes */ #define KVM_DEV_XIVE_GRP_SYNC 3 /* 64-bit source attributes */ +#define KVM_DEV_XIVE_GRP_EAS 4 /* 64-bit eas attributes */ /* 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 eas attribute values */ +#define KVM_XIVE_EAS_PRIORITY_SHIFT 0 +#define KVM_XIVE_EAS_PRIORITY_MASK 0x7 +#define KVM_XIVE_EAS_SERVER_SHIFT 3 +#define KVM_XIVE_EAS_SERVER_MASK 0xfffffff8ULL +#define KVM_XIVE_EAS_MASK_SHIFT 32 +#define KVM_XIVE_EAS_MASK_MASK 0x100000000ULL +#define KVM_XIVE_EAS_EISN_SHIFT 33 +#define KVM_XIVE_EAS_EISN_MASK 0xfffffffe00000000ULL + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index f2de1bcf3b35..0468b605baa7 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -525,6 +525,88 @@ static int kvmppc_xive_native_sync(struct kvmppc_xive *xive, long irq, u64 addr) return 0; } +static int kvmppc_xive_native_set_eas(struct kvmppc_xive *xive, long irq, + u64 addr) +{ + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + u64 __user *ubufp = (u64 __user *) addr; + u16 src; + u64 kvm_eas; + u32 server; + u8 priority; + u32 eisn; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) + return -ENOENT; + + state = &sb->irq_state[src]; + + if (!state->valid) + return -EINVAL; + + if (get_user(kvm_eas, ubufp)) + return -EFAULT; + + pr_devel("%s irq=0x%lx eas=%016llx\n", __func__, irq, kvm_eas); + + priority = (kvm_eas & KVM_XIVE_EAS_PRIORITY_MASK) >> + KVM_XIVE_EAS_PRIORITY_SHIFT; + server = (kvm_eas & KVM_XIVE_EAS_SERVER_MASK) >> + KVM_XIVE_EAS_SERVER_SHIFT; + eisn = (kvm_eas & KVM_XIVE_EAS_EISN_MASK) >> KVM_XIVE_EAS_EISN_SHIFT; + + if (priority != xive_prio_from_guest(priority)) { + pr_err("invalid priority for queue %d for VCPU %d\n", + priority, server); + return -EINVAL; + } + + return kvmppc_xive_native_set_source_config(xive, sb, state, server, + priority, eisn); +} + +static int kvmppc_xive_native_get_eas(struct kvmppc_xive *xive, long irq, + u64 addr) +{ + struct kvmppc_xive_src_block *sb; + struct kvmppc_xive_irq_state *state; + u64 __user *ubufp = (u64 __user *) addr; + u16 src; + u64 kvm_eas; + + sb = kvmppc_xive_find_source(xive, irq, &src); + if (!sb) + return -ENOENT; + + state = &sb->irq_state[src]; + + if (!state->valid) + return -EINVAL; + + arch_spin_lock(&sb->lock); + + if (state->act_priority == MASKED) + kvm_eas = KVM_XIVE_EAS_MASK_MASK; + else { + kvm_eas = (state->act_priority << KVM_XIVE_EAS_PRIORITY_SHIFT) & + KVM_XIVE_EAS_PRIORITY_MASK; + kvm_eas |= (state->act_server << KVM_XIVE_EAS_SERVER_SHIFT) & + KVM_XIVE_EAS_SERVER_MASK; + kvm_eas |= ((u64) state->eisn << KVM_XIVE_EAS_EISN_SHIFT) & + KVM_XIVE_EAS_EISN_MASK; + } + arch_spin_unlock(&sb->lock); + + pr_devel("%s irq=0x%lx eas=%016llx\n", __func__, irq, kvm_eas); + + if (put_user(kvm_eas, ubufp)) + return -EFAULT; + + return 0; +} + static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -544,6 +626,8 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev, attr->addr); case KVM_DEV_XIVE_GRP_SYNC: return kvmppc_xive_native_sync(xive, attr->attr, attr->addr); + case KVM_DEV_XIVE_GRP_EAS: + return kvmppc_xive_native_set_eas(xive, attr->attr, attr->addr); } return -ENXIO; } @@ -564,6 +648,8 @@ static int kvmppc_xive_native_get_attr(struct kvm_device *dev, return kvmppc_xive_native_get_vc_base(xive, attr->addr); } break; + case KVM_DEV_XIVE_GRP_EAS: + return kvmppc_xive_native_get_eas(xive, attr->attr, attr->addr); } return -ENXIO; } @@ -583,6 +669,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, break; case KVM_DEV_XIVE_GRP_SOURCES: case KVM_DEV_XIVE_GRP_SYNC: + case KVM_DEV_XIVE_GRP_EAS: if (attr->attr >= KVMPPC_XIVE_FIRST_IRQ && attr->attr < KVMPPC_XIVE_NR_IRQS) return 0; From patchwork Mon Jan 7 18:43:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751117 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D8F686C5 for ; Mon, 7 Jan 2019 19:02:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C939F289B1 for ; Mon, 7 Jan 2019 19:02:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BDA34289B3; Mon, 7 Jan 2019 19:02:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0FF94289B1 for ; Mon, 7 Jan 2019 19:02:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727301AbfAGTCO (ORCPT ); Mon, 7 Jan 2019 14:02:14 -0500 Received: from 9.mo179.mail-out.ovh.net ([46.105.76.148]:34472 "EHLO 9.mo179.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727410AbfAGTCN (ORCPT ); Mon, 7 Jan 2019 14:02:13 -0500 Received: from player737.ha.ovh.net (unknown [10.109.146.5]) by mo179.mail-out.ovh.net (Postfix) with ESMTP id 45A1110F8FE for ; Mon, 7 Jan 2019 19:46:49 +0100 (CET) Received: from kaod.org (lfbn-1-10605-110.w90-89.abo.wanadoo.fr [90.89.196.110]) (Authenticated sender: clg@kaod.org) by player737.ha.ovh.net (Postfix) with ESMTPSA id 3C26918665BD; Mon, 7 Jan 2019 18:46:38 +0000 (UTC) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 16/19] KVM: PPC: Book3S HV: add get/set accessors for the EQ configuration Date: Mon, 7 Jan 2019 19:43:28 +0100 Message-Id: <20190107184331.8429-17-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11428165532934179799 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtledrvdejgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP These are used to capture the XIVE END table of the KVM device. It relies on an OPAL call to retrieve from the XIVE IC the EQ toggle bit and index which are updated by the HW when events are enqueued in the guest RAM. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/uapi/asm/kvm.h | 21 ++++ arch/powerpc/kvm/book3s_xive_native.c | 166 ++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index faf024f39858..95302558ce10 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -684,6 +684,7 @@ struct kvm_ppc_cpu_char { #define KVM_DEV_XIVE_GRP_SOURCES 2 /* 64-bit source attributes */ #define KVM_DEV_XIVE_GRP_SYNC 3 /* 64-bit source attributes */ #define KVM_DEV_XIVE_GRP_EAS 4 /* 64-bit eas attributes */ +#define KVM_DEV_XIVE_GRP_EQ 5 /* 64-bit eq attributes */ /* Layout of 64-bit XIVE source attribute values */ #define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0) @@ -699,4 +700,24 @@ struct kvm_ppc_cpu_char { #define KVM_XIVE_EAS_EISN_SHIFT 33 #define KVM_XIVE_EAS_EISN_MASK 0xfffffffe00000000ULL +/* Layout of 64-bit eq attribute */ +#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 64-bit eq attribute values */ +struct kvm_ppc_xive_eq { + __u32 flags; + __u32 qsize; + __u64 qpage; + __u32 qtoggle; + __u32 qindex; +}; + +#define KVM_XIVE_EQ_FLAG_ENABLED 0x00000001 +#define KVM_XIVE_EQ_FLAG_ALWAYS_NOTIFY 0x00000002 +#define KVM_XIVE_EQ_FLAG_ESCALATE 0x00000004 + + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 0468b605baa7..f4eb71eafc57 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -607,6 +607,164 @@ static int kvmppc_xive_native_get_eas(struct kvmppc_xive *xive, long irq, return 0; } +static int kvmppc_xive_native_set_queue(struct kvmppc_xive *xive, long eq_idx, + u64 addr) +{ + struct kvm *kvm = xive->kvm; + struct kvm_vcpu *vcpu; + struct kvmppc_xive_vcpu *xc; + void __user *ubufp = (u64 __user *) addr; + u32 server; + u8 priority; + struct kvm_ppc_xive_eq kvm_eq; + int rc; + __be32 *qaddr = 0; + struct page *page; + struct xive_q *q; + + /* + * Demangle priority/server tuple from the EQ index + */ + priority = (eq_idx & KVM_XIVE_EQ_PRIORITY_MASK) >> + KVM_XIVE_EQ_PRIORITY_SHIFT; + server = (eq_idx & KVM_XIVE_EQ_SERVER_MASK) >> + KVM_XIVE_EQ_SERVER_SHIFT; + + if (copy_from_user(&kvm_eq, ubufp, sizeof(kvm_eq))) + return -EFAULT; + + vcpu = kvmppc_xive_find_server(kvm, server); + if (!vcpu) { + pr_err("Can't find server %d\n", server); + return -ENOENT; + } + xc = vcpu->arch.xive_vcpu; + + if (priority != xive_prio_from_guest(priority)) { + pr_err("Trying to restore invalid queue %d for VCPU %d\n", + priority, server); + return -EINVAL; + } + q = &xc->queues[priority]; + + pr_devel("%s VCPU %d priority %d fl:%x sz:%d addr:%llx g:%d idx:%d\n", + __func__, server, priority, kvm_eq.flags, + kvm_eq.qsize, kvm_eq.qpage, kvm_eq.qtoggle, kvm_eq.qindex); + + rc = xive_native_validate_queue_size(kvm_eq.qsize); + if (rc || !kvm_eq.qsize) { + pr_err("invalid queue size %d\n", kvm_eq.qsize); + return rc; + } + + page = gfn_to_page(kvm, gpa_to_gfn(kvm_eq.qpage)); + if (is_error_page(page)) { + pr_warn("Couldn't get guest page for %llx!\n", kvm_eq.qpage); + return -ENOMEM; + } + qaddr = page_to_virt(page) + (kvm_eq.qpage & ~PAGE_MASK); + + /* Backup queue page guest address for migration */ + q->guest_qpage = kvm_eq.qpage; + q->guest_qsize = kvm_eq.qsize; + + rc = xive_native_configure_queue(xc->vp_id, q, priority, + (__be32 *) qaddr, kvm_eq.qsize, true); + if (rc) { + pr_err("Failed to configure queue %d for VCPU %d: %d\n", + priority, xc->server_num, rc); + put_page(page); + return rc; + } + + rc = xive_native_set_queue_state(xc->vp_id, priority, kvm_eq.qtoggle, + kvm_eq.qindex); + if (rc) + goto error; + + rc = kvmppc_xive_attach_escalation(vcpu, priority); +error: + if (rc) + xive_native_cleanup_queue(vcpu, priority); + return rc; +} + +static int kvmppc_xive_native_get_queue(struct kvmppc_xive *xive, long eq_idx, + u64 addr) +{ + struct kvm *kvm = xive->kvm; + struct kvm_vcpu *vcpu; + struct kvmppc_xive_vcpu *xc; + struct xive_q *q; + void __user *ubufp = (u64 __user *) addr; + u32 server; + u8 priority; + struct kvm_ppc_xive_eq kvm_eq; + u64 qpage; + u64 qsize; + u64 qeoi_page; + u32 escalate_irq; + u64 qflags; + int rc; + + /* + * Demangle priority/server tuple from the EQ index + */ + priority = (eq_idx & KVM_XIVE_EQ_PRIORITY_MASK) >> + KVM_XIVE_EQ_PRIORITY_SHIFT; + server = (eq_idx & KVM_XIVE_EQ_SERVER_MASK) >> + KVM_XIVE_EQ_SERVER_SHIFT; + + vcpu = kvmppc_xive_find_server(kvm, server); + if (!vcpu) { + pr_err("Can't find server %d\n", server); + return -ENOENT; + } + xc = vcpu->arch.xive_vcpu; + + if (priority != xive_prio_from_guest(priority)) { + pr_err("invalid priority for queue %d for VCPU %d\n", + priority, server); + return -EINVAL; + } + q = &xc->queues[priority]; + + memset(&kvm_eq, 0, sizeof(kvm_eq)); + + if (!q->qpage) + return 0; + + rc = xive_native_get_queue_info(xc->vp_id, priority, &qpage, &qsize, + &qeoi_page, &escalate_irq, &qflags); + if (rc) + return rc; + + kvm_eq.flags = 0; + if (qflags & OPAL_XIVE_EQ_ENABLED) + kvm_eq.flags |= KVM_XIVE_EQ_FLAG_ENABLED; + if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY) + kvm_eq.flags |= KVM_XIVE_EQ_FLAG_ALWAYS_NOTIFY; + if (qflags & OPAL_XIVE_EQ_ESCALATE) + kvm_eq.flags |= KVM_XIVE_EQ_FLAG_ESCALATE; + + kvm_eq.qsize = q->guest_qsize; + kvm_eq.qpage = q->guest_qpage; + + rc = xive_native_get_queue_state(xc->vp_id, priority, &kvm_eq.qtoggle, + &kvm_eq.qindex); + if (rc) + return rc; + + pr_devel("%s VCPU %d priority %d fl:%x sz:%d addr:%llx g:%d idx:%d\n", + __func__, server, priority, kvm_eq.flags, + kvm_eq.qsize, kvm_eq.qpage, kvm_eq.qtoggle, kvm_eq.qindex); + + if (copy_to_user(ubufp, &kvm_eq, sizeof(kvm_eq))) + return -EFAULT; + + return 0; +} + static int kvmppc_xive_native_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -628,6 +786,9 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev, return kvmppc_xive_native_sync(xive, attr->attr, attr->addr); case KVM_DEV_XIVE_GRP_EAS: return kvmppc_xive_native_set_eas(xive, attr->attr, attr->addr); + case KVM_DEV_XIVE_GRP_EQ: + return kvmppc_xive_native_set_queue(xive, attr->attr, + attr->addr); } return -ENXIO; } @@ -650,6 +811,9 @@ static int kvmppc_xive_native_get_attr(struct kvm_device *dev, break; case KVM_DEV_XIVE_GRP_EAS: return kvmppc_xive_native_get_eas(xive, attr->attr, attr->addr); + case KVM_DEV_XIVE_GRP_EQ: + return kvmppc_xive_native_get_queue(xive, attr->attr, + attr->addr); } return -ENXIO; } @@ -674,6 +838,8 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev, attr->attr < KVMPPC_XIVE_NR_IRQS) return 0; break; + case KVM_DEV_XIVE_GRP_EQ: + return 0; } return -ENXIO; } From patchwork Mon Jan 7 19:10:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751131 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 93ED713B5 for ; Mon, 7 Jan 2019 19:10:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 81694289BD for ; Mon, 7 Jan 2019 19:10:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F8E3289D0; Mon, 7 Jan 2019 19:10:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CD599289C7 for ; Mon, 7 Jan 2019 19:10:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727188AbfAGTKZ (ORCPT ); Mon, 7 Jan 2019 14:10:25 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:41004 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726655AbfAGTKZ (ORCPT ); Mon, 7 Jan 2019 14:10:25 -0500 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id x07J3lUN058809 for ; Mon, 7 Jan 2019 14:10:23 -0500 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0b-001b2d01.pphosted.com with ESMTP id 2pvc5hst1b-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 07 Jan 2019 14:10:23 -0500 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 7 Jan 2019 19:10:21 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp07.uk.ibm.com (192.168.101.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Mon, 7 Jan 2019 19:10:18 -0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x07JAHuD41418816 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 7 Jan 2019 19:10:17 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BA8794C04A; Mon, 7 Jan 2019 19:10:17 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9EEC84C040; Mon, 7 Jan 2019 19:10:17 +0000 (GMT) Received: from smtp.lab.toulouse-stg.fr.ibm.com (unknown [9.101.4.1]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 7 Jan 2019 19:10:17 +0000 (GMT) Received: from zorba.kaod.org.com (sig-9-145-153-156.de.ibm.com [9.145.153.156]) by smtp.lab.toulouse-stg.fr.ibm.com (Postfix) with ESMTP id D6FC12201CD; Mon, 7 Jan 2019 20:10:16 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 17/19] KVM: PPC: Book3S HV: add get/set accessors for the VP XIVE state Date: Mon, 7 Jan 2019 20:10:04 +0100 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107184331.8429-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19010719-0028-0000-0000-000003358579 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19010719-0029-0000-0000-000023F29044 Message-Id: <20190107191006.10648-1-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-01-07_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=542 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901070160 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP At a VCPU level, the state of the thread context interrupt management registers needs to be collected. These registers are cached under the 'xive_saved_state.w01' field of the VCPU when the VPCU context is pulled from the HW thread. An OPAL call retrieves the backup of the IPB register in the NVT structure and merges it in the KVM state. The structures of the interface between QEMU and KVM provisions some extra room (two u64) for further extensions if more state needs to be transferred back to QEMU. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/asm/kvm_ppc.h | 5 ++ arch/powerpc/include/uapi/asm/kvm.h | 2 + arch/powerpc/kvm/book3s.c | 24 +++++++++ arch/powerpc/kvm/book3s_xive_native.c | 78 +++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 4cc897039485..49c488af168c 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -270,6 +270,7 @@ union kvmppc_one_reg { u64 addr; u64 length; } vpaval; + u64 xive_timaval[4]; }; struct kvmppc_ops { @@ -603,6 +604,8 @@ extern void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu); extern void kvmppc_xive_native_init_module(void); extern void kvmppc_xive_native_exit_module(void); extern int kvmppc_xive_native_hcall(struct kvm_vcpu *vcpu, u32 cmd); +extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val); +extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val); #else static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, @@ -637,6 +640,8 @@ static inline void kvmppc_xive_native_init_module(void) { } static inline void kvmppc_xive_native_exit_module(void) { } static inline int kvmppc_xive_native_hcall(struct kvm_vcpu *vcpu, u32 cmd) { return 0; } +static inline int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) { return 0; } +static inline int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) { return -ENOENT; } #endif /* CONFIG_KVM_XIVE */ diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 95302558ce10..3c958c39a782 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/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 +#define KVM_REG_PPC_VP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U256 | 0x8d) + /* Device control API: PPC-specific devices */ #define KVM_DEV_MPIC_GRP_MISC 1 #define KVM_DEV_MPIC_BASE_ADDR 0 /* 64-bit */ diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index de7eed191107..5ad658077a35 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -641,6 +641,18 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, *val = get_reg_val(id, kvmppc_xics_get_icp(vcpu)); break; #endif /* CONFIG_KVM_XICS */ +#ifdef CONFIG_KVM_XIVE + case KVM_REG_PPC_VP_STATE: + if (!vcpu->arch.xive_vcpu) { + r = -ENXIO; + break; + } + if (xive_enabled()) + r = kvmppc_xive_native_get_vp(vcpu, val); + else + r = -ENXIO; + break; +#endif /* CONFIG_KVM_XIVE */ case KVM_REG_PPC_FSCR: *val = get_reg_val(id, vcpu->arch.fscr); break; @@ -714,6 +726,18 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, r = kvmppc_xics_set_icp(vcpu, set_reg_val(id, *val)); break; #endif /* CONFIG_KVM_XICS */ +#ifdef CONFIG_KVM_XIVE + case KVM_REG_PPC_VP_STATE: + if (!vcpu->arch.xive_vcpu) { + r = -ENXIO; + break; + } + if (xive_enabled()) + r = kvmppc_xive_native_set_vp(vcpu, val); + else + r = -ENXIO; + break; +#endif /* CONFIG_KVM_XIVE */ case KVM_REG_PPC_FSCR: vcpu->arch.fscr = set_reg_val(id, *val); break; diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index f4eb71eafc57..1aefb366df0b 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -424,6 +424,84 @@ static int xive_native_validate_queue_size(u32 qsize) } } +#define TM_IPB_SHIFT 40 +#define TM_IPB_MASK (((u64) 0xFF) << TM_IPB_SHIFT) + +int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + u64 opal_state; + int rc; + + if (!kvmppc_xive_enabled(vcpu)) + return -EPERM; + + if (!xc) + return -ENOENT; + + /* Thread context registers. We only care about IPB and CPPR */ + val->xive_timaval[0] = vcpu->arch.xive_saved_state.w01; + + /* + * Return the OS CAM line to print out the VP identifier in + * the QEMU monitor. This is not restored. + */ + val->xive_timaval[1] = vcpu->arch.xive_cam_word; + + /* Get the VP state from OPAL */ + rc = xive_native_get_vp_state(xc->vp_id, &opal_state); + if (rc) + return rc; + + /* + * Capture the backup of IPB register in the NVT structure and + * merge it in our KVM VP state. + * + * TODO: P10 support. + */ + val->xive_timaval[0] |= cpu_to_be64(opal_state & TM_IPB_MASK); + + pr_devel("%s NSR=%02x CPPR=%02x IBP=%02x PIPR=%02x w01=%016llx w2=%08x opal=%016llx\n", + __func__, + vcpu->arch.xive_saved_state.nsr, + vcpu->arch.xive_saved_state.cppr, + vcpu->arch.xive_saved_state.ipb, + vcpu->arch.xive_saved_state.pipr, + vcpu->arch.xive_saved_state.w01, + (u32) vcpu->arch.xive_cam_word, opal_state); + + return 0; +} + +int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + struct kvmppc_xive *xive = vcpu->kvm->arch.xive; + + pr_devel("%s w01=%016llx vp=%016llx\n", __func__, + val->xive_timaval[0], val->xive_timaval[1]); + + if (!kvmppc_xive_enabled(vcpu)) + return -EPERM; + + if (!xc || !xive) + return -ENOENT; + + /* We can't update the state of a "pushed" VCPU */ + if (WARN_ON(vcpu->arch.xive_pushed)) + return -EIO; + + /* Thread context registers. only restore IPB and CPPR ? */ + vcpu->arch.xive_saved_state.w01 = val->xive_timaval[0]; + + /* + * There is no need to restore the XIVE internal state (IPB + * stored in the NVT) as the IPB register was merged in KVM VP + * state. + */ + return 0; +} + static int kvmppc_xive_native_set_source(struct kvmppc_xive *xive, long irq, u64 addr) { From patchwork Mon Jan 7 19:10:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751129 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F372213BF for ; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E417D289BF for ; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D82A5289CB; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5439D289B9 for ; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727314AbfAGTK1 (ORCPT ); Mon, 7 Jan 2019 14:10:27 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:42492 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726655AbfAGTK0 (ORCPT ); Mon, 7 Jan 2019 14:10:26 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id x07J3mga142722 for ; Mon, 7 Jan 2019 14:10:25 -0500 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0a-001b2d01.pphosted.com with ESMTP id 2pvbuhtwhj-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 07 Jan 2019 14:10:25 -0500 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 7 Jan 2019 19:10:22 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp04.uk.ibm.com (192.168.101.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Mon, 7 Jan 2019 19:10:19 -0000 Received: from d06av24.portsmouth.uk.ibm.com (mk.ibm.com [9.149.105.60]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x07JAI6Z35258422 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 7 Jan 2019 19:10:18 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 78D424204F; Mon, 7 Jan 2019 19:10:18 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5C39B42041; Mon, 7 Jan 2019 19:10:18 +0000 (GMT) Received: from smtp.lab.toulouse-stg.fr.ibm.com (unknown [9.101.4.1]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 7 Jan 2019 19:10:18 +0000 (GMT) Received: from zorba.kaod.org.com (sig-9-145-153-156.de.ibm.com [9.145.153.156]) by smtp.lab.toulouse-stg.fr.ibm.com (Postfix) with ESMTP id 93738220359; Mon, 7 Jan 2019 20:10:17 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 18/19] KVM: PPC: Book3S HV: add passthrough support Date: Mon, 7 Jan 2019 20:10:05 +0100 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107191006.10648-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> <20190107191006.10648-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19010719-0016-0000-0000-000002418864 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19010719-0017-0000-0000-0000329B9849 Message-Id: <20190107191006.10648-2-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-01-07_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=842 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901070160 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Clear the ESB pages from the VMA of the IRQ being pass through to the guest and let the fault handler repopulate the VMA when the ESB pages are accessed for an EOI or for a trigger. Storing the VMA under the KVM XIVE device is a little ugly. Signed-off-by: Cédric Le Goater --- arch/powerpc/kvm/book3s_xive.h | 8 +++++++ arch/powerpc/kvm/book3s_xive.c | 15 ++++++++++++++ arch/powerpc/kvm/book3s_xive_native.c | 30 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 31e598e62589..6e64d3496a2c 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -90,6 +90,11 @@ struct kvmppc_xive_src_block { struct kvmppc_xive_irq_state irq_state[KVMPPC_XICS_IRQ_PER_ICS]; }; +struct kvmppc_xive; + +struct kvmppc_xive_ops { + int (*reset_mapped)(struct kvm *kvm, unsigned long guest_irq); +}; struct kvmppc_xive { struct kvm *kvm; @@ -131,6 +136,9 @@ struct kvmppc_xive { /* VC base address for ESBs */ u64 vc_base; + + struct kvmppc_xive_ops *ops; + struct vm_area_struct *vma; }; #define KVMPPC_XIVE_Q_COUNT 8 diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index e9f05d9c9ad5..9b4751713554 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -946,6 +946,13 @@ int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, /* Turn the IPI hard off */ xive_vm_esb_load(&state->ipi_data, XIVE_ESB_SET_PQ_01); + /* + * Reset ESB guest mapping. Needed when ESB pages are exposed + * to the guest in XIVE native mode + */ + if (xive->ops && xive->ops->reset_mapped) + xive->ops->reset_mapped(kvm, guest_irq); + /* Grab info about irq */ state->pt_number = hw_irq; state->pt_data = irq_data_get_irq_handler_data(host_data); @@ -1031,6 +1038,14 @@ int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq, state->pt_number = 0; state->pt_data = NULL; + /* + * Reset ESB guest mapping. Needed when ESB pages are exposed + * to the guest in XIVE native mode + */ + if (xive->ops && xive->ops->reset_mapped) { + xive->ops->reset_mapped(kvm, guest_irq); + } + /* Reconfigure the IPI */ xive_native_configure_irq(state->ipi_number, xive_vp(xive, state->act_server), diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 1aefb366df0b..12edac29995e 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -240,6 +240,32 @@ static int kvmppc_xive_native_get_vc_base(struct kvmppc_xive *xive, u64 addr) return 0; } +static int kvmppc_xive_native_reset_mapped(struct kvm *kvm, unsigned long irq) +{ + struct kvmppc_xive *xive = kvm->arch.xive; + struct mm_struct *mm = kvm->mm; + struct vm_area_struct *vma = xive->vma; + unsigned long address; + + if (irq >= KVMPPC_XIVE_NR_IRQS) + return -EINVAL; + + pr_debug("clearing esb pages for girq 0x%lx\n", irq); + + down_read(&mm->mmap_sem); + /* TODO: can we clear the PTEs without keeping a VMA pointer ? */ + if (vma) { + address = vma->vm_start + irq * (2ull << PAGE_SHIFT); + zap_vma_ptes(vma, address, 2ull << PAGE_SHIFT); + } + up_read(&mm->mmap_sem); + return 0; +} + +static struct kvmppc_xive_ops kvmppc_xive_native_ops = { + .reset_mapped = kvmppc_xive_native_reset_mapped, +}; + static int xive_native_esb_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; @@ -292,6 +318,8 @@ static const struct vm_operations_struct xive_native_esb_vmops = { static int xive_native_esb_mmap(struct file *file, struct vm_area_struct *vma) { + struct kvmppc_xive *xive = vma->vm_file->private_data; + /* There are two ESB pages (trigger and EOI) per IRQ */ if (vma_pages(vma) + vma->vm_pgoff > KVMPPC_XIVE_NR_IRQS * 2) return -EINVAL; @@ -299,6 +327,7 @@ static int xive_native_esb_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_IO | VM_PFNMAP; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_ops = &xive_native_esb_vmops; + xive->vma = vma; /* TODO: get rid of the VMA pointer */ return 0; } @@ -992,6 +1021,7 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) xive->vc_base = XIVE_VC_BASE; xive->single_escalation = xive_native_has_single_escalation(); + xive->ops = &kvmppc_xive_native_ops; if (ret) kfree(xive); From patchwork Mon Jan 7 19:10:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 10751127 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9039713AD for ; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 81EAB289CF for ; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 75E0A289CC; Mon, 7 Jan 2019 19:10:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 894C5289BC for ; Mon, 7 Jan 2019 19:10:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727315AbfAGTK1 (ORCPT ); Mon, 7 Jan 2019 14:10:27 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:41846 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727244AbfAGTK0 (ORCPT ); Mon, 7 Jan 2019 14:10:26 -0500 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id x07J3jj2056076 for ; Mon, 7 Jan 2019 14:10:25 -0500 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0a-001b2d01.pphosted.com with ESMTP id 2pvadefkr1-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 07 Jan 2019 14:10:25 -0500 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 7 Jan 2019 19:10:23 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp05.uk.ibm.com (192.168.101.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Mon, 7 Jan 2019 19:10:20 -0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x07JAJ7R56426572 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 7 Jan 2019 19:10:19 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3455DA4055; Mon, 7 Jan 2019 19:10:19 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 180A4A4053; Mon, 7 Jan 2019 19:10:19 +0000 (GMT) Received: from smtp.lab.toulouse-stg.fr.ibm.com (unknown [9.101.4.1]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 7 Jan 2019 19:10:19 +0000 (GMT) Received: from zorba.kaod.org.com (sig-9-145-153-156.de.ibm.com [9.145.153.156]) by smtp.lab.toulouse-stg.fr.ibm.com (Postfix) with ESMTP id 54B022201CD; Mon, 7 Jan 2019 20:10:18 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , Benjamin Herrenschmidt , Michael Ellerman , linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH 19/19] KVM: introduce a KVM_DELETE_DEVICE ioctl Date: Mon, 7 Jan 2019 20:10:06 +0100 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107191006.10648-1-clg@kaod.org> References: <20190107184331.8429-1-clg@kaod.org> <20190107191006.10648-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19010719-0020-0000-0000-000003028B96 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19010719-0021-0000-0000-0000215399A3 Message-Id: <20190107191006.10648-3-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-01-07_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=13 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901070160 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This will be used to destroy the KVM XICS or XIVE device when the sPAPR machine is reseted. When the VM boots, the CAS negotiation process will determine which interrupt mode to use and the appropriate KVM device will then be created. Signed-off-by: Cédric Le Goater --- include/linux/kvm_host.h | 2 ++ include/uapi/linux/kvm.h | 2 ++ arch/powerpc/kvm/book3s_xive.c | 38 +++++++++++++++++++++++++- arch/powerpc/kvm/book3s_xive_native.c | 24 +++++++++++++++++ virt/kvm/kvm_main.c | 39 +++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index c38cc5eb7e73..259b6885dc74 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1218,6 +1218,8 @@ struct kvm_device_ops { */ void (*destroy)(struct kvm_device *dev); + int (*delete)(struct kvm_device *dev); + int (*set_attr)(struct kvm_device *dev, struct kvm_device_attr *attr); int (*get_attr)(struct kvm_device *dev, struct kvm_device_attr *attr); int (*has_attr)(struct kvm_device *dev, struct kvm_device_attr *attr); diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 52bf74a1616e..b00cb4d986cf 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1331,6 +1331,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) +#define KVM_DELETE_DEVICE _IOWR(KVMIO, 0xf0, struct kvm_create_device) + /* * ioctls for vcpu fds */ diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 9b4751713554..5449fb4c87f9 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1109,11 +1109,19 @@ void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu) void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; - struct kvmppc_xive *xive = xc->xive; + struct kvmppc_xive *xive; int i; + if (!kvmppc_xics_enabled(vcpu)) + return; + + if (!xc) + return; + pr_devel("cleanup_vcpu(cpu=%d)\n", xc->server_num); + xive = xc->xive; + /* Ensure no interrupt is still routed to that VP */ xc->valid = false; kvmppc_xive_disable_vcpu_interrupts(vcpu); @@ -1150,6 +1158,10 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu) } /* Free the VP */ kfree(xc); + + /* Cleanup the vcpu */ + vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; + vcpu->arch.xive_vcpu = NULL; } int kvmppc_xive_connect_vcpu(struct kvm_device *dev, @@ -1861,6 +1873,29 @@ static void kvmppc_xive_free(struct kvm_device *dev) kfree(dev); } +static int kvmppc_xive_delete(struct kvm_device *dev) +{ + struct kvm *kvm = dev->kvm; + unsigned int i; + struct kvm_vcpu *vcpu; + + if (!kvm->arch.xive) + return -EPERM; + + /* + * call kick_all_cpus_sync() to ensure that all CPUs have + * executed any pending interrupts + */ + if (is_kvmppc_hv_enabled(kvm)) + kick_all_cpus_sync(); + + kvm_for_each_vcpu(i, vcpu, kvm) + kvmppc_xive_cleanup_vcpu(vcpu); + + kvmppc_xive_free(dev); + return 0; +} + static int kvmppc_xive_create(struct kvm_device *dev, u32 type) { struct kvmppc_xive *xive; @@ -2035,6 +2070,7 @@ struct kvm_device_ops kvm_xive_ops = { .create = kvmppc_xive_create, .init = kvmppc_xive_init, .destroy = kvmppc_xive_free, + .delete = kvmppc_xive_delete, .set_attr = xive_set_attr, .get_attr = xive_get_attr, .has_attr = xive_has_attr, diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 12edac29995e..7367962e670a 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -979,6 +979,29 @@ static void kvmppc_xive_native_free(struct kvm_device *dev) kfree(dev); } +static int kvmppc_xive_native_delete(struct kvm_device *dev) +{ + struct kvm *kvm = dev->kvm; + unsigned int i; + struct kvm_vcpu *vcpu; + + if (!kvm->arch.xive) + return -EPERM; + + /* + * call kick_all_cpus_sync() to ensure that all CPUs have + * executed any pending interrupts + */ + if (is_kvmppc_hv_enabled(kvm)) + kick_all_cpus_sync(); + + kvm_for_each_vcpu(i, vcpu, kvm) + kvmppc_xive_native_cleanup_vcpu(vcpu); + + kvmppc_xive_native_free(dev); + return 0; +} + /* * ESB MMIO address of chip 0 */ @@ -1350,6 +1373,7 @@ struct kvm_device_ops kvm_xive_native_ops = { .create = kvmppc_xive_native_create, .init = kvmppc_xive_native_init, .destroy = kvmppc_xive_native_free, + .delete = kvmppc_xive_native_delete, .set_attr = kvmppc_xive_native_set_attr, .get_attr = kvmppc_xive_native_get_attr, .has_attr = kvmppc_xive_native_has_attr, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 1f888a103f78..c93c35c43675 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3009,6 +3009,31 @@ static int kvm_ioctl_create_device(struct kvm *kvm, return 0; } +static int kvm_ioctl_delete_device(struct kvm *kvm, + struct kvm_create_device *cd) +{ + struct fd f; + struct kvm_device *dev; + int ret; + + f = fdget(cd->fd); + if (!f.file) + return -EBADF; + + dev = kvm_device_from_filp(f.file); + fdput(f); + + if (!dev) + return -EPERM; + + mutex_lock(&kvm->lock); + list_del(&dev->vm_node); + mutex_unlock(&kvm->lock); + ret = dev->ops->delete(dev); + + return ret; +} + static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) { switch (arg) { @@ -3253,6 +3278,20 @@ static long kvm_vm_ioctl(struct file *filp, r = 0; break; } + case KVM_DELETE_DEVICE: { + struct kvm_create_device cd; + + r = -EFAULT; + if (copy_from_user(&cd, argp, sizeof(cd))) + goto out; + + r = kvm_ioctl_delete_device(kvm, &cd); + if (r) + goto out; + + r = 0; + break; + } case KVM_CHECK_EXTENSION: r = kvm_vm_ioctl_check_extension_generic(kvm, arg); break;