From patchwork Thu Oct 24 08:17:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208477 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F2EB613B1 for ; Thu, 24 Oct 2019 08:20:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C84FF20856 for ; Thu, 24 Oct 2019 08:20:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="pOIo6nL/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C84FF20856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYLs-0007My-Hb for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:20:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36468) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKQ-0004b7-8p for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKO-0004yQ-Tl for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:42 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:59063) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKO-0004rP-Gx; Thu, 24 Oct 2019 04:18:40 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrX2xX5z9sPc; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905116; bh=5KV84r29nIJXr/A9Jl+oWqntFxHPYStDWAbStjFb6C0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pOIo6nL/g0cs7ZmGtQyiVU+Xwptba5ORRELo0HylMxOJfHIlyM0NGu3E/5XmLd9Zs B6riZ8E/jZ8RC2HkJPL7s7MrJfWtZ4z+/NdFX3LkBWPAY88qyz2XDxnPfvcy/AVoCk 8LshCdkzJzY+USm1i9YBjvUJUAz+MLNGx8pXqTc8= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 01/28] xive: Make some device types not user creatable Date: Thu, 24 Oct 2019 19:17:46 +1100 Message-Id: <20191024081813.2115-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz Some device types of the XIVE model are exposed to the QEMU command line: $ ppc64-softmmu/qemu-system-ppc64 -device help | grep xive name "xive-end-source", desc "XIVE END Source" name "xive-source", desc "XIVE Interrupt Source" name "xive-tctx", desc "XIVE Interrupt Thread Context" These are internal devices that shouldn't be instantiable by the user. By the way, they can't be because their respective realize functions expect link properties that can't be set from the command line: qemu-system-ppc64: -device xive-source: required link 'xive' not found: Property '.xive' not found qemu-system-ppc64: -device xive-end-source: required link 'xive' not found: Property '.xive' not found qemu-system-ppc64: -device xive-tctx: required link 'cpu' not found: Property '.cpu' not found Hide them by setting dc->user_creatable to false in their respective class init functions. Signed-off-by: Greg Kurz Message-Id: <157017473006.331610.2983143972519884544.stgit@bahia.lan> Message-Id: <157045578401.865784.6058183726552779559.stgit@bahia.lan> Reviewed-by: Cédric Le Goater [dwg: Folded comment update into base patch] Signed-off-by: David Gibson --- hw/intc/xive.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 29df06df11..453d389848 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -670,6 +670,11 @@ static void xive_tctx_class_init(ObjectClass *klass, void *data) dc->realize = xive_tctx_realize; dc->unrealize = xive_tctx_unrealize; dc->vmsd = &vmstate_xive_tctx; + /* + * Reason: part of XIVE interrupt controller, needs to be wired up + * by xive_tctx_create(). + */ + dc->user_creatable = false; } static const TypeInfo xive_tctx_info = { @@ -1118,6 +1123,11 @@ static void xive_source_class_init(ObjectClass *klass, void *data) dc->props = xive_source_properties; dc->realize = xive_source_realize; dc->vmsd = &vmstate_xive_source; + /* + * Reason: part of XIVE interrupt controller, needs to be wired up, + * e.g. by spapr_xive_instance_init(). + */ + dc->user_creatable = false; } static const TypeInfo xive_source_info = { @@ -1853,6 +1863,11 @@ static void xive_end_source_class_init(ObjectClass *klass, void *data) dc->desc = "XIVE END Source"; dc->props = xive_end_source_properties; dc->realize = xive_end_source_realize; + /* + * Reason: part of XIVE interrupt controller, needs to be wired up, + * e.g. by spapr_xive_instance_init(). + */ + dc->user_creatable = false; } static const TypeInfo xive_end_source_info = { From patchwork Thu Oct 24 08:17:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208483 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CA0D7112C for ; Thu, 24 Oct 2019 08:20:18 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A045320856 for ; Thu, 24 Oct 2019 08:20:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="lKd4Mzcn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A045320856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34850 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYLw-0007Sp-T7 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:20:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36467) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKQ-0004b5-M8 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKO-0004yG-T9 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:42 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:34347 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKN-0004rk-Qt; Thu, 24 Oct 2019 04:18:40 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrX3hSFz9sQr; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905116; bh=ocrX3ncUYBFcZTW4CQsb4v8fYUjtodAeqwtBgAzm4yU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lKd4MzcnENckXJd3esl6QCug9Zc2gwb5zxoRqhg5YwZJevt14eFhqvPLDpp2IPYrw pNgpc4lHiBgN3YySoNlW+a7CTQX9CIqUNuIjWuhSKRgYMixh0rRAw+Yr5Y4EpFZbK9 1Ywaf+B6LjM7E1sEYCmDHPmDhexsE1mi+8fuVxqg= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 02/28] xics: Make some device types not user creatable Date: Thu, 24 Oct 2019 19:17:47 +1100 Message-Id: <20191024081813.2115-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz Some device types of the XICS model are exposed to the QEMU command line: $ ppc64-softmmu/qemu-system-ppc64 -device help | grep ic[sp] name "icp" name "ics" name "ics-spapr" name "pnv-icp", desc "PowerNV ICP" These are internal devices that shouldn't be instantiable by the user. By the way, they can't be because their respective realize functions expect link properties that can't be set from the command line: qemu-system-ppc64: -device icp: required link 'xics' not found: Property '.xics' not found qemu-system-ppc64: -device ics: required link 'xics' not found: Property '.xics' not found qemu-system-ppc64: -device ics-spapr: required link 'xics' not found: Property '.xics' not found qemu-system-ppc64: -device pnv-icp: required link 'xics' not found: Property '.xics' not found Hide them by setting dc->user_creatable to false in the base class "icp" and "ics" init functions. Signed-off-by: Greg Kurz Message-Id: <157017826724.337875.14822177178282524024.stgit@bahia.lan> Message-Id: <157045578962.865784.8551555523533955113.stgit@bahia.lan> [dwg: Folded reason comment into base patch] Signed-off-by: David Gibson --- hw/intc/xics.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index dfe7dbd254..b5ac408f7b 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -369,6 +369,11 @@ static void icp_class_init(ObjectClass *klass, void *data) dc->realize = icp_realize; dc->unrealize = icp_unrealize; + /* + * Reason: part of XICS interrupt controller, needs to be wired up + * by icp_create(). + */ + dc->user_creatable = false; } static const TypeInfo icp_info = { @@ -689,6 +694,11 @@ static void ics_class_init(ObjectClass *klass, void *data) dc->props = ics_properties; dc->reset = ics_reset; dc->vmsd = &vmstate_ics; + /* + * Reason: part of XICS interrupt controller, needs to be wired up, + * e.g. by spapr_irq_init(). + */ + dc->user_creatable = false; } static const TypeInfo ics_info = { From patchwork Thu Oct 24 08:17:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208501 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1FF43112C for ; Thu, 24 Oct 2019 08:26:44 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EA1B920659 for ; Thu, 24 Oct 2019 08:26:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="ZGmYsw/C" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EA1B920659 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34916 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYSA-0003ni-DK for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:26:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36556) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKT-0004k4-9k for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-00054r-HT for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:45 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:54339 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-0004zf-5N; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrX6s7hz9sR3; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905116; bh=bDJ+lL6U7/EjRyMJMnAmLePHj2/5rsdcdvyY0UDu9xU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZGmYsw/CupiLTExxSXKfkADhiCYCMymEsc8fkH4oplEbzIBrdRGklkrTxlN8PQlpA Np2i0nbiAvuBDcVYIpZhQG9LIT9oDgIcZkjPZAlGUwIx5G/u9OFtTwCLOQ7nXKwp2Q r6rmsY7Ltq1jHzRb2cD6y6Z+6g97O0yMhbInUfFE= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 03/28] target/ppc: Fix for optimized vsl/vsr instructions Date: Thu, 24 Oct 2019 19:17:48 +1100 Message-Id: <20191024081813.2115-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, Mark Cave-Ayland , qemu-devel@nongnu.org, groug@kaod.org, Aleksandar Markovic , qemu-ppc@nongnu.org, clg@kaod.org, Stefan Brankovic , David Gibson , "Paul A. Clark" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Stefan Brankovic In previous implementation, invocation of TCG shift function could request shift of TCG variable by 64 bits when variable 'sh' is 0, which is not supported in TCG (values can be shifted by 0 to 63 bits). This patch fixes this by using two separate invocation of TCG shift functions, with maximum shift amount of 32. Name of variable 'shifted' is changed to 'carry' so variable naming is similar to old helper implementation. Variables 'avrA' and 'avrB' are replaced with variable 'avr'. Fixes: 4e6d0920e7547e6af4bbac5ffe9adfe6ea621822 Reported-by: "Paul A. Clark" Reported-by: Mark Cave-Ayland Suggested-by: Aleksandar Markovic Signed-off-by: Stefan Brankovic Message-Id: <1570196639-7025-2-git-send-email-stefan.brankovic@rt-rk.com> Tested-by: Paul A. Clarke Signed-off-by: David Gibson --- target/ppc/translate/vmx-impl.inc.c | 84 ++++++++++++++--------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 2472a5217a..81d5a7a341 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -590,40 +590,38 @@ static void trans_vsl(DisasContext *ctx) int VT = rD(ctx->opcode); int VA = rA(ctx->opcode); int VB = rB(ctx->opcode); - TCGv_i64 avrA = tcg_temp_new_i64(); - TCGv_i64 avrB = tcg_temp_new_i64(); + TCGv_i64 avr = tcg_temp_new_i64(); TCGv_i64 sh = tcg_temp_new_i64(); - TCGv_i64 shifted = tcg_temp_new_i64(); + TCGv_i64 carry = tcg_temp_new_i64(); TCGv_i64 tmp = tcg_temp_new_i64(); - /* Place bits 125-127 of vB in sh. */ - get_avr64(avrB, VB, false); - tcg_gen_andi_i64(sh, avrB, 0x07ULL); + /* Place bits 125-127 of vB in 'sh'. */ + get_avr64(avr, VB, false); + tcg_gen_andi_i64(sh, avr, 0x07ULL); /* - * Save highest sh bits of lower doubleword element of vA in variable - * shifted and perform shift on lower doubleword. + * Save highest 'sh' bits of lower doubleword element of vA in variable + * 'carry' and perform shift on lower doubleword. */ - get_avr64(avrA, VA, false); - tcg_gen_subfi_i64(tmp, 64, sh); - tcg_gen_shr_i64(shifted, avrA, tmp); - tcg_gen_andi_i64(shifted, shifted, 0x7fULL); - tcg_gen_shl_i64(avrA, avrA, sh); - set_avr64(VT, avrA, false); + get_avr64(avr, VA, false); + tcg_gen_subfi_i64(tmp, 32, sh); + tcg_gen_shri_i64(carry, avr, 32); + tcg_gen_shr_i64(carry, carry, tmp); + tcg_gen_shl_i64(avr, avr, sh); + set_avr64(VT, avr, false); /* * Perform shift on higher doubleword element of vA and replace lowest - * sh bits with shifted. + * 'sh' bits with 'carry'. */ - get_avr64(avrA, VA, true); - tcg_gen_shl_i64(avrA, avrA, sh); - tcg_gen_or_i64(avrA, avrA, shifted); - set_avr64(VT, avrA, true); + get_avr64(avr, VA, true); + tcg_gen_shl_i64(avr, avr, sh); + tcg_gen_or_i64(avr, avr, carry); + set_avr64(VT, avr, true); - tcg_temp_free_i64(avrA); - tcg_temp_free_i64(avrB); + tcg_temp_free_i64(avr); tcg_temp_free_i64(sh); - tcg_temp_free_i64(shifted); + tcg_temp_free_i64(carry); tcg_temp_free_i64(tmp); } @@ -639,39 +637,37 @@ static void trans_vsr(DisasContext *ctx) int VT = rD(ctx->opcode); int VA = rA(ctx->opcode); int VB = rB(ctx->opcode); - TCGv_i64 avrA = tcg_temp_new_i64(); - TCGv_i64 avrB = tcg_temp_new_i64(); + TCGv_i64 avr = tcg_temp_new_i64(); TCGv_i64 sh = tcg_temp_new_i64(); - TCGv_i64 shifted = tcg_temp_new_i64(); + TCGv_i64 carry = tcg_temp_new_i64(); TCGv_i64 tmp = tcg_temp_new_i64(); - /* Place bits 125-127 of vB in sh. */ - get_avr64(avrB, VB, false); - tcg_gen_andi_i64(sh, avrB, 0x07ULL); + /* Place bits 125-127 of vB in 'sh'. */ + get_avr64(avr, VB, false); + tcg_gen_andi_i64(sh, avr, 0x07ULL); /* - * Save lowest sh bits of higher doubleword element of vA in variable - * shifted and perform shift on higher doubleword. + * Save lowest 'sh' bits of higher doubleword element of vA in variable + * 'carry' and perform shift on higher doubleword. */ - get_avr64(avrA, VA, true); - tcg_gen_subfi_i64(tmp, 64, sh); - tcg_gen_shl_i64(shifted, avrA, tmp); - tcg_gen_andi_i64(shifted, shifted, 0xfe00000000000000ULL); - tcg_gen_shr_i64(avrA, avrA, sh); - set_avr64(VT, avrA, true); + get_avr64(avr, VA, true); + tcg_gen_subfi_i64(tmp, 32, sh); + tcg_gen_shli_i64(carry, avr, 32); + tcg_gen_shl_i64(carry, carry, tmp); + tcg_gen_shr_i64(avr, avr, sh); + set_avr64(VT, avr, true); /* * Perform shift on lower doubleword element of vA and replace highest - * sh bits with shifted. + * 'sh' bits with 'carry'. */ - get_avr64(avrA, VA, false); - tcg_gen_shr_i64(avrA, avrA, sh); - tcg_gen_or_i64(avrA, avrA, shifted); - set_avr64(VT, avrA, false); + get_avr64(avr, VA, false); + tcg_gen_shr_i64(avr, avr, sh); + tcg_gen_or_i64(avr, avr, carry); + set_avr64(VT, avr, false); - tcg_temp_free_i64(avrA); - tcg_temp_free_i64(avrB); + tcg_temp_free_i64(avr); tcg_temp_free_i64(sh); - tcg_temp_free_i64(shifted); + tcg_temp_free_i64(carry); tcg_temp_free_i64(tmp); } From patchwork Thu Oct 24 08:17:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208487 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D85C513B1 for ; Thu, 24 Oct 2019 08:23:09 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AEC7C20856 for ; Thu, 24 Oct 2019 08:23:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="AiNwoTDj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AEC7C20856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34880 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYOi-0005dl-41 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:23:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36474) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKQ-0004c9-G2 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKP-0004yw-3t for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:42 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:34799 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKO-0004s8-Lw; Thu, 24 Oct 2019 04:18:41 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrX5tRCz9sR6; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905116; bh=SQwpN+RW74j0cauvfIg1SAmlAX+IHu0+B9uvfDotYJw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AiNwoTDjffU6mIsWMCImthT6K6awsq+Bo6/mJsJwMvjYwGXEc2K3IIYvCfoT6zetL 5IqEFD9WqjnnS4iahFdwwXn8xV0WRMEAqB/6vC9oJWu19BgEm7nKh935KvBFjpi2sb ciOlFtvcjJVxDT0KuxiP2BQllauMKFit2I/Ikn2U= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 04/28] ppc/pnv: Improve trigger data definition Date: Thu, 24 Oct 2019 19:17:49 +1100 Message-Id: <20191024081813.2115-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater The trigger data is used for both triggers of a HW source interrupts, PHB, PSI, and triggers for rerouting interrupts between interrupt controllers. When an interrupt is rerouted, the trigger data follows an "END trigger" format. In that case, the remote IC needs EAS containing an END index to perform a lookup of an END. An END trigger, bit0 of word0 set to '1', is defined as : |0123|4567|0123|4567|0123|4567|0123|4567| W0 E=1 |1P--|BLOC| END IDX | W1 E=1 |M | END DATA | An EAS is defined as : |0123|4567|0123|4567|0123|4567|0123|4567| W0 |V---|BLOC| END IDX | W1 |M | END DATA | The END trigger adds an extra 'PQ' bit, bit1 of word0 set to '1', signaling that the PQ bits have been checked. That bit is unused in the initial EAS definition. When a HW device performs the trigger, the trigger data follows an "EAS trigger" format because the trigger data in that case contains an EAS index which the IC needs to look for. An EAS trigger, bit0 of word0 set to '0', is defined as : |0123|4567|0123|4567|0123|4567|0123|4567| W0 E=0 |0P--|---- ---- ---- ---- ---- ---- ----| W1 E=0 |BLOC| EAS INDEX | There is also a 'PQ' bit, bit1 of word0 to '1', signaling that the PQ bits have been checked. Introduce these new trigger bits and rename the XIVE_SRCNO macros in XIVE_EAS to reflect better the nature of the data. Signed-off-by: Cédric Le Goater Message-Id: <20191007084102.29776-2-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/pnv_xive.c | 20 ++++++++++++++++---- hw/intc/xive.c | 4 ++-- include/hw/ppc/xive_regs.h | 26 +++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index ed6e9d71bb..348f2fdd26 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -385,7 +385,7 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx, PnvXive *xive = PNV_XIVE(xrtr); if (pnv_xive_get_ic(blk) != xive) { - xive_error(xive, "VST: EAS %x is remote !?", XIVE_SRCNO(blk, idx)); + xive_error(xive, "VST: EAS %x is remote !?", XIVE_EAS(blk, idx)); return -1; } @@ -431,7 +431,7 @@ static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno) PnvXive *xive = PNV_XIVE(xn); uint8_t blk = xive->chip->chip_id; - xive_router_notify(xn, XIVE_SRCNO(blk, srcno)); + xive_router_notify(xn, XIVE_EAS(blk, srcno)); } /* @@ -1225,12 +1225,24 @@ static const MemoryRegionOps pnv_xive_ic_reg_ops = { static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val) { + uint8_t blk; + uint32_t idx; + + if (val & XIVE_TRIGGER_END) { + xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64, + addr, val); + return; + } + /* * Forward the source event notification directly to the Router. * The source interrupt number should already be correctly encoded * with the chip block id by the sending device (PHB, PSI). */ - xive_router_notify(XIVE_NOTIFIER(xive), val); + blk = XIVE_EAS_BLOCK(val); + idx = XIVE_EAS_INDEX(val); + + xive_router_notify(XIVE_NOTIFIER(xive), XIVE_EAS(blk, idx)); } static void pnv_xive_ic_notify_write(void *opaque, hwaddr addr, uint64_t val, @@ -1566,7 +1578,7 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon) { XiveRouter *xrtr = XIVE_ROUTER(xive); uint8_t blk = xive->chip->chip_id; - uint32_t srcno0 = XIVE_SRCNO(blk, 0); + uint32_t srcno0 = XIVE_EAS(blk, 0); uint32_t nr_ipis = pnv_xive_nr_ipis(xive); uint32_t nr_ends = pnv_xive_nr_ends(xive); XiveEAS eas; diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 453d389848..d420c6571e 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1658,8 +1658,8 @@ do_escalation: void xive_router_notify(XiveNotifier *xn, uint32_t lisn) { XiveRouter *xrtr = XIVE_ROUTER(xn); - uint8_t eas_blk = XIVE_SRCNO_BLOCK(lisn); - uint32_t eas_idx = XIVE_SRCNO_INDEX(lisn); + uint8_t eas_blk = XIVE_EAS_BLOCK(lisn); + uint32_t eas_idx = XIVE_EAS_INDEX(lisn); XiveEAS eas; /* EAS cache lookup */ diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index 08c8bf7172..55307cd153 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -22,9 +22,29 @@ /* * Interrupt source number encoding on PowerBUS */ -#define XIVE_SRCNO_BLOCK(srcno) (((srcno) >> 28) & 0xf) -#define XIVE_SRCNO_INDEX(srcno) ((srcno) & 0x0fffffff) -#define XIVE_SRCNO(blk, idx) ((uint32_t)(blk) << 28 | (idx)) +/* + * Trigger data definition + * + * The trigger definition is used for triggers both for HW source + * interrupts (PHB, PSI), as well as for rerouting interrupts between + * Interrupt Controller. + * + * HW source controllers set bit0 of word0 to ‘0’ as they provide EAS + * information (EAS block + EAS index) in the 8 byte data and not END + * information, which is use for rerouting interrupts. + * + * bit1 of word0 to ‘1’ signals that the state bit check has been + * performed. + */ +#define XIVE_TRIGGER_END PPC_BIT(0) +#define XIVE_TRIGGER_PQ PPC_BIT(1) + +/* + * QEMU macros to manipulate the trigger payload in native endian + */ +#define XIVE_EAS_BLOCK(n) (((n) >> 28) & 0xf) +#define XIVE_EAS_INDEX(n) ((n) & 0x0fffffff) +#define XIVE_EAS(blk, idx) ((uint32_t)(blk) << 28 | (idx)) #define TM_SHIFT 16 From patchwork Thu Oct 24 08:17:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208479 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22A6D112C for ; Thu, 24 Oct 2019 08:20:14 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ED21C2166E for ; Thu, 24 Oct 2019 08:20:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="GvW40Ooy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ED21C2166E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYLs-0007NV-Ja for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:20:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36464) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKQ-0004as-9F for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKO-0004y8-Sh for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:41 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:53349 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKN-0004rx-Pn; Thu, 24 Oct 2019 04:18:40 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrX4wNPz9sQv; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905116; bh=DjdvcuO8WddDt5+4oGTr2StA6WKWigfux/PYV+2l3b4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GvW40OoylaXcri4/IYc5e3lqH0ma/HNvz+LkTeYYx0icTC3L9XTIKMOASYiEE+unL gjrCcVfKMCxyGpJC+nFW0SAgiDnC3lE6bCRTOyOxOIO++EeStVrIkfO3Bse62Sondy 32a6oP1nqmCHDLA/Q8en+GLiMRDyiFDoL2znodj4= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 05/28] ppc/pnv: Use address_space_stq_be() when triggering an interrupt from PSI Date: Thu, 24 Oct 2019 19:17:50 +1100 Message-Id: <20191024081813.2115-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater Include the XIVE_TRIGGER_PQ bit in the trigger data which is how hardware signals to the IC that the PQ bits of the interrupt source have been checked. Signed-off-by: Cédric Le Goater Message-Id: <20191007084102.29776-3-clg@kaod.org> Signed-off-by: David Gibson --- hw/ppc/pnv_psi.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index a997f16bb4..68d0dfacfe 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -660,10 +660,19 @@ static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno) uint32_t offset = (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT); - uint64_t lisn = cpu_to_be64(offset + srcno); + uint64_t data = XIVE_TRIGGER_PQ | offset | srcno; + MemTxResult result; - if (valid) { - cpu_physical_memory_write(notify_addr, &lisn, sizeof(lisn)); + if (!valid) { + return; + } + + address_space_stq_be(&address_space_memory, notify_addr, data, + MEMTXATTRS_UNSPECIFIED, &result); + if (result != MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: trigger failed @%" + HWADDR_PRIx "\n", __func__, notif_port); + return; } } From patchwork Thu Oct 24 08:17:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208489 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 53A44112C for ; Thu, 24 Oct 2019 08:23:14 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2AA9F20856 for ; Thu, 24 Oct 2019 08:23:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="DxlR9TgE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2AA9F20856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34882 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYOm-0005md-Nk for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:23:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36560) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKT-0004k8-Ah for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-000558-J6 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:45 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:45981 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-0004zl-71; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrY36ctz9sRK; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905117; bh=UZTZ+rNi2S7nifzD4DHbqXRrfElzrdf4P+U68TJ+Ip4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DxlR9TgEwFtNCW49PwOaOBaEmppb7j4rlJDlFz8Rnctd4pAI55/cM1rkMacssxahP ypOOWPXn3n/oUwQ909xi92qJ+o/dfPLi3wsp240TCqJZObGhtpKHVvuNR/+Y+mobVZ 6CIodkk9dqHTgMSyJ/ZDBRgU9fbBALDixFuU6ZII= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 06/28] spapr: Set VSMT to smp_threads by default Date: Thu, 24 Oct 2019 19:17:51 +1100 Message-Id: <20191024081813.2115-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz Support for setting VSMT is available in KVM since linux-4.13. Most distros that support KVM on POWER already have it. It thus seem reasonable enough to have the default machine to set VSMT to smp_threads. This brings contiguous VCPU ids and thus brings their upper bound down to the machine's max_cpus. This is especially useful for XIVE KVM devices, which may thus allocate only one VP descriptor per VCPU. Signed-off-by: Greg Kurz Message-Id: <157010411885.246126.12610015369068227139.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/ppc/spapr.c | 7 ++++++- include/hw/ppc/spapr.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4eb97d3a9b..428b834f30 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2496,6 +2496,7 @@ static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx) static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp) { MachineState *ms = MACHINE(spapr); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); Error *local_err = NULL; bool vsmt_user = !!spapr->vsmt; int kvm_smt = kvmppc_smt_threads(); @@ -2522,7 +2523,7 @@ static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp) goto out; } /* In this case, spapr->vsmt has been set by the command line */ - } else { + } else if (!smc->smp_threads_vsmt) { /* * Default VSMT value is tricky, because we need it to be as * consistent as possible (for migration), but this requires @@ -2531,6 +2532,8 @@ static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp) * overwhelmingly common case in production systems. */ spapr->vsmt = MAX(8, smp_threads); + } else { + spapr->vsmt = smp_threads; } /* KVM: If necessary, set the SMT mode: */ @@ -4438,6 +4441,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) smc->irq = &spapr_irq_dual; smc->dr_phb_enabled = true; smc->linux_pci_probe = true; + smc->smp_threads_vsmt = true; } static const TypeInfo spapr_machine_info = { @@ -4505,6 +4509,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc) spapr_machine_4_2_class_options(mc); smc->linux_pci_probe = false; + smc->smp_threads_vsmt = false; compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index cbd1a4c9f3..2009eb64f9 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -122,6 +122,7 @@ struct SpaprMachineClass { bool broken_host_serial_model; /* present real host info to the guest */ bool pre_4_1_migration; /* don't migrate hpt-max-page-size */ bool linux_pci_probe; + bool smp_threads_vsmt; /* set VSMT to smp_threads by default */ void (*phb_placement)(SpaprMachineState *spapr, uint32_t index, uint64_t *buid, hwaddr *pio, From patchwork Thu Oct 24 08:17:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208499 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 256E9112C for ; Thu, 24 Oct 2019 08:26:23 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F04C220856 for ; Thu, 24 Oct 2019 08:26:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="WmLnmIRi" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F04C220856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34914 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYRp-0003EB-Ud for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:26:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36538) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKT-0004jP-1c for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-00054i-Gv for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:44 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:43339 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-0004zj-50; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrY1qc1z9sRQ; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905117; bh=QE+VjKlHW32sv6S8hNVKI2dRx7I/EdLEKnK8b1S4tII=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WmLnmIRilamn5zF4pL5LIcpkopvOST42DzAQDGJPgOTPGBiXfk9Xm+vnfl2n924zH vtydgDT/oNrE1POMsn3q2iohAJjcYbeD5pvT7ozwD1UdG6Avu7R/D+j2ohvxBO+exV 8rtatOalwnHXHQ9JAzjeXrfdOOtAyxdns9bUOkvE= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 07/28] spapr, xics, xive: Introduce SpaprInterruptController QOM interface Date: Thu, 24 Oct 2019 19:17:52 +1100 Message-Id: <20191024081813.2115-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The SpaprIrq structure is used to represent ths spapr machine's irq backend. Except that it kind of conflates two concepts: one is the backend proper - a specific interrupt controller that we might or might not be using, the other is the irq configuration which covers the layout of irq space and which interrupt controllers are allowed. This leads to some pretty confusing code paths for the "dual" configuration where its hooks redirect to other SpaprIrq structures depending on the currently active irq controller. To clean this up, we start by introducing a new SpaprInterruptController QOM interface to represent strictly an interrupt controller backend, not counting anything configuration related. We implement this interface in the XICs and XIVE interrupt controllers, and in future we'll move relevant methods from SpaprIrq into it. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 4 ++++ hw/intc/xics_spapr.c | 4 ++++ hw/ppc/spapr_irq.c | 13 +++++++++++++ include/hw/ppc/spapr_irq.h | 14 ++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 04879abf2e..b67e9c3245 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -519,6 +519,10 @@ static const TypeInfo spapr_xive_info = { .instance_init = spapr_xive_instance_init, .instance_size = sizeof(SpaprXive), .class_init = spapr_xive_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_SPAPR_INTC }, + { } + }, }; static void spapr_xive_register_types(void) diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 6e5eb24b3c..4874e6be55 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -343,6 +343,10 @@ static const TypeInfo ics_spapr_info = { .name = TYPE_ICS_SPAPR, .parent = TYPE_ICS, .class_init = ics_spapr_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_SPAPR_INTC }, + { } + }, }; static void xics_spapr_register_types(void) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 457eabe24c..8791dec1ba 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -23,6 +23,12 @@ #include "trace.h" +static const TypeInfo spapr_intc_info = { + .name = TYPE_SPAPR_INTC, + .parent = TYPE_INTERFACE, + .class_size = sizeof(SpaprInterruptControllerClass), +}; + void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis) { spapr->irq_map_nr = nr_msis; @@ -762,3 +768,10 @@ SpaprIrq spapr_irq_xics_legacy = { .set_irq = spapr_irq_set_irq_xics, .init_kvm = spapr_irq_init_kvm_xics, }; + +static void spapr_irq_register_types(void) +{ + type_register_static(&spapr_intc_info); +} + +type_init(spapr_irq_register_types) diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 69a37f608e..b9398e0be3 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -31,6 +31,20 @@ typedef struct SpaprMachineState SpaprMachineState; +typedef struct SpaprInterruptController SpaprInterruptController; + +#define TYPE_SPAPR_INTC "spapr-interrupt-controller" +#define SPAPR_INTC(obj) \ + INTERFACE_CHECK(SpaprInterruptController, (obj), TYPE_SPAPR_INTC) +#define SPAPR_INTC_CLASS(klass) \ + OBJECT_CLASS_CHECK(SpaprInterruptControllerClass, (klass), TYPE_SPAPR_INTC) +#define SPAPR_INTC_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SpaprInterruptControllerClass, (obj), TYPE_SPAPR_INTC) + +typedef struct SpaprInterruptControllerClass { + InterfaceClass parent; +} SpaprInterruptControllerClass; + void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis); int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, Error **errp); From patchwork Thu Oct 24 08:17:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208495 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C1D4513B1 for ; Thu, 24 Oct 2019 08:26:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 87FAE20856 for ; Thu, 24 Oct 2019 08:26:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="EDWZmgWU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 87FAE20856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34912 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYRV-0002Ws-8B for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:26:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36588) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKU-0004mx-2V for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-00055f-Pa for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:45 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:35313 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-00050A-Cj; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrY4Y0jz9sRD; Thu, 24 Oct 2019 19:18:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905117; bh=6dzl8JJ8+fSiRyb7o7fBhYuTKyrLVQ6TySLo4kuU1Y0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EDWZmgWUHw/+FRrtMFUnHpzZEWWjMJne+QnZ1AhSB0Fpek36GXgwSFeCYwFWjyLl3 9T39J+EmH1hH4+rZ0MPb6uetKQRfqFSlzwBFrurqg4tuRdoqaB+KcbpdfYVljiNRFX Tk83gSvqam4GiXfGkdZ3f954JTsF6zeVT5xinkno= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 08/28] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController Date: Thu, 24 Oct 2019 19:17:53 +1100 Message-Id: <20191024081813.2115-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This method essentially represents code which belongs to the interrupt controller, but needs to be called on all possible intcs, rather than just the currently active one. The "dual" version therefore calls into the xics and xive versions confusingly. Handle this more directly, by making it instead a method on the intc backend, and always calling it on every backend that exists. While we're there, streamline the error reporting a bit. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 25 ++++++++++++ hw/intc/xics_spapr.c | 18 +++++++++ hw/ppc/spapr_cpu_core.c | 3 +- hw/ppc/spapr_irq.c | 81 +++++++++++--------------------------- include/hw/ppc/spapr_irq.h | 13 +++++- 5 files changed, 79 insertions(+), 61 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index b67e9c3245..9338daba3d 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -495,10 +495,33 @@ static Property spapr_xive_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc, + PowerPCCPU *cpu, Error **errp) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + Object *obj; + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp); + if (!obj) { + return -1; + } + + spapr_cpu->tctx = XIVE_TCTX(obj); + + /* + * (TCG) Early setting the OS CAM line for hotplugged CPUs as they + * don't beneficiate from the reset of the XIVE IRQ backend + */ + spapr_xive_set_tctx_os_cam(spapr_cpu->tctx); + return 0; +} + static void spapr_xive_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass); + SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass); dc->desc = "sPAPR XIVE Interrupt Controller"; dc->props = spapr_xive_properties; @@ -511,6 +534,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) xrc->get_nvt = spapr_xive_get_nvt; xrc->write_nvt = spapr_xive_write_nvt; xrc->get_tctx = spapr_xive_get_tctx; + + sicc->cpu_intc_create = spapr_xive_cpu_intc_create; } static const TypeInfo spapr_xive_info = { diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 4874e6be55..946311b858 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -330,13 +330,31 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle)); } +static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc, + PowerPCCPU *cpu, Error **errp) +{ + ICSState *ics = ICS_SPAPR(intc); + Object *obj; + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp); + if (!obj) { + return -1; + } + + spapr_cpu->icp = ICP(obj); + return 0; +} + static void ics_spapr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ICSStateClass *isc = ICS_CLASS(klass); + SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass); device_class_set_parent_realize(dc, ics_spapr_realize, &isc->parent_realize); + sicc->cpu_intc_create = xics_spapr_cpu_intc_create; } static const TypeInfo ics_spapr_info = { diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 1d93de8161..3e4302c7d5 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -237,8 +237,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, qemu_register_reset(spapr_cpu_reset, cpu); spapr_cpu_reset(cpu); - spapr->irq->cpu_intc_create(spapr, cpu, &local_err); - if (local_err) { + if (spapr_irq_cpu_intc_create(spapr, cpu, &local_err) < 0) { goto error_unregister; } diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 8791dec1ba..9cb2fc71ca 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -138,23 +138,6 @@ static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon) ics_pic_print_info(spapr->ics, mon); } -static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr, - PowerPCCPU *cpu, Error **errp) -{ - Error *local_err = NULL; - Object *obj; - SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); - - obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr), - &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - spapr_cpu->icp = ICP(obj); -} - static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) { if (!kvm_irqchip_in_kernel()) { @@ -203,7 +186,6 @@ SpaprIrq spapr_irq_xics = { .free = spapr_irq_free_xics, .print_info = spapr_irq_print_info_xics, .dt_populate = spapr_dt_xics, - .cpu_intc_create = spapr_irq_cpu_intc_create_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, .set_irq = spapr_irq_set_irq_xics, @@ -239,28 +221,6 @@ static void spapr_irq_print_info_xive(SpaprMachineState *spapr, spapr_xive_pic_print_info(spapr->xive, mon); } -static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr, - PowerPCCPU *cpu, Error **errp) -{ - Error *local_err = NULL; - Object *obj; - SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); - - obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - spapr_cpu->tctx = XIVE_TCTX(obj); - - /* - * (TCG) Early setting the OS CAM line for hotplugged CPUs as they - * don't beneficiate from the reset of the XIVE IRQ backend - */ - spapr_xive_set_tctx_os_cam(spapr_cpu->tctx); -} - static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id) { return spapr_xive_post_load(spapr->xive, version_id); @@ -316,7 +276,6 @@ SpaprIrq spapr_irq_xive = { .free = spapr_irq_free_xive, .print_info = spapr_irq_print_info_xive, .dt_populate = spapr_dt_xive, - .cpu_intc_create = spapr_irq_cpu_intc_create_xive, .post_load = spapr_irq_post_load_xive, .reset = spapr_irq_reset_xive, .set_irq = spapr_irq_set_irq_xive, @@ -381,20 +340,6 @@ static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr, spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle); } -static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr, - PowerPCCPU *cpu, Error **errp) -{ - Error *local_err = NULL; - - spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - spapr_irq_xics.cpu_intc_create(spapr, cpu, errp); -} - static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) { /* @@ -460,7 +405,6 @@ SpaprIrq spapr_irq_dual = { .free = spapr_irq_free_dual, .print_info = spapr_irq_print_info_dual, .dt_populate = spapr_irq_dt_populate_dual, - .cpu_intc_create = spapr_irq_cpu_intc_create_dual, .post_load = spapr_irq_post_load_dual, .reset = spapr_irq_reset_dual, .set_irq = spapr_irq_set_irq_dual, @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp) /* * sPAPR IRQ frontend routines for devices */ +#define ALL_INTCS(spapr_) \ + { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), } + +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, + PowerPCCPU *cpu, Error **errp) +{ + SpaprInterruptController *intcs[] = ALL_INTCS(spapr); + int i; + int rc; + + for (i = 0; i < ARRAY_SIZE(intcs); i++) { + SpaprInterruptController *intc = intcs[i]; + if (intc) { + SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); + rc = sicc->cpu_intc_create(intc, cpu, errp); + if (rc < 0) { + return rc; + } + } + } + + return 0; +} + void spapr_irq_init(SpaprMachineState *spapr, Error **errp) { MachineState *machine = MACHINE(spapr); @@ -762,7 +730,6 @@ SpaprIrq spapr_irq_xics_legacy = { .free = spapr_irq_free_xics, .print_info = spapr_irq_print_info_xics, .dt_populate = spapr_dt_xics, - .cpu_intc_create = spapr_irq_cpu_intc_create_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, .set_irq = spapr_irq_set_irq_xics, diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index b9398e0be3..5e641e23c1 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -43,8 +43,19 @@ typedef struct SpaprInterruptController SpaprInterruptController; typedef struct SpaprInterruptControllerClass { InterfaceClass parent; + + /* + * These methods will typically be called on all intcs, active and + * inactive + */ + int (*cpu_intc_create)(SpaprInterruptController *intc, + PowerPCCPU *cpu, Error **errp); } SpaprInterruptControllerClass; +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, + PowerPCCPU *cpu, Error **errp); + + void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis); int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, Error **errp); @@ -61,8 +72,6 @@ typedef struct SpaprIrq { void (*print_info)(SpaprMachineState *spapr, Monitor *mon); void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); - void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu, - Error **errp); int (*post_load)(SpaprMachineState *spapr, int version_id); void (*reset)(SpaprMachineState *spapr, Error **errp); void (*set_irq)(void *opaque, int srcno, int val); From patchwork Thu Oct 24 08:17:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208509 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BE254112C for ; Thu, 24 Oct 2019 08:29:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 84C9220856 for ; Thu, 24 Oct 2019 08:29:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="l+h4tI5k" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 84C9220856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34964 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYVC-0001z9-QJ for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:29:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36597) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKU-0004nA-5h for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-00054w-HW for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:46 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:51065 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-0004zh-4a; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrY0Zxrz9sR0; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905117; bh=3rarXC+2dGixFEg3CKdOUSqUn8XUU6WBiaqJUrhqbCM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l+h4tI5k6P7Ig0cRbBPAE72/luZfxuL5Ofjw659hNLbyvB4ItapoD5VYYyM7g6k75 IB7PdXW3qEKUO35LfQvsHt2zW4OsaBu8foKw9nQjXZ5nrtvRYMJ/O3+hWUcED2/cIh I+OX2BJJLaY6C/blF0wal1MiZ1DavX6TTMjzkZj0= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 09/28] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController Date: Thu, 24 Oct 2019 19:17:54 +1100 Message-Id: <20191024081813.2115-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" These methods, like cpu_intc_create, really belong to the interrupt controller, but need to be called on all possible intcs. Like cpu_intc_create, therefore, make them methods on the intc and always call it for all existing intcs. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 71 ++++++++++++----------- hw/intc/xics_spapr.c | 29 ++++++++++ hw/ppc/spapr_irq.c | 110 +++++++++++------------------------- include/hw/ppc/spapr_irq.h | 5 +- include/hw/ppc/spapr_xive.h | 2 - 5 files changed, 102 insertions(+), 115 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 9338daba3d..ff1a175b44 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = { }, }; +static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn, + bool lsi, Error **errp) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + XiveSource *xsrc = &xive->source; + + assert(lisn < xive->nr_irqs); + + if (xive_eas_is_valid(&xive->eat[lisn])) { + error_setg(errp, "IRQ %d is not free", lisn); + return -EBUSY; + } + + /* + * Set default values when allocating an IRQ number + */ + xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED); + if (lsi) { + xive_source_irq_set_lsi(xsrc, lisn); + } + + if (kvm_irqchip_in_kernel()) { + return kvmppc_xive_source_reset_one(xsrc, lisn, errp); + } + + return 0; +} + +static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + assert(lisn < xive->nr_irqs); + + xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID); +} + static Property spapr_xive_properties[] = { DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0), DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0), @@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) xrc->get_tctx = spapr_xive_get_tctx; sicc->cpu_intc_create = spapr_xive_cpu_intc_create; + sicc->claim_irq = spapr_xive_claim_irq; + sicc->free_irq = spapr_xive_free_irq; } static const TypeInfo spapr_xive_info = { @@ -557,39 +595,6 @@ static void spapr_xive_register_types(void) type_init(spapr_xive_register_types) -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp) -{ - XiveSource *xsrc = &xive->source; - - assert(lisn < xive->nr_irqs); - - if (xive_eas_is_valid(&xive->eat[lisn])) { - error_setg(errp, "IRQ %d is not free", lisn); - return -EBUSY; - } - - /* - * Set default values when allocating an IRQ number - */ - xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED); - if (lsi) { - xive_source_irq_set_lsi(xsrc, lisn); - } - - if (kvm_irqchip_in_kernel()) { - return kvmppc_xive_source_reset_one(xsrc, lisn, errp); - } - - return 0; -} - -void spapr_xive_irq_free(SpaprXive *xive, int lisn) -{ - assert(lisn < xive->nr_irqs); - - xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID); -} - /* * XIVE hcalls * diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 946311b858..224fe1efcd 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -346,6 +346,33 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc, return 0; } +static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq, + bool lsi, Error **errp) +{ + ICSState *ics = ICS_SPAPR(intc); + + assert(ics); + assert(ics_valid_irq(ics, irq)); + + if (!ics_irq_free(ics, irq - ics->offset)) { + error_setg(errp, "IRQ %d is not free", irq); + return -EBUSY; + } + + ics_set_irq_type(ics, irq - ics->offset, lsi); + return 0; +} + +static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq) +{ + ICSState *ics = ICS_SPAPR(intc); + uint32_t srcno = irq - ics->offset; + + assert(ics_valid_irq(ics, irq)); + + memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState)); +} + static void ics_spapr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) device_class_set_parent_realize(dc, ics_spapr_realize, &isc->parent_realize); sicc->cpu_intc_create = xics_spapr_cpu_intc_create; + sicc->claim_irq = xics_spapr_claim_irq; + sicc->free_irq = xics_spapr_free_irq; } static const TypeInfo ics_spapr_info = { diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 9cb2fc71ca..83882cfad3 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr, * XICS IRQ backend. */ -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi, - Error **errp) -{ - ICSState *ics = spapr->ics; - - assert(ics); - assert(ics_valid_irq(ics, irq)); - - if (!ics_irq_free(ics, irq - ics->offset)) { - error_setg(errp, "IRQ %d is not free", irq); - return -1; - } - - ics_set_irq_type(ics, irq - ics->offset, lsi); - return 0; -} - -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq) -{ - ICSState *ics = spapr->ics; - uint32_t srcno = irq - ics->offset; - - assert(ics_valid_irq(ics, irq)); - - memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState)); -} - static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon) { CPUState *cs; @@ -182,8 +155,6 @@ SpaprIrq spapr_irq_xics = { .xics = true, .xive = false, - .claim = spapr_irq_claim_xics, - .free = spapr_irq_free_xics, .print_info = spapr_irq_print_info_xics, .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, @@ -196,17 +167,6 @@ SpaprIrq spapr_irq_xics = { * XIVE IRQ backend. */ -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi, - Error **errp) -{ - return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp); -} - -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq) -{ - spapr_xive_irq_free(spapr->xive, irq); -} - static void spapr_irq_print_info_xive(SpaprMachineState *spapr, Monitor *mon) { @@ -272,8 +232,6 @@ SpaprIrq spapr_irq_xive = { .xics = false, .xive = true, - .claim = spapr_irq_claim_xive, - .free = spapr_irq_free_xive, .print_info = spapr_irq_print_info_xive, .dt_populate = spapr_dt_xive, .post_load = spapr_irq_post_load_xive, @@ -301,33 +259,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr) &spapr_irq_xive : &spapr_irq_xics; } -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi, - Error **errp) -{ - Error *local_err = NULL; - int ret; - - ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return ret; - } - - ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return ret; - } - - return ret; -} - -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq) -{ - spapr_irq_xics.free(spapr, irq); - spapr_irq_xive.free(spapr, irq); -} - static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon) { spapr_irq_current(spapr)->print_info(spapr, mon); @@ -401,8 +332,6 @@ SpaprIrq spapr_irq_dual = { .xics = true, .xive = true, - .claim = spapr_irq_claim_dual, - .free = spapr_irq_free_dual, .print_info = spapr_irq_print_info_dual, .dt_populate = spapr_irq_dt_populate_dual, .post_load = spapr_irq_post_load_dual, @@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) /* Enable the CPU IPIs */ for (i = 0; i < nr_servers; ++i) { - if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, - false, errp) < 0) { + SpaprInterruptControllerClass *sicc + = SPAPR_INTC_GET_CLASS(spapr->xive); + + if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i, + false, errp) < 0) { return; } } @@ -587,21 +519,45 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp) { + SpaprInterruptController *intcs[] = ALL_INTCS(spapr); + int i; + int rc; + assert(irq >= SPAPR_XIRQ_BASE); assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE)); - return spapr->irq->claim(spapr, irq, lsi, errp); + for (i = 0; i < ARRAY_SIZE(intcs); i++) { + SpaprInterruptController *intc = intcs[i]; + if (intc) { + SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); + rc = sicc->claim_irq(intc, irq, lsi, errp); + if (rc < 0) { + return rc; + } + } + } + + return 0; } void spapr_irq_free(SpaprMachineState *spapr, int irq, int num) { - int i; + SpaprInterruptController *intcs[] = ALL_INTCS(spapr); + int i, j; assert(irq >= SPAPR_XIRQ_BASE); assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE)); for (i = irq; i < (irq + num); i++) { - spapr->irq->free(spapr, i); + for (j = 0; j < ARRAY_SIZE(intcs); j++) { + SpaprInterruptController *intc = intcs[j]; + + if (intc) { + SpaprInterruptControllerClass *sicc + = SPAPR_INTC_GET_CLASS(intc); + sicc->free_irq(intc, i); + } + } } } @@ -726,8 +682,6 @@ SpaprIrq spapr_irq_xics_legacy = { .xics = true, .xive = false, - .claim = spapr_irq_claim_xics, - .free = spapr_irq_free_xics, .print_info = spapr_irq_print_info_xics, .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 5e641e23c1..adfef0fcbe 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -50,6 +50,9 @@ typedef struct SpaprInterruptControllerClass { */ int (*cpu_intc_create)(SpaprInterruptController *intc, PowerPCCPU *cpu, Error **errp); + int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi, + Error **errp); + void (*free_irq)(SpaprInterruptController *intc, int irq); } SpaprInterruptControllerClass; int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, @@ -67,8 +70,6 @@ typedef struct SpaprIrq { bool xics; bool xive; - int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp); - void (*free)(SpaprMachineState *spapr, int irq); void (*print_info)(SpaprMachineState *spapr, Monitor *mon); void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 0df20a6590..8f875673f5 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -54,8 +54,6 @@ typedef struct SpaprXive { */ #define SPAPR_XIVE_BLOCK_ID 0x0 -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp); -void spapr_xive_irq_free(SpaprXive *xive, int lisn); void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon); int spapr_xive_post_load(SpaprXive *xive, int version_id); From patchwork Thu Oct 24 08:17:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208507 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 12E8B112C for ; Thu, 24 Oct 2019 08:29:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DD5FF20856 for ; Thu, 24 Oct 2019 08:29:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="eezqC+IB" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DD5FF20856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34952 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYUw-0001Ky-Ba for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:29:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36580) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKT-0004ln-SB for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKS-00056Q-0H for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:45 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:41453 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-00050W-Il; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ11zBz9sRf; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=wvXDPshufdCi8k7tW6RyXt9zWULGsXaEFYKD7nC2PAY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eezqC+IBbY4DT7BR1gZQ4xZCgYRdjIqelisu58awYF9niOFA66JP/PZkPHKyWWyxr zmvtVCegkNUK3Vo7R98rwSEHTf/LXmkN1/UWH9s3E2Yc+kgXWYWcWh6TwQ3Kn9UVXe usWkLbVVz91T1/xLZQLqpvL2/E0l4JOdhwcBqguA= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 10/28] spapr: Formalize notion of active interrupt controller Date: Thu, 24 Oct 2019 19:17:55 +1100 Message-Id: <20191024081813.2115-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" spapr now has the mechanism of constructing both XICS and XIVE instances of the SpaprInterruptController interface. However, only one of the interrupt controllers will actually be active at any given time, depending on feature negotiation with the guest. This is handled in the current code via spapr_irq_current() which checks the OV5 vector from feature negotiation to determine the current backend. Determining the active controller at the point we need it like this can be pretty confusing, because it makes it very non obvious at what points the active controller can change. This can make it difficult to reason about the code and where a change of active controller could appear in sequence with other events. Make this mechanism more explicit by adding an 'active_intc' pointer and an explicit spapr_irq_update_active_intc() function to update it from the CAS state. We also add hooks on the intc backend which will get called when it is activated or deactivated. For now we just introduce the switch and hooks, later patches will actually start using them. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr_irq.c | 51 ++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 5 ++-- include/hw/ppc/spapr_irq.h | 5 ++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 83882cfad3..249a2688ac 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -586,6 +586,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq) int spapr_irq_post_load(SpaprMachineState *spapr, int version_id) { + spapr_irq_update_active_intc(spapr); return spapr->irq->post_load(spapr, version_id); } @@ -593,6 +594,8 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp) { assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr)); + spapr_irq_update_active_intc(spapr); + if (spapr->irq->reset) { spapr->irq->reset(spapr, errp); } @@ -619,6 +622,54 @@ int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp) return phandle; } +static void set_active_intc(SpaprMachineState *spapr, + SpaprInterruptController *new_intc) +{ + SpaprInterruptControllerClass *sicc; + + assert(new_intc); + + if (new_intc == spapr->active_intc) { + /* Nothing to do */ + return; + } + + if (spapr->active_intc) { + sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc); + if (sicc->deactivate) { + sicc->deactivate(spapr->active_intc); + } + } + + sicc = SPAPR_INTC_GET_CLASS(new_intc); + if (sicc->activate) { + sicc->activate(new_intc, &error_fatal); + } + + spapr->active_intc = new_intc; +} + +void spapr_irq_update_active_intc(SpaprMachineState *spapr) +{ + SpaprInterruptController *new_intc; + + if (!spapr->ics) { + /* + * XXX before we run CAS, ov5_cas is initialized empty, which + * indicates XICS, even if we have ic-mode=xive. TODO: clean + * up the CAS path so that we have a clearer way of handling + * this. + */ + new_intc = SPAPR_INTC(spapr->xive); + } else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + new_intc = SPAPR_INTC(spapr->xive); + } else { + new_intc = SPAPR_INTC(spapr->ics); + } + + set_active_intc(spapr, new_intc); +} + /* * XICS legacy routines - to deprecate one day */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 2009eb64f9..3b34cf5207 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -144,7 +144,6 @@ struct SpaprMachineState { struct SpaprVioBus *vio_bus; QLIST_HEAD(, SpaprPhbState) phbs; struct SpaprNvram *nvram; - ICSState *ics; SpaprRtcState rtc; SpaprResizeHpt resize_hpt; @@ -196,9 +195,11 @@ struct SpaprMachineState { int32_t irq_map_nr; unsigned long *irq_map; - SpaprXive *xive; SpaprIrq *irq; qemu_irq *qirqs; + SpaprInterruptController *active_intc; + ICSState *ics; + SpaprXive *xive; bool cmd_line_caps[SPAPR_CAP_NUM]; SpaprCapabilities def, eff, mig; diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index adfef0fcbe..593059eff5 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -44,6 +44,9 @@ typedef struct SpaprInterruptController SpaprInterruptController; typedef struct SpaprInterruptControllerClass { InterfaceClass parent; + int (*activate)(SpaprInterruptController *intc, Error **errp); + void (*deactivate)(SpaprInterruptController *intc); + /* * These methods will typically be called on all intcs, active and * inactive @@ -55,6 +58,8 @@ typedef struct SpaprInterruptControllerClass { void (*free_irq)(SpaprInterruptController *intc, int irq); } SpaprInterruptControllerClass; +void spapr_irq_update_active_intc(SpaprMachineState *spapr); + int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, PowerPCCPU *cpu, Error **errp); From patchwork Thu Oct 24 08:17:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208485 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8AE0A13B1 for ; Thu, 24 Oct 2019 08:23:07 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 60E0020856 for ; Thu, 24 Oct 2019 08:23:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="NYLqdn4Z" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 60E0020856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34878 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYOf-0005Zq-JO for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:23:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36591) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKU-0004n4-3r for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-00055k-Q0 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:45 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:37017 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-00050Q-Df; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrY5YLbz9sRN; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905117; bh=cGgO+LrlalDR1CfDdRewQUa5XMqicGnpQGJf4D6HOmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NYLqdn4Z0fg8dNqdzUp+B/lvW+ITjaBqV8mdcXcJ7oiK+dYz0ugPNcbw4C46TJKwu JVVXO9EV4/Mu7Grjp8r9d837B52KNUxp3ulXKM6Hm+OU7pE7/ny1fX5B0KNyflIyae d2mzBFWoZwh/OD/ynhRGAnCr9S1x57Beh9PCeqkU= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 11/28] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController Date: Thu, 24 Oct 2019 19:17:56 +1100 Message-Id: <20191024081813.2115-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dispatch directly through that, rather than dispatching via SpaprIrq with the dual version having to do a second conditional dispatch. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 12 +++++++++++ hw/intc/xics_spapr.c | 9 +++++++++ hw/ppc/spapr_irq.c | 41 ++++++++++---------------------------- include/hw/ppc/spapr_irq.h | 4 +++- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index ff1a175b44..52d5e71793 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc, return 0; } +static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_source_set_irq(&xive->source, irq, val); + } else { + xive_source_set_irq(&xive->source, irq, val); + } +} + static void spapr_xive_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->cpu_intc_create = spapr_xive_cpu_intc_create; sicc->claim_irq = spapr_xive_claim_irq; sicc->free_irq = spapr_xive_free_irq; + sicc->set_irq = spapr_xive_set_irq; } static const TypeInfo spapr_xive_info = { diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 224fe1efcd..02372697f6 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq) memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState)); } +static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val) +{ + ICSState *ics = ICS_SPAPR(intc); + uint32_t srcno = irq - ics->offset; + + ics_set_irq(ics, srcno, val); +} + static void ics_spapr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) sicc->cpu_intc_create = xics_spapr_cpu_intc_create; sicc->claim_irq = xics_spapr_claim_irq; sicc->free_irq = xics_spapr_free_irq; + sicc->set_irq = xics_spapr_set_irq; } static const TypeInfo ics_spapr_info = { diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 249a2688ac..bfccb815ed 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) return 0; } -static void spapr_irq_set_irq_xics(void *opaque, int irq, int val) -{ - SpaprMachineState *spapr = opaque; - uint32_t srcno = irq - spapr->ics->offset; - - ics_set_irq(spapr->ics, srcno, val); -} - static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp) { Error *local_err = NULL; @@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = { .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, - .set_irq = spapr_irq_set_irq_xics, .init_kvm = spapr_irq_init_kvm_xics, }; @@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) spapr_xive_mmio_set_enabled(spapr->xive, true); } -static void spapr_irq_set_irq_xive(void *opaque, int irq, int val) -{ - SpaprMachineState *spapr = opaque; - - if (kvm_irqchip_in_kernel()) { - kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val); - } else { - xive_source_set_irq(&spapr->xive->source, irq, val); - } -} - static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp) { if (kvm_enabled()) { @@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = { .dt_populate = spapr_dt_xive, .post_load = spapr_irq_post_load_xive, .reset = spapr_irq_reset_xive, - .set_irq = spapr_irq_set_irq_xive, .init_kvm = spapr_irq_init_kvm_xive, }; @@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp) spapr_irq_current(spapr)->reset(spapr, errp); } -static void spapr_irq_set_irq_dual(void *opaque, int irq, int val) -{ - SpaprMachineState *spapr = opaque; - - spapr_irq_current(spapr)->set_irq(spapr, irq, val); -} - /* * Define values in sync with the XIVE and XICS backend */ @@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = { .dt_populate = spapr_irq_dt_populate_dual, .post_load = spapr_irq_post_load_dual, .reset = spapr_irq_reset_dual, - .set_irq = spapr_irq_set_irq_dual, .init_kvm = NULL, /* should not be used */ }; @@ -424,6 +395,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, return 0; } +static void spapr_set_irq(void *opaque, int irq, int level) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(opaque); + SpaprInterruptControllerClass *sicc + = SPAPR_INTC_GET_CLASS(spapr->active_intc); + + sicc->set_irq(spapr->active_intc, irq, level); +} + void spapr_irq_init(SpaprMachineState *spapr, Error **errp) { MachineState *machine = MACHINE(spapr); @@ -513,7 +493,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) spapr_xive_hcall_init(spapr); } - spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr, + spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr, spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE); } @@ -737,7 +717,6 @@ SpaprIrq spapr_irq_xics_legacy = { .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, - .set_irq = spapr_irq_set_irq_xics, .init_kvm = spapr_irq_init_kvm_xics, }; diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 593059eff5..ece8d2ea48 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -56,6 +56,9 @@ typedef struct SpaprInterruptControllerClass { int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi, Error **errp); void (*free_irq)(SpaprInterruptController *intc, int irq); + + /* These methods should only be called on the active intc */ + void (*set_irq)(SpaprInterruptController *intc, int irq, int val); } SpaprInterruptControllerClass; void spapr_irq_update_active_intc(SpaprMachineState *spapr); @@ -80,7 +83,6 @@ typedef struct SpaprIrq { void *fdt, uint32_t phandle); int (*post_load)(SpaprMachineState *spapr, int version_id); void (*reset)(SpaprMachineState *spapr, Error **errp); - void (*set_irq)(void *opaque, int srcno, int val); void (*init_kvm)(SpaprMachineState *spapr, Error **errp); } SpaprIrq; From patchwork Thu Oct 24 08:17:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208491 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 83BF213B1 for ; Thu, 24 Oct 2019 08:23:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 59A4E2070B for ; Thu, 24 Oct 2019 08:23:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="DtLNTJv+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 59A4E2070B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34884 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYOz-0006C4-K1 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:23:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36571) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKT-0004kZ-Hz for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKR-00056H-Uh for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:45 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:32983 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKR-00050T-H5; Thu, 24 Oct 2019 04:18:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrY6my7z9sRX; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905117; bh=Y4tlqaw+1bOhPtsgVo+T80XZay4GmD5LhgnqMj46KQ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DtLNTJv+21gKzUUYd7v+3nbr55tFKpbXJK/4VjYlU19tRhWYRIwDR98mm8E9tuuUT q4JvUI9tfBlgxKMlP1/lZCR8lrjTtT2CLpZZFhPyMtZo+S5X+TT7d5gf/sD92+kJVJ 1LeOozWevsmgni0059K5y2CL/EJWn5NsS5LnTCg8= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 12/28] spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController Date: Thu, 24 Oct 2019 19:17:57 +1100 Message-Id: <20191024081813.2115-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dispatch directly through that, rather than dispatching via SpaprIrq with the dual version having to do a second conditional dispatch. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 15 +++++++++++++ hw/intc/xics_spapr.c | 15 +++++++++++++ hw/ppc/spapr.c | 2 +- hw/ppc/spapr_irq.c | 44 +++++++------------------------------- include/hw/ppc/spapr_irq.h | 4 ++-- 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 52d5e71793..700ec5c9c1 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -564,6 +564,20 @@ static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val) } } +static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + CPUState *cs; + + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + + xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon); + } + + spapr_xive_pic_print_info(xive, mon); +} + static void spapr_xive_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -586,6 +600,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->claim_irq = spapr_xive_claim_irq; sicc->free_irq = spapr_xive_free_irq; sicc->set_irq = spapr_xive_set_irq; + sicc->print_info = spapr_xive_print_info; } static const TypeInfo spapr_xive_info = { diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 02372697f6..415defe394 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -381,6 +381,20 @@ static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val) ics_set_irq(ics, srcno, val); } +static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon) +{ + ICSState *ics = ICS_SPAPR(intc); + CPUState *cs; + + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + + icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon); + } + + ics_pic_print_info(ics, mon); +} + static void ics_spapr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -393,6 +407,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) sicc->claim_irq = xics_spapr_claim_irq; sicc->free_irq = xics_spapr_free_irq; sicc->set_irq = xics_spapr_set_irq; + sicc->print_info = xics_spapr_print_info; } static const TypeInfo ics_spapr_info = { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 428b834f30..24fe12b244 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4266,7 +4266,7 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj, { SpaprMachineState *spapr = SPAPR_MACHINE(obj); - spapr->irq->print_info(spapr, mon); + spapr_irq_print_info(spapr, mon); monitor_printf(mon, "irqchip: %s\n", kvm_irqchip_in_kernel() ? "in-kernel" : "emulated"); } diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index bfccb815ed..a29b527232 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -98,19 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr, * XICS IRQ backend. */ -static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon) -{ - CPUState *cs; - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - - icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon); - } - - ics_pic_print_info(spapr->ics, mon); -} - static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) { if (!kvm_irqchip_in_kernel()) { @@ -147,7 +134,6 @@ SpaprIrq spapr_irq_xics = { .xics = true, .xive = false, - .print_info = spapr_irq_print_info_xics, .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, @@ -158,20 +144,6 @@ SpaprIrq spapr_irq_xics = { * XIVE IRQ backend. */ -static void spapr_irq_print_info_xive(SpaprMachineState *spapr, - Monitor *mon) -{ - CPUState *cs; - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - - xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon); - } - - spapr_xive_pic_print_info(spapr->xive, mon); -} - static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id) { return spapr_xive_post_load(spapr->xive, version_id); @@ -212,7 +184,6 @@ SpaprIrq spapr_irq_xive = { .xics = false, .xive = true, - .print_info = spapr_irq_print_info_xive, .dt_populate = spapr_dt_xive, .post_load = spapr_irq_post_load_xive, .reset = spapr_irq_reset_xive, @@ -238,11 +209,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr) &spapr_irq_xive : &spapr_irq_xics; } -static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon) -{ - spapr_irq_current(spapr)->print_info(spapr, mon); -} - static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle) @@ -304,7 +270,6 @@ SpaprIrq spapr_irq_dual = { .xics = true, .xive = true, - .print_info = spapr_irq_print_info_dual, .dt_populate = spapr_irq_dt_populate_dual, .post_load = spapr_irq_post_load_dual, .reset = spapr_irq_reset_dual, @@ -404,6 +369,14 @@ static void spapr_set_irq(void *opaque, int irq, int level) sicc->set_irq(spapr->active_intc, irq, level); } +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon) +{ + SpaprInterruptControllerClass *sicc + = SPAPR_INTC_GET_CLASS(spapr->active_intc); + + sicc->print_info(spapr->active_intc, mon); +} + void spapr_irq_init(SpaprMachineState *spapr, Error **errp) { MachineState *machine = MACHINE(spapr); @@ -713,7 +686,6 @@ SpaprIrq spapr_irq_xics_legacy = { .xics = true, .xive = false, - .print_info = spapr_irq_print_info_xics, .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index ece8d2ea48..bdfeb3b107 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -59,13 +59,14 @@ typedef struct SpaprInterruptControllerClass { /* These methods should only be called on the active intc */ void (*set_irq)(SpaprInterruptController *intc, int irq, int val); + void (*print_info)(SpaprInterruptController *intc, Monitor *mon); } SpaprInterruptControllerClass; void spapr_irq_update_active_intc(SpaprMachineState *spapr); int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, PowerPCCPU *cpu, Error **errp); - +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon); void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis); int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, @@ -78,7 +79,6 @@ typedef struct SpaprIrq { bool xics; bool xive; - void (*print_info)(SpaprMachineState *spapr, Monitor *mon); void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); int (*post_load)(SpaprMachineState *spapr, int version_id); From patchwork Thu Oct 24 08:17:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208533 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2C5E614ED for ; Thu, 24 Oct 2019 08:44:44 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E6675205F4 for ; Thu, 24 Oct 2019 08:44:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="UosDykEZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E6675205F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35238 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYja-0000M2-UR for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:44:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36762) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKY-0004vY-Q8 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKV-0005Gi-Gt for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:50 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:50791 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKU-000597-Re; Thu, 24 Oct 2019 04:18:47 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ2qTLz9sRm; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=zWVhbYOZmUnJ8e+Ef4VJMXT3ETq6nGVuOZb+Xr8IZzc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UosDykEZ8xLi6r5OKSCZJCuN7xvvp4LL0zQ2KPLkgbCnMRrZCTEYyZKdcukSTaa5b 9P6aMjXMrzpHVemtZVXkBojKr+Bz4O3C/jR9IM6WkuWtHdCDQ9kt71vMIsK+O+dPlS GrtNIb+fiXkTUq3o9KiGP8dXaac3UCw18HFBcKF4= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 13/28] spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController Date: Thu, 24 Oct 2019 19:17:58 +1100 Message-Id: <20191024081813.2115-14-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dispatch directly through that, rather than dispatching via SpaprIrq with the dual version having to do a second conditional dispatch. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 125 ++++++++++++++++++------------------ hw/intc/xics_spapr.c | 5 +- hw/ppc/spapr.c | 3 +- hw/ppc/spapr_irq.c | 20 +++--- include/hw/ppc/spapr_irq.h | 6 +- include/hw/ppc/spapr_xive.h | 2 - include/hw/ppc/xics_spapr.h | 2 - 7 files changed, 80 insertions(+), 83 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 700ec5c9c1..37ffb74ca5 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -578,6 +578,68 @@ static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon) spapr_xive_pic_print_info(xive, mon); } +static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers, + void *fdt, uint32_t phandle) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + int node; + uint64_t timas[2 * 2]; + /* Interrupt number ranges for the IPIs */ + uint32_t lisn_ranges[] = { + cpu_to_be32(0), + cpu_to_be32(nr_servers), + }; + /* + * EQ size - the sizes of pages supported by the system 4K, 64K, + * 2M, 16M. We only advertise 64K for the moment. + */ + uint32_t eq_sizes[] = { + cpu_to_be32(16), /* 64K */ + }; + /* + * The following array is in sync with the reserved priorities + * defined by the 'spapr_xive_priority_is_reserved' routine. + */ + uint32_t plat_res_int_priorities[] = { + cpu_to_be32(7), /* start */ + cpu_to_be32(0xf8), /* count */ + }; + + /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */ + timas[0] = cpu_to_be64(xive->tm_base + + XIVE_TM_USER_PAGE * (1ull << TM_SHIFT)); + timas[1] = cpu_to_be64(1ull << TM_SHIFT); + timas[2] = cpu_to_be64(xive->tm_base + + XIVE_TM_OS_PAGE * (1ull << TM_SHIFT)); + timas[3] = cpu_to_be64(1ull << TM_SHIFT); + + _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename)); + + _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe")); + _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas))); + + _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe")); + _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes, + sizeof(eq_sizes))); + _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges, + sizeof(lisn_ranges))); + + /* For Linux to link the LSIs to the interrupt controller. */ + _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0)); + _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2)); + + /* For SLOF */ + _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle)); + _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle)); + + /* + * The "ibm,plat-res-int-priorities" property defines the priority + * ranges reserved by the hypervisor + */ + _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities", + plat_res_int_priorities, sizeof(plat_res_int_priorities))); +} + static void spapr_xive_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -601,6 +663,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->free_irq = spapr_xive_free_irq; sicc->set_irq = spapr_xive_set_irq; sicc->print_info = spapr_xive_print_info; + sicc->dt = spapr_xive_dt; } static const TypeInfo spapr_xive_info = { @@ -1601,65 +1664,3 @@ void spapr_xive_hcall_init(SpaprMachineState *spapr) spapr_register_hypercall(H_INT_SYNC, h_int_sync); spapr_register_hypercall(H_INT_RESET, h_int_reset); } - -void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, - uint32_t phandle) -{ - SpaprXive *xive = spapr->xive; - int node; - uint64_t timas[2 * 2]; - /* Interrupt number ranges for the IPIs */ - uint32_t lisn_ranges[] = { - cpu_to_be32(0), - cpu_to_be32(nr_servers), - }; - /* - * EQ size - the sizes of pages supported by the system 4K, 64K, - * 2M, 16M. We only advertise 64K for the moment. - */ - uint32_t eq_sizes[] = { - cpu_to_be32(16), /* 64K */ - }; - /* - * The following array is in sync with the reserved priorities - * defined by the 'spapr_xive_priority_is_reserved' routine. - */ - uint32_t plat_res_int_priorities[] = { - cpu_to_be32(7), /* start */ - cpu_to_be32(0xf8), /* count */ - }; - - /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */ - timas[0] = cpu_to_be64(xive->tm_base + - XIVE_TM_USER_PAGE * (1ull << TM_SHIFT)); - timas[1] = cpu_to_be64(1ull << TM_SHIFT); - timas[2] = cpu_to_be64(xive->tm_base + - XIVE_TM_OS_PAGE * (1ull << TM_SHIFT)); - timas[3] = cpu_to_be64(1ull << TM_SHIFT); - - _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename)); - - _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe")); - _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas))); - - _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe")); - _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes, - sizeof(eq_sizes))); - _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges, - sizeof(lisn_ranges))); - - /* For Linux to link the LSIs to the interrupt controller. */ - _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0)); - _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2)); - - /* For SLOF */ - _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle)); - _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle)); - - /* - * The "ibm,plat-res-int-priorities" property defines the priority - * ranges reserved by the hypervisor - */ - _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities", - plat_res_int_priorities, sizeof(plat_res_int_priorities))); -} diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 415defe394..4eabafc7e1 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -308,8 +308,8 @@ static void ics_spapr_realize(DeviceState *dev, Error **errp) spapr_register_hypercall(H_IPOLL, h_ipoll); } -void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, - uint32_t phandle) +static void xics_spapr_dt(SpaprInterruptController *intc, uint32_t nr_servers, + void *fdt, uint32_t phandle) { uint32_t interrupt_server_ranges_prop[] = { 0, cpu_to_be32(nr_servers), @@ -408,6 +408,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) sicc->free_irq = xics_spapr_free_irq; sicc->set_irq = xics_spapr_set_irq; sicc->print_info = xics_spapr_print_info; + sicc->dt = xics_spapr_dt; } static const TypeInfo ics_spapr_info = { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 24fe12b244..c9623600c2 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1247,8 +1247,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr) _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); /* /interrupt controller */ - spapr->irq->dt_populate(spapr, spapr_max_server_number(spapr), fdt, - PHANDLE_INTC); + spapr_irq_dt(spapr, spapr_max_server_number(spapr), fdt, PHANDLE_INTC); ret = spapr_populate_memory(spapr, fdt); if (ret < 0) { diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index a29b527232..a8005072e6 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -134,7 +134,6 @@ SpaprIrq spapr_irq_xics = { .xics = true, .xive = false, - .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, .init_kvm = spapr_irq_init_kvm_xics, @@ -184,7 +183,6 @@ SpaprIrq spapr_irq_xive = { .xics = false, .xive = true, - .dt_populate = spapr_dt_xive, .post_load = spapr_irq_post_load_xive, .reset = spapr_irq_reset_xive, .init_kvm = spapr_irq_init_kvm_xive, @@ -209,13 +207,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr) &spapr_irq_xive : &spapr_irq_xics; } -static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr, - uint32_t nr_servers, void *fdt, - uint32_t phandle) -{ - spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle); -} - static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) { /* @@ -270,7 +261,6 @@ SpaprIrq spapr_irq_dual = { .xics = true, .xive = true, - .dt_populate = spapr_irq_dt_populate_dual, .post_load = spapr_irq_post_load_dual, .reset = spapr_irq_reset_dual, .init_kvm = NULL, /* should not be used */ @@ -377,6 +367,15 @@ void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon) sicc->print_info(spapr->active_intc, mon); } +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, + void *fdt, uint32_t phandle) +{ + SpaprInterruptControllerClass *sicc + = SPAPR_INTC_GET_CLASS(spapr->active_intc); + + sicc->dt(spapr->active_intc, nr_servers, fdt, phandle); +} + void spapr_irq_init(SpaprMachineState *spapr, Error **errp) { MachineState *machine = MACHINE(spapr); @@ -686,7 +685,6 @@ SpaprIrq spapr_irq_xics_legacy = { .xics = true, .xive = false, - .dt_populate = spapr_dt_xics, .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, .init_kvm = spapr_irq_init_kvm_xics, diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index bdfeb3b107..0df95e1b5a 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -60,6 +60,8 @@ typedef struct SpaprInterruptControllerClass { /* These methods should only be called on the active intc */ void (*set_irq)(SpaprInterruptController *intc, int irq, int val); void (*print_info)(SpaprInterruptController *intc, Monitor *mon); + void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers, + void *fdt, uint32_t phandle); } SpaprInterruptControllerClass; void spapr_irq_update_active_intc(SpaprMachineState *spapr); @@ -67,6 +69,8 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr); int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, PowerPCCPU *cpu, Error **errp); void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon); +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, + void *fdt, uint32_t phandle); void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis); int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, @@ -79,8 +83,6 @@ typedef struct SpaprIrq { bool xics; bool xive; - void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers, - void *fdt, uint32_t phandle); int (*post_load)(SpaprMachineState *spapr, int version_id); void (*reset)(SpaprMachineState *spapr, Error **errp); void (*init_kvm)(SpaprMachineState *spapr, Error **errp); diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 8f875673f5..ebe156eb30 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -58,8 +58,6 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon); int spapr_xive_post_load(SpaprXive *xive, int version_id); void spapr_xive_hcall_init(SpaprMachineState *spapr); -void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, - uint32_t phandle); void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx); void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable); void spapr_xive_map_mmio(SpaprXive *xive); diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h index 0b35e85c26..8e4fb6adce 100644 --- a/include/hw/ppc/xics_spapr.h +++ b/include/hw/ppc/xics_spapr.h @@ -32,8 +32,6 @@ #define TYPE_ICS_SPAPR "ics-spapr" #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR) -void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, - uint32_t phandle); int xics_kvm_connect(SpaprMachineState *spapr, Error **errp); void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp); bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr); From patchwork Thu Oct 24 08:17:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208517 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F17FF139A for ; Thu, 24 Oct 2019 08:36:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C8100205ED for ; Thu, 24 Oct 2019 08:36:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="YEOHrlqE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C8100205ED Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35100 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYbM-0005rM-Fg for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:36:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36968) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKs-0005ar-79 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKp-0005tx-Ju for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:10 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:40787 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKp-000592-55; Thu, 24 Oct 2019 04:19:07 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ1zv4z9sRV; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=14lr9JEGz77/t8EG1ZaezP7gMjFaSymG2CgVirQ0kyg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YEOHrlqEbkiJAzoyfZezPeVdIYADhpz8sfOUO1WSYDBTmJeqFsNAohOss0sC1t7OI EyQ6Fq4wONE2SKzzKCfXRTXd7fQK3rR/jyDn9PfeH7tZedDA9L9eO6JsQ7jZMJVYwM bxhQAzF2hHTccXeiMiWPaPD+xhEUhTtcrkK9sXDs= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 14/28] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines Date: Thu, 24 Oct 2019 19:17:59 +1100 Message-Id: <20191024081813.2115-15-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Both XICS and XIVE have routines to connect and disconnect KVM with similar but not identical signatures. This adjusts them to match exactly, which will be useful for further cleanups later. While we're there, we add an explicit return value to the connect path to streamline error reporting in the callers. We remove error reporting the disconnect path. In the XICS case this wasn't used at all. In the XIVE case the only error case was if the KVM device was set up, but KVM didn't have the capability to do so which is pretty obviously impossible. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive_kvm.c | 22 ++++++++++------------ hw/intc/xics_kvm.c | 9 +++++---- hw/ppc/spapr_irq.c | 22 +++++----------------- include/hw/ppc/spapr_xive.h | 4 ++-- include/hw/ppc/xics_spapr.h | 4 ++-- 5 files changed, 24 insertions(+), 37 deletions(-) diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c index 51b334b676..08012ac7cd 100644 --- a/hw/intc/spapr_xive_kvm.c +++ b/hw/intc/spapr_xive_kvm.c @@ -740,8 +740,9 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len, * All the XIVE memory regions are now backed by mappings from the KVM * XIVE device. */ -void kvmppc_xive_connect(SpaprXive *xive, Error **errp) +int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp) { + SpaprXive *xive = SPAPR_XIVE(intc); XiveSource *xsrc = &xive->source; Error *local_err = NULL; size_t esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs; @@ -753,19 +754,19 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp) * rebooting under the XIVE-only interrupt mode. */ if (xive->fd != -1) { - return; + return 0; } if (!kvmppc_has_cap_xive()) { error_setg(errp, "IRQ_XIVE capability must be present for KVM"); - return; + return -1; } /* First, create the KVM XIVE device */ xive->fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false); if (xive->fd < 0) { error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device"); - return; + return -1; } /* @@ -821,15 +822,17 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp) kvm_kernel_irqchip = true; kvm_msi_via_irqfd_allowed = true; kvm_gsi_direct_mapping = true; - return; + return 0; fail: error_propagate(errp, local_err); - kvmppc_xive_disconnect(xive, NULL); + kvmppc_xive_disconnect(intc); + return -1; } -void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp) +void kvmppc_xive_disconnect(SpaprInterruptController *intc) { + SpaprXive *xive = SPAPR_XIVE(intc); XiveSource *xsrc; size_t esb_len; @@ -838,11 +841,6 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp) return; } - if (!kvmppc_has_cap_xive()) { - error_setg(errp, "IRQ_XIVE capability must be present for KVM"); - return; - } - /* Clear the KVM mapping */ xsrc = &xive->source; esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs; diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index ba90d6dc96..954c424b36 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -342,8 +342,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val) } } -int xics_kvm_connect(SpaprMachineState *spapr, Error **errp) +int xics_kvm_connect(SpaprInterruptController *intc, Error **errp) { + ICSState *ics = ICS_SPAPR(intc); int rc; CPUState *cs; Error *local_err = NULL; @@ -413,7 +414,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp) } /* Update the KVM sources */ - ics_set_kvm_state(spapr->ics, &local_err); + ics_set_kvm_state(ics, &local_err); if (local_err) { goto fail; } @@ -431,11 +432,11 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp) fail: error_propagate(errp, local_err); - xics_kvm_disconnect(spapr, NULL); + xics_kvm_disconnect(intc); return -1; } -void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp) +void xics_kvm_disconnect(SpaprInterruptController *intc) { /* * Only on P9 using the XICS-on XIVE KVM device: diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index a8005072e6..5c8ffb27da 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -124,7 +124,7 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp) static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp) { if (kvm_enabled()) { - xics_kvm_connect(spapr, errp); + xics_kvm_connect(SPAPR_INTC(spapr->ics), errp); } } @@ -173,7 +173,7 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp) { if (kvm_enabled()) { - kvmppc_xive_connect(spapr->xive, errp); + kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp); } } @@ -215,7 +215,7 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) */ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { if (kvm_irqchip_in_kernel()) { - xics_kvm_disconnect(spapr, &error_fatal); + xics_kvm_disconnect(SPAPR_INTC(spapr->ics)); } spapr_irq_xive.reset(spapr, &error_fatal); } @@ -225,8 +225,6 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp) { - Error *local_err = NULL; - /* * Deactivate the XIVE MMIOs. The XIVE backend will reenable them * if selected. @@ -235,18 +233,8 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp) /* Destroy all KVM devices */ if (kvm_irqchip_in_kernel()) { - xics_kvm_disconnect(spapr, &local_err); - if (local_err) { - error_propagate(errp, local_err); - error_prepend(errp, "KVM XICS disconnect failed: "); - return; - } - kvmppc_xive_disconnect(spapr->xive, &local_err); - if (local_err) { - error_propagate(errp, local_err); - error_prepend(errp, "KVM XIVE disconnect failed: "); - return; - } + xics_kvm_disconnect(SPAPR_INTC(spapr->ics)); + kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive)); } spapr_irq_current(spapr)->reset(spapr, errp); diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index ebe156eb30..64972754f9 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -68,8 +68,8 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx, /* * KVM XIVE device helpers */ -void kvmppc_xive_connect(SpaprXive *xive, Error **errp); -void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp); +int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp); +void kvmppc_xive_disconnect(SpaprInterruptController *intc); void kvmppc_xive_reset(SpaprXive *xive, Error **errp); void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS *eas, Error **errp); diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h index 8e4fb6adce..28b87038c8 100644 --- a/include/hw/ppc/xics_spapr.h +++ b/include/hw/ppc/xics_spapr.h @@ -32,8 +32,8 @@ #define TYPE_ICS_SPAPR "ics-spapr" #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR) -int xics_kvm_connect(SpaprMachineState *spapr, Error **errp); -void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp); +int xics_kvm_connect(SpaprInterruptController *intc, Error **errp); +void xics_kvm_disconnect(SpaprInterruptController *intc); bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr); #endif /* XICS_SPAPR_H */ From patchwork Thu Oct 24 08:18:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208515 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8CC8713BD for ; Thu, 24 Oct 2019 08:34:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1676F205ED for ; Thu, 24 Oct 2019 08:34:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="cQ4J071t" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1676F205ED Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35088 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYa2-000458-Oo for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:34:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36723) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKX-0004t2-GO for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKV-0005Gx-J9 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:49 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:48817 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKV-00059J-4i; Thu, 24 Oct 2019 04:18:47 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ46jRz9sRl; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=LIu/9orQqM+uHUGN1XbfnZlinvHNg01lhAvD+xkXWok=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cQ4J071tEkPoYAN5fDp/RYbQxMy+53cu9miBiB6dxNVMZQQr0V1W2oHKLEclPw8Ru tSd/MJiTwymeqQFGXVB6guFT+P2lv8M/3Yz9keSXxZg3rH2vSpaLpYJGH1d6xyjMUw t9O6exA6HSFTQzTIAtPRwH1IJKrEocziOy4vNelQ= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 15/28] spapr: Remove SpaprIrq::init_kvm hook Date: Thu, 24 Oct 2019 19:18:00 +1100 Message-Id: <20191024081813.2115-16-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This hook is a bit odd. The only caller is spapr_irq_init_kvm(), but it explicitly takes an SpaprIrq *, so it's never really called through the current SpaprIrq. Essentially this is just a way of passing through a function pointer so that spapr_irq_init_kvm() can handle some configuration and error handling logic without duplicating it between the xics and xive reset paths. So, make it just take that function pointer. Because of earlier reworks to the KVM connect/disconnect code in the xics and xive backends we can also eliminate some wrapper functions and streamline error handling a bit. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr_irq.c | 74 +++++++++++++------------------------- include/hw/ppc/spapr_irq.h | 1 - 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 5c8ffb27da..7cd18e5b15 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -65,33 +65,35 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num) bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); } -static void spapr_irq_init_kvm(SpaprMachineState *spapr, - SpaprIrq *irq, Error **errp) +static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), + SpaprInterruptController *intc, + Error **errp) { - MachineState *machine = MACHINE(spapr); + MachineState *machine = MACHINE(qdev_get_machine()); Error *local_err = NULL; if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) { - irq->init_kvm(spapr, &local_err); - if (local_err && machine_kernel_irqchip_required(machine)) { - error_prepend(&local_err, - "kernel_irqchip requested but unavailable: "); - error_propagate(errp, local_err); - return; - } + if (fn(intc, &local_err) < 0) { + if (machine_kernel_irqchip_required(machine)) { + error_prepend(&local_err, + "kernel_irqchip requested but unavailable: "); + error_propagate(errp, local_err); + return -1; + } - if (!local_err) { - return; + /* + * We failed to initialize the KVM device, fallback to + * emulated mode + */ + error_prepend(&local_err, + "kernel_irqchip allowed but unavailable: "); + error_append_hint(&local_err, + "Falling back to kernel-irqchip=off\n"); + warn_report_err(local_err); } - - /* - * We failed to initialize the KVM device, fallback to - * emulated mode - */ - error_prepend(&local_err, "kernel_irqchip allowed but unavailable: "); - error_append_hint(&local_err, "Falling back to kernel-irqchip=off\n"); - warn_report_err(local_err); } + + return 0; } /* @@ -112,20 +114,7 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp) { - Error *local_err = NULL; - - spapr_irq_init_kvm(spapr, &spapr_irq_xics, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } -} - -static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp) -{ - if (kvm_enabled()) { - xics_kvm_connect(SPAPR_INTC(spapr->ics), errp); - } + spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp); } SpaprIrq spapr_irq_xics = { @@ -136,7 +125,6 @@ SpaprIrq spapr_irq_xics = { .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, - .init_kvm = spapr_irq_init_kvm_xics, }; /* @@ -151,7 +139,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id) static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) { CPUState *cs; - Error *local_err = NULL; CPU_FOREACH(cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -160,9 +147,8 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); } - spapr_irq_init_kvm(spapr, &spapr_irq_xive, &local_err); - if (local_err) { - error_propagate(errp, local_err); + if (spapr_irq_init_kvm(kvmppc_xive_connect, + SPAPR_INTC(spapr->xive), errp) < 0) { return; } @@ -170,13 +156,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) spapr_xive_mmio_set_enabled(spapr->xive, true); } -static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp) -{ - if (kvm_enabled()) { - kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp); - } -} - SpaprIrq spapr_irq_xive = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, @@ -185,7 +164,6 @@ SpaprIrq spapr_irq_xive = { .post_load = spapr_irq_post_load_xive, .reset = spapr_irq_reset_xive, - .init_kvm = spapr_irq_init_kvm_xive, }; /* @@ -251,7 +229,6 @@ SpaprIrq spapr_irq_dual = { .post_load = spapr_irq_post_load_dual, .reset = spapr_irq_reset_dual, - .init_kvm = NULL, /* should not be used */ }; @@ -675,7 +652,6 @@ SpaprIrq spapr_irq_xics_legacy = { .post_load = spapr_irq_post_load_xics, .reset = spapr_irq_reset_xics, - .init_kvm = spapr_irq_init_kvm_xics, }; static void spapr_irq_register_types(void) diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 0df95e1b5a..06179b271f 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -85,7 +85,6 @@ typedef struct SpaprIrq { int (*post_load)(SpaprMachineState *spapr, int version_id); void (*reset)(SpaprMachineState *spapr, Error **errp); - void (*init_kvm)(SpaprMachineState *spapr, Error **errp); } SpaprIrq; extern SpaprIrq spapr_irq_xics; From patchwork Thu Oct 24 08:18:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208553 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 134B214ED for ; Thu, 24 Oct 2019 08:53:51 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DE39620684 for ; Thu, 24 Oct 2019 08:53:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="gv9IOIdt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DE39620684 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35436 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYsQ-0001Hf-0a for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:53:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37019) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKw-0005el-EF for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKu-00062j-7h for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:14 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:38935 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKr-0005I8-Vw; Thu, 24 Oct 2019 04:19:10 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrc0psjz9sRw; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905120; bh=LyfjSmc3UzDimBWwuQhp/YFmtiDawfKqTC8C17xCY8o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gv9IOIdtxRZTtb92PPEyourcdD3gR4dGCa8YGfr5kD5JSc22Xd+7oM19jlXeKE07T jW18anQ16Oux9GQ8nqqN8e6x42QS4L/44KjNHs8mFmQwUxncplBj2MjDm7/bwg0V/b 3sTMM06aAwMj5jjnTkcPLL6uJzuum2Z7lul+Sdug= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 16/28] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate Date: Thu, 24 Oct 2019 19:18:01 +1100 Message-Id: <20191024081813.2115-17-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" It turns out that all the logic in the SpaprIrq::reset hooks (and some in the SpaprIrq::post_load hooks) isn't really related to resetting the irq backend (that's handled by the backends' own reset routines). Rather its about getting the backend ready to be the active interrupt controller or stopping being the active interrupt controller - reset (and post_load) is just the only time that changes at present. To make this flow clearer, move the logic into the explicit backend activate and deactivate hooks. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 38 +++++++++++++++++++++ hw/intc/xics_spapr.c | 17 ++++++++++ hw/ppc/spapr_irq.c | 67 ++------------------------------------ include/hw/ppc/spapr_irq.h | 4 ++- 4 files changed, 61 insertions(+), 65 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 37ffb74ca5..1811653aac 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -640,6 +640,42 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers, plat_res_int_priorities, sizeof(plat_res_int_priorities))); } +static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + CPUState *cs; + + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + + /* (TCG) Set the OS CAM line of the thread interrupt context. */ + spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); + } + + if (kvm_enabled()) { + int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp); + if (rc < 0) { + return rc; + } + } + + /* Activate the XIVE MMIOs */ + spapr_xive_mmio_set_enabled(xive, true); + + return 0; +} + +static void spapr_xive_deactivate(SpaprInterruptController *intc) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + + spapr_xive_mmio_set_enabled(xive, false); + + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_disconnect(intc); + } +} + static void spapr_xive_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -658,6 +694,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) xrc->write_nvt = spapr_xive_write_nvt; xrc->get_tctx = spapr_xive_get_tctx; + sicc->activate = spapr_xive_activate; + sicc->deactivate = spapr_xive_deactivate; sicc->cpu_intc_create = spapr_xive_cpu_intc_create; sicc->claim_irq = spapr_xive_claim_irq; sicc->free_irq = spapr_xive_free_irq; diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 4eabafc7e1..90b4d48877 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -395,6 +395,21 @@ static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon) ics_pic_print_info(ics, mon); } +static int xics_spapr_activate(SpaprInterruptController *intc, Error **errp) +{ + if (kvm_enabled()) { + return spapr_irq_init_kvm(xics_kvm_connect, intc, errp); + } + return 0; +} + +static void xics_spapr_deactivate(SpaprInterruptController *intc) +{ + if (kvm_irqchip_in_kernel()) { + xics_kvm_disconnect(intc); + } +} + static void ics_spapr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -403,6 +418,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) device_class_set_parent_realize(dc, ics_spapr_realize, &isc->parent_realize); + sicc->activate = xics_spapr_activate; + sicc->deactivate = xics_spapr_deactivate; sicc->cpu_intc_create = xics_spapr_cpu_intc_create; sicc->claim_irq = xics_spapr_claim_irq; sicc->free_irq = xics_spapr_free_irq; diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 7cd18e5b15..f70b331f44 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -65,9 +65,9 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num) bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); } -static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), - SpaprInterruptController *intc, - Error **errp) +int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), + SpaprInterruptController *intc, + Error **errp) { MachineState *machine = MACHINE(qdev_get_machine()); Error *local_err = NULL; @@ -112,11 +112,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) return 0; } -static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp) -{ - spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp); -} - SpaprIrq spapr_irq_xics = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, @@ -124,7 +119,6 @@ SpaprIrq spapr_irq_xics = { .xive = false, .post_load = spapr_irq_post_load_xics, - .reset = spapr_irq_reset_xics, }; /* @@ -136,26 +130,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id) return spapr_xive_post_load(spapr->xive, version_id); } -static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) -{ - CPUState *cs; - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - - /* (TCG) Set the OS CAM line of the thread interrupt context. */ - spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); - } - - if (spapr_irq_init_kvm(kvmppc_xive_connect, - SPAPR_INTC(spapr->xive), errp) < 0) { - return; - } - - /* Activate the XIVE MMIOs */ - spapr_xive_mmio_set_enabled(spapr->xive, true); -} - SpaprIrq spapr_irq_xive = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, @@ -163,7 +137,6 @@ SpaprIrq spapr_irq_xive = { .xive = true, .post_load = spapr_irq_post_load_xive, - .reset = spapr_irq_reset_xive, }; /* @@ -187,37 +160,9 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr) static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) { - /* - * Force a reset of the XIVE backend after migration. The machine - * defaults to XICS at startup. - */ - if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { - if (kvm_irqchip_in_kernel()) { - xics_kvm_disconnect(SPAPR_INTC(spapr->ics)); - } - spapr_irq_xive.reset(spapr, &error_fatal); - } - return spapr_irq_current(spapr)->post_load(spapr, version_id); } -static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp) -{ - /* - * Deactivate the XIVE MMIOs. The XIVE backend will reenable them - * if selected. - */ - spapr_xive_mmio_set_enabled(spapr->xive, false); - - /* Destroy all KVM devices */ - if (kvm_irqchip_in_kernel()) { - xics_kvm_disconnect(SPAPR_INTC(spapr->ics)); - kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive)); - } - - spapr_irq_current(spapr)->reset(spapr, errp); -} - /* * Define values in sync with the XIVE and XICS backend */ @@ -228,7 +173,6 @@ SpaprIrq spapr_irq_dual = { .xive = true, .post_load = spapr_irq_post_load_dual, - .reset = spapr_irq_reset_dual, }; @@ -512,10 +456,6 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp) assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr)); spapr_irq_update_active_intc(spapr); - - if (spapr->irq->reset) { - spapr->irq->reset(spapr, errp); - } } int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp) @@ -651,7 +591,6 @@ SpaprIrq spapr_irq_xics_legacy = { .xive = false, .post_load = spapr_irq_post_load_xics, - .reset = spapr_irq_reset_xics, }; static void spapr_irq_register_types(void) diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 06179b271f..e02e44624b 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -84,7 +84,6 @@ typedef struct SpaprIrq { bool xive; int (*post_load)(SpaprMachineState *spapr, int version_id); - void (*reset)(SpaprMachineState *spapr, Error **errp); } SpaprIrq; extern SpaprIrq spapr_irq_xics; @@ -99,6 +98,9 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq); int spapr_irq_post_load(SpaprMachineState *spapr, int version_id); void spapr_irq_reset(SpaprMachineState *spapr, Error **errp); int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp); +int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), + SpaprInterruptController *intc, + Error **errp); /* * XICS legacy routines From patchwork Thu Oct 24 08:18:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208519 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B8511920 for ; Thu, 24 Oct 2019 08:36:14 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 22A80205ED for ; Thu, 24 Oct 2019 08:36:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="nAhoyMbd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 22A80205ED Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35102 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYbM-0005rx-Qm for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:36:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36706) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKX-0004sA-0j for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKU-0005EZ-Jv for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:48 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:60747 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKU-00057d-6X; Thu, 24 Oct 2019 04:18:46 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ6x1sz9sS9; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=EnkOd+cFS560IbTJUs1/5e/f7lteTIS2I3MFC/TeA6g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nAhoyMbdzu2GTDVXh6Ec6fJ7uenYfeKkEiAhB9IZZi8tqtBgRl5xyXBGU1GIoy/3f OgGJuSeW2O3yhha49KTIKpJR4EcX4cVfLg0TqocN0O1tuwOWr1MoMINMDLkjJjIh4R R8jzQfN6jSxEtbv+VanRn54wlDs8+IMVoLw2UT8I= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 17/28] spapr, xics, xive: Move SpaprIrq::post_load hook to backends Date: Thu, 24 Oct 2019 19:18:02 +1100 Message-Id: <20191024081813.2115-18-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The remaining logic in the post_load hook really belongs to the interrupt controller backends, and just needs to be called on the active controller (after the active controller is set to the right thing based on the incoming migration in the generic spapr_irq_post_load() logic). Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 5 +++-- hw/intc/xics_spapr.c | 13 +++++++++++ hw/ppc/spapr_irq.c | 45 ++++--------------------------------- include/hw/ppc/spapr_irq.h | 3 +-- include/hw/ppc/spapr_xive.h | 1 - 5 files changed, 21 insertions(+), 46 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 1811653aac..ba32d2cc5b 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -462,10 +462,10 @@ static int vmstate_spapr_xive_pre_save(void *opaque) * Called by the sPAPR IRQ backend 'post_load' method at the machine * level. */ -int spapr_xive_post_load(SpaprXive *xive, int version_id) +static int spapr_xive_post_load(SpaprInterruptController *intc, int version_id) { if (kvm_irqchip_in_kernel()) { - return kvmppc_xive_post_load(xive, version_id); + return kvmppc_xive_post_load(SPAPR_XIVE(intc), version_id); } return 0; @@ -702,6 +702,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->set_irq = spapr_xive_set_irq; sicc->print_info = spapr_xive_print_info; sicc->dt = spapr_xive_dt; + sicc->post_load = spapr_xive_post_load; } static const TypeInfo spapr_xive_info = { diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 90b4d48877..4f64b9a9fc 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -395,6 +395,18 @@ static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon) ics_pic_print_info(ics, mon); } +static int xics_spapr_post_load(SpaprInterruptController *intc, int version_id) +{ + if (!kvm_irqchip_in_kernel()) { + CPUState *cs; + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + icp_resend(spapr_cpu_state(cpu)->icp); + } + } + return 0; +} + static int xics_spapr_activate(SpaprInterruptController *intc, Error **errp) { if (kvm_enabled()) { @@ -426,6 +438,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) sicc->set_irq = xics_spapr_set_irq; sicc->print_info = xics_spapr_print_info; sicc->dt = xics_spapr_dt; + sicc->post_load = xics_spapr_post_load; } static const TypeInfo ics_spapr_info = { diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index f70b331f44..f3d18b1dad 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -100,43 +100,22 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), * XICS IRQ backend. */ -static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) -{ - if (!kvm_irqchip_in_kernel()) { - CPUState *cs; - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - icp_resend(spapr_cpu_state(cpu)->icp); - } - } - return 0; -} - SpaprIrq spapr_irq_xics = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, .xics = true, .xive = false, - - .post_load = spapr_irq_post_load_xics, }; /* * XIVE IRQ backend. */ -static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id) -{ - return spapr_xive_post_load(spapr->xive, version_id); -} - SpaprIrq spapr_irq_xive = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, .xics = false, .xive = true, - - .post_load = spapr_irq_post_load_xive, }; /* @@ -148,21 +127,6 @@ SpaprIrq spapr_irq_xive = { * activated after an extra machine reset. */ -/* - * Returns the sPAPR IRQ backend negotiated by CAS. XICS is the - * default. - */ -static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr) -{ - return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ? - &spapr_irq_xive : &spapr_irq_xics; -} - -static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) -{ - return spapr_irq_current(spapr)->post_load(spapr, version_id); -} - /* * Define values in sync with the XIVE and XICS backend */ @@ -171,8 +135,6 @@ SpaprIrq spapr_irq_dual = { .nr_msis = SPAPR_NR_MSIS, .xics = true, .xive = true, - - .post_load = spapr_irq_post_load_dual, }; @@ -447,8 +409,11 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq) int spapr_irq_post_load(SpaprMachineState *spapr, int version_id) { + SpaprInterruptControllerClass *sicc; + spapr_irq_update_active_intc(spapr); - return spapr->irq->post_load(spapr, version_id); + sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc); + return sicc->post_load(spapr->active_intc, version_id); } void spapr_irq_reset(SpaprMachineState *spapr, Error **errp) @@ -589,8 +554,6 @@ SpaprIrq spapr_irq_xics_legacy = { .nr_msis = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS, .xics = true, .xive = false, - - .post_load = spapr_irq_post_load_xics, }; static void spapr_irq_register_types(void) diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index e02e44624b..08173e714c 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -62,6 +62,7 @@ typedef struct SpaprInterruptControllerClass { void (*print_info)(SpaprInterruptController *intc, Monitor *mon); void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers, void *fdt, uint32_t phandle); + int (*post_load)(SpaprInterruptController *intc, int version_id); } SpaprInterruptControllerClass; void spapr_irq_update_active_intc(SpaprMachineState *spapr); @@ -82,8 +83,6 @@ typedef struct SpaprIrq { uint32_t nr_msis; bool xics; bool xive; - - int (*post_load)(SpaprMachineState *spapr, int version_id); } SpaprIrq; extern SpaprIrq spapr_irq_xics; diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 64972754f9..d84bd5c229 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -55,7 +55,6 @@ typedef struct SpaprXive { #define SPAPR_XIVE_BLOCK_ID 0x0 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon); -int spapr_xive_post_load(SpaprXive *xive, int version_id); void spapr_xive_hcall_init(SpaprMachineState *spapr); void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx); From patchwork Thu Oct 24 08:18:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208527 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D0F4814ED for ; Thu, 24 Oct 2019 08:40:56 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A6A54205F4 for ; Thu, 24 Oct 2019 08:40:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="WbJ4FuHU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A6A54205F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35172 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYfv-0000pg-OY for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:40:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36737) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKY-0004u9-BD for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKV-0005GF-Cp for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:49 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:56399 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKU-00059Q-W3; Thu, 24 Oct 2019 04:18:47 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrb1QMMz9sRt; Thu, 24 Oct 2019 19:18:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905119; bh=0xroAoogH/n6iQTehhcMVK4LTjQRlDojtcSKJlA+WKQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WbJ4FuHUJ4l/T5eajcucLh2PDpoY14y8uADQA5E3W8QB4H8lF/GYiYbXCkq8BqvrU bL1BMxEbuHFi2Hs5H7Pk7+CON5vyGdjGlORyw6de3c7lzlx3p9259KLL+EY+JuK2K7 rxvY/qqD+Y2YWid4CPD0zwilKfbwWa2AQLYN6RVU= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 18/28] spapr: Remove SpaprIrq::nr_msis Date: Thu, 24 Oct 2019 19:18:03 +1100 Message-Id: <20191024081813.2115-19-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The nr_msis value we use here has to line up with whether we're using legacy or modern irq allocation. Therefore it's safer to derive it based on legacy_irq_allocation rather than having SpaprIrq contain a canned value. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr.c | 5 ++--- hw/ppc/spapr_irq.c | 26 +++++++++++++++++--------- hw/ppc/spapr_pci.c | 7 ++++--- include/hw/pci-host/spapr.h | 4 ++-- include/hw/ppc/spapr_irq.h | 4 +--- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c9623600c2..99867b5e6d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1267,7 +1267,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr) } QLIST_FOREACH(phb, &spapr->phbs, list) { - ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL); + ret = spapr_dt_phb(spapr, phb, PHANDLE_INTC, fdt, NULL); if (ret < 0) { error_report("couldn't setup PCI devices in fdt"); exit(1); @@ -3905,8 +3905,7 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, return -1; } - if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis, - fdt_start_offset)) { + if (spapr_dt_phb(spapr, sphb, intc_phandle, fdt, fdt_start_offset)) { error_setg(errp, "unable to create FDT node for PHB %d", sphb->index); return -1; } diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index f3d18b1dad..be90d36333 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -29,9 +29,14 @@ static const TypeInfo spapr_intc_info = { .class_size = sizeof(SpaprInterruptControllerClass), }; -void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis) +static void spapr_irq_msi_init(SpaprMachineState *spapr) { - spapr->irq_map_nr = nr_msis; + if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { + /* Legacy mode doesn't use this allocator */ + return; + } + + spapr->irq_map_nr = spapr_irq_nr_msis(spapr); spapr->irq_map = bitmap_new(spapr->irq_map_nr); } @@ -102,7 +107,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), SpaprIrq spapr_irq_xics = { .nr_xirqs = SPAPR_NR_XIRQS, - .nr_msis = SPAPR_NR_MSIS, .xics = true, .xive = false, }; @@ -113,7 +117,6 @@ SpaprIrq spapr_irq_xics = { SpaprIrq spapr_irq_xive = { .nr_xirqs = SPAPR_NR_XIRQS, - .nr_msis = SPAPR_NR_MSIS, .xics = false, .xive = true, }; @@ -132,7 +135,6 @@ SpaprIrq spapr_irq_xive = { */ SpaprIrq spapr_irq_dual = { .nr_xirqs = SPAPR_NR_XIRQS, - .nr_msis = SPAPR_NR_MSIS, .xics = true, .xive = true, }; @@ -247,6 +249,15 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, sicc->dt(spapr->active_intc, nr_servers, fdt, phandle); } +uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr) +{ + if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { + return spapr->irq->nr_xirqs; + } else { + return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI; + } +} + void spapr_irq_init(SpaprMachineState *spapr, Error **errp) { MachineState *machine = MACHINE(spapr); @@ -267,9 +278,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) } /* Initialize the MSI IRQ allocator. */ - if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { - spapr_irq_msi_init(spapr, spapr->irq->nr_msis); - } + spapr_irq_msi_init(spapr); if (spapr->irq->xics) { Error *local_err = NULL; @@ -551,7 +560,6 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp) SpaprIrq spapr_irq_xics_legacy = { .nr_xirqs = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS, - .nr_msis = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS, .xics = true, .xive = false, }; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 01ff41d4c4..cc0e7829b6 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2277,8 +2277,8 @@ static void spapr_phb_pci_enumerate(SpaprPhbState *phb) } -int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt, - uint32_t nr_msis, int *node_offset) +int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb, + uint32_t intc_phandle, void *fdt, int *node_offset) { int bus_off, i, j, ret; uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; @@ -2343,7 +2343,8 @@ int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt, _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges)); _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg))); _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1)); - _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", nr_msis)); + _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", + spapr_irq_nr_msis(spapr))); /* Dynamic DMA window */ if (phb->ddw_enabled) { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 23506f05d9..8877ff51fb 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -128,8 +128,8 @@ struct SpaprPhbState { #define SPAPR_PCI_NV2ATSD_WIN_SIZE (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \ 64 * KiB) -int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt, - uint32_t nr_msis, int *node_offset); +int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb, + uint32_t intc_phandle, void *fdt, int *node_offset); void spapr_pci_rtas_init(void); diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 08173e714c..befe8e01dc 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -27,7 +27,6 @@ #define SPAPR_IRQ_MSI (SPAPR_XIRQ_BASE + 0x0300) #define SPAPR_NR_XIRQS 0x1000 -#define SPAPR_NR_MSIS (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI) typedef struct SpaprMachineState SpaprMachineState; @@ -73,14 +72,13 @@ void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon); void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); -void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis); +uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr); int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, Error **errp); void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num); typedef struct SpaprIrq { uint32_t nr_xirqs; - uint32_t nr_msis; bool xics; bool xive; } SpaprIrq; From patchwork Thu Oct 24 08:18:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208521 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 25B11139A for ; Thu, 24 Oct 2019 08:37:56 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F0222205F4 for ; Thu, 24 Oct 2019 08:37:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="fFVx8WL6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F0222205F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35142 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYd0-0000S1-Pz for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:37:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36987) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKu-0005cy-BJ for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKs-0005x8-6U for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:12 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:49959 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKr-0005Ff-3e; Thu, 24 Oct 2019 04:19:10 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrc02XSz9sS8; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905120; bh=Z2T5X90rkUlGdktll16peXsxkC/IypKtcNGi46Zo65g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fFVx8WL6KLAbGD7IT4Nd1mNpElnRqdRfyvnPV9dcd4iaW5thQNJPX8F6QUQWFfrPp uqWy3iwKEy8qFUbXXNOc0HqXN3MVO3iSXtC26a70yGTMyIq+ba60/UYq0zbF/d8daR NSr2Cu1VK5VLjUuz+LuTcY4PUm+rfDiJXSiizVlk= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 19/28] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass Date: Thu, 24 Oct 2019 19:18:04 +1100 Message-Id: <20191024081813.2115-20-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" For the benefit of peripheral device allocation, the number of available irqs really wants to be the same on a given machine type version, regardless of what irq backends we are using. That's the case now, but only because we make sure the different SpaprIrq instances have the same value except for the special legacy one. Since this really only depends on machine type version, move the value to SpaprMachineClass instead of SpaprIrq. This also puts the code to set it to the lower value on old machine types right next to setting legacy_irq_allocation, which needs to go hand in hand. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr.c | 2 ++ hw/ppc/spapr_irq.c | 33 ++++++++++++++++----------------- include/hw/ppc/spapr.h | 1 + include/hw/ppc/spapr_irq.h | 1 - 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 99867b5e6d..f9410d390a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4440,6 +4440,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) smc->dr_phb_enabled = true; smc->linux_pci_probe = true; smc->smp_threads_vsmt = true; + smc->nr_xirqs = SPAPR_NR_XIRQS; } static const TypeInfo spapr_machine_info = { @@ -4576,6 +4577,7 @@ static void spapr_machine_3_0_class_options(MachineClass *mc) compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len); smc->legacy_irq_allocation = true; + smc->nr_xirqs = 0x400; smc->irq = &spapr_irq_xics_legacy; } diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index be90d36333..234d1073e5 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -106,7 +106,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), */ SpaprIrq spapr_irq_xics = { - .nr_xirqs = SPAPR_NR_XIRQS, .xics = true, .xive = false, }; @@ -116,7 +115,6 @@ SpaprIrq spapr_irq_xics = { */ SpaprIrq spapr_irq_xive = { - .nr_xirqs = SPAPR_NR_XIRQS, .xics = false, .xive = true, }; @@ -134,7 +132,6 @@ SpaprIrq spapr_irq_xive = { * Define values in sync with the XIVE and XICS backend */ SpaprIrq spapr_irq_dual = { - .nr_xirqs = SPAPR_NR_XIRQS, .xics = true, .xive = true, }; @@ -251,16 +248,19 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr) { - if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { - return spapr->irq->nr_xirqs; + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + + if (smc->legacy_irq_allocation) { + return smc->nr_xirqs; } else { - return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI; + return SPAPR_XIRQ_BASE + smc->nr_xirqs - SPAPR_IRQ_MSI; } } void spapr_irq_init(SpaprMachineState *spapr, Error **errp) { MachineState *machine = MACHINE(spapr); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); if (machine_kernel_irqchip_split(machine)) { error_setg(errp, "kernel_irqchip split mode not supported on pseries"); @@ -298,8 +298,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) return; } - object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs", - &local_err); + object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -320,8 +319,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) int i; dev = qdev_create(NULL, TYPE_SPAPR_XIVE); - qdev_prop_set_uint32(dev, "nr-irqs", - spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE); + qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE); /* * 8 XIVE END structures per CPU. One for each available * priority @@ -346,17 +344,18 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp) } spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr, - spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE); + smc->nr_xirqs + SPAPR_XIRQ_BASE); } int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp) { SpaprInterruptController *intcs[] = ALL_INTCS(spapr); int i; + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); int rc; assert(irq >= SPAPR_XIRQ_BASE); - assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE)); + assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE)); for (i = 0; i < ARRAY_SIZE(intcs); i++) { SpaprInterruptController *intc = intcs[i]; @@ -376,9 +375,10 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num) { SpaprInterruptController *intcs[] = ALL_INTCS(spapr); int i, j; + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); assert(irq >= SPAPR_XIRQ_BASE); - assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE)); + assert((irq + num) <= (smc->nr_xirqs + SPAPR_XIRQ_BASE)); for (i = irq; i < (irq + num); i++) { for (j = 0; j < ARRAY_SIZE(intcs); j++) { @@ -395,6 +395,8 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num) qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq) { + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + /* * This interface is basically for VIO and PHB devices to find the * right qemu_irq to manipulate, so we only allow access to the @@ -403,7 +405,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq) * interfaces, we can change this if we need to in future. */ assert(irq >= SPAPR_XIRQ_BASE); - assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE)); + assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE)); if (spapr->ics) { assert(ics_valid_irq(spapr->ics, irq)); @@ -556,10 +558,7 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp) return first + ics->offset; } -#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS 0x400 - SpaprIrq spapr_irq_xics_legacy = { - .nr_xirqs = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS, .xics = true, .xive = false, }; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 3b34cf5207..d5ab5ea7b2 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -119,6 +119,7 @@ struct SpaprMachineClass { bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ bool pre_2_10_has_unused_icps; bool legacy_irq_allocation; + uint32_t nr_xirqs; bool broken_host_serial_model; /* present real host info to the guest */ bool pre_4_1_migration; /* don't migrate hpt-max-page-size */ bool linux_pci_probe; diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index befe8e01dc..5e150a6679 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -78,7 +78,6 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align, void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num); typedef struct SpaprIrq { - uint32_t nr_xirqs; bool xics; bool xive; } SpaprIrq; From patchwork Thu Oct 24 08:18:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208539 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F8AA1575 for ; Thu, 24 Oct 2019 08:49:46 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3A5AE20684 for ; Thu, 24 Oct 2019 08:49:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="oJuLFNBT" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3A5AE20684 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35314 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYoT-0007NG-Cw for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:49:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36956) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKh-0005Dl-Ki for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKW-0005Jz-GB for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:59 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:46585 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKV-00059S-4i; Thu, 24 Oct 2019 04:18:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrb36BWz9sRv; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905119; bh=EPux0Y4efV3uvIsvh40j5ryux2pI8RixF0hQF7ITXc0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oJuLFNBTmZQ5p8sXCni0dPPBQN/ULibMGCjTTSAsqnT5jAjxx4lpVovWtIp6ciGBy lZaQSO5783+up32OmZXPVnh1+6zgaAr+y7bwTPsj7eCU8pv9wxnIFx/E+px/9UkYME dkpnFiCrhjM33f3VakXcaaMiNJgcGLC/S/pAWlVo= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 20/28] pseries: Update SLOF firmware image Date: Thu, 24 Oct 2019 19:18:05 +1100 Message-Id: <20191024081813.2115-21-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, Alexey Kardashevskiy , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Alexey Kardashevskiy This aims v4.2 and fixes: 1. full FDT rendering; 2. gcc9 -Waddress-of-packed-member. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- pc-bios/README | 2 +- pc-bios/slof.bin | Bin 930640 -> 928552 bytes roms/SLOF | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index 0b0b5d42ad..830645c51f 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20190911. + built from git tag qemu-slof-20191022. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index 2af0c5d5fc0c6aa06c34016f6deb767700ad4d3f..0b93fe8c011fc352803dc24e3110b7f926493769 100644 GIT binary patch delta 118274 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 Y!gOEP_L;}Kw$J*}Z>Im?>WAn2KMr!Q;Q#;t delta 124758 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

8zEyT@G49<^0lIa2 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 IVLO}uAMh!0ng9R* diff --git a/roms/SLOF b/roms/SLOF index bcc3c4e5c2..899d988365 160000 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit bcc3c4e5c21a015f4680894c4ec978a90d4a2d69 +Subproject commit 899d98836513bb3d6a4f4e48ef7cee887ee5f57b From patchwork Thu Oct 24 08:18:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208505 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 07ACB112C for ; Thu, 24 Oct 2019 08:29:24 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D2EDF20856 for ; Thu, 24 Oct 2019 08:29:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="ONI4c/XU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D2EDF20856 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34950 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYUk-0000xu-Ky for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:29:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36658) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKW-0004qU-1O for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKU-0005Dm-Dq for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:47 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:50725 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKU-00056l-0L; Thu, 24 Oct 2019 04:18:46 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ59Qbz9sRp; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=zjFNkfEC2lqwHnFh4a9YRFMi7iKEynZsNvxFNHQaBOs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ONI4c/XUmavxAY3xRrSDWq2rDSawT1GWPe/scy1UrIFGLdpna+XZDZ1aTd3zBxMit fMVKmKoOHlobjkarh17I83ZN1nihyw3S1vdmOpaSftd0JONAt9pfgRbBUozg/6rWXB UQDJaD0sGMiKnX0dGN/vWumKGpUA9mvP0/8BFYmU= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 21/28] spapr: Don't request to unplug the same core twice Date: Thu, 24 Oct 2019 19:18:06 +1100 Message-Id: <20191024081813.2115-22-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz We must not call spapr_drc_detach() on a detached DRC otherwise bad things can happen, ie. QEMU hangs or crashes. This is easily demonstrated with a CPU hotplug/unplug loop using QMP. Signed-off-by: Greg Kurz Message-Id: <157185826035.3073024.1664101000438499392.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/ppc/spapr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f9410d390a..94f9d27096 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3741,9 +3741,10 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, spapr_vcpu_id(spapr, cc->core_id)); g_assert(drc); - spapr_drc_detach(drc); - - spapr_hotplug_req_remove_by_index(drc); + if (!spapr_drc_unplug_requested(drc)) { + spapr_drc_detach(drc); + spapr_hotplug_req_remove_by_index(drc); + } } int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, From patchwork Thu Oct 24 08:18:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208523 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 18B1B139A for ; Thu, 24 Oct 2019 08:38:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E3549205F4 for ; Thu, 24 Oct 2019 08:38:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="Xvsykxd6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E3549205F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYdP-0001Ov-NZ for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:38:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36772) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKZ-0004vn-2c for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKX-0005Lv-7T for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:50 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:49623 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKW-0005FO-Pm; Thu, 24 Oct 2019 04:18:49 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrb69vtz9sSD; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905119; bh=2GQELmF9NAz3E1thmQgh3U2TnmTQMJ3gjnRXnpahuIE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Xvsykxd6jwZn4ReHp/D4yUtr5IeKL8+irxtwHROhf9at1/Eh+gn3U5SKNnMNedmRm 17xtJAViYO4VAaUnbx47gXR3/XrO4DRv93LhAhZyOnOYQFuxJCmq5rjngJF0SuTnB/ IucIC4f/2ATIkni6i0ZNLKIITfhCYnqcTEIZB30s= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 22/28] spapr: move CPU reset after presenter creation Date: Thu, 24 Oct 2019 19:18:07 +1100 Message-Id: <20191024081813.2115-23-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater This change prepares ground for future changes which will reset the interrupt presenter in the reset handler of the sPAPR and PowerNV cores. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Greg Kurz Signed-off-by: Cédric Le Goater Message-Id: <20191022163812.330-2-clg@kaod.org> Signed-off-by: David Gibson --- hw/ppc/spapr_cpu_core.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 3e4302c7d5..2b21285d20 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -234,13 +234,16 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); kvmppc_set_papr(cpu); - qemu_register_reset(spapr_cpu_reset, cpu); - spapr_cpu_reset(cpu); - if (spapr_irq_cpu_intc_create(spapr, cpu, &local_err) < 0) { - goto error_unregister; + goto error_intc_create; } + /* + * FIXME: Hot-plugged CPUs are not reset. Do it at realize. + */ + qemu_register_reset(spapr_cpu_reset, cpu); + spapr_cpu_reset(cpu); + if (!sc->pre_3_0_migration) { vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state, cpu->machine_data); @@ -248,8 +251,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, return; -error_unregister: - qemu_unregister_reset(spapr_cpu_reset, cpu); +error_intc_create: cpu_remove_sync(CPU(cpu)); error: error_propagate(errp, local_err); From patchwork Thu Oct 24 08:18:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208513 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BF4F5112B for ; Thu, 24 Oct 2019 08:33:25 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 96334205ED for ; Thu, 24 Oct 2019 08:33:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="B02p8wvi" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 96334205ED Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35046 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYYe-0000NI-32 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:33:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36680) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKW-0004rM-Fc for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKU-0005EP-II for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:48 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:36839 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKU-00057Y-4L; Thu, 24 Oct 2019 04:18:46 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrZ65kqz9sS6; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905118; bh=I+w0vyc2IGs0peaw/UV5O//pvuGcu05DaH5gofGUyMY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B02p8wvinxdeLiQMq9Kd7Vsm/W2hBJVeyME6fFK59ADNps9tca8Fsf2Ew8FxeN4vW L6ep32Yr4FGrlCSfRSYVREh5oBecCWAnZOx5xwgxupTTm6YQGfxjXgN2PmG5l4H6zZ w4CbicVU0kma9xo1K3AL+iL4leO2TpLN3eTJHQTs= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 23/28] spapr_cpu_core: Implement DeviceClass::reset Date: Thu, 24 Oct 2019 19:18:08 +1100 Message-Id: <20191024081813.2115-24-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz Since vCPUs aren't plugged into a bus, we manually register a reset handler for each vCPU. We also call this handler at realize time to ensure hot plugged vCPUs are reset before being exposed to the guest. This results in vCPUs being reset twice at machine reset. It doesn't break anything but it is slightly suboptimal and above all confusing. The hotplug path in device_set_realized() already knows how to reset a hotplugged device if the device reset handler is present. Implement one for sPAPR CPU cores that resets all vCPUs under a core. While here rename spapr_cpu_reset() to spapr_reset_vcpu() for consistency with spapr_realize_vcpu() and spapr_unrealize_vcpu(). Signed-off-by: Greg Kurz Reviewed-by: Philippe Mathieu-Daudé [clg: add documentation on the reset helper usage ] Signed-off-by: Cédric Le Goater Message-Id: <20191022163812.330-3-clg@kaod.org> Signed-off-by: David Gibson --- hw/ppc/spapr_cpu_core.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 2b21285d20..2e34832d0e 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -25,9 +25,8 @@ #include "sysemu/hw_accel.h" #include "qemu/error-report.h" -static void spapr_cpu_reset(void *opaque) +static void spapr_reset_vcpu(PowerPCCPU *cpu) { - PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); @@ -193,7 +192,6 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc) if (!sc->pre_3_0_migration) { vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data); } - qemu_unregister_reset(spapr_cpu_reset, cpu); if (spapr_cpu_state(cpu)->icp) { object_unparent(OBJECT(spapr_cpu_state(cpu)->icp)); } @@ -204,12 +202,36 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc) object_unparent(OBJECT(cpu)); } +/* + * Called when CPUs are hot-plugged. + */ +static void spapr_cpu_core_reset(DeviceState *dev) +{ + CPUCore *cc = CPU_CORE(dev); + SpaprCpuCore *sc = SPAPR_CPU_CORE(dev); + int i; + + for (i = 0; i < cc->nr_threads; i++) { + spapr_reset_vcpu(sc->threads[i]); + } +} + +/* + * Called by the machine reset. + */ +static void spapr_cpu_core_reset_handler(void *opaque) +{ + spapr_cpu_core_reset(opaque); +} + static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp) { SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); CPUCore *cc = CPU_CORE(dev); int i; + qemu_unregister_reset(spapr_cpu_core_reset_handler, sc); + for (i = 0; i < cc->nr_threads; i++) { spapr_unrealize_vcpu(sc->threads[i], sc); } @@ -238,12 +260,6 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, goto error_intc_create; } - /* - * FIXME: Hot-plugged CPUs are not reset. Do it at realize. - */ - qemu_register_reset(spapr_cpu_reset, cpu); - spapr_cpu_reset(cpu); - if (!sc->pre_3_0_migration) { vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state, cpu->machine_data); @@ -338,6 +354,8 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) goto err_unrealize; } } + + qemu_register_reset(spapr_cpu_core_reset_handler, sc); return; err_unrealize: @@ -366,6 +384,7 @@ static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) dc->realize = spapr_cpu_core_realize; dc->unrealize = spapr_cpu_core_unrealize; + dc->reset = spapr_cpu_core_reset; dc->props = spapr_cpu_core_properties; scc->cpu_type = data; } From patchwork Thu Oct 24 08:18:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208541 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AF2051864 for ; Thu, 24 Oct 2019 08:51:39 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 859532166E for ; Thu, 24 Oct 2019 08:51:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="m4hAIxE0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 859532166E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35336 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYqI-00046p-JV for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:51:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36986) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKu-0005cw-Ab for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKs-0005x2-63 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:12 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:53191 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKq-0005F9-Mg; Thu, 24 Oct 2019 04:19:09 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrb5BH3z9sS3; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905119; bh=Jy7FCp7Yn0XLreGhMwXC3M/9n37BHJsLOVJc7ykVS3o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m4hAIxE06FkIc5jenwxT3unfIYYlZ5gsGHjhn720zHEd7QcNZRH77Ly3lhdpOJlmM yRlt1htyoiylPSmbf8/WKILU1YxRaw5nQKQDzzoz7lSyps/vLW1/3K+QRvfbN2cC3k l5ZsQsDvbO0c9xwZPLhkpgrGrRCWwSup9ARwZV2o= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 24/28] ppc/pnv: Introduce a PnvCore reset handler Date: Thu, 24 Oct 2019 19:18:09 +1100 Message-Id: <20191024081813.2115-25-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater in which individual CPUs are reset. It will ease the introduction of future change reseting the interrupt presenter from the CPU reset handler. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Message-Id: <20191022163812.330-4-clg@kaod.org> Signed-off-by: David Gibson --- hw/ppc/pnv_core.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index b1a7489e7a..9f981a4940 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -40,9 +40,8 @@ static const char *pnv_core_cpu_typename(PnvCore *pc) return cpu_type; } -static void pnv_cpu_reset(void *opaque) +static void pnv_core_cpu_reset(PowerPCCPU *cpu) { - PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -192,8 +191,17 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp) /* Set time-base frequency to 512 MHz */ cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ); +} + +static void pnv_core_reset(void *dev) +{ + CPUCore *cc = CPU_CORE(dev); + PnvCore *pc = PNV_CORE(dev); + int i; - qemu_register_reset(pnv_cpu_reset, cpu); + for (i = 0; i < cc->nr_threads; i++) { + pnv_core_cpu_reset(pc->threads[i]); + } } static void pnv_core_realize(DeviceState *dev, Error **errp) @@ -244,6 +252,8 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id); pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops, pc, name, PNV_XSCOM_EX_SIZE); + + qemu_register_reset(pnv_core_reset, pc); return; err: @@ -259,7 +269,6 @@ static void pnv_unrealize_vcpu(PowerPCCPU *cpu) { PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); - qemu_unregister_reset(pnv_cpu_reset, cpu); object_unparent(OBJECT(pnv_cpu_state(cpu)->intc)); cpu_remove_sync(CPU(cpu)); cpu->machine_data = NULL; @@ -273,6 +282,8 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp) CPUCore *cc = CPU_CORE(dev); int i; + qemu_unregister_reset(pnv_core_reset, pc); + for (i = 0; i < cc->nr_threads; i++) { pnv_unrealize_vcpu(pc->threads[i]); } From patchwork Thu Oct 24 08:18:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208555 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0159A14ED for ; Thu, 24 Oct 2019 08:55:38 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CC1C020684 for ; Thu, 24 Oct 2019 08:55:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="YOp14rL+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CC1C020684 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35478 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYu8-0004jg-Ud for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:55:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37017) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKw-0005ei-EP for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKu-00062t-96 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:14 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:47887 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKs-0005Ih-Fc; Thu, 24 Oct 2019 04:19:12 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrc2Mh1z9sSJ; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905120; bh=tzJ+7MOt2gZTDZOt/gkdmDHnADHessDKG06YzqJyGLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YOp14rL+X7uTApnva66vvaTZ2/UKFKvzBAIste07UkMbyoTiM8YCi10ldkncFlYe0 FguJNFIJUC7/2H6fYNWertG7zvXqFF0qe2FqY4abt/eDlbjz5cMf5O6sKCsGIHGkF6 t+b1r2CBpuA8uvjKEoEKlGA6gIbGIzO4iWv0Zy9A= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 25/28] ppc/pnv: Add a PnvChip pointer to PnvCore Date: Thu, 24 Oct 2019 19:18:10 +1100 Message-Id: <20191024081813.2115-26-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater We will use it to reset the interrupt presenter from the CPU reset handler. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Message-Id: <20191022163812.330-5-clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/pnv_core.c | 3 ++- include/hw/ppc/pnv_core.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 9f981a4940..cc17bbfed8 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -222,6 +222,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) "required link 'chip' not found: "); return; } + pc->chip = PNV_CHIP(chip); pc->threads = g_new(PowerPCCPU *, cc->nr_threads); for (i = 0; i < cc->nr_threads; i++) { @@ -243,7 +244,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } for (j = 0; j < cc->nr_threads; j++) { - pnv_realize_vcpu(pc->threads[j], PNV_CHIP(chip), &local_err); + pnv_realize_vcpu(pc->threads[j], pc->chip, &local_err); if (local_err) { goto err; } diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h index bfbd2ec42a..55eee95104 100644 --- a/include/hw/ppc/pnv_core.h +++ b/include/hw/ppc/pnv_core.h @@ -31,6 +31,8 @@ #define PNV_CORE_GET_CLASS(obj) \ OBJECT_GET_CLASS(PnvCoreClass, (obj), TYPE_PNV_CORE) +typedef struct PnvChip PnvChip; + typedef struct PnvCore { /*< private >*/ CPUCore parent_obj; @@ -38,6 +40,7 @@ typedef struct PnvCore { /*< public >*/ PowerPCCPU **threads; uint32_t pir; + PnvChip *chip; MemoryRegion xscom_regs; } PnvCore; From patchwork Thu Oct 24 08:18:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208529 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DC73D139A for ; Thu, 24 Oct 2019 08:41:40 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F77C205F4 for ; Thu, 24 Oct 2019 08:41:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="jTjMZZr0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F77C205F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35176 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYgd-0003Ci-4Q for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:41:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37018) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKw-0005ek-Ek for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKu-000636-A1 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:19:14 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:57411 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKt-0005LF-3G; Thu, 24 Oct 2019 04:19:12 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrc37hxz9sSF; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905120; bh=Ka1Ggpk4WXltmaabL+Ppf3sWhfAmXmA7mulQQ7mDOLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jTjMZZr0CZYEV9ahAF1NGassMIDnFrT3XYqKNB4sIYH+Yd3rTCvKZOSBWghyvk8Mm F/sfZ9H56k7bAzL6F4p3Vfd5wPDDcgnEBKNS5zS4pJM5c81sAWRp29V+kE5yhgoQSA utCUzOMC+KtKtPZKeoZz5SReLHlnxx7nF6HDUVu0= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 26/28] ppc: Reset the interrupt presenter from the CPU reset handler Date: Thu, 24 Oct 2019 19:18:11 +1100 Message-Id: <20191024081813.2115-27-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater On the sPAPR machine and PowerNV machine, the interrupt presenters are created by a machine handler at the core level and are reset independently. This is not consistent and it raises issues when it comes to handle hot-plugged CPUs. In that case, the presenters are not reset. This is less of an issue in XICS, although a zero MFFR could be a concern, but in XIVE, the OS CAM line is not set and this breaks the presenting algorithm. The current code has workarounds which need a global cleanup. Extend the sPAPR IRQ backend and the PowerNV Chip class with a new cpu_intc_reset() handler called by the CPU reset handler and remove the XiveTCTX reset handler which is now redundant. Signed-off-by: Cédric Le Goater Message-Id: <20191022163812.330-6-clg@kaod.org> Reviewed-by: Greg Kurz Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 9 +++++++++ hw/intc/xics.c | 8 ++------ hw/intc/xics_spapr.c | 7 +++++++ hw/intc/xive.c | 12 +----------- hw/ppc/pnv.c | 18 ++++++++++++++++++ hw/ppc/pnv_core.c | 7 +++++-- hw/ppc/spapr_cpu_core.c | 5 ++++- hw/ppc/spapr_irq.c | 14 ++++++++++++++ include/hw/ppc/pnv.h | 1 + include/hw/ppc/spapr_irq.h | 2 ++ include/hw/ppc/xics.h | 1 + include/hw/ppc/xive.h | 1 + 12 files changed, 65 insertions(+), 20 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index ba32d2cc5b..20a8d8285f 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -553,6 +553,14 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc, return 0; } +static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc, + PowerPCCPU *cpu) +{ + XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx; + + xive_tctx_reset(tctx); +} + static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val) { SpaprXive *xive = SPAPR_XIVE(intc); @@ -697,6 +705,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->activate = spapr_xive_activate; sicc->deactivate = spapr_xive_deactivate; sicc->cpu_intc_create = spapr_xive_cpu_intc_create; + sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset; sicc->claim_irq = spapr_xive_claim_irq; sicc->free_irq = spapr_xive_free_irq; sicc->set_irq = spapr_xive_set_irq; diff --git a/hw/intc/xics.c b/hw/intc/xics.c index b5ac408f7b..6da05763f9 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -274,10 +274,8 @@ static const VMStateDescription vmstate_icp_server = { }, }; -static void icp_reset_handler(void *dev) +void icp_reset(ICPState *icp) { - ICPState *icp = ICP(dev); - icp->xirr = 0; icp->pending_priority = 0xff; icp->mfrr = 0xff; @@ -288,7 +286,7 @@ static void icp_reset_handler(void *dev) if (kvm_irqchip_in_kernel()) { Error *local_err = NULL; - icp_set_kvm_state(ICP(dev), &local_err); + icp_set_kvm_state(icp, &local_err); if (local_err) { error_report_err(local_err); } @@ -351,7 +349,6 @@ static void icp_realize(DeviceState *dev, Error **errp) } } - qemu_register_reset(icp_reset_handler, dev); vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp); } @@ -360,7 +357,6 @@ static void icp_unrealize(DeviceState *dev, Error **errp) ICPState *icp = ICP(dev); vmstate_unregister(NULL, &vmstate_icp_server, icp); - qemu_unregister_reset(icp_reset_handler, dev); } static void icp_class_init(ObjectClass *klass, void *data) diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 4f64b9a9fc..7418fb9f37 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -346,6 +346,12 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc, return 0; } +static void xics_spapr_cpu_intc_reset(SpaprInterruptController *intc, + PowerPCCPU *cpu) +{ + icp_reset(spapr_cpu_state(cpu)->icp); +} + static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq, bool lsi, Error **errp) { @@ -433,6 +439,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) sicc->activate = xics_spapr_activate; sicc->deactivate = xics_spapr_deactivate; sicc->cpu_intc_create = xics_spapr_cpu_intc_create; + sicc->cpu_intc_reset = xics_spapr_cpu_intc_reset; sicc->claim_irq = xics_spapr_claim_irq; sicc->free_irq = xics_spapr_free_irq; sicc->set_irq = xics_spapr_set_irq; diff --git a/hw/intc/xive.c b/hw/intc/xive.c index d420c6571e..f066be5eb5 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -547,10 +547,8 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon) } } -static void xive_tctx_reset(void *dev) +void xive_tctx_reset(XiveTCTX *tctx) { - XiveTCTX *tctx = XIVE_TCTX(dev); - memset(tctx->regs, 0, sizeof(tctx->regs)); /* Set some defaults */ @@ -607,13 +605,6 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp) return; } } - - qemu_register_reset(xive_tctx_reset, dev); -} - -static void xive_tctx_unrealize(DeviceState *dev, Error **errp) -{ - qemu_unregister_reset(xive_tctx_reset, dev); } static int vmstate_xive_tctx_pre_save(void *opaque) @@ -668,7 +659,6 @@ static void xive_tctx_class_init(ObjectClass *klass, void *data) dc->desc = "XIVE Interrupt Thread Context"; dc->realize = xive_tctx_realize; - dc->unrealize = xive_tctx_unrealize; dc->vmsd = &vmstate_xive_tctx; /* * Reason: part of XIVE interrupt controller, needs to be wired up diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 7cf64b6d25..4a51fb65a8 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -778,6 +778,13 @@ static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu, pnv_cpu->intc = obj; } +static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu) +{ + PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); + + icp_reset(ICP(pnv_cpu->intc)); +} + /* * 0:48 Reserved - Read as zeroes * 49:52 Node ID @@ -815,6 +822,13 @@ static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu, pnv_cpu->intc = obj; } +static void pnv_chip_power9_intc_reset(PnvChip *chip, PowerPCCPU *cpu) +{ + PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); + + xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc)); +} + /* * Allowed core identifiers on a POWER8 Processor Chip : * @@ -984,6 +998,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8E_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; + k->intc_reset = pnv_chip_power8_intc_reset; k->isa_create = pnv_chip_power8_isa_create; k->dt_populate = pnv_chip_power8_dt_populate; k->pic_print_info = pnv_chip_power8_pic_print_info; @@ -1003,6 +1018,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; + k->intc_reset = pnv_chip_power8_intc_reset; k->isa_create = pnv_chip_power8_isa_create; k->dt_populate = pnv_chip_power8_dt_populate; k->pic_print_info = pnv_chip_power8_pic_print_info; @@ -1022,6 +1038,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; + k->intc_reset = pnv_chip_power8_intc_reset; k->isa_create = pnv_chip_power8nvl_isa_create; k->dt_populate = pnv_chip_power8_dt_populate; k->pic_print_info = pnv_chip_power8_pic_print_info; @@ -1191,6 +1208,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER9_CORE_MASK; k->core_pir = pnv_chip_core_pir_p9; k->intc_create = pnv_chip_power9_intc_create; + k->intc_reset = pnv_chip_power9_intc_reset; k->isa_create = pnv_chip_power9_isa_create; k->dt_populate = pnv_chip_power9_dt_populate; k->pic_print_info = pnv_chip_power9_pic_print_info; diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index cc17bbfed8..be0310ac03 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -40,10 +40,11 @@ static const char *pnv_core_cpu_typename(PnvCore *pc) return cpu_type; } -static void pnv_core_cpu_reset(PowerPCCPU *cpu) +static void pnv_core_cpu_reset(PowerPCCPU *cpu, PnvChip *chip) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); cpu_reset(cs); @@ -54,6 +55,8 @@ static void pnv_core_cpu_reset(PowerPCCPU *cpu) env->gpr[3] = PNV_FDT_ADDR; env->nip = 0x10; env->msr |= MSR_HVB; /* Hypervisor mode */ + + pcc->intc_reset(chip, cpu); } /* @@ -200,7 +203,7 @@ static void pnv_core_reset(void *dev) int i; for (i = 0; i < cc->nr_threads; i++) { - pnv_core_cpu_reset(pc->threads[i]); + pnv_core_cpu_reset(pc->threads[i], pc->chip); } } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 2e34832d0e..ef7b27a66d 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -32,6 +32,7 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu) PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); target_ulong lpcr; + SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); cpu_reset(cs); @@ -76,9 +77,11 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu) spapr_cpu->dtl_addr = 0; spapr_cpu->dtl_size = 0; - spapr_caps_cpu_apply(SPAPR_MACHINE(qdev_get_machine()), cpu); + spapr_caps_cpu_apply(spapr, cpu); kvm_check_mmu(cpu, &error_fatal); + + spapr_irq_cpu_intc_reset(spapr, cpu); } void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 234d1073e5..b941608b69 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -220,6 +220,20 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, return 0; } +void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu) +{ + SpaprInterruptController *intcs[] = ALL_INTCS(spapr); + int i; + + for (i = 0; i < ARRAY_SIZE(intcs); i++) { + SpaprInterruptController *intc = intcs[i]; + if (intc) { + SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); + sicc->cpu_intc_reset(intc, cpu); + } + } +} + static void spapr_set_irq(void *opaque, int irq, int level) { SpaprMachineState *spapr = SPAPR_MACHINE(opaque); diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 1cdbe55bf8..2a780e633f 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -111,6 +111,7 @@ typedef struct PnvChipClass { uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp); + void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu); ISABus *(*isa_create)(PnvChip *chip, Error **errp); void (*dt_populate)(PnvChip *chip, void *fdt); void (*pic_print_info)(PnvChip *chip, Monitor *mon); diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 5e150a6679..09232999b0 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -52,6 +52,7 @@ typedef struct SpaprInterruptControllerClass { */ int (*cpu_intc_create)(SpaprInterruptController *intc, PowerPCCPU *cpu, Error **errp); + void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu); int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi, Error **errp); void (*free_irq)(SpaprInterruptController *intc, int irq); @@ -68,6 +69,7 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr); int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, PowerPCCPU *cpu, Error **errp); +void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu); void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon); void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 1e6a9300eb..602173c122 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -161,6 +161,7 @@ void icp_set_mfrr(ICPState *icp, uint8_t mfrr); uint32_t icp_accept(ICPState *ss); uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr); void icp_eoi(ICPState *icp, uint32_t xirr); +void icp_reset(ICPState *icp); void ics_write_xive(ICSState *ics, int nr, int server, uint8_t priority, uint8_t saved_priority); diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index fd3319bd32..99381639f5 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -415,6 +415,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size); void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon); Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp); +void xive_tctx_reset(XiveTCTX *tctx); static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx) { From patchwork Thu Oct 24 08:18:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208503 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B2D88112C for ; Thu, 24 Oct 2019 08:27:07 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8952A20659 for ; Thu, 24 Oct 2019 08:27:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="ZdaYAK8o" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8952A20659 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:34918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYSY-0004d9-6C for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:27:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36876) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKb-00050m-G6 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKZ-0005S3-QG for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:53 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:41411 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKZ-0005Mw-Dh; Thu, 24 Oct 2019 04:18:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrc3xhsz9sSG; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905120; bh=Xs8W+ykQ9G+OhrnzjhaEi48Z3MoKVYbgdQ4As7qwqyY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZdaYAK8oYIcLEuSh3jRxfGvwNzGBup5FKcMbTNwpTVadOJHcyMHzQpVqbUQ7Sp45U rPBs90s05XH51Cec0oC6zFSW/8kTxba7vw/WdMB+hBbULNZc1FWufn13xAyAo70tf2 h8MuUcaEThjsGscl2NFnqfSeDxr0L6qJy7IF5avE= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 27/28] ppc/pnv: Fix naming of routines realizing the CPUs Date: Thu, 24 Oct 2019 19:18:12 +1100 Message-Id: <20191024081813.2115-28-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater The 'vcpu' suffix is inherited from the sPAPR machine. Use better names for PowerNV. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Message-Id: <20191022163812.330-7-clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/pnv_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index be0310ac03..e81cd3a3e0 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -162,7 +162,7 @@ static const MemoryRegionOps pnv_core_power9_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp) +static void pnv_core_cpu_realize(PowerPCCPU *cpu, PnvChip *chip, Error **errp) { CPUPPCState *env = &cpu->env; int core_pir; @@ -247,7 +247,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } for (j = 0; j < cc->nr_threads; j++) { - pnv_realize_vcpu(pc->threads[j], pc->chip, &local_err); + pnv_core_cpu_realize(pc->threads[j], pc->chip, &local_err); if (local_err) { goto err; } @@ -269,7 +269,7 @@ err: error_propagate(errp, local_err); } -static void pnv_unrealize_vcpu(PowerPCCPU *cpu) +static void pnv_core_cpu_unrealize(PowerPCCPU *cpu) { PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); @@ -289,7 +289,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp) qemu_unregister_reset(pnv_core_reset, pc); for (i = 0; i < cc->nr_threads; i++) { - pnv_unrealize_vcpu(pc->threads[i]); + pnv_core_cpu_unrealize(pc->threads[i]); } g_free(pc->threads); } From patchwork Thu Oct 24 08:18:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11208535 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 94C0813B1 for ; Thu, 24 Oct 2019 08:47:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 67E5C20684 for ; Thu, 24 Oct 2019 08:47:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="dtirUoML" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 67E5C20684 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35292 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYm7-0004Ad-IV for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 04:47:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36832) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNYKa-0004ye-Ae for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNYKY-0005Ol-H7 for qemu-devel@nongnu.org; Thu, 24 Oct 2019 04:18:52 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:40291 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iNYKY-0005IN-3v; Thu, 24 Oct 2019 04:18:50 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46zKrc1jf3z9sRs; Thu, 24 Oct 2019 19:18:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1571905120; bh=U2SbhbG10Q31T/En/uIElsIUQzlSawLqGYxd7BEmbcM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dtirUoMLuKsi7E+qp3tzeIOrUhadgLyotNIf5jpZ5+lu3tl6tnMfiqiDQFiSIiGPp tcknkFlDUqiLfT2JtreCvylqRGSlGpKoAz9ZmJKqWc7iI5ibDEX06GF1anC46fpZK0 rVH4gEXrReOoAuOazztjnAcv1+b82HimoIArXPYo= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 28/28] spapr/xive: Set the OS CAM line at reset Date: Thu, 24 Oct 2019 19:18:13 +1100 Message-Id: <20191024081813.2115-29-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191024081813.2115-1-david@gibson.dropbear.id.au> References: <20191024081813.2115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater When a Virtual Processor is scheduled to run on a HW thread, the hypervisor pushes its identifier in the OS CAM line. When running with kernel_irqchip=off, QEMU needs to emulate the same behavior. Set the OS CAM line when the interrupt presenter of the sPAPR core is reset. This will also cover the case of hot-plugged CPUs. This change also has the benefit to remove the use of CPU_FOREACH() which can be unsafe. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Message-Id: <20191022163812.330-8-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 48 +++++++++++++------------------------ include/hw/ppc/spapr_xive.h | 1 - 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 20a8d8285f..d8e1291905 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -205,23 +205,6 @@ void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable) memory_region_set_enabled(&xive->end_source.esb_mmio, false); } -/* - * When a Virtual Processor is scheduled to run on a HW thread, the - * hypervisor pushes its identifier in the OS CAM line. Emulate the - * same behavior under QEMU. - */ -void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx) -{ - uint8_t nvt_blk; - uint32_t nvt_idx; - uint32_t nvt_cam; - - spapr_xive_cpu_to_nvt(POWERPC_CPU(tctx->cs), &nvt_blk, &nvt_idx); - - nvt_cam = cpu_to_be32(TM_QW1W2_VO | xive_nvt_cam_line(nvt_blk, nvt_idx)); - memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &nvt_cam, 4); -} - static void spapr_xive_end_reset(XiveEND *end) { memset(end, 0, sizeof(*end)); @@ -544,21 +527,32 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc, } spapr_cpu->tctx = XIVE_TCTX(obj); - - /* - * (TCG) Early setting the OS CAM line for hotplugged CPUs as they - * don't beneficiate from the reset of the XIVE IRQ backend - */ - spapr_xive_set_tctx_os_cam(spapr_cpu->tctx); return 0; } +static void xive_tctx_set_os_cam(XiveTCTX *tctx, uint32_t os_cam) +{ + uint32_t qw1w2 = cpu_to_be32(TM_QW1W2_VO | os_cam); + memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4); +} + static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc, PowerPCCPU *cpu) { XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx; + uint8_t nvt_blk; + uint32_t nvt_idx; xive_tctx_reset(tctx); + + /* + * When a Virtual Processor is scheduled to run on a HW thread, + * the hypervisor pushes its identifier in the OS CAM line. + * Emulate the same behavior under QEMU. + */ + spapr_xive_cpu_to_nvt(cpu, &nvt_blk, &nvt_idx); + + xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx)); } static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val) @@ -651,14 +645,6 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers, static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp) { SpaprXive *xive = SPAPR_XIVE(intc); - CPUState *cs; - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - - /* (TCG) Set the OS CAM line of the thread interrupt context. */ - spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); - } if (kvm_enabled()) { int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp); diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index d84bd5c229..742b7e834f 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -57,7 +57,6 @@ typedef struct SpaprXive { void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon); void spapr_xive_hcall_init(SpaprMachineState *spapr); -void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx); void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable); void spapr_xive_map_mmio(SpaprXive *xive);